fix(router): handle lastPathIndex of empty-path routes
This commit is contained in:
parent
83bc5c97ef
commit
7a4f6621ed
|
@ -116,7 +116,8 @@ function processPathsWithParamsAgainstRoute(
|
||||||
const snapshot = new ActivatedRouteSnapshot(
|
const snapshot = new ActivatedRouteSnapshot(
|
||||||
paths, Object.freeze(merge(inherited.allParams, params)),
|
paths, Object.freeze(merge(inherited.allParams, params)),
|
||||||
merge(inherited.allData, getData(route)), outlet, route.component, route,
|
merge(inherited.allData, getData(route)), outlet, route.component, route,
|
||||||
getSourceSegment(rawSegment), getPathIndexShift(rawSegment) - 1, newInheritedResolve);
|
getSourceSegment(rawSegment), getPathIndexShift(rawSegment) + paths.length,
|
||||||
|
newInheritedResolve);
|
||||||
return [new TreeNode<ActivatedRouteSnapshot>(snapshot, [])];
|
return [new TreeNode<ActivatedRouteSnapshot>(snapshot, [])];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -130,7 +131,7 @@ function processPathsWithParamsAgainstRoute(
|
||||||
const snapshot = new ActivatedRouteSnapshot(
|
const snapshot = new ActivatedRouteSnapshot(
|
||||||
consumedPaths, Object.freeze(merge(inherited.allParams, parameters)),
|
consumedPaths, Object.freeze(merge(inherited.allParams, parameters)),
|
||||||
merge(inherited.allData, getData(route)), outlet, route.component, route,
|
merge(inherited.allData, getData(route)), outlet, route.component, route,
|
||||||
getSourceSegment(rawSegment), getPathIndexShift(rawSegment) + pathIndex + lastChild - 1,
|
getSourceSegment(rawSegment), getPathIndexShift(rawSegment) + consumedPaths.length,
|
||||||
newInheritedResolve);
|
newInheritedResolve);
|
||||||
|
|
||||||
const newInherited = route.component ?
|
const newInherited = route.component ?
|
||||||
|
@ -227,12 +228,12 @@ function getSourceSegment(segment: UrlSegment): UrlSegment {
|
||||||
|
|
||||||
function getPathIndexShift(segment: UrlSegment): number {
|
function getPathIndexShift(segment: UrlSegment): number {
|
||||||
let s = segment;
|
let s = segment;
|
||||||
let res = 0;
|
let res = (s._pathIndexShift ? s._pathIndexShift : 0);
|
||||||
while (s._sourceSegment) {
|
while (s._sourceSegment) {
|
||||||
s = s._sourceSegment;
|
s = s._sourceSegment;
|
||||||
res += segment._pathIndexShift;
|
res += (s._pathIndexShift ? s._pathIndexShift : 0);
|
||||||
}
|
}
|
||||||
return res;
|
return res - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
function split(
|
function split(
|
||||||
|
@ -245,7 +246,7 @@ function split(
|
||||||
createChildrenForEmptyPaths(
|
createChildrenForEmptyPaths(
|
||||||
segment, consumedPaths, config, new UrlSegment(slicedPath, segment.children)));
|
segment, consumedPaths, config, new UrlSegment(slicedPath, segment.children)));
|
||||||
s._sourceSegment = segment;
|
s._sourceSegment = segment;
|
||||||
s._pathIndexShift = 0;
|
s._pathIndexShift = consumedPaths.length;
|
||||||
return {segment: s, slicedPath: []};
|
return {segment: s, slicedPath: []};
|
||||||
|
|
||||||
} else if (slicedPath.length === 0 && containsEmptyPathMatches(segment, slicedPath, config)) {
|
} else if (slicedPath.length === 0 && containsEmptyPathMatches(segment, slicedPath, config)) {
|
||||||
|
@ -253,11 +254,14 @@ function split(
|
||||||
segment.pathsWithParams,
|
segment.pathsWithParams,
|
||||||
addEmptyPathsToChildrenIfNeeded(segment, slicedPath, config, segment.children));
|
addEmptyPathsToChildrenIfNeeded(segment, slicedPath, config, segment.children));
|
||||||
s._sourceSegment = segment;
|
s._sourceSegment = segment;
|
||||||
s._pathIndexShift = 0;
|
s._pathIndexShift = consumedPaths.length;
|
||||||
return {segment: s, slicedPath};
|
return {segment: s, slicedPath};
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
return {segment, slicedPath};
|
const s = new UrlSegment(segment.pathsWithParams, segment.children);
|
||||||
|
s._sourceSegment = segment;
|
||||||
|
s._pathIndexShift = consumedPaths.length;
|
||||||
|
return {segment: s, slicedPath};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,6 @@ import {DefaultUrlSerializer, UrlPathWithParams, UrlSegment, UrlTree} from '../s
|
||||||
describe('createUrlTree', () => {
|
describe('createUrlTree', () => {
|
||||||
const serializer = new DefaultUrlSerializer();
|
const serializer = new DefaultUrlSerializer();
|
||||||
|
|
||||||
|
|
||||||
it('should navigate to the root', () => {
|
it('should navigate to the root', () => {
|
||||||
const p = serializer.parse('/');
|
const p = serializer.parse('/');
|
||||||
const t = createRoot(p, ['/']);
|
const t = createRoot(p, ['/']);
|
||||||
|
@ -132,12 +131,6 @@ describe('createUrlTree', () => {
|
||||||
expect(serializer.serialize(t)).toEqual('/a/c2');
|
expect(serializer.serialize(t)).toEqual('/a/c2');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should work when given ../', () => {
|
|
||||||
const p = serializer.parse('/a/c');
|
|
||||||
const t = create(p.root.children[PRIMARY_OUTLET], 1, p, ['../', 'c2']);
|
|
||||||
expect(serializer.serialize(t)).toEqual('/a/c2');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should support setting matrix params', () => {
|
it('should support setting matrix params', () => {
|
||||||
const p = serializer.parse('/a/(c//left:cp)(left:ap)');
|
const p = serializer.parse('/a/(c//left:cp)(left:ap)');
|
||||||
const t = create(p.root.children[PRIMARY_OUTLET], 0, p, ['../', {x: 5}]);
|
const t = create(p.root.children[PRIMARY_OUTLET], 0, p, ['../', {x: 5}]);
|
||||||
|
@ -152,10 +145,22 @@ describe('createUrlTree', () => {
|
||||||
expect(serializer.serialize(t)).toEqual('/q2(left:ap)');
|
expect(serializer.serialize(t)).toEqual('/q2(left:ap)');
|
||||||
});
|
});
|
||||||
|
|
||||||
xit('should navigate to the root', () => {
|
it('should navigate to the root', () => {
|
||||||
const p = serializer.parse('/a/c');
|
const p = serializer.parse('/a/c');
|
||||||
const t = create(p.root.children[PRIMARY_OUTLET], 0, p, ['../']);
|
const t = create(p.root.children[PRIMARY_OUTLET], 0, p, ['../']);
|
||||||
expect(serializer.serialize(t)).toEqual('');
|
expect(serializer.serialize(t)).toEqual('/');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should work with ../ when absolute url', () => {
|
||||||
|
const p = serializer.parse('/a/c');
|
||||||
|
const t = create(p.root.children[PRIMARY_OUTLET], 1, p, ['../', 'c2']);
|
||||||
|
expect(serializer.serialize(t)).toEqual('/a/c2');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should work with position = -1', () => {
|
||||||
|
const p = serializer.parse('/');
|
||||||
|
const t = create(p.root, -1, p, ['11']);
|
||||||
|
expect(serializer.serialize(t)).toEqual('/11');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should throw when too many ..', () => {
|
it('should throw when too many ..', () => {
|
||||||
|
@ -196,6 +201,7 @@ describe('createUrlTree', () => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
function createRoot(tree: UrlTree, commands: any[], queryParams?: Params, fragment?: string) {
|
function createRoot(tree: UrlTree, commands: any[], queryParams?: Params, fragment?: string) {
|
||||||
const s = new ActivatedRouteSnapshot(
|
const s = new ActivatedRouteSnapshot(
|
||||||
[], <any>{}, <any>{}, PRIMARY_OUTLET, 'someComponent', null, tree.root, -1, <any>null);
|
[], <any>{}, <any>{}, PRIMARY_OUTLET, 'someComponent', null, tree.root, -1, <any>null);
|
||||||
|
|
|
@ -81,6 +81,28 @@ describe('recognize', () => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should set url segment and index properly (wildcard)', () => {
|
||||||
|
const url = tree('a/b/c');
|
||||||
|
recognize(
|
||||||
|
RootComponent,
|
||||||
|
[
|
||||||
|
{path: 'a', component: ComponentA, children: [{path: '**', component: ComponentB}]},
|
||||||
|
],
|
||||||
|
url, 'a/b/c')
|
||||||
|
.subscribe((s: RouterStateSnapshot) => {
|
||||||
|
expect(s.root._urlSegment).toBe(url.root);
|
||||||
|
expect(s.root._lastPathIndex).toBe(-1);
|
||||||
|
|
||||||
|
const compA = s.firstChild(s.root);
|
||||||
|
expect(compA._urlSegment).toBe(url.root.children[PRIMARY_OUTLET]);
|
||||||
|
expect(compA._lastPathIndex).toBe(0);
|
||||||
|
|
||||||
|
const compC = s.firstChild(<any>compA);
|
||||||
|
expect(compC._urlSegment).toBe(url.root.children[PRIMARY_OUTLET]);
|
||||||
|
expect(compC._lastPathIndex).toBe(2);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
it('should match routes in the depth first order', () => {
|
it('should match routes in the depth first order', () => {
|
||||||
checkRecognize(
|
checkRecognize(
|
||||||
[
|
[
|
||||||
|
@ -357,6 +379,62 @@ describe('recognize', () => {
|
||||||
expect(c._lastPathIndex).toBe(0);
|
expect(c._lastPathIndex).toBe(0);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should set url segment and index properly when nested empty-path segments', () => {
|
||||||
|
const url = tree('a');
|
||||||
|
recognize(
|
||||||
|
RootComponent, [{
|
||||||
|
path: 'a',
|
||||||
|
children: [
|
||||||
|
{path: '', component: ComponentB, children: [{path: '', component: ComponentC}]}
|
||||||
|
]
|
||||||
|
}],
|
||||||
|
url, 'a')
|
||||||
|
.forEach((s: RouterStateSnapshot) => {
|
||||||
|
expect(s.root._urlSegment).toBe(url.root);
|
||||||
|
expect(s.root._lastPathIndex).toBe(-1);
|
||||||
|
|
||||||
|
const a = s.firstChild(s.root);
|
||||||
|
expect(a._urlSegment).toBe(url.root.children[PRIMARY_OUTLET]);
|
||||||
|
expect(a._lastPathIndex).toBe(0);
|
||||||
|
|
||||||
|
const b = s.firstChild(a);
|
||||||
|
expect(b._urlSegment).toBe(url.root.children[PRIMARY_OUTLET]);
|
||||||
|
expect(b._lastPathIndex).toBe(0);
|
||||||
|
|
||||||
|
const c = s.firstChild(b);
|
||||||
|
expect(c._urlSegment).toBe(url.root.children[PRIMARY_OUTLET]);
|
||||||
|
expect(c._lastPathIndex).toBe(0);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should set url segment and index properly when nested empty-path segments (2)', () => {
|
||||||
|
const url = tree('');
|
||||||
|
recognize(
|
||||||
|
RootComponent, [{
|
||||||
|
path: '',
|
||||||
|
children: [
|
||||||
|
{path: '', component: ComponentB, children: [{path: '', component: ComponentC}]}
|
||||||
|
]
|
||||||
|
}],
|
||||||
|
url, '')
|
||||||
|
.forEach((s: RouterStateSnapshot) => {
|
||||||
|
expect(s.root._urlSegment).toBe(url.root);
|
||||||
|
expect(s.root._lastPathIndex).toBe(-1);
|
||||||
|
|
||||||
|
const a = s.firstChild(s.root);
|
||||||
|
expect(a._urlSegment).toBe(url.root);
|
||||||
|
expect(a._lastPathIndex).toBe(-1);
|
||||||
|
|
||||||
|
const b = s.firstChild(a);
|
||||||
|
expect(b._urlSegment).toBe(url.root);
|
||||||
|
expect(b._lastPathIndex).toBe(-1);
|
||||||
|
|
||||||
|
const c = s.firstChild(b);
|
||||||
|
expect(c._urlSegment).toBe(url.root);
|
||||||
|
expect(c._lastPathIndex).toBe(-1);
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('aux split at the end (no right child)', () => {
|
describe('aux split at the end (no right child)', () => {
|
||||||
|
|
Loading…
Reference in New Issue