| 
									
										
											  
											
												refactor(angular_1_router): use directives for route targets
BREAKING CHANGE:
Previously, route configuration took a controller constructor function as the value of
`component` in a route definition:
```
$route.config([
  { route: '/', component: MyController }
])
```
Based on the name of the controller, we used to use a componentMapper service to
determine what template to pair with each controller, how to bind the instance to
the $scope.
To make the 1.x router more semantically alligned with Angular 2, we now route to a directive.
Thus a route configuration takes a normalized directive name:
```
$route.config([
  { route: '/', component: 'myDirective' }
])
```
BREAKING CHANGE:
In order to avoid name collisions, lifecycle hooks are now prefixed with `$`. Before:
```
MyController.prototype.onActivate = ...
```
After:
```
MyController.prototype.$onActivate = ...
```
Same for `$canActivate` (which now lives on the directive factory function),
`$canDeactivate`, `$canReuse`, and `$onDeactivate` hooks.
											
										 
											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()). | 
					
						
							| 
									
										
											  
											
												refactor(angular_1_router): use directives for route targets
BREAKING CHANGE:
Previously, route configuration took a controller constructor function as the value of
`component` in a route definition:
```
$route.config([
  { route: '/', component: MyController }
])
```
Based on the name of the controller, we used to use a componentMapper service to
determine what template to pair with each controller, how to bind the instance to
the $scope.
To make the 1.x router more semantically alligned with Angular 2, we now route to a directive.
Thus a route configuration takes a normalized directive name:
```
$route.config([
  { route: '/', component: 'myDirective' }
])
```
BREAKING CHANGE:
In order to avoid name collisions, lifecycle hooks are now prefixed with `$`. Before:
```
MyController.prototype.onActivate = ...
```
After:
```
MyController.prototype.$onActivate = ...
```
Same for `$canActivate` (which now lives on the directive factory function),
`$canDeactivate`, `$canReuse`, and `$onDeactivate` hooks.
											
										 
											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) { | 
					
						
							| 
									
										
											  
											
												refactor(angular_1_router): use directives for route targets
BREAKING CHANGE:
Previously, route configuration took a controller constructor function as the value of
`component` in a route definition:
```
$route.config([
  { route: '/', component: MyController }
])
```
Based on the name of the controller, we used to use a componentMapper service to
determine what template to pair with each controller, how to bind the instance to
the $scope.
To make the 1.x router more semantically alligned with Angular 2, we now route to a directive.
Thus a route configuration takes a normalized directive name:
```
$route.config([
  { route: '/', component: 'myDirective' }
])
```
BREAKING CHANGE:
In order to avoid name collisions, lifecycle hooks are now prefixed with `$`. Before:
```
MyController.prototype.onActivate = ...
```
After:
```
MyController.prototype.$onActivate = ...
```
Same for `$canActivate` (which now lives on the directive factory function),
`$canDeactivate`, `$canReuse`, and `$onDeactivate` hooks.
											
										 
											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}}
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
											  
											
												refactor(router): improve recognition and generation pipeline
This is a big change. @matsko also deserves much of the credit for the implementation.
Previously, `ComponentInstruction`s held all the state for async components.
Now, we introduce several subclasses for `Instruction` to describe each type of navigation.
BREAKING CHANGE:
Redirects now use the Link DSL syntax. Before:
```
@RouteConfig([
	{ path: '/foo', redirectTo: '/bar' },
	{ path: '/bar', component: BarCmp }
])
```
After:
```
@RouteConfig([
	{ path: '/foo', redirectTo: ['Bar'] },
	{ path: '/bar', component: BarCmp, name: 'Bar' }
])
```
BREAKING CHANGE:
This also introduces `useAsDefault` in the RouteConfig, which makes cases like lazy-loading
and encapsulating large routes with sub-routes easier.
Previously, you could use `redirectTo` like this to expand a URL like `/tab` to `/tab/posts`:
@RouteConfig([
	{ path: '/tab', redirectTo: '/tab/users' }
	{ path: '/tab', component: TabsCmp, name: 'Tab' }
])
AppCmp { ... }
Now the recommended way to handle this is case is to use `useAsDefault` like so:
```
@RouteConfig([
	{ path: '/tab', component: TabsCmp, name: 'Tab' }
])
AppCmp { ... }
@RouteConfig([
	{ path: '/posts', component: PostsCmp, useAsDefault: true, name: 'Posts' },
	{ path: '/users', component: UsersCmp, name: 'Users' }
])
TabsCmp { ... }
```
In the above example, you can write just `['/Tab']` and the route `Users` is automatically selected as a child route.
Closes #4728
Closes #4228
Closes #4170
Closes #4490
Closes #4694
Closes #5200
Closes #5475
											
										 
											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;}; | 
					
						
							| 
									
										
											  
											
												refactor(angular_1_router): use directives for route targets
