Skip to content

Commit

Permalink
fix(router): Fix relative link generation from empty path components (a…
Browse files Browse the repository at this point in the history
…ngular#37446)

Partial resubmit of angular#26243
Fixes incorrect url tree generation for empty path components with children.
Adds a test to demonstrate the failure of createUrlTree for those routes.
Fixes angular#13011
Fixes angular#35687

PR Close angular#37446
  • Loading branch information
atscott authored and profanis committed Sep 5, 2020
1 parent 6970b86 commit 2298b87
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 4 deletions.
7 changes: 6 additions & 1 deletion packages/router/src/create_url_tree.ts
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,12 @@ function findStartingPosition(nav: Navigation, tree: UrlTree, route: ActivatedRo
}

if (route.snapshot._lastPathIndex === -1) {
return new Position(route.snapshot._urlSegment, true, 0);
const segmentGroup = route.snapshot._urlSegment;
// Pathless ActivatedRoute has _lastPathIndex === -1 but should not process children
// see issue #26224, #13011, #35687
// However, if the ActivatedRoute is the root we should process children like above.
const processChildren = segmentGroup === tree.root;
return new Position(segmentGroup, processChildren, 0);
}

const modifier = isMatrixParams(nav.commands[0]) ? 0 : 1;
Expand Down
29 changes: 26 additions & 3 deletions packages/router/test/create_url_tree.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import {BehaviorSubject} from 'rxjs';
import {createUrlTree} from '../src/create_url_tree';
import {ActivatedRoute, ActivatedRouteSnapshot, advanceActivatedRoute} from '../src/router_state';
import {Params, PRIMARY_OUTLET} from '../src/shared';
import {DefaultUrlSerializer, UrlSegmentGroup, UrlTree} from '../src/url_tree';
import {DefaultUrlSerializer, UrlSegment, UrlSegmentGroup, UrlTree} from '../src/url_tree';

describe('createUrlTree', () => {
const serializer = new DefaultUrlSerializer();
Expand Down Expand Up @@ -240,6 +240,29 @@ describe('createUrlTree', () => {
const t = createRoot(p, [], {}, 'fragment');
expect(t.fragment).toEqual('fragment');
});

it('should support pathless route', () => {
const p = serializer.parse('/a');
const t = create(p.root.children[PRIMARY_OUTLET], -1, p, ['b']);
expect(serializer.serialize(t)).toEqual('/b');
});

it('should support pathless route with ../ at root', () => {
const p = serializer.parse('/a');
const t = create(p.root.children[PRIMARY_OUTLET], -1, p, ['../b']);
expect(serializer.serialize(t)).toEqual('/b');
});

it('should support pathless child of pathless root', () => {
// i.e. routes = {path: '', loadChildren: () => import('child')...}
// forChild: {path: '', component: Comp}
const p = serializer.parse('');
const empty = new UrlSegmentGroup([], {});
p.root.children[PRIMARY_OUTLET] = empty;
empty.parent = p.root;
const t = create(empty, -1, p, ['lazy']);
expect(serializer.serialize(t)).toEqual('/lazy');
});
});

function createRoot(tree: UrlTree, commands: any[], queryParams?: Params, fragment?: string) {
Expand All @@ -260,8 +283,8 @@ function create(
expect(segment).toBeDefined();
}
const s = new (ActivatedRouteSnapshot as any)(
[], <any>{}, <any>{}, '', <any>{}, PRIMARY_OUTLET, 'someComponent', null, <any>segment,
startIndex, <any>null);
segment.segments, <any>{}, <any>{}, '', <any>{}, PRIMARY_OUTLET, 'someComponent', null,
<any>segment, startIndex, <any>null);
const a = new (ActivatedRoute as any)(
new BehaviorSubject(null!), new BehaviorSubject(null!), new BehaviorSubject(null!),
new BehaviorSubject(null!), new BehaviorSubject(null!), PRIMARY_OUTLET, 'someComponent', s);
Expand Down

0 comments on commit 2298b87

Please sign in to comment.