mirror of
https://github.com/angular/angular.git
synced 2026-09-14 13:54:52 +08:00
refactor(router): Remove legacy url creation code (#49360)
This commit removes code for the old way of creating a `UrlTree`. PR Close #49360
This commit is contained in:
committed by
Pawel Kozlowski
parent
60d71484fd
commit
ff9d3b0f02
@@ -137,12 +137,6 @@
|
||||
{
|
||||
"name": "Console"
|
||||
},
|
||||
{
|
||||
"name": "CreateUrlTreeStrategy"
|
||||
},
|
||||
{
|
||||
"name": "CreateUrlTreeUsingSnapshot"
|
||||
},
|
||||
{
|
||||
"name": "DEFAULT_APP_ID"
|
||||
},
|
||||
@@ -884,6 +878,9 @@
|
||||
{
|
||||
"name": "absoluteRedirect"
|
||||
},
|
||||
{
|
||||
"name": "addEmptyPathsToChildrenIfNeeded"
|
||||
},
|
||||
{
|
||||
"name": "addPropertyAlias"
|
||||
},
|
||||
@@ -1001,6 +998,9 @@
|
||||
{
|
||||
"name": "convertToParamMap"
|
||||
},
|
||||
{
|
||||
"name": "createChildrenForEmptyPaths"
|
||||
},
|
||||
{
|
||||
"name": "createContainerRef"
|
||||
},
|
||||
@@ -1358,9 +1358,6 @@
|
||||
{
|
||||
"name": "getParentInjectorView"
|
||||
},
|
||||
{
|
||||
"name": "getPathIndexShift"
|
||||
},
|
||||
{
|
||||
"name": "getPipeDef"
|
||||
},
|
||||
@@ -1382,9 +1379,6 @@
|
||||
{
|
||||
"name": "getSimpleChangesStore"
|
||||
},
|
||||
{
|
||||
"name": "getSourceSegmentGroup"
|
||||
},
|
||||
{
|
||||
"name": "getSymbolIterator"
|
||||
},
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
import {ɵRuntimeError as RuntimeError} from '@angular/core';
|
||||
|
||||
import {RuntimeErrorCode} from './errors';
|
||||
import {ActivatedRoute, ActivatedRouteSnapshot} from './router_state';
|
||||
import {ActivatedRouteSnapshot} from './router_state';
|
||||
import {Params, PRIMARY_OUTLET} from './shared';
|
||||
import {createRoot, squashSegmentGroup, UrlSegment, UrlSegmentGroup, UrlTree} from './url_tree';
|
||||
import {last, shallowEqual} from './utils/collection';
|
||||
@@ -123,38 +123,6 @@ export function createUrlTreeFromSegmentGroup(
|
||||
return tree(root, position.segmentGroup, newSegmentGroup, queryParams, fragment);
|
||||
}
|
||||
|
||||
export function createUrlTree(
|
||||
route: ActivatedRoute, urlTree: UrlTree, commands: any[], queryParams: Params|null,
|
||||
fragment: string|null): UrlTree {
|
||||
if (commands.length === 0) {
|
||||
return tree(urlTree.root, urlTree.root, urlTree.root, queryParams, fragment);
|
||||
}
|
||||
|
||||
const nav = computeNavigation(commands);
|
||||
|
||||
if (nav.toRoot()) {
|
||||
return tree(urlTree.root, urlTree.root, new UrlSegmentGroup([], {}), queryParams, fragment);
|
||||
}
|
||||
|
||||
function createTreeUsingPathIndex(lastPathIndex: number) {
|
||||
const startingPosition =
|
||||
findStartingPosition(nav, urlTree, route.snapshot?._urlSegment, lastPathIndex);
|
||||
|
||||
const segmentGroup = startingPosition.processChildren ?
|
||||
updateSegmentGroupChildren(
|
||||
startingPosition.segmentGroup, startingPosition.index, nav.commands) :
|
||||
updateSegmentGroup(startingPosition.segmentGroup, startingPosition.index, nav.commands);
|
||||
return tree(urlTree.root, startingPosition.segmentGroup, segmentGroup, queryParams, fragment);
|
||||
}
|
||||
// Note: The types should disallow `snapshot` from being `undefined` but due to test mocks, this
|
||||
// may be the case. Since we try to access it at an earlier point before the refactor to add the
|
||||
// warning for `relativeLinkResolution: 'legacy'`, this may cause failures in tests where it
|
||||
// didn't before.
|
||||
const result = createTreeUsingPathIndex(route.snapshot?._lastPathIndex);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
function isMatrixParams(command: any): boolean {
|
||||
return typeof command === 'object' && command != null && !command.outlets && !command.segmentPath;
|
||||
}
|
||||
@@ -309,26 +277,6 @@ function findStartingPositionForTargetGroup(
|
||||
return createPositionApplyingDoubleDots(target, index, nav.numberOfDoubleDots);
|
||||
}
|
||||
|
||||
function findStartingPosition(
|
||||
nav: Navigation, tree: UrlTree, segmentGroup: UrlSegmentGroup,
|
||||
lastPathIndex: number): Position {
|
||||
if (nav.isAbsolute) {
|
||||
return new Position(tree.root, true, 0);
|
||||
}
|
||||
|
||||
if (lastPathIndex === -1) {
|
||||
// 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;
|
||||
const index = lastPathIndex + modifier;
|
||||
return createPositionApplyingDoubleDots(segmentGroup, index, nav.numberOfDoubleDots);
|
||||
}
|
||||
|
||||
function createPositionApplyingDoubleDots(
|
||||
group: UrlSegmentGroup, index: number, numberOfDoubleDots: number): Position {
|
||||
let g = group;
|
||||
|
||||
@@ -1,78 +0,0 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google LLC All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {Injectable} from '@angular/core';
|
||||
|
||||
import {createSegmentGroupFromRoute, createUrlTree, createUrlTreeFromSegmentGroup} from './create_url_tree';
|
||||
import {ActivatedRoute, RouterState} from './router_state';
|
||||
import {Params} from './shared';
|
||||
import {UrlSegmentGroup, UrlTree} from './url_tree';
|
||||
|
||||
const NG_DEV_MODE = typeof ngDevMode === 'undefined' || ngDevMode;
|
||||
|
||||
@Injectable()
|
||||
export class LegacyCreateUrlTree implements CreateUrlTreeStrategy {
|
||||
createUrlTree(
|
||||
relativeTo: ActivatedRoute|null|undefined, currentState: RouterState, currentUrlTree: UrlTree,
|
||||
commands: any[], queryParams: Params|null, fragment: string|null): UrlTree {
|
||||
const a = relativeTo || currentState.root;
|
||||
const tree = createUrlTree(a, currentUrlTree, commands, queryParams, fragment);
|
||||
if (NG_DEV_MODE) {
|
||||
const treeFromSnapshotStrategy = new CreateUrlTreeUsingSnapshot().createUrlTree(
|
||||
relativeTo, currentState, currentUrlTree, commands, queryParams, fragment);
|
||||
if (treeFromSnapshotStrategy.toString() !== tree.toString()) {
|
||||
let warningString = `The navigation to ${tree.toString()} will instead go to ${
|
||||
treeFromSnapshotStrategy.toString()} in an upcoming version of Angular.`;
|
||||
if (!!relativeTo) {
|
||||
warningString += ' `relativeTo` might need to be removed from the `UrlCreationOptions`.';
|
||||
}
|
||||
tree._warnIfUsedForNavigation = warningString;
|
||||
}
|
||||
}
|
||||
return tree;
|
||||
}
|
||||
}
|
||||
|
||||
@Injectable()
|
||||
export class CreateUrlTreeUsingSnapshot implements CreateUrlTreeStrategy {
|
||||
createUrlTree(
|
||||
relativeTo: ActivatedRoute|null|undefined, currentState: RouterState, currentUrlTree: UrlTree,
|
||||
commands: any[], queryParams: Params|null, fragment: string|null): UrlTree {
|
||||
let relativeToUrlSegmentGroup: UrlSegmentGroup|undefined;
|
||||
try {
|
||||
const relativeToSnapshot = relativeTo ? relativeTo.snapshot : currentState.snapshot.root;
|
||||
relativeToUrlSegmentGroup = createSegmentGroupFromRoute(relativeToSnapshot);
|
||||
} catch (e: unknown) {
|
||||
// This is strictly for backwards compatibility with tests that create
|
||||
// invalid `ActivatedRoute` mocks.
|
||||
// Note: the difference between having this fallback for invalid `ActivatedRoute` setups and
|
||||
// just throwing is ~500 test failures. Fixing all of those tests by hand is not feasible at
|
||||
// the moment.
|
||||
if (typeof commands[0] !== 'string' || !commands[0].startsWith('/')) {
|
||||
// Navigations that were absolute in the old way of creating UrlTrees
|
||||
// would still work because they wouldn't attempt to match the
|
||||
// segments in the `ActivatedRoute` to the `currentUrlTree` but
|
||||
// instead just replace the root segment with the navigation result.
|
||||
// Non-absolute navigations would fail to apply the commands because
|
||||
// the logic could not find the segment to replace (so they'd act like there were no
|
||||
// commands).
|
||||
commands = [];
|
||||
}
|
||||
relativeToUrlSegmentGroup = currentUrlTree.root;
|
||||
}
|
||||
return createUrlTreeFromSegmentGroup(
|
||||
relativeToUrlSegmentGroup, commands, queryParams, fragment);
|
||||
}
|
||||
}
|
||||
|
||||
@Injectable({providedIn: 'root', useClass: CreateUrlTreeUsingSnapshot})
|
||||
export abstract class CreateUrlTreeStrategy {
|
||||
abstract createUrlTree(
|
||||
relativeTo: ActivatedRoute|null|undefined, currentState: RouterState, currentUrlTree: UrlTree,
|
||||
commands: any[], queryParams: Params|null, fragment: string|null): UrlTree;
|
||||
}
|
||||
@@ -70,8 +70,7 @@ export class Recognizer {
|
||||
// navigation, resulting in the router being out of sync with the browser.
|
||||
const root = new ActivatedRouteSnapshot(
|
||||
[], Object.freeze({}), Object.freeze({...this.urlTree.queryParams}),
|
||||
this.urlTree.fragment, {}, PRIMARY_OUTLET, this.rootComponentType, null,
|
||||
this.urlTree.root, -1, {});
|
||||
this.urlTree.fragment, {}, PRIMARY_OUTLET, this.rootComponentType, null, {});
|
||||
|
||||
const rootNode = new TreeNode<ActivatedRouteSnapshot>(root, children);
|
||||
const routeState = new RouterStateSnapshot(this.url, rootNode);
|
||||
@@ -177,11 +176,10 @@ export class Recognizer {
|
||||
|
||||
if (route.path === '**') {
|
||||
const params = segments.length > 0 ? last(segments)!.parameters : {};
|
||||
const pathIndexShift = getPathIndexShift(rawSegment) + segments.length;
|
||||
const snapshot = new ActivatedRouteSnapshot(
|
||||
segments, params, Object.freeze({...this.urlTree.queryParams}), this.urlTree.fragment,
|
||||
getData(route), getOutlet(route), route.component ?? route._loadedComponent ?? null,
|
||||
route, getSourceSegmentGroup(rawSegment), pathIndexShift, getResolve(route));
|
||||
route, getResolve(route));
|
||||
matchResult = of({
|
||||
snapshot,
|
||||
consumedSegments: [],
|
||||
@@ -194,13 +192,11 @@ export class Recognizer {
|
||||
if (!matched) {
|
||||
return null;
|
||||
}
|
||||
const pathIndexShift = getPathIndexShift(rawSegment) + consumedSegments.length;
|
||||
|
||||
const snapshot = new ActivatedRouteSnapshot(
|
||||
consumedSegments, parameters, Object.freeze({...this.urlTree.queryParams}),
|
||||
this.urlTree.fragment, getData(route), getOutlet(route),
|
||||
route.component ?? route._loadedComponent ?? null, route,
|
||||
getSourceSegmentGroup(rawSegment), pathIndexShift, getResolve(route));
|
||||
route.component ?? route._loadedComponent ?? null, route, getResolve(route));
|
||||
return {snapshot, consumedSegments, remainingSegments};
|
||||
}));
|
||||
}
|
||||
@@ -335,34 +331,6 @@ function checkOutletNameUniqueness(nodes: TreeNode<ActivatedRouteSnapshot>[]): v
|
||||
});
|
||||
}
|
||||
|
||||
function getSourceSegmentGroup(segmentGroup: UrlSegmentGroup): UrlSegmentGroup {
|
||||
let s = segmentGroup;
|
||||
while (s._sourceSegment) {
|
||||
s = s._sourceSegment;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
function getPathIndexShift(segmentGroup: UrlSegmentGroup): number {
|
||||
let s = segmentGroup;
|
||||
let res = s._segmentIndexShift ?? 0;
|
||||
while (s._sourceSegment) {
|
||||
s = s._sourceSegment;
|
||||
res += s._segmentIndexShift ?? 0;
|
||||
}
|
||||
return res - 1;
|
||||
}
|
||||
|
||||
function getCorrectedPathIndexShift(segmentGroup: UrlSegmentGroup): number {
|
||||
let s = segmentGroup;
|
||||
let res = s._segmentIndexShiftCorrected ?? s._segmentIndexShift ?? 0;
|
||||
while (s._sourceSegment) {
|
||||
s = s._sourceSegment;
|
||||
res += s._segmentIndexShiftCorrected ?? s._segmentIndexShift ?? 0;
|
||||
}
|
||||
return res - 1;
|
||||
}
|
||||
|
||||
function getData(route: Route): Data {
|
||||
return route.data || {};
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ import {Location} from '@angular/common';
|
||||
import {inject, Injectable, NgZone, Type, ɵConsole as Console, ɵRuntimeError as RuntimeError} from '@angular/core';
|
||||
import {Observable, of, SubscriptionLike} from 'rxjs';
|
||||
|
||||
import {CreateUrlTreeStrategy} from './create_url_tree_strategy';
|
||||
import {createSegmentGroupFromRoute, createUrlTreeFromSegmentGroup} from './create_url_tree';
|
||||
import {RuntimeErrorCode} from './errors';
|
||||
import {Event, IMPERATIVE_NAVIGATION, NavigationTrigger} from './events';
|
||||
import {NavigationBehaviorOptions, OnSameUrlNavigation, Routes} from './models';
|
||||
@@ -22,7 +22,7 @@ import {ROUTES} from './router_config_loader';
|
||||
import {createEmptyState, RouterState} from './router_state';
|
||||
import {Params} from './shared';
|
||||
import {UrlHandlingStrategy} from './url_handling_strategy';
|
||||
import {containsTree, IsActiveMatchOptions, isUrlTree, UrlSerializer, UrlTree} from './url_tree';
|
||||
import {containsTree, IsActiveMatchOptions, isUrlTree, UrlSegmentGroup, UrlSerializer, UrlTree} from './url_tree';
|
||||
import {standardizeConfig, validateConfig} from './utils/config';
|
||||
|
||||
|
||||
@@ -220,9 +220,6 @@ export class Router {
|
||||
*/
|
||||
routeReuseStrategy = inject(RouteReuseStrategy);
|
||||
|
||||
/** Strategy used to create a UrlTree. */
|
||||
private readonly urlCreationStrategy = inject(CreateUrlTreeStrategy);
|
||||
|
||||
/**
|
||||
* A strategy for setting the title based on the `routerState`.
|
||||
*
|
||||
@@ -531,8 +528,30 @@ export class Router {
|
||||
if (q !== null) {
|
||||
q = this.removeEmptyProps(q);
|
||||
}
|
||||
return this.urlCreationStrategy.createUrlTree(
|
||||
relativeTo, this.routerState, this.currentUrlTree, commands, q, f ?? null);
|
||||
|
||||
let relativeToUrlSegmentGroup: UrlSegmentGroup|undefined;
|
||||
try {
|
||||
const relativeToSnapshot = relativeTo ? relativeTo.snapshot : this.routerState.snapshot.root;
|
||||
relativeToUrlSegmentGroup = createSegmentGroupFromRoute(relativeToSnapshot);
|
||||
} catch (e: unknown) {
|
||||
// This is strictly for backwards compatibility with tests that create
|
||||
// invalid `ActivatedRoute` mocks.
|
||||
// Note: the difference between having this fallback for invalid `ActivatedRoute` setups and
|
||||
// just throwing is ~500 test failures. Fixing all of those tests by hand is not feasible at
|
||||
// the moment.
|
||||
if (typeof commands[0] !== 'string' || !commands[0].startsWith('/')) {
|
||||
// Navigations that were absolute in the old way of creating UrlTrees
|
||||
// would still work because they wouldn't attempt to match the
|
||||
// segments in the `ActivatedRoute` to the `currentUrlTree` but
|
||||
// instead just replace the root segment with the navigation result.
|
||||
// Non-absolute navigations would fail to apply the commands because
|
||||
// the logic could not find the segment to replace (so they'd act like there were no
|
||||
// commands).
|
||||
commands = [];
|
||||
}
|
||||
relativeToUrlSegmentGroup = this.currentUrlTree.root;
|
||||
}
|
||||
return createUrlTreeFromSegmentGroup(relativeToUrlSegmentGroup, commands, q, f ?? null);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -84,7 +84,7 @@ export function createEmptyStateSnapshot(
|
||||
const fragment = '';
|
||||
const activated = new ActivatedRouteSnapshot(
|
||||
[], emptyParams, emptyQueryParams, fragment, emptyData, PRIMARY_OUTLET, rootComponent, null,
|
||||
urlTree.root, -1, {});
|
||||
{});
|
||||
return new RouterStateSnapshot('', new TreeNode<ActivatedRouteSnapshot>(activated, []));
|
||||
}
|
||||
|
||||
@@ -281,10 +281,6 @@ function flattenInherited(pathFromRoot: ActivatedRouteSnapshot[]): Inherited {
|
||||
export class ActivatedRouteSnapshot {
|
||||
/** The configuration used to match this route **/
|
||||
public readonly routeConfig: Route|null;
|
||||
/** @internal **/
|
||||
_urlSegment: UrlSegmentGroup;
|
||||
/** @internal */
|
||||
_lastPathIndex: number;
|
||||
/** @internal */
|
||||
_resolve: ResolveData;
|
||||
/** @internal */
|
||||
@@ -336,11 +332,8 @@ export class ActivatedRouteSnapshot {
|
||||
/** The outlet name of the route */
|
||||
public outlet: string,
|
||||
/** The component of the route */
|
||||
public component: Type<any>|null, routeConfig: Route|null, urlSegment: UrlSegmentGroup,
|
||||
lastPathIndex: number, resolve: ResolveData) {
|
||||
public component: Type<any>|null, routeConfig: Route|null, resolve: ResolveData) {
|
||||
this.routeConfig = routeConfig;
|
||||
this._urlSegment = urlSegment;
|
||||
this._lastPathIndex = lastPathIndex;
|
||||
this._resolve = resolve;
|
||||
}
|
||||
|
||||
|
||||
@@ -233,17 +233,6 @@ export class UrlTree {
|
||||
* @publicApi
|
||||
*/
|
||||
export class UrlSegmentGroup {
|
||||
/** @internal */
|
||||
_sourceSegment?: UrlSegmentGroup;
|
||||
/** @internal */
|
||||
_segmentIndexShift?: number;
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* Used only in dev mode to detect if application relies on `relativeLinkResolution: 'legacy'`
|
||||
* Should be removed in when `relativeLinkResolution` is removed.
|
||||
*/
|
||||
_segmentIndexShiftCorrected?: number;
|
||||
/** The parent node in the url tree */
|
||||
parent: UrlSegmentGroup|null = null;
|
||||
|
||||
|
||||
@@ -96,10 +96,7 @@ export function split(
|
||||
const s = new UrlSegmentGroup(
|
||||
consumedSegments,
|
||||
createChildrenForEmptyPaths(
|
||||
segmentGroup, consumedSegments, config,
|
||||
new UrlSegmentGroup(slicedSegments, segmentGroup.children)));
|
||||
s._sourceSegment = segmentGroup;
|
||||
s._segmentIndexShift = consumedSegments.length;
|
||||
config, new UrlSegmentGroup(slicedSegments, segmentGroup.children)));
|
||||
return {segmentGroup: s, slicedSegments: []};
|
||||
}
|
||||
|
||||
@@ -109,14 +106,10 @@ export function split(
|
||||
segmentGroup.segments,
|
||||
addEmptyPathsToChildrenIfNeeded(
|
||||
segmentGroup, consumedSegments, slicedSegments, config, segmentGroup.children));
|
||||
s._sourceSegment = segmentGroup;
|
||||
s._segmentIndexShift = consumedSegments.length;
|
||||
return {segmentGroup: s, slicedSegments};
|
||||
}
|
||||
|
||||
const s = new UrlSegmentGroup(segmentGroup.segments, segmentGroup.children);
|
||||
s._sourceSegment = segmentGroup;
|
||||
s._segmentIndexShift = consumedSegments.length;
|
||||
return {segmentGroup: s, slicedSegments};
|
||||
}
|
||||
|
||||
@@ -128,8 +121,6 @@ function addEmptyPathsToChildrenIfNeeded(
|
||||
for (const r of routes) {
|
||||
if (emptyPathMatch(segmentGroup, slicedSegments, r) && !children[getOutlet(r)]) {
|
||||
const s = new UrlSegmentGroup([], {});
|
||||
s._sourceSegment = segmentGroup;
|
||||
s._segmentIndexShift = consumedSegments.length;
|
||||
res[getOutlet(r)] = s;
|
||||
}
|
||||
}
|
||||
@@ -137,18 +128,13 @@ function addEmptyPathsToChildrenIfNeeded(
|
||||
}
|
||||
|
||||
function createChildrenForEmptyPaths(
|
||||
segmentGroup: UrlSegmentGroup, consumedSegments: UrlSegment[], routes: Route[],
|
||||
primarySegment: UrlSegmentGroup): {[name: string]: UrlSegmentGroup} {
|
||||
routes: Route[], primarySegment: UrlSegmentGroup): {[name: string]: UrlSegmentGroup} {
|
||||
const res: {[name: string]: UrlSegmentGroup} = {};
|
||||
res[PRIMARY_OUTLET] = primarySegment;
|
||||
primarySegment._sourceSegment = segmentGroup;
|
||||
primarySegment._segmentIndexShift = consumedSegments.length;
|
||||
|
||||
for (const r of routes) {
|
||||
if (r.path === '' && getOutlet(r) !== PRIMARY_OUTLET) {
|
||||
const s = new UrlSegmentGroup([], {});
|
||||
s._sourceSegment = segmentGroup;
|
||||
s._segmentIndexShift = consumedSegments.length;
|
||||
res[getOutlet(r)] = s;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ import {Type} from '@angular/core';
|
||||
import {Data, ResolveData, Route} from '../src/models';
|
||||
import {ActivatedRouteSnapshot} from '../src/router_state';
|
||||
import {Params} from '../src/shared';
|
||||
import {UrlSegment, UrlSegmentGroup, UrlTree} from '../src/url_tree';
|
||||
import {UrlSegment, UrlTree} from '../src/url_tree';
|
||||
|
||||
export class Logger {
|
||||
logs: string[] = [];
|
||||
@@ -39,8 +39,6 @@ export declare type ARSArgs = {
|
||||
data?: Data,
|
||||
outlet?: string, component: Type<unknown>| string | null,
|
||||
routeConfig?: Route | null,
|
||||
urlSegment?: UrlSegmentGroup,
|
||||
lastPathIndex?: number,
|
||||
resolve?: ResolveData
|
||||
};
|
||||
|
||||
@@ -48,5 +46,5 @@ export function createActivatedRouteSnapshot(args: ARSArgs): ActivatedRouteSnaps
|
||||
return new (ActivatedRouteSnapshot as any)(
|
||||
args.url || [], args.params || {}, args.queryParams || null, args.fragment || null,
|
||||
args.data || null, args.outlet || null, args.component, args.routeConfig || {},
|
||||
args.urlSegment || null, args.lastPathIndex || -1, args.resolve || {});
|
||||
args.resolve || {});
|
||||
}
|
||||
|
||||
@@ -52,59 +52,13 @@ describe('recognize', async () => {
|
||||
],
|
||||
'a(left:b//right:c)');
|
||||
expect(s.root.url.toString()).toEqual(url.root.toString());
|
||||
expect((s.root as any)._lastPathIndex).toBe(-1);
|
||||
|
||||
const c = s.root.children;
|
||||
expect(c[0].url.toString()).toEqual(url.root.children[PRIMARY_OUTLET].toString());
|
||||
expect((c[0] as any)._lastPathIndex).toBe(0);
|
||||
|
||||
expect(c[1].url.toString()).toEqual(url.root.children['left'].toString());
|
||||
expect((c[1] as any)._lastPathIndex).toBe(0);
|
||||
|
||||
expect(c[2].url.toString()).toEqual(url.root.children['right'].toString());
|
||||
expect((c[2] as any)._lastPathIndex).toBe(0);
|
||||
});
|
||||
|
||||
it('should set url segment and index properly (nested case)', async () => {
|
||||
const url = tree('a/b/c');
|
||||
const s = await recognize(
|
||||
[
|
||||
{path: 'a/b', component: ComponentA, children: [{path: 'c', component: ComponentC}]},
|
||||
],
|
||||
'a/b/c');
|
||||
expect((s.root as any)._urlSegment.toString()).toEqual(url.root.toString());
|
||||
expect((s.root as any)._lastPathIndex).toBe(-1);
|
||||
|
||||
const compA = s.root.firstChild!;
|
||||
expect((compA as any)._urlSegment.toString())
|
||||
.toEqual(url.root.children[PRIMARY_OUTLET].toString());
|
||||
expect((compA as any)._lastPathIndex).toBe(1);
|
||||
|
||||
const compC = compA.firstChild!;
|
||||
expect((compC as any)._urlSegment.toString())
|
||||
.toEqual(url.root.children[PRIMARY_OUTLET].toString());
|
||||
expect((compC as any)._lastPathIndex).toBe(2);
|
||||
});
|
||||
|
||||
it('should set url segment and index properly (wildcard)', async () => {
|
||||
const url = tree('a/b/c');
|
||||
const s = await recognize(
|
||||
[
|
||||
{path: 'a', component: ComponentA, children: [{path: '**', component: ComponentB}]},
|
||||
],
|
||||
'a/b/c');
|
||||
expect((s.root as any)._urlSegment.toString()).toEqual(url.root.toString());
|
||||
expect((s.root as any)._lastPathIndex).toBe(-1);
|
||||
|
||||
const compA = s.root.firstChild!;
|
||||
expect((compA as any)._urlSegment.toString())
|
||||
.toEqual(url.root.children[PRIMARY_OUTLET].toString());
|
||||
expect((compA as any)._lastPathIndex).toBe(0);
|
||||
|
||||
const compC = compA.firstChild!;
|
||||
expect((compC as any)._urlSegment.toString())
|
||||
.toEqual(url.root.children[PRIMARY_OUTLET].toString());
|
||||
expect((compC as any)._lastPathIndex).toBe(2);
|
||||
});
|
||||
|
||||
it('should match routes in the depth first order', async () => {
|
||||
@@ -251,22 +205,6 @@ describe('recognize', async () => {
|
||||
checkActivatedRoute(s.root.firstChild!.firstChild!, '', {}, ComponentB);
|
||||
});
|
||||
|
||||
it('should set url segment and index properly', async () => {
|
||||
const url = tree('') as any;
|
||||
const s = await recognize(
|
||||
[{path: '', component: ComponentA, children: [{path: '', component: ComponentB}]}], '');
|
||||
expect((s.root as any)._urlSegment.toString()).toEqual(url.root.toString());
|
||||
expect((s.root as any)._lastPathIndex).toBe(-1);
|
||||
|
||||
const c = s.root.firstChild!;
|
||||
expect((c as any)._urlSegment.toString()).toEqual(url.root.toString());
|
||||
expect((c as any)._lastPathIndex).toBe(-1);
|
||||
|
||||
const c2 = s.root.firstChild!.firstChild!;
|
||||
expect((c2 as any)._urlSegment.toString()).toEqual(url.root.toString());
|
||||
expect((c2 as any)._lastPathIndex).toBe(-1);
|
||||
});
|
||||
|
||||
it('should inherit params', async () => {
|
||||
const s = await recognize(
|
||||
[{
|
||||
@@ -349,129 +287,6 @@ describe('recognize', async () => {
|
||||
expect(c.length).toEqual(1);
|
||||
checkActivatedRoute(c[0], 'b', {}, ComponentB);
|
||||
});
|
||||
|
||||
it('should set url segment and index properly', async () => {
|
||||
const url = tree('a/b') as any;
|
||||
const s = await recognize(
|
||||
[{
|
||||
path: 'a',
|
||||
component: ComponentA,
|
||||
children: [
|
||||
{path: 'b', component: ComponentB}, {path: '', component: ComponentC, outlet: 'aux'}
|
||||
]
|
||||
}],
|
||||
'a/b');
|
||||
expect((s.root as any)._urlSegment.toString()).toEqual(url.root.toString());
|
||||
expect((s.root as any)._lastPathIndex).toBe(-1);
|
||||
|
||||
const a = s.root.firstChild!;
|
||||
expect((a as any)._urlSegment.toString())
|
||||
.toEqual(url.root.children[PRIMARY_OUTLET].toString());
|
||||
expect((a as any)._lastPathIndex).toBe(0);
|
||||
|
||||
const b = a.firstChild!;
|
||||
expect((b as any)._urlSegment.toString())
|
||||
.toEqual(url.root.children[PRIMARY_OUTLET].toString());
|
||||
expect((b as any)._lastPathIndex).toBe(1);
|
||||
|
||||
const c = a.children[1];
|
||||
expect((c as any)._urlSegment.toString())
|
||||
.toEqual(url.root.children[PRIMARY_OUTLET].toString());
|
||||
expect((c as any)._lastPathIndex).toBe(0);
|
||||
});
|
||||
|
||||
it('should set url segment and index properly when nested empty-path segments', async () => {
|
||||
const url = tree('a') as any;
|
||||
const s = await recognize(
|
||||
[{
|
||||
path: 'a',
|
||||
children:
|
||||
[{path: '', component: ComponentB, children: [{path: '', component: ComponentC}]}]
|
||||
}],
|
||||
'a');
|
||||
expect((s.root as any)._urlSegment.toString()).toEqual(url.root.toString());
|
||||
expect((s.root as any)._lastPathIndex).toBe(-1);
|
||||
|
||||
const a = s.root.firstChild!;
|
||||
expect((a as any)._urlSegment.toString())
|
||||
.toEqual(url.root.children[PRIMARY_OUTLET].toString());
|
||||
expect((a as any)._lastPathIndex).toBe(0);
|
||||
|
||||
const b = a.firstChild!;
|
||||
expect((b as any)._urlSegment.toString())
|
||||
.toEqual(url.root.children[PRIMARY_OUTLET].toString());
|
||||
expect((b as any)._lastPathIndex).toBe(0);
|
||||
|
||||
const c = b.firstChild!;
|
||||
expect((c as any)._urlSegment.toString())
|
||||
.toEqual(url.root.children[PRIMARY_OUTLET].toString());
|
||||
expect((c as any)._lastPathIndex).toBe(0);
|
||||
});
|
||||
|
||||
it('should set url segment and index properly for nested empty-path segments', async () => {
|
||||
const url = tree('a/b');
|
||||
const s = await recognize(
|
||||
[{
|
||||
path: 'a',
|
||||
children: [{
|
||||
path: 'b',
|
||||
component: ComponentB,
|
||||
children: [
|
||||
{path: '', component: ComponentC, children: [{path: '', component: ComponentD}]}
|
||||
]
|
||||
}]
|
||||
}],
|
||||
'a/b', 'emptyOnly');
|
||||
expect((s.root as any)._urlSegment.toString()).toEqual(url.root.toString());
|
||||
expect((s.root as any)._lastPathIndex).toBe(-1);
|
||||
|
||||
const a = s.root.firstChild!;
|
||||
expect((a as any)._urlSegment.toString())
|
||||
.toEqual(url.root.children[PRIMARY_OUTLET].toString());
|
||||
expect((a as any)._lastPathIndex).toBe(0);
|
||||
|
||||
const b = a.firstChild!;
|
||||
expect((b as any)._urlSegment.toString())
|
||||
.toEqual(url.root.children[PRIMARY_OUTLET].toString());
|
||||
expect((b as any)._lastPathIndex).toBe(1);
|
||||
|
||||
const c = b.firstChild!;
|
||||
expect((c as any)._urlSegment.toString())
|
||||
.toEqual(url.root.children[PRIMARY_OUTLET].toString());
|
||||
expect((c as any)._lastPathIndex).toBe(1);
|
||||
|
||||
const d = c.firstChild!;
|
||||
expect((d as any)._urlSegment.toString())
|
||||
.toEqual(url.root.children[PRIMARY_OUTLET].toString());
|
||||
expect((d as any)._lastPathIndex).toBe(1);
|
||||
});
|
||||
|
||||
it('should set url segment and index properly when nested empty-path segments (2)',
|
||||
async () => {
|
||||
const url = tree('');
|
||||
const s = await recognize(
|
||||
[{
|
||||
path: '',
|
||||
children: [
|
||||
{path: '', component: ComponentB, children: [{path: '', component: ComponentC}]}
|
||||
]
|
||||
}],
|
||||
'');
|
||||
expect((s.root as any)._urlSegment.toString()).toEqual(url.root.toString());
|
||||
expect((s.root as any)._lastPathIndex).toBe(-1);
|
||||
|
||||
const a = s.root.firstChild!;
|
||||
expect((a as any)._urlSegment.toString()).toEqual(url.root.toString());
|
||||
expect((a as any)._lastPathIndex).toBe(-1);
|
||||
|
||||
const b = a.firstChild!;
|
||||
expect((b as any)._urlSegment.toString()).toEqual(url.root.toString());
|
||||
expect((b as any)._lastPathIndex).toBe(-1);
|
||||
|
||||
const c = b.firstChild!;
|
||||
expect((c as any)._urlSegment.toString()).toEqual(url.root.toString());
|
||||
expect((c as any)._lastPathIndex).toBe(-1);
|
||||
});
|
||||
});
|
||||
|
||||
describe('aux split at the end (no right child)', async () => {
|
||||
|
||||
Reference in New Issue
Block a user