diff --git a/goldens/public-api/router/index.md b/goldens/public-api/router/index.md index 701f6ce95bdbf..33d22e999f3e9 100644 --- a/goldens/public-api/router/index.md +++ b/goldens/public-api/router/index.md @@ -283,14 +283,12 @@ export const enum EventType { } // @public -export interface ExtraOptions extends InMemoryScrollingOptions, RouterConfigOptions { +export interface ExtraOptions extends InMemoryScrollingOptions, RouterConfigOptions, InternalExtraOptions { enableTracing?: boolean; errorHandler?: ErrorHandler; initialNavigation?: InitialNavigation; malformedUriErrorHandler?: (error: URIError, urlSerializer: UrlSerializer, url: string) => UrlTree; preloadingStrategy?: any; - // @deprecated - relativeLinkResolution?: 'legacy' | 'corrected'; scrollOffset?: [number, number] | (() => [number, number]); useHash?: boolean; } @@ -648,8 +646,6 @@ export class Router { onSameUrlNavigation: 'reload' | 'ignore'; paramsInheritanceStrategy: 'emptyOnly' | 'always'; parseUrl(url: string): UrlTree; - // @deprecated - relativeLinkResolution: 'legacy' | 'corrected'; resetConfig(config: Routes): void; routeReuseStrategy: RouteReuseStrategy; readonly routerState: RouterState; diff --git a/packages/router/src/patchable_relative_link_resolution.ts b/packages/router/src/patchable_relative_link_resolution.ts index e62a8b4cffb36..491c2de355af6 100644 --- a/packages/router/src/patchable_relative_link_resolution.ts +++ b/packages/router/src/patchable_relative_link_resolution.ts @@ -11,3 +11,5 @@ */ export function assignRelativeLinkResolution( router: {relativeLinkResolution: 'legacy'|'corrected'}): void {} + +export interface InternalExtraOptions {} diff --git a/packages/router/src/router.ts b/packages/router/src/router.ts index f6e35fb39fdd7..0f832fa5e585d 100644 --- a/packages/router/src/router.ts +++ b/packages/router/src/router.ts @@ -310,10 +310,6 @@ export function assignExtraOptionsToRouter(opts: ExtraOptions, router: Router): router.paramsInheritanceStrategy = opts.paramsInheritanceStrategy; } - if (opts.relativeLinkResolution) { - router.relativeLinkResolution = opts.relativeLinkResolution; - } - if (opts.urlUpdateStrategy) { router.urlUpdateStrategy = opts.urlUpdateStrategy; } @@ -531,10 +527,9 @@ export class Router { urlUpdateStrategy: 'deferred'|'eager' = 'deferred'; /** - * Enables a bug fix that corrects relative link resolution in components with empty paths. - * @see `RouterModule` - * - * @deprecated + * TODO(atscott): Remove all references to relativeLinkResolution when internal cleanup is + * finished. + * @internal */ relativeLinkResolution: 'legacy'|'corrected' = 'corrected'; diff --git a/packages/router/src/router_config.ts b/packages/router/src/router_config.ts index abbe1ce2f6ded..f90cd563f9254 100644 --- a/packages/router/src/router_config.ts +++ b/packages/router/src/router_config.ts @@ -8,6 +8,7 @@ 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; @@ -172,7 +173,8 @@ export interface InMemoryScrollingOptions { * * @publicApi */ -export interface ExtraOptions extends InMemoryScrollingOptions, RouterConfigOptions { +export interface ExtraOptions extends InMemoryScrollingOptions, RouterConfigOptions, + InternalExtraOptions { /** * When true, log all internal navigation events to the console. * Use for debugging. @@ -234,42 +236,6 @@ export interface ExtraOptions extends InMemoryScrollingOptions, RouterConfigOpti * */ malformedUriErrorHandler?: (error: URIError, urlSerializer: UrlSerializer, url: string) => UrlTree; - - /** - * Enables a bug fix that corrects relative link resolution in components with empty paths. - * Example: - * - * ``` - * const routes = [ - * { - * path: '', - * component: ContainerComponent, - * children: [ - * { path: 'a', component: AComponent }, - * { path: 'b', component: BComponent }, - * ] - * } - * ]; - * ``` - * - * From the `ContainerComponent`, you should be able to navigate to `AComponent` using - * the following `routerLink`, but it will not work if `relativeLinkResolution` is set - * to `'legacy'`: - * - * `Link to A` - * - * However, this will work: - * - * `Link to A` - * - * In other words, you're required to use `../` rather than `./` when the relative link - * resolution is set to `'legacy'`. - * - * The default in v11 is `corrected`. - * - * @deprecated - */ - relativeLinkResolution?: 'legacy'|'corrected'; } /** diff --git a/packages/router/test/integration.spec.ts b/packages/router/test/integration.spec.ts index 6e11e68561358..1e81786c59fde 100644 --- a/packages/router/test/integration.spec.ts +++ b/packages/router/test/integration.spec.ts @@ -83,45 +83,22 @@ describe('Integration', () => { ]); }))); - describe('relativeLinkResolution', () => { - beforeEach(inject([Router], (router: Router) => { - router.resetConfig([{ - path: 'foo', - children: [{path: 'bar', children: [{path: '', component: RelativeLinkCmp}]}] - }]); - })); - - it('should not ignore empty paths in legacy mode', - fakeAsync(inject([Router], (router: Router) => { - const warnSpy = spyOn(console, 'warn'); - router.relativeLinkResolution = 'legacy'; - const fixture = createRoot(router, RootCmp); - - router.navigateByUrl('/foo/bar'); - advance(fixture); - - const link = fixture.nativeElement.querySelector('a'); - expect(link.getAttribute('href')).toEqual('/foo/bar/simple'); - expect(warnSpy.calls.first().args[0]) - .toContain('/foo/bar/simple will change to /foo/simple'); - expect(warnSpy.calls.first().args[0]) - .toContain('relativeLinkResolution: \'legacy\' is deprecated'); - }))); - - it('should ignore empty paths in corrected mode', - fakeAsync(inject([Router], (router: Router) => { - router.relativeLinkResolution = 'corrected'; + it('should ignore empty paths in relative links', + fakeAsync(inject([Router], (router: Router) => { + router.resetConfig([{ + path: 'foo', + children: [{path: 'bar', children: [{path: '', component: RelativeLinkCmp}]}] + }]); - const fixture = createRoot(router, RootCmp); + const fixture = createRoot(router, RootCmp); - router.navigateByUrl('/foo/bar'); - advance(fixture); + router.navigateByUrl('/foo/bar'); + advance(fixture); - const link = fixture.nativeElement.querySelector('a'); - expect(link.getAttribute('href')).toEqual('/foo/simple'); - }))); - }); + const link = fixture.nativeElement.querySelector('a'); + expect(link.getAttribute('href')).toEqual('/foo/simple'); + }))); it('should set the restoredState to null when executing imperative navigations', fakeAsync(inject([Router], (router: Router) => { @@ -6474,55 +6451,31 @@ describe('Integration', () => { expect(relativeLinkCmp.buttonLink.urlTree.toString()).toEqual('/root/childRoot'); })); - describe('relativeLinkResolution', () => { - @Component({selector: 'link-cmp', template: `link`}) - class RelativeLinkCmp { - } - - @NgModule({ - declarations: [RelativeLinkCmp], - imports: [RouterModule.forChild([ - {path: 'foo/bar', children: [{path: '', component: RelativeLinkCmp}]}, - ])] - }) - class LazyLoadedModule { - } - - it('should not ignore empty path when in legacy mode', - fakeAsync(inject([Router], (router: Router) => { - const warnSpy = spyOn(console, 'warn'); - router.relativeLinkResolution = 'legacy'; - - const fixture = createRoot(router, RootCmp); - - router.resetConfig([{path: 'lazy', loadChildren: () => LazyLoadedModule}]); - - router.navigateByUrl('/lazy/foo/bar'); - advance(fixture); - - const link = fixture.nativeElement.querySelector('a'); - expect(link.getAttribute('href')).toEqual('/lazy/foo/bar/simple'); - expect(warnSpy.calls.first().args[0]) - .toContain('/lazy/foo/bar/simple will change to /lazy/foo/simple'); - expect(warnSpy.calls.first().args[0]) - .toContain('relativeLinkResolution: \'legacy\' is deprecated'); - }))); + it('should ignore empty path for relative links', + fakeAsync(inject([Router], (router: Router) => { + @Component({selector: 'link-cmp', template: `link`}) + class RelativeLinkCmp { + } - it('should ignore empty path when in corrected mode', - fakeAsync(inject([Router], (router: Router) => { - router.relativeLinkResolution = 'corrected'; + @NgModule({ + declarations: [RelativeLinkCmp], + imports: [RouterModule.forChild([ + {path: 'foo/bar', children: [{path: '', component: RelativeLinkCmp}]}, + ])] + }) + class LazyLoadedModule { + } - const fixture = createRoot(router, RootCmp); + const fixture = createRoot(router, RootCmp); - router.resetConfig([{path: 'lazy', loadChildren: () => LazyLoadedModule}]); + router.resetConfig([{path: 'lazy', loadChildren: () => LazyLoadedModule}]); - router.navigateByUrl('/lazy/foo/bar'); - advance(fixture); + router.navigateByUrl('/lazy/foo/bar'); + advance(fixture); - const link = fixture.nativeElement.querySelector('a'); - expect(link.getAttribute('href')).toEqual('/lazy/foo/simple'); - }))); - }); + const link = fixture.nativeElement.querySelector('a'); + expect(link.getAttribute('href')).toEqual('/lazy/foo/simple'); + }))); }); describe('Custom Route Reuse Strategy', () => {