From 3af585c004a7785015d5a4af4640fc56365220ad Mon Sep 17 00:00:00 2001 From: Andrew Scott Date: Mon, 26 Oct 2020 20:38:28 -0700 Subject: [PATCH] fix(router): Ensure all outlets are used when commands have a prefix (#39456) When there is a primary outlet present in the outlets map and the object is also prefixed with some other commands, the current logic only uses the primary outlet and ignores the others. This change ensures that all outlets are respected at the segment level when prefixed with other commands. PR Close #39456 --- packages/router/src/create_url_tree.ts | 18 +++++++++--------- packages/router/test/create_url_tree.spec.ts | 4 ++-- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/packages/router/src/create_url_tree.ts b/packages/router/src/create_url_tree.ts index c7fcb31260..2a70e23e2c 100644 --- a/packages/router/src/create_url_tree.ts +++ b/packages/router/src/create_url_tree.ts @@ -186,13 +186,6 @@ function createPositionApplyingDoubleDots( return new Position(g, false, ci - dd); } -function getPath(command: any): any { - if (isCommandWithOutlets(command)) { - return command.outlets[PRIMARY_OUTLET]; - } - return `${command}`; -} - function getOutlets(commands: any[]): {[k: string]: any[]} { if (isCommandWithOutlets(commands[0])) { return commands[0].outlets; @@ -259,7 +252,14 @@ function prefixedWith(segmentGroup: UrlSegmentGroup, startIndex: number, command while (currentPathIndex < segmentGroup.segments.length) { if (currentCommandIndex >= commands.length) return noMatch; const path = segmentGroup.segments[currentPathIndex]; - const curr = getPath(commands[currentCommandIndex]); + const command = commands[currentCommandIndex]; + // Do not try to consume command as part of the prefixing if it has outlets because it can + // contain outlets other than the one being processed. Consuming the outlets command would + // result in other outlets being ignored. + if (isCommandWithOutlets(command)) { + break; + } + const curr = `${command}`; const next = currentCommandIndex < commands.length - 1 ? commands[currentCommandIndex + 1] : null; @@ -298,7 +298,7 @@ function createNewSegmentGroup( continue; } - const curr = getPath(command); + const curr = isCommandWithOutlets(command) ? command.outlets[PRIMARY_OUTLET] : `${command}`; const next = (i < commands.length - 1) ? commands[i + 1] : null; if (curr && next && isMatrixParams(next)) { paths.push(new UrlSegment(curr, stringify(next))); diff --git a/packages/router/test/create_url_tree.spec.ts b/packages/router/test/create_url_tree.spec.ts index 75e2564492..d51fa48d95 100644 --- a/packages/router/test/create_url_tree.spec.ts +++ b/packages/router/test/create_url_tree.spec.ts @@ -150,13 +150,13 @@ describe('createUrlTree', () => { expect(serializer.serialize(t)).toEqual('/parent/child'); }); - xit('should support updating secondary and primary outlets with prefix', () => { + it('should support updating secondary and primary outlets with prefix', () => { const p = serializer.parse('/parent/child'); const t = createRoot(p, ['parent', {outlets: {primary: 'child', secondary: 'popup'}}]); expect(serializer.serialize(t)).toEqual('/parent/(child//secondary:popup)'); }); - xit('should support updating two outlets at the same time relative to non-root segment', () => { + it('should support updating two outlets at the same time relative to non-root segment', () => { const p = serializer.parse('/parent/child'); const t = create( p.root.children[PRIMARY_OUTLET], 0 /* relativeTo: 'parent' */, p,