/** * @license * Copyright Google Inc. All Rights Reserved. * * Use of this source code is governed by an MIT-style license that can be * found in the LICENSE file at https://angular.io/license */ angular.module('ngComponentRouter'). value('$route', null). // can be overloaded with ngRouteShim // Because AngularJS 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()). // 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) { // When this file is processed, the line below is replaced with // the contents of `../lib/facades.es5`. //{{FACADES}} var exports = { Injectable: function () {}, InjectionToken: function () {}, Inject: function () {} }; var routerRequire = function () {return exports;}; // When this file is processed, the line below is replaced with // the contents of the compiled TypeScript classes. //{{SHARED_CODE}} function getComponentConstructor(name) { var serviceName = name + 'Directive'; if ($injector.has(serviceName)) { var definitions = $injector.get(serviceName); if (definitions.length > 1) { throw new Error('too many directives named "' + name + '"'); } return definitions[0].controller; } else { throw new Error('directive "' + name + '" is not registered'); } } //TODO: this is a hack to replace the exiting implementation at run-time exports.getCanActivateHook = function (directiveName) { var controller = getComponentConstructor(directiveName); return controller.$canActivate && function (next, prev) { return $injector.invoke(controller.$canActivate, null, { $nextInstruction: next, $prevInstruction: prev }); }; }; // This hack removes assertions about the type of the "component" // property in a route config exports.assertComponentExists = function () {}; angular.stringifyInstruction = function (instruction) { return instruction.toRootUrl(); }; var RouteRegistry = exports.RouteRegistry; var RootRouter = exports.RootRouter; // Override this method to actually get hold of the child routes RouteRegistry.prototype.configFromComponent = function (component) { var that = this; if (typeof component === 'string') { // 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)) { config = angular.extend({}, config, { loader: function() { return $injector.invoke(loader); } }); } that.config(component, config); }); } } }; var registry = new RouteRegistry($routerRootComponent); var location = new Location(); var router = new RootRouter(registry, location, $routerRootComponent); $rootScope.$watch(function () { return $location.url(); }, function (path) { if (router.lastNavigationAttempt !== path) { router.navigateByUrl(path); } }); router.subscribe(function () { $rootScope.$broadcast('$routeChangeSuccess', {}); }); return router; }