2015-09-18 15:53:50 -07:00
|
|
|
|
|
|
|
|
|
|
angular.module('ngComponentRouter').
|
|
|
|
|
|
value('$route', null). // can be overloaded with ngRouteShim
|
2015-11-01 14:31:36 -06:00
|
|
|
|
// Because Angular 1 has no notion of a root component, we use an object with unique identity
|
|
|
|
|
|
// to represent this. Can be overloaded with a component name
|
|
|
|
|
|
value('$routerRootComponent', new Object()).
|
2015-09-18 15:53:50 -07:00
|
|
|
|
|
2016-03-21 11:49:37 +00:00
|
|
|
|
// Unfortunately, $location doesn't expose what the current hashPrefix is
|
|
|
|
|
|
// So we have to monkey patch the $locationProvider to capture this value
|
|
|
|
|
|
provider('$locationHashPrefix', ['$locationProvider', $locationHashPrefixProvider]).
|
|
|
|
|
|
factory('$rootRouter', ['$q', '$location', '$browser', '$rootScope', '$injector', '$routerRootComponent', '$locationHashPrefix', routerFactory]);
|
|
|
|
|
|
|
|
|
|
|
|
function $locationHashPrefixProvider($locationProvider) {
|
|
|
|
|
|
|
|
|
|
|
|
// Get hold of the original hashPrefix method
|
|
|
|
|
|
var hashPrefixFn = $locationProvider.hashPrefix.bind($locationProvider);
|
|
|
|
|
|
|
|
|
|
|
|
// Read the current hashPrefix (in case it was set before this monkey-patch occurred)
|
|
|
|
|
|
var hashPrefix = hashPrefixFn();
|
|
|
|
|
|
|
|
|
|
|
|
// Override the helper so that we can read any changes to the prefix (after this monkey-patch)
|
|
|
|
|
|
$locationProvider.hashPrefix = function(prefix) {
|
|
|
|
|
|
if (angular.isDefined(prefix)) {
|
|
|
|
|
|
hashPrefix = prefix;
|
|
|
|
|
|
}
|
|
|
|
|
|
return hashPrefixFn(prefix);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Return the final hashPrefix as the value of this service
|
|
|
|
|
|
this.$get = function() { return hashPrefix; };
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function routerFactory($q, $location, $browser, $rootScope, $injector, $routerRootComponent, $locationHashPrefix) {
|
2015-09-18 15:53:50 -07:00
|
|
|
|
|
|
|
|
|
|
// When this file is processed, the line below is replaced with
|
|
|
|
|
|
// the contents of `../lib/facades.es5`.
|
|
|
|
|
|
//{{FACADES}}
|
|
|
|
|
|
|
2015-11-23 18:07:37 -08:00
|
|
|
|
var exports = {
|
|
|
|
|
|
Injectable: function () {},
|
|
|
|
|
|
OpaqueToken: function () {},
|
|
|
|
|
|
Inject: function () {}
|
|
|
|
|
|
};
|
2016-02-11 21:54:29 -06:00
|
|
|
|
var routerRequire = function () {return exports;};
|
2015-09-18 15:53:50 -07:00
|
|
|
|
|
|
|
|
|
|
// When this file is processed, the line below is replaced with
|
|
|
|
|
|
// the contents of the compiled TypeScript classes.
|
|
|
|
|
|
//{{SHARED_CODE}}
|
|
|
|
|
|
|
2016-02-25 13:03:29 +00:00
|
|
|
|
function getComponentConstructor(name) {
|
|
|
|
|
|
var serviceName = name + 'Directive';
|
|
|
|
|
|
if ($injector.has(serviceName)) {
|
|
|
|
|
|
var definitions = $injector.get(serviceName);
|
|
|
|
|
|
if (definitions.length > 1) {
|
|
|
|
|
|
throw new BaseException('too many directives named "' + name + '"');
|
|
|
|
|
|
}
|
|
|
|
|
|
return definitions[0].controller;
|
|
|
|
|
|
} else {
|
|
|
|
|
|
throw new BaseException('directive "' + name + '" is not registered');
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2015-09-18 15:53:50 -07:00
|
|
|
|
//TODO: this is a hack to replace the exiting implementation at run-time
|
|
|
|
|
|
exports.getCanActivateHook = function (directiveName) {
|
2016-02-25 13:03:29 +00:00
|
|
|
|
var controller = getComponentConstructor(directiveName);
|
|
|
|
|
|
return controller.$canActivate && function (next, prev) {
|
|
|
|
|
|
return $injector.invoke(controller.$canActivate, null, {
|
2015-09-18 15:53:50 -07:00
|
|
|
|
$nextInstruction: next,
|
|
|
|
|
|
$prevInstruction: prev
|
|
|
|
|
|
});
|
|
|
|
|
|
};
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// This hack removes assertions about the type of the "component"
|
|
|
|
|
|
// property in a route config
|
|
|
|
|
|
exports.assertComponentExists = function () {};
|
|
|
|
|
|
|
2015-11-23 18:07:37 -08:00
|
|
|
|
angular.stringifyInstruction = function (instruction) {
|
|
|
|
|
|
return instruction.toRootUrl();
|
|
|
|
|
|
};
|
2015-09-18 15:53:50 -07:00
|
|
|
|
|
|
|
|
|
|
var RouteRegistry = exports.RouteRegistry;
|
|
|
|
|
|
var RootRouter = exports.RootRouter;
|
|
|
|
|
|
|
2016-02-25 13:03:29 +00:00
|
|
|
|
// Override this method to actually get hold of the child routes
|
|
|
|
|
|
RouteRegistry.prototype.configFromComponent = function (component) {
|
|
|
|
|
|
var that = this;
|
|
|
|
|
|
if (isString(component)) {
|
|
|
|
|
|
// Don't read the annotations component a type more than once –
|
|
|
|
|
|
// this prevents an infinite loop if a component routes recursively.
|
|
|
|
|
|
if (this._rules.has(component)) {
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
var controller = getComponentConstructor(component);
|
|
|
|
|
|
if (angular.isArray(controller.$routeConfig)) {
|
|
|
|
|
|
controller.$routeConfig.forEach(function (config) {
|
|
|
|
|
|
var loader = config.loader;
|
|
|
|
|
|
if (isPresent(loader)) {
|
2016-04-14 17:23:55 -05:00
|
|
|
|
config = angular.extend({}, config, { loader: function() { return $injector.invoke(loader); } });
|
2016-02-25 13:03:29 +00:00
|
|
|
|
}
|
|
|
|
|
|
that.config(component, config);
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2015-11-01 14:31:36 -06:00
|
|
|
|
var registry = new RouteRegistry($routerRootComponent);
|
2015-09-18 15:53:50 -07:00
|
|
|
|
var location = new Location();
|
|
|
|
|
|
|
2015-11-01 14:31:36 -06:00
|
|
|
|
var router = new RootRouter(registry, location, $routerRootComponent);
|
2016-01-26 13:51:50 +01:00
|
|
|
|
$rootScope.$watch(function () { return $location.url(); }, function (path) {
|
2015-09-18 15:53:50 -07:00
|
|
|
|
if (router.lastNavigationAttempt !== path) {
|
|
|
|
|
|
router.navigateByUrl(path);
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
router.subscribe(function () {
|
|
|
|
|
|
$rootScope.$broadcast('$routeChangeSuccess', {});
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
return router;
|
|
|
|
|
|
}
|