BREAKING CHANGE:
Previously, route configuration took a controller constructor function as the value of
`component` in a route definition:
```
$route.config([
  { route: '/', component: MyController }
])
```
Based on the name of the controller, we used to use a componentMapper service to
determine what template to pair with each controller, how to bind the instance to
the $scope.
To make the 1.x router more semantically alligned with Angular 2, we now route to a directive.
Thus a route configuration takes a normalized directive name:
```
$route.config([
  { route: '/', component: 'myDirective' }
])
```
BREAKING CHANGE:
In order to avoid name collisions, lifecycle hooks are now prefixed with `$`. Before:
```
MyController.prototype.onActivate = ...
```
After:
```
MyController.prototype.$onActivate = ...
```
Same for `$canActivate` (which now lives on the directive factory function),
`$canDeactivate`, `$canReuse`, and `$onDeactivate` hooks.
											
										 
											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'); | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  |   } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
											  
											
												refactor(angular_1_router): use directives for route targets
BREAKING CHANGE:
Previously, route configuration took a controller constructor function as the value of
`component` in a route definition:
```
$route.config([
  { route: '/', component: MyController }
])
```
Based on the name of the controller, we used to use a componentMapper service to
determine what template to pair with each controller, how to bind the instance to
the $scope.
To make the 1.x router more semantically alligned with Angular 2, we now route to a directive.
Thus a route configuration takes a normalized directive name:
```
$route.config([
  { route: '/', component: 'myDirective' }
])
```
BREAKING CHANGE:
In order to avoid name collisions, lifecycle hooks are now prefixed with `$`. Before:
```
MyController.prototype.onActivate = ...
```
After:
```
MyController.prototype.$onActivate = ...
```
Same for `$canActivate` (which now lives on the directive factory function),
`$canDeactivate`, `$canReuse`, and `$onDeactivate` hooks.
											
										 
											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, { | 
					
						
							| 
									
										
											  
											
												refactor(angular_1_router): use directives for route targets
BREAKING CHANGE:
Previously, route configuration took a controller constructor function as the value of
`component` in a route definition:
```
$route.config([
  { route: '/', component: MyController }
])
```
Based on the name of the controller, we used to use a componentMapper service to
determine what template to pair with each controller, how to bind the instance to
the $scope.
To make the 1.x router more semantically alligned with Angular 2, we now route to a directive.
Thus a route configuration takes a normalized directive name:
```
$route.config([
  { route: '/', component: 'myDirective' }
])
```
BREAKING CHANGE:
In order to avoid name collisions, lifecycle hooks are now prefixed with `$`. Before:
```
MyController.prototype.onActivate = ...
```
After:
```
MyController.prototype.$onActivate = ...
```
Same for `$canActivate` (which now lives on the directive factory function),
`$canDeactivate`, `$canReuse`, and `$onDeactivate` hooks.
											
										 
											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 () {}; | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
											  
											
												refactor(router): improve recognition and generation pipeline
This is a big change. @matsko also deserves much of the credit for the implementation.
Previously, `ComponentInstruction`s held all the state for async components.
Now, we introduce several subclasses for `Instruction` to describe each type of navigation.
BREAKING CHANGE:
Redirects now use the Link DSL syntax. Before:
```
@RouteConfig([
	{ path: '/foo', redirectTo: '/bar' },
	{ path: '/bar', component: BarCmp }
])
```
After:
```
@RouteConfig([
	{ path: '/foo', redirectTo: ['Bar'] },
	{ path: '/bar', component: BarCmp, name: 'Bar' }
])
```
BREAKING CHANGE:
This also introduces `useAsDefault` in the RouteConfig, which makes cases like lazy-loading
and encapsulating large routes with sub-routes easier.
Previously, you could use `redirectTo` like this to expand a URL like `/tab` to `/tab/posts`:
@RouteConfig([
	{ path: '/tab', redirectTo: '/tab/users' }
	{ path: '/tab', component: TabsCmp, name: 'Tab' }
])
AppCmp { ... }
Now the recommended way to handle this is case is to use `useAsDefault` like so:
```
@RouteConfig([
	{ path: '/tab', component: TabsCmp, name: 'Tab' }
])
AppCmp { ... }
@RouteConfig([
	{ path: '/posts', component: PostsCmp, useAsDefault: true, name: 'Posts' },
	{ path: '/users', component: UsersCmp, name: 'Users' }
])
TabsCmp { ... }
```
In the above example, you can write just `['/Tab']` and the route `Users` is automatically selected as a child route.
Closes #4728
Closes #4228
Closes #4170
Closes #4490
Closes #4694
Closes #5200
Closes #5475
											
										 
											2015-11-23 18:07:37 -08:00
										 |  |  |  |   angular.stringifyInstruction = function (instruction) { | 
					
						
							|  |  |  |  |     return instruction.toRootUrl(); | 
					
						
							|  |  |  |  |   }; | 
					
						
							| 
									
										
											  
											
												refactor(angular_1_router): use directives for route targets
BREAKING CHANGE:
Previously, route configuration took a controller constructor function as the value of
`component` in a route definition:
```
$route.config([
  { route: '/', component: MyController }
])
```
Based on the name of the controller, we used to use a componentMapper service to
determine what template to pair with each controller, how to bind the instance to
the $scope.
To make the 1.x router more semantically alligned with Angular 2, we now route to a directive.
Thus a route configuration takes a normalized directive name:
```
$route.config([
  { route: '/', component: 'myDirective' }
])
```
BREAKING CHANGE:
In order to avoid name collisions, lifecycle hooks are now prefixed with `$`. Before:
```
MyController.prototype.onActivate = ...
```
After:
```
MyController.prototype.$onActivate = ...
```
Same for `$canActivate` (which now lives on the directive factory function),
`$canDeactivate`, `$canReuse`, and `$onDeactivate` hooks.
											
										 
											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); | 
					
						
							| 
									
										
											  
											
												refactor(angular_1_router): use directives for route targets
