mirror of
https://github.com/angular/angular.git
synced 2026-09-14 13:54:52 +08:00
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:
committed by
Andrew Kushnir
parent
64d6db67d4
commit
99898f3370
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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 {}
|
||||
@@ -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 => {
|
||||
|
||||
@@ -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 => {
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user