From 67c80fbb5eeff7071f55d03bc9812d02e61ebeee Mon Sep 17 00:00:00 2001 From: Tobias Bosch Date: Thu, 21 Apr 2016 11:17:49 -0700 Subject: [PATCH] fix(compiler): support string tokens with `.` inside. Closes #8178 --- .../@angular/router-deprecated/src/router.ts | 38 +++++++++------- .../test/integration/router_link_spec.ts | 45 +++++++++++++++++++ 2 files changed, 68 insertions(+), 15 deletions(-) diff --git a/modules/@angular/router-deprecated/src/router.ts b/modules/@angular/router-deprecated/src/router.ts index 7587686a21..62492b1da2 100644 --- a/modules/@angular/router-deprecated/src/router.ts +++ b/modules/@angular/router-deprecated/src/router.ts @@ -9,6 +9,7 @@ import {RouterOutlet} from './directives/router_outlet'; import {getCanActivateHook} from './lifecycle/route_lifecycle_reflector'; import {RouteDefinition} from './route_config/route_config_impl'; import {Injectable, Inject} from '@angular/core'; +import {DefaultInstruction} from "./instruction"; let _resolveToTrue = PromiseWrapper.resolve(true); let _resolveToFalse = PromiseWrapper.resolve(false); @@ -131,8 +132,9 @@ export class Router { */ isRouteActive(instruction: Instruction): boolean { var router: Router = this; + var currentInstruction = this.currentInstruction; - if (isBlank(this.currentInstruction)) { + if (isBlank(currentInstruction)) { return false; } @@ -142,22 +144,28 @@ export class Router { instruction = instruction.child; } - if (isBlank(instruction.component) || isBlank(this.currentInstruction.component) || - this.currentInstruction.component.routeName != instruction.component.routeName) { - return false; - } + let reason = true; - let paramEquals = true; + // check the instructions in depth + do { + if (isBlank(instruction.component) || isBlank(currentInstruction.component) || + currentInstruction.component.routeName != instruction.component.routeName) { + return false; + } + if (isPresent(instruction.component.params)) { + StringMapWrapper.forEach(instruction.component.params, (value, key) => { + if (currentInstruction.component.params[key] !== value) { + reason = false; + } + }); + } + currentInstruction = currentInstruction.child; + instruction = instruction.child; + } while (isPresent(currentInstruction) && isPresent(instruction) && + !(instruction instanceof DefaultInstruction) && reason); - if (isPresent(this.currentInstruction.component.params)) { - StringMapWrapper.forEach(instruction.component.params, (value, key) => { - if (this.currentInstruction.component.params[key] !== value) { - paramEquals = false; - } - }); - } - - return paramEquals; + // ignore DefaultInstruction + return reason && (isBlank(instruction) || instruction instanceof DefaultInstruction); } diff --git a/modules/@angular/router-deprecated/test/integration/router_link_spec.ts b/modules/@angular/router-deprecated/test/integration/router_link_spec.ts index 55d7b2cf11..edf1c79372 100644 --- a/modules/@angular/router-deprecated/test/integration/router_link_spec.ts +++ b/modules/@angular/router-deprecated/test/integration/router_link_spec.ts @@ -295,6 +295,51 @@ export function main() { router.navigateByUrl('/child-with-grandchild/grandchild?extra=0'); }); })); + + it('should not be added to links in other child routes', + inject([AsyncTestCompleter], (async) => { + router.config([ + new Route({path: '/child', component: HelloCmp, name: 'Child'}), + new Route({ + path: '/child-with-grandchild/...', + component: ParentCmp, + name: 'ChildWithGrandchild' + }), + new Route({ + path: '/child-with-other-grandchild/...', + component: ParentCmp, + name: 'ChildWithOtherGrandchild' + }) + ]) + .then((_) => compile(`Child + Better Child + Better Child + `)) + .then((_) => { + var element = fixture.debugElement.nativeElement; + + fixture.detectChanges(); + + var link1 = getDOM().querySelector(element, '.child-link'); + var link2 = getDOM().querySelector(element, '.child-with-grandchild-link'); + var link3 = getDOM().querySelector(element, '.child-with-other-grandchild-link'); + + expect(link1).not.toHaveCssClass('router-link-active'); + expect(link2).not.toHaveCssClass('router-link-active'); + expect(link3).not.toHaveCssClass('router-link-active'); + + router.subscribe((_) => { + fixture.detectChanges(); + + expect(link1).not.toHaveCssClass('router-link-active'); + expect(link2).toHaveCssClass('router-link-active'); + expect(link3).not.toHaveCssClass('router-link-active'); + + async.done(); + }); + router.navigateByUrl('/child-with-grandchild/grandchild?extra=0'); + }); + })); }); describe('when clicked', () => {