BREAKING CHANGE:
Previously, route configuration took a controller constructor function as the value of
`component` in a route definition:
```
$route.config([
  { route: '/', component: MyController }
])
```
Based on the name of the controller, we used to use a componentMapper service to
determine what template to pair with each controller, how to bind the instance to
the $scope.
To make the 1.x router more semantically alligned with Angular 2, we now route to a directive.
Thus a route configuration takes a normalized directive name:
```
$route.config([
  { route: '/', component: 'myDirective' }
])
```
BREAKING CHANGE:
In order to avoid name collisions, lifecycle hooks are now prefixed with `$`. Before:
```
MyController.prototype.onActivate = ...
```
After:
```
MyController.prototype.$onActivate = ...
```
Same for `$canActivate` (which now lives on the directive factory function),
`$canDeactivate`, `$canReuse`, and `$onDeactivate` hooks.
											
										 
											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) { | 
					
						
							| 
									
										
											  
											
												refactor(angular_1_router): use directives for route targets
BREAKING CHANGE:
Previously, route configuration took a controller constructor function as the value of
`component` in a route definition:
```
$route.config([
  { route: '/', component: MyController }
])
```
Based on the name of the controller, we used to use a componentMapper service to
determine what template to pair with each controller, how to bind the instance to
the $scope.
To make the 1.x router more semantically alligned with Angular 2, we now route to a directive.
Thus a route configuration takes a normalized directive name:
```
$route.config([
  { route: '/', component: 'myDirective' }
])
```
BREAKING CHANGE:
In order to avoid name collisions, lifecycle hooks are now prefixed with `$`. Before:
```
MyController.prototype.onActivate = ...
```
After:
```
MyController.prototype.$onActivate = ...
```
Same for `$canActivate` (which now lives on the directive factory function),
`$canDeactivate`, `$canReuse`, and `$onDeactivate` hooks.
											
										 
											2015-09-18 15:53:50 -07:00
										 |  |  |  |     if (router.lastNavigationAttempt !== path) { | 
					
						
							|  |  |  |  |       router.navigateByUrl(path); | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  |   }); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |   router.subscribe(function () { | 
					
						
							|  |  |  |  |     $rootScope.$broadcast('$routeChangeSuccess', {}); | 
					
						
							|  |  |  |  |   }); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |   return router; | 
					
						
							|  |  |  |  | } |