├── BUILD_INFO ├── README.md ├── LICENSE ├── types ├── upgrade.d.ts ├── testing.d.ts └── router.d.ts ├── package.json └── fesm2022 ├── upgrade.mjs ├── router.mjs ├── router.mjs.map ├── upgrade.mjs.map ├── testing.mjs ├── testing.mjs.map └── _router_module-chunk.mjs /BUILD_INFO: -------------------------------------------------------------------------------- 1 | Wed Dec 17 01:42:26 UTC 2025 2 | 9fa77af1106578f4fe79e8091df0fab7ed66c096 3 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Angular 2 | 3 | The sources for this package are in the main [Angular](https://github.com/angular/angular) repo. Please file issues and pull requests against that repo. 4 | 5 | Usage information and reference details can be found in [Angular documentation](https://angular.dev/overview). 6 | 7 | License: MIT 8 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License 2 | 3 | Copyright (c) 2010-2025 Google LLC. https://angular.dev/license 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /types/upgrade.d.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @license Angular v21.1.0-next.3+sha-9fa77af 3 | * (c) 2010-2025 Google LLC. https://angular.dev/ 4 | * License: MIT 5 | */ 6 | 7 | import * as i0 from '@angular/core'; 8 | import { ComponentRef } from '@angular/core'; 9 | import { UpgradeModule } from '@angular/upgrade/static'; 10 | 11 | /** 12 | * Creates an initializer that sets up `ngRoute` integration 13 | * along with setting up the Angular router. 14 | * 15 | * @usageNotes 16 | * 17 | * For standalone applications: 18 | * ```ts 19 | * export const appConfig: ApplicationConfig = { 20 | * providers: [RouterUpgradeInitializer], 21 | * }; 22 | * ``` 23 | * 24 | * For NgModule based applications: 25 | * ```ts 26 | * @NgModule({ 27 | * imports: [ 28 | * RouterModule.forRoot(SOME_ROUTES), 29 | * UpgradeModule 30 | * ], 31 | * providers: [ 32 | * RouterUpgradeInitializer 33 | * ] 34 | * }) 35 | * export class AppModule { 36 | * ngDoBootstrap() {} 37 | * } 38 | * ``` 39 | * 40 | * @publicApi 41 | */ 42 | declare const RouterUpgradeInitializer: { 43 | provide: i0.InjectionToken) => void)[]>; 44 | multi: boolean; 45 | useFactory: () => () => void; 46 | }; 47 | /** 48 | * Sets up a location change listener to trigger `history.pushState`. 49 | * Works around the problem that `onPopState` does not trigger `history.pushState`. 50 | * Must be called *after* calling `UpgradeModule.bootstrap`. 51 | * 52 | * @param ngUpgrade The upgrade NgModule. 53 | * @param urlType The location strategy. 54 | * @see {@link /api/common/HashLocationStrategy HashLocationStrategy} 55 | * @see {@link /api/common/PathLocationStrategy PathLocationStrategy} 56 | * 57 | * @publicApi 58 | */ 59 | declare function setUpLocationSync(ngUpgrade: UpgradeModule, urlType?: 'path' | 'hash'): void; 60 | 61 | export { RouterUpgradeInitializer, setUpLocationSync }; 62 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@angular/router", 3 | "version": "21.1.0-next.3+sha-9fa77af", 4 | "description": "Angular - the routing library", 5 | "keywords": [ 6 | "angular", 7 | "router" 8 | ], 9 | "repository": { 10 | "type": "git", 11 | "url": "git+https://github.com/angular/angular.git", 12 | "directory": "packages/router" 13 | }, 14 | "author": "angular", 15 | "license": "MIT", 16 | "engines": { 17 | "node": "^20.19.0 || ^22.12.0 || >=24.0.0" 18 | }, 19 | "bugs": { 20 | "url": "https://github.com/angular/angular/issues" 21 | }, 22 | "homepage": "https://github.com/angular/angular/tree/main/packages/router", 23 | "dependencies": { 24 | "tslib": "^2.3.0" 25 | }, 26 | "devDependencies": { 27 | "@types/dom-navigation": "^1.0.5" 28 | }, 29 | "peerDependencies": { 30 | "@angular/core": "21.1.0-next.3+sha-9fa77af", 31 | "@angular/common": "21.1.0-next.3+sha-9fa77af", 32 | "@angular/platform-browser": "21.1.0-next.3+sha-9fa77af", 33 | "rxjs": "^6.5.3 || ^7.4.0" 34 | }, 35 | "ng-update": { 36 | "packageGroup": [ 37 | "@angular/core", 38 | "@angular/bazel", 39 | "@angular/common", 40 | "@angular/compiler", 41 | "@angular/compiler-cli", 42 | "@angular/animations", 43 | "@angular/elements", 44 | "@angular/platform-browser", 45 | "@angular/platform-browser-dynamic", 46 | "@angular/forms", 47 | "@angular/platform-server", 48 | "@angular/upgrade", 49 | "@angular/router", 50 | "@angular/language-service", 51 | "@angular/localize", 52 | "@angular/service-worker" 53 | ] 54 | }, 55 | "sideEffects": false, 56 | "module": "./fesm2022/router.mjs", 57 | "typings": "./types/router.d.ts", 58 | "type": "module", 59 | "exports": { 60 | "./package.json": { 61 | "default": "./package.json" 62 | }, 63 | ".": { 64 | "types": "./types/router.d.ts", 65 | "default": "./fesm2022/router.mjs" 66 | }, 67 | "./testing": { 68 | "types": "./types/testing.d.ts", 69 | "default": "./fesm2022/testing.mjs" 70 | }, 71 | "./upgrade": { 72 | "types": "./types/upgrade.d.ts", 73 | "default": "./fesm2022/upgrade.mjs" 74 | } 75 | } 76 | } -------------------------------------------------------------------------------- /fesm2022/upgrade.mjs: -------------------------------------------------------------------------------- 1 | /** 2 | * @license Angular v21.1.0-next.3+sha-9fa77af 3 | * (c) 2010-2025 Google LLC. https://angular.dev/ 4 | * License: MIT 5 | */ 6 | 7 | import { Location } from '@angular/common'; 8 | import { APP_BOOTSTRAP_LISTENER, inject } from '@angular/core'; 9 | import { UpgradeModule } from '@angular/upgrade/static'; 10 | import { Router } from './_router-chunk.mjs'; 11 | import 'rxjs'; 12 | import 'rxjs/operators'; 13 | import '@angular/platform-browser'; 14 | 15 | const RouterUpgradeInitializer = { 16 | provide: APP_BOOTSTRAP_LISTENER, 17 | multi: true, 18 | useFactory: locationSyncBootstrapListener 19 | }; 20 | function locationSyncBootstrapListener() { 21 | const ngUpgrade = inject(UpgradeModule); 22 | return () => { 23 | setUpLocationSync(ngUpgrade); 24 | }; 25 | } 26 | function setUpLocationSync(ngUpgrade, urlType = 'path') { 27 | if (!ngUpgrade.$injector) { 28 | throw new Error(` 29 | RouterUpgradeInitializer can be used only after UpgradeModule.bootstrap has been called. 30 | Remove RouterUpgradeInitializer and call setUpLocationSync after UpgradeModule.bootstrap. 31 | `); 32 | } 33 | const router = ngUpgrade.injector.get(Router); 34 | const location = ngUpgrade.injector.get(Location); 35 | ngUpgrade.$injector.get('$rootScope').$on('$locationChangeStart', (event, newUrl, oldUrl, newState, oldState) => { 36 | const currentNavigationId = router.getCurrentNavigation()?.id; 37 | const newStateNavigationId = newState?.navigationId; 38 | if (newStateNavigationId !== undefined && newStateNavigationId === currentNavigationId) { 39 | return; 40 | } 41 | let url; 42 | if (urlType === 'path') { 43 | url = resolveUrl(newUrl); 44 | } else if (urlType === 'hash') { 45 | const hashIdx = newUrl.indexOf('#'); 46 | url = resolveUrl(newUrl.substring(0, hashIdx) + newUrl.substring(hashIdx + 1)); 47 | } else { 48 | throw 'Invalid URLType passed to setUpLocationSync: ' + urlType; 49 | } 50 | const path = location.normalize(url.pathname); 51 | router.navigateByUrl(path + url.search + url.hash); 52 | }); 53 | } 54 | let anchor; 55 | function resolveUrl(url) { 56 | anchor ??= document.createElement('a'); 57 | anchor.setAttribute('href', url); 58 | anchor.setAttribute('href', anchor.href); 59 | return { 60 | pathname: `/${anchor.pathname.replace(/^\//, '')}`, 61 | search: anchor.search, 62 | hash: anchor.hash 63 | }; 64 | } 65 | 66 | export { RouterUpgradeInitializer, locationSyncBootstrapListener, setUpLocationSync }; 67 | //# sourceMappingURL=upgrade.mjs.map 68 | -------------------------------------------------------------------------------- /fesm2022/router.mjs: -------------------------------------------------------------------------------- 1 | /** 2 | * @license Angular v21.1.0-next.3+sha-9fa77af 3 | * (c) 2010-2025 Google LLC. https://angular.dev/ 4 | * License: MIT 5 | */ 6 | 7 | export { ActivatedRoute, ActivatedRouteSnapshot, ActivationEnd, ActivationStart, BaseRouteReuseStrategy, ChildActivationEnd, ChildActivationStart, ChildrenOutletContexts, DefaultTitleStrategy, DefaultUrlSerializer, EventType, GuardsCheckEnd, GuardsCheckStart, NavigationCancel, NavigationCancellationCode, NavigationEnd, NavigationError, NavigationSkipped, NavigationSkippedCode, NavigationStart, OutletContext, PRIMARY_OUTLET, ROUTER_CONFIGURATION, ROUTER_OUTLET_DATA, ROUTES, RedirectCommand, ResolveEnd, ResolveStart, RouteConfigLoadEnd, RouteConfigLoadStart, RouteReuseStrategy, Router, RouterEvent, RouterOutlet, RouterState, RouterStateSnapshot, RoutesRecognized, Scroll, TitleStrategy, UrlHandlingStrategy, UrlSegment, UrlSegmentGroup, UrlSerializer, UrlTree, convertToParamMap, createUrlTreeFromSnapshot, defaultUrlMatcher, ɵEmptyOutletComponent, afterNextNavigation as ɵafterNextNavigation, loadChildren as ɵloadChildren, provideSometimesSyncRecognize as ɵprovideSometimesSyncRecognize } from './_router-chunk.mjs'; 8 | export { NoPreloading, PreloadAllModules, PreloadingStrategy, ROUTER_INITIALIZER, RouterLink, RouterLinkActive, RouterLink as RouterLinkWithHref, RouterModule, RouterPreloader, provideRouter, provideRoutes, withComponentInputBinding, withDebugTracing, withDisabledInitialNavigation, withEnabledBlockingInitialNavigation, withHashLocation, withInMemoryScrolling, withNavigationErrorHandler, withPreloading, withRouterConfig, withViewTransitions, ROUTER_PROVIDERS as ɵROUTER_PROVIDERS, withPlatformNavigation as ɵwithPlatformNavigation } from './_router_module-chunk.mjs'; 9 | import { inject, Version } from '@angular/core'; 10 | import '@angular/common'; 11 | import 'rxjs'; 12 | import 'rxjs/operators'; 13 | import '@angular/platform-browser'; 14 | 15 | function mapToCanMatch(providers) { 16 | return providers.map(provider => (...params) => inject(provider).canMatch(...params)); 17 | } 18 | function mapToCanActivate(providers) { 19 | return providers.map(provider => (...params) => inject(provider).canActivate(...params)); 20 | } 21 | function mapToCanActivateChild(providers) { 22 | return providers.map(provider => (...params) => inject(provider).canActivateChild(...params)); 23 | } 24 | function mapToCanDeactivate(providers) { 25 | return providers.map(provider => (...params) => inject(provider).canDeactivate(...params)); 26 | } 27 | function mapToResolve(provider) { 28 | return (...params) => inject(provider).resolve(...params); 29 | } 30 | 31 | const VERSION = /* @__PURE__ */new Version('21.1.0-next.3+sha-9fa77af'); 32 | 33 | export { VERSION, mapToCanActivate, mapToCanActivateChild, mapToCanDeactivate, mapToCanMatch, mapToResolve }; 34 | //# sourceMappingURL=router.mjs.map 35 | -------------------------------------------------------------------------------- /fesm2022/router.mjs.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"router.mjs","sources":["../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/router/src/utils/functional_guards.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/router/src/version.ts"],"sourcesContent":["/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.dev/license\n */\n\nimport {inject, Type} from '@angular/core';\n\nimport {\n CanActivate,\n CanActivateChild,\n CanActivateChildFn,\n CanActivateFn,\n CanDeactivate,\n CanDeactivateFn,\n CanMatch,\n CanMatchFn,\n Resolve,\n ResolveFn,\n} from '../models';\n\n/**\n * Maps an array of injectable classes with canMatch functions to an array of equivalent\n * `CanMatchFn` for use in a `Route` definition.\n *\n * Usage {@example router/utils/functional_guards.ts region='CanActivate'}\n *\n * @publicApi\n * @see {@link Route}\n */\nexport function mapToCanMatch(providers: Array>): CanMatchFn[] {\n return providers.map(\n (provider) =>\n (...params) =>\n inject(provider).canMatch(...params),\n );\n}\n\n/**\n * Maps an array of injectable classes with canActivate functions to an array of equivalent\n * `CanActivateFn` for use in a `Route` definition.\n *\n * Usage {@example router/utils/functional_guards.ts region='CanActivate'}\n *\n * @publicApi\n * @see {@link Route}\n */\nexport function mapToCanActivate(providers: Array>): CanActivateFn[] {\n return providers.map(\n (provider) =>\n (...params) =>\n inject(provider).canActivate(...params),\n );\n}\n/**\n * Maps an array of injectable classes with canActivateChild functions to an array of equivalent\n * `CanActivateChildFn` for use in a `Route` definition.\n *\n * Usage {@example router/utils/functional_guards.ts region='CanActivate'}\n *\n * @publicApi\n * @see {@link Route}\n */\nexport function mapToCanActivateChild(\n providers: Array>,\n): CanActivateChildFn[] {\n return providers.map(\n (provider) =>\n (...params) =>\n inject(provider).canActivateChild(...params),\n );\n}\n/**\n * Maps an array of injectable classes with canDeactivate functions to an array of equivalent\n * `CanDeactivateFn` for use in a `Route` definition.\n *\n * Usage {@example router/utils/functional_guards.ts region='CanActivate'}\n *\n * @publicApi\n * @see {@link Route}\n */\nexport function mapToCanDeactivate(\n providers: Array>>,\n): CanDeactivateFn[] {\n return providers.map(\n (provider) =>\n (...params) =>\n inject(provider).canDeactivate(...params),\n );\n}\n/**\n * Maps an injectable class with a resolve function to an equivalent `ResolveFn`\n * for use in a `Route` definition.\n *\n * Usage {@example router/utils/functional_guards.ts region='Resolve'}\n *\n * @publicApi\n * @see {@link Route}\n */\nexport function mapToResolve(provider: Type>): ResolveFn {\n return (...params) => inject(provider).resolve(...params);\n}\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.dev/license\n */\n\n/**\n * @module\n * @description\n * Entry point for all public APIs of the router package.\n */\n\nimport {Version} from '@angular/core';\n\n/**\n * @publicApi\n */\nexport const VERSION = /* @__PURE__ */ new Version('21.1.0-next.3+sha-9fa77af');\n"],"names":["mapToCanMatch","providers","map","provider","params","inject","canMatch","mapToCanActivate","canActivate","mapToCanActivateChild","canActivateChild","mapToCanDeactivate","canDeactivate","mapToResolve","resolve","VERSION","Version"],"mappings":";;;;;;;;;;;;;;AAgCM,SAAUA,aAAaA,CAACC,SAAgC,EAAA;EAC5D,OAAOA,SAAS,CAACC,GAAG,CACjBC,QAAQ,IACP,CAAC,GAAGC,MAAM,KACRC,MAAM,CAACF,QAAQ,CAAC,CAACG,QAAQ,CAAC,GAAGF,MAAM,CAAC,CACzC;AACH;AAWM,SAAUG,gBAAgBA,CAACN,SAAmC,EAAA;EAClE,OAAOA,SAAS,CAACC,GAAG,CACjBC,QAAQ,IACP,CAAC,GAAGC,MAAM,KACRC,MAAM,CAACF,QAAQ,CAAC,CAACK,WAAW,CAAC,GAAGJ,MAAM,CAAC,CAC5C;AACH;AAUM,SAAUK,qBAAqBA,CACnCR,SAAwC,EAAA;EAExC,OAAOA,SAAS,CAACC,GAAG,CACjBC,QAAQ,IACP,CAAC,GAAGC,MAAM,KACRC,MAAM,CAACF,QAAQ,CAAC,CAACO,gBAAgB,CAAC,GAAGN,MAAM,CAAC,CACjD;AACH;AAUM,SAAUO,kBAAkBA,CAChCV,SAAwC,EAAA;EAExC,OAAOA,SAAS,CAACC,GAAG,CACjBC,QAAQ,IACP,CAAC,GAAGC,MAAM,KACRC,MAAM,CAACF,QAAQ,CAAC,CAACS,aAAa,CAAC,GAAGR,MAAM,CAAC,CAC9C;AACH;AAUM,SAAUS,YAAYA,CAAIV,QAA0B,EAAA;AACxD,EAAA,OAAO,CAAC,GAAGC,MAAM,KAAKC,MAAM,CAACF,QAAQ,CAAC,CAACW,OAAO,CAAC,GAAGV,MAAM,CAAC;AAC3D;;ACpFO,MAAMW,OAAO,kBAAmB,IAAIC,OAAO,CAAC,mBAAmB;;;;"} -------------------------------------------------------------------------------- /types/testing.d.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @license Angular v21.1.0-next.3+sha-9fa77af 3 | * (c) 2010-2025 Google LLC. https://angular.dev/ 4 | * License: MIT 5 | */ 6 | 7 | import * as i0 from '@angular/core'; 8 | import { ModuleWithProviders, WritableSignal, DebugElement, Type } from '@angular/core'; 9 | import { Routes, ExtraOptions, RouterModule } from './_router_module-chunk.js'; 10 | export { ɵEmptyOutletComponent as ɵɵEmptyOutletComponent, RouterLink as ɵɵRouterLink, RouterLinkActive as ɵɵRouterLinkActive, RouterOutlet as ɵɵRouterOutlet } from './_router_module-chunk.js'; 11 | import { ComponentFixture } from '@angular/core/testing'; 12 | import 'rxjs'; 13 | import '@angular/common'; 14 | 15 | /** 16 | * @description 17 | * 18 | * Sets up the router to be used for testing. 19 | * 20 | * The modules sets up the router to be used for testing. 21 | * It provides spy implementations of `Location` and `LocationStrategy`. 22 | * 23 | * @usageNotes 24 | * ### Example 25 | * 26 | * ```ts 27 | * beforeEach(() => { 28 | * TestBed.configureTestingModule({ 29 | * imports: [ 30 | * RouterModule.forRoot( 31 | * [{path: '', component: BlankCmp}, {path: 'simple', component: SimpleCmp}] 32 | * ) 33 | * ] 34 | * }); 35 | * }); 36 | * ``` 37 | * 38 | * @publicApi 39 | * @deprecated Use `provideRouter` or `RouterModule`/`RouterModule.forRoot` instead. 40 | * This module was previously used to provide a helpful collection of test fakes, 41 | * most notably those for `Location` and `LocationStrategy`. These are generally not 42 | * required anymore, as `MockPlatformLocation` is provided in `TestBed` by default. 43 | * However, you can use them directly with `provideLocationMocks`. 44 | */ 45 | declare class RouterTestingModule { 46 | static withRoutes(routes: Routes, config?: ExtraOptions): ModuleWithProviders; 47 | static ɵfac: i0.ɵɵFactoryDeclaration; 48 | static ɵmod: i0.ɵɵNgModuleDeclaration; 49 | static ɵinj: i0.ɵɵInjectorDeclaration; 50 | } 51 | 52 | /** 53 | * A testing harness for the `Router` to reduce the boilerplate needed to test routes and routed 54 | * components. 55 | * 56 | * @publicApi 57 | */ 58 | declare class RouterTestingHarness { 59 | /** 60 | * Creates a `RouterTestingHarness` instance. 61 | * 62 | * The `RouterTestingHarness` also creates its own root component with a `RouterOutlet` for the 63 | * purposes of rendering route components. 64 | * 65 | * Throws an error if an instance has already been created. 66 | * Use of this harness also requires `destroyAfterEach: true` in the `ModuleTeardownOptions` 67 | * 68 | * @param initialUrl The target of navigation to trigger before returning the harness. 69 | */ 70 | static create(initialUrl?: string): Promise; 71 | /** 72 | * Fixture of the root component of the RouterTestingHarness 73 | */ 74 | readonly fixture: ComponentFixture<{ 75 | routerOutletData: WritableSignal; 76 | }>; 77 | /** Instructs the root fixture to run change detection. */ 78 | detectChanges(): void; 79 | /** The `DebugElement` of the `RouterOutlet` component. `null` if the outlet is not activated. */ 80 | get routeDebugElement(): DebugElement | null; 81 | /** The native element of the `RouterOutlet` component. `null` if the outlet is not activated. */ 82 | get routeNativeElement(): HTMLElement | null; 83 | /** 84 | * Triggers a `Router` navigation and waits for it to complete. 85 | * 86 | * The root component with a `RouterOutlet` created for the harness is used to render `Route` 87 | * components. The root component is reused within the same test in subsequent calls to 88 | * `navigateForTest`. 89 | * 90 | * When testing `Routes` with a guards that reject the navigation, the `RouterOutlet` might not be 91 | * activated and the `activatedComponent` may be `null`. 92 | * 93 | * {@example router/testing/test/router_testing_harness_examples.spec.ts region='Guard'} 94 | * 95 | * @param url The target of the navigation. Passed to `Router.navigateByUrl`. 96 | * @returns The activated component instance of the `RouterOutlet` after navigation completes 97 | * (`null` if the outlet does not get activated). 98 | */ 99 | navigateByUrl(url: string): Promise; 100 | /** 101 | * Triggers a router navigation and waits for it to complete. 102 | * 103 | * The root component with a `RouterOutlet` created for the harness is used to render `Route` 104 | * components. 105 | * 106 | * {@example router/testing/test/router_testing_harness_examples.spec.ts region='RoutedComponent'} 107 | * 108 | * The root component is reused within the same test in subsequent calls to `navigateByUrl`. 109 | * 110 | * This function also makes it easier to test components that depend on `ActivatedRoute` data. 111 | * 112 | * {@example router/testing/test/router_testing_harness_examples.spec.ts region='ActivatedRoute'} 113 | * 114 | * @param url The target of the navigation. Passed to `Router.navigateByUrl`. 115 | * @param requiredRoutedComponentType After navigation completes, the required type for the 116 | * activated component of the `RouterOutlet`. If the outlet is not activated or a different 117 | * component is activated, this function will throw an error. 118 | * @returns The activated component instance of the `RouterOutlet` after navigation completes. 119 | */ 120 | navigateByUrl(url: string, requiredRoutedComponentType: Type): Promise; 121 | } 122 | 123 | export { RouterTestingHarness, RouterTestingModule }; 124 | -------------------------------------------------------------------------------- /fesm2022/upgrade.mjs.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"upgrade.mjs","sources":["../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/router/upgrade/src/upgrade.ts"],"sourcesContent":["/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.dev/license\n */\n\nimport {Location} from '@angular/common';\nimport {APP_BOOTSTRAP_LISTENER, ComponentRef, inject} from '@angular/core';\nimport {Router, ɵRestoredState as RestoredState} from '../../index';\nimport {UpgradeModule} from '@angular/upgrade/static';\n\n/**\n * Creates an initializer that sets up `ngRoute` integration\n * along with setting up the Angular router.\n *\n * @usageNotes\n *\n * For standalone applications:\n * ```ts\n * export const appConfig: ApplicationConfig = {\n * providers: [RouterUpgradeInitializer],\n * };\n * ```\n *\n * For NgModule based applications:\n * ```ts\n * @NgModule({\n * imports: [\n * RouterModule.forRoot(SOME_ROUTES),\n * UpgradeModule\n * ],\n * providers: [\n * RouterUpgradeInitializer\n * ]\n * })\n * export class AppModule {\n * ngDoBootstrap() {}\n * }\n * ```\n *\n * @publicApi\n */\nexport const RouterUpgradeInitializer = {\n provide: APP_BOOTSTRAP_LISTENER,\n multi: true,\n useFactory: locationSyncBootstrapListener as () => () => void,\n};\n\n/**\n * @internal\n */\nexport function locationSyncBootstrapListener() {\n const ngUpgrade = inject(UpgradeModule);\n\n return () => {\n setUpLocationSync(ngUpgrade);\n };\n}\n\n/**\n * Sets up a location change listener to trigger `history.pushState`.\n * Works around the problem that `onPopState` does not trigger `history.pushState`.\n * Must be called *after* calling `UpgradeModule.bootstrap`.\n *\n * @param ngUpgrade The upgrade NgModule.\n * @param urlType The location strategy.\n * @see {@link /api/common/HashLocationStrategy HashLocationStrategy}\n * @see {@link /api/common/PathLocationStrategy PathLocationStrategy}\n *\n * @publicApi\n */\nexport function setUpLocationSync(\n ngUpgrade: UpgradeModule,\n urlType: 'path' | 'hash' = 'path',\n): void {\n if (!ngUpgrade.$injector) {\n throw new Error(`\n RouterUpgradeInitializer can be used only after UpgradeModule.bootstrap has been called.\n Remove RouterUpgradeInitializer and call setUpLocationSync after UpgradeModule.bootstrap.\n `);\n }\n\n const router: Router = ngUpgrade.injector.get(Router);\n const location: Location = ngUpgrade.injector.get(Location);\n\n ngUpgrade.$injector\n .get('$rootScope')\n .$on(\n '$locationChangeStart',\n (\n event: any,\n newUrl: string,\n oldUrl: string,\n newState?: {[k: string]: unknown} | RestoredState,\n oldState?: {[k: string]: unknown} | RestoredState,\n ) => {\n // Navigations coming from Angular router have a navigationId state\n // property. Don't trigger Angular router navigation again if it is\n // caused by a URL change from the current Angular router\n // navigation.\n const currentNavigationId = router.getCurrentNavigation()?.id;\n const newStateNavigationId = newState?.navigationId;\n if (newStateNavigationId !== undefined && newStateNavigationId === currentNavigationId) {\n return;\n }\n\n let url;\n if (urlType === 'path') {\n url = resolveUrl(newUrl);\n } else if (urlType === 'hash') {\n // Remove the first hash from the URL\n const hashIdx = newUrl.indexOf('#');\n url = resolveUrl(newUrl.substring(0, hashIdx) + newUrl.substring(hashIdx + 1));\n } else {\n throw 'Invalid URLType passed to setUpLocationSync: ' + urlType;\n }\n const path = location.normalize(url.pathname);\n router.navigateByUrl(path + url.search + url.hash);\n },\n );\n}\n\n/**\n * Normalizes and parses a URL.\n *\n * - Normalizing means that a relative URL will be resolved into an absolute URL in the context of\n * the application document.\n * - Parsing means that the anchor's `protocol`, `hostname`, `port`, `pathname` and related\n * properties are all populated to reflect the normalized URL.\n *\n * While this approach has wide compatibility, it doesn't work as expected on IE. On IE, normalizing\n * happens similar to other browsers, but the parsed components will not be set. (E.g. if you assign\n * `a.href = 'foo'`, then `a.protocol`, `a.host`, etc. will not be correctly updated.)\n * We work around that by performing the parsing in a 2nd step by taking a previously normalized URL\n * and assigning it again. This correctly populates all properties.\n *\n * See\n * https://github.com/angular/angular.js/blob/2c7400e7d07b0f6cec1817dab40b9250ce8ebce6/src/ng/urlUtils.js#L26-L33\n * for more info.\n */\nlet anchor: HTMLAnchorElement | undefined;\nfunction resolveUrl(url: string): {pathname: string; search: string; hash: string} {\n anchor ??= document.createElement('a');\n\n anchor.setAttribute('href', url);\n anchor.setAttribute('href', anchor.href);\n\n return {\n // IE does not start `pathname` with `/` like other browsers.\n pathname: `/${anchor.pathname.replace(/^\\//, '')}`,\n search: anchor.search,\n hash: anchor.hash,\n };\n}\n"],"names":["RouterUpgradeInitializer","provide","APP_BOOTSTRAP_LISTENER","multi","useFactory","locationSyncBootstrapListener","ngUpgrade","inject","UpgradeModule","setUpLocationSync","urlType","$injector","Error","router","injector","get","Router","location","Location","$on","event","newUrl","oldUrl","newState","oldState","currentNavigationId","getCurrentNavigation","id","newStateNavigationId","navigationId","undefined","url","resolveUrl","hashIdx","indexOf","substring","path","normalize","pathname","navigateByUrl","search","hash","anchor","document","createElement","setAttribute","href","replace"],"mappings":";;;;;;;;;;;;;;AA4CO,MAAMA,wBAAwB,GAAG;AACtCC,EAAAA,OAAO,EAAEC,sBAAsB;AAC/BC,EAAAA,KAAK,EAAE,IAAI;AACXC,EAAAA,UAAU,EAAEC;;SAMEA,6BAA6BA,GAAA;AAC3C,EAAA,MAAMC,SAAS,GAAGC,MAAM,CAACC,aAAa,CAAC;AAEvC,EAAA,OAAO,MAAK;IACVC,iBAAiB,CAACH,SAAS,CAAC;GAC7B;AACH;SAcgBG,iBAAiBA,CAC/BH,SAAwB,EACxBI,UAA2B,MAAM,EAAA;AAEjC,EAAA,IAAI,CAACJ,SAAS,CAACK,SAAS,EAAE;IACxB,MAAM,IAAIC,KAAK,CAAC;;;AAGb,MAAA,CAAA,CAAC;AACN;EAEA,MAAMC,MAAM,GAAWP,SAAS,CAACQ,QAAQ,CAACC,GAAG,CAACC,MAAM,CAAC;EACrD,MAAMC,QAAQ,GAAaX,SAAS,CAACQ,QAAQ,CAACC,GAAG,CAACG,QAAQ,CAAC;EAE3DZ,SAAS,CAACK,SAAS,CAChBI,GAAG,CAAC,YAAY,CAAA,CAChBI,GAAG,CACF,sBAAsB,EACtB,CACEC,KAAU,EACVC,MAAc,EACdC,MAAc,EACdC,QAAiD,EACjDC,QAAiD,KAC/C;IAKF,MAAMC,mBAAmB,GAAGZ,MAAM,CAACa,oBAAoB,EAAE,EAAEC,EAAE;AAC7D,IAAA,MAAMC,oBAAoB,GAAGL,QAAQ,EAAEM,YAAY;AACnD,IAAA,IAAID,oBAAoB,KAAKE,SAAS,IAAIF,oBAAoB,KAAKH,mBAAmB,EAAE;AACtF,MAAA;AACF;AAEA,IAAA,IAAIM,GAAG;IACP,IAAIrB,OAAO,KAAK,MAAM,EAAE;AACtBqB,MAAAA,GAAG,GAAGC,UAAU,CAACX,MAAM,CAAC;AAC1B,KAAA,MAAO,IAAIX,OAAO,KAAK,MAAM,EAAE;AAE7B,MAAA,MAAMuB,OAAO,GAAGZ,MAAM,CAACa,OAAO,CAAC,GAAG,CAAC;MACnCH,GAAG,GAAGC,UAAU,CAACX,MAAM,CAACc,SAAS,CAAC,CAAC,EAAEF,OAAO,CAAC,GAAGZ,MAAM,CAACc,SAAS,CAACF,OAAO,GAAG,CAAC,CAAC,CAAC;AAChF,KAAA,MAAO;MACL,MAAM,+CAA+C,GAAGvB,OAAO;AACjE;IACA,MAAM0B,IAAI,GAAGnB,QAAQ,CAACoB,SAAS,CAACN,GAAG,CAACO,QAAQ,CAAC;AAC7CzB,IAAAA,MAAM,CAAC0B,aAAa,CAACH,IAAI,GAAGL,GAAG,CAACS,MAAM,GAAGT,GAAG,CAACU,IAAI,CAAC;AACpD,GAAC,CACF;AACL;AAoBA,IAAIC,MAAqC;AACzC,SAASV,UAAUA,CAACD,GAAW,EAAA;AAC7BW,EAAAA,MAAM,KAAKC,QAAQ,CAACC,aAAa,CAAC,GAAG,CAAC;AAEtCF,EAAAA,MAAM,CAACG,YAAY,CAAC,MAAM,EAAEd,GAAG,CAAC;EAChCW,MAAM,CAACG,YAAY,CAAC,MAAM,EAAEH,MAAM,CAACI,IAAI,CAAC;EAExC,OAAO;AAELR,IAAAA,QAAQ,EAAE,CAAA,CAAA,EAAII,MAAM,CAACJ,QAAQ,CAACS,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAE,CAAA;IAClDP,MAAM,EAAEE,MAAM,CAACF,MAAM;IACrBC,IAAI,EAAEC,MAAM,CAACD;GACd;AACH;;;;"} -------------------------------------------------------------------------------- /fesm2022/testing.mjs: -------------------------------------------------------------------------------- 1 | /** 2 | * @license Angular v21.1.0-next.3+sha-9fa77af 3 | * (c) 2010-2025 Google LLC. https://angular.dev/ 4 | * License: MIT 5 | */ 6 | 7 | import * as i0 from '@angular/core'; 8 | import { NgModule, Injectable, signal, Component, ViewChild } from '@angular/core'; 9 | import { TestBed } from '@angular/core/testing'; 10 | import { ROUTES, ROUTER_CONFIGURATION, RouterOutlet, Router, afterNextNavigation } from './_router-chunk.mjs'; 11 | export { ɵEmptyOutletComponent as ɵɵEmptyOutletComponent } from './_router-chunk.mjs'; 12 | import { RouterModule, ROUTER_PROVIDERS, withPreloading, NoPreloading } from './_router_module-chunk.mjs'; 13 | export { RouterLink as ɵɵRouterLink, RouterLinkActive as ɵɵRouterLinkActive } from './_router_module-chunk.mjs'; 14 | import { provideLocationMocks } from '@angular/common/testing'; 15 | import '@angular/common'; 16 | import 'rxjs'; 17 | import 'rxjs/operators'; 18 | import '@angular/platform-browser'; 19 | 20 | class RouterTestingModule { 21 | static withRoutes(routes, config) { 22 | return { 23 | ngModule: RouterTestingModule, 24 | providers: [{ 25 | provide: ROUTES, 26 | multi: true, 27 | useValue: routes 28 | }, { 29 | provide: ROUTER_CONFIGURATION, 30 | useValue: config ? config : {} 31 | }] 32 | }; 33 | } 34 | static ɵfac = i0.ɵɵngDeclareFactory({ 35 | minVersion: "12.0.0", 36 | version: "21.1.0-next.3+sha-9fa77af", 37 | ngImport: i0, 38 | type: RouterTestingModule, 39 | deps: [], 40 | target: i0.ɵɵFactoryTarget.NgModule 41 | }); 42 | static ɵmod = i0.ɵɵngDeclareNgModule({ 43 | minVersion: "14.0.0", 44 | version: "21.1.0-next.3+sha-9fa77af", 45 | ngImport: i0, 46 | type: RouterTestingModule, 47 | exports: [RouterModule] 48 | }); 49 | static ɵinj = i0.ɵɵngDeclareInjector({ 50 | minVersion: "12.0.0", 51 | version: "21.1.0-next.3+sha-9fa77af", 52 | ngImport: i0, 53 | type: RouterTestingModule, 54 | providers: [ROUTER_PROVIDERS, provideLocationMocks(), withPreloading(NoPreloading).ɵproviders, { 55 | provide: ROUTES, 56 | multi: true, 57 | useValue: [] 58 | }], 59 | imports: [RouterModule] 60 | }); 61 | } 62 | i0.ɵɵngDeclareClassMetadata({ 63 | minVersion: "12.0.0", 64 | version: "21.1.0-next.3+sha-9fa77af", 65 | ngImport: i0, 66 | type: RouterTestingModule, 67 | decorators: [{ 68 | type: NgModule, 69 | args: [{ 70 | exports: [RouterModule], 71 | providers: [ROUTER_PROVIDERS, provideLocationMocks(), withPreloading(NoPreloading).ɵproviders, { 72 | provide: ROUTES, 73 | multi: true, 74 | useValue: [] 75 | }] 76 | }] 77 | }] 78 | }); 79 | 80 | class RootFixtureService { 81 | fixture; 82 | harness; 83 | createHarness() { 84 | if (this.harness) { 85 | throw new Error('Only one harness should be created per test.'); 86 | } 87 | this.harness = new RouterTestingHarness(this.getRootFixture()); 88 | return this.harness; 89 | } 90 | getRootFixture() { 91 | if (this.fixture !== undefined) { 92 | return this.fixture; 93 | } 94 | this.fixture = TestBed.createComponent(RootCmp); 95 | this.fixture.detectChanges(); 96 | return this.fixture; 97 | } 98 | static ɵfac = i0.ɵɵngDeclareFactory({ 99 | minVersion: "12.0.0", 100 | version: "21.1.0-next.3+sha-9fa77af", 101 | ngImport: i0, 102 | type: RootFixtureService, 103 | deps: [], 104 | target: i0.ɵɵFactoryTarget.Injectable 105 | }); 106 | static ɵprov = i0.ɵɵngDeclareInjectable({ 107 | minVersion: "12.0.0", 108 | version: "21.1.0-next.3+sha-9fa77af", 109 | ngImport: i0, 110 | type: RootFixtureService, 111 | providedIn: 'root' 112 | }); 113 | } 114 | i0.ɵɵngDeclareClassMetadata({ 115 | minVersion: "12.0.0", 116 | version: "21.1.0-next.3+sha-9fa77af", 117 | ngImport: i0, 118 | type: RootFixtureService, 119 | decorators: [{ 120 | type: Injectable, 121 | args: [{ 122 | providedIn: 'root' 123 | }] 124 | }] 125 | }); 126 | class RootCmp { 127 | outlet; 128 | routerOutletData = signal(undefined, ...(ngDevMode ? [{ 129 | debugName: "routerOutletData" 130 | }] : [])); 131 | static ɵfac = i0.ɵɵngDeclareFactory({ 132 | minVersion: "12.0.0", 133 | version: "21.1.0-next.3+sha-9fa77af", 134 | ngImport: i0, 135 | type: RootCmp, 136 | deps: [], 137 | target: i0.ɵɵFactoryTarget.Component 138 | }); 139 | static ɵcmp = i0.ɵɵngDeclareComponent({ 140 | minVersion: "14.0.0", 141 | version: "21.1.0-next.3+sha-9fa77af", 142 | type: RootCmp, 143 | isStandalone: true, 144 | selector: "ng-component", 145 | viewQueries: [{ 146 | propertyName: "outlet", 147 | first: true, 148 | predicate: RouterOutlet, 149 | descendants: true 150 | }], 151 | ngImport: i0, 152 | template: '', 153 | isInline: true, 154 | dependencies: [{ 155 | kind: "directive", 156 | type: RouterOutlet, 157 | selector: "router-outlet", 158 | inputs: ["name", "routerOutletData"], 159 | outputs: ["activate", "deactivate", "attach", "detach"], 160 | exportAs: ["outlet"] 161 | }] 162 | }); 163 | } 164 | i0.ɵɵngDeclareClassMetadata({ 165 | minVersion: "12.0.0", 166 | version: "21.1.0-next.3+sha-9fa77af", 167 | ngImport: i0, 168 | type: RootCmp, 169 | decorators: [{ 170 | type: Component, 171 | args: [{ 172 | template: '', 173 | imports: [RouterOutlet] 174 | }] 175 | }], 176 | propDecorators: { 177 | outlet: [{ 178 | type: ViewChild, 179 | args: [RouterOutlet] 180 | }] 181 | } 182 | }); 183 | class RouterTestingHarness { 184 | static async create(initialUrl) { 185 | const harness = TestBed.inject(RootFixtureService).createHarness(); 186 | if (initialUrl !== undefined) { 187 | await harness.navigateByUrl(initialUrl); 188 | } 189 | return harness; 190 | } 191 | fixture; 192 | constructor(fixture) { 193 | this.fixture = fixture; 194 | } 195 | detectChanges() { 196 | this.fixture.detectChanges(); 197 | } 198 | get routeDebugElement() { 199 | const outlet = this.fixture.componentInstance.outlet; 200 | if (!outlet || !outlet.isActivated) { 201 | return null; 202 | } 203 | return this.fixture.debugElement.query(v => v.componentInstance === outlet.component); 204 | } 205 | get routeNativeElement() { 206 | return this.routeDebugElement?.nativeElement ?? null; 207 | } 208 | async navigateByUrl(url, requiredRoutedComponentType) { 209 | const router = TestBed.inject(Router); 210 | let resolveFn; 211 | const redirectTrackingPromise = new Promise(resolve => { 212 | resolveFn = resolve; 213 | }); 214 | afterNextNavigation(TestBed.inject(Router), resolveFn); 215 | await router.navigateByUrl(url); 216 | await redirectTrackingPromise; 217 | this.fixture.detectChanges(); 218 | const outlet = this.fixture.componentInstance.outlet; 219 | if (outlet && outlet.isActivated && outlet.activatedRoute.component) { 220 | const activatedComponent = outlet.component; 221 | if (requiredRoutedComponentType !== undefined && !(activatedComponent instanceof requiredRoutedComponentType)) { 222 | throw new Error(`Unexpected routed component type. Expected ${requiredRoutedComponentType.name} but got ${activatedComponent.constructor.name}`); 223 | } 224 | return activatedComponent; 225 | } else { 226 | if (requiredRoutedComponentType !== undefined) { 227 | throw new Error(`Unexpected routed component type. Expected ${requiredRoutedComponentType.name} but the navigation did not activate any component.`); 228 | } 229 | return null; 230 | } 231 | } 232 | } 233 | 234 | export { RouterTestingHarness, RouterTestingModule, RouterOutlet as ɵɵRouterOutlet }; 235 | //# sourceMappingURL=testing.mjs.map 236 | -------------------------------------------------------------------------------- /fesm2022/testing.mjs.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"testing.mjs","sources":["../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/router/testing/src/router_testing_module.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/router/testing/src/router_testing_harness.ts"],"sourcesContent":["/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.dev/license\n */\n\nimport {provideLocationMocks} from '@angular/common/testing';\nimport {ModuleWithProviders, NgModule} from '@angular/core';\nimport {\n ExtraOptions,\n NoPreloading,\n ROUTER_CONFIGURATION,\n RouterModule,\n ROUTES,\n Routes,\n withPreloading,\n ɵROUTER_PROVIDERS as ROUTER_PROVIDERS,\n} from '../../index';\n\n/**\n * @description\n *\n * Sets up the router to be used for testing.\n *\n * The modules sets up the router to be used for testing.\n * It provides spy implementations of `Location` and `LocationStrategy`.\n *\n * @usageNotes\n * ### Example\n *\n * ```ts\n * beforeEach(() => {\n * TestBed.configureTestingModule({\n * imports: [\n * RouterModule.forRoot(\n * [{path: '', component: BlankCmp}, {path: 'simple', component: SimpleCmp}]\n * )\n * ]\n * });\n * });\n * ```\n *\n * @publicApi\n * @deprecated Use `provideRouter` or `RouterModule`/`RouterModule.forRoot` instead.\n * This module was previously used to provide a helpful collection of test fakes,\n * most notably those for `Location` and `LocationStrategy`. These are generally not\n * required anymore, as `MockPlatformLocation` is provided in `TestBed` by default.\n * However, you can use them directly with `provideLocationMocks`.\n */\n@NgModule({\n exports: [RouterModule],\n providers: [\n ROUTER_PROVIDERS,\n provideLocationMocks(),\n withPreloading(NoPreloading).ɵproviders,\n {provide: ROUTES, multi: true, useValue: []},\n ],\n})\nexport class RouterTestingModule {\n static withRoutes(\n routes: Routes,\n config?: ExtraOptions,\n ): ModuleWithProviders {\n return {\n ngModule: RouterTestingModule,\n providers: [\n {provide: ROUTES, multi: true, useValue: routes},\n {provide: ROUTER_CONFIGURATION, useValue: config ? config : {}},\n ],\n };\n }\n}\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.dev/license\n */\n\nimport {\n Component,\n DebugElement,\n Injectable,\n Type,\n ViewChild,\n WritableSignal,\n signal,\n} from '@angular/core';\nimport {ComponentFixture, TestBed} from '@angular/core/testing';\nimport {Router, RouterOutlet, ɵafterNextNavigation as afterNextNavigation} from '../../index';\n\n@Injectable({providedIn: 'root'})\nexport class RootFixtureService {\n private fixture?: ComponentFixture;\n private harness?: RouterTestingHarness;\n\n createHarness(): RouterTestingHarness {\n if (this.harness) {\n throw new Error('Only one harness should be created per test.');\n }\n this.harness = new RouterTestingHarness(this.getRootFixture());\n return this.harness;\n }\n\n private getRootFixture(): ComponentFixture {\n if (this.fixture !== undefined) {\n return this.fixture;\n }\n this.fixture = TestBed.createComponent(RootCmp);\n this.fixture.detectChanges();\n return this.fixture;\n }\n}\n\n@Component({\n template: '',\n imports: [RouterOutlet],\n})\nexport class RootCmp {\n @ViewChild(RouterOutlet) outlet?: RouterOutlet;\n readonly routerOutletData = signal(undefined);\n}\n\n/**\n * A testing harness for the `Router` to reduce the boilerplate needed to test routes and routed\n * components.\n *\n * @publicApi\n */\nexport class RouterTestingHarness {\n /**\n * Creates a `RouterTestingHarness` instance.\n *\n * The `RouterTestingHarness` also creates its own root component with a `RouterOutlet` for the\n * purposes of rendering route components.\n *\n * Throws an error if an instance has already been created.\n * Use of this harness also requires `destroyAfterEach: true` in the `ModuleTeardownOptions`\n *\n * @param initialUrl The target of navigation to trigger before returning the harness.\n */\n static async create(initialUrl?: string): Promise {\n const harness = TestBed.inject(RootFixtureService).createHarness();\n if (initialUrl !== undefined) {\n await harness.navigateByUrl(initialUrl);\n }\n return harness;\n }\n\n /**\n * Fixture of the root component of the RouterTestingHarness\n */\n public readonly fixture: ComponentFixture<{routerOutletData: WritableSignal}>;\n\n /** @internal */\n constructor(fixture: ComponentFixture<{routerOutletData: WritableSignal}>) {\n this.fixture = fixture;\n }\n\n /** Instructs the root fixture to run change detection. */\n detectChanges(): void {\n this.fixture.detectChanges();\n }\n /** The `DebugElement` of the `RouterOutlet` component. `null` if the outlet is not activated. */\n get routeDebugElement(): DebugElement | null {\n const outlet = (this.fixture.componentInstance as RootCmp).outlet;\n if (!outlet || !outlet.isActivated) {\n return null;\n }\n return this.fixture.debugElement.query((v) => v.componentInstance === outlet.component);\n }\n /** The native element of the `RouterOutlet` component. `null` if the outlet is not activated. */\n get routeNativeElement(): HTMLElement | null {\n return this.routeDebugElement?.nativeElement ?? null;\n }\n\n /**\n * Triggers a `Router` navigation and waits for it to complete.\n *\n * The root component with a `RouterOutlet` created for the harness is used to render `Route`\n * components. The root component is reused within the same test in subsequent calls to\n * `navigateForTest`.\n *\n * When testing `Routes` with a guards that reject the navigation, the `RouterOutlet` might not be\n * activated and the `activatedComponent` may be `null`.\n *\n * {@example router/testing/test/router_testing_harness_examples.spec.ts region='Guard'}\n *\n * @param url The target of the navigation. Passed to `Router.navigateByUrl`.\n * @returns The activated component instance of the `RouterOutlet` after navigation completes\n * (`null` if the outlet does not get activated).\n */\n async navigateByUrl(url: string): Promise;\n /**\n * Triggers a router navigation and waits for it to complete.\n *\n * The root component with a `RouterOutlet` created for the harness is used to render `Route`\n * components.\n *\n * {@example router/testing/test/router_testing_harness_examples.spec.ts region='RoutedComponent'}\n *\n * The root component is reused within the same test in subsequent calls to `navigateByUrl`.\n *\n * This function also makes it easier to test components that depend on `ActivatedRoute` data.\n *\n * {@example router/testing/test/router_testing_harness_examples.spec.ts region='ActivatedRoute'}\n *\n * @param url The target of the navigation. Passed to `Router.navigateByUrl`.\n * @param requiredRoutedComponentType After navigation completes, the required type for the\n * activated component of the `RouterOutlet`. If the outlet is not activated or a different\n * component is activated, this function will throw an error.\n * @returns The activated component instance of the `RouterOutlet` after navigation completes.\n */\n async navigateByUrl(url: string, requiredRoutedComponentType: Type): Promise;\n async navigateByUrl(url: string, requiredRoutedComponentType?: Type): Promise {\n const router = TestBed.inject(Router);\n let resolveFn!: () => void;\n const redirectTrackingPromise = new Promise((resolve) => {\n resolveFn = resolve;\n });\n afterNextNavigation(TestBed.inject(Router), resolveFn);\n await router.navigateByUrl(url);\n await redirectTrackingPromise;\n this.fixture.detectChanges();\n const outlet = (this.fixture.componentInstance as RootCmp).outlet;\n // The outlet might not be activated if the user is testing a navigation for a guard that\n // rejects\n if (outlet && outlet.isActivated && outlet.activatedRoute.component) {\n const activatedComponent = outlet.component;\n if (\n requiredRoutedComponentType !== undefined &&\n !(activatedComponent instanceof requiredRoutedComponentType)\n ) {\n throw new Error(\n `Unexpected routed component type. Expected ${requiredRoutedComponentType.name} but got ${activatedComponent.constructor.name}`,\n );\n }\n return activatedComponent as T;\n } else {\n if (requiredRoutedComponentType !== undefined) {\n throw new Error(\n `Unexpected routed component type. Expected ${requiredRoutedComponentType.name} but the navigation did not activate any component.`,\n );\n }\n return null;\n }\n }\n}\n"],"names":["RouterTestingModule","withRoutes","routes","config","ngModule","providers","provide","ROUTES","multi","useValue","ROUTER_CONFIGURATION","deps","target","i0","ɵɵFactoryTarget","NgModule","ɵmod","ɵɵngDeclareNgModule","minVersion","version","ngImport","type","RouterModule","ɵinj","ɵɵngDeclareInjector","ROUTER_PROVIDERS","provideLocationMocks","withPreloading","NoPreloading","ɵproviders","imports","decorators","args","exports","RootFixtureService","fixture","harness","createHarness","Error","RouterTestingHarness","getRootFixture","undefined","TestBed","createComponent","RootCmp","detectChanges","Injectable","ɵprov","ɵɵngDeclareInjectable","providedIn","outlet","routerOutletData","signal","Component","ɵcmp","ɵɵngDeclareComponent","isStandalone","selector","viewQueries","propertyName","first","predicate","RouterOutlet","descendants","template","inputs","outputs","exportAs","ViewChild","create","initialUrl","inject","navigateByUrl","constructor","routeDebugElement","componentInstance","isActivated","debugElement","query","v","component","routeNativeElement","nativeElement","url","requiredRoutedComponentType","router","Router","resolveFn","redirectTrackingPromise","Promise","resolve","afterNextNavigation","activatedRoute","activatedComponent","name"],"mappings":";;;;;;;;;;;;;;;;;;;MA4DaA,mBAAmB,CAAA;AAC9B,EAAA,OAAOC,UAAUA,CACfC,MAAc,EACdC,MAAqB,EAAA;IAErB,OAAO;AACLC,MAAAA,QAAQ,EAAEJ,mBAAmB;AAC7BK,MAAAA,SAAS,EAAE,CACT;AAACC,QAAAA,OAAO,EAAEC,MAAM;AAAEC,QAAAA,KAAK,EAAE,IAAI;AAAEC,QAAAA,QAAQ,EAAEP;AAAO,OAAA,EAChD;AAACI,QAAAA,OAAO,EAAEI,oBAAoB;AAAED,QAAAA,QAAQ,EAAEN,MAAM,GAAGA,MAAM,GAAG;OAAG;KAElE;AACH;;;;;UAZWH,mBAAmB;AAAAW,IAAAA,IAAA,EAAA,EAAA;AAAAC,IAAAA,MAAA,EAAAC,EAAA,CAAAC,eAAA,CAAAC;AAAA,GAAA,CAAA;AAAnB,EAAA,OAAAC,IAAA,GAAAH,EAAA,CAAAI,mBAAA,CAAA;AAAAC,IAAAA,UAAA,EAAA,QAAA;AAAAC,IAAAA,OAAA,EAAA,mBAAA;AAAAC,IAAAA,QAAA,EAAAP,EAAA;AAAAQ,IAAAA,IAAA,EAAArB,mBAAmB;cARpBsB,YAAY;AAAA,GAAA,CAAA;AAQX,EAAA,OAAAC,IAAA,GAAAV,EAAA,CAAAW,mBAAA,CAAA;AAAAN,IAAAA,UAAA,EAAA,QAAA;AAAAC,IAAAA,OAAA,EAAA,mBAAA;AAAAC,IAAAA,QAAA,EAAAP,EAAA;AAAAQ,IAAAA,IAAA,EAAArB,mBAAmB;AAPnBK,IAAAA,SAAA,EAAA,CACToB,gBAAgB,EAChBC,oBAAoB,EAAE,EACtBC,cAAc,CAACC,YAAY,CAAC,CAACC,UAAU,EACvC;AAACvB,MAAAA,OAAO,EAAEC,MAAM;AAAEC,MAAAA,KAAK,EAAE,IAAI;AAAEC,MAAAA,QAAQ,EAAE;AAAG,KAAA,CAC7C;IAAAqB,OAAA,EAAA,CANSR,YAAY;AAAA,GAAA,CAAA;;;;;;QAQXtB,mBAAmB;AAAA+B,EAAAA,UAAA,EAAA,CAAA;UAT/BhB,QAAQ;AAACiB,IAAAA,IAAA,EAAA,CAAA;MACRC,OAAO,EAAE,CAACX,YAAY,CAAC;AACvBjB,MAAAA,SAAS,EAAE,CACToB,gBAAgB,EAChBC,oBAAoB,EAAE,EACtBC,cAAc,CAACC,YAAY,CAAC,CAACC,UAAU,EACvC;AAACvB,QAAAA,OAAO,EAAEC,MAAM;AAAEC,QAAAA,KAAK,EAAE,IAAI;AAAEC,QAAAA,QAAQ,EAAE;OAAG;KAE/C;;;;MCtCYyB,kBAAkB,CAAA;EACrBC,OAAO;EACPC,OAAO;AAEfC,EAAAA,aAAaA,GAAA;IACX,IAAI,IAAI,CAACD,OAAO,EAAE;AAChB,MAAA,MAAM,IAAIE,KAAK,CAAC,8CAA8C,CAAC;AACjE;IACA,IAAI,CAACF,OAAO,GAAG,IAAIG,oBAAoB,CAAC,IAAI,CAACC,cAAc,EAAE,CAAC;IAC9D,OAAO,IAAI,CAACJ,OAAO;AACrB;AAEQI,EAAAA,cAAcA,GAAA;AACpB,IAAA,IAAI,IAAI,CAACL,OAAO,KAAKM,SAAS,EAAE;MAC9B,OAAO,IAAI,CAACN,OAAO;AACrB;IACA,IAAI,CAACA,OAAO,GAAGO,OAAO,CAACC,eAAe,CAACC,OAAO,CAAC;AAC/C,IAAA,IAAI,CAACT,OAAO,CAACU,aAAa,EAAE;IAC5B,OAAO,IAAI,CAACV,OAAO;AACrB;;;;;UAnBWD,kBAAkB;AAAAvB,IAAAA,IAAA,EAAA,EAAA;AAAAC,IAAAA,MAAA,EAAAC,EAAA,CAAAC,eAAA,CAAAgC;AAAA,GAAA,CAAA;AAAlB,EAAA,OAAAC,KAAA,GAAAlC,EAAA,CAAAmC,qBAAA,CAAA;AAAA9B,IAAAA,UAAA,EAAA,QAAA;AAAAC,IAAAA,OAAA,EAAA,mBAAA;AAAAC,IAAAA,QAAA,EAAAP,EAAA;AAAAQ,IAAAA,IAAA,EAAAa,kBAAkB;gBADN;AAAM,GAAA,CAAA;;;;;;QAClBA,kBAAkB;AAAAH,EAAAA,UAAA,EAAA,CAAA;UAD9Be,UAAU;WAAC;AAACG,MAAAA,UAAU,EAAE;KAAO;;;MA2BnBL,OAAO,CAAA;EACOM,MAAM;EACtBC,gBAAgB,GAAGC,MAAM,CAAUX,SAAS;;WAAC;;;;;UAF3CG,OAAO;AAAAjC,IAAAA,IAAA,EAAA,EAAA;AAAAC,IAAAA,MAAA,EAAAC,EAAA,CAAAC,eAAA,CAAAuC;AAAA,GAAA,CAAA;AAAP,EAAA,OAAAC,IAAA,GAAAzC,EAAA,CAAA0C,oBAAA,CAAA;AAAArC,IAAAA,UAAA,EAAA,QAAA;AAAAC,IAAAA,OAAA,EAAA,mBAAA;AAAAE,IAAAA,IAAA,EAAAuB,OAAO;AACPY,IAAAA,YAAA,EAAA,IAAA;AAAAC,IAAAA,QAAA,EAAA,cAAA;AAAAC,IAAAA,WAAA,EAAA,CAAA;AAAAC,MAAAA,YAAA,EAAA,QAAA;AAAAC,MAAAA,KAAA,EAAA,IAAA;AAAAC,MAAAA,SAAA,EAAAC,YAAY;AAJbC,MAAAA,WAAA,EAAA;AAAA,KAAA,CAAA;AAAA3C,IAAAA,QAAA,EAAAP,EAAA;AAAAmD,IAAAA,QAAA,EAAA,yEAAyE;;;;YACzEF,YAAY;AAAAL,MAAAA,QAAA,EAAA,eAAA;AAAAQ,MAAAA,MAAA,EAAA,CAAA,MAAA,EAAA,kBAAA,CAAA;MAAAC,OAAA,EAAA,CAAA,UAAA,EAAA,YAAA,EAAA,QAAA,EAAA,QAAA,CAAA;MAAAC,QAAA,EAAA,CAAA,QAAA;KAAA;AAAA,GAAA,CAAA;;;;;;QAEXvB,OAAO;AAAAb,EAAAA,UAAA,EAAA,CAAA;UAJnBsB,SAAS;AAACrB,IAAAA,IAAA,EAAA,CAAA;AACTgC,MAAAA,QAAQ,EAAE,yEAAyE;MACnFlC,OAAO,EAAE,CAACgC,YAAY;KACvB;;;;YAEEM,SAAS;aAACN,YAAY;;;;MAUZvB,oBAAoB,CAAA;EAY/B,aAAa8B,MAAMA,CAACC,UAAmB,EAAA;IACrC,MAAMlC,OAAO,GAAGM,OAAO,CAAC6B,MAAM,CAACrC,kBAAkB,CAAC,CAACG,aAAa,EAAE;IAClE,IAAIiC,UAAU,KAAK7B,SAAS,EAAE;AAC5B,MAAA,MAAML,OAAO,CAACoC,aAAa,CAACF,UAAU,CAAC;AACzC;AACA,IAAA,OAAOlC,OAAO;AAChB;EAKgBD,OAAO;EAGvBsC,WAAAA,CAAYtC,OAAsE,EAAA;IAChF,IAAI,CAACA,OAAO,GAAGA,OAAO;AACxB;AAGAU,EAAAA,aAAaA,GAAA;AACX,IAAA,IAAI,CAACV,OAAO,CAACU,aAAa,EAAE;AAC9B;EAEA,IAAI6B,iBAAiBA,GAAA;IACnB,MAAMxB,MAAM,GAAI,IAAI,CAACf,OAAO,CAACwC,iBAA6B,CAACzB,MAAM;AACjE,IAAA,IAAI,CAACA,MAAM,IAAI,CAACA,MAAM,CAAC0B,WAAW,EAAE;AAClC,MAAA,OAAO,IAAI;AACb;AACA,IAAA,OAAO,IAAI,CAACzC,OAAO,CAAC0C,YAAY,CAACC,KAAK,CAAEC,CAAC,IAAKA,CAAC,CAACJ,iBAAiB,KAAKzB,MAAM,CAAC8B,SAAS,CAAC;AACzF;EAEA,IAAIC,kBAAkBA,GAAA;AACpB,IAAA,OAAO,IAAI,CAACP,iBAAiB,EAAEQ,aAAa,IAAI,IAAI;AACtD;AAwCA,EAAA,MAAMV,aAAaA,CAAIW,GAAW,EAAEC,2BAAqC,EAAA;AACvE,IAAA,MAAMC,MAAM,GAAG3C,OAAO,CAAC6B,MAAM,CAACe,MAAM,CAAC;AACrC,IAAA,IAAIC,SAAsB;AAC1B,IAAA,MAAMC,uBAAuB,GAAG,IAAIC,OAAO,CAAQC,OAAO,IAAI;AAC5DH,MAAAA,SAAS,GAAGG,OAAO;AACrB,KAAC,CAAC;IACFC,mBAAmB,CAACjD,OAAO,CAAC6B,MAAM,CAACe,MAAM,CAAC,EAAEC,SAAS,CAAC;AACtD,IAAA,MAAMF,MAAM,CAACb,aAAa,CAACW,GAAG,CAAC;AAC/B,IAAA,MAAMK,uBAAuB;AAC7B,IAAA,IAAI,CAACrD,OAAO,CAACU,aAAa,EAAE;IAC5B,MAAMK,MAAM,GAAI,IAAI,CAACf,OAAO,CAACwC,iBAA6B,CAACzB,MAAM;IAGjE,IAAIA,MAAM,IAAIA,MAAM,CAAC0B,WAAW,IAAI1B,MAAM,CAAC0C,cAAc,CAACZ,SAAS,EAAE;AACnE,MAAA,MAAMa,kBAAkB,GAAG3C,MAAM,CAAC8B,SAAS;MAC3C,IACEI,2BAA2B,KAAK3C,SAAS,IACzC,EAAEoD,kBAAkB,YAAYT,2BAA2B,CAAC,EAC5D;AACA,QAAA,MAAM,IAAI9C,KAAK,CACb,CAAA,2CAAA,EAA8C8C,2BAA2B,CAACU,IAAI,CAAYD,SAAAA,EAAAA,kBAAkB,CAACpB,WAAW,CAACqB,IAAI,EAAE,CAChI;AACH;AACA,MAAA,OAAOD,kBAAuB;AAChC,KAAA,MAAO;MACL,IAAIT,2BAA2B,KAAK3C,SAAS,EAAE;QAC7C,MAAM,IAAIH,KAAK,CACb,CAAA,2CAAA,EAA8C8C,2BAA2B,CAACU,IAAI,qDAAqD,CACpI;AACH;AACA,MAAA,OAAO,IAAI;AACb;AACF;AACD;;;;"} -------------------------------------------------------------------------------- /types/router.d.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @license Angular v21.1.0-next.3+sha-9fa77af 3 | * (c) 2010-2025 Google LLC. https://angular.dev/ 4 | * License: MIT 5 | */ 6 | 7 | import { ActivatedRouteSnapshot, Params, DefaultUrlSerializer, UrlTree, RouterOutletContract, ActivatedRoute, RouterStateSnapshot, Route, LoadedRouterConfig, Router, Routes, InMemoryScrollingOptions, RouterConfigOptions, NavigationError, RedirectCommand, CanMatch, CanMatchFn, CanActivate, CanActivateFn, CanActivateChild, CanActivateChildFn, CanDeactivate, CanDeactivateFn, Resolve, ResolveFn, Event } from './_router_module-chunk.js'; 8 | export { ActivationEnd, ActivationStart, BaseRouteReuseStrategy, CanLoad, CanLoadFn, ChildActivationEnd, ChildActivationStart, Data, DefaultExport, DeprecatedGuard, DeprecatedResolve, DetachedRouteHandle, EventType, ExtraOptions, GuardResult, GuardsCheckEnd, GuardsCheckStart, InitialNavigation, IsActiveMatchOptions, LoadChildren, LoadChildrenCallback, MaybeAsync, Navigation, NavigationBehaviorOptions, NavigationCancel, NavigationCancellationCode, NavigationEnd, NavigationExtras, NavigationSkipped, NavigationSkippedCode, NavigationStart, OnSameUrlNavigation, PRIMARY_OUTLET, ParamMap, QueryParamsHandling, ROUTER_CONFIGURATION, ROUTER_INITIALIZER, ROUTER_OUTLET_DATA, RedirectFunction, ResolveData, ResolveEnd, ResolveStart, RouteConfigLoadEnd, RouteConfigLoadStart, RouteReuseStrategy, RouterEvent, RouterLink, RouterLinkActive, RouterLink as RouterLinkWithHref, RouterModule, RouterOutlet, RouterState, RoutesRecognized, RunGuardsAndResolvers, Scroll, UrlCreationOptions, UrlMatchResult, UrlMatcher, UrlSegment, UrlSegmentGroup, UrlSerializer, convertToParamMap, defaultUrlMatcher, ɵEmptyOutletComponent, ROUTER_PROVIDERS as ɵROUTER_PROVIDERS, RestoredState as ɵRestoredState } from './_router_module-chunk.js'; 9 | import { Title } from '@angular/platform-browser'; 10 | import * as i0 from '@angular/core'; 11 | import { ComponentRef, EnvironmentInjector, InjectionToken, Compiler, Injector, Type, OnDestroy, EnvironmentProviders, Provider, Version } from '@angular/core'; 12 | import { Observable } from 'rxjs'; 13 | import '@angular/common'; 14 | 15 | /** 16 | * Creates a `UrlTree` relative to an `ActivatedRouteSnapshot`. 17 | * 18 | * @publicApi 19 | * 20 | * 21 | * @param relativeTo The `ActivatedRouteSnapshot` to apply the commands to 22 | * @param commands An array of URL fragments with which to construct the new URL tree. 23 | * If the path is static, can be the literal URL string. For a dynamic path, pass an array of path 24 | * segments, followed by the parameters for each segment. 25 | * The fragments are applied to the one provided in the `relativeTo` parameter. 26 | * @param queryParams The query parameters for the `UrlTree`. `null` if the `UrlTree` does not have 27 | * any query parameters. 28 | * @param fragment The fragment for the `UrlTree`. `null` if the `UrlTree` does not have a fragment. 29 | * @param urlSerializer The `UrlSerializer` to use for handling query parameter normalization. 30 | * You should provide your application's custom `UrlSerializer` if one is configured to parse and 31 | * serialize query parameter values to and from objects other than strings/string arrays. 32 | * 33 | * @usageNotes 34 | * 35 | * ```ts 36 | * // create /team/33/user/11 37 | * createUrlTreeFromSnapshot(snapshot, ['/team', 33, 'user', 11]); 38 | * 39 | * // create /team/33;expand=true/user/11 40 | * createUrlTreeFromSnapshot(snapshot, ['/team', 33, {expand: true}, 'user', 11]); 41 | * 42 | * // you can collapse static segments like this (this works only with the first passed-in value): 43 | * createUrlTreeFromSnapshot(snapshot, ['/team/33/user', userId]); 44 | * 45 | * // If the first segment can contain slashes, and you do not want the router to split it, 46 | * // you can do the following: 47 | * createUrlTreeFromSnapshot(snapshot, [{segmentPath: '/one/two'}]); 48 | * 49 | * // create /team/33/(user/11//right:chat) 50 | * createUrlTreeFromSnapshot(snapshot, ['/team', 33, {outlets: {primary: 'user/11', right: 51 | * 'chat'}}], null, null); 52 | * 53 | * // remove the right secondary node 54 | * createUrlTreeFromSnapshot(snapshot, ['/team', 33, {outlets: {primary: 'user/11', right: null}}]); 55 | * 56 | * // For the examples below, assume the current URL is for the `/team/33/user/11` and the 57 | * `ActivatedRouteSnapshot` points to `user/11`: 58 | * 59 | * // navigate to /team/33/user/11/details 60 | * createUrlTreeFromSnapshot(snapshot, ['details']); 61 | * 62 | * // navigate to /team/33/user/22 63 | * createUrlTreeFromSnapshot(snapshot, ['../22']); 64 | * 65 | * // navigate to /team/44/user/22 66 | * createUrlTreeFromSnapshot(snapshot, ['../../team/44/user/22']); 67 | * ``` 68 | */ 69 | declare function createUrlTreeFromSnapshot(relativeTo: ActivatedRouteSnapshot, commands: readonly any[], queryParams?: Params | null, fragment?: string | null, urlSerializer?: DefaultUrlSerializer): UrlTree; 70 | 71 | /** 72 | * Store contextual information about a `RouterOutlet` 73 | * 74 | * @publicApi 75 | */ 76 | declare class OutletContext { 77 | private readonly rootInjector; 78 | outlet: RouterOutletContract | null; 79 | route: ActivatedRoute | null; 80 | children: ChildrenOutletContexts; 81 | attachRef: ComponentRef | null; 82 | get injector(): EnvironmentInjector; 83 | constructor(rootInjector: EnvironmentInjector); 84 | } 85 | /** 86 | * Store contextual information about the children (= nested) `RouterOutlet` 87 | * 88 | * @publicApi 89 | */ 90 | declare class ChildrenOutletContexts { 91 | private rootInjector; 92 | private contexts; 93 | /** @docs-private */ 94 | constructor(rootInjector: EnvironmentInjector); 95 | /** Called when a `RouterOutlet` directive is instantiated */ 96 | onChildOutletCreated(childName: string, outlet: RouterOutletContract): void; 97 | /** 98 | * Called when a `RouterOutlet` directive is destroyed. 99 | * We need to keep the context as the outlet could be destroyed inside a NgIf and might be 100 | * re-created later. 101 | */ 102 | onChildOutletDestroyed(childName: string): void; 103 | /** 104 | * Called when the corresponding route is deactivated during navigation. 105 | * Because the component get destroyed, all children outlet are destroyed. 106 | */ 107 | onOutletDeactivated(): Map; 108 | onOutletReAttached(contexts: Map): void; 109 | getOrCreateContext(childName: string): OutletContext; 110 | getContext(childName: string): OutletContext | null; 111 | static ɵfac: i0.ɵɵFactoryDeclaration; 112 | static ɵprov: i0.ɵɵInjectableDeclaration; 113 | } 114 | 115 | /** 116 | * Options to configure the View Transitions integration in the Router. 117 | * 118 | * @developerPreview 20.0 119 | * @see withViewTransitions 120 | */ 121 | interface ViewTransitionsFeatureOptions { 122 | /** 123 | * Skips the very first call to `startViewTransition`. This can be useful for disabling the 124 | * animation during the application's initial loading phase. 125 | */ 126 | skipInitialTransition?: boolean; 127 | /** 128 | * A function to run after the `ViewTransition` is created. 129 | * 130 | * This function is run in an injection context and can use `inject`. 131 | */ 132 | onViewTransitionCreated?: (transitionInfo: ViewTransitionInfo) => void; 133 | } 134 | /** 135 | * The information passed to the `onViewTransitionCreated` function provided in the 136 | * `withViewTransitions` feature options. 137 | * 138 | * @developerPreview 20.0 139 | */ 140 | interface ViewTransitionInfo { 141 | /** 142 | * The `ViewTransition` returned by the call to `startViewTransition`. 143 | * @see https://developer.mozilla.org/en-US/docs/Web/API/ViewTransition 144 | */ 145 | transition: ViewTransition; 146 | /** 147 | * The `ActivatedRouteSnapshot` that the navigation is transitioning from. 148 | */ 149 | from: ActivatedRouteSnapshot; 150 | /** 151 | * The `ActivatedRouteSnapshot` that the navigation is transitioning to. 152 | */ 153 | to: ActivatedRouteSnapshot; 154 | } 155 | 156 | /** 157 | * Provides a strategy for setting the page title after a router navigation. 158 | * 159 | * The built-in implementation traverses the router state snapshot and finds the deepest primary 160 | * outlet with `title` property. Given the `Routes` below, navigating to 161 | * `/base/child(popup:aux)` would result in the document title being set to "child". 162 | * ```ts 163 | * [ 164 | * {path: 'base', title: 'base', children: [ 165 | * {path: 'child', title: 'child'}, 166 | * ], 167 | * {path: 'aux', outlet: 'popup', title: 'popupTitle'} 168 | * ] 169 | * ``` 170 | * 171 | * This class can be used as a base class for custom title strategies. That is, you can create your 172 | * own class that extends the `TitleStrategy`. Note that in the above example, the `title` 173 | * from the named outlet is never used. However, a custom strategy might be implemented to 174 | * incorporate titles in named outlets. 175 | * 176 | * @publicApi 177 | * @see [Page title guide](guide/routing/define-routes#using-titlestrategy-for-page-titles) 178 | */ 179 | declare abstract class TitleStrategy { 180 | /** Performs the application title update. */ 181 | abstract updateTitle(snapshot: RouterStateSnapshot): void; 182 | /** 183 | * @returns The `title` of the deepest primary route. 184 | */ 185 | buildTitle(snapshot: RouterStateSnapshot): string | undefined; 186 | /** 187 | * Given an `ActivatedRouteSnapshot`, returns the final value of the 188 | * `Route.title` property, which can either be a static string or a resolved value. 189 | */ 190 | getResolvedTitleForRoute(snapshot: ActivatedRouteSnapshot): any; 191 | static ɵfac: i0.ɵɵFactoryDeclaration; 192 | static ɵprov: i0.ɵɵInjectableDeclaration; 193 | } 194 | /** 195 | * The default `TitleStrategy` used by the router that updates the title using the `Title` service. 196 | */ 197 | declare class DefaultTitleStrategy extends TitleStrategy { 198 | readonly title: Title; 199 | constructor(title: Title); 200 | /** 201 | * Sets the title of the browser to the given value. 202 | * 203 | * @param title The `pageTitle` from the deepest primary route. 204 | */ 205 | updateTitle(snapshot: RouterStateSnapshot): void; 206 | static ɵfac: i0.ɵɵFactoryDeclaration; 207 | static ɵprov: i0.ɵɵInjectableDeclaration; 208 | } 209 | 210 | /** 211 | * The DI token for a router configuration. 212 | * 213 | * `ROUTES` is a low level API for router configuration via dependency injection. 214 | * 215 | * We recommend that in almost all cases to use higher level APIs such as `RouterModule.forRoot()`, 216 | * `provideRouter`, or `Router.resetConfig()`. 217 | * 218 | * @publicApi 219 | */ 220 | declare const ROUTES: InjectionToken; 221 | declare class RouterConfigLoader { 222 | private componentLoaders; 223 | private childrenLoaders; 224 | onLoadStartListener?: (r: Route) => void; 225 | onLoadEndListener?: (r: Route) => void; 226 | private readonly compiler; 227 | loadComponent(injector: EnvironmentInjector, route: Route): Promise>; 228 | loadChildren(parentInjector: Injector, route: Route): Promise; 229 | static ɵfac: i0.ɵɵFactoryDeclaration; 230 | static ɵprov: i0.ɵɵInjectableDeclaration; 231 | } 232 | /** 233 | * Executes a `route.loadChildren` callback and converts the result to an array of child routes and 234 | * an injector if that callback returned a module. 235 | * 236 | * This function is used for the route discovery during prerendering 237 | * in @angular-devkit/build-angular. If there are any updates to the contract here, it will require 238 | * an update to the extractor. 239 | */ 240 | declare function loadChildren(route: Route, compiler: Compiler, parentInjector: Injector, onLoadEndListener?: (r: Route) => void): Promise; 241 | 242 | /** 243 | * @description 244 | * 245 | * Provides a preloading strategy. 246 | * 247 | * @see [Preloading strategy](guide/routing/customizing-route-behavior#preloading-strategy) 248 | * @publicApi 249 | */ 250 | declare abstract class PreloadingStrategy { 251 | abstract preload(route: Route, fn: () => Observable): Observable; 252 | } 253 | /** 254 | * @description 255 | * 256 | * Provides a preloading strategy that preloads all modules as quickly as possible. 257 | * 258 | * ```ts 259 | * RouterModule.forRoot(ROUTES, {preloadingStrategy: PreloadAllModules}) 260 | * ``` 261 | * 262 | * ```ts 263 | * export const appConfig: ApplicationConfig = { 264 | * providers: [ 265 | * provideRouter( 266 | * routes, 267 | * withPreloading(PreloadAllModules) 268 | * ) 269 | * ] 270 | * }; 271 | * ``` 272 | * 273 | * 274 | * @see [Preloading strategy](guide/routing/customizing-route-behavior#preloading-strategy) 275 | * 276 | * @publicApi 277 | */ 278 | declare class PreloadAllModules implements PreloadingStrategy { 279 | preload(route: Route, fn: () => Observable): Observable; 280 | static ɵfac: i0.ɵɵFactoryDeclaration; 281 | static ɵprov: i0.ɵɵInjectableDeclaration; 282 | } 283 | /** 284 | * @description 285 | * 286 | * Provides a preloading strategy that does not preload any modules. 287 | * 288 | * This strategy is enabled by default. 289 | * 290 | * @see [Preloading strategy](guide/routing/customizing-route-behavior#preloading-strategy) 291 | * 292 | * @publicApi 293 | */ 294 | declare class NoPreloading implements PreloadingStrategy { 295 | preload(route: Route, fn: () => Observable): Observable; 296 | static ɵfac: i0.ɵɵFactoryDeclaration; 297 | static ɵprov: i0.ɵɵInjectableDeclaration; 298 | } 299 | /** 300 | * The preloader optimistically loads all router configurations to 301 | * make navigations into lazily-loaded sections of the application faster. 302 | * 303 | * The preloader runs in the background. When the router bootstraps, the preloader 304 | * starts listening to all navigation events. After every such event, the preloader 305 | * will check if any configurations can be loaded lazily. 306 | * 307 | * If a route is protected by `canLoad` guards, the preloaded will not load it. 308 | * 309 | * @publicApi 310 | */ 311 | declare class RouterPreloader implements OnDestroy { 312 | private router; 313 | private injector; 314 | private preloadingStrategy; 315 | private loader; 316 | private subscription?; 317 | constructor(router: Router, injector: EnvironmentInjector, preloadingStrategy: PreloadingStrategy, loader: RouterConfigLoader); 318 | setUpPreloading(): void; 319 | preload(): Observable; 320 | /** @docs-private */ 321 | ngOnDestroy(): void; 322 | private processRoutes; 323 | private preloadConfig; 324 | static ɵfac: i0.ɵɵFactoryDeclaration; 325 | static ɵprov: i0.ɵɵInjectableDeclaration; 326 | } 327 | 328 | /** 329 | * Sets up providers necessary to enable `Router` functionality for the application. 330 | * Allows to configure a set of routes as well as extra features that should be enabled. 331 | * 332 | * @usageNotes 333 | * 334 | * Basic example of how you can add a Router to your application: 335 | * ```ts 336 | * const appRoutes: Routes = []; 337 | * bootstrapApplication(AppComponent, { 338 | * providers: [provideRouter(appRoutes)] 339 | * }); 340 | * ``` 341 | * 342 | * You can also enable optional features in the Router by adding functions from the `RouterFeatures` 343 | * type: 344 | * ```ts 345 | * const appRoutes: Routes = []; 346 | * bootstrapApplication(AppComponent, 347 | * { 348 | * providers: [ 349 | * provideRouter(appRoutes, 350 | * withDebugTracing(), 351 | * withRouterConfig({paramsInheritanceStrategy: 'always'})) 352 | * ] 353 | * } 354 | * ); 355 | * ``` 356 | * @see [Router](guide/routing) 357 | * 358 | * @see {@link RouterFeatures} 359 | * 360 | * @publicApi 361 | * @param routes A set of `Route`s to use for the application routing table. 362 | * @param features Optional features to configure additional router behaviors. 363 | * @returns A set of providers to setup a Router. 364 | */ 365 | declare function provideRouter(routes: Routes, ...features: RouterFeatures[]): EnvironmentProviders; 366 | /** 367 | * Helper type to represent a Router feature. 368 | * 369 | * @publicApi 370 | */ 371 | interface RouterFeature { 372 | ɵkind: FeatureKind; 373 | ɵproviders: Array; 374 | } 375 | /** 376 | * Registers a DI provider for a set of routes. 377 | * @param routes The route configuration to provide. 378 | * 379 | * @usageNotes 380 | * 381 | * ```ts 382 | * @NgModule({ 383 | * providers: [provideRoutes(ROUTES)] 384 | * }) 385 | * class LazyLoadedChildModule {} 386 | * ``` 387 | * 388 | * @deprecated If necessary, provide routes using the `ROUTES` `InjectionToken`. 389 | * @see {@link ROUTES} 390 | * @publicApi 391 | */ 392 | declare function provideRoutes(routes: Routes): Provider[]; 393 | /** 394 | * A type alias for providers returned by `withInMemoryScrolling` for use with `provideRouter`. 395 | * 396 | * @see {@link withInMemoryScrolling} 397 | * @see {@link provideRouter} 398 | * 399 | * @publicApi 400 | */ 401 | type InMemoryScrollingFeature = RouterFeature; 402 | /** 403 | * Enables customizable scrolling behavior for router navigations. 404 | * 405 | * @usageNotes 406 | * 407 | * Basic example of how you can enable scrolling feature: 408 | * ```ts 409 | * const appRoutes: Routes = []; 410 | * bootstrapApplication(AppComponent, 411 | * { 412 | * providers: [ 413 | * provideRouter(appRoutes, withInMemoryScrolling()) 414 | * ] 415 | * } 416 | * ); 417 | * ``` 418 | * 419 | * @see {@link provideRouter} 420 | * @see {@link ViewportScroller} 421 | * 422 | * @publicApi 423 | * @param options Set of configuration parameters to customize scrolling behavior, see 424 | * `InMemoryScrollingOptions` for additional information. 425 | * @returns A set of providers for use with `provideRouter`. 426 | */ 427 | declare function withInMemoryScrolling(options?: InMemoryScrollingOptions): InMemoryScrollingFeature; 428 | /** 429 | * Enables the use of the browser's `History` API for navigation. 430 | * 431 | * @description 432 | * This function provides a `Location` strategy that uses the browser's `History` API. 433 | * It is required when using features that rely on `history.state`. For example, the 434 | * `state` object in `NavigationExtras` is passed to `history.pushState` or 435 | * `history.replaceState`. 436 | * 437 | * @usageNotes 438 | * 439 | * ```typescript 440 | * const appRoutes: Routes = [ 441 | * { path: 'page', component: PageComponent }, 442 | * ]; 443 | * 444 | * bootstrapApplication(AppComponent, { 445 | * providers: [ 446 | * provideRouter(appRoutes, withPlatformNavigation()) 447 | * ] 448 | * }); 449 | * ``` 450 | * 451 | * @returns A `RouterFeature` that enables the platform navigation. 452 | */ 453 | declare function withPlatformNavigation(): RouterFeature; 454 | /** 455 | * A type alias for providers returned by `withEnabledBlockingInitialNavigation` for use with 456 | * `provideRouter`. 457 | * 458 | * @see {@link withEnabledBlockingInitialNavigation} 459 | * @see {@link provideRouter} 460 | * 461 | * @publicApi 462 | */ 463 | type EnabledBlockingInitialNavigationFeature = RouterFeature; 464 | /** 465 | * A type alias for providers returned by `withEnabledBlockingInitialNavigation` or 466 | * `withDisabledInitialNavigation` functions for use with `provideRouter`. 467 | * 468 | * @see {@link withEnabledBlockingInitialNavigation} 469 | * @see {@link withDisabledInitialNavigation} 470 | * @see {@link provideRouter} 471 | * 472 | * @publicApi 473 | */ 474 | type InitialNavigationFeature = EnabledBlockingInitialNavigationFeature | DisabledInitialNavigationFeature; 475 | /** 476 | * Configures initial navigation to start before the root component is created. 477 | * 478 | * The bootstrap is blocked until the initial navigation is complete. This should be set in case 479 | * you use [server-side rendering](guide/ssr), but do not enable [hydration](guide/hydration) for 480 | * your application. 481 | * 482 | * @usageNotes 483 | * 484 | * Basic example of how you can enable this navigation behavior: 485 | * ```ts 486 | * const appRoutes: Routes = []; 487 | * bootstrapApplication(AppComponent, 488 | * { 489 | * providers: [ 490 | * provideRouter(appRoutes, withEnabledBlockingInitialNavigation()) 491 | * ] 492 | * } 493 | * ); 494 | * ``` 495 | * 496 | * @see {@link provideRouter} 497 | * 498 | * @publicApi 499 | * @returns A set of providers for use with `provideRouter`. 500 | */ 501 | declare function withEnabledBlockingInitialNavigation(): EnabledBlockingInitialNavigationFeature; 502 | /** 503 | * A type alias for providers returned by `withDisabledInitialNavigation` for use with 504 | * `provideRouter`. 505 | * 506 | * @see {@link withDisabledInitialNavigation} 507 | * @see {@link provideRouter} 508 | * 509 | * @publicApi 510 | */ 511 | type DisabledInitialNavigationFeature = RouterFeature; 512 | /** 513 | * Disables initial navigation. 514 | * 515 | * Use if there is a reason to have more control over when the router starts its initial navigation 516 | * due to some complex initialization logic. 517 | * 518 | * @usageNotes 519 | * 520 | * Basic example of how you can disable initial navigation: 521 | * ```ts 522 | * const appRoutes: Routes = []; 523 | * bootstrapApplication(AppComponent, 524 | * { 525 | * providers: [ 526 | * provideRouter(appRoutes, withDisabledInitialNavigation()) 527 | * ] 528 | * } 529 | * ); 530 | * ``` 531 | * 532 | * @see {@link provideRouter} 533 | * 534 | * @returns A set of providers for use with `provideRouter`. 535 | * 536 | * @publicApi 537 | */ 538 | declare function withDisabledInitialNavigation(): DisabledInitialNavigationFeature; 539 | /** 540 | * A type alias for providers returned by `withDebugTracing` for use with `provideRouter`. 541 | * 542 | * @see {@link withDebugTracing} 543 | * @see {@link provideRouter} 544 | * 545 | * @publicApi 546 | */ 547 | type DebugTracingFeature = RouterFeature; 548 | /** 549 | * Enables logging of all internal navigation events to the console. 550 | * Extra logging might be useful for debugging purposes to inspect Router event sequence. 551 | * 552 | * @usageNotes 553 | * 554 | * Basic example of how you can enable debug tracing: 555 | * ```ts 556 | * const appRoutes: Routes = []; 557 | * bootstrapApplication(AppComponent, 558 | * { 559 | * providers: [ 560 | * provideRouter(appRoutes, withDebugTracing()) 561 | * ] 562 | * } 563 | * ); 564 | * ``` 565 | * 566 | * @see {@link provideRouter} 567 | * 568 | * @returns A set of providers for use with `provideRouter`. 569 | * 570 | * @publicApi 571 | */ 572 | declare function withDebugTracing(): DebugTracingFeature; 573 | /** 574 | * A type alias that represents a feature which enables preloading in Router. 575 | * The type is used to describe the return value of the `withPreloading` function. 576 | * 577 | * @see {@link withPreloading} 578 | * @see {@link provideRouter} 579 | * 580 | * @publicApi 581 | */ 582 | type PreloadingFeature = RouterFeature; 583 | /** 584 | * Allows to configure a preloading strategy to use. The strategy is configured by providing a 585 | * reference to a class that implements a `PreloadingStrategy`. 586 | * 587 | * @usageNotes 588 | * 589 | * Basic example of how you can configure preloading: 590 | * ```ts 591 | * const appRoutes: Routes = []; 592 | * bootstrapApplication(AppComponent, 593 | * { 594 | * providers: [ 595 | * provideRouter(appRoutes, withPreloading(PreloadAllModules)) 596 | * ] 597 | * } 598 | * ); 599 | * ``` 600 | * 601 | * @see {@link provideRouter} 602 | * 603 | * @param preloadingStrategy A reference to a class that implements a `PreloadingStrategy` that 604 | * should be used. 605 | * @returns A set of providers for use with `provideRouter`. 606 | * 607 | * @see [Preloading strategy](guide/routing/customizing-route-behavior#preloading-strategy) 608 | * 609 | * @publicApi 610 | */ 611 | declare function withPreloading(preloadingStrategy: Type): PreloadingFeature; 612 | /** 613 | * A type alias for providers returned by `withRouterConfig` for use with `provideRouter`. 614 | * 615 | * @see {@link withRouterConfig} 616 | * @see {@link provideRouter} 617 | * 618 | * @publicApi 619 | */ 620 | type RouterConfigurationFeature = RouterFeature; 621 | /** 622 | * Allows to provide extra parameters to configure Router. 623 | * 624 | * @usageNotes 625 | * 626 | * Basic example of how you can provide extra configuration options: 627 | * ```ts 628 | * const appRoutes: Routes = []; 629 | * bootstrapApplication(AppComponent, 630 | * { 631 | * providers: [ 632 | * provideRouter(appRoutes, withRouterConfig({ 633 | * onSameUrlNavigation: 'reload' 634 | * })) 635 | * ] 636 | * } 637 | * ); 638 | * ``` 639 | * 640 | * @see {@link provideRouter} 641 | * 642 | * @param options A set of parameters to configure Router, see `RouterConfigOptions` for 643 | * additional information. 644 | * @returns A set of providers for use with `provideRouter`. 645 | * 646 | * @see [Router configuration options](guide/routing/customizing-route-behavior#router-configuration-options) 647 | * 648 | * @publicApi 649 | */ 650 | declare function withRouterConfig(options: RouterConfigOptions): RouterConfigurationFeature; 651 | /** 652 | * A type alias for providers returned by `withHashLocation` for use with `provideRouter`. 653 | * 654 | * @see {@link withHashLocation} 655 | * @see {@link provideRouter} 656 | * 657 | * @publicApi 658 | */ 659 | type RouterHashLocationFeature = RouterFeature; 660 | /** 661 | * Provides the location strategy that uses the URL fragment instead of the history API. 662 | * 663 | * @usageNotes 664 | * 665 | * Basic example of how you can use the hash location option: 666 | * ```ts 667 | * const appRoutes: Routes = []; 668 | * bootstrapApplication(AppComponent, 669 | * { 670 | * providers: [ 671 | * provideRouter(appRoutes, withHashLocation()) 672 | * ] 673 | * } 674 | * ); 675 | * ``` 676 | * 677 | * @see {@link provideRouter} 678 | * @see {@link /api/common/HashLocationStrategy HashLocationStrategy} 679 | * 680 | * @returns A set of providers for use with `provideRouter`. 681 | * 682 | * @publicApi 683 | */ 684 | declare function withHashLocation(): RouterHashLocationFeature; 685 | /** 686 | * A type alias for providers returned by `withNavigationErrorHandler` for use with `provideRouter`. 687 | * 688 | * @see {@link withNavigationErrorHandler} 689 | * @see {@link provideRouter} 690 | * 691 | * @publicApi 692 | */ 693 | type NavigationErrorHandlerFeature = RouterFeature; 694 | /** 695 | * Provides a function which is called when a navigation error occurs. 696 | * 697 | * This function is run inside application's [injection context](guide/di/dependency-injection-context) 698 | * so you can use the [`inject`](api/core/inject) function. 699 | * 700 | * This function can return a `RedirectCommand` to convert the error to a redirect, similar to returning 701 | * a `UrlTree` or `RedirectCommand` from a guard. This will also prevent the `Router` from emitting 702 | * `NavigationError`; it will instead emit `NavigationCancel` with code NavigationCancellationCode.Redirect. 703 | * Return values other than `RedirectCommand` are ignored and do not change any behavior with respect to 704 | * how the `Router` handles the error. 705 | * 706 | * @usageNotes 707 | * 708 | * Basic example of how you can use the error handler option: 709 | * ```ts 710 | * const appRoutes: Routes = []; 711 | * bootstrapApplication(AppComponent, 712 | * { 713 | * providers: [ 714 | * provideRouter(appRoutes, withNavigationErrorHandler((e: NavigationError) => 715 | * inject(MyErrorTracker).trackError(e))) 716 | * ] 717 | * } 718 | * ); 719 | * ``` 720 | * 721 | * @see {@link NavigationError} 722 | * @see {@link /api/core/inject inject} 723 | * @see {@link runInInjectionContext} 724 | * @see [Centralize error handling in withNavigationErrorHandler](guide/routing/data-resolvers#centralize-error-handling-in-withnavigationerrorhandler) 725 | * 726 | * @returns A set of providers for use with `provideRouter`. 727 | * 728 | * @publicApi 729 | */ 730 | declare function withNavigationErrorHandler(handler: (error: NavigationError) => unknown | RedirectCommand): NavigationErrorHandlerFeature; 731 | /** 732 | * A type alias for providers returned by `withComponentInputBinding` for use with `provideRouter`. 733 | * 734 | * @see {@link withComponentInputBinding} 735 | * @see {@link provideRouter} 736 | * 737 | * @publicApi 738 | */ 739 | type ComponentInputBindingFeature = RouterFeature; 740 | /** 741 | * A type alias for providers returned by `withViewTransitions` for use with `provideRouter`. 742 | * 743 | * @see {@link withViewTransitions} 744 | * @see {@link provideRouter} 745 | * 746 | * @publicApi 747 | */ 748 | type ViewTransitionsFeature = RouterFeature; 749 | /** 750 | * Enables binding information from the `Router` state directly to the inputs of the component in 751 | * `Route` configurations. 752 | * 753 | * @usageNotes 754 | * 755 | * Basic example of how you can enable the feature: 756 | * ```ts 757 | * const appRoutes: Routes = []; 758 | * bootstrapApplication(AppComponent, 759 | * { 760 | * providers: [ 761 | * provideRouter(appRoutes, withComponentInputBinding()) 762 | * ] 763 | * } 764 | * ); 765 | * ``` 766 | * 767 | * The router bindings information from any of the following sources: 768 | * 769 | * - query parameters 770 | * - path and matrix parameters 771 | * - static route data 772 | * - data from resolvers 773 | * 774 | * Duplicate keys are resolved in the same order from above, from least to greatest, 775 | * meaning that resolvers have the highest precedence and override any of the other information 776 | * from the route. 777 | * 778 | * Importantly, when an input does not have an item in the route data with a matching key, this 779 | * input is set to `undefined`. This prevents previous information from being 780 | * retained if the data got removed from the route (i.e. if a query parameter is removed). 781 | * Default values can be provided with a resolver on the route to ensure the value is always present 782 | * or an input and use an input transform in the component. 783 | * 784 | * @see {@link /guide/components/inputs#input-transforms Input Transforms} 785 | * @returns A set of providers for use with `provideRouter`. 786 | */ 787 | declare function withComponentInputBinding(): ComponentInputBindingFeature; 788 | /** 789 | * Enables view transitions in the Router by running the route activation and deactivation inside of 790 | * `document.startViewTransition`. 791 | * 792 | * Note: The View Transitions API is not available in all browsers. If the browser does not support 793 | * view transitions, the Router will not attempt to start a view transition and continue processing 794 | * the navigation as usual. 795 | * 796 | * @usageNotes 797 | * 798 | * Basic example of how you can enable the feature: 799 | * ```ts 800 | * const appRoutes: Routes = []; 801 | * bootstrapApplication(AppComponent, 802 | * { 803 | * providers: [ 804 | * provideRouter(appRoutes, withViewTransitions()) 805 | * ] 806 | * } 807 | * ); 808 | * ``` 809 | * 810 | * @returns A set of providers for use with `provideRouter`. 811 | * @see https://developer.chrome.com/docs/web-platform/view-transitions/ 812 | * @see https://developer.mozilla.org/en-US/docs/Web/API/View_Transitions_API 813 | * @see [Route transition animations](guide/routing/route-transition-animations) 814 | * @developerPreview 19.0 815 | */ 816 | declare function withViewTransitions(options?: ViewTransitionsFeatureOptions): ViewTransitionsFeature; 817 | /** 818 | * A type alias that represents all Router features available for use with `provideRouter`. 819 | * Features can be enabled by adding special functions to the `provideRouter` call. 820 | * See documentation for each symbol to find corresponding function name. See also `provideRouter` 821 | * documentation on how to use those functions. 822 | * 823 | * @see {@link provideRouter} 824 | * 825 | * @publicApi 826 | */ 827 | type RouterFeatures = PreloadingFeature | DebugTracingFeature | InitialNavigationFeature | InMemoryScrollingFeature | RouterConfigurationFeature | NavigationErrorHandlerFeature | ComponentInputBindingFeature | ViewTransitionsFeature | RouterHashLocationFeature; 828 | /** 829 | * The list of features as an enum to uniquely type each feature. 830 | */ 831 | declare const enum RouterFeatureKind { 832 | PreloadingFeature = 0, 833 | DebugTracingFeature = 1, 834 | EnabledBlockingInitialNavigationFeature = 2, 835 | DisabledInitialNavigationFeature = 3, 836 | InMemoryScrollingFeature = 4, 837 | RouterConfigurationFeature = 5, 838 | RouterHashLocationFeature = 6, 839 | NavigationErrorHandlerFeature = 7, 840 | ComponentInputBindingFeature = 8, 841 | ViewTransitionsFeature = 9 842 | } 843 | 844 | /** 845 | * @description 846 | * 847 | * Provides a way to migrate AngularJS applications to Angular. 848 | * 849 | * @see [URL handling strategy](guide/routing/customizing-route-behavior#built-in-preloading-strategies) 850 | * 851 | * @publicApi 852 | */ 853 | declare abstract class UrlHandlingStrategy { 854 | /** 855 | * Tells the router if this URL should be processed. 856 | * 857 | * When it returns true, the router will execute the regular navigation. 858 | * When it returns false, the router will set the router state to an empty state. 859 | * As a result, all the active components will be destroyed. 860 | * 861 | */ 862 | abstract shouldProcessUrl(url: UrlTree): boolean; 863 | /** 864 | * Extracts the part of the URL that should be handled by the router. 865 | * The rest of the URL will remain untouched. 866 | */ 867 | abstract extract(url: UrlTree): UrlTree; 868 | /** 869 | * Merges the URL fragment with the rest of the URL. 870 | */ 871 | abstract merge(newUrlPart: UrlTree, rawUrl: UrlTree): UrlTree; 872 | static ɵfac: i0.ɵɵFactoryDeclaration; 873 | static ɵprov: i0.ɵɵInjectableDeclaration; 874 | } 875 | 876 | /** 877 | * Maps an array of injectable classes with canMatch functions to an array of equivalent 878 | * `CanMatchFn` for use in a `Route` definition. 879 | * 880 | * Usage {@example router/utils/functional_guards.ts region='CanActivate'} 881 | * 882 | * @publicApi 883 | * @see {@link Route} 884 | */ 885 | declare function mapToCanMatch(providers: Array>): CanMatchFn[]; 886 | /** 887 | * Maps an array of injectable classes with canActivate functions to an array of equivalent 888 | * `CanActivateFn` for use in a `Route` definition. 889 | * 890 | * Usage {@example router/utils/functional_guards.ts region='CanActivate'} 891 | * 892 | * @publicApi 893 | * @see {@link Route} 894 | */ 895 | declare function mapToCanActivate(providers: Array>): CanActivateFn[]; 896 | /** 897 | * Maps an array of injectable classes with canActivateChild functions to an array of equivalent 898 | * `CanActivateChildFn` for use in a `Route` definition. 899 | * 900 | * Usage {@example router/utils/functional_guards.ts region='CanActivate'} 901 | * 902 | * @publicApi 903 | * @see {@link Route} 904 | */ 905 | declare function mapToCanActivateChild(providers: Array>): CanActivateChildFn[]; 906 | /** 907 | * Maps an array of injectable classes with canDeactivate functions to an array of equivalent 908 | * `CanDeactivateFn` for use in a `Route` definition. 909 | * 910 | * Usage {@example router/utils/functional_guards.ts region='CanActivate'} 911 | * 912 | * @publicApi 913 | * @see {@link Route} 914 | */ 915 | declare function mapToCanDeactivate(providers: Array>>): CanDeactivateFn[]; 916 | /** 917 | * Maps an injectable class with a resolve function to an equivalent `ResolveFn` 918 | * for use in a `Route` definition. 919 | * 920 | * Usage {@example router/utils/functional_guards.ts region='Resolve'} 921 | * 922 | * @publicApi 923 | * @see {@link Route} 924 | */ 925 | declare function mapToResolve(provider: Type>): ResolveFn; 926 | 927 | /** 928 | * @module 929 | * @description 930 | * Entry point for all public APIs of the router package. 931 | */ 932 | 933 | /** 934 | * @publicApi 935 | */ 936 | declare const VERSION: Version; 937 | 938 | /** 939 | * Performs the given action once the router finishes its next/current navigation. 940 | * 941 | * The navigation is considered complete under the following conditions: 942 | * - `NavigationCancel` event emits and the code is not `NavigationCancellationCode.Redirect` or 943 | * `NavigationCancellationCode.SupersededByNewNavigation`. In these cases, the 944 | * redirecting/superseding navigation must finish. 945 | * - `NavigationError`, `NavigationEnd`, or `NavigationSkipped` event emits 946 | */ 947 | declare function afterNextNavigation(router: { 948 | events: Observable; 949 | }, action: () => void): void; 950 | 951 | /** 952 | * Provides a way to use the synchronous version of the recognize function using rxjs. 953 | */ 954 | declare function provideSometimesSyncRecognize(): EnvironmentProviders; 955 | 956 | export { ActivatedRoute, ActivatedRouteSnapshot, CanActivate, CanActivateChild, CanActivateChildFn, CanActivateFn, CanDeactivate, CanDeactivateFn, CanMatch, CanMatchFn, ChildrenOutletContexts, DefaultTitleStrategy, DefaultUrlSerializer, Event, InMemoryScrollingOptions, NavigationError, NoPreloading, OutletContext, Params, PreloadAllModules, PreloadingStrategy, ROUTES, RedirectCommand, Resolve, ResolveFn, Route, Router, RouterConfigOptions, RouterOutletContract, RouterPreloader, RouterStateSnapshot, Routes, TitleStrategy, UrlHandlingStrategy, UrlTree, VERSION, createUrlTreeFromSnapshot, mapToCanActivate, mapToCanActivateChild, mapToCanDeactivate, mapToCanMatch, mapToResolve, provideRouter, provideRoutes, withComponentInputBinding, withDebugTracing, withDisabledInitialNavigation, withEnabledBlockingInitialNavigation, withHashLocation, withInMemoryScrolling, withNavigationErrorHandler, withPreloading, withRouterConfig, withViewTransitions, afterNextNavigation as ɵafterNextNavigation, loadChildren as ɵloadChildren, provideSometimesSyncRecognize as ɵprovideSometimesSyncRecognize, withPlatformNavigation as ɵwithPlatformNavigation }; 957 | export type { ComponentInputBindingFeature, DebugTracingFeature, DisabledInitialNavigationFeature, EnabledBlockingInitialNavigationFeature, InMemoryScrollingFeature, InitialNavigationFeature, NavigationErrorHandlerFeature, PreloadingFeature, RouterConfigurationFeature, RouterFeature, RouterFeatures, RouterHashLocationFeature, ViewTransitionInfo, ViewTransitionsFeature, ViewTransitionsFeatureOptions }; 958 | -------------------------------------------------------------------------------- /fesm2022/_router_module-chunk.mjs: -------------------------------------------------------------------------------- 1 | /** 2 | * @license Angular v21.1.0-next.3+sha-9fa77af 3 | * (c) 2010-2025 Google LLC. https://angular.dev/ 4 | * License: MIT 5 | */ 6 | 7 | import * as i3 from '@angular/common'; 8 | import { ViewportScroller, PlatformNavigation, PlatformLocation, Location, ɵNavigationAdapterForLocation as _NavigationAdapterForLocation, LOCATION_INITIALIZED, LocationStrategy, HashLocationStrategy, PathLocationStrategy } from '@angular/common'; 9 | import * as i0 from '@angular/core'; 10 | import { signal, untracked, inject, ɵINTERNAL_APPLICATION_ERROR_HANDLER as _INTERNAL_APPLICATION_ERROR_HANDLER, HostAttributeToken, ɵRuntimeError as _RuntimeError, booleanAttribute, Directive, Attribute, HostBinding, Input, HostListener, EventEmitter, ContentChildren, Output, Injectable, createEnvironmentInjector, InjectionToken, NgZone, EnvironmentInjector, DestroyRef, afterNextRender, ɵpromiseWithResolvers as _promiseWithResolvers, ɵpublishExternalGlobalUtil as _publishExternalGlobalUtil, makeEnvironmentProviders, APP_BOOTSTRAP_LISTENER, provideEnvironmentInitializer, Injector, ApplicationRef, ɵIS_ENABLED_BLOCKING_INITIAL_NAVIGATION as _IS_ENABLED_BLOCKING_INITIAL_NAVIGATION, provideAppInitializer, ɵperformanceMarkFeature as _performanceMarkFeature, ENVIRONMENT_INITIALIZER, NgModule } from '@angular/core'; 11 | import { ROUTER_CONFIGURATION, NavigationEnd, isUrlTree, Router, ActivatedRoute, RouterConfigLoader, IMPERATIVE_NAVIGATION, UrlSerializer, NavigationTransitions, NavigationStart, NavigationSkipped, NavigationSkippedCode, Scroll, StateManager, RoutesRecognized, BeforeActivateRoutes, NavigationCancel, NavigationError, isRedirectingEvent, NavigationCancellationCode, ROUTES, afterNextNavigation, stringifyEvent, NAVIGATION_ERROR_HANDLER, RoutedComponentInputBinder, INPUT_BINDER, CREATE_VIEW_TRANSITION, createViewTransition, VIEW_TRANSITION_OPTIONS, DefaultUrlSerializer, ChildrenOutletContexts, RouterOutlet, ɵEmptyOutletComponent as _EmptyOutletComponent } from './_router-chunk.mjs'; 12 | import { Subject, of, from } from 'rxjs'; 13 | import { mergeAll, catchError, filter, concatMap, mergeMap } from 'rxjs/operators'; 14 | 15 | class RouterLink { 16 | router; 17 | route; 18 | tabIndexAttribute; 19 | renderer; 20 | el; 21 | locationStrategy; 22 | reactiveHref = signal(null, ...(ngDevMode ? [{ 23 | debugName: "reactiveHref" 24 | }] : [])); 25 | get href() { 26 | return untracked(this.reactiveHref); 27 | } 28 | set href(value) { 29 | this.reactiveHref.set(value); 30 | } 31 | target; 32 | queryParams; 33 | fragment; 34 | queryParamsHandling; 35 | state; 36 | info; 37 | relativeTo; 38 | isAnchorElement; 39 | subscription; 40 | onChanges = new Subject(); 41 | applicationErrorHandler = inject(_INTERNAL_APPLICATION_ERROR_HANDLER); 42 | options = inject(ROUTER_CONFIGURATION, { 43 | optional: true 44 | }); 45 | constructor(router, route, tabIndexAttribute, renderer, el, locationStrategy) { 46 | this.router = router; 47 | this.route = route; 48 | this.tabIndexAttribute = tabIndexAttribute; 49 | this.renderer = renderer; 50 | this.el = el; 51 | this.locationStrategy = locationStrategy; 52 | this.reactiveHref.set(inject(new HostAttributeToken('href'), { 53 | optional: true 54 | })); 55 | const tagName = el.nativeElement.tagName?.toLowerCase(); 56 | this.isAnchorElement = tagName === 'a' || tagName === 'area' || !!(typeof customElements === 'object' && customElements.get(tagName)?.observedAttributes?.includes?.('href')); 57 | if (!this.isAnchorElement) { 58 | this.subscribeToNavigationEventsIfNecessary(); 59 | } else { 60 | this.setTabIndexIfNotOnNativeEl('0'); 61 | } 62 | } 63 | subscribeToNavigationEventsIfNecessary() { 64 | if (this.subscription !== undefined || !this.isAnchorElement) { 65 | return; 66 | } 67 | let createSubcription = this.preserveFragment; 68 | const dependsOnRouterState = handling => handling === 'merge' || handling === 'preserve'; 69 | createSubcription ||= dependsOnRouterState(this.queryParamsHandling); 70 | createSubcription ||= !this.queryParamsHandling && !dependsOnRouterState(this.options?.defaultQueryParamsHandling); 71 | if (!createSubcription) { 72 | return; 73 | } 74 | this.subscription = this.router.events.subscribe(s => { 75 | if (s instanceof NavigationEnd) { 76 | this.updateHref(); 77 | } 78 | }); 79 | } 80 | preserveFragment = false; 81 | skipLocationChange = false; 82 | replaceUrl = false; 83 | setTabIndexIfNotOnNativeEl(newTabIndex) { 84 | if (this.tabIndexAttribute != null || this.isAnchorElement) { 85 | return; 86 | } 87 | this.applyAttributeValue('tabindex', newTabIndex); 88 | } 89 | ngOnChanges(changes) { 90 | if (ngDevMode && isUrlTree(this.routerLinkInput) && (this.fragment !== undefined || this.queryParams || this.queryParamsHandling || this.preserveFragment || this.relativeTo)) { 91 | throw new _RuntimeError(4017, 'Cannot configure queryParams or fragment when using a UrlTree as the routerLink input value.'); 92 | } 93 | if (this.isAnchorElement) { 94 | this.updateHref(); 95 | this.subscribeToNavigationEventsIfNecessary(); 96 | } 97 | this.onChanges.next(this); 98 | } 99 | routerLinkInput = null; 100 | set routerLink(commandsOrUrlTree) { 101 | if (commandsOrUrlTree == null) { 102 | this.routerLinkInput = null; 103 | this.setTabIndexIfNotOnNativeEl(null); 104 | } else { 105 | if (isUrlTree(commandsOrUrlTree)) { 106 | this.routerLinkInput = commandsOrUrlTree; 107 | } else { 108 | this.routerLinkInput = Array.isArray(commandsOrUrlTree) ? commandsOrUrlTree : [commandsOrUrlTree]; 109 | } 110 | this.setTabIndexIfNotOnNativeEl('0'); 111 | } 112 | } 113 | onClick(button, ctrlKey, shiftKey, altKey, metaKey) { 114 | const urlTree = this.urlTree; 115 | if (urlTree === null) { 116 | return true; 117 | } 118 | if (this.isAnchorElement) { 119 | if (button !== 0 || ctrlKey || shiftKey || altKey || metaKey) { 120 | return true; 121 | } 122 | if (typeof this.target === 'string' && this.target != '_self') { 123 | return true; 124 | } 125 | } 126 | const extras = { 127 | skipLocationChange: this.skipLocationChange, 128 | replaceUrl: this.replaceUrl, 129 | state: this.state, 130 | info: this.info 131 | }; 132 | this.router.navigateByUrl(urlTree, extras)?.catch(e => { 133 | this.applicationErrorHandler(e); 134 | }); 135 | return !this.isAnchorElement; 136 | } 137 | ngOnDestroy() { 138 | this.subscription?.unsubscribe(); 139 | } 140 | updateHref() { 141 | const urlTree = this.urlTree; 142 | this.reactiveHref.set(urlTree !== null && this.locationStrategy ? this.locationStrategy?.prepareExternalUrl(this.router.serializeUrl(urlTree)) ?? '' : null); 143 | } 144 | applyAttributeValue(attrName, attrValue) { 145 | const renderer = this.renderer; 146 | const nativeElement = this.el.nativeElement; 147 | if (attrValue !== null) { 148 | renderer.setAttribute(nativeElement, attrName, attrValue); 149 | } else { 150 | renderer.removeAttribute(nativeElement, attrName); 151 | } 152 | } 153 | get urlTree() { 154 | if (this.routerLinkInput === null) { 155 | return null; 156 | } else if (isUrlTree(this.routerLinkInput)) { 157 | return this.routerLinkInput; 158 | } 159 | return this.router.createUrlTree(this.routerLinkInput, { 160 | relativeTo: this.relativeTo !== undefined ? this.relativeTo : this.route, 161 | queryParams: this.queryParams, 162 | fragment: this.fragment, 163 | queryParamsHandling: this.queryParamsHandling, 164 | preserveFragment: this.preserveFragment 165 | }); 166 | } 167 | static ɵfac = i0.ɵɵngDeclareFactory({ 168 | minVersion: "12.0.0", 169 | version: "21.1.0-next.3+sha-9fa77af", 170 | ngImport: i0, 171 | type: RouterLink, 172 | deps: [{ 173 | token: Router 174 | }, { 175 | token: ActivatedRoute 176 | }, { 177 | token: 'tabindex', 178 | attribute: true 179 | }, { 180 | token: i0.Renderer2 181 | }, { 182 | token: i0.ElementRef 183 | }, { 184 | token: i3.LocationStrategy 185 | }], 186 | target: i0.ɵɵFactoryTarget.Directive 187 | }); 188 | static ɵdir = i0.ɵɵngDeclareDirective({ 189 | minVersion: "16.1.0", 190 | version: "21.1.0-next.3+sha-9fa77af", 191 | type: RouterLink, 192 | isStandalone: true, 193 | selector: "[routerLink]", 194 | inputs: { 195 | target: "target", 196 | queryParams: "queryParams", 197 | fragment: "fragment", 198 | queryParamsHandling: "queryParamsHandling", 199 | state: "state", 200 | info: "info", 201 | relativeTo: "relativeTo", 202 | preserveFragment: ["preserveFragment", "preserveFragment", booleanAttribute], 203 | skipLocationChange: ["skipLocationChange", "skipLocationChange", booleanAttribute], 204 | replaceUrl: ["replaceUrl", "replaceUrl", booleanAttribute], 205 | routerLink: "routerLink" 206 | }, 207 | host: { 208 | listeners: { 209 | "click": "onClick($event.button,$event.ctrlKey,$event.shiftKey,$event.altKey,$event.metaKey)" 210 | }, 211 | properties: { 212 | "attr.href": "reactiveHref()", 213 | "attr.target": "this.target" 214 | } 215 | }, 216 | usesOnChanges: true, 217 | ngImport: i0 218 | }); 219 | } 220 | i0.ɵɵngDeclareClassMetadata({ 221 | minVersion: "12.0.0", 222 | version: "21.1.0-next.3+sha-9fa77af", 223 | ngImport: i0, 224 | type: RouterLink, 225 | decorators: [{ 226 | type: Directive, 227 | args: [{ 228 | selector: '[routerLink]', 229 | host: { 230 | '[attr.href]': 'reactiveHref()' 231 | } 232 | }] 233 | }], 234 | ctorParameters: () => [{ 235 | type: Router 236 | }, { 237 | type: ActivatedRoute 238 | }, { 239 | type: undefined, 240 | decorators: [{ 241 | type: Attribute, 242 | args: ['tabindex'] 243 | }] 244 | }, { 245 | type: i0.Renderer2 246 | }, { 247 | type: i0.ElementRef 248 | }, { 249 | type: i3.LocationStrategy 250 | }], 251 | propDecorators: { 252 | target: [{ 253 | type: HostBinding, 254 | args: ['attr.target'] 255 | }, { 256 | type: Input 257 | }], 258 | queryParams: [{ 259 | type: Input 260 | }], 261 | fragment: [{ 262 | type: Input 263 | }], 264 | queryParamsHandling: [{ 265 | type: Input 266 | }], 267 | state: [{ 268 | type: Input 269 | }], 270 | info: [{ 271 | type: Input 272 | }], 273 | relativeTo: [{ 274 | type: Input 275 | }], 276 | preserveFragment: [{ 277 | type: Input, 278 | args: [{ 279 | transform: booleanAttribute 280 | }] 281 | }], 282 | skipLocationChange: [{ 283 | type: Input, 284 | args: [{ 285 | transform: booleanAttribute 286 | }] 287 | }], 288 | replaceUrl: [{ 289 | type: Input, 290 | args: [{ 291 | transform: booleanAttribute 292 | }] 293 | }], 294 | routerLink: [{ 295 | type: Input 296 | }], 297 | onClick: [{ 298 | type: HostListener, 299 | args: ['click', ['$event.button', '$event.ctrlKey', '$event.shiftKey', '$event.altKey', '$event.metaKey']] 300 | }] 301 | } 302 | }); 303 | 304 | class RouterLinkActive { 305 | router; 306 | element; 307 | renderer; 308 | cdr; 309 | links; 310 | classes = []; 311 | routerEventsSubscription; 312 | linkInputChangesSubscription; 313 | _isActive = false; 314 | get isActive() { 315 | return this._isActive; 316 | } 317 | routerLinkActiveOptions = { 318 | exact: false 319 | }; 320 | ariaCurrentWhenActive; 321 | isActiveChange = new EventEmitter(); 322 | link = inject(RouterLink, { 323 | optional: true 324 | }); 325 | constructor(router, element, renderer, cdr) { 326 | this.router = router; 327 | this.element = element; 328 | this.renderer = renderer; 329 | this.cdr = cdr; 330 | this.routerEventsSubscription = router.events.subscribe(s => { 331 | if (s instanceof NavigationEnd) { 332 | this.update(); 333 | } 334 | }); 335 | } 336 | ngAfterContentInit() { 337 | of(this.links.changes, of(null)).pipe(mergeAll()).subscribe(_ => { 338 | this.update(); 339 | this.subscribeToEachLinkOnChanges(); 340 | }); 341 | } 342 | subscribeToEachLinkOnChanges() { 343 | this.linkInputChangesSubscription?.unsubscribe(); 344 | const allLinkChanges = [...this.links.toArray(), this.link].filter(link => !!link).map(link => link.onChanges); 345 | this.linkInputChangesSubscription = from(allLinkChanges).pipe(mergeAll()).subscribe(link => { 346 | if (this._isActive !== this.isLinkActive(this.router)(link)) { 347 | this.update(); 348 | } 349 | }); 350 | } 351 | set routerLinkActive(data) { 352 | const classes = Array.isArray(data) ? data : data.split(' '); 353 | this.classes = classes.filter(c => !!c); 354 | } 355 | ngOnChanges(changes) { 356 | this.update(); 357 | } 358 | ngOnDestroy() { 359 | this.routerEventsSubscription.unsubscribe(); 360 | this.linkInputChangesSubscription?.unsubscribe(); 361 | } 362 | update() { 363 | if (!this.links || !this.router.navigated) return; 364 | queueMicrotask(() => { 365 | const hasActiveLinks = this.hasActiveLinks(); 366 | this.classes.forEach(c => { 367 | if (hasActiveLinks) { 368 | this.renderer.addClass(this.element.nativeElement, c); 369 | } else { 370 | this.renderer.removeClass(this.element.nativeElement, c); 371 | } 372 | }); 373 | if (hasActiveLinks && this.ariaCurrentWhenActive !== undefined) { 374 | this.renderer.setAttribute(this.element.nativeElement, 'aria-current', this.ariaCurrentWhenActive.toString()); 375 | } else { 376 | this.renderer.removeAttribute(this.element.nativeElement, 'aria-current'); 377 | } 378 | if (this._isActive !== hasActiveLinks) { 379 | this._isActive = hasActiveLinks; 380 | this.cdr.markForCheck(); 381 | this.isActiveChange.emit(hasActiveLinks); 382 | } 383 | }); 384 | } 385 | isLinkActive(router) { 386 | const options = isActiveMatchOptions(this.routerLinkActiveOptions) ? this.routerLinkActiveOptions : this.routerLinkActiveOptions.exact || false; 387 | return link => { 388 | const urlTree = link.urlTree; 389 | return urlTree ? router.isActive(urlTree, options) : false; 390 | }; 391 | } 392 | hasActiveLinks() { 393 | const isActiveCheckFn = this.isLinkActive(this.router); 394 | return this.link && isActiveCheckFn(this.link) || this.links.some(isActiveCheckFn); 395 | } 396 | static ɵfac = i0.ɵɵngDeclareFactory({ 397 | minVersion: "12.0.0", 398 | version: "21.1.0-next.3+sha-9fa77af", 399 | ngImport: i0, 400 | type: RouterLinkActive, 401 | deps: [{ 402 | token: Router 403 | }, { 404 | token: i0.ElementRef 405 | }, { 406 | token: i0.Renderer2 407 | }, { 408 | token: i0.ChangeDetectorRef 409 | }], 410 | target: i0.ɵɵFactoryTarget.Directive 411 | }); 412 | static ɵdir = i0.ɵɵngDeclareDirective({ 413 | minVersion: "14.0.0", 414 | version: "21.1.0-next.3+sha-9fa77af", 415 | type: RouterLinkActive, 416 | isStandalone: true, 417 | selector: "[routerLinkActive]", 418 | inputs: { 419 | routerLinkActiveOptions: "routerLinkActiveOptions", 420 | ariaCurrentWhenActive: "ariaCurrentWhenActive", 421 | routerLinkActive: "routerLinkActive" 422 | }, 423 | outputs: { 424 | isActiveChange: "isActiveChange" 425 | }, 426 | queries: [{ 427 | propertyName: "links", 428 | predicate: RouterLink, 429 | descendants: true 430 | }], 431 | exportAs: ["routerLinkActive"], 432 | usesOnChanges: true, 433 | ngImport: i0 434 | }); 435 | } 436 | i0.ɵɵngDeclareClassMetadata({ 437 | minVersion: "12.0.0", 438 | version: "21.1.0-next.3+sha-9fa77af", 439 | ngImport: i0, 440 | type: RouterLinkActive, 441 | decorators: [{ 442 | type: Directive, 443 | args: [{ 444 | selector: '[routerLinkActive]', 445 | exportAs: 'routerLinkActive' 446 | }] 447 | }], 448 | ctorParameters: () => [{ 449 | type: Router 450 | }, { 451 | type: i0.ElementRef 452 | }, { 453 | type: i0.Renderer2 454 | }, { 455 | type: i0.ChangeDetectorRef 456 | }], 457 | propDecorators: { 458 | links: [{ 459 | type: ContentChildren, 460 | args: [RouterLink, { 461 | descendants: true 462 | }] 463 | }], 464 | routerLinkActiveOptions: [{ 465 | type: Input 466 | }], 467 | ariaCurrentWhenActive: [{ 468 | type: Input 469 | }], 470 | isActiveChange: [{ 471 | type: Output 472 | }], 473 | routerLinkActive: [{ 474 | type: Input 475 | }] 476 | } 477 | }); 478 | function isActiveMatchOptions(options) { 479 | return !!options.paths; 480 | } 481 | 482 | class PreloadingStrategy {} 483 | class PreloadAllModules { 484 | preload(route, fn) { 485 | return fn().pipe(catchError(() => of(null))); 486 | } 487 | static ɵfac = i0.ɵɵngDeclareFactory({ 488 | minVersion: "12.0.0", 489 | version: "21.1.0-next.3+sha-9fa77af", 490 | ngImport: i0, 491 | type: PreloadAllModules, 492 | deps: [], 493 | target: i0.ɵɵFactoryTarget.Injectable 494 | }); 495 | static ɵprov = i0.ɵɵngDeclareInjectable({ 496 | minVersion: "12.0.0", 497 | version: "21.1.0-next.3+sha-9fa77af", 498 | ngImport: i0, 499 | type: PreloadAllModules, 500 | providedIn: 'root' 501 | }); 502 | } 503 | i0.ɵɵngDeclareClassMetadata({ 504 | minVersion: "12.0.0", 505 | version: "21.1.0-next.3+sha-9fa77af", 506 | ngImport: i0, 507 | type: PreloadAllModules, 508 | decorators: [{ 509 | type: Injectable, 510 | args: [{ 511 | providedIn: 'root' 512 | }] 513 | }] 514 | }); 515 | class NoPreloading { 516 | preload(route, fn) { 517 | return of(null); 518 | } 519 | static ɵfac = i0.ɵɵngDeclareFactory({ 520 | minVersion: "12.0.0", 521 | version: "21.1.0-next.3+sha-9fa77af", 522 | ngImport: i0, 523 | type: NoPreloading, 524 | deps: [], 525 | target: i0.ɵɵFactoryTarget.Injectable 526 | }); 527 | static ɵprov = i0.ɵɵngDeclareInjectable({ 528 | minVersion: "12.0.0", 529 | version: "21.1.0-next.3+sha-9fa77af", 530 | ngImport: i0, 531 | type: NoPreloading, 532 | providedIn: 'root' 533 | }); 534 | } 535 | i0.ɵɵngDeclareClassMetadata({ 536 | minVersion: "12.0.0", 537 | version: "21.1.0-next.3+sha-9fa77af", 538 | ngImport: i0, 539 | type: NoPreloading, 540 | decorators: [{ 541 | type: Injectable, 542 | args: [{ 543 | providedIn: 'root' 544 | }] 545 | }] 546 | }); 547 | class RouterPreloader { 548 | router; 549 | injector; 550 | preloadingStrategy; 551 | loader; 552 | subscription; 553 | constructor(router, injector, preloadingStrategy, loader) { 554 | this.router = router; 555 | this.injector = injector; 556 | this.preloadingStrategy = preloadingStrategy; 557 | this.loader = loader; 558 | } 559 | setUpPreloading() { 560 | this.subscription = this.router.events.pipe(filter(e => e instanceof NavigationEnd), concatMap(() => this.preload())).subscribe(() => {}); 561 | } 562 | preload() { 563 | return this.processRoutes(this.injector, this.router.config); 564 | } 565 | ngOnDestroy() { 566 | if (this.subscription) { 567 | this.subscription.unsubscribe(); 568 | } 569 | } 570 | processRoutes(injector, routes) { 571 | const res = []; 572 | for (const route of routes) { 573 | if (route.providers && !route._injector) { 574 | route._injector = createEnvironmentInjector(route.providers, injector, `Route: ${route.path}`); 575 | } 576 | const injectorForCurrentRoute = route._injector ?? injector; 577 | const injectorForChildren = route._loadedInjector ?? injectorForCurrentRoute; 578 | if (route.loadChildren && !route._loadedRoutes && route.canLoad === undefined || route.loadComponent && !route._loadedComponent) { 579 | res.push(this.preloadConfig(injectorForCurrentRoute, route)); 580 | } 581 | if (route.children || route._loadedRoutes) { 582 | res.push(this.processRoutes(injectorForChildren, route.children ?? route._loadedRoutes)); 583 | } 584 | } 585 | return from(res).pipe(mergeAll()); 586 | } 587 | preloadConfig(injector, route) { 588 | return this.preloadingStrategy.preload(route, () => { 589 | let loadedChildren$; 590 | if (route.loadChildren && route.canLoad === undefined) { 591 | loadedChildren$ = from(this.loader.loadChildren(injector, route)); 592 | } else { 593 | loadedChildren$ = of(null); 594 | } 595 | const recursiveLoadChildren$ = loadedChildren$.pipe(mergeMap(config => { 596 | if (config === null) { 597 | return of(void 0); 598 | } 599 | route._loadedRoutes = config.routes; 600 | route._loadedInjector = config.injector; 601 | return this.processRoutes(config.injector ?? injector, config.routes); 602 | })); 603 | if (route.loadComponent && !route._loadedComponent) { 604 | const loadComponent$ = this.loader.loadComponent(injector, route); 605 | return from([recursiveLoadChildren$, loadComponent$]).pipe(mergeAll()); 606 | } else { 607 | return recursiveLoadChildren$; 608 | } 609 | }); 610 | } 611 | static ɵfac = i0.ɵɵngDeclareFactory({ 612 | minVersion: "12.0.0", 613 | version: "21.1.0-next.3+sha-9fa77af", 614 | ngImport: i0, 615 | type: RouterPreloader, 616 | deps: [{ 617 | token: Router 618 | }, { 619 | token: i0.EnvironmentInjector 620 | }, { 621 | token: PreloadingStrategy 622 | }, { 623 | token: RouterConfigLoader 624 | }], 625 | target: i0.ɵɵFactoryTarget.Injectable 626 | }); 627 | static ɵprov = i0.ɵɵngDeclareInjectable({ 628 | minVersion: "12.0.0", 629 | version: "21.1.0-next.3+sha-9fa77af", 630 | ngImport: i0, 631 | type: RouterPreloader, 632 | providedIn: 'root' 633 | }); 634 | } 635 | i0.ɵɵngDeclareClassMetadata({ 636 | minVersion: "12.0.0", 637 | version: "21.1.0-next.3+sha-9fa77af", 638 | ngImport: i0, 639 | type: RouterPreloader, 640 | decorators: [{ 641 | type: Injectable, 642 | args: [{ 643 | providedIn: 'root' 644 | }] 645 | }], 646 | ctorParameters: () => [{ 647 | type: Router 648 | }, { 649 | type: i0.EnvironmentInjector 650 | }, { 651 | type: PreloadingStrategy 652 | }, { 653 | type: RouterConfigLoader 654 | }] 655 | }); 656 | 657 | const ROUTER_SCROLLER = new InjectionToken(typeof ngDevMode !== 'undefined' && ngDevMode ? 'Router Scroller' : ''); 658 | class RouterScroller { 659 | options; 660 | routerEventsSubscription; 661 | scrollEventsSubscription; 662 | lastId = 0; 663 | lastSource = IMPERATIVE_NAVIGATION; 664 | restoredId = 0; 665 | store = {}; 666 | urlSerializer = inject(UrlSerializer); 667 | zone = inject(NgZone); 668 | viewportScroller = inject(ViewportScroller); 669 | transitions = inject(NavigationTransitions); 670 | constructor(options) { 671 | this.options = options; 672 | this.options.scrollPositionRestoration ||= 'disabled'; 673 | this.options.anchorScrolling ||= 'disabled'; 674 | } 675 | init() { 676 | if (this.options.scrollPositionRestoration !== 'disabled') { 677 | this.viewportScroller.setHistoryScrollRestoration('manual'); 678 | } 679 | this.routerEventsSubscription = this.createScrollEvents(); 680 | this.scrollEventsSubscription = this.consumeScrollEvents(); 681 | } 682 | createScrollEvents() { 683 | return this.transitions.events.subscribe(e => { 684 | if (e instanceof NavigationStart) { 685 | this.store[this.lastId] = this.viewportScroller.getScrollPosition(); 686 | this.lastSource = e.navigationTrigger; 687 | this.restoredId = e.restoredState ? e.restoredState.navigationId : 0; 688 | } else if (e instanceof NavigationEnd) { 689 | this.lastId = e.id; 690 | this.scheduleScrollEvent(e, this.urlSerializer.parse(e.urlAfterRedirects).fragment); 691 | } else if (e instanceof NavigationSkipped && e.code === NavigationSkippedCode.IgnoredSameUrlNavigation) { 692 | this.lastSource = undefined; 693 | this.restoredId = 0; 694 | this.scheduleScrollEvent(e, this.urlSerializer.parse(e.url).fragment); 695 | } 696 | }); 697 | } 698 | consumeScrollEvents() { 699 | return this.transitions.events.subscribe(e => { 700 | if (!(e instanceof Scroll) || e.scrollBehavior === 'manual') return; 701 | const instantScroll = { 702 | behavior: 'instant' 703 | }; 704 | if (e.position) { 705 | if (this.options.scrollPositionRestoration === 'top') { 706 | this.viewportScroller.scrollToPosition([0, 0], instantScroll); 707 | } else if (this.options.scrollPositionRestoration === 'enabled') { 708 | this.viewportScroller.scrollToPosition(e.position, instantScroll); 709 | } 710 | } else { 711 | if (e.anchor && this.options.anchorScrolling === 'enabled') { 712 | this.viewportScroller.scrollToAnchor(e.anchor); 713 | } else if (this.options.scrollPositionRestoration !== 'disabled') { 714 | this.viewportScroller.scrollToPosition([0, 0]); 715 | } 716 | } 717 | }); 718 | } 719 | scheduleScrollEvent(routerEvent, anchor) { 720 | const scroll = untracked(this.transitions.currentNavigation)?.extras.scroll; 721 | this.zone.runOutsideAngular(async () => { 722 | await new Promise(resolve => { 723 | setTimeout(resolve); 724 | if (typeof requestAnimationFrame !== 'undefined') { 725 | requestAnimationFrame(resolve); 726 | } 727 | }); 728 | this.zone.run(() => { 729 | this.transitions.events.next(new Scroll(routerEvent, this.lastSource === 'popstate' ? this.store[this.restoredId] : null, anchor, scroll)); 730 | }); 731 | }); 732 | } 733 | ngOnDestroy() { 734 | this.routerEventsSubscription?.unsubscribe(); 735 | this.scrollEventsSubscription?.unsubscribe(); 736 | } 737 | static ɵfac = i0.ɵɵngDeclareFactory({ 738 | minVersion: "12.0.0", 739 | version: "21.1.0-next.3+sha-9fa77af", 740 | ngImport: i0, 741 | type: RouterScroller, 742 | deps: "invalid", 743 | target: i0.ɵɵFactoryTarget.Injectable 744 | }); 745 | static ɵprov = i0.ɵɵngDeclareInjectable({ 746 | minVersion: "12.0.0", 747 | version: "21.1.0-next.3+sha-9fa77af", 748 | ngImport: i0, 749 | type: RouterScroller 750 | }); 751 | } 752 | i0.ɵɵngDeclareClassMetadata({ 753 | minVersion: "12.0.0", 754 | version: "21.1.0-next.3+sha-9fa77af", 755 | ngImport: i0, 756 | type: RouterScroller, 757 | decorators: [{ 758 | type: Injectable 759 | }], 760 | ctorParameters: () => [{ 761 | type: undefined 762 | }] 763 | }); 764 | 765 | function getLoadedRoutes(route) { 766 | return route._loadedRoutes; 767 | } 768 | function getRouterInstance(injector) { 769 | return injector.get(Router, null, { 770 | optional: true 771 | }); 772 | } 773 | function navigateByUrl(router, url) { 774 | if (!(router instanceof Router)) { 775 | throw new Error('The provided router is not an Angular Router.'); 776 | } 777 | return router.navigateByUrl(url); 778 | } 779 | 780 | class NavigationStateManager extends StateManager { 781 | injector = inject(EnvironmentInjector); 782 | navigation = inject(PlatformNavigation); 783 | inMemoryScrollingEnabled = inject(ROUTER_SCROLLER, { 784 | optional: true 785 | }) !== null; 786 | base = new URL(inject(PlatformLocation).href).origin; 787 | appRootURL = new URL(this.location.prepareExternalUrl?.('/') ?? '/', this.base).href; 788 | activeHistoryEntry = this.navigation.currentEntry; 789 | currentNavigation = {}; 790 | nonRouterCurrentEntryChangeSubject = new Subject(); 791 | nonRouterEntryChangeListener; 792 | get registered() { 793 | return this.nonRouterEntryChangeListener !== undefined && !this.nonRouterEntryChangeListener.closed; 794 | } 795 | constructor() { 796 | super(); 797 | const navigateListener = event => { 798 | this.handleNavigate(event); 799 | }; 800 | this.navigation.addEventListener('navigate', navigateListener); 801 | inject(DestroyRef).onDestroy(() => this.navigation.removeEventListener('navigate', navigateListener)); 802 | } 803 | registerNonRouterCurrentEntryChangeListener(listener) { 804 | this.activeHistoryEntry = this.navigation.currentEntry; 805 | this.nonRouterEntryChangeListener = this.nonRouterCurrentEntryChangeSubject.subscribe(({ 806 | path, 807 | state 808 | }) => { 809 | listener(path, state, 'popstate'); 810 | }); 811 | return this.nonRouterEntryChangeListener; 812 | } 813 | async handleRouterEvent(e, transition) { 814 | this.currentNavigation = { 815 | ...this.currentNavigation, 816 | routerTransition: transition 817 | }; 818 | if (e instanceof NavigationStart) { 819 | this.updateStateMemento(); 820 | } else if (e instanceof NavigationSkipped) { 821 | this.finishNavigation(); 822 | this.commitTransition(transition); 823 | } else if (e instanceof RoutesRecognized) { 824 | if (this.urlUpdateStrategy === 'eager' && !transition.extras.skipLocationChange) { 825 | this.createNavigationForTransition(transition); 826 | } 827 | } else if (e instanceof BeforeActivateRoutes) { 828 | this.commitTransition(transition); 829 | if (this.urlUpdateStrategy === 'deferred' && !transition.extras.skipLocationChange) { 830 | this.createNavigationForTransition(transition); 831 | } 832 | } else if (e instanceof NavigationCancel || e instanceof NavigationError) { 833 | void this.cancel(transition, e); 834 | } else if (e instanceof NavigationEnd) { 835 | const { 836 | resolveHandler, 837 | removeAbortListener 838 | } = this.currentNavigation; 839 | this.currentNavigation = {}; 840 | removeAbortListener?.(); 841 | this.activeHistoryEntry = this.navigation.currentEntry; 842 | afterNextRender({ 843 | read: () => resolveHandler?.() 844 | }, { 845 | injector: this.injector 846 | }); 847 | } 848 | } 849 | createNavigationForTransition(transition) { 850 | const { 851 | navigationEvent 852 | } = this.currentNavigation; 853 | if (navigationEvent && (navigationEvent.navigationType === 'traverse' || navigationEvent.navigationType === 'reload') && this.eventAndRouterDestinationsMatch(navigationEvent, transition)) { 854 | return; 855 | } 856 | this.currentNavigation.removeAbortListener?.(); 857 | const path = this.createBrowserPath(transition); 858 | this.navigate(path, transition); 859 | } 860 | navigate(internalPath, transition) { 861 | const path = transition.extras.skipLocationChange ? this.navigation.currentEntry.url : this.location.prepareExternalUrl(internalPath); 862 | const state = { 863 | ...transition.extras.state, 864 | navigationId: transition.id 865 | }; 866 | const info = { 867 | ɵrouterInfo: { 868 | intercept: true 869 | } 870 | }; 871 | if (!this.navigation.transition && this.currentNavigation.navigationEvent) { 872 | transition.extras.replaceUrl = false; 873 | } 874 | const history = this.location.isCurrentPathEqualTo(path) || transition.extras.replaceUrl || transition.extras.skipLocationChange ? 'replace' : 'push'; 875 | handleResultRejections(this.navigation.navigate(path, { 876 | state, 877 | history, 878 | info 879 | })); 880 | } 881 | finishNavigation() { 882 | this.currentNavigation?.resolveHandler?.(); 883 | this.currentNavigation = {}; 884 | } 885 | async cancel(transition, cause) { 886 | this.currentNavigation.rejectNavigateEvent?.(); 887 | const clearedState = {}; 888 | this.currentNavigation = clearedState; 889 | if (isRedirectingEvent(cause)) { 890 | return; 891 | } 892 | const isTraversalReset = this.canceledNavigationResolution === 'computed' && this.navigation.currentEntry.key !== this.activeHistoryEntry.key; 893 | this.resetInternalState(transition.finalUrl, isTraversalReset); 894 | if (this.navigation.currentEntry.id === this.activeHistoryEntry.id) { 895 | return; 896 | } 897 | if (cause instanceof NavigationCancel && cause.code === NavigationCancellationCode.Aborted) { 898 | await Promise.resolve(); 899 | if (this.currentNavigation !== clearedState) { 900 | return; 901 | } 902 | } 903 | if (isTraversalReset) { 904 | handleResultRejections(this.navigation.traverseTo(this.activeHistoryEntry.key, { 905 | info: { 906 | ɵrouterInfo: { 907 | intercept: false 908 | } 909 | } 910 | })); 911 | } else { 912 | const internalPath = this.urlSerializer.serialize(this.getCurrentUrlTree()); 913 | const pathOrUrl = this.location.prepareExternalUrl(internalPath); 914 | handleResultRejections(this.navigation.navigate(pathOrUrl, { 915 | state: this.activeHistoryEntry.getState(), 916 | history: 'replace', 917 | info: { 918 | ɵrouterInfo: { 919 | intercept: false 920 | } 921 | } 922 | })); 923 | } 924 | } 925 | resetInternalState(finalUrl, traversalReset) { 926 | this.routerState = this.stateMemento.routerState; 927 | this.currentUrlTree = this.stateMemento.currentUrlTree; 928 | this.rawUrlTree = traversalReset ? this.stateMemento.rawUrlTree : this.urlHandlingStrategy.merge(this.currentUrlTree, finalUrl ?? this.rawUrlTree); 929 | } 930 | handleNavigate(event) { 931 | if (!event.canIntercept) { 932 | return; 933 | } 934 | const routerInfo = event?.info?.ɵrouterInfo; 935 | if (routerInfo && !routerInfo.intercept) { 936 | return; 937 | } 938 | const isTriggeredByRouterTransition = !!routerInfo; 939 | if (!isTriggeredByRouterTransition) { 940 | this.currentNavigation.routerTransition?.abort(); 941 | if (!this.registered) { 942 | this.finishNavigation(); 943 | return; 944 | } 945 | } 946 | this.currentNavigation = { 947 | ...this.currentNavigation 948 | }; 949 | this.currentNavigation.navigationEvent = event; 950 | const abortHandler = () => { 951 | this.currentNavigation.routerTransition?.abort(); 952 | }; 953 | event.signal.addEventListener('abort', abortHandler); 954 | this.currentNavigation.removeAbortListener = () => event.signal.removeEventListener('abort', abortHandler); 955 | let scroll = this.inMemoryScrollingEnabled ? 'manual' : this.currentNavigation.routerTransition?.extras.scroll ?? 'after-transition'; 956 | const interceptOptions = { 957 | scroll 958 | }; 959 | const { 960 | promise: handlerPromise, 961 | resolve: resolveHandler, 962 | reject: rejectHandler 963 | } = _promiseWithResolvers(); 964 | this.currentNavigation.resolveHandler = () => { 965 | this.currentNavigation.removeAbortListener?.(); 966 | resolveHandler(); 967 | }; 968 | this.currentNavigation.rejectNavigateEvent = () => { 969 | this.currentNavigation.removeAbortListener?.(); 970 | rejectHandler(); 971 | }; 972 | handlerPromise.catch(() => {}); 973 | interceptOptions.handler = () => handlerPromise; 974 | event.intercept(interceptOptions); 975 | if (!isTriggeredByRouterTransition) { 976 | this.handleNavigateEventTriggeredOutsideRouterAPIs(event); 977 | } 978 | } 979 | handleNavigateEventTriggeredOutsideRouterAPIs(event) { 980 | const path = event.destination.url.substring(this.appRootURL.length - 1); 981 | const state = event.destination.getState(); 982 | this.nonRouterCurrentEntryChangeSubject.next({ 983 | path, 984 | state 985 | }); 986 | } 987 | eventAndRouterDestinationsMatch(navigateEvent, transition) { 988 | const internalPath = this.createBrowserPath(transition); 989 | const eventDestination = new URL(navigateEvent.destination.url); 990 | const routerDestination = this.location.prepareExternalUrl(internalPath); 991 | return new URL(routerDestination, eventDestination.origin).href === eventDestination.href; 992 | } 993 | static ɵfac = i0.ɵɵngDeclareFactory({ 994 | minVersion: "12.0.0", 995 | version: "21.1.0-next.3+sha-9fa77af", 996 | ngImport: i0, 997 | type: NavigationStateManager, 998 | deps: [], 999 | target: i0.ɵɵFactoryTarget.Injectable 1000 | }); 1001 | static ɵprov = i0.ɵɵngDeclareInjectable({ 1002 | minVersion: "12.0.0", 1003 | version: "21.1.0-next.3+sha-9fa77af", 1004 | ngImport: i0, 1005 | type: NavigationStateManager, 1006 | providedIn: 'root' 1007 | }); 1008 | } 1009 | i0.ɵɵngDeclareClassMetadata({ 1010 | minVersion: "12.0.0", 1011 | version: "21.1.0-next.3+sha-9fa77af", 1012 | ngImport: i0, 1013 | type: NavigationStateManager, 1014 | decorators: [{ 1015 | type: Injectable, 1016 | args: [{ 1017 | providedIn: 'root' 1018 | }] 1019 | }], 1020 | ctorParameters: () => [] 1021 | }); 1022 | function handleResultRejections(result) { 1023 | result.finished.catch(() => {}); 1024 | result.committed.catch(() => {}); 1025 | return result; 1026 | } 1027 | 1028 | function provideRouter(routes, ...features) { 1029 | if (typeof ngDevMode === 'undefined' || ngDevMode) { 1030 | _publishExternalGlobalUtil('ɵgetLoadedRoutes', getLoadedRoutes); 1031 | _publishExternalGlobalUtil('ɵgetRouterInstance', getRouterInstance); 1032 | _publishExternalGlobalUtil('ɵnavigateByUrl', navigateByUrl); 1033 | } 1034 | return makeEnvironmentProviders([{ 1035 | provide: ROUTES, 1036 | multi: true, 1037 | useValue: routes 1038 | }, typeof ngDevMode === 'undefined' || ngDevMode ? { 1039 | provide: ROUTER_IS_PROVIDED, 1040 | useValue: true 1041 | } : [], { 1042 | provide: ActivatedRoute, 1043 | useFactory: rootRoute 1044 | }, { 1045 | provide: APP_BOOTSTRAP_LISTENER, 1046 | multi: true, 1047 | useFactory: getBootstrapListener 1048 | }, features.map(feature => feature.ɵproviders)]); 1049 | } 1050 | function rootRoute() { 1051 | return inject(Router).routerState.root; 1052 | } 1053 | function routerFeature(kind, providers) { 1054 | return { 1055 | ɵkind: kind, 1056 | ɵproviders: providers 1057 | }; 1058 | } 1059 | const ROUTER_IS_PROVIDED = new InjectionToken(typeof ngDevMode !== 'undefined' && ngDevMode ? 'Router is provided' : '', { 1060 | factory: () => false 1061 | }); 1062 | const routerIsProvidedDevModeCheck = { 1063 | provide: ENVIRONMENT_INITIALIZER, 1064 | multi: true, 1065 | useFactory() { 1066 | return () => { 1067 | if (!inject(ROUTER_IS_PROVIDED)) { 1068 | console.warn('`provideRoutes` was called without `provideRouter` or `RouterModule.forRoot`. ' + 'This is likely a mistake.'); 1069 | } 1070 | }; 1071 | } 1072 | }; 1073 | function provideRoutes(routes) { 1074 | return [{ 1075 | provide: ROUTES, 1076 | multi: true, 1077 | useValue: routes 1078 | }, typeof ngDevMode === 'undefined' || ngDevMode ? routerIsProvidedDevModeCheck : []]; 1079 | } 1080 | function withInMemoryScrolling(options = {}) { 1081 | const providers = [{ 1082 | provide: ROUTER_SCROLLER, 1083 | useFactory: () => new RouterScroller(options) 1084 | }]; 1085 | return routerFeature(4, providers); 1086 | } 1087 | function withPlatformNavigation() { 1088 | const devModeLocationCheck = typeof ngDevMode === 'undefined' || ngDevMode ? [provideEnvironmentInitializer(() => { 1089 | const locationInstance = inject(Location); 1090 | if (!(locationInstance instanceof _NavigationAdapterForLocation)) { 1091 | const locationConstructorName = locationInstance.constructor.name; 1092 | let message = `'withPlatformNavigation' provides a 'Location' implementation that ensures navigation APIs are consistently used.` + ` An instance of ${locationConstructorName} was found instead.`; 1093 | if (locationConstructorName === 'SpyLocation') { 1094 | message += ` One of 'RouterTestingModule' or 'provideLocationMocks' was likely used. 'withPlatformNavigation' does not work with these because they override the Location implementation.`; 1095 | } 1096 | throw new Error(message); 1097 | } 1098 | })] : []; 1099 | const providers = [{ 1100 | provide: StateManager, 1101 | useExisting: NavigationStateManager 1102 | }, { 1103 | provide: Location, 1104 | useClass: _NavigationAdapterForLocation 1105 | }, devModeLocationCheck]; 1106 | return routerFeature(4, providers); 1107 | } 1108 | function getBootstrapListener() { 1109 | const injector = inject(Injector); 1110 | return bootstrappedComponentRef => { 1111 | const ref = injector.get(ApplicationRef); 1112 | if (bootstrappedComponentRef !== ref.components[0]) { 1113 | return; 1114 | } 1115 | const router = injector.get(Router); 1116 | const bootstrapDone = injector.get(BOOTSTRAP_DONE); 1117 | if (injector.get(INITIAL_NAVIGATION) === 1) { 1118 | router.initialNavigation(); 1119 | } 1120 | injector.get(ROUTER_PRELOADER, null, { 1121 | optional: true 1122 | })?.setUpPreloading(); 1123 | injector.get(ROUTER_SCROLLER, null, { 1124 | optional: true 1125 | })?.init(); 1126 | router.resetRootComponentType(ref.componentTypes[0]); 1127 | if (!bootstrapDone.closed) { 1128 | bootstrapDone.next(); 1129 | bootstrapDone.complete(); 1130 | bootstrapDone.unsubscribe(); 1131 | } 1132 | }; 1133 | } 1134 | const BOOTSTRAP_DONE = new InjectionToken(typeof ngDevMode === 'undefined' || ngDevMode ? 'bootstrap done indicator' : '', { 1135 | factory: () => { 1136 | return new Subject(); 1137 | } 1138 | }); 1139 | const INITIAL_NAVIGATION = new InjectionToken(typeof ngDevMode === 'undefined' || ngDevMode ? 'initial navigation' : '', { 1140 | factory: () => 1 1141 | }); 1142 | function withEnabledBlockingInitialNavigation() { 1143 | const providers = [{ 1144 | provide: _IS_ENABLED_BLOCKING_INITIAL_NAVIGATION, 1145 | useValue: true 1146 | }, { 1147 | provide: INITIAL_NAVIGATION, 1148 | useValue: 0 1149 | }, provideAppInitializer(() => { 1150 | const injector = inject(Injector); 1151 | const locationInitialized = injector.get(LOCATION_INITIALIZED, Promise.resolve()); 1152 | return locationInitialized.then(() => { 1153 | return new Promise(resolve => { 1154 | const router = injector.get(Router); 1155 | const bootstrapDone = injector.get(BOOTSTRAP_DONE); 1156 | afterNextNavigation(router, () => { 1157 | resolve(true); 1158 | }); 1159 | injector.get(NavigationTransitions).afterPreactivation = () => { 1160 | resolve(true); 1161 | return bootstrapDone.closed ? of(void 0) : bootstrapDone; 1162 | }; 1163 | router.initialNavigation(); 1164 | }); 1165 | }); 1166 | })]; 1167 | return routerFeature(2, providers); 1168 | } 1169 | function withDisabledInitialNavigation() { 1170 | const providers = [provideAppInitializer(() => { 1171 | inject(Router).setUpLocationChangeListener(); 1172 | }), { 1173 | provide: INITIAL_NAVIGATION, 1174 | useValue: 2 1175 | }]; 1176 | return routerFeature(3, providers); 1177 | } 1178 | function withDebugTracing() { 1179 | let providers = []; 1180 | if (typeof ngDevMode === 'undefined' || ngDevMode) { 1181 | providers = [{ 1182 | provide: ENVIRONMENT_INITIALIZER, 1183 | multi: true, 1184 | useFactory: () => { 1185 | const router = inject(Router); 1186 | return () => router.events.subscribe(e => { 1187 | console.group?.(`Router Event: ${e.constructor.name}`); 1188 | console.log(stringifyEvent(e)); 1189 | console.log(e); 1190 | console.groupEnd?.(); 1191 | }); 1192 | } 1193 | }]; 1194 | } else { 1195 | providers = []; 1196 | } 1197 | return routerFeature(1, providers); 1198 | } 1199 | const ROUTER_PRELOADER = new InjectionToken(typeof ngDevMode === 'undefined' || ngDevMode ? 'router preloader' : ''); 1200 | function withPreloading(preloadingStrategy) { 1201 | const providers = [{ 1202 | provide: ROUTER_PRELOADER, 1203 | useExisting: RouterPreloader 1204 | }, { 1205 | provide: PreloadingStrategy, 1206 | useExisting: preloadingStrategy 1207 | }]; 1208 | return routerFeature(0, providers); 1209 | } 1210 | function withRouterConfig(options) { 1211 | const providers = [{ 1212 | provide: ROUTER_CONFIGURATION, 1213 | useValue: options 1214 | }]; 1215 | return routerFeature(5, providers); 1216 | } 1217 | function withHashLocation() { 1218 | const providers = [{ 1219 | provide: LocationStrategy, 1220 | useClass: HashLocationStrategy 1221 | }]; 1222 | return routerFeature(6, providers); 1223 | } 1224 | function withNavigationErrorHandler(handler) { 1225 | const providers = [{ 1226 | provide: NAVIGATION_ERROR_HANDLER, 1227 | useValue: handler 1228 | }]; 1229 | return routerFeature(7, providers); 1230 | } 1231 | function withComponentInputBinding() { 1232 | const providers = [RoutedComponentInputBinder, { 1233 | provide: INPUT_BINDER, 1234 | useExisting: RoutedComponentInputBinder 1235 | }]; 1236 | return routerFeature(8, providers); 1237 | } 1238 | function withViewTransitions(options) { 1239 | _performanceMarkFeature('NgRouterViewTransitions'); 1240 | const providers = [{ 1241 | provide: CREATE_VIEW_TRANSITION, 1242 | useValue: createViewTransition 1243 | }, { 1244 | provide: VIEW_TRANSITION_OPTIONS, 1245 | useValue: { 1246 | skipNextTransition: !!options?.skipInitialTransition, 1247 | ...options 1248 | } 1249 | }]; 1250 | return routerFeature(9, providers); 1251 | } 1252 | 1253 | const ROUTER_DIRECTIVES = [RouterOutlet, RouterLink, RouterLinkActive, _EmptyOutletComponent]; 1254 | const ROUTER_FORROOT_GUARD = new InjectionToken(typeof ngDevMode === 'undefined' || ngDevMode ? 'router duplicate forRoot guard' : ''); 1255 | const ROUTER_PROVIDERS = [Location, { 1256 | provide: UrlSerializer, 1257 | useClass: DefaultUrlSerializer 1258 | }, Router, ChildrenOutletContexts, { 1259 | provide: ActivatedRoute, 1260 | useFactory: rootRoute 1261 | }, RouterConfigLoader, typeof ngDevMode === 'undefined' || ngDevMode ? { 1262 | provide: ROUTER_IS_PROVIDED, 1263 | useValue: true 1264 | } : []]; 1265 | class RouterModule { 1266 | constructor() { 1267 | if (typeof ngDevMode === 'undefined' || ngDevMode) { 1268 | inject(ROUTER_FORROOT_GUARD, { 1269 | optional: true 1270 | }); 1271 | } 1272 | } 1273 | static forRoot(routes, config) { 1274 | return { 1275 | ngModule: RouterModule, 1276 | providers: [ROUTER_PROVIDERS, typeof ngDevMode === 'undefined' || ngDevMode ? config?.enableTracing ? withDebugTracing().ɵproviders : [] : [], { 1277 | provide: ROUTES, 1278 | multi: true, 1279 | useValue: routes 1280 | }, typeof ngDevMode === 'undefined' || ngDevMode ? { 1281 | provide: ROUTER_FORROOT_GUARD, 1282 | useFactory: provideForRootGuard 1283 | } : [], config?.errorHandler ? { 1284 | provide: NAVIGATION_ERROR_HANDLER, 1285 | useValue: config.errorHandler 1286 | } : [], { 1287 | provide: ROUTER_CONFIGURATION, 1288 | useValue: config ? config : {} 1289 | }, config?.useHash ? provideHashLocationStrategy() : providePathLocationStrategy(), provideRouterScroller(), config?.preloadingStrategy ? withPreloading(config.preloadingStrategy).ɵproviders : [], config?.initialNavigation ? provideInitialNavigation(config) : [], config?.bindToComponentInputs ? withComponentInputBinding().ɵproviders : [], config?.enableViewTransitions ? withViewTransitions().ɵproviders : [], provideRouterInitializer()] 1290 | }; 1291 | } 1292 | static forChild(routes) { 1293 | return { 1294 | ngModule: RouterModule, 1295 | providers: [{ 1296 | provide: ROUTES, 1297 | multi: true, 1298 | useValue: routes 1299 | }] 1300 | }; 1301 | } 1302 | static ɵfac = i0.ɵɵngDeclareFactory({ 1303 | minVersion: "12.0.0", 1304 | version: "21.1.0-next.3+sha-9fa77af", 1305 | ngImport: i0, 1306 | type: RouterModule, 1307 | deps: [], 1308 | target: i0.ɵɵFactoryTarget.NgModule 1309 | }); 1310 | static ɵmod = i0.ɵɵngDeclareNgModule({ 1311 | minVersion: "14.0.0", 1312 | version: "21.1.0-next.3+sha-9fa77af", 1313 | ngImport: i0, 1314 | type: RouterModule, 1315 | imports: [RouterOutlet, RouterLink, RouterLinkActive, _EmptyOutletComponent], 1316 | exports: [RouterOutlet, RouterLink, RouterLinkActive, _EmptyOutletComponent] 1317 | }); 1318 | static ɵinj = i0.ɵɵngDeclareInjector({ 1319 | minVersion: "12.0.0", 1320 | version: "21.1.0-next.3+sha-9fa77af", 1321 | ngImport: i0, 1322 | type: RouterModule 1323 | }); 1324 | } 1325 | i0.ɵɵngDeclareClassMetadata({ 1326 | minVersion: "12.0.0", 1327 | version: "21.1.0-next.3+sha-9fa77af", 1328 | ngImport: i0, 1329 | type: RouterModule, 1330 | decorators: [{ 1331 | type: NgModule, 1332 | args: [{ 1333 | imports: ROUTER_DIRECTIVES, 1334 | exports: ROUTER_DIRECTIVES 1335 | }] 1336 | }], 1337 | ctorParameters: () => [] 1338 | }); 1339 | function provideRouterScroller() { 1340 | return { 1341 | provide: ROUTER_SCROLLER, 1342 | useFactory: () => { 1343 | const viewportScroller = inject(ViewportScroller); 1344 | const config = inject(ROUTER_CONFIGURATION); 1345 | if (config.scrollOffset) { 1346 | viewportScroller.setOffset(config.scrollOffset); 1347 | } 1348 | return new RouterScroller(config); 1349 | } 1350 | }; 1351 | } 1352 | function provideHashLocationStrategy() { 1353 | return { 1354 | provide: LocationStrategy, 1355 | useClass: HashLocationStrategy 1356 | }; 1357 | } 1358 | function providePathLocationStrategy() { 1359 | return { 1360 | provide: LocationStrategy, 1361 | useClass: PathLocationStrategy 1362 | }; 1363 | } 1364 | function provideForRootGuard() { 1365 | const router = inject(Router, { 1366 | optional: true, 1367 | skipSelf: true 1368 | }); 1369 | if (router) { 1370 | throw new _RuntimeError(4007, `The Router was provided more than once. This can happen if 'forRoot' is used outside of the root injector.` + ` Lazy loaded modules should use RouterModule.forChild() instead.`); 1371 | } 1372 | return 'guarded'; 1373 | } 1374 | function provideInitialNavigation(config) { 1375 | return [config.initialNavigation === 'disabled' ? withDisabledInitialNavigation().ɵproviders : [], config.initialNavigation === 'enabledBlocking' ? withEnabledBlockingInitialNavigation().ɵproviders : []]; 1376 | } 1377 | const ROUTER_INITIALIZER = new InjectionToken(typeof ngDevMode === 'undefined' || ngDevMode ? 'Router Initializer' : ''); 1378 | function provideRouterInitializer() { 1379 | return [{ 1380 | provide: ROUTER_INITIALIZER, 1381 | useFactory: getBootstrapListener 1382 | }, { 1383 | provide: APP_BOOTSTRAP_LISTENER, 1384 | multi: true, 1385 | useExisting: ROUTER_INITIALIZER 1386 | }]; 1387 | } 1388 | 1389 | export { NoPreloading, PreloadAllModules, PreloadingStrategy, ROUTER_INITIALIZER, ROUTER_PROVIDERS, RouterLink, RouterLinkActive, RouterModule, RouterPreloader, provideRouter, provideRoutes, withComponentInputBinding, withDebugTracing, withDisabledInitialNavigation, withEnabledBlockingInitialNavigation, withHashLocation, withInMemoryScrolling, withNavigationErrorHandler, withPlatformNavigation, withPreloading, withRouterConfig, withViewTransitions }; 1390 | //# sourceMappingURL=_router_module-chunk.mjs.map 1391 | --------------------------------------------------------------------------------