refactor(router): Remove code to support relativeLinkResolution (#47933)

The public API for enabling this option has already been removed. This change
updates the internal Router code to not include any logic to support it.

PR Close #47933
This commit is contained in:
Andrew Scott
2022-11-01 10:27:28 -07:00
committed by Andrew Kushnir
parent 64d6db67d4
commit 99898f3370
10 changed files with 56 additions and 126 deletions
+1 -1
View File
@@ -288,7 +288,7 @@ export const enum EventType {
}
// @public
export interface ExtraOptions extends InMemoryScrollingOptions, RouterConfigOptions, InternalExtraOptions {
export interface ExtraOptions extends InMemoryScrollingOptions, RouterConfigOptions {
enableTracing?: boolean;
errorHandler?: ErrorHandler;
initialNavigation?: InitialNavigation;
-11
View File
@@ -151,17 +151,6 @@ export function createUrlTree(
// didn't before.
const result = createTreeUsingPathIndex(route.snapshot?._lastPathIndex);
// Check if application is relying on `relativeLinkResolution: 'legacy'`
if (typeof ngDevMode === 'undefined' || !!ngDevMode) {
const correctedResult = createTreeUsingPathIndex(route.snapshot?._correctedLastPathIndex);
if (correctedResult.toString() !== result.toString()) {
console.warn(
`relativeLinkResolution: 'legacy' is deprecated and will be removed in a future version of Angular. The link to ${
result.toString()} will change to ${
correctedResult.toString()} if the code is not updated before then.`);
}
}
return result;
}
+3 -4
View File
@@ -17,12 +17,11 @@ import {UrlSerializer} from '../url_tree';
export function recognize(
injector: EnvironmentInjector, rootComponentType: Type<any>|null, config: Route[],
serializer: UrlSerializer, paramsInheritanceStrategy: 'emptyOnly'|'always',
relativeLinkResolution: 'legacy'|'corrected'): MonoTypeOperatorFunction<NavigationTransition> {
serializer: UrlSerializer, paramsInheritanceStrategy: 'emptyOnly'|'always'):
MonoTypeOperatorFunction<NavigationTransition> {
return mergeMap(
t => recognizeFn(
injector, rootComponentType, config, t.urlAfterRedirects!,
serializer.serialize(t.urlAfterRedirects!), serializer, paramsInheritanceStrategy,
relativeLinkResolution)
serializer.serialize(t.urlAfterRedirects!), serializer, paramsInheritanceStrategy)
.pipe(map(targetSnapshot => ({...t, targetSnapshot}))));
}
@@ -1,15 +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
*/
/**
* Exists to aid internal migration off of the deprecated relativeLinkResolution option.
*/
export function assignRelativeLinkResolution(
router: {relativeLinkResolution: 'legacy'|'corrected'}): void {}
export interface InternalExtraOptions {}
+7 -18
View File
@@ -33,11 +33,11 @@ function newObservableError(e: unknown): Observable<RouterStateSnapshot> {
export function recognize(
injector: EnvironmentInjector, rootComponentType: Type<any>|null, config: Routes,
urlTree: UrlTree, url: string, urlSerializer: UrlSerializer,
paramsInheritanceStrategy: ParamsInheritanceStrategy = 'emptyOnly',
relativeLinkResolution: 'legacy'|'corrected' = 'legacy'): Observable<RouterStateSnapshot> {
paramsInheritanceStrategy: ParamsInheritanceStrategy =
'emptyOnly'): Observable<RouterStateSnapshot> {
return new Recognizer(
injector, rootComponentType, config, urlTree, url, paramsInheritanceStrategy,
relativeLinkResolution, urlSerializer)
urlSerializer)
.recognize()
.pipe(switchMap(result => {
if (result === null) {
@@ -53,14 +53,11 @@ export class Recognizer {
private injector: EnvironmentInjector, private rootComponentType: Type<any>|null,
private config: Routes, private urlTree: UrlTree, private url: string,
private paramsInheritanceStrategy: ParamsInheritanceStrategy,
private relativeLinkResolution: 'legacy'|'corrected',
private readonly urlSerializer: UrlSerializer) {}
recognize(): Observable<RouterStateSnapshot|null> {
const rootSegmentGroup =
split(
this.urlTree.root, [], [], this.config.filter(c => c.redirectTo === undefined),
this.relativeLinkResolution)
split(this.urlTree.root, [], [], this.config.filter(c => c.redirectTo === undefined))
.segmentGroup;
return this.processSegmentGroup(this.injector, this.config, rootSegmentGroup, PRIMARY_OUTLET)
@@ -184,12 +181,7 @@ export class Recognizer {
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),
// NG_DEV_MODE is used to prevent the getCorrectedPathIndexShift function from affecting
// production bundle size. This value is intended only to surface a warning to users
// depending on `relativeLinkResolution: 'legacy'` in dev mode.
(NG_DEV_MODE ? getCorrectedPathIndexShift(rawSegment) + segments.length :
pathIndexShift));
route, getSourceSegmentGroup(rawSegment), pathIndexShift, getResolve(route));
matchResult = of({
snapshot,
consumedSegments: [],
@@ -208,10 +200,7 @@ export class Recognizer {
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),
(NG_DEV_MODE ?
getCorrectedPathIndexShift(rawSegment) + consumedSegments.length :
pathIndexShift));
getSourceSegmentGroup(rawSegment), pathIndexShift, getResolve(route));
return {snapshot, consumedSegments, remainingSegments};
}));
}
@@ -231,7 +220,7 @@ export class Recognizer {
// Filter out routes with redirectTo because we are trying to create activated route
// snapshots and don't handle redirects here. That should have been done in
// `applyRedirects`.
childConfig.filter(c => c.redirectTo === undefined), this.relativeLinkResolution);
childConfig.filter(c => c.redirectTo === undefined));
if (slicedSegments.length === 0 && segmentGroup.hasChildren()) {
return this.processChildren(childInjector, childConfig, segmentGroup).pipe(map(children => {
+1 -12
View File
@@ -24,7 +24,6 @@ import {recognize} from './operators/recognize';
import {resolveData} from './operators/resolve_data';
import {switchTap} from './operators/switch_tap';
import {DefaultTitleStrategy, TitleStrategy} from './page_title_strategy';
import {assignRelativeLinkResolution} from './patchable_relative_link_resolution';
import {DefaultRouteReuseStrategy, RouteReuseStrategy} from './route_reuse_strategy';
import {ErrorHandler, ExtraOptions, ROUTER_CONFIGURATION} from './router_config';
import {RouterConfigLoader, ROUTES} from './router_config_loader';
@@ -346,8 +345,6 @@ export function setupRouter() {
assignExtraOptionsToRouter(opts, router);
assignRelativeLinkResolution(router);
return router;
}
@@ -526,13 +523,6 @@ export class Router {
*/
urlUpdateStrategy: 'deferred'|'eager' = 'deferred';
/**
* TODO(atscott): Remove all references to relativeLinkResolution when internal cleanup is
* finished.
* @internal
*/
relativeLinkResolution: 'legacy'|'corrected' = 'corrected';
/**
* Configures how the Router attempts to restore state when a navigation is cancelled.
*
@@ -693,8 +683,7 @@ export class Router {
// Recognize
recognize(
this.ngModule.injector, this.rootComponentType, this.config,
this.urlSerializer, this.paramsInheritanceStrategy,
this.relativeLinkResolution),
this.urlSerializer, this.paramsInheritanceStrategy),
// Update URL if in `eager` update mode
tap(t => {
+1 -3
View File
@@ -8,7 +8,6 @@
import {InjectionToken} from '@angular/core';
import {InternalExtraOptions} from './patchable_relative_link_resolution';
import {UrlSerializer, UrlTree} from './url_tree';
const NG_DEV_MODE = typeof ngDevMode === 'undefined' || !!ngDevMode;
@@ -171,8 +170,7 @@ export interface InMemoryScrollingOptions {
*
* @publicApi
*/
export interface ExtraOptions extends InMemoryScrollingOptions, RouterConfigOptions,
InternalExtraOptions {
export interface ExtraOptions extends InMemoryScrollingOptions, RouterConfigOptions {
/**
* When true, log all internal navigation events to the console.
* Use for debugging.
+1 -9
View File
@@ -285,13 +285,6 @@ export class ActivatedRouteSnapshot {
_urlSegment: UrlSegmentGroup;
/** @internal */
_lastPathIndex: number;
/**
* @internal
*
* Used only in dev mode to detect if application relies on `relativeLinkResolution: 'legacy'`
* Should be removed in v16.
*/
_correctedLastPathIndex: number;
/** @internal */
_resolve: ResolveData;
/** @internal */
@@ -348,11 +341,10 @@ export class ActivatedRouteSnapshot {
public outlet: string,
/** The component of the route */
public component: Type<any>|null, routeConfig: Route|null, urlSegment: UrlSegmentGroup,
lastPathIndex: number, resolve: ResolveData, correctedLastPathIndex?: number) {
lastPathIndex: number, resolve: ResolveData) {
this.routeConfig = routeConfig;
this._urlSegment = urlSegment;
this._lastPathIndex = lastPathIndex;
this._correctedLastPathIndex = correctedLastPathIndex ?? lastPathIndex;
this._resolve = resolve;
}
+5 -13
View File
@@ -91,7 +91,7 @@ export function match(
export function split(
segmentGroup: UrlSegmentGroup, consumedSegments: UrlSegment[], slicedSegments: UrlSegment[],
config: Route[], relativeLinkResolution: 'legacy'|'corrected' = 'corrected') {
config: Route[]) {
if (slicedSegments.length > 0 &&
containsEmptyPathMatchesWithNamedOutlets(segmentGroup, slicedSegments, config)) {
const s = new UrlSegmentGroup(
@@ -109,8 +109,7 @@ export function split(
const s = new UrlSegmentGroup(
segmentGroup.segments,
addEmptyPathsToChildrenIfNeeded(
segmentGroup, consumedSegments, slicedSegments, config, segmentGroup.children,
relativeLinkResolution));
segmentGroup, consumedSegments, slicedSegments, config, segmentGroup.children));
s._sourceSegment = segmentGroup;
s._segmentIndexShift = consumedSegments.length;
return {segmentGroup: s, slicedSegments};
@@ -124,21 +123,14 @@ export function split(
function addEmptyPathsToChildrenIfNeeded(
segmentGroup: UrlSegmentGroup, consumedSegments: UrlSegment[], slicedSegments: UrlSegment[],
routes: Route[], children: {[name: string]: UrlSegmentGroup},
relativeLinkResolution: 'legacy'|'corrected'): {[name: string]: UrlSegmentGroup} {
routes: Route[],
children: {[name: string]: UrlSegmentGroup}): {[name: string]: UrlSegmentGroup} {
const res: {[name: string]: UrlSegmentGroup} = {};
for (const r of routes) {
if (emptyPathMatch(segmentGroup, slicedSegments, r) && !children[getOutlet(r)]) {
const s = new UrlSegmentGroup([], {});
s._sourceSegment = segmentGroup;
if (relativeLinkResolution === 'legacy') {
s._segmentIndexShift = segmentGroup.segments.length;
if (typeof ngDevMode === 'undefined' || !!ngDevMode) {
s._segmentIndexShiftCorrected = consumedSegments.length;
}
} else {
s._segmentIndexShift = consumedSegments.length;
}
s._segmentIndexShift = consumedSegments.length;
res[getOutlet(r)] = s;
}
}
+37 -40
View File
@@ -408,46 +408,43 @@ describe('recognize', async () => {
expect((c as any)._lastPathIndex).toBe(0);
});
it('should set url segment and index properly with the "corrected" option 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', 'corrected');
expect((s.root as any)._urlSegment.toString()).toEqual(url.root.toString());
expect((s.root as any)._lastPathIndex).toBe(-1);
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 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 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 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);
});
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 () => {
@@ -658,7 +655,7 @@ describe('recognize', async () => {
children: [{path: 'b', component: ComponentB}],
},
],
tree('/b'), '/b', 'emptyOnly', 'corrected', new DefaultUrlSerializer())
tree('/b'), '/b', 'emptyOnly', new DefaultUrlSerializer())
.recognize()
.toPromise();
expect(s).toBeNull();
@@ -830,12 +827,12 @@ describe('recognize', async () => {
});
async function recognize(
config: Routes, url: string, paramsInheritanceStrategy: 'emptyOnly'|'always' = 'emptyOnly',
relativeLinkResolution: 'legacy'|'corrected' = 'legacy'): Promise<RouterStateSnapshot> {
config: Routes, url: string,
paramsInheritanceStrategy: 'emptyOnly'|'always' = 'emptyOnly'): Promise<RouterStateSnapshot> {
const serializer = new DefaultUrlSerializer();
const result = await new Recognizer(
TestBed.inject(EnvironmentInjector), RootComponent, config, tree(url), url,
paramsInheritanceStrategy, relativeLinkResolution, serializer)
paramsInheritanceStrategy, serializer)
.recognize()
.toPromise();
expect(result).not.toBeNull();