131 lines
4.5 KiB
JavaScript
131 lines
4.5 KiB
JavaScript
/**
|
||
* @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;
|
||
}
|