| 
									
										
										
										
											2015-05-29 14:58:41 -07:00
										 |  |  | import { | 
					
						
							|  |  |  |   AsyncTestCompleter, | 
					
						
							| 
									
										
										
										
											2015-06-26 16:04:19 -07:00
										 |  |  |   TestComponentBuilder, | 
					
						
							|  |  |  |   asNativeElements, | 
					
						
							| 
									
										
										
										
											2015-05-29 14:58:41 -07:00
										 |  |  |   beforeEach, | 
					
						
							|  |  |  |   ddescribe, | 
					
						
							|  |  |  |   xdescribe, | 
					
						
							|  |  |  |   describe, | 
					
						
							|  |  |  |   el, | 
					
						
							|  |  |  |   expect, | 
					
						
							|  |  |  |   iit, | 
					
						
							|  |  |  |   inject, | 
					
						
							|  |  |  |   beforeEachBindings, | 
					
						
							|  |  |  |   it, | 
					
						
							|  |  |  |   xit | 
					
						
							|  |  |  | } from 'angular2/test_lib'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import {Injector, bind} from 'angular2/di'; | 
					
						
							|  |  |  | import {Component, View} from 'angular2/src/core/annotations/decorators'; | 
					
						
							|  |  |  | import * as annotations from 'angular2/src/core/annotations_impl/view'; | 
					
						
							| 
									
										
										
										
											2015-07-07 15:44:29 -07:00
										 |  |  | import {CONST, NumberWrapper, isPresent} from 'angular2/src/facade/lang'; | 
					
						
							|  |  |  | import {Promise, PromiseWrapper, EventEmitter, ObservableWrapper} from 'angular2/src/facade/async'; | 
					
						
							| 
									
										
										
										
											2015-05-29 14:58:41 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | import {RootRouter} from 'angular2/src/router/router'; | 
					
						
							|  |  |  | import {Pipeline} from 'angular2/src/router/pipeline'; | 
					
						
							|  |  |  | import {Router, RouterOutlet, RouterLink, RouteParams} from 'angular2/router'; | 
					
						
							|  |  |  | import {RouteConfig} from 'angular2/src/router/route_config_decorator'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import {DOM} from 'angular2/src/dom/dom_adapter'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import {SpyLocation} from 'angular2/src/mock/location_mock'; | 
					
						
							|  |  |  | import {Location} from 'angular2/src/router/location'; | 
					
						
							|  |  |  | import {RouteRegistry} from 'angular2/src/router/route_registry'; | 
					
						
							| 
									
										
										
										
											2015-07-07 15:44:29 -07:00
										 |  |  | import { | 
					
						
							|  |  |  |   OnActivate, | 
					
						
							|  |  |  |   OnDeactivate, | 
					
						
							|  |  |  |   OnReuse, | 
					
						
							|  |  |  |   CanDeactivate, | 
					
						
							|  |  |  |   CanReuse | 
					
						
							|  |  |  | } from 'angular2/src/router/interfaces'; | 
					
						
							|  |  |  | import {CanActivate} from 'angular2/src/router/lifecycle_annotations'; | 
					
						
							|  |  |  | import {Instruction} from 'angular2/src/router/instruction'; | 
					
						
							| 
									
										
										
										
											2015-05-29 14:58:41 -07:00
										 |  |  | import {DirectiveResolver} from 'angular2/src/core/compiler/directive_resolver'; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-07-07 15:44:29 -07:00
										 |  |  | var cmpInstanceCount, log, eventBus, completer; | 
					
						
							| 
									
										
										
										
											2015-05-29 14:58:41 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | export function main() { | 
					
						
							|  |  |  |   describe('Outlet Directive', () => { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-06-26 16:04:19 -07:00
										 |  |  |     var tcb: TestComponentBuilder; | 
					
						
							|  |  |  |     var rootTC, rtr, location; | 
					
						
							| 
									
										
										
										
											2015-05-29 14:58:41 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     beforeEachBindings(() => [ | 
					
						
							|  |  |  |       Pipeline, | 
					
						
							| 
									
										
										
										
											2015-07-06 17:41:15 -07:00
										 |  |  |       RouteRegistry, | 
					
						
							| 
									
										
										
										
											2015-05-29 14:58:41 -07:00
										 |  |  |       DirectiveResolver, | 
					
						
							|  |  |  |       bind(Location).toClass(SpyLocation), | 
					
						
							| 
									
										
										
										
											2015-06-03 13:42:57 -07:00
										 |  |  |       bind(Router) | 
					
						
							|  |  |  |           .toFactory((registry, pipeline, | 
					
						
							|  |  |  |                       location) => { return new RootRouter(registry, pipeline, location, MyComp); }, | 
					
						
							|  |  |  |                      [RouteRegistry, Pipeline, Location]) | 
					
						
							| 
									
										
										
										
											2015-05-29 14:58:41 -07:00
										 |  |  |     ]); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-06-26 16:04:19 -07:00
										 |  |  |     beforeEach(inject([TestComponentBuilder, Router, Location], (tcBuilder, router, loc) => { | 
					
						
							|  |  |  |       tcb = tcBuilder; | 
					
						
							| 
									
										
										
										
											2015-05-29 14:58:41 -07:00
										 |  |  |       rtr = router; | 
					
						
							|  |  |  |       location = loc; | 
					
						
							| 
									
										
										
										
											2015-07-07 15:44:29 -07:00
										 |  |  |       cmpInstanceCount = 0; | 
					
						
							|  |  |  |       log = ''; | 
					
						
							|  |  |  |       eventBus = new EventEmitter(); | 
					
						
							| 
									
										
										
										
											2015-05-29 14:58:41 -07:00
										 |  |  |     })); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     function compile(template: string = "<router-outlet></router-outlet>") { | 
					
						
							| 
									
										
										
										
											2015-06-26 16:04:19 -07:00
										 |  |  |       return tcb.overrideView(MyComp, new annotations.View({ | 
					
						
							|  |  |  |                   template: ('<div>' + template + '</div>'), | 
					
						
							|  |  |  |                   directives: [RouterOutlet, RouterLink] | 
					
						
							|  |  |  |                 })) | 
					
						
							|  |  |  |           .createAsync(MyComp) | 
					
						
							|  |  |  |           .then((tc) => { rootTC = tc; }); | 
					
						
							| 
									
										
										
										
											2015-05-29 14:58:41 -07:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('should work in a simple case', inject([AsyncTestCompleter], (async) => { | 
					
						
							|  |  |  |          compile() | 
					
						
							|  |  |  |              .then((_) => rtr.config({'path': '/test', 'component': HelloCmp})) | 
					
						
							|  |  |  |              .then((_) => rtr.navigate('/test')) | 
					
						
							|  |  |  |              .then((_) => { | 
					
						
							| 
									
										
										
										
											2015-06-26 16:04:19 -07:00
										 |  |  |                rootTC.detectChanges(); | 
					
						
							|  |  |  |                expect(rootTC.nativeElement).toHaveText('hello'); | 
					
						
							| 
									
										
										
										
											2015-05-29 14:58:41 -07:00
										 |  |  |                async.done(); | 
					
						
							|  |  |  |              }); | 
					
						
							|  |  |  |        })); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('should navigate between components with different parameters', | 
					
						
							|  |  |  |        inject([AsyncTestCompleter], (async) => { | 
					
						
							|  |  |  |          compile() | 
					
						
							|  |  |  |              .then((_) => rtr.config({'path': '/user/:name', 'component': UserCmp})) | 
					
						
							|  |  |  |              .then((_) => rtr.navigate('/user/brian')) | 
					
						
							| 
									
										
										
										
											2015-06-03 13:42:57 -07:00
										 |  |  |              .then((_) => { | 
					
						
							| 
									
										
										
										
											2015-06-26 16:04:19 -07:00
										 |  |  |                rootTC.detectChanges(); | 
					
						
							|  |  |  |                expect(rootTC.nativeElement).toHaveText('hello brian'); | 
					
						
							| 
									
										
										
										
											2015-06-03 13:42:57 -07:00
										 |  |  |              }) | 
					
						
							| 
									
										
										
										
											2015-05-29 14:58:41 -07:00
										 |  |  |              .then((_) => rtr.navigate('/user/igor')) | 
					
						
							|  |  |  |              .then((_) => { | 
					
						
							| 
									
										
										
										
											2015-06-26 16:04:19 -07:00
										 |  |  |                rootTC.detectChanges(); | 
					
						
							|  |  |  |                expect(rootTC.nativeElement).toHaveText('hello igor'); | 
					
						
							| 
									
										
										
										
											2015-05-29 14:58:41 -07:00
										 |  |  |                async.done(); | 
					
						
							|  |  |  |              }); | 
					
						
							|  |  |  |        })); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('should work with child routers', inject([AsyncTestCompleter], (async) => { | 
					
						
							|  |  |  |          compile('outer { <router-outlet></router-outlet> }') | 
					
						
							| 
									
										
										
										
											2015-06-17 11:57:38 -07:00
										 |  |  |              .then((_) => rtr.config({'path': '/a/...', 'component': ParentCmp})) | 
					
						
							| 
									
										
										
										
											2015-05-29 14:58:41 -07:00
										 |  |  |              .then((_) => rtr.navigate('/a/b')) | 
					
						
							|  |  |  |              .then((_) => { | 
					
						
							| 
									
										
										
										
											2015-06-26 16:04:19 -07:00
										 |  |  |                rootTC.detectChanges(); | 
					
						
							|  |  |  |                expect(rootTC.nativeElement).toHaveText('outer { inner { hello } }'); | 
					
						
							| 
									
										
										
										
											2015-05-29 14:58:41 -07:00
										 |  |  |                async.done(); | 
					
						
							|  |  |  |              }); | 
					
						
							|  |  |  |        })); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('should work with redirects', inject([AsyncTestCompleter, Location], (async, location) => { | 
					
						
							|  |  |  |          compile() | 
					
						
							|  |  |  |              .then((_) => rtr.config({'path': '/original', 'redirectTo': '/redirected'})) | 
					
						
							|  |  |  |              .then((_) => rtr.config({'path': '/redirected', 'component': A})) | 
					
						
							|  |  |  |              .then((_) => rtr.navigate('/original')) | 
					
						
							|  |  |  |              .then((_) => { | 
					
						
							| 
									
										
										
										
											2015-06-26 16:04:19 -07:00
										 |  |  |                rootTC.detectChanges(); | 
					
						
							|  |  |  |                expect(rootTC.nativeElement).toHaveText('A'); | 
					
						
							| 
									
										
										
										
											2015-05-29 14:58:41 -07:00
										 |  |  |                expect(location.urlChanges).toEqual(['/redirected']); | 
					
						
							|  |  |  |                async.done(); | 
					
						
							|  |  |  |              }); | 
					
						
							|  |  |  |        })); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-06-26 16:04:19 -07:00
										 |  |  |     function getHref(tc) { | 
					
						
							|  |  |  |       return DOM.getAttribute(tc.componentViewChildren[0].nativeElement, 'href'); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2015-05-29 14:58:41 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     it('should generate absolute hrefs that include the base href', | 
					
						
							|  |  |  |        inject([AsyncTestCompleter], (async) => { | 
					
						
							|  |  |  |          location.setBaseHref('/my/base'); | 
					
						
							| 
									
										
										
										
											2015-06-30 13:18:51 -07:00
										 |  |  |          compile('<a href="hello" [router-link]="[\'./user\']"></a>') | 
					
						
							| 
									
										
										
										
											2015-05-29 14:58:41 -07:00
										 |  |  |              .then((_) => rtr.config({'path': '/user', 'component': UserCmp, 'as': 'user'})) | 
					
						
							|  |  |  |              .then((_) => rtr.navigate('/a/b')) | 
					
						
							|  |  |  |              .then((_) => { | 
					
						
							| 
									
										
										
										
											2015-06-26 16:04:19 -07:00
										 |  |  |                rootTC.detectChanges(); | 
					
						
							|  |  |  |                expect(getHref(rootTC)).toEqual('/my/base/user'); | 
					
						
							| 
									
										
										
										
											2015-05-29 14:58:41 -07:00
										 |  |  |                async.done(); | 
					
						
							|  |  |  |              }); | 
					
						
							|  |  |  |        })); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('should generate link hrefs without params', inject([AsyncTestCompleter], (async) => { | 
					
						
							| 
									
										
										
										
											2015-06-30 13:18:51 -07:00
										 |  |  |          compile('<a href="hello" [router-link]="[\'./user\']"></a>') | 
					
						
							| 
									
										
										
										
											2015-05-29 14:58:41 -07:00
										 |  |  |              .then((_) => rtr.config({'path': '/user', 'component': UserCmp, 'as': 'user'})) | 
					
						
							|  |  |  |              .then((_) => rtr.navigate('/a/b')) | 
					
						
							|  |  |  |              .then((_) => { | 
					
						
							| 
									
										
										
										
											2015-06-26 16:04:19 -07:00
										 |  |  |                rootTC.detectChanges(); | 
					
						
							|  |  |  |                expect(getHref(rootTC)).toEqual('/user'); | 
					
						
							| 
									
										
										
										
											2015-05-29 14:58:41 -07:00
										 |  |  |                async.done(); | 
					
						
							|  |  |  |              }); | 
					
						
							|  |  |  |        })); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('should reuse common parent components', inject([AsyncTestCompleter], (async) => { | 
					
						
							|  |  |  |          compile() | 
					
						
							| 
									
										
										
										
											2015-06-17 11:57:38 -07:00
										 |  |  |              .then((_) => rtr.config({'path': '/team/:id/...', 'component': TeamCmp})) | 
					
						
							| 
									
										
										
										
											2015-05-29 14:58:41 -07:00
										 |  |  |              .then((_) => rtr.navigate('/team/angular/user/rado')) | 
					
						
							| 
									
										
										
										
											2015-06-03 13:42:57 -07:00
										 |  |  |              .then((_) => { | 
					
						
							| 
									
										
										
										
											2015-06-26 16:04:19 -07:00
										 |  |  |                rootTC.detectChanges(); | 
					
						
							| 
									
										
										
										
											2015-07-07 15:44:29 -07:00
										 |  |  |                expect(cmpInstanceCount).toBe(1); | 
					
						
							| 
									
										
										
										
											2015-06-26 16:04:19 -07:00
										 |  |  |                expect(rootTC.nativeElement).toHaveText('team angular { hello rado }'); | 
					
						
							| 
									
										
										
										
											2015-06-03 13:42:57 -07:00
										 |  |  |              }) | 
					
						
							| 
									
										
										
										
											2015-05-29 14:58:41 -07:00
										 |  |  |              .then((_) => rtr.navigate('/team/angular/user/victor')) | 
					
						
							|  |  |  |              .then((_) => { | 
					
						
							| 
									
										
										
										
											2015-06-26 16:04:19 -07:00
										 |  |  |                rootTC.detectChanges(); | 
					
						
							| 
									
										
										
										
											2015-07-07 15:44:29 -07:00
										 |  |  |                expect(cmpInstanceCount).toBe(1); | 
					
						
							| 
									
										
										
										
											2015-06-26 16:04:19 -07:00
										 |  |  |                expect(rootTC.nativeElement).toHaveText('team angular { hello victor }'); | 
					
						
							| 
									
										
										
										
											2015-05-29 14:58:41 -07:00
										 |  |  |                async.done(); | 
					
						
							|  |  |  |              }); | 
					
						
							|  |  |  |        })); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('should generate link hrefs with params', inject([AsyncTestCompleter], (async) => { | 
					
						
							| 
									
										
										
										
											2015-06-30 13:18:51 -07:00
										 |  |  |          compile('<a href="hello" [router-link]="[\'./user\', {name: name}]">{{name}}</a>') | 
					
						
							| 
									
										
										
										
											2015-05-29 14:58:41 -07:00
										 |  |  |              .then((_) => rtr.config({'path': '/user/:name', 'component': UserCmp, 'as': 'user'})) | 
					
						
							|  |  |  |              .then((_) => rtr.navigate('/a/b')) | 
					
						
							|  |  |  |              .then((_) => { | 
					
						
							| 
									
										
										
										
											2015-06-26 16:04:19 -07:00
										 |  |  |                rootTC.componentInstance.name = 'brian'; | 
					
						
							|  |  |  |                rootTC.detectChanges(); | 
					
						
							|  |  |  |                expect(rootTC.nativeElement).toHaveText('brian'); | 
					
						
							|  |  |  |                expect(DOM.getAttribute(rootTC.componentViewChildren[0].nativeElement, 'href')) | 
					
						
							| 
									
										
										
										
											2015-05-29 14:58:41 -07:00
										 |  |  |                    .toEqual('/user/brian'); | 
					
						
							|  |  |  |                async.done(); | 
					
						
							|  |  |  |              }); | 
					
						
							|  |  |  |        })); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-07-06 17:41:15 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     it('should generate link hrefs from a child to its sibling', | 
					
						
							|  |  |  |        inject([AsyncTestCompleter], (async) => { | 
					
						
							|  |  |  |          compile() | 
					
						
							|  |  |  |              .then((_) => rtr.config( | 
					
						
							|  |  |  |                        {'path': '/page/:number', 'component': SiblingPageCmp, 'as': 'page'})) | 
					
						
							|  |  |  |              .then((_) => rtr.navigate('/page/1')) | 
					
						
							|  |  |  |              .then((_) => { | 
					
						
							|  |  |  |                rootTC.detectChanges(); | 
					
						
							|  |  |  |                expect(DOM.getAttribute(rootTC.componentViewChildren[1] | 
					
						
							|  |  |  |                                            .componentViewChildren[0] | 
					
						
							|  |  |  |                                            .children[0] | 
					
						
							|  |  |  |                                            .nativeElement, | 
					
						
							|  |  |  |                                        'href')) | 
					
						
							|  |  |  |                    .toEqual('/page/2'); | 
					
						
							|  |  |  |                async.done(); | 
					
						
							|  |  |  |              }); | 
					
						
							|  |  |  |        })); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('should generate relative links preserving the existing parent route', | 
					
						
							|  |  |  |        inject([AsyncTestCompleter], (async) => { | 
					
						
							|  |  |  |          compile() | 
					
						
							|  |  |  |              .then((_) => | 
					
						
							|  |  |  |                        rtr.config({'path': '/book/:title/...', 'component': BookCmp, 'as': 'book'})) | 
					
						
							|  |  |  |              .then((_) => rtr.navigate('/book/1984/page/1')) | 
					
						
							|  |  |  |              .then((_) => { | 
					
						
							|  |  |  |                rootTC.detectChanges(); | 
					
						
							|  |  |  |                expect(DOM.getAttribute( | 
					
						
							|  |  |  |                           rootTC.componentViewChildren[1].componentViewChildren[0].nativeElement, | 
					
						
							|  |  |  |                           'href')) | 
					
						
							|  |  |  |                    .toEqual('/book/1984/page/100'); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                expect(DOM.getAttribute(rootTC.componentViewChildren[1] | 
					
						
							|  |  |  |                                            .componentViewChildren[2] | 
					
						
							|  |  |  |                                            .componentViewChildren[0] | 
					
						
							|  |  |  |                                            .children[0] | 
					
						
							|  |  |  |                                            .nativeElement, | 
					
						
							|  |  |  |                                        'href')) | 
					
						
							|  |  |  |                    .toEqual('/book/1984/page/2'); | 
					
						
							|  |  |  |                async.done(); | 
					
						
							|  |  |  |              }); | 
					
						
							|  |  |  |        })); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-07-07 15:44:29 -07:00
										 |  |  |     it('should call the onActivate hook', inject([AsyncTestCompleter], (async) => { | 
					
						
							|  |  |  |          compile() | 
					
						
							|  |  |  |              .then((_) => rtr.config({'path': '/...', 'component': LifecycleCmp})) | 
					
						
							|  |  |  |              .then((_) => rtr.navigate('/on-activate')) | 
					
						
							|  |  |  |              .then((_) => { | 
					
						
							|  |  |  |                rootTC.detectChanges(); | 
					
						
							|  |  |  |                expect(rootTC.nativeElement).toHaveText('activate cmp'); | 
					
						
							|  |  |  |                expect(log).toEqual('activate: null -> /on-activate;'); | 
					
						
							|  |  |  |                async.done(); | 
					
						
							|  |  |  |              }); | 
					
						
							|  |  |  |        })); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('should wait for a parent component\'s onActivate hook to resolve before calling its child\'s', | 
					
						
							|  |  |  |        inject([AsyncTestCompleter], (async) => { | 
					
						
							|  |  |  |          compile() | 
					
						
							|  |  |  |              .then((_) => rtr.config({'path': '/...', 'component': LifecycleCmp})) | 
					
						
							|  |  |  |              .then((_) => { | 
					
						
							|  |  |  |                ObservableWrapper.subscribe(eventBus, (ev) => { | 
					
						
							|  |  |  |                  if (ev.startsWith('parent activate')) { | 
					
						
							|  |  |  |                    completer.resolve(true); | 
					
						
							|  |  |  |                  } | 
					
						
							|  |  |  |                }); | 
					
						
							|  |  |  |                rtr.navigate('/parent-activate/child-activate') | 
					
						
							|  |  |  |                    .then((_) => { | 
					
						
							|  |  |  |                      rootTC.detectChanges(); | 
					
						
							|  |  |  |                      expect(rootTC.nativeElement).toHaveText('parent {activate cmp}'); | 
					
						
							|  |  |  |                      expect(log).toEqual( | 
					
						
							|  |  |  |                          'parent activate: null -> /parent-activate/child-activate;activate: null -> /child-activate;'); | 
					
						
							|  |  |  |                      async.done(); | 
					
						
							|  |  |  |                    }); | 
					
						
							|  |  |  |              }); | 
					
						
							|  |  |  |        })); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('should call the onDeactivate hook', inject([AsyncTestCompleter], (async) => { | 
					
						
							|  |  |  |          compile() | 
					
						
							|  |  |  |              .then((_) => rtr.config({'path': '/...', 'component': LifecycleCmp})) | 
					
						
							|  |  |  |              .then((_) => rtr.navigate('/on-deactivate')) | 
					
						
							|  |  |  |              .then((_) => rtr.navigate('/a')) | 
					
						
							|  |  |  |              .then((_) => { | 
					
						
							|  |  |  |                rootTC.detectChanges(); | 
					
						
							|  |  |  |                expect(rootTC.nativeElement).toHaveText('A'); | 
					
						
							|  |  |  |                expect(log).toEqual('deactivate: /on-deactivate -> /a;'); | 
					
						
							|  |  |  |                async.done(); | 
					
						
							|  |  |  |              }); | 
					
						
							|  |  |  |        })); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('should wait for a child component\'s onDeactivate hook to resolve before calling its parent\'s', | 
					
						
							|  |  |  |        inject([AsyncTestCompleter], (async) => { | 
					
						
							|  |  |  |          compile() | 
					
						
							|  |  |  |              .then((_) => rtr.config({'path': '/...', 'component': LifecycleCmp})) | 
					
						
							|  |  |  |              .then((_) => rtr.navigate('/parent-deactivate/child-deactivate')) | 
					
						
							|  |  |  |              .then((_) => { | 
					
						
							|  |  |  |                ObservableWrapper.subscribe(eventBus, (ev) => { | 
					
						
							|  |  |  |                  if (ev.startsWith('deactivate')) { | 
					
						
							|  |  |  |                    completer.resolve(true); | 
					
						
							|  |  |  |                    rootTC.detectChanges(); | 
					
						
							|  |  |  |                    expect(rootTC.nativeElement).toHaveText('parent {deactivate cmp}'); | 
					
						
							|  |  |  |                  } | 
					
						
							|  |  |  |                }); | 
					
						
							|  |  |  |                rtr.navigate('/a').then((_) => { | 
					
						
							|  |  |  |                  rootTC.detectChanges(); | 
					
						
							|  |  |  |                  expect(rootTC.nativeElement).toHaveText('A'); | 
					
						
							|  |  |  |                  expect(log).toEqual( | 
					
						
							|  |  |  |                      'deactivate: /child-deactivate -> null;parent deactivate: /parent-deactivate/child-deactivate -> /a;'); | 
					
						
							|  |  |  |                  async.done(); | 
					
						
							|  |  |  |                }); | 
					
						
							|  |  |  |              }); | 
					
						
							|  |  |  |        })); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('should reuse a component when the canReuse hook returns false', | 
					
						
							|  |  |  |        inject([AsyncTestCompleter], (async) => { | 
					
						
							|  |  |  |          compile() | 
					
						
							|  |  |  |              .then((_) => rtr.config({'path': '/...', 'component': LifecycleCmp})) | 
					
						
							|  |  |  |              .then((_) => rtr.navigate('/on-reuse/1/a')) | 
					
						
							|  |  |  |              .then((_) => { | 
					
						
							|  |  |  |                rootTC.detectChanges(); | 
					
						
							|  |  |  |                expect(log).toEqual(''); | 
					
						
							|  |  |  |                expect(rootTC.nativeElement).toHaveText('reuse {A}'); | 
					
						
							|  |  |  |                expect(cmpInstanceCount).toBe(1); | 
					
						
							|  |  |  |              }) | 
					
						
							|  |  |  |              .then((_) => rtr.navigate('/on-reuse/2/b')) | 
					
						
							|  |  |  |              .then((_) => { | 
					
						
							|  |  |  |                rootTC.detectChanges(); | 
					
						
							|  |  |  |                expect(log).toEqual('reuse: /on-reuse/1/a -> /on-reuse/2/b;'); | 
					
						
							|  |  |  |                expect(rootTC.nativeElement).toHaveText('reuse {B}'); | 
					
						
							|  |  |  |                expect(cmpInstanceCount).toBe(1); | 
					
						
							|  |  |  |                async.done(); | 
					
						
							|  |  |  |              }); | 
					
						
							|  |  |  |        })); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('should not reuse a component when the canReuse hook returns false', | 
					
						
							|  |  |  |        inject([AsyncTestCompleter], (async) => { | 
					
						
							|  |  |  |          compile() | 
					
						
							|  |  |  |              .then((_) => rtr.config({'path': '/...', 'component': LifecycleCmp})) | 
					
						
							|  |  |  |              .then((_) => rtr.navigate('/never-reuse/1/a')) | 
					
						
							|  |  |  |              .then((_) => { | 
					
						
							|  |  |  |                rootTC.detectChanges(); | 
					
						
							|  |  |  |                expect(log).toEqual(''); | 
					
						
							|  |  |  |                expect(rootTC.nativeElement).toHaveText('reuse {A}'); | 
					
						
							|  |  |  |                expect(cmpInstanceCount).toBe(1); | 
					
						
							|  |  |  |              }) | 
					
						
							|  |  |  |              .then((_) => rtr.navigate('/never-reuse/2/b')) | 
					
						
							|  |  |  |              .then((_) => { | 
					
						
							|  |  |  |                rootTC.detectChanges(); | 
					
						
							|  |  |  |                expect(log).toEqual(''); | 
					
						
							|  |  |  |                expect(rootTC.nativeElement).toHaveText('reuse {B}'); | 
					
						
							|  |  |  |                expect(cmpInstanceCount).toBe(2); | 
					
						
							|  |  |  |                async.done(); | 
					
						
							|  |  |  |              }); | 
					
						
							|  |  |  |        })); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('should navigate when canActivate returns true', inject([AsyncTestCompleter], (async) => { | 
					
						
							|  |  |  |          compile() | 
					
						
							|  |  |  |              .then((_) => rtr.config({'path': '/...', 'component': LifecycleCmp})) | 
					
						
							|  |  |  |              .then((_) => { | 
					
						
							|  |  |  |                ObservableWrapper.subscribe(eventBus, (ev) => { | 
					
						
							|  |  |  |                  if (ev.startsWith('canActivate')) { | 
					
						
							|  |  |  |                    completer.resolve(true); | 
					
						
							|  |  |  |                  } | 
					
						
							|  |  |  |                }); | 
					
						
							|  |  |  |                rtr.navigate('/can-activate/a') | 
					
						
							|  |  |  |                    .then((_) => { | 
					
						
							|  |  |  |                      rootTC.detectChanges(); | 
					
						
							|  |  |  |                      expect(rootTC.nativeElement).toHaveText('canActivate {A}'); | 
					
						
							|  |  |  |                      expect(log).toEqual('canActivate: null -> /can-activate/a;'); | 
					
						
							|  |  |  |                      async.done(); | 
					
						
							|  |  |  |                    }); | 
					
						
							|  |  |  |              }); | 
					
						
							|  |  |  |        })); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('should not navigate when canActivate returns false', | 
					
						
							|  |  |  |        inject([AsyncTestCompleter], (async) => { | 
					
						
							|  |  |  |          compile() | 
					
						
							|  |  |  |              .then((_) => rtr.config({'path': '/...', 'component': LifecycleCmp})) | 
					
						
							|  |  |  |              .then((_) => { | 
					
						
							|  |  |  |                ObservableWrapper.subscribe(eventBus, (ev) => { | 
					
						
							|  |  |  |                  if (ev.startsWith('canActivate')) { | 
					
						
							|  |  |  |                    completer.resolve(false); | 
					
						
							|  |  |  |                  } | 
					
						
							|  |  |  |                }); | 
					
						
							|  |  |  |                rtr.navigate('/can-activate/a') | 
					
						
							|  |  |  |                    .then((_) => { | 
					
						
							|  |  |  |                      rootTC.detectChanges(); | 
					
						
							|  |  |  |                      expect(rootTC.nativeElement).toHaveText(''); | 
					
						
							|  |  |  |                      expect(log).toEqual('canActivate: null -> /can-activate/a;'); | 
					
						
							|  |  |  |                      async.done(); | 
					
						
							|  |  |  |                    }); | 
					
						
							|  |  |  |              }); | 
					
						
							|  |  |  |        })); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('should navigate away when canDeactivate returns true', | 
					
						
							|  |  |  |        inject([AsyncTestCompleter], (async) => { | 
					
						
							|  |  |  |          compile() | 
					
						
							|  |  |  |              .then((_) => rtr.config({'path': '/...', 'component': LifecycleCmp})) | 
					
						
							|  |  |  |              .then((_) => rtr.navigate('/can-deactivate/a')) | 
					
						
							|  |  |  |              .then((_) => { | 
					
						
							|  |  |  |                rootTC.detectChanges(); | 
					
						
							|  |  |  |                expect(rootTC.nativeElement).toHaveText('canDeactivate {A}'); | 
					
						
							|  |  |  |                expect(log).toEqual(''); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                ObservableWrapper.subscribe(eventBus, (ev) => { | 
					
						
							|  |  |  |                  if (ev.startsWith('canDeactivate')) { | 
					
						
							|  |  |  |                    completer.resolve(true); | 
					
						
							|  |  |  |                  } | 
					
						
							|  |  |  |                }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                rtr.navigate('/a').then((_) => { | 
					
						
							|  |  |  |                  rootTC.detectChanges(); | 
					
						
							|  |  |  |                  expect(rootTC.nativeElement).toHaveText('A'); | 
					
						
							|  |  |  |                  expect(log).toEqual('canDeactivate: /can-deactivate/a -> /a;'); | 
					
						
							|  |  |  |                  async.done(); | 
					
						
							|  |  |  |                }); | 
					
						
							|  |  |  |              }); | 
					
						
							|  |  |  |        })); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('should not navigate away when canDeactivate returns false', | 
					
						
							|  |  |  |        inject([AsyncTestCompleter], (async) => { | 
					
						
							|  |  |  |          compile() | 
					
						
							|  |  |  |              .then((_) => rtr.config({'path': '/...', 'component': LifecycleCmp})) | 
					
						
							|  |  |  |              .then((_) => rtr.navigate('/can-deactivate/a')) | 
					
						
							|  |  |  |              .then((_) => { | 
					
						
							|  |  |  |                rootTC.detectChanges(); | 
					
						
							|  |  |  |                expect(rootTC.nativeElement).toHaveText('canDeactivate {A}'); | 
					
						
							|  |  |  |                expect(log).toEqual(''); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                ObservableWrapper.subscribe(eventBus, (ev) => { | 
					
						
							|  |  |  |                  if (ev.startsWith('canDeactivate')) { | 
					
						
							|  |  |  |                    completer.resolve(false); | 
					
						
							|  |  |  |                  } | 
					
						
							|  |  |  |                }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                rtr.navigate('/a').then((_) => { | 
					
						
							|  |  |  |                  rootTC.detectChanges(); | 
					
						
							|  |  |  |                  expect(rootTC.nativeElement).toHaveText('canDeactivate {A}'); | 
					
						
							|  |  |  |                  expect(log).toEqual('canDeactivate: /can-deactivate/a -> /a;'); | 
					
						
							|  |  |  |                  async.done(); | 
					
						
							|  |  |  |                }); | 
					
						
							|  |  |  |              }); | 
					
						
							|  |  |  |        })); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('should run activation and deactivation hooks in the correct order', | 
					
						
							|  |  |  |        inject([AsyncTestCompleter], (async) => { | 
					
						
							|  |  |  |          compile() | 
					
						
							|  |  |  |              .then((_) => rtr.config({'path': '/...', 'component': LifecycleCmp})) | 
					
						
							|  |  |  |              .then((_) => rtr.navigate('/activation-hooks/child')) | 
					
						
							|  |  |  |              .then((_) => { | 
					
						
							|  |  |  |                expect(log).toEqual('canActivate child: null -> /child;' + | 
					
						
							|  |  |  |                                    'canActivate parent: null -> /activation-hooks/child;' + | 
					
						
							|  |  |  |                                    'onActivate parent: null -> /activation-hooks/child;' + | 
					
						
							|  |  |  |                                    'onActivate child: null -> /child;'); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                log = ''; | 
					
						
							|  |  |  |                return rtr.navigate('/a'); | 
					
						
							|  |  |  |              }) | 
					
						
							|  |  |  |              .then((_) => { | 
					
						
							|  |  |  |                expect(log).toEqual('canDeactivate parent: /activation-hooks/child -> /a;' + | 
					
						
							|  |  |  |                                    'canDeactivate child: /child -> null;' + | 
					
						
							|  |  |  |                                    'onDeactivate child: /child -> null;' + | 
					
						
							|  |  |  |                                    'onDeactivate parent: /activation-hooks/child -> /a;'); | 
					
						
							|  |  |  |                async.done(); | 
					
						
							|  |  |  |              }); | 
					
						
							|  |  |  |        })); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('should only run reuse hooks when reusing', inject([AsyncTestCompleter], (async) => { | 
					
						
							|  |  |  |          compile() | 
					
						
							|  |  |  |              .then((_) => rtr.config({'path': '/...', 'component': LifecycleCmp})) | 
					
						
							|  |  |  |              .then((_) => rtr.navigate('/reuse-hooks/1')) | 
					
						
							|  |  |  |              .then((_) => { | 
					
						
							|  |  |  |                expect(log).toEqual('canActivate: null -> /reuse-hooks/1;' + | 
					
						
							|  |  |  |                                    'onActivate: null -> /reuse-hooks/1;'); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                ObservableWrapper.subscribe(eventBus, (ev) => { | 
					
						
							|  |  |  |                  if (ev.startsWith('canReuse')) { | 
					
						
							|  |  |  |                    completer.resolve(true); | 
					
						
							|  |  |  |                  } | 
					
						
							|  |  |  |                }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                log = ''; | 
					
						
							|  |  |  |                return rtr.navigate('/reuse-hooks/2'); | 
					
						
							|  |  |  |              }) | 
					
						
							|  |  |  |              .then((_) => { | 
					
						
							|  |  |  |                expect(log).toEqual('canReuse: /reuse-hooks/1 -> /reuse-hooks/2;' + | 
					
						
							|  |  |  |                                    'onReuse: /reuse-hooks/1 -> /reuse-hooks/2;'); | 
					
						
							|  |  |  |                async.done(); | 
					
						
							|  |  |  |              }); | 
					
						
							|  |  |  |        })); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('should not run reuse hooks when not reusing', inject([AsyncTestCompleter], (async) => { | 
					
						
							|  |  |  |          compile() | 
					
						
							|  |  |  |              .then((_) => rtr.config({'path': '/...', 'component': LifecycleCmp})) | 
					
						
							|  |  |  |              .then((_) => rtr.navigate('/reuse-hooks/1')) | 
					
						
							|  |  |  |              .then((_) => { | 
					
						
							|  |  |  |                expect(log).toEqual('canActivate: null -> /reuse-hooks/1;' + | 
					
						
							|  |  |  |                                    'onActivate: null -> /reuse-hooks/1;'); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                ObservableWrapper.subscribe(eventBus, (ev) => { | 
					
						
							|  |  |  |                  if (ev.startsWith('canReuse')) { | 
					
						
							|  |  |  |                    completer.resolve(false); | 
					
						
							|  |  |  |                  } | 
					
						
							|  |  |  |                }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                log = ''; | 
					
						
							|  |  |  |                return rtr.navigate('/reuse-hooks/2'); | 
					
						
							|  |  |  |              }) | 
					
						
							|  |  |  |              .then((_) => { | 
					
						
							|  |  |  |                expect(log).toEqual('canReuse: /reuse-hooks/1 -> /reuse-hooks/2;' + | 
					
						
							|  |  |  |                                    'canActivate: /reuse-hooks/1 -> /reuse-hooks/2;' + | 
					
						
							|  |  |  |                                    'canDeactivate: /reuse-hooks/1 -> /reuse-hooks/2;' + | 
					
						
							|  |  |  |                                    'onDeactivate: /reuse-hooks/1 -> /reuse-hooks/2;' + | 
					
						
							|  |  |  |                                    'onActivate: /reuse-hooks/1 -> /reuse-hooks/2;'); | 
					
						
							|  |  |  |                async.done(); | 
					
						
							|  |  |  |              }); | 
					
						
							|  |  |  |        })); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-05-29 14:58:41 -07:00
										 |  |  |     describe('when clicked', () => { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       var clickOnElement = function(view) { | 
					
						
							| 
									
										
										
										
											2015-06-26 16:04:19 -07:00
										 |  |  |         var anchorEl = rootTC.componentViewChildren[0].nativeElement; | 
					
						
							| 
									
										
										
										
											2015-05-29 14:58:41 -07:00
										 |  |  |         var dispatchedEvent = DOM.createMouseEvent('click'); | 
					
						
							|  |  |  |         DOM.dispatchEvent(anchorEl, dispatchedEvent); | 
					
						
							|  |  |  |         return dispatchedEvent; | 
					
						
							|  |  |  |       }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       it('should navigate to link hrefs without params', inject([AsyncTestCompleter], (async) => { | 
					
						
							| 
									
										
										
										
											2015-06-30 13:18:51 -07:00
										 |  |  |            compile('<a href="hello" [router-link]="[\'./user\']"></a>') | 
					
						
							| 
									
										
										
										
											2015-05-29 14:58:41 -07:00
										 |  |  |                .then((_) => rtr.config({'path': '/user', 'component': UserCmp, 'as': 'user'})) | 
					
						
							|  |  |  |                .then((_) => rtr.navigate('/a/b')) | 
					
						
							|  |  |  |                .then((_) => { | 
					
						
							| 
									
										
										
										
											2015-06-26 16:04:19 -07:00
										 |  |  |                  rootTC.detectChanges(); | 
					
						
							| 
									
										
										
										
											2015-05-29 14:58:41 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-06-26 16:04:19 -07:00
										 |  |  |                  var dispatchedEvent = clickOnElement(rootTC); | 
					
						
							| 
									
										
										
										
											2015-05-29 14:58:41 -07:00
										 |  |  |                  expect(dispatchedEvent.defaultPrevented || !dispatchedEvent.returnValue) | 
					
						
							|  |  |  |                      .toBe(true); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                  // router navigation is async.
 | 
					
						
							|  |  |  |                  rtr.subscribe((_) => { | 
					
						
							|  |  |  |                    expect(location.urlChanges).toEqual(['/user']); | 
					
						
							|  |  |  |                    async.done(); | 
					
						
							|  |  |  |                  }); | 
					
						
							|  |  |  |                }); | 
					
						
							|  |  |  |          })); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       it('should navigate to link hrefs in presence of base href', | 
					
						
							|  |  |  |          inject([AsyncTestCompleter], (async) => { | 
					
						
							|  |  |  |            location.setBaseHref('/base'); | 
					
						
							| 
									
										
										
										
											2015-06-30 13:18:51 -07:00
										 |  |  |            compile('<a href="hello" [router-link]="[\'./user\']"></a>') | 
					
						
							| 
									
										
										
										
											2015-05-29 14:58:41 -07:00
										 |  |  |                .then((_) => rtr.config({'path': '/user', 'component': UserCmp, 'as': 'user'})) | 
					
						
							|  |  |  |                .then((_) => rtr.navigate('/a/b')) | 
					
						
							|  |  |  |                .then((_) => { | 
					
						
							| 
									
										
										
										
											2015-06-26 16:04:19 -07:00
										 |  |  |                  rootTC.detectChanges(); | 
					
						
							| 
									
										
										
										
											2015-05-29 14:58:41 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-06-26 16:04:19 -07:00
										 |  |  |                  var dispatchedEvent = clickOnElement(rootTC); | 
					
						
							| 
									
										
										
										
											2015-05-29 14:58:41 -07:00
										 |  |  |                  expect(dispatchedEvent.defaultPrevented || !dispatchedEvent.returnValue) | 
					
						
							|  |  |  |                      .toBe(true); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                  // router navigation is async.
 | 
					
						
							|  |  |  |                  rtr.subscribe((_) => { | 
					
						
							|  |  |  |                    expect(location.urlChanges).toEqual(['/base/user']); | 
					
						
							|  |  |  |                    async.done(); | 
					
						
							|  |  |  |                  }); | 
					
						
							|  |  |  |                }); | 
					
						
							|  |  |  |          })); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @Component({selector: 'hello-cmp'}) | 
					
						
							|  |  |  | @View({template: "{{greeting}}"}) | 
					
						
							|  |  |  | class HelloCmp { | 
					
						
							|  |  |  |   greeting: string; | 
					
						
							|  |  |  |   constructor() { this.greeting = "hello"; } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @Component({selector: 'a-cmp'}) | 
					
						
							|  |  |  | @View({template: "A"}) | 
					
						
							|  |  |  | class A { | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @Component({selector: 'b-cmp'}) | 
					
						
							|  |  |  | @View({template: "B"}) | 
					
						
							|  |  |  | class B { | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @Component({selector: 'user-cmp'}) | 
					
						
							|  |  |  | @View({template: "hello {{user}}"}) | 
					
						
							|  |  |  | class UserCmp { | 
					
						
							|  |  |  |   user: string; | 
					
						
							|  |  |  |   constructor(params: RouteParams) { this.user = params.get('name'); } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-07-06 17:41:15 -07:00
										 |  |  | @Component({selector: 'page-cmp'}) | 
					
						
							|  |  |  | @View({ | 
					
						
							|  |  |  |   template: | 
					
						
							|  |  |  |       `page #{{pageNumber}} | <a href="hello" [router-link]="[\'../page\', {number: nextPage}]">next</a>`, | 
					
						
							|  |  |  |   directives: [RouterLink] | 
					
						
							|  |  |  | }) | 
					
						
							|  |  |  | class SiblingPageCmp { | 
					
						
							|  |  |  |   pageNumber: number; | 
					
						
							|  |  |  |   nextPage: number; | 
					
						
							|  |  |  |   constructor(params: RouteParams) { | 
					
						
							|  |  |  |     this.pageNumber = NumberWrapper.parseInt(params.get('number'), 10); | 
					
						
							|  |  |  |     this.nextPage = this.pageNumber + 1; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @Component({selector: 'book-cmp'}) | 
					
						
							|  |  |  | @View({ | 
					
						
							|  |  |  |   template: `<a href="hello" [router-link]="[\'./page\', {number: 100}]">{{title}}</a> |
 | 
					
						
							|  |  |  |     <router-outlet></router-outlet>`, | 
					
						
							|  |  |  |   directives: [RouterLink, RouterOutlet] | 
					
						
							|  |  |  | }) | 
					
						
							|  |  |  | @RouteConfig([{path: '/page/:number', component: SiblingPageCmp, 'as': 'page'}]) | 
					
						
							|  |  |  | class BookCmp { | 
					
						
							|  |  |  |   title: string; | 
					
						
							|  |  |  |   constructor(params: RouteParams) { this.title = params.get('title'); } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-05-29 14:58:41 -07:00
										 |  |  | @Component({selector: 'parent-cmp'}) | 
					
						
							|  |  |  | @View({template: "inner { <router-outlet></router-outlet> }", directives: [RouterOutlet]}) | 
					
						
							|  |  |  | @RouteConfig([{path: '/b', component: HelloCmp}]) | 
					
						
							|  |  |  | class ParentCmp { | 
					
						
							|  |  |  |   constructor() {} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @Component({selector: 'team-cmp'}) | 
					
						
							|  |  |  | @View({template: "team {{id}} { <router-outlet></router-outlet> }", directives: [RouterOutlet]}) | 
					
						
							|  |  |  | @RouteConfig([{path: '/user/:name', component: UserCmp}]) | 
					
						
							|  |  |  | class TeamCmp { | 
					
						
							|  |  |  |   id: string; | 
					
						
							|  |  |  |   constructor(params: RouteParams) { | 
					
						
							|  |  |  |     this.id = params.get('id'); | 
					
						
							| 
									
										
										
										
											2015-07-07 15:44:29 -07:00
										 |  |  |     cmpInstanceCount += 1; | 
					
						
							| 
									
										
										
										
											2015-05-29 14:58:41 -07:00
										 |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @Component({selector: 'my-comp'}) | 
					
						
							|  |  |  | class MyComp { | 
					
						
							|  |  |  |   name; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2015-07-07 15:44:29 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | function logHook(name: string, next: Instruction, prev: Instruction) { | 
					
						
							|  |  |  |   var message = name + ': ' + (isPresent(prev) ? prev.accumulatedUrl : 'null') + ' -> ' + | 
					
						
							|  |  |  |                 (isPresent(next) ? next.accumulatedUrl : 'null') + ';'; | 
					
						
							|  |  |  |   log += message; | 
					
						
							|  |  |  |   ObservableWrapper.callNext(eventBus, message); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @Component({selector: 'activate-cmp'}) | 
					
						
							|  |  |  | @View({template: 'activate cmp'}) | 
					
						
							|  |  |  | class ActivateCmp implements OnActivate { | 
					
						
							|  |  |  |   onActivate(next: Instruction, prev: Instruction) { logHook('activate', next, prev); } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @Component({selector: 'parent-activate-cmp'}) | 
					
						
							|  |  |  | @View({template: `parent {<router-outlet></router-outlet>}`, directives: [RouterOutlet]}) | 
					
						
							|  |  |  | @RouteConfig([{path: '/child-activate', component: ActivateCmp}]) | 
					
						
							|  |  |  | class ParentActivateCmp implements OnActivate { | 
					
						
							|  |  |  |   onActivate(next: Instruction, prev: Instruction): Promise<any> { | 
					
						
							|  |  |  |     completer = PromiseWrapper.completer(); | 
					
						
							|  |  |  |     logHook('parent activate', next, prev); | 
					
						
							|  |  |  |     return completer.promise; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @Component({selector: 'deactivate-cmp'}) | 
					
						
							|  |  |  | @View({template: 'deactivate cmp'}) | 
					
						
							|  |  |  | class DeactivateCmp implements OnDeactivate { | 
					
						
							|  |  |  |   onDeactivate(next: Instruction, prev: Instruction) { logHook('deactivate', next, prev); } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @Component({selector: 'deactivate-cmp'}) | 
					
						
							|  |  |  | @View({template: 'deactivate cmp'}) | 
					
						
							|  |  |  | class WaitDeactivateCmp implements OnDeactivate { | 
					
						
							|  |  |  |   onDeactivate(next: Instruction, prev: Instruction): Promise<any> { | 
					
						
							|  |  |  |     completer = PromiseWrapper.completer(); | 
					
						
							|  |  |  |     logHook('deactivate', next, prev); | 
					
						
							|  |  |  |     return completer.promise; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @Component({selector: 'parent-deactivate-cmp'}) | 
					
						
							|  |  |  | @View({template: `parent {<router-outlet></router-outlet>}`, directives: [RouterOutlet]}) | 
					
						
							|  |  |  | @RouteConfig([{path: '/child-deactivate', component: WaitDeactivateCmp}]) | 
					
						
							|  |  |  | class ParentDeactivateCmp implements OnDeactivate { | 
					
						
							|  |  |  |   onDeactivate(next: Instruction, prev: Instruction) { logHook('parent deactivate', next, prev); } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @Component({selector: 'reuse-cmp'}) | 
					
						
							|  |  |  | @View({template: `reuse {<router-outlet></router-outlet>}`, directives: [RouterOutlet]}) | 
					
						
							|  |  |  | @RouteConfig([{path: '/a', component: A}, {path: '/b', component: B}]) | 
					
						
							|  |  |  | class ReuseCmp implements OnReuse, CanReuse { | 
					
						
							|  |  |  |   constructor() { cmpInstanceCount += 1; } | 
					
						
							|  |  |  |   canReuse(next: Instruction, prev: Instruction) { return true; } | 
					
						
							|  |  |  |   onReuse(next: Instruction, prev: Instruction) { logHook('reuse', next, prev); } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @Component({selector: 'never-reuse-cmp'}) | 
					
						
							|  |  |  | @View({template: `reuse {<router-outlet></router-outlet>}`, directives: [RouterOutlet]}) | 
					
						
							|  |  |  | @RouteConfig([{path: '/a', component: A}, {path: '/b', component: B}]) | 
					
						
							|  |  |  | class NeverReuseCmp implements OnReuse, CanReuse { | 
					
						
							|  |  |  |   constructor() { cmpInstanceCount += 1; } | 
					
						
							|  |  |  |   canReuse(next: Instruction, prev: Instruction) { return false; } | 
					
						
							|  |  |  |   onReuse(next: Instruction, prev: Instruction) { logHook('reuse', next, prev); } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @Component({selector: 'can-activate-cmp'}) | 
					
						
							|  |  |  | @View({template: `canActivate {<router-outlet></router-outlet>}`, directives: [RouterOutlet]}) | 
					
						
							|  |  |  | @RouteConfig([{path: '/a', component: A}, {path: '/b', component: B}]) | 
					
						
							|  |  |  | @CanActivate(CanActivateCmp.canActivate) | 
					
						
							|  |  |  | class CanActivateCmp { | 
					
						
							|  |  |  |   static canActivate(next: Instruction, prev: Instruction) { | 
					
						
							|  |  |  |     completer = PromiseWrapper.completer(); | 
					
						
							|  |  |  |     logHook('canActivate', next, prev); | 
					
						
							|  |  |  |     return completer.promise; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @Component({selector: 'can-deactivate-cmp'}) | 
					
						
							|  |  |  | @View({template: `canDeactivate {<router-outlet></router-outlet>}`, directives: [RouterOutlet]}) | 
					
						
							|  |  |  | @RouteConfig([{path: '/a', component: A}, {path: '/b', component: B}]) | 
					
						
							|  |  |  | class CanDeactivateCmp implements CanDeactivate { | 
					
						
							|  |  |  |   canDeactivate(next: Instruction, prev: Instruction) { | 
					
						
							|  |  |  |     completer = PromiseWrapper.completer(); | 
					
						
							|  |  |  |     logHook('canDeactivate', next, prev); | 
					
						
							|  |  |  |     return completer.promise; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @Component({selector: 'all-hooks-child-cmp'}) | 
					
						
							|  |  |  | @View({template: `child`}) | 
					
						
							|  |  |  | @CanActivate(AllHooksChildCmp.canActivate) | 
					
						
							|  |  |  | class AllHooksChildCmp implements CanDeactivate, OnDeactivate, OnActivate { | 
					
						
							|  |  |  |   canDeactivate(next: Instruction, prev: Instruction) { | 
					
						
							|  |  |  |     logHook('canDeactivate child', next, prev); | 
					
						
							|  |  |  |     return true; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   onDeactivate(next: Instruction, prev: Instruction) { logHook('onDeactivate child', next, prev); } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   static canActivate(next: Instruction, prev: Instruction) { | 
					
						
							|  |  |  |     logHook('canActivate child', next, prev); | 
					
						
							|  |  |  |     return true; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   onActivate(next: Instruction, prev: Instruction) { logHook('onActivate child', next, prev); } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @Component({selector: 'all-hooks-parent-cmp'}) | 
					
						
							|  |  |  | @View({template: `<router-outlet></router-outlet>`, directives: [RouterOutlet]}) | 
					
						
							|  |  |  | @RouteConfig([{path: '/child', component: AllHooksChildCmp}]) | 
					
						
							|  |  |  | @CanActivate(AllHooksParentCmp.canActivate) | 
					
						
							|  |  |  | class AllHooksParentCmp implements CanDeactivate, OnDeactivate, OnActivate { | 
					
						
							|  |  |  |   canDeactivate(next: Instruction, prev: Instruction) { | 
					
						
							|  |  |  |     logHook('canDeactivate parent', next, prev); | 
					
						
							|  |  |  |     return true; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   onDeactivate(next: Instruction, prev: Instruction) { logHook('onDeactivate parent', next, prev); } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   static canActivate(next: Instruction, prev: Instruction) { | 
					
						
							|  |  |  |     logHook('canActivate parent', next, prev); | 
					
						
							|  |  |  |     return true; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   onActivate(next: Instruction, prev: Instruction) { logHook('onActivate parent', next, prev); } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @Component({selector: 'reuse-hooks-cmp'}) | 
					
						
							|  |  |  | @View({template: 'reuse hooks cmp'}) | 
					
						
							|  |  |  | @CanActivate(ReuseHooksCmp.canActivate) | 
					
						
							|  |  |  | class ReuseHooksCmp implements OnActivate, OnReuse, OnDeactivate, CanReuse, CanDeactivate { | 
					
						
							|  |  |  |   canReuse(next: Instruction, prev: Instruction): Promise<any> { | 
					
						
							|  |  |  |     completer = PromiseWrapper.completer(); | 
					
						
							|  |  |  |     logHook('canReuse', next, prev); | 
					
						
							|  |  |  |     return completer.promise; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   onReuse(next: Instruction, prev: Instruction) { logHook('onReuse', next, prev); } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   canDeactivate(next: Instruction, prev: Instruction) { | 
					
						
							|  |  |  |     logHook('canDeactivate', next, prev); | 
					
						
							|  |  |  |     return true; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   onDeactivate(next: Instruction, prev: Instruction) { logHook('onDeactivate', next, prev); } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   static canActivate(next: Instruction, prev: Instruction) { | 
					
						
							|  |  |  |     logHook('canActivate', next, prev); | 
					
						
							|  |  |  |     return true; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   onActivate(next: Instruction, prev: Instruction) { logHook('onActivate', next, prev); } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @Component({selector: 'lifecycle-cmp'}) | 
					
						
							|  |  |  | @View({template: `<router-outlet></router-outlet>`, directives: [RouterOutlet]}) | 
					
						
							|  |  |  | @RouteConfig([ | 
					
						
							|  |  |  |   {path: '/a', component: A}, | 
					
						
							|  |  |  |   {path: '/on-activate', component: ActivateCmp}, | 
					
						
							|  |  |  |   {path: '/parent-activate/...', component: ParentActivateCmp}, | 
					
						
							|  |  |  |   {path: '/on-deactivate', component: DeactivateCmp}, | 
					
						
							|  |  |  |   {path: '/parent-deactivate/...', component: ParentDeactivateCmp}, | 
					
						
							|  |  |  |   {path: '/on-reuse/:number/...', component: ReuseCmp}, | 
					
						
							|  |  |  |   {path: '/never-reuse/:number/...', component: NeverReuseCmp}, | 
					
						
							|  |  |  |   {path: '/can-activate/...', component: CanActivateCmp}, | 
					
						
							|  |  |  |   {path: '/can-deactivate/...', component: CanDeactivateCmp}, | 
					
						
							|  |  |  |   {path: '/activation-hooks/...', component: AllHooksParentCmp}, | 
					
						
							|  |  |  |   {path: '/reuse-hooks/:number', component: ReuseHooksCmp} | 
					
						
							|  |  |  | ]) | 
					
						
							|  |  |  | class LifecycleCmp { | 
					
						
							|  |  |  | } |