@angular/router 19.2.4 → 19.2.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,1632 @@
1
+ /**
2
+ * @license Angular v19.2.6
3
+ * (c) 2010-2025 Google LLC. https://angular.io/
4
+ * License: MIT
5
+ */
6
+
7
+ import * as i3 from '@angular/common';
8
+ import { LOCATION_INITIALIZED, HashLocationStrategy, LocationStrategy, ViewportScroller, Location, PathLocationStrategy } from '@angular/common';
9
+ import * as i0 from '@angular/core';
10
+ import { ɵRuntimeError as _RuntimeError, ɵɵsanitizeUrlOrResourceUrl as __sanitizeUrlOrResourceUrl, booleanAttribute, HostListener, Input, HostBinding, Attribute, Directive, EventEmitter, Output, ContentChildren, Optional, createEnvironmentInjector, Injectable, InjectionToken, ɵperformanceMarkFeature as _performanceMarkFeature, makeEnvironmentProviders, APP_BOOTSTRAP_LISTENER, ENVIRONMENT_INITIALIZER, provideAppInitializer, inject, Injector, ApplicationRef, InjectFlags, NgZone, SkipSelf, NgModule } from '@angular/core';
11
+ import { NavigationEnd, isUrlTree, Router, ActivatedRoute, RouterConfigLoader, NavigationStart, NavigationSkipped, NavigationSkippedCode, Scroll, UrlSerializer, NavigationTransitions, ROUTES, afterNextNavigation, ROUTER_CONFIGURATION, NAVIGATION_ERROR_HANDLER, RoutedComponentInputBinder, INPUT_BINDER, createViewTransition, CREATE_VIEW_TRANSITION, VIEW_TRANSITION_OPTIONS, stringifyEvent, DefaultUrlSerializer, ChildrenOutletContexts, RouterOutlet, ɵEmptyOutletComponent as _EmptyOutletComponent } from './router-B-Y85L0c.mjs';
12
+ import { Subject, of, from } from 'rxjs';
13
+ import { mergeAll, catchError, filter, concatMap, mergeMap } from 'rxjs/operators';
14
+
15
+ /**
16
+ * @description
17
+ *
18
+ * When applied to an element in a template, makes that element a link
19
+ * that initiates navigation to a route. Navigation opens one or more routed components
20
+ * in one or more `<router-outlet>` locations on the page.
21
+ *
22
+ * Given a route configuration `[{ path: 'user/:name', component: UserCmp }]`,
23
+ * the following creates a static link to the route:
24
+ * `<a routerLink="/user/bob">link to user component</a>`
25
+ *
26
+ * You can use dynamic values to generate the link.
27
+ * For a dynamic link, pass an array of path segments,
28
+ * followed by the params for each segment.
29
+ * For example, `['/team', teamId, 'user', userName, {details: true}]`
30
+ * generates a link to `/team/11/user/bob;details=true`.
31
+ *
32
+ * Multiple static segments can be merged into one term and combined with dynamic segments.
33
+ * For example, `['/team/11/user', userName, {details: true}]`
34
+ *
35
+ * The input that you provide to the link is treated as a delta to the current URL.
36
+ * For instance, suppose the current URL is `/user/(box//aux:team)`.
37
+ * The link `<a [routerLink]="['/user/jim']">Jim</a>` creates the URL
38
+ * `/user/(jim//aux:team)`.
39
+ * See {@link Router#createUrlTree} for more information.
40
+ *
41
+ * @usageNotes
42
+ *
43
+ * You can use absolute or relative paths in a link, set query parameters,
44
+ * control how parameters are handled, and keep a history of navigation states.
45
+ *
46
+ * ### Relative link paths
47
+ *
48
+ * The first segment name can be prepended with `/`, `./`, or `../`.
49
+ * * If the first segment begins with `/`, the router looks up the route from the root of the
50
+ * app.
51
+ * * If the first segment begins with `./`, or doesn't begin with a slash, the router
52
+ * looks in the children of the current activated route.
53
+ * * If the first segment begins with `../`, the router goes up one level in the route tree.
54
+ *
55
+ * ### Setting and handling query params and fragments
56
+ *
57
+ * The following link adds a query parameter and a fragment to the generated URL:
58
+ *
59
+ * ```html
60
+ * <a [routerLink]="['/user/bob']" [queryParams]="{debug: true}" fragment="education">
61
+ * link to user component
62
+ * </a>
63
+ * ```
64
+ * By default, the directive constructs the new URL using the given query parameters.
65
+ * The example generates the link: `/user/bob?debug=true#education`.
66
+ *
67
+ * You can instruct the directive to handle query parameters differently
68
+ * by specifying the `queryParamsHandling` option in the link.
69
+ * Allowed values are:
70
+ *
71
+ * - `'merge'`: Merge the given `queryParams` into the current query params.
72
+ * - `'preserve'`: Preserve the current query params.
73
+ *
74
+ * For example:
75
+ *
76
+ * ```html
77
+ * <a [routerLink]="['/user/bob']" [queryParams]="{debug: true}" queryParamsHandling="merge">
78
+ * link to user component
79
+ * </a>
80
+ * ```
81
+ *
82
+ * `queryParams`, `fragment`, `queryParamsHandling`, `preserveFragment`, and `relativeTo`
83
+ * cannot be used when the `routerLink` input is a `UrlTree`.
84
+ *
85
+ * See {@link UrlCreationOptions#queryParamsHandling}.
86
+ *
87
+ * ### Preserving navigation history
88
+ *
89
+ * You can provide a `state` value to be persisted to the browser's
90
+ * [`History.state` property](https://developer.mozilla.org/en-US/docs/Web/API/History#Properties).
91
+ * For example:
92
+ *
93
+ * ```html
94
+ * <a [routerLink]="['/user/bob']" [state]="{tracingId: 123}">
95
+ * link to user component
96
+ * </a>
97
+ * ```
98
+ *
99
+ * Use {@link Router#getCurrentNavigation} to retrieve a saved
100
+ * navigation-state value. For example, to capture the `tracingId` during the `NavigationStart`
101
+ * event:
102
+ *
103
+ * ```ts
104
+ * // Get NavigationStart events
105
+ * router.events.pipe(filter(e => e instanceof NavigationStart)).subscribe(e => {
106
+ * const navigation = router.getCurrentNavigation();
107
+ * tracingService.trace({id: navigation.extras.state.tracingId});
108
+ * });
109
+ * ```
110
+ *
111
+ * @ngModule RouterModule
112
+ *
113
+ * @publicApi
114
+ */
115
+ class RouterLink {
116
+ router;
117
+ route;
118
+ tabIndexAttribute;
119
+ renderer;
120
+ el;
121
+ locationStrategy;
122
+ /**
123
+ * Represents an `href` attribute value applied to a host element,
124
+ * when a host element is `<a>`. For other tags, the value is `null`.
125
+ */
126
+ href = null;
127
+ /**
128
+ * Represents the `target` attribute on a host element.
129
+ * This is only used when the host element is an `<a>` tag.
130
+ */
131
+ target;
132
+ /**
133
+ * Passed to {@link Router#createUrlTree} as part of the
134
+ * `UrlCreationOptions`.
135
+ * @see {@link UrlCreationOptions#queryParams}
136
+ * @see {@link Router#createUrlTree}
137
+ */
138
+ queryParams;
139
+ /**
140
+ * Passed to {@link Router#createUrlTree} as part of the
141
+ * `UrlCreationOptions`.
142
+ * @see {@link UrlCreationOptions#fragment}
143
+ * @see {@link Router#createUrlTree}
144
+ */
145
+ fragment;
146
+ /**
147
+ * Passed to {@link Router#createUrlTree} as part of the
148
+ * `UrlCreationOptions`.
149
+ * @see {@link UrlCreationOptions#queryParamsHandling}
150
+ * @see {@link Router#createUrlTree}
151
+ */
152
+ queryParamsHandling;
153
+ /**
154
+ * Passed to {@link Router#navigateByUrl} as part of the
155
+ * `NavigationBehaviorOptions`.
156
+ * @see {@link NavigationBehaviorOptions#state}
157
+ * @see {@link Router#navigateByUrl}
158
+ */
159
+ state;
160
+ /**
161
+ * Passed to {@link Router#navigateByUrl} as part of the
162
+ * `NavigationBehaviorOptions`.
163
+ * @see {@link NavigationBehaviorOptions#info}
164
+ * @see {@link Router#navigateByUrl}
165
+ */
166
+ info;
167
+ /**
168
+ * Passed to {@link Router#createUrlTree} as part of the
169
+ * `UrlCreationOptions`.
170
+ * Specify a value here when you do not want to use the default value
171
+ * for `routerLink`, which is the current activated route.
172
+ * Note that a value of `undefined` here will use the `routerLink` default.
173
+ * @see {@link UrlCreationOptions#relativeTo}
174
+ * @see {@link Router#createUrlTree}
175
+ */
176
+ relativeTo;
177
+ /** Whether a host element is an `<a>` tag. */
178
+ isAnchorElement;
179
+ subscription;
180
+ /** @internal */
181
+ onChanges = new Subject();
182
+ constructor(router, route, tabIndexAttribute, renderer, el, locationStrategy) {
183
+ this.router = router;
184
+ this.route = route;
185
+ this.tabIndexAttribute = tabIndexAttribute;
186
+ this.renderer = renderer;
187
+ this.el = el;
188
+ this.locationStrategy = locationStrategy;
189
+ const tagName = el.nativeElement.tagName?.toLowerCase();
190
+ this.isAnchorElement = tagName === 'a' || tagName === 'area';
191
+ if (this.isAnchorElement) {
192
+ this.subscription = router.events.subscribe((s) => {
193
+ if (s instanceof NavigationEnd) {
194
+ this.updateHref();
195
+ }
196
+ });
197
+ }
198
+ else {
199
+ this.setTabIndexIfNotOnNativeEl('0');
200
+ }
201
+ }
202
+ /**
203
+ * Passed to {@link Router#createUrlTree} as part of the
204
+ * `UrlCreationOptions`.
205
+ * @see {@link UrlCreationOptions#preserveFragment}
206
+ * @see {@link Router#createUrlTree}
207
+ */
208
+ preserveFragment = false;
209
+ /**
210
+ * Passed to {@link Router#navigateByUrl} as part of the
211
+ * `NavigationBehaviorOptions`.
212
+ * @see {@link NavigationBehaviorOptions#skipLocationChange}
213
+ * @see {@link Router#navigateByUrl}
214
+ */
215
+ skipLocationChange = false;
216
+ /**
217
+ * Passed to {@link Router#navigateByUrl} as part of the
218
+ * `NavigationBehaviorOptions`.
219
+ * @see {@link NavigationBehaviorOptions#replaceUrl}
220
+ * @see {@link Router#navigateByUrl}
221
+ */
222
+ replaceUrl = false;
223
+ /**
224
+ * Modifies the tab index if there was not a tabindex attribute on the element during
225
+ * instantiation.
226
+ */
227
+ setTabIndexIfNotOnNativeEl(newTabIndex) {
228
+ if (this.tabIndexAttribute != null /* both `null` and `undefined` */ || this.isAnchorElement) {
229
+ return;
230
+ }
231
+ this.applyAttributeValue('tabindex', newTabIndex);
232
+ }
233
+ /** @nodoc */
234
+ // TODO(atscott): Remove changes parameter in major version as a breaking change.
235
+ ngOnChanges(changes) {
236
+ if (ngDevMode &&
237
+ isUrlTree(this.routerLinkInput) &&
238
+ (this.fragment !== undefined ||
239
+ this.queryParams ||
240
+ this.queryParamsHandling ||
241
+ this.preserveFragment ||
242
+ this.relativeTo)) {
243
+ throw new _RuntimeError(4016 /* RuntimeErrorCode.INVALID_ROUTER_LINK_INPUTS */, 'Cannot configure queryParams or fragment when using a UrlTree as the routerLink input value.');
244
+ }
245
+ if (this.isAnchorElement) {
246
+ this.updateHref();
247
+ }
248
+ // This is subscribed to by `RouterLinkActive` so that it knows to update when there are changes
249
+ // to the RouterLinks it's tracking.
250
+ this.onChanges.next(this);
251
+ }
252
+ routerLinkInput = null;
253
+ /**
254
+ * Commands to pass to {@link Router#createUrlTree} or a `UrlTree`.
255
+ * - **array**: commands to pass to {@link Router#createUrlTree}.
256
+ * - **string**: shorthand for array of commands with just the string, i.e. `['/route']`
257
+ * - **UrlTree**: a `UrlTree` for this link rather than creating one from the commands
258
+ * and other inputs that correspond to properties of `UrlCreationOptions`.
259
+ * - **null|undefined**: effectively disables the `routerLink`
260
+ * @see {@link Router#createUrlTree}
261
+ */
262
+ set routerLink(commandsOrUrlTree) {
263
+ if (commandsOrUrlTree == null) {
264
+ this.routerLinkInput = null;
265
+ this.setTabIndexIfNotOnNativeEl(null);
266
+ }
267
+ else {
268
+ if (isUrlTree(commandsOrUrlTree)) {
269
+ this.routerLinkInput = commandsOrUrlTree;
270
+ }
271
+ else {
272
+ this.routerLinkInput = Array.isArray(commandsOrUrlTree)
273
+ ? commandsOrUrlTree
274
+ : [commandsOrUrlTree];
275
+ }
276
+ this.setTabIndexIfNotOnNativeEl('0');
277
+ }
278
+ }
279
+ /** @nodoc */
280
+ onClick(button, ctrlKey, shiftKey, altKey, metaKey) {
281
+ const urlTree = this.urlTree;
282
+ if (urlTree === null) {
283
+ return true;
284
+ }
285
+ if (this.isAnchorElement) {
286
+ if (button !== 0 || ctrlKey || shiftKey || altKey || metaKey) {
287
+ return true;
288
+ }
289
+ if (typeof this.target === 'string' && this.target != '_self') {
290
+ return true;
291
+ }
292
+ }
293
+ const extras = {
294
+ skipLocationChange: this.skipLocationChange,
295
+ replaceUrl: this.replaceUrl,
296
+ state: this.state,
297
+ info: this.info,
298
+ };
299
+ this.router.navigateByUrl(urlTree, extras);
300
+ // Return `false` for `<a>` elements to prevent default action
301
+ // and cancel the native behavior, since the navigation is handled
302
+ // by the Router.
303
+ return !this.isAnchorElement;
304
+ }
305
+ /** @nodoc */
306
+ ngOnDestroy() {
307
+ this.subscription?.unsubscribe();
308
+ }
309
+ updateHref() {
310
+ const urlTree = this.urlTree;
311
+ this.href =
312
+ urlTree !== null && this.locationStrategy
313
+ ? this.locationStrategy?.prepareExternalUrl(this.router.serializeUrl(urlTree))
314
+ : null;
315
+ const sanitizedValue = this.href === null
316
+ ? null
317
+ : // This class represents a directive that can be added to both `<a>` elements,
318
+ // as well as other elements. As a result, we can't define security context at
319
+ // compile time. So the security context is deferred to runtime.
320
+ // The `ɵɵsanitizeUrlOrResourceUrl` selects the necessary sanitizer function
321
+ // based on the tag and property names. The logic mimics the one from
322
+ // `packages/compiler/src/schema/dom_security_schema.ts`, which is used at compile time.
323
+ //
324
+ // Note: we should investigate whether we can switch to using `@HostBinding('attr.href')`
325
+ // instead of applying a value via a renderer, after a final merge of the
326
+ // `RouterLinkWithHref` directive.
327
+ __sanitizeUrlOrResourceUrl(this.href, this.el.nativeElement.tagName.toLowerCase(), 'href');
328
+ this.applyAttributeValue('href', sanitizedValue);
329
+ }
330
+ applyAttributeValue(attrName, attrValue) {
331
+ const renderer = this.renderer;
332
+ const nativeElement = this.el.nativeElement;
333
+ if (attrValue !== null) {
334
+ renderer.setAttribute(nativeElement, attrName, attrValue);
335
+ }
336
+ else {
337
+ renderer.removeAttribute(nativeElement, attrName);
338
+ }
339
+ }
340
+ get urlTree() {
341
+ if (this.routerLinkInput === null) {
342
+ return null;
343
+ }
344
+ else if (isUrlTree(this.routerLinkInput)) {
345
+ return this.routerLinkInput;
346
+ }
347
+ return this.router.createUrlTree(this.routerLinkInput, {
348
+ // If the `relativeTo` input is not defined, we want to use `this.route` by default.
349
+ // Otherwise, we should use the value provided by the user in the input.
350
+ relativeTo: this.relativeTo !== undefined ? this.relativeTo : this.route,
351
+ queryParams: this.queryParams,
352
+ fragment: this.fragment,
353
+ queryParamsHandling: this.queryParamsHandling,
354
+ preserveFragment: this.preserveFragment,
355
+ });
356
+ }
357
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.6", ngImport: i0, type: RouterLink, deps: [{ token: Router }, { token: ActivatedRoute }, { token: 'tabindex', attribute: true }, { token: i0.Renderer2 }, { token: i0.ElementRef }, { token: i3.LocationStrategy }], target: i0.ɵɵFactoryTarget.Directive });
358
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "16.1.0", version: "19.2.6", type: RouterLink, isStandalone: true, selector: "[routerLink]", inputs: { target: "target", queryParams: "queryParams", fragment: "fragment", queryParamsHandling: "queryParamsHandling", state: "state", info: "info", relativeTo: "relativeTo", preserveFragment: ["preserveFragment", "preserveFragment", booleanAttribute], skipLocationChange: ["skipLocationChange", "skipLocationChange", booleanAttribute], replaceUrl: ["replaceUrl", "replaceUrl", booleanAttribute], routerLink: "routerLink" }, host: { listeners: { "click": "onClick($event.button,$event.ctrlKey,$event.shiftKey,$event.altKey,$event.metaKey)" }, properties: { "attr.target": "this.target" } }, usesOnChanges: true, ngImport: i0 });
359
+ }
360
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.6", ngImport: i0, type: RouterLink, decorators: [{
361
+ type: Directive,
362
+ args: [{
363
+ selector: '[routerLink]',
364
+ }]
365
+ }], ctorParameters: () => [{ type: Router }, { type: ActivatedRoute }, { type: undefined, decorators: [{
366
+ type: Attribute,
367
+ args: ['tabindex']
368
+ }] }, { type: i0.Renderer2 }, { type: i0.ElementRef }, { type: i3.LocationStrategy }], propDecorators: { target: [{
369
+ type: HostBinding,
370
+ args: ['attr.target']
371
+ }, {
372
+ type: Input
373
+ }], queryParams: [{
374
+ type: Input
375
+ }], fragment: [{
376
+ type: Input
377
+ }], queryParamsHandling: [{
378
+ type: Input
379
+ }], state: [{
380
+ type: Input
381
+ }], info: [{
382
+ type: Input
383
+ }], relativeTo: [{
384
+ type: Input
385
+ }], preserveFragment: [{
386
+ type: Input,
387
+ args: [{ transform: booleanAttribute }]
388
+ }], skipLocationChange: [{
389
+ type: Input,
390
+ args: [{ transform: booleanAttribute }]
391
+ }], replaceUrl: [{
392
+ type: Input,
393
+ args: [{ transform: booleanAttribute }]
394
+ }], routerLink: [{
395
+ type: Input
396
+ }], onClick: [{
397
+ type: HostListener,
398
+ args: ['click', [
399
+ '$event.button',
400
+ '$event.ctrlKey',
401
+ '$event.shiftKey',
402
+ '$event.altKey',
403
+ '$event.metaKey',
404
+ ]]
405
+ }] } });
406
+
407
+ /**
408
+ *
409
+ * @description
410
+ *
411
+ * Tracks whether the linked route of an element is currently active, and allows you
412
+ * to specify one or more CSS classes to add to the element when the linked route
413
+ * is active.
414
+ *
415
+ * Use this directive to create a visual distinction for elements associated with an active route.
416
+ * For example, the following code highlights the word "Bob" when the router
417
+ * activates the associated route:
418
+ *
419
+ * ```html
420
+ * <a routerLink="/user/bob" routerLinkActive="active-link">Bob</a>
421
+ * ```
422
+ *
423
+ * Whenever the URL is either '/user' or '/user/bob', the "active-link" class is
424
+ * added to the anchor tag. If the URL changes, the class is removed.
425
+ *
426
+ * You can set more than one class using a space-separated string or an array.
427
+ * For example:
428
+ *
429
+ * ```html
430
+ * <a routerLink="/user/bob" routerLinkActive="class1 class2">Bob</a>
431
+ * <a routerLink="/user/bob" [routerLinkActive]="['class1', 'class2']">Bob</a>
432
+ * ```
433
+ *
434
+ * To add the classes only when the URL matches the link exactly, add the option `exact: true`:
435
+ *
436
+ * ```html
437
+ * <a routerLink="/user/bob" routerLinkActive="active-link" [routerLinkActiveOptions]="{exact:
438
+ * true}">Bob</a>
439
+ * ```
440
+ *
441
+ * To directly check the `isActive` status of the link, assign the `RouterLinkActive`
442
+ * instance to a template variable.
443
+ * For example, the following checks the status without assigning any CSS classes:
444
+ *
445
+ * ```html
446
+ * <a routerLink="/user/bob" routerLinkActive #rla="routerLinkActive">
447
+ * Bob {{ rla.isActive ? '(already open)' : ''}}
448
+ * </a>
449
+ * ```
450
+ *
451
+ * You can apply the `RouterLinkActive` directive to an ancestor of linked elements.
452
+ * For example, the following sets the active-link class on the `<div>` parent tag
453
+ * when the URL is either '/user/jim' or '/user/bob'.
454
+ *
455
+ * ```html
456
+ * <div routerLinkActive="active-link" [routerLinkActiveOptions]="{exact: true}">
457
+ * <a routerLink="/user/jim">Jim</a>
458
+ * <a routerLink="/user/bob">Bob</a>
459
+ * </div>
460
+ * ```
461
+ *
462
+ * The `RouterLinkActive` directive can also be used to set the aria-current attribute
463
+ * to provide an alternative distinction for active elements to visually impaired users.
464
+ *
465
+ * For example, the following code adds the 'active' class to the Home Page link when it is
466
+ * indeed active and in such case also sets its aria-current attribute to 'page':
467
+ *
468
+ * ```html
469
+ * <a routerLink="/" routerLinkActive="active" ariaCurrentWhenActive="page">Home Page</a>
470
+ * ```
471
+ *
472
+ * @ngModule RouterModule
473
+ *
474
+ * @publicApi
475
+ */
476
+ class RouterLinkActive {
477
+ router;
478
+ element;
479
+ renderer;
480
+ cdr;
481
+ link;
482
+ links;
483
+ classes = [];
484
+ routerEventsSubscription;
485
+ linkInputChangesSubscription;
486
+ _isActive = false;
487
+ get isActive() {
488
+ return this._isActive;
489
+ }
490
+ /**
491
+ * Options to configure how to determine if the router link is active.
492
+ *
493
+ * These options are passed to the `Router.isActive()` function.
494
+ *
495
+ * @see {@link Router#isActive}
496
+ */
497
+ routerLinkActiveOptions = { exact: false };
498
+ /**
499
+ * Aria-current attribute to apply when the router link is active.
500
+ *
501
+ * Possible values: `'page'` | `'step'` | `'location'` | `'date'` | `'time'` | `true` | `false`.
502
+ *
503
+ * @see {@link https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-current}
504
+ */
505
+ ariaCurrentWhenActive;
506
+ /**
507
+ *
508
+ * You can use the output `isActiveChange` to get notified each time the link becomes
509
+ * active or inactive.
510
+ *
511
+ * Emits:
512
+ * true -> Route is active
513
+ * false -> Route is inactive
514
+ *
515
+ * ```html
516
+ * <a
517
+ * routerLink="/user/bob"
518
+ * routerLinkActive="active-link"
519
+ * (isActiveChange)="this.onRouterLinkActive($event)">Bob</a>
520
+ * ```
521
+ */
522
+ isActiveChange = new EventEmitter();
523
+ constructor(router, element, renderer, cdr, link) {
524
+ this.router = router;
525
+ this.element = element;
526
+ this.renderer = renderer;
527
+ this.cdr = cdr;
528
+ this.link = link;
529
+ this.routerEventsSubscription = router.events.subscribe((s) => {
530
+ if (s instanceof NavigationEnd) {
531
+ this.update();
532
+ }
533
+ });
534
+ }
535
+ /** @nodoc */
536
+ ngAfterContentInit() {
537
+ // `of(null)` is used to force subscribe body to execute once immediately (like `startWith`).
538
+ of(this.links.changes, of(null))
539
+ .pipe(mergeAll())
540
+ .subscribe((_) => {
541
+ this.update();
542
+ this.subscribeToEachLinkOnChanges();
543
+ });
544
+ }
545
+ subscribeToEachLinkOnChanges() {
546
+ this.linkInputChangesSubscription?.unsubscribe();
547
+ const allLinkChanges = [...this.links.toArray(), this.link]
548
+ .filter((link) => !!link)
549
+ .map((link) => link.onChanges);
550
+ this.linkInputChangesSubscription = from(allLinkChanges)
551
+ .pipe(mergeAll())
552
+ .subscribe((link) => {
553
+ if (this._isActive !== this.isLinkActive(this.router)(link)) {
554
+ this.update();
555
+ }
556
+ });
557
+ }
558
+ set routerLinkActive(data) {
559
+ const classes = Array.isArray(data) ? data : data.split(' ');
560
+ this.classes = classes.filter((c) => !!c);
561
+ }
562
+ /** @nodoc */
563
+ ngOnChanges(changes) {
564
+ this.update();
565
+ }
566
+ /** @nodoc */
567
+ ngOnDestroy() {
568
+ this.routerEventsSubscription.unsubscribe();
569
+ this.linkInputChangesSubscription?.unsubscribe();
570
+ }
571
+ update() {
572
+ if (!this.links || !this.router.navigated)
573
+ return;
574
+ queueMicrotask(() => {
575
+ const hasActiveLinks = this.hasActiveLinks();
576
+ this.classes.forEach((c) => {
577
+ if (hasActiveLinks) {
578
+ this.renderer.addClass(this.element.nativeElement, c);
579
+ }
580
+ else {
581
+ this.renderer.removeClass(this.element.nativeElement, c);
582
+ }
583
+ });
584
+ if (hasActiveLinks && this.ariaCurrentWhenActive !== undefined) {
585
+ this.renderer.setAttribute(this.element.nativeElement, 'aria-current', this.ariaCurrentWhenActive.toString());
586
+ }
587
+ else {
588
+ this.renderer.removeAttribute(this.element.nativeElement, 'aria-current');
589
+ }
590
+ // Only emit change if the active state changed.
591
+ if (this._isActive !== hasActiveLinks) {
592
+ this._isActive = hasActiveLinks;
593
+ this.cdr.markForCheck();
594
+ // Emit on isActiveChange after classes are updated
595
+ this.isActiveChange.emit(hasActiveLinks);
596
+ }
597
+ });
598
+ }
599
+ isLinkActive(router) {
600
+ const options = isActiveMatchOptions(this.routerLinkActiveOptions)
601
+ ? this.routerLinkActiveOptions
602
+ : // While the types should disallow `undefined` here, it's possible without strict inputs
603
+ this.routerLinkActiveOptions.exact || false;
604
+ return (link) => {
605
+ const urlTree = link.urlTree;
606
+ return urlTree ? router.isActive(urlTree, options) : false;
607
+ };
608
+ }
609
+ hasActiveLinks() {
610
+ const isActiveCheckFn = this.isLinkActive(this.router);
611
+ return (this.link && isActiveCheckFn(this.link)) || this.links.some(isActiveCheckFn);
612
+ }
613
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.6", ngImport: i0, type: RouterLinkActive, deps: [{ token: Router }, { token: i0.ElementRef }, { token: i0.Renderer2 }, { token: i0.ChangeDetectorRef }, { token: RouterLink, optional: true }], target: i0.ɵɵFactoryTarget.Directive });
614
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.2.6", type: RouterLinkActive, isStandalone: true, selector: "[routerLinkActive]", inputs: { routerLinkActiveOptions: "routerLinkActiveOptions", ariaCurrentWhenActive: "ariaCurrentWhenActive", routerLinkActive: "routerLinkActive" }, outputs: { isActiveChange: "isActiveChange" }, queries: [{ propertyName: "links", predicate: RouterLink, descendants: true }], exportAs: ["routerLinkActive"], usesOnChanges: true, ngImport: i0 });
615
+ }
616
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.6", ngImport: i0, type: RouterLinkActive, decorators: [{
617
+ type: Directive,
618
+ args: [{
619
+ selector: '[routerLinkActive]',
620
+ exportAs: 'routerLinkActive',
621
+ }]
622
+ }], ctorParameters: () => [{ type: Router }, { type: i0.ElementRef }, { type: i0.Renderer2 }, { type: i0.ChangeDetectorRef }, { type: RouterLink, decorators: [{
623
+ type: Optional
624
+ }] }], propDecorators: { links: [{
625
+ type: ContentChildren,
626
+ args: [RouterLink, { descendants: true }]
627
+ }], routerLinkActiveOptions: [{
628
+ type: Input
629
+ }], ariaCurrentWhenActive: [{
630
+ type: Input
631
+ }], isActiveChange: [{
632
+ type: Output
633
+ }], routerLinkActive: [{
634
+ type: Input
635
+ }] } });
636
+ /**
637
+ * Use instead of `'paths' in options` to be compatible with property renaming
638
+ */
639
+ function isActiveMatchOptions(options) {
640
+ return !!options.paths;
641
+ }
642
+
643
+ /**
644
+ * @description
645
+ *
646
+ * Provides a preloading strategy.
647
+ *
648
+ * @publicApi
649
+ */
650
+ class PreloadingStrategy {
651
+ }
652
+ /**
653
+ * @description
654
+ *
655
+ * Provides a preloading strategy that preloads all modules as quickly as possible.
656
+ *
657
+ * ```ts
658
+ * RouterModule.forRoot(ROUTES, {preloadingStrategy: PreloadAllModules})
659
+ * ```
660
+ *
661
+ * @publicApi
662
+ */
663
+ class PreloadAllModules {
664
+ preload(route, fn) {
665
+ return fn().pipe(catchError(() => of(null)));
666
+ }
667
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.6", ngImport: i0, type: PreloadAllModules, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
668
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.6", ngImport: i0, type: PreloadAllModules, providedIn: 'root' });
669
+ }
670
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.6", ngImport: i0, type: PreloadAllModules, decorators: [{
671
+ type: Injectable,
672
+ args: [{ providedIn: 'root' }]
673
+ }] });
674
+ /**
675
+ * @description
676
+ *
677
+ * Provides a preloading strategy that does not preload any modules.
678
+ *
679
+ * This strategy is enabled by default.
680
+ *
681
+ * @publicApi
682
+ */
683
+ class NoPreloading {
684
+ preload(route, fn) {
685
+ return of(null);
686
+ }
687
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.6", ngImport: i0, type: NoPreloading, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
688
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.6", ngImport: i0, type: NoPreloading, providedIn: 'root' });
689
+ }
690
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.6", ngImport: i0, type: NoPreloading, decorators: [{
691
+ type: Injectable,
692
+ args: [{ providedIn: 'root' }]
693
+ }] });
694
+ /**
695
+ * The preloader optimistically loads all router configurations to
696
+ * make navigations into lazily-loaded sections of the application faster.
697
+ *
698
+ * The preloader runs in the background. When the router bootstraps, the preloader
699
+ * starts listening to all navigation events. After every such event, the preloader
700
+ * will check if any configurations can be loaded lazily.
701
+ *
702
+ * If a route is protected by `canLoad` guards, the preloaded will not load it.
703
+ *
704
+ * @publicApi
705
+ */
706
+ class RouterPreloader {
707
+ router;
708
+ injector;
709
+ preloadingStrategy;
710
+ loader;
711
+ subscription;
712
+ constructor(router, compiler, injector, preloadingStrategy, loader) {
713
+ this.router = router;
714
+ this.injector = injector;
715
+ this.preloadingStrategy = preloadingStrategy;
716
+ this.loader = loader;
717
+ }
718
+ setUpPreloading() {
719
+ this.subscription = this.router.events
720
+ .pipe(filter((e) => e instanceof NavigationEnd), concatMap(() => this.preload()))
721
+ .subscribe(() => { });
722
+ }
723
+ preload() {
724
+ return this.processRoutes(this.injector, this.router.config);
725
+ }
726
+ /** @nodoc */
727
+ ngOnDestroy() {
728
+ if (this.subscription) {
729
+ this.subscription.unsubscribe();
730
+ }
731
+ }
732
+ processRoutes(injector, routes) {
733
+ const res = [];
734
+ for (const route of routes) {
735
+ if (route.providers && !route._injector) {
736
+ route._injector = createEnvironmentInjector(route.providers, injector, `Route: ${route.path}`);
737
+ }
738
+ const injectorForCurrentRoute = route._injector ?? injector;
739
+ const injectorForChildren = route._loadedInjector ?? injectorForCurrentRoute;
740
+ // Note that `canLoad` is only checked as a condition that prevents `loadChildren` and not
741
+ // `loadComponent`. `canLoad` guards only block loading of child routes by design. This
742
+ // happens as a consequence of needing to descend into children for route matching immediately
743
+ // while component loading is deferred until route activation. Because `canLoad` guards can
744
+ // have side effects, we cannot execute them here so we instead skip preloading altogether
745
+ // when present. Lastly, it remains to be decided whether `canLoad` should behave this way
746
+ // at all. Code splitting and lazy loading is separate from client-side authorization checks
747
+ // and should not be used as a security measure to prevent loading of code.
748
+ if ((route.loadChildren && !route._loadedRoutes && route.canLoad === undefined) ||
749
+ (route.loadComponent && !route._loadedComponent)) {
750
+ res.push(this.preloadConfig(injectorForCurrentRoute, route));
751
+ }
752
+ if (route.children || route._loadedRoutes) {
753
+ res.push(this.processRoutes(injectorForChildren, (route.children ?? route._loadedRoutes)));
754
+ }
755
+ }
756
+ return from(res).pipe(mergeAll());
757
+ }
758
+ preloadConfig(injector, route) {
759
+ return this.preloadingStrategy.preload(route, () => {
760
+ let loadedChildren$;
761
+ if (route.loadChildren && route.canLoad === undefined) {
762
+ loadedChildren$ = this.loader.loadChildren(injector, route);
763
+ }
764
+ else {
765
+ loadedChildren$ = of(null);
766
+ }
767
+ const recursiveLoadChildren$ = loadedChildren$.pipe(mergeMap((config) => {
768
+ if (config === null) {
769
+ return of(void 0);
770
+ }
771
+ route._loadedRoutes = config.routes;
772
+ route._loadedInjector = config.injector;
773
+ // If the loaded config was a module, use that as the module/module injector going
774
+ // forward. Otherwise, continue using the current module/module injector.
775
+ return this.processRoutes(config.injector ?? injector, config.routes);
776
+ }));
777
+ if (route.loadComponent && !route._loadedComponent) {
778
+ const loadComponent$ = this.loader.loadComponent(route);
779
+ return from([recursiveLoadChildren$, loadComponent$]).pipe(mergeAll());
780
+ }
781
+ else {
782
+ return recursiveLoadChildren$;
783
+ }
784
+ });
785
+ }
786
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.6", ngImport: i0, type: RouterPreloader, deps: [{ token: Router }, { token: i0.Compiler }, { token: i0.EnvironmentInjector }, { token: PreloadingStrategy }, { token: RouterConfigLoader }], target: i0.ɵɵFactoryTarget.Injectable });
787
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.6", ngImport: i0, type: RouterPreloader, providedIn: 'root' });
788
+ }
789
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.6", ngImport: i0, type: RouterPreloader, decorators: [{
790
+ type: Injectable,
791
+ args: [{ providedIn: 'root' }]
792
+ }], ctorParameters: () => [{ type: Router }, { type: i0.Compiler }, { type: i0.EnvironmentInjector }, { type: PreloadingStrategy }, { type: RouterConfigLoader }] });
793
+
794
+ const ROUTER_SCROLLER = new InjectionToken('');
795
+ class RouterScroller {
796
+ urlSerializer;
797
+ transitions;
798
+ viewportScroller;
799
+ zone;
800
+ options;
801
+ routerEventsSubscription;
802
+ scrollEventsSubscription;
803
+ lastId = 0;
804
+ lastSource = 'imperative';
805
+ restoredId = 0;
806
+ store = {};
807
+ /** @nodoc */
808
+ constructor(urlSerializer, transitions, viewportScroller, zone, options = {}) {
809
+ this.urlSerializer = urlSerializer;
810
+ this.transitions = transitions;
811
+ this.viewportScroller = viewportScroller;
812
+ this.zone = zone;
813
+ this.options = options;
814
+ // Default both options to 'disabled'
815
+ options.scrollPositionRestoration ||= 'disabled';
816
+ options.anchorScrolling ||= 'disabled';
817
+ }
818
+ init() {
819
+ // we want to disable the automatic scrolling because having two places
820
+ // responsible for scrolling results race conditions, especially given
821
+ // that browser don't implement this behavior consistently
822
+ if (this.options.scrollPositionRestoration !== 'disabled') {
823
+ this.viewportScroller.setHistoryScrollRestoration('manual');
824
+ }
825
+ this.routerEventsSubscription = this.createScrollEvents();
826
+ this.scrollEventsSubscription = this.consumeScrollEvents();
827
+ }
828
+ createScrollEvents() {
829
+ return this.transitions.events.subscribe((e) => {
830
+ if (e instanceof NavigationStart) {
831
+ // store the scroll position of the current stable navigations.
832
+ this.store[this.lastId] = this.viewportScroller.getScrollPosition();
833
+ this.lastSource = e.navigationTrigger;
834
+ this.restoredId = e.restoredState ? e.restoredState.navigationId : 0;
835
+ }
836
+ else if (e instanceof NavigationEnd) {
837
+ this.lastId = e.id;
838
+ this.scheduleScrollEvent(e, this.urlSerializer.parse(e.urlAfterRedirects).fragment);
839
+ }
840
+ else if (e instanceof NavigationSkipped &&
841
+ e.code === NavigationSkippedCode.IgnoredSameUrlNavigation) {
842
+ this.lastSource = undefined;
843
+ this.restoredId = 0;
844
+ this.scheduleScrollEvent(e, this.urlSerializer.parse(e.url).fragment);
845
+ }
846
+ });
847
+ }
848
+ consumeScrollEvents() {
849
+ return this.transitions.events.subscribe((e) => {
850
+ if (!(e instanceof Scroll))
851
+ return;
852
+ // a popstate event. The pop state event will always ignore anchor scrolling.
853
+ if (e.position) {
854
+ if (this.options.scrollPositionRestoration === 'top') {
855
+ this.viewportScroller.scrollToPosition([0, 0]);
856
+ }
857
+ else if (this.options.scrollPositionRestoration === 'enabled') {
858
+ this.viewportScroller.scrollToPosition(e.position);
859
+ }
860
+ // imperative navigation "forward"
861
+ }
862
+ else {
863
+ if (e.anchor && this.options.anchorScrolling === 'enabled') {
864
+ this.viewportScroller.scrollToAnchor(e.anchor);
865
+ }
866
+ else if (this.options.scrollPositionRestoration !== 'disabled') {
867
+ this.viewportScroller.scrollToPosition([0, 0]);
868
+ }
869
+ }
870
+ });
871
+ }
872
+ scheduleScrollEvent(routerEvent, anchor) {
873
+ this.zone.runOutsideAngular(() => {
874
+ // The scroll event needs to be delayed until after change detection. Otherwise, we may
875
+ // attempt to restore the scroll position before the router outlet has fully rendered the
876
+ // component by executing its update block of the template function.
877
+ setTimeout(() => {
878
+ this.zone.run(() => {
879
+ this.transitions.events.next(new Scroll(routerEvent, this.lastSource === 'popstate' ? this.store[this.restoredId] : null, anchor));
880
+ });
881
+ }, 0);
882
+ });
883
+ }
884
+ /** @nodoc */
885
+ ngOnDestroy() {
886
+ this.routerEventsSubscription?.unsubscribe();
887
+ this.scrollEventsSubscription?.unsubscribe();
888
+ }
889
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.6", ngImport: i0, type: RouterScroller, deps: "invalid", target: i0.ɵɵFactoryTarget.Injectable });
890
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.6", ngImport: i0, type: RouterScroller });
891
+ }
892
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.6", ngImport: i0, type: RouterScroller, decorators: [{
893
+ type: Injectable
894
+ }], ctorParameters: () => [{ type: UrlSerializer }, { type: NavigationTransitions }, { type: i3.ViewportScroller }, { type: i0.NgZone }, { type: undefined }] });
895
+
896
+ /**
897
+ * Sets up providers necessary to enable `Router` functionality for the application.
898
+ * Allows to configure a set of routes as well as extra features that should be enabled.
899
+ *
900
+ * @usageNotes
901
+ *
902
+ * Basic example of how you can add a Router to your application:
903
+ * ```ts
904
+ * const appRoutes: Routes = [];
905
+ * bootstrapApplication(AppComponent, {
906
+ * providers: [provideRouter(appRoutes)]
907
+ * });
908
+ * ```
909
+ *
910
+ * You can also enable optional features in the Router by adding functions from the `RouterFeatures`
911
+ * type:
912
+ * ```ts
913
+ * const appRoutes: Routes = [];
914
+ * bootstrapApplication(AppComponent,
915
+ * {
916
+ * providers: [
917
+ * provideRouter(appRoutes,
918
+ * withDebugTracing(),
919
+ * withRouterConfig({paramsInheritanceStrategy: 'always'}))
920
+ * ]
921
+ * }
922
+ * );
923
+ * ```
924
+ *
925
+ * @see {@link RouterFeatures}
926
+ *
927
+ * @publicApi
928
+ * @param routes A set of `Route`s to use for the application routing table.
929
+ * @param features Optional features to configure additional router behaviors.
930
+ * @returns A set of providers to setup a Router.
931
+ */
932
+ function provideRouter(routes, ...features) {
933
+ return makeEnvironmentProviders([
934
+ { provide: ROUTES, multi: true, useValue: routes },
935
+ typeof ngDevMode === 'undefined' || ngDevMode
936
+ ? { provide: ROUTER_IS_PROVIDED, useValue: true }
937
+ : [],
938
+ { provide: ActivatedRoute, useFactory: rootRoute, deps: [Router] },
939
+ { provide: APP_BOOTSTRAP_LISTENER, multi: true, useFactory: getBootstrapListener },
940
+ features.map((feature) => feature.ɵproviders),
941
+ ]);
942
+ }
943
+ function rootRoute(router) {
944
+ return router.routerState.root;
945
+ }
946
+ /**
947
+ * Helper function to create an object that represents a Router feature.
948
+ */
949
+ function routerFeature(kind, providers) {
950
+ return { ɵkind: kind, ɵproviders: providers };
951
+ }
952
+ /**
953
+ * An Injection token used to indicate whether `provideRouter` or `RouterModule.forRoot` was ever
954
+ * called.
955
+ */
956
+ const ROUTER_IS_PROVIDED = new InjectionToken('', {
957
+ providedIn: 'root',
958
+ factory: () => false,
959
+ });
960
+ const routerIsProvidedDevModeCheck = {
961
+ provide: ENVIRONMENT_INITIALIZER,
962
+ multi: true,
963
+ useFactory() {
964
+ return () => {
965
+ if (!inject(ROUTER_IS_PROVIDED)) {
966
+ console.warn('`provideRoutes` was called without `provideRouter` or `RouterModule.forRoot`. ' +
967
+ 'This is likely a mistake.');
968
+ }
969
+ };
970
+ },
971
+ };
972
+ /**
973
+ * Registers a DI provider for a set of routes.
974
+ * @param routes The route configuration to provide.
975
+ *
976
+ * @usageNotes
977
+ *
978
+ * ```ts
979
+ * @NgModule({
980
+ * providers: [provideRoutes(ROUTES)]
981
+ * })
982
+ * class LazyLoadedChildModule {}
983
+ * ```
984
+ *
985
+ * @deprecated If necessary, provide routes using the `ROUTES` `InjectionToken`.
986
+ * @see {@link ROUTES}
987
+ * @publicApi
988
+ */
989
+ function provideRoutes(routes) {
990
+ return [
991
+ { provide: ROUTES, multi: true, useValue: routes },
992
+ typeof ngDevMode === 'undefined' || ngDevMode ? routerIsProvidedDevModeCheck : [],
993
+ ];
994
+ }
995
+ /**
996
+ * Enables customizable scrolling behavior for router navigations.
997
+ *
998
+ * @usageNotes
999
+ *
1000
+ * Basic example of how you can enable scrolling feature:
1001
+ * ```ts
1002
+ * const appRoutes: Routes = [];
1003
+ * bootstrapApplication(AppComponent,
1004
+ * {
1005
+ * providers: [
1006
+ * provideRouter(appRoutes, withInMemoryScrolling())
1007
+ * ]
1008
+ * }
1009
+ * );
1010
+ * ```
1011
+ *
1012
+ * @see {@link provideRouter}
1013
+ * @see {@link ViewportScroller}
1014
+ *
1015
+ * @publicApi
1016
+ * @param options Set of configuration parameters to customize scrolling behavior, see
1017
+ * `InMemoryScrollingOptions` for additional information.
1018
+ * @returns A set of providers for use with `provideRouter`.
1019
+ */
1020
+ function withInMemoryScrolling(options = {}) {
1021
+ const providers = [
1022
+ {
1023
+ provide: ROUTER_SCROLLER,
1024
+ useFactory: () => {
1025
+ const viewportScroller = inject(ViewportScroller);
1026
+ const zone = inject(NgZone);
1027
+ const transitions = inject(NavigationTransitions);
1028
+ const urlSerializer = inject(UrlSerializer);
1029
+ return new RouterScroller(urlSerializer, transitions, viewportScroller, zone, options);
1030
+ },
1031
+ },
1032
+ ];
1033
+ return routerFeature(4 /* RouterFeatureKind.InMemoryScrollingFeature */, providers);
1034
+ }
1035
+ function getBootstrapListener() {
1036
+ const injector = inject(Injector);
1037
+ return (bootstrappedComponentRef) => {
1038
+ const ref = injector.get(ApplicationRef);
1039
+ if (bootstrappedComponentRef !== ref.components[0]) {
1040
+ return;
1041
+ }
1042
+ const router = injector.get(Router);
1043
+ const bootstrapDone = injector.get(BOOTSTRAP_DONE);
1044
+ if (injector.get(INITIAL_NAVIGATION) === 1 /* InitialNavigation.EnabledNonBlocking */) {
1045
+ router.initialNavigation();
1046
+ }
1047
+ injector.get(ROUTER_PRELOADER, null, InjectFlags.Optional)?.setUpPreloading();
1048
+ injector.get(ROUTER_SCROLLER, null, InjectFlags.Optional)?.init();
1049
+ router.resetRootComponentType(ref.componentTypes[0]);
1050
+ if (!bootstrapDone.closed) {
1051
+ bootstrapDone.next();
1052
+ bootstrapDone.complete();
1053
+ bootstrapDone.unsubscribe();
1054
+ }
1055
+ };
1056
+ }
1057
+ /**
1058
+ * A subject used to indicate that the bootstrapping phase is done. When initial navigation is
1059
+ * `enabledBlocking`, the first navigation waits until bootstrapping is finished before continuing
1060
+ * to the activation phase.
1061
+ */
1062
+ const BOOTSTRAP_DONE = new InjectionToken(typeof ngDevMode === 'undefined' || ngDevMode ? 'bootstrap done indicator' : '', {
1063
+ factory: () => {
1064
+ return new Subject();
1065
+ },
1066
+ });
1067
+ const INITIAL_NAVIGATION = new InjectionToken(typeof ngDevMode === 'undefined' || ngDevMode ? 'initial navigation' : '', { providedIn: 'root', factory: () => 1 /* InitialNavigation.EnabledNonBlocking */ });
1068
+ /**
1069
+ * Configures initial navigation to start before the root component is created.
1070
+ *
1071
+ * The bootstrap is blocked until the initial navigation is complete. This should be set in case
1072
+ * you use [server-side rendering](guide/ssr), but do not enable [hydration](guide/hydration) for
1073
+ * your application.
1074
+ *
1075
+ * @usageNotes
1076
+ *
1077
+ * Basic example of how you can enable this navigation behavior:
1078
+ * ```ts
1079
+ * const appRoutes: Routes = [];
1080
+ * bootstrapApplication(AppComponent,
1081
+ * {
1082
+ * providers: [
1083
+ * provideRouter(appRoutes, withEnabledBlockingInitialNavigation())
1084
+ * ]
1085
+ * }
1086
+ * );
1087
+ * ```
1088
+ *
1089
+ * @see {@link provideRouter}
1090
+ *
1091
+ * @publicApi
1092
+ * @returns A set of providers for use with `provideRouter`.
1093
+ */
1094
+ function withEnabledBlockingInitialNavigation() {
1095
+ const providers = [
1096
+ { provide: INITIAL_NAVIGATION, useValue: 0 /* InitialNavigation.EnabledBlocking */ },
1097
+ provideAppInitializer(() => {
1098
+ const injector = inject(Injector);
1099
+ const locationInitialized = injector.get(LOCATION_INITIALIZED, Promise.resolve());
1100
+ return locationInitialized.then(() => {
1101
+ return new Promise((resolve) => {
1102
+ const router = injector.get(Router);
1103
+ const bootstrapDone = injector.get(BOOTSTRAP_DONE);
1104
+ afterNextNavigation(router, () => {
1105
+ // Unblock APP_INITIALIZER in case the initial navigation was canceled or errored
1106
+ // without a redirect.
1107
+ resolve(true);
1108
+ });
1109
+ injector.get(NavigationTransitions).afterPreactivation = () => {
1110
+ // Unblock APP_INITIALIZER once we get to `afterPreactivation`. At this point, we
1111
+ // assume activation will complete successfully (even though this is not
1112
+ // guaranteed).
1113
+ resolve(true);
1114
+ return bootstrapDone.closed ? of(void 0) : bootstrapDone;
1115
+ };
1116
+ router.initialNavigation();
1117
+ });
1118
+ });
1119
+ }),
1120
+ ];
1121
+ return routerFeature(2 /* RouterFeatureKind.EnabledBlockingInitialNavigationFeature */, providers);
1122
+ }
1123
+ /**
1124
+ * Disables initial navigation.
1125
+ *
1126
+ * Use if there is a reason to have more control over when the router starts its initial navigation
1127
+ * due to some complex initialization logic.
1128
+ *
1129
+ * @usageNotes
1130
+ *
1131
+ * Basic example of how you can disable initial navigation:
1132
+ * ```ts
1133
+ * const appRoutes: Routes = [];
1134
+ * bootstrapApplication(AppComponent,
1135
+ * {
1136
+ * providers: [
1137
+ * provideRouter(appRoutes, withDisabledInitialNavigation())
1138
+ * ]
1139
+ * }
1140
+ * );
1141
+ * ```
1142
+ *
1143
+ * @see {@link provideRouter}
1144
+ *
1145
+ * @returns A set of providers for use with `provideRouter`.
1146
+ *
1147
+ * @publicApi
1148
+ */
1149
+ function withDisabledInitialNavigation() {
1150
+ const providers = [
1151
+ provideAppInitializer(() => {
1152
+ inject(Router).setUpLocationChangeListener();
1153
+ }),
1154
+ { provide: INITIAL_NAVIGATION, useValue: 2 /* InitialNavigation.Disabled */ },
1155
+ ];
1156
+ return routerFeature(3 /* RouterFeatureKind.DisabledInitialNavigationFeature */, providers);
1157
+ }
1158
+ /**
1159
+ * Enables logging of all internal navigation events to the console.
1160
+ * Extra logging might be useful for debugging purposes to inspect Router event sequence.
1161
+ *
1162
+ * @usageNotes
1163
+ *
1164
+ * Basic example of how you can enable debug tracing:
1165
+ * ```ts
1166
+ * const appRoutes: Routes = [];
1167
+ * bootstrapApplication(AppComponent,
1168
+ * {
1169
+ * providers: [
1170
+ * provideRouter(appRoutes, withDebugTracing())
1171
+ * ]
1172
+ * }
1173
+ * );
1174
+ * ```
1175
+ *
1176
+ * @see {@link provideRouter}
1177
+ *
1178
+ * @returns A set of providers for use with `provideRouter`.
1179
+ *
1180
+ * @publicApi
1181
+ */
1182
+ function withDebugTracing() {
1183
+ let providers = [];
1184
+ if (typeof ngDevMode === 'undefined' || ngDevMode) {
1185
+ providers = [
1186
+ {
1187
+ provide: ENVIRONMENT_INITIALIZER,
1188
+ multi: true,
1189
+ useFactory: () => {
1190
+ const router = inject(Router);
1191
+ return () => router.events.subscribe((e) => {
1192
+ // tslint:disable:no-console
1193
+ console.group?.(`Router Event: ${e.constructor.name}`);
1194
+ console.log(stringifyEvent(e));
1195
+ console.log(e);
1196
+ console.groupEnd?.();
1197
+ // tslint:enable:no-console
1198
+ });
1199
+ },
1200
+ },
1201
+ ];
1202
+ }
1203
+ else {
1204
+ providers = [];
1205
+ }
1206
+ return routerFeature(1 /* RouterFeatureKind.DebugTracingFeature */, providers);
1207
+ }
1208
+ const ROUTER_PRELOADER = new InjectionToken(typeof ngDevMode === 'undefined' || ngDevMode ? 'router preloader' : '');
1209
+ /**
1210
+ * Allows to configure a preloading strategy to use. The strategy is configured by providing a
1211
+ * reference to a class that implements a `PreloadingStrategy`.
1212
+ *
1213
+ * @usageNotes
1214
+ *
1215
+ * Basic example of how you can configure preloading:
1216
+ * ```ts
1217
+ * const appRoutes: Routes = [];
1218
+ * bootstrapApplication(AppComponent,
1219
+ * {
1220
+ * providers: [
1221
+ * provideRouter(appRoutes, withPreloading(PreloadAllModules))
1222
+ * ]
1223
+ * }
1224
+ * );
1225
+ * ```
1226
+ *
1227
+ * @see {@link provideRouter}
1228
+ *
1229
+ * @param preloadingStrategy A reference to a class that implements a `PreloadingStrategy` that
1230
+ * should be used.
1231
+ * @returns A set of providers for use with `provideRouter`.
1232
+ *
1233
+ * @publicApi
1234
+ */
1235
+ function withPreloading(preloadingStrategy) {
1236
+ const providers = [
1237
+ { provide: ROUTER_PRELOADER, useExisting: RouterPreloader },
1238
+ { provide: PreloadingStrategy, useExisting: preloadingStrategy },
1239
+ ];
1240
+ return routerFeature(0 /* RouterFeatureKind.PreloadingFeature */, providers);
1241
+ }
1242
+ /**
1243
+ * Allows to provide extra parameters to configure Router.
1244
+ *
1245
+ * @usageNotes
1246
+ *
1247
+ * Basic example of how you can provide extra configuration options:
1248
+ * ```ts
1249
+ * const appRoutes: Routes = [];
1250
+ * bootstrapApplication(AppComponent,
1251
+ * {
1252
+ * providers: [
1253
+ * provideRouter(appRoutes, withRouterConfig({
1254
+ * onSameUrlNavigation: 'reload'
1255
+ * }))
1256
+ * ]
1257
+ * }
1258
+ * );
1259
+ * ```
1260
+ *
1261
+ * @see {@link provideRouter}
1262
+ *
1263
+ * @param options A set of parameters to configure Router, see `RouterConfigOptions` for
1264
+ * additional information.
1265
+ * @returns A set of providers for use with `provideRouter`.
1266
+ *
1267
+ * @publicApi
1268
+ */
1269
+ function withRouterConfig(options) {
1270
+ const providers = [{ provide: ROUTER_CONFIGURATION, useValue: options }];
1271
+ return routerFeature(5 /* RouterFeatureKind.RouterConfigurationFeature */, providers);
1272
+ }
1273
+ /**
1274
+ * Provides the location strategy that uses the URL fragment instead of the history API.
1275
+ *
1276
+ * @usageNotes
1277
+ *
1278
+ * Basic example of how you can use the hash location option:
1279
+ * ```ts
1280
+ * const appRoutes: Routes = [];
1281
+ * bootstrapApplication(AppComponent,
1282
+ * {
1283
+ * providers: [
1284
+ * provideRouter(appRoutes, withHashLocation())
1285
+ * ]
1286
+ * }
1287
+ * );
1288
+ * ```
1289
+ *
1290
+ * @see {@link provideRouter}
1291
+ * @see {@link /api/common/HashLocationStrategy HashLocationStrategy}
1292
+ *
1293
+ * @returns A set of providers for use with `provideRouter`.
1294
+ *
1295
+ * @publicApi
1296
+ */
1297
+ function withHashLocation() {
1298
+ const providers = [{ provide: LocationStrategy, useClass: HashLocationStrategy }];
1299
+ return routerFeature(6 /* RouterFeatureKind.RouterHashLocationFeature */, providers);
1300
+ }
1301
+ /**
1302
+ * Provides a function which is called when a navigation error occurs.
1303
+ *
1304
+ * This function is run inside application's [injection context](guide/di/dependency-injection-context)
1305
+ * so you can use the [`inject`](api/core/inject) function.
1306
+ *
1307
+ * This function can return a `RedirectCommand` to convert the error to a redirect, similar to returning
1308
+ * a `UrlTree` or `RedirectCommand` from a guard. This will also prevent the `Router` from emitting
1309
+ * `NavigationError`; it will instead emit `NavigationCancel` with code NavigationCancellationCode.Redirect.
1310
+ * Return values other than `RedirectCommand` are ignored and do not change any behavior with respect to
1311
+ * how the `Router` handles the error.
1312
+ *
1313
+ * @usageNotes
1314
+ *
1315
+ * Basic example of how you can use the error handler option:
1316
+ * ```ts
1317
+ * const appRoutes: Routes = [];
1318
+ * bootstrapApplication(AppComponent,
1319
+ * {
1320
+ * providers: [
1321
+ * provideRouter(appRoutes, withNavigationErrorHandler((e: NavigationError) =>
1322
+ * inject(MyErrorTracker).trackError(e)))
1323
+ * ]
1324
+ * }
1325
+ * );
1326
+ * ```
1327
+ *
1328
+ * @see {@link NavigationError}
1329
+ * @see {@link /api/core/inject inject}
1330
+ * @see {@link runInInjectionContext}
1331
+ *
1332
+ * @returns A set of providers for use with `provideRouter`.
1333
+ *
1334
+ * @publicApi
1335
+ */
1336
+ function withNavigationErrorHandler(handler) {
1337
+ const providers = [
1338
+ {
1339
+ provide: NAVIGATION_ERROR_HANDLER,
1340
+ useValue: handler,
1341
+ },
1342
+ ];
1343
+ return routerFeature(7 /* RouterFeatureKind.NavigationErrorHandlerFeature */, providers);
1344
+ }
1345
+ /**
1346
+ * Enables binding information from the `Router` state directly to the inputs of the component in
1347
+ * `Route` configurations.
1348
+ *
1349
+ * @usageNotes
1350
+ *
1351
+ * Basic example of how you can enable the feature:
1352
+ * ```ts
1353
+ * const appRoutes: Routes = [];
1354
+ * bootstrapApplication(AppComponent,
1355
+ * {
1356
+ * providers: [
1357
+ * provideRouter(appRoutes, withComponentInputBinding())
1358
+ * ]
1359
+ * }
1360
+ * );
1361
+ * ```
1362
+ *
1363
+ * The router bindings information from any of the following sources:
1364
+ *
1365
+ * - query parameters
1366
+ * - path and matrix parameters
1367
+ * - static route data
1368
+ * - data from resolvers
1369
+ *
1370
+ * Duplicate keys are resolved in the same order from above, from least to greatest,
1371
+ * meaning that resolvers have the highest precedence and override any of the other information
1372
+ * from the route.
1373
+ *
1374
+ * Importantly, when an input does not have an item in the route data with a matching key, this
1375
+ * input is set to `undefined`. This prevents previous information from being
1376
+ * retained if the data got removed from the route (i.e. if a query parameter is removed).
1377
+ * Default values can be provided with a resolver on the route to ensure the value is always present
1378
+ * or an input and use an input transform in the component.
1379
+ *
1380
+ * @see {@link /guide/components/inputs#input-transforms Input Transforms}
1381
+ * @returns A set of providers for use with `provideRouter`.
1382
+ */
1383
+ function withComponentInputBinding() {
1384
+ const providers = [
1385
+ RoutedComponentInputBinder,
1386
+ { provide: INPUT_BINDER, useExisting: RoutedComponentInputBinder },
1387
+ ];
1388
+ return routerFeature(8 /* RouterFeatureKind.ComponentInputBindingFeature */, providers);
1389
+ }
1390
+ /**
1391
+ * Enables view transitions in the Router by running the route activation and deactivation inside of
1392
+ * `document.startViewTransition`.
1393
+ *
1394
+ * Note: The View Transitions API is not available in all browsers. If the browser does not support
1395
+ * view transitions, the Router will not attempt to start a view transition and continue processing
1396
+ * the navigation as usual.
1397
+ *
1398
+ * @usageNotes
1399
+ *
1400
+ * Basic example of how you can enable the feature:
1401
+ * ```ts
1402
+ * const appRoutes: Routes = [];
1403
+ * bootstrapApplication(AppComponent,
1404
+ * {
1405
+ * providers: [
1406
+ * provideRouter(appRoutes, withViewTransitions())
1407
+ * ]
1408
+ * }
1409
+ * );
1410
+ * ```
1411
+ *
1412
+ * @returns A set of providers for use with `provideRouter`.
1413
+ * @see https://developer.chrome.com/docs/web-platform/view-transitions/
1414
+ * @see https://developer.mozilla.org/en-US/docs/Web/API/View_Transitions_API
1415
+ * @developerPreview
1416
+ */
1417
+ function withViewTransitions(options) {
1418
+ _performanceMarkFeature('NgRouterViewTransitions');
1419
+ const providers = [
1420
+ { provide: CREATE_VIEW_TRANSITION, useValue: createViewTransition },
1421
+ {
1422
+ provide: VIEW_TRANSITION_OPTIONS,
1423
+ useValue: { skipNextTransition: !!options?.skipInitialTransition, ...options },
1424
+ },
1425
+ ];
1426
+ return routerFeature(9 /* RouterFeatureKind.ViewTransitionsFeature */, providers);
1427
+ }
1428
+
1429
+ /**
1430
+ * The directives defined in the `RouterModule`.
1431
+ */
1432
+ const ROUTER_DIRECTIVES = [RouterOutlet, RouterLink, RouterLinkActive, _EmptyOutletComponent];
1433
+ /**
1434
+ * @docsNotRequired
1435
+ */
1436
+ const ROUTER_FORROOT_GUARD = new InjectionToken(typeof ngDevMode === 'undefined' || ngDevMode ? 'router duplicate forRoot guard' : '');
1437
+ // TODO(atscott): All of these except `ActivatedRoute` are `providedIn: 'root'`. They are only kept
1438
+ // here to avoid a breaking change whereby the provider order matters based on where the
1439
+ // `RouterModule`/`RouterTestingModule` is imported. These can/should be removed as a "breaking"
1440
+ // change in a major version.
1441
+ const ROUTER_PROVIDERS = [
1442
+ Location,
1443
+ { provide: UrlSerializer, useClass: DefaultUrlSerializer },
1444
+ Router,
1445
+ ChildrenOutletContexts,
1446
+ { provide: ActivatedRoute, useFactory: rootRoute, deps: [Router] },
1447
+ RouterConfigLoader,
1448
+ // Only used to warn when `provideRoutes` is used without `RouterModule` or `provideRouter`. Can
1449
+ // be removed when `provideRoutes` is removed.
1450
+ typeof ngDevMode === 'undefined' || ngDevMode
1451
+ ? { provide: ROUTER_IS_PROVIDED, useValue: true }
1452
+ : [],
1453
+ ];
1454
+ /**
1455
+ * @description
1456
+ *
1457
+ * Adds directives and providers for in-app navigation among views defined in an application.
1458
+ * Use the Angular `Router` service to declaratively specify application states and manage state
1459
+ * transitions.
1460
+ *
1461
+ * You can import this NgModule multiple times, once for each lazy-loaded bundle.
1462
+ * However, only one `Router` service can be active.
1463
+ * To ensure this, there are two ways to register routes when importing this module:
1464
+ *
1465
+ * * The `forRoot()` method creates an `NgModule` that contains all the directives, the given
1466
+ * routes, and the `Router` service itself.
1467
+ * * The `forChild()` method creates an `NgModule` that contains all the directives and the given
1468
+ * routes, but does not include the `Router` service.
1469
+ *
1470
+ * @see [Routing and Navigation guide](guide/routing/common-router-tasks) for an
1471
+ * overview of how the `Router` service should be used.
1472
+ *
1473
+ * @publicApi
1474
+ */
1475
+ class RouterModule {
1476
+ constructor() {
1477
+ if (typeof ngDevMode === 'undefined' || ngDevMode) {
1478
+ inject(ROUTER_FORROOT_GUARD, { optional: true });
1479
+ }
1480
+ }
1481
+ /**
1482
+ * Creates and configures a module with all the router providers and directives.
1483
+ * Optionally sets up an application listener to perform an initial navigation.
1484
+ *
1485
+ * When registering the NgModule at the root, import as follows:
1486
+ *
1487
+ * ```ts
1488
+ * @NgModule({
1489
+ * imports: [RouterModule.forRoot(ROUTES)]
1490
+ * })
1491
+ * class MyNgModule {}
1492
+ * ```
1493
+ *
1494
+ * @param routes An array of `Route` objects that define the navigation paths for the application.
1495
+ * @param config An `ExtraOptions` configuration object that controls how navigation is performed.
1496
+ * @return The new `NgModule`.
1497
+ *
1498
+ */
1499
+ static forRoot(routes, config) {
1500
+ return {
1501
+ ngModule: RouterModule,
1502
+ providers: [
1503
+ ROUTER_PROVIDERS,
1504
+ typeof ngDevMode === 'undefined' || ngDevMode
1505
+ ? config?.enableTracing
1506
+ ? withDebugTracing().ɵproviders
1507
+ : []
1508
+ : [],
1509
+ { provide: ROUTES, multi: true, useValue: routes },
1510
+ typeof ngDevMode === 'undefined' || ngDevMode
1511
+ ? {
1512
+ provide: ROUTER_FORROOT_GUARD,
1513
+ useFactory: provideForRootGuard,
1514
+ deps: [[Router, new Optional(), new SkipSelf()]],
1515
+ }
1516
+ : [],
1517
+ config?.errorHandler
1518
+ ? {
1519
+ provide: NAVIGATION_ERROR_HANDLER,
1520
+ useValue: config.errorHandler,
1521
+ }
1522
+ : [],
1523
+ { provide: ROUTER_CONFIGURATION, useValue: config ? config : {} },
1524
+ config?.useHash ? provideHashLocationStrategy() : providePathLocationStrategy(),
1525
+ provideRouterScroller(),
1526
+ config?.preloadingStrategy ? withPreloading(config.preloadingStrategy).ɵproviders : [],
1527
+ config?.initialNavigation ? provideInitialNavigation(config) : [],
1528
+ config?.bindToComponentInputs ? withComponentInputBinding().ɵproviders : [],
1529
+ config?.enableViewTransitions ? withViewTransitions().ɵproviders : [],
1530
+ provideRouterInitializer(),
1531
+ ],
1532
+ };
1533
+ }
1534
+ /**
1535
+ * Creates a module with all the router directives and a provider registering routes,
1536
+ * without creating a new Router service.
1537
+ * When registering for submodules and lazy-loaded submodules, create the NgModule as follows:
1538
+ *
1539
+ * ```ts
1540
+ * @NgModule({
1541
+ * imports: [RouterModule.forChild(ROUTES)]
1542
+ * })
1543
+ * class MyNgModule {}
1544
+ * ```
1545
+ *
1546
+ * @param routes An array of `Route` objects that define the navigation paths for the submodule.
1547
+ * @return The new NgModule.
1548
+ *
1549
+ */
1550
+ static forChild(routes) {
1551
+ return {
1552
+ ngModule: RouterModule,
1553
+ providers: [{ provide: ROUTES, multi: true, useValue: routes }],
1554
+ };
1555
+ }
1556
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.6", ngImport: i0, type: RouterModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
1557
+ static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "19.2.6", ngImport: i0, type: RouterModule, imports: [RouterOutlet, RouterLink, RouterLinkActive, _EmptyOutletComponent], exports: [RouterOutlet, RouterLink, RouterLinkActive, _EmptyOutletComponent] });
1558
+ static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "19.2.6", ngImport: i0, type: RouterModule });
1559
+ }
1560
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.6", ngImport: i0, type: RouterModule, decorators: [{
1561
+ type: NgModule,
1562
+ args: [{
1563
+ imports: ROUTER_DIRECTIVES,
1564
+ exports: ROUTER_DIRECTIVES,
1565
+ }]
1566
+ }], ctorParameters: () => [] });
1567
+ /**
1568
+ * For internal use by `RouterModule` only. Note that this differs from `withInMemoryRouterScroller`
1569
+ * because it reads from the `ExtraOptions` which should not be used in the standalone world.
1570
+ */
1571
+ function provideRouterScroller() {
1572
+ return {
1573
+ provide: ROUTER_SCROLLER,
1574
+ useFactory: () => {
1575
+ const viewportScroller = inject(ViewportScroller);
1576
+ const zone = inject(NgZone);
1577
+ const config = inject(ROUTER_CONFIGURATION);
1578
+ const transitions = inject(NavigationTransitions);
1579
+ const urlSerializer = inject(UrlSerializer);
1580
+ if (config.scrollOffset) {
1581
+ viewportScroller.setOffset(config.scrollOffset);
1582
+ }
1583
+ return new RouterScroller(urlSerializer, transitions, viewportScroller, zone, config);
1584
+ },
1585
+ };
1586
+ }
1587
+ // Note: For internal use only with `RouterModule`. Standalone setup via `provideRouter` should
1588
+ // provide hash location directly via `{provide: LocationStrategy, useClass: HashLocationStrategy}`.
1589
+ function provideHashLocationStrategy() {
1590
+ return { provide: LocationStrategy, useClass: HashLocationStrategy };
1591
+ }
1592
+ // Note: For internal use only with `RouterModule`. Standalone setup via `provideRouter` does not
1593
+ // need this at all because `PathLocationStrategy` is the default factory for `LocationStrategy`.
1594
+ function providePathLocationStrategy() {
1595
+ return { provide: LocationStrategy, useClass: PathLocationStrategy };
1596
+ }
1597
+ function provideForRootGuard(router) {
1598
+ if (router) {
1599
+ throw new _RuntimeError(4007 /* RuntimeErrorCode.FOR_ROOT_CALLED_TWICE */, `The Router was provided more than once. This can happen if 'forRoot' is used outside of the root injector.` +
1600
+ ` Lazy loaded modules should use RouterModule.forChild() instead.`);
1601
+ }
1602
+ return 'guarded';
1603
+ }
1604
+ // Note: For internal use only with `RouterModule`. Standalone router setup with `provideRouter`
1605
+ // users call `withXInitialNavigation` directly.
1606
+ function provideInitialNavigation(config) {
1607
+ return [
1608
+ config.initialNavigation === 'disabled' ? withDisabledInitialNavigation().ɵproviders : [],
1609
+ config.initialNavigation === 'enabledBlocking'
1610
+ ? withEnabledBlockingInitialNavigation().ɵproviders
1611
+ : [],
1612
+ ];
1613
+ }
1614
+ // TODO(atscott): This should not be in the public API
1615
+ /**
1616
+ * A DI token for the router initializer that
1617
+ * is called after the app is bootstrapped.
1618
+ *
1619
+ * @publicApi
1620
+ */
1621
+ const ROUTER_INITIALIZER = new InjectionToken(typeof ngDevMode === 'undefined' || ngDevMode ? 'Router Initializer' : '');
1622
+ function provideRouterInitializer() {
1623
+ return [
1624
+ // ROUTER_INITIALIZER token should be removed. It's public API but shouldn't be. We can just
1625
+ // have `getBootstrapListener` directly attached to APP_BOOTSTRAP_LISTENER.
1626
+ { provide: ROUTER_INITIALIZER, useFactory: getBootstrapListener },
1627
+ { provide: APP_BOOTSTRAP_LISTENER, multi: true, useExisting: ROUTER_INITIALIZER },
1628
+ ];
1629
+ }
1630
+
1631
+ export { NoPreloading, PreloadAllModules, PreloadingStrategy, ROUTER_INITIALIZER, ROUTER_PROVIDERS, RouterLink, RouterLinkActive, RouterModule, RouterPreloader, provideRouter, provideRoutes, withComponentInputBinding, withDebugTracing, withDisabledInitialNavigation, withEnabledBlockingInitialNavigation, withHashLocation, withInMemoryScrolling, withNavigationErrorHandler, withPreloading, withRouterConfig, withViewTransitions };
1632
+ //# sourceMappingURL=router_module-CbmfhtZA.mjs.map