@angular/router 15.0.0 → 15.0.2

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.
Files changed (40) hide show
  1. package/esm2020/src/components/empty_outlet.mjs +3 -3
  2. package/esm2020/src/deprecated_load_children.mjs +3 -1
  3. package/esm2020/src/directives/router_link.mjs +3 -3
  4. package/esm2020/src/directives/router_link_active.mjs +3 -3
  5. package/esm2020/src/directives/router_outlet.mjs +5 -5
  6. package/esm2020/src/index.mjs +1 -1
  7. package/esm2020/src/models.mjs +1 -1
  8. package/esm2020/src/navigation_transition.mjs +380 -0
  9. package/esm2020/src/operators/activate_routes.mjs +1 -1
  10. package/esm2020/src/operators/apply_redirects.mjs +1 -1
  11. package/esm2020/src/operators/check_guards.mjs +1 -1
  12. package/esm2020/src/operators/recognize.mjs +1 -1
  13. package/esm2020/src/operators/resolve_data.mjs +1 -1
  14. package/esm2020/src/page_title_strategy.mjs +6 -6
  15. package/esm2020/src/private_export.mjs +1 -1
  16. package/esm2020/src/provide_router.mjs +11 -15
  17. package/esm2020/src/route_reuse_strategy.mjs +15 -1
  18. package/esm2020/src/router.mjs +76 -407
  19. package/esm2020/src/router_config_loader.mjs +3 -3
  20. package/esm2020/src/router_module.mjs +9 -7
  21. package/esm2020/src/router_outlet_context.mjs +3 -3
  22. package/esm2020/src/router_preloader.mjs +9 -9
  23. package/esm2020/src/router_scroller.mjs +20 -21
  24. package/esm2020/src/router_state.mjs +1 -1
  25. package/esm2020/src/url_handling_strategy.mjs +15 -1
  26. package/esm2020/src/url_tree.mjs +4 -4
  27. package/esm2020/src/version.mjs +1 -1
  28. package/esm2020/testing/src/router_testing_module.mjs +4 -4
  29. package/fesm2015/router.mjs +790 -732
  30. package/fesm2015/router.mjs.map +1 -1
  31. package/fesm2015/testing.mjs +5 -5
  32. package/fesm2015/upgrade.mjs +1 -1
  33. package/fesm2020/router.mjs +794 -735
  34. package/fesm2020/router.mjs.map +1 -1
  35. package/fesm2020/testing.mjs +5 -5
  36. package/fesm2020/upgrade.mjs +1 -1
  37. package/index.d.ts +24 -80
  38. package/package.json +4 -4
  39. package/testing/index.d.ts +1 -1
  40. package/upgrade/index.d.ts +1 -1
@@ -1,11 +1,11 @@
1
1
  /**
2
- * @license Angular v15.0.0
2
+ * @license Angular v15.0.2
3
3
  * (c) 2010-2022 Google LLC. https://angular.io/
4
4
  * License: MIT
5
5
  */
6
6
 
7
7
  import * as i0 from '@angular/core';
8
- import { ɵisObservable, ɵisPromise, ɵRuntimeError, Injectable, EventEmitter, inject, ViewContainerRef, ChangeDetectorRef, EnvironmentInjector, Directive, Input, Output, Component, createEnvironmentInjector, ɵisStandalone, ComponentFactoryResolver, ɵisInjectable, InjectionToken, InjectFlags, NgModuleFactory, Injector, Compiler, NgModuleRef, ɵConsole, NgZone, ɵcoerceToBoolean, ɵɵsanitizeUrlOrResourceUrl, Attribute, HostBinding, HostListener, Optional, ContentChildren, makeEnvironmentProviders, APP_BOOTSTRAP_LISTENER, ENVIRONMENT_INITIALIZER, ApplicationRef, APP_INITIALIZER, NgProbeToken, SkipSelf, NgModule, Inject, Version } from '@angular/core';
8
+ import { ɵisObservable, ɵisPromise, ɵRuntimeError, Injectable, EventEmitter, inject, ViewContainerRef, ChangeDetectorRef, EnvironmentInjector, Directive, Input, Output, Component, createEnvironmentInjector, ɵisStandalone, ComponentFactoryResolver, ɵisInjectable, InjectionToken, InjectFlags, NgModuleFactory, Injector, Compiler, ɵConsole, NgZone, ɵcoerceToBoolean, ɵɵsanitizeUrlOrResourceUrl, Attribute, HostBinding, HostListener, Optional, ContentChildren, makeEnvironmentProviders, APP_BOOTSTRAP_LISTENER, ENVIRONMENT_INITIALIZER, ApplicationRef, APP_INITIALIZER, NgProbeToken, SkipSelf, NgModule, Inject, Version } from '@angular/core';
9
9
  import { from, of, BehaviorSubject, EmptyError, combineLatest, concat, defer, pipe, throwError, Observable, EMPTY, ConnectableObservable, Subject } from 'rxjs';
10
10
  import * as i3 from '@angular/common';
11
11
  import { Location, ViewportScroller, LOCATION_INITIALIZED, LocationStrategy, HashLocationStrategy, PathLocationStrategy } from '@angular/common';
@@ -202,7 +202,7 @@ function wrapIntoObservable(value) {
202
202
  * Use of this source code is governed by an MIT-style license that can be
203
203
  * found in the LICENSE file at https://angular.io/license
204
204
  */
205
- const NG_DEV_MODE$9 = typeof ngDevMode === 'undefined' || ngDevMode;
205
+ const NG_DEV_MODE$a = typeof ngDevMode === 'undefined' || ngDevMode;
206
206
  const pathCompareMap = {
207
207
  'exact': equalSegmentGroups,
208
208
  'subset': containsSegmentGroup,
@@ -327,7 +327,7 @@ class UrlTree {
327
327
  this.root = root;
328
328
  this.queryParams = queryParams;
329
329
  this.fragment = fragment;
330
- if (NG_DEV_MODE$9) {
330
+ if (NG_DEV_MODE$a) {
331
331
  if (root.segments.length > 0) {
332
332
  throw new ɵRuntimeError(4015 /* RuntimeErrorCode.INVALID_ROOT_URL_SEGMENT */, 'The root `UrlSegmentGroup` should not contain `segments`. ' +
333
333
  'Instead, these segments belong in the `children` so they can be associated with a named outlet.');
@@ -461,9 +461,9 @@ function mapChildrenIntoArray(segment, fn) {
461
461
  */
462
462
  class UrlSerializer {
463
463
  }
464
- UrlSerializer.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: UrlSerializer, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
465
- UrlSerializer.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: UrlSerializer, providedIn: 'root', useFactory: () => new DefaultUrlSerializer() });
466
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: UrlSerializer, decorators: [{
464
+ UrlSerializer.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.2", ngImport: i0, type: UrlSerializer, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
465
+ UrlSerializer.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.0.2", ngImport: i0, type: UrlSerializer, providedIn: 'root', useFactory: () => new DefaultUrlSerializer() });
466
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.2", ngImport: i0, type: UrlSerializer, decorators: [{
467
467
  type: Injectable,
468
468
  args: [{ providedIn: 'root', useFactory: () => new DefaultUrlSerializer() }]
469
469
  }] });
@@ -675,7 +675,7 @@ class UrlParser {
675
675
  parseSegment() {
676
676
  const path = matchSegments(this.remaining);
677
677
  if (path === '' && this.peekStartsWith(';')) {
678
- throw new ɵRuntimeError(4009 /* RuntimeErrorCode.EMPTY_PATH_WITH_PARAMS */, NG_DEV_MODE$9 && `Empty path url segment cannot have parameters: '${this.remaining}'.`);
678
+ throw new ɵRuntimeError(4009 /* RuntimeErrorCode.EMPTY_PATH_WITH_PARAMS */, NG_DEV_MODE$a && `Empty path url segment cannot have parameters: '${this.remaining}'.`);
679
679
  }
680
680
  this.capture(path);
681
681
  return new UrlSegment(decode(path), this.parseMatrixParams());
@@ -744,7 +744,7 @@ class UrlParser {
744
744
  // if is is not one of these characters, then the segment was unescaped
745
745
  // or the group was not closed
746
746
  if (next !== '/' && next !== ')' && next !== ';') {
747
- throw new ɵRuntimeError(4010 /* RuntimeErrorCode.UNPARSABLE_URL */, NG_DEV_MODE$9 && `Cannot parse url '${this.url}'`);
747
+ throw new ɵRuntimeError(4010 /* RuntimeErrorCode.UNPARSABLE_URL */, NG_DEV_MODE$a && `Cannot parse url '${this.url}'`);
748
748
  }
749
749
  let outletName = undefined;
750
750
  if (path.indexOf(':') > -1) {
@@ -775,7 +775,7 @@ class UrlParser {
775
775
  }
776
776
  capture(str) {
777
777
  if (!this.consumeOptional(str)) {
778
- throw new ɵRuntimeError(4011 /* RuntimeErrorCode.UNEXPECTED_VALUE_IN_URL */, NG_DEV_MODE$9 && `Expected "${str}".`);
778
+ throw new ɵRuntimeError(4011 /* RuntimeErrorCode.UNEXPECTED_VALUE_IN_URL */, NG_DEV_MODE$a && `Expected "${str}".`);
779
779
  }
780
780
  }
781
781
  }
@@ -828,7 +828,7 @@ function isUrlTree(v) {
828
828
  * Use of this source code is governed by an MIT-style license that can be
829
829
  * found in the LICENSE file at https://angular.io/license
830
830
  */
831
- const NG_DEV_MODE$8 = typeof ngDevMode === 'undefined' || ngDevMode;
831
+ const NG_DEV_MODE$9 = typeof ngDevMode === 'undefined' || ngDevMode;
832
832
  /**
833
833
  * Creates a `UrlTree` relative to an `ActivatedRouteSnapshot`.
834
834
  *
@@ -999,11 +999,11 @@ class Navigation {
999
999
  this.numberOfDoubleDots = numberOfDoubleDots;
1000
1000
  this.commands = commands;
1001
1001
  if (isAbsolute && commands.length > 0 && isMatrixParams(commands[0])) {
1002
- throw new ɵRuntimeError(4003 /* RuntimeErrorCode.ROOT_SEGMENT_MATRIX_PARAMS */, NG_DEV_MODE$8 && 'Root segment cannot have matrix parameters');
1002
+ throw new ɵRuntimeError(4003 /* RuntimeErrorCode.ROOT_SEGMENT_MATRIX_PARAMS */, NG_DEV_MODE$9 && 'Root segment cannot have matrix parameters');
1003
1003
  }
1004
1004
  const cmdWithOutlet = commands.find(isCommandWithOutlets);
1005
1005
  if (cmdWithOutlet && cmdWithOutlet !== last(commands)) {
1006
- throw new ɵRuntimeError(4004 /* RuntimeErrorCode.MISPLACED_OUTLETS_COMMAND */, NG_DEV_MODE$8 && '{outlets:{}} has to be the last command');
1006
+ throw new ɵRuntimeError(4004 /* RuntimeErrorCode.MISPLACED_OUTLETS_COMMAND */, NG_DEV_MODE$9 && '{outlets:{}} has to be the last command');
1007
1007
  }
1008
1008
  }
1009
1009
  toRoot() {
@@ -1102,7 +1102,7 @@ function createPositionApplyingDoubleDots(group, index, numberOfDoubleDots) {
1102
1102
  dd -= ci;
1103
1103
  g = g.parent;
1104
1104
  if (!g) {
1105
- throw new ɵRuntimeError(4005 /* RuntimeErrorCode.INVALID_DOUBLE_DOTS */, NG_DEV_MODE$8 && 'Invalid number of \'../\'');
1105
+ throw new ɵRuntimeError(4005 /* RuntimeErrorCode.INVALID_DOUBLE_DOTS */, NG_DEV_MODE$9 && 'Invalid number of \'../\'');
1106
1106
  }
1107
1107
  ci = g.segments.length;
1108
1108
  }
@@ -2386,9 +2386,9 @@ class ChildrenOutletContexts {
2386
2386
  return this.contexts.get(childName) || null;
2387
2387
  }
2388
2388
  }
2389
- ChildrenOutletContexts.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: ChildrenOutletContexts, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
2390
- ChildrenOutletContexts.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: ChildrenOutletContexts, providedIn: 'root' });
2391
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: ChildrenOutletContexts, decorators: [{
2389
+ ChildrenOutletContexts.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.2", ngImport: i0, type: ChildrenOutletContexts, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
2390
+ ChildrenOutletContexts.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.0.2", ngImport: i0, type: ChildrenOutletContexts, providedIn: 'root' });
2391
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.2", ngImport: i0, type: ChildrenOutletContexts, decorators: [{
2392
2392
  type: Injectable,
2393
2393
  args: [{ providedIn: 'root' }]
2394
2394
  }] });
@@ -2400,7 +2400,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.0", ngImpor
2400
2400
  * Use of this source code is governed by an MIT-style license that can be
2401
2401
  * found in the LICENSE file at https://angular.io/license
2402
2402
  */
2403
- const NG_DEV_MODE$7 = typeof ngDevMode === 'undefined' || ngDevMode;
2403
+ const NG_DEV_MODE$8 = typeof ngDevMode === 'undefined' || ngDevMode;
2404
2404
  /**
2405
2405
  * @description
2406
2406
  *
@@ -2540,12 +2540,12 @@ class RouterOutlet {
2540
2540
  */
2541
2541
  get component() {
2542
2542
  if (!this.activated)
2543
- throw new ɵRuntimeError(4012 /* RuntimeErrorCode.OUTLET_NOT_ACTIVATED */, NG_DEV_MODE$7 && 'Outlet is not activated');
2543
+ throw new ɵRuntimeError(4012 /* RuntimeErrorCode.OUTLET_NOT_ACTIVATED */, NG_DEV_MODE$8 && 'Outlet is not activated');
2544
2544
  return this.activated.instance;
2545
2545
  }
2546
2546
  get activatedRoute() {
2547
2547
  if (!this.activated)
2548
- throw new ɵRuntimeError(4012 /* RuntimeErrorCode.OUTLET_NOT_ACTIVATED */, NG_DEV_MODE$7 && 'Outlet is not activated');
2548
+ throw new ɵRuntimeError(4012 /* RuntimeErrorCode.OUTLET_NOT_ACTIVATED */, NG_DEV_MODE$8 && 'Outlet is not activated');
2549
2549
  return this._activatedRoute;
2550
2550
  }
2551
2551
  get activatedRouteData() {
@@ -2559,7 +2559,7 @@ class RouterOutlet {
2559
2559
  */
2560
2560
  detach() {
2561
2561
  if (!this.activated)
2562
- throw new ɵRuntimeError(4012 /* RuntimeErrorCode.OUTLET_NOT_ACTIVATED */, NG_DEV_MODE$7 && 'Outlet is not activated');
2562
+ throw new ɵRuntimeError(4012 /* RuntimeErrorCode.OUTLET_NOT_ACTIVATED */, NG_DEV_MODE$8 && 'Outlet is not activated');
2563
2563
  this.location.detach();
2564
2564
  const cmp = this.activated;
2565
2565
  this.activated = null;
@@ -2587,11 +2587,11 @@ class RouterOutlet {
2587
2587
  }
2588
2588
  activateWith(activatedRoute, resolverOrInjector) {
2589
2589
  if (this.isActivated) {
2590
- throw new ɵRuntimeError(4013 /* RuntimeErrorCode.OUTLET_ALREADY_ACTIVATED */, NG_DEV_MODE$7 && 'Cannot activate an already activated outlet');
2590
+ throw new ɵRuntimeError(4013 /* RuntimeErrorCode.OUTLET_ALREADY_ACTIVATED */, NG_DEV_MODE$8 && 'Cannot activate an already activated outlet');
2591
2591
  }
2592
2592
  this._activatedRoute = activatedRoute;
2593
2593
  const location = this.location;
2594
- const snapshot = activatedRoute._futureSnapshot;
2594
+ const snapshot = activatedRoute.snapshot;
2595
2595
  const component = snapshot.component;
2596
2596
  const childContexts = this.parentContexts.getOrCreateContext(this.name).children;
2597
2597
  const injector = new OutletInjector(activatedRoute, childContexts, location.injector);
@@ -2609,9 +2609,9 @@ class RouterOutlet {
2609
2609
  this.activateEvents.emit(this.activated.instance);
2610
2610
  }
2611
2611
  }
2612
- RouterOutlet.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: RouterOutlet, deps: [], target: i0.ɵɵFactoryTarget.Directive });
2613
- RouterOutlet.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.0.0", type: RouterOutlet, isStandalone: true, selector: "router-outlet", inputs: { name: "name" }, outputs: { activateEvents: "activate", deactivateEvents: "deactivate", attachEvents: "attach", detachEvents: "detach" }, exportAs: ["outlet"], usesOnChanges: true, ngImport: i0 });
2614
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: RouterOutlet, decorators: [{
2612
+ RouterOutlet.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.2", ngImport: i0, type: RouterOutlet, deps: [], target: i0.ɵɵFactoryTarget.Directive });
2613
+ RouterOutlet.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.0.2", type: RouterOutlet, isStandalone: true, selector: "router-outlet", inputs: { name: "name" }, outputs: { activateEvents: "activate", deactivateEvents: "deactivate", attachEvents: "attach", detachEvents: "detach" }, exportAs: ["outlet"], usesOnChanges: true, ngImport: i0 });
2614
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.2", ngImport: i0, type: RouterOutlet, decorators: [{
2615
2615
  type: Directive,
2616
2616
  args: [{
2617
2617
  selector: 'router-outlet',
@@ -2671,9 +2671,9 @@ function isComponentFactoryResolver(item) {
2671
2671
  */
2672
2672
  class ɵEmptyOutletComponent {
2673
2673
  }
2674
- ɵEmptyOutletComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: ɵEmptyOutletComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
2675
- ɵEmptyOutletComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.0.0", type: ɵEmptyOutletComponent, isStandalone: true, selector: "ng-component", ngImport: i0, template: `<router-outlet></router-outlet>`, isInline: true, dependencies: [{ kind: "directive", type: RouterOutlet, selector: "router-outlet", inputs: ["name"], outputs: ["activate", "deactivate", "attach", "detach"], exportAs: ["outlet"] }] });
2676
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: ɵEmptyOutletComponent, decorators: [{
2674
+ ɵEmptyOutletComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.2", ngImport: i0, type: ɵEmptyOutletComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
2675
+ ɵEmptyOutletComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.0.2", type: ɵEmptyOutletComponent, isStandalone: true, selector: "ng-component", ngImport: i0, template: `<router-outlet></router-outlet>`, isInline: true, dependencies: [{ kind: "directive", type: RouterOutlet, selector: "router-outlet", inputs: ["name"], outputs: ["activate", "deactivate", "attach", "detach"], exportAs: ["outlet"] }] });
2676
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.2", ngImport: i0, type: ɵEmptyOutletComponent, decorators: [{
2677
2677
  type: Component,
2678
2678
  args: [{
2679
2679
  template: `<router-outlet></router-outlet>`,
@@ -3591,7 +3591,7 @@ function noLeftoversInUrl(segmentGroup, segments, outlet) {
3591
3591
  * Use of this source code is governed by an MIT-style license that can be
3592
3592
  * found in the LICENSE file at https://angular.io/license
3593
3593
  */
3594
- const NG_DEV_MODE$6 = typeof ngDevMode === 'undefined' || ngDevMode;
3594
+ const NG_DEV_MODE$7 = typeof ngDevMode === 'undefined' || ngDevMode;
3595
3595
  class NoMatch$1 {
3596
3596
  constructor(segmentGroup) {
3597
3597
  this.segmentGroup = segmentGroup || null;
@@ -3609,11 +3609,11 @@ function absoluteRedirect(newTree) {
3609
3609
  return throwError(new AbsoluteRedirect(newTree));
3610
3610
  }
3611
3611
  function namedOutletsRedirect(redirectTo) {
3612
- return throwError(new ɵRuntimeError(4000 /* RuntimeErrorCode.NAMED_OUTLET_REDIRECT */, NG_DEV_MODE$6 &&
3612
+ return throwError(new ɵRuntimeError(4000 /* RuntimeErrorCode.NAMED_OUTLET_REDIRECT */, NG_DEV_MODE$7 &&
3613
3613
  `Only absolute redirects can have named outlets. redirectTo: '${redirectTo}'`));
3614
3614
  }
3615
3615
  function canLoadFails(route) {
3616
- return throwError(navigationCancelingError(NG_DEV_MODE$6 &&
3616
+ return throwError(navigationCancelingError(NG_DEV_MODE$7 &&
3617
3617
  `Cannot load children because the guard of the route "path: '${route.path}'" returned false`, 3 /* NavigationCancellationCode.GuardRejected */));
3618
3618
  }
3619
3619
  /**
@@ -3673,7 +3673,7 @@ class ApplyRedirects {
3673
3673
  }));
3674
3674
  }
3675
3675
  noMatchError(e) {
3676
- return new ɵRuntimeError(4002 /* RuntimeErrorCode.NO_MATCH */, NG_DEV_MODE$6 && `Cannot match any routes. URL Segment: '${e.segmentGroup}'`);
3676
+ return new ɵRuntimeError(4002 /* RuntimeErrorCode.NO_MATCH */, NG_DEV_MODE$7 && `Cannot match any routes. URL Segment: '${e.segmentGroup}'`);
3677
3677
  }
3678
3678
  createUrlTree(rootCandidate, queryParams, fragment) {
3679
3679
  const root = createRoot(rootCandidate);
@@ -3890,7 +3890,7 @@ class ApplyRedirects {
3890
3890
  findPosParam(redirectTo, redirectToUrlSegment, posParams) {
3891
3891
  const pos = posParams[redirectToUrlSegment.path.substring(1)];
3892
3892
  if (!pos)
3893
- throw new ɵRuntimeError(4001 /* RuntimeErrorCode.MISSING_REDIRECT */, NG_DEV_MODE$6 &&
3893
+ throw new ɵRuntimeError(4001 /* RuntimeErrorCode.MISSING_REDIRECT */, NG_DEV_MODE$7 &&
3894
3894
  `Cannot redirect to '${redirectTo}'. Cannot find '${redirectToUrlSegment.path}'.`);
3895
3895
  return pos;
3896
3896
  }
@@ -3926,7 +3926,7 @@ function applyRedirects(environmentInjector, configLoader, urlSerializer, config
3926
3926
  * Use of this source code is governed by an MIT-style license that can be
3927
3927
  * found in the LICENSE file at https://angular.io/license
3928
3928
  */
3929
- const NG_DEV_MODE$5 = typeof ngDevMode === 'undefined' || !!ngDevMode;
3929
+ const NG_DEV_MODE$6 = typeof ngDevMode === 'undefined' || !!ngDevMode;
3930
3930
  class NoMatch {
3931
3931
  }
3932
3932
  function newObservableError(e) {
@@ -4014,7 +4014,7 @@ class Recognizer {
4014
4014
  // multiple activated results for the same outlet. We should merge the children of
4015
4015
  // these results so the final return value is only one `TreeNode` per outlet.
4016
4016
  const mergedChildren = mergeEmptyPathMatches(children);
4017
- if (NG_DEV_MODE$5) {
4017
+ if (NG_DEV_MODE$6) {
4018
4018
  // This should really never happen - we are only taking the first match for each
4019
4019
  // outlet and merge the empty path matches.
4020
4020
  checkOutletNameUniqueness(mergedChildren);
@@ -4173,7 +4173,7 @@ function checkOutletNameUniqueness(nodes) {
4173
4173
  if (routeWithSameOutletName) {
4174
4174
  const p = routeWithSameOutletName.url.map(s => s.toString()).join('/');
4175
4175
  const c = n.value.url.map(s => s.toString()).join('/');
4176
- throw new ɵRuntimeError(4006 /* RuntimeErrorCode.TWO_SEGMENTS_WITH_SAME_OUTLET */, NG_DEV_MODE$5 && `Two segments cannot have the same outlet name: '${p}' and '${c}'.`);
4176
+ throw new ɵRuntimeError(4006 /* RuntimeErrorCode.TWO_SEGMENTS_WITH_SAME_OUTLET */, NG_DEV_MODE$6 && `Two segments cannot have the same outlet name: '${p}' and '${c}'.`);
4177
4177
  }
4178
4178
  names[n.value.outlet] = n.value;
4179
4179
  });
@@ -4314,174 +4314,8 @@ function switchTap(next) {
4314
4314
  * Use of this source code is governed by an MIT-style license that can be
4315
4315
  * found in the LICENSE file at https://angular.io/license
4316
4316
  */
4317
- /**
4318
- * Provides a strategy for setting the page title after a router navigation.
4319
- *
4320
- * The built-in implementation traverses the router state snapshot and finds the deepest primary
4321
- * outlet with `title` property. Given the `Routes` below, navigating to
4322
- * `/base/child(popup:aux)` would result in the document title being set to "child".
4323
- * ```
4324
- * [
4325
- * {path: 'base', title: 'base', children: [
4326
- * {path: 'child', title: 'child'},
4327
- * ],
4328
- * {path: 'aux', outlet: 'popup', title: 'popupTitle'}
4329
- * ]
4330
- * ```
4331
- *
4332
- * This class can be used as a base class for custom title strategies. That is, you can create your
4333
- * own class that extends the `TitleStrategy`. Note that in the above example, the `title`
4334
- * from the named outlet is never used. However, a custom strategy might be implemented to
4335
- * incorporate titles in named outlets.
4336
- *
4337
- * @publicApi
4338
- * @see [Page title guide](guide/router#setting-the-page-title)
4339
- */
4340
- class TitleStrategy {
4341
- /**
4342
- * @returns The `title` of the deepest primary route.
4343
- */
4344
- buildTitle(snapshot) {
4345
- var _a;
4346
- let pageTitle;
4347
- let route = snapshot.root;
4348
- while (route !== undefined) {
4349
- pageTitle = (_a = this.getResolvedTitleForRoute(route)) !== null && _a !== void 0 ? _a : pageTitle;
4350
- route = route.children.find(child => child.outlet === PRIMARY_OUTLET);
4351
- }
4352
- return pageTitle;
4353
- }
4354
- /**
4355
- * Given an `ActivatedRouteSnapshot`, returns the final value of the
4356
- * `Route.title` property, which can either be a static string or a resolved value.
4357
- */
4358
- getResolvedTitleForRoute(snapshot) {
4359
- return snapshot.data[RouteTitleKey];
4360
- }
4361
- }
4362
- TitleStrategy.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: TitleStrategy, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
4363
- TitleStrategy.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: TitleStrategy, providedIn: 'root', useFactory: () => inject(DefaultTitleStrategy) });
4364
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: TitleStrategy, decorators: [{
4365
- type: Injectable,
4366
- args: [{ providedIn: 'root', useFactory: () => inject(DefaultTitleStrategy) }]
4367
- }] });
4368
- /**
4369
- * The default `TitleStrategy` used by the router that updates the title using the `Title` service.
4370
- */
4371
- class DefaultTitleStrategy extends TitleStrategy {
4372
- constructor(title) {
4373
- super();
4374
- this.title = title;
4375
- }
4376
- /**
4377
- * Sets the title of the browser to the given value.
4378
- *
4379
- * @param title The `pageTitle` from the deepest primary route.
4380
- */
4381
- updateTitle(snapshot) {
4382
- const title = this.buildTitle(snapshot);
4383
- if (title !== undefined) {
4384
- this.title.setTitle(title);
4385
- }
4386
- }
4387
- }
4388
- DefaultTitleStrategy.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: DefaultTitleStrategy, deps: [{ token: i1.Title }], target: i0.ɵɵFactoryTarget.Injectable });
4389
- DefaultTitleStrategy.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: DefaultTitleStrategy, providedIn: 'root' });
4390
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: DefaultTitleStrategy, decorators: [{
4391
- type: Injectable,
4392
- args: [{ providedIn: 'root' }]
4393
- }], ctorParameters: function () { return [{ type: i1.Title }]; } });
4394
-
4395
- /**
4396
- * @license
4397
- * Copyright Google LLC All Rights Reserved.
4398
- *
4399
- * Use of this source code is governed by an MIT-style license that can be
4400
- * found in the LICENSE file at https://angular.io/license
4401
- */
4402
- /**
4403
- * @description
4404
- *
4405
- * Provides a way to customize when activated routes get reused.
4406
- *
4407
- * @publicApi
4408
- */
4409
- class RouteReuseStrategy {
4410
- }
4411
- /**
4412
- * @description
4413
- *
4414
- * This base route reuse strategy only reuses routes when the matched router configs are
4415
- * identical. This prevents components from being destroyed and recreated
4416
- * when just the route parameters, query parameters or fragment change
4417
- * (that is, the existing component is _reused_).
4418
- *
4419
- * This strategy does not store any routes for later reuse.
4420
- *
4421
- * Angular uses this strategy by default.
4422
- *
4423
- *
4424
- * It can be used as a base class for custom route reuse strategies, i.e. you can create your own
4425
- * class that extends the `BaseRouteReuseStrategy` one.
4426
- * @publicApi
4427
- */
4428
- class BaseRouteReuseStrategy {
4429
- /**
4430
- * Whether the given route should detach for later reuse.
4431
- * Always returns false for `BaseRouteReuseStrategy`.
4432
- * */
4433
- shouldDetach(route) {
4434
- return false;
4435
- }
4436
- /**
4437
- * A no-op; the route is never stored since this strategy never detaches routes for later re-use.
4438
- */
4439
- store(route, detachedTree) { }
4440
- /** Returns `false`, meaning the route (and its subtree) is never reattached */
4441
- shouldAttach(route) {
4442
- return false;
4443
- }
4444
- /** Returns `null` because this strategy does not store routes for later re-use. */
4445
- retrieve(route) {
4446
- return null;
4447
- }
4448
- /**
4449
- * Determines if a route should be reused.
4450
- * This strategy returns `true` when the future route config and current route config are
4451
- * identical.
4452
- */
4453
- shouldReuseRoute(future, curr) {
4454
- return future.routeConfig === curr.routeConfig;
4455
- }
4456
- }
4457
- class DefaultRouteReuseStrategy extends BaseRouteReuseStrategy {
4458
- }
4459
-
4460
- /**
4461
- * @license
4462
- * Copyright Google LLC All Rights Reserved.
4463
- *
4464
- * Use of this source code is governed by an MIT-style license that can be
4465
- * found in the LICENSE file at https://angular.io/license
4466
- */
4467
- const NG_DEV_MODE$4 = typeof ngDevMode === 'undefined' || !!ngDevMode;
4468
- /**
4469
- * A [DI token](guide/glossary/#di-token) for the router service.
4470
- *
4471
- * @publicApi
4472
- */
4473
- const ROUTER_CONFIGURATION = new InjectionToken(NG_DEV_MODE$4 ? 'router config' : '', {
4474
- providedIn: 'root',
4475
- factory: () => ({}),
4476
- });
4477
-
4478
- /**
4479
- * @license
4480
- * Copyright Google LLC All Rights Reserved.
4481
- *
4482
- * Use of this source code is governed by an MIT-style license that can be
4483
- * found in the LICENSE file at https://angular.io/license
4484
- */
4317
+ // This file exists to support the legacy `loadChildren: string` behavior being patched back into
4318
+ // Angular.
4485
4319
  function deprecatedLoadChildrenString(injector, loadChildren) {
4486
4320
  return null;
4487
4321
  }
@@ -4493,7 +4327,7 @@ function deprecatedLoadChildrenString(injector, loadChildren) {
4493
4327
  * Use of this source code is governed by an MIT-style license that can be
4494
4328
  * found in the LICENSE file at https://angular.io/license
4495
4329
  */
4496
- const NG_DEV_MODE$3 = typeof ngDevMode === 'undefined' || !!ngDevMode;
4330
+ const NG_DEV_MODE$5 = typeof ngDevMode === 'undefined' || !!ngDevMode;
4497
4331
  /**
4498
4332
  * The [DI token](guide/glossary/#di-token) for a router configuration.
4499
4333
  *
@@ -4528,7 +4362,7 @@ class RouterConfigLoader {
4528
4362
  if (this.onLoadEndListener) {
4529
4363
  this.onLoadEndListener(route);
4530
4364
  }
4531
- NG_DEV_MODE$3 && assertStandalone((_a = route.path) !== null && _a !== void 0 ? _a : '', component);
4365
+ NG_DEV_MODE$5 && assertStandalone((_a = route.path) !== null && _a !== void 0 ? _a : '', component);
4532
4366
  route._loadedComponent = component;
4533
4367
  }), finalize(() => {
4534
4368
  this.componentLoaders.delete(route);
@@ -4571,7 +4405,7 @@ class RouterConfigLoader {
4571
4405
  rawRoutes = flatten(injector.get(ROUTES, [], InjectFlags.Self | InjectFlags.Optional));
4572
4406
  }
4573
4407
  const routes = rawRoutes.map(standardizeConfig);
4574
- NG_DEV_MODE$3 && validateConfig(routes, route.path, requireStandaloneComponents);
4408
+ NG_DEV_MODE$5 && validateConfig(routes, route.path, requireStandaloneComponents);
4575
4409
  return { routes, injector };
4576
4410
  }), finalize(() => {
4577
4411
  this.childrenLoaders.delete(route);
@@ -4598,9 +4432,9 @@ class RouterConfigLoader {
4598
4432
  }));
4599
4433
  }
4600
4434
  }
4601
- RouterConfigLoader.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: RouterConfigLoader, deps: [{ token: i0.Injector }, { token: i0.Compiler }], target: i0.ɵɵFactoryTarget.Injectable });
4602
- RouterConfigLoader.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: RouterConfigLoader, providedIn: 'root' });
4603
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: RouterConfigLoader, decorators: [{
4435
+ RouterConfigLoader.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.2", ngImport: i0, type: RouterConfigLoader, deps: [{ token: i0.Injector }, { token: i0.Compiler }], target: i0.ɵɵFactoryTarget.Injectable });
4436
+ RouterConfigLoader.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.0.2", ngImport: i0, type: RouterConfigLoader, providedIn: 'root' });
4437
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.2", ngImport: i0, type: RouterConfigLoader, decorators: [{
4604
4438
  type: Injectable,
4605
4439
  args: [{ providedIn: 'root' }]
4606
4440
  }], ctorParameters: function () { return [{ type: i0.Injector }, { type: i0.Compiler }]; } });
@@ -4623,84 +4457,631 @@ function maybeUnwrapDefaultExport(input) {
4623
4457
  * Use of this source code is governed by an MIT-style license that can be
4624
4458
  * found in the LICENSE file at https://angular.io/license
4625
4459
  */
4626
- /**
4627
- * @description
4628
- *
4629
- * Provides a way to migrate AngularJS applications to Angular.
4630
- *
4631
- * @publicApi
4632
- */
4633
- class UrlHandlingStrategy {
4634
- }
4635
- /**
4636
- * @publicApi
4637
- */
4638
- class DefaultUrlHandlingStrategy {
4639
- shouldProcessUrl(url) {
4640
- return true;
4641
- }
4642
- extract(url) {
4643
- return url;
4644
- }
4645
- merge(newUrlPart, wholeUrl) {
4646
- return newUrlPart;
4647
- }
4648
- }
4649
-
4650
- /**
4651
- * @license
4652
- * Copyright Google LLC All Rights Reserved.
4653
- *
4654
- * Use of this source code is governed by an MIT-style license that can be
4655
- * found in the LICENSE file at https://angular.io/license
4656
- */
4657
- const NG_DEV_MODE$2 = typeof ngDevMode === 'undefined' || !!ngDevMode;
4658
- function defaultErrorHandler(error) {
4659
- throw error;
4660
- }
4661
- function defaultMalformedUriErrorHandler(error, urlSerializer, url) {
4662
- return urlSerializer.parse('/');
4663
- }
4664
- /**
4665
- * The equivalent `IsActiveMatchOptions` options for `Router.isActive` is called with `true`
4666
- * (exact = true).
4667
- */
4668
- const exactMatchOptions = {
4669
- paths: 'exact',
4670
- fragment: 'ignored',
4671
- matrixParams: 'ignored',
4672
- queryParams: 'exact'
4673
- };
4674
- /**
4675
- * The equivalent `IsActiveMatchOptions` options for `Router.isActive` is called with `false`
4676
- * (exact = false).
4677
- */
4678
- const subsetMatchOptions = {
4679
- paths: 'subset',
4680
- fragment: 'ignored',
4681
- matrixParams: 'ignored',
4682
- queryParams: 'subset'
4683
- };
4684
- function assignExtraOptionsToRouter(opts, router) {
4685
- if (opts.errorHandler) {
4686
- router.errorHandler = opts.errorHandler;
4687
- }
4688
- if (opts.malformedUriErrorHandler) {
4689
- router.malformedUriErrorHandler = opts.malformedUriErrorHandler;
4690
- }
4691
- if (opts.onSameUrlNavigation) {
4692
- router.onSameUrlNavigation = opts.onSameUrlNavigation;
4460
+ const NG_DEV_MODE$4 = typeof ngDevMode === 'undefined' || !!ngDevMode;
4461
+ class NavigationTransitions {
4462
+ constructor() {
4463
+ this.currentNavigation = null;
4464
+ this.lastSuccessfulNavigation = null;
4465
+ this.events = new Subject();
4466
+ this.configLoader = inject(RouterConfigLoader);
4467
+ this.environmentInjector = inject(EnvironmentInjector);
4468
+ this.urlSerializer = inject(UrlSerializer);
4469
+ this.rootContexts = inject(ChildrenOutletContexts);
4470
+ this.navigationId = 0;
4471
+ const onLoadStart = (r) => this.events.next(new RouteConfigLoadStart(r));
4472
+ const onLoadEnd = (r) => this.events.next(new RouteConfigLoadEnd(r));
4473
+ this.configLoader.onLoadEndListener = onLoadEnd;
4474
+ this.configLoader.onLoadStartListener = onLoadStart;
4693
4475
  }
4694
- if (opts.paramsInheritanceStrategy) {
4695
- router.paramsInheritanceStrategy = opts.paramsInheritanceStrategy;
4476
+ get hasRequestedNavigation() {
4477
+ return this.navigationId !== 0;
4696
4478
  }
4697
- if (opts.urlUpdateStrategy) {
4698
- router.urlUpdateStrategy = opts.urlUpdateStrategy;
4479
+ complete() {
4480
+ var _a;
4481
+ (_a = this.transitions) === null || _a === void 0 ? void 0 : _a.complete();
4699
4482
  }
4700
- if (opts.canceledNavigationResolution) {
4701
- router.canceledNavigationResolution = opts.canceledNavigationResolution;
4483
+ handleNavigationRequest(request) {
4484
+ var _a;
4485
+ const id = ++this.navigationId;
4486
+ (_a = this.transitions) === null || _a === void 0 ? void 0 : _a.next(Object.assign(Object.assign(Object.assign({}, this.transitions.value), request), { id }));
4702
4487
  }
4703
- }
4488
+ setupNavigations(router) {
4489
+ this.transitions = new BehaviorSubject({
4490
+ id: 0,
4491
+ targetPageId: 0,
4492
+ currentUrlTree: router.currentUrlTree,
4493
+ currentRawUrl: router.currentUrlTree,
4494
+ extractedUrl: router.urlHandlingStrategy.extract(router.currentUrlTree),
4495
+ urlAfterRedirects: router.urlHandlingStrategy.extract(router.currentUrlTree),
4496
+ rawUrl: router.currentUrlTree,
4497
+ extras: {},
4498
+ resolve: null,
4499
+ reject: null,
4500
+ promise: Promise.resolve(true),
4501
+ source: 'imperative',
4502
+ restoredState: null,
4503
+ currentSnapshot: router.routerState.snapshot,
4504
+ targetSnapshot: null,
4505
+ currentRouterState: router.routerState,
4506
+ targetRouterState: null,
4507
+ guards: { canActivateChecks: [], canDeactivateChecks: [] },
4508
+ guardsResult: null,
4509
+ });
4510
+ return this.transitions.pipe(filter(t => t.id !== 0),
4511
+ // Extract URL
4512
+ map(t => (Object.assign(Object.assign({}, t), { extractedUrl: router.urlHandlingStrategy.extract(t.rawUrl) }))),
4513
+ // Using switchMap so we cancel executing navigations when a new one comes in
4514
+ switchMap(overallTransitionState => {
4515
+ let completed = false;
4516
+ let errored = false;
4517
+ return of(overallTransitionState)
4518
+ .pipe(
4519
+ // Store the Navigation object
4520
+ tap(t => {
4521
+ this.currentNavigation = {
4522
+ id: t.id,
4523
+ initialUrl: t.rawUrl,
4524
+ extractedUrl: t.extractedUrl,
4525
+ trigger: t.source,
4526
+ extras: t.extras,
4527
+ previousNavigation: !this.lastSuccessfulNavigation ? null : Object.assign(Object.assign({}, this.lastSuccessfulNavigation), { previousNavigation: null }),
4528
+ };
4529
+ }), switchMap(t => {
4530
+ const browserUrlTree = router.browserUrlTree.toString();
4531
+ const urlTransition = !router.navigated ||
4532
+ t.extractedUrl.toString() !== browserUrlTree ||
4533
+ // Navigations which succeed or ones which fail and are cleaned up
4534
+ // correctly should result in `browserUrlTree` and `currentUrlTree`
4535
+ // matching. If this is not the case, assume something went wrong and
4536
+ // try processing the URL again.
4537
+ browserUrlTree !== router.currentUrlTree.toString();
4538
+ const processCurrentUrl = (router.onSameUrlNavigation === 'reload' ? true : urlTransition) &&
4539
+ router.urlHandlingStrategy.shouldProcessUrl(t.rawUrl);
4540
+ if (processCurrentUrl) {
4541
+ // If the source of the navigation is from a browser event, the URL is
4542
+ // already updated. We already need to sync the internal state.
4543
+ if (isBrowserTriggeredNavigation(t.source)) {
4544
+ router.browserUrlTree = t.extractedUrl;
4545
+ }
4546
+ return of(t).pipe(
4547
+ // Fire NavigationStart event
4548
+ switchMap(t => {
4549
+ var _a, _b;
4550
+ const transition = (_a = this.transitions) === null || _a === void 0 ? void 0 : _a.getValue();
4551
+ this.events.next(new NavigationStart(t.id, this.urlSerializer.serialize(t.extractedUrl), t.source, t.restoredState));
4552
+ if (transition !== ((_b = this.transitions) === null || _b === void 0 ? void 0 : _b.getValue())) {
4553
+ return EMPTY;
4554
+ }
4555
+ // This delay is required to match old behavior that forced
4556
+ // navigation to always be async
4557
+ return Promise.resolve(t);
4558
+ }),
4559
+ // ApplyRedirects
4560
+ applyRedirects(this.environmentInjector, this.configLoader, this.urlSerializer, router.config),
4561
+ // Update the currentNavigation
4562
+ // `urlAfterRedirects` is guaranteed to be set after this point
4563
+ tap(t => {
4564
+ this.currentNavigation = Object.assign(Object.assign({}, this.currentNavigation), { finalUrl: t.urlAfterRedirects });
4565
+ overallTransitionState.urlAfterRedirects = t.urlAfterRedirects;
4566
+ }),
4567
+ // Recognize
4568
+ recognize(this.environmentInjector, router.rootComponentType, router.config, this.urlSerializer, router.paramsInheritanceStrategy),
4569
+ // Update URL if in `eager` update mode
4570
+ tap(t => {
4571
+ overallTransitionState.targetSnapshot = t.targetSnapshot;
4572
+ if (router.urlUpdateStrategy === 'eager') {
4573
+ if (!t.extras.skipLocationChange) {
4574
+ const rawUrl = router.urlHandlingStrategy.merge(t.urlAfterRedirects, t.rawUrl);
4575
+ router.setBrowserUrl(rawUrl, t);
4576
+ }
4577
+ router.browserUrlTree = t.urlAfterRedirects;
4578
+ }
4579
+ // Fire RoutesRecognized
4580
+ const routesRecognized = new RoutesRecognized(t.id, this.urlSerializer.serialize(t.extractedUrl), this.urlSerializer.serialize(t.urlAfterRedirects), t.targetSnapshot);
4581
+ this.events.next(routesRecognized);
4582
+ }));
4583
+ }
4584
+ else {
4585
+ const processPreviousUrl = urlTransition && router.rawUrlTree &&
4586
+ router.urlHandlingStrategy.shouldProcessUrl(router.rawUrlTree);
4587
+ /* When the current URL shouldn't be processed, but the previous one
4588
+ * was, we handle this "error condition" by navigating to the
4589
+ * previously successful URL, but leaving the URL intact.*/
4590
+ if (processPreviousUrl) {
4591
+ const { id, extractedUrl, source, restoredState, extras } = t;
4592
+ const navStart = new NavigationStart(id, this.urlSerializer.serialize(extractedUrl), source, restoredState);
4593
+ this.events.next(navStart);
4594
+ const targetSnapshot = createEmptyState(extractedUrl, router.rootComponentType)
4595
+ .snapshot;
4596
+ overallTransitionState = Object.assign(Object.assign({}, t), { targetSnapshot, urlAfterRedirects: extractedUrl, extras: Object.assign(Object.assign({}, extras), { skipLocationChange: false, replaceUrl: false }) });
4597
+ return of(overallTransitionState);
4598
+ }
4599
+ else {
4600
+ /* When neither the current or previous URL can be processed, do
4601
+ * nothing other than update router's internal reference to the
4602
+ * current "settled" URL. This way the next navigation will be coming
4603
+ * from the current URL in the browser.
4604
+ */
4605
+ router.rawUrlTree = t.rawUrl;
4606
+ t.resolve(null);
4607
+ return EMPTY;
4608
+ }
4609
+ }
4610
+ }),
4611
+ // --- GUARDS ---
4612
+ tap(t => {
4613
+ const guardsStart = new GuardsCheckStart(t.id, this.urlSerializer.serialize(t.extractedUrl), this.urlSerializer.serialize(t.urlAfterRedirects), t.targetSnapshot);
4614
+ this.events.next(guardsStart);
4615
+ }), map(t => {
4616
+ overallTransitionState = Object.assign(Object.assign({}, t), { guards: getAllRouteGuards(t.targetSnapshot, t.currentSnapshot, this.rootContexts) });
4617
+ return overallTransitionState;
4618
+ }), checkGuards(this.environmentInjector, (evt) => this.events.next(evt)), tap(t => {
4619
+ overallTransitionState.guardsResult = t.guardsResult;
4620
+ if (isUrlTree(t.guardsResult)) {
4621
+ throw redirectingNavigationError(this.urlSerializer, t.guardsResult);
4622
+ }
4623
+ const guardsEnd = new GuardsCheckEnd(t.id, this.urlSerializer.serialize(t.extractedUrl), this.urlSerializer.serialize(t.urlAfterRedirects), t.targetSnapshot, !!t.guardsResult);
4624
+ this.events.next(guardsEnd);
4625
+ }), filter(t => {
4626
+ if (!t.guardsResult) {
4627
+ router.restoreHistory(t);
4628
+ this.cancelNavigationTransition(t, '', 3 /* NavigationCancellationCode.GuardRejected */, router);
4629
+ return false;
4630
+ }
4631
+ return true;
4632
+ }),
4633
+ // --- RESOLVE ---
4634
+ switchTap(t => {
4635
+ if (t.guards.canActivateChecks.length) {
4636
+ return of(t).pipe(tap(t => {
4637
+ const resolveStart = new ResolveStart(t.id, this.urlSerializer.serialize(t.extractedUrl), this.urlSerializer.serialize(t.urlAfterRedirects), t.targetSnapshot);
4638
+ this.events.next(resolveStart);
4639
+ }), switchMap(t => {
4640
+ let dataResolved = false;
4641
+ return of(t).pipe(resolveData(router.paramsInheritanceStrategy, this.environmentInjector), tap({
4642
+ next: () => dataResolved = true,
4643
+ complete: () => {
4644
+ if (!dataResolved) {
4645
+ router.restoreHistory(t);
4646
+ this.cancelNavigationTransition(t, NG_DEV_MODE$4 ?
4647
+ `At least one route resolver didn't emit any value.` :
4648
+ '', 2 /* NavigationCancellationCode.NoDataFromResolver */, router);
4649
+ }
4650
+ }
4651
+ }));
4652
+ }), tap(t => {
4653
+ const resolveEnd = new ResolveEnd(t.id, this.urlSerializer.serialize(t.extractedUrl), this.urlSerializer.serialize(t.urlAfterRedirects), t.targetSnapshot);
4654
+ this.events.next(resolveEnd);
4655
+ }));
4656
+ }
4657
+ return undefined;
4658
+ }),
4659
+ // --- LOAD COMPONENTS ---
4660
+ switchTap((t) => {
4661
+ const loadComponents = (route) => {
4662
+ var _a;
4663
+ const loaders = [];
4664
+ if (((_a = route.routeConfig) === null || _a === void 0 ? void 0 : _a.loadComponent) &&
4665
+ !route.routeConfig._loadedComponent) {
4666
+ loaders.push(this.configLoader.loadComponent(route.routeConfig)
4667
+ .pipe(tap(loadedComponent => {
4668
+ route.component = loadedComponent;
4669
+ }), map(() => void 0)));
4670
+ }
4671
+ for (const child of route.children) {
4672
+ loaders.push(...loadComponents(child));
4673
+ }
4674
+ return loaders;
4675
+ };
4676
+ return combineLatest(loadComponents(t.targetSnapshot.root))
4677
+ .pipe(defaultIfEmpty(), take(1));
4678
+ }), switchTap(() => router.afterPreactivation()), map((t) => {
4679
+ const targetRouterState = createRouterState(router.routeReuseStrategy, t.targetSnapshot, t.currentRouterState);
4680
+ overallTransitionState = Object.assign(Object.assign({}, t), { targetRouterState });
4681
+ return (overallTransitionState);
4682
+ }),
4683
+ /* Once here, we are about to activate synchronously. The assumption is
4684
+ this will succeed, and user code may read from the Router service.
4685
+ Therefore before activation, we need to update router properties storing
4686
+ the current URL and the RouterState, as well as updated the browser URL.
4687
+ All this should happen *before* activating. */
4688
+ tap((t) => {
4689
+ router.currentUrlTree = t.urlAfterRedirects;
4690
+ router.rawUrlTree =
4691
+ router.urlHandlingStrategy.merge(t.urlAfterRedirects, t.rawUrl);
4692
+ router.routerState =
4693
+ t.targetRouterState;
4694
+ if (router.urlUpdateStrategy === 'deferred') {
4695
+ if (!t.extras.skipLocationChange) {
4696
+ router.setBrowserUrl(router.rawUrlTree, t);
4697
+ }
4698
+ router.browserUrlTree = t.urlAfterRedirects;
4699
+ }
4700
+ }), activateRoutes(this.rootContexts, router.routeReuseStrategy, (evt) => this.events.next(evt)), tap({
4701
+ next: (t) => {
4702
+ var _a;
4703
+ completed = true;
4704
+ this.lastSuccessfulNavigation = this.currentNavigation;
4705
+ router.navigated = true;
4706
+ this.events.next(new NavigationEnd(t.id, this.urlSerializer.serialize(t.extractedUrl), this.urlSerializer.serialize(router.currentUrlTree)));
4707
+ (_a = router.titleStrategy) === null || _a === void 0 ? void 0 : _a.updateTitle(t.targetRouterState.snapshot);
4708
+ t.resolve(true);
4709
+ },
4710
+ complete: () => {
4711
+ completed = true;
4712
+ }
4713
+ }), finalize(() => {
4714
+ var _a;
4715
+ /* When the navigation stream finishes either through error or success,
4716
+ * we set the `completed` or `errored` flag. However, there are some
4717
+ * situations where we could get here without either of those being set.
4718
+ * For instance, a redirect during NavigationStart. Therefore, this is a
4719
+ * catch-all to make sure the NavigationCancel event is fired when a
4720
+ * navigation gets cancelled but not caught by other means. */
4721
+ if (!completed && !errored) {
4722
+ const cancelationReason = NG_DEV_MODE$4 ?
4723
+ `Navigation ID ${overallTransitionState
4724
+ .id} is not equal to the current navigation id ${this.navigationId}` :
4725
+ '';
4726
+ this.cancelNavigationTransition(overallTransitionState, cancelationReason, 1 /* NavigationCancellationCode.SupersededByNewNavigation */, router);
4727
+ }
4728
+ // Only clear current navigation if it is still set to the one that
4729
+ // finalized.
4730
+ if (((_a = this.currentNavigation) === null || _a === void 0 ? void 0 : _a.id) === overallTransitionState.id) {
4731
+ this.currentNavigation = null;
4732
+ }
4733
+ }), catchError((e) => {
4734
+ var _a;
4735
+ errored = true;
4736
+ /* This error type is issued during Redirect, and is handled as a
4737
+ * cancellation rather than an error. */
4738
+ if (isNavigationCancelingError$1(e)) {
4739
+ if (!isRedirectingNavigationCancelingError$1(e)) {
4740
+ // Set property only if we're not redirecting. If we landed on a page
4741
+ // and redirect to `/` route, the new navigation is going to see the
4742
+ // `/` isn't a change from the default currentUrlTree and won't
4743
+ // navigate. This is only applicable with initial navigation, so
4744
+ // setting `navigated` only when not redirecting resolves this
4745
+ // scenario.
4746
+ router.navigated = true;
4747
+ router.restoreHistory(overallTransitionState, true);
4748
+ }
4749
+ const navCancel = new NavigationCancel(overallTransitionState.id, this.urlSerializer.serialize(overallTransitionState.extractedUrl), e.message, e.cancellationCode);
4750
+ this.events.next(navCancel);
4751
+ // When redirecting, we need to delay resolving the navigation
4752
+ // promise and push it to the redirect navigation
4753
+ if (!isRedirectingNavigationCancelingError$1(e)) {
4754
+ overallTransitionState.resolve(false);
4755
+ }
4756
+ else {
4757
+ const mergedTree = router.urlHandlingStrategy.merge(e.url, router.rawUrlTree);
4758
+ const extras = {
4759
+ skipLocationChange: overallTransitionState.extras.skipLocationChange,
4760
+ // The URL is already updated at this point if we have 'eager' URL
4761
+ // updates or if the navigation was triggered by the browser (back
4762
+ // button, URL bar, etc). We want to replace that item in history
4763
+ // if the navigation is rejected.
4764
+ replaceUrl: router.urlUpdateStrategy === 'eager' ||
4765
+ isBrowserTriggeredNavigation(overallTransitionState.source)
4766
+ };
4767
+ router.scheduleNavigation(mergedTree, 'imperative', null, extras, {
4768
+ resolve: overallTransitionState.resolve,
4769
+ reject: overallTransitionState.reject,
4770
+ promise: overallTransitionState.promise
4771
+ });
4772
+ }
4773
+ /* All other errors should reset to the router's internal URL reference
4774
+ * to the pre-error state. */
4775
+ }
4776
+ else {
4777
+ router.restoreHistory(overallTransitionState, true);
4778
+ const navError = new NavigationError(overallTransitionState.id, this.urlSerializer.serialize(overallTransitionState.extractedUrl), e, (_a = overallTransitionState.targetSnapshot) !== null && _a !== void 0 ? _a : undefined);
4779
+ this.events.next(navError);
4780
+ try {
4781
+ overallTransitionState.resolve(router.errorHandler(e));
4782
+ }
4783
+ catch (ee) {
4784
+ overallTransitionState.reject(ee);
4785
+ }
4786
+ }
4787
+ return EMPTY;
4788
+ }));
4789
+ // TODO(jasonaden): remove cast once g3 is on updated TypeScript
4790
+ }));
4791
+ }
4792
+ cancelNavigationTransition(t, reason, code, router) {
4793
+ const navCancel = new NavigationCancel(t.id, this.urlSerializer.serialize(t.extractedUrl), reason, code);
4794
+ this.events.next(navCancel);
4795
+ t.resolve(false);
4796
+ }
4797
+ }
4798
+ NavigationTransitions.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.2", ngImport: i0, type: NavigationTransitions, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
4799
+ NavigationTransitions.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.0.2", ngImport: i0, type: NavigationTransitions, providedIn: 'root' });
4800
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.2", ngImport: i0, type: NavigationTransitions, decorators: [{
4801
+ type: Injectable,
4802
+ args: [{ providedIn: 'root' }]
4803
+ }], ctorParameters: function () { return []; } });
4804
+ function isBrowserTriggeredNavigation(source) {
4805
+ return source !== 'imperative';
4806
+ }
4807
+
4808
+ /**
4809
+ * @license
4810
+ * Copyright Google LLC All Rights Reserved.
4811
+ *
4812
+ * Use of this source code is governed by an MIT-style license that can be
4813
+ * found in the LICENSE file at https://angular.io/license
4814
+ */
4815
+ /**
4816
+ * Provides a strategy for setting the page title after a router navigation.
4817
+ *
4818
+ * The built-in implementation traverses the router state snapshot and finds the deepest primary
4819
+ * outlet with `title` property. Given the `Routes` below, navigating to
4820
+ * `/base/child(popup:aux)` would result in the document title being set to "child".
4821
+ * ```
4822
+ * [
4823
+ * {path: 'base', title: 'base', children: [
4824
+ * {path: 'child', title: 'child'},
4825
+ * ],
4826
+ * {path: 'aux', outlet: 'popup', title: 'popupTitle'}
4827
+ * ]
4828
+ * ```
4829
+ *
4830
+ * This class can be used as a base class for custom title strategies. That is, you can create your
4831
+ * own class that extends the `TitleStrategy`. Note that in the above example, the `title`
4832
+ * from the named outlet is never used. However, a custom strategy might be implemented to
4833
+ * incorporate titles in named outlets.
4834
+ *
4835
+ * @publicApi
4836
+ * @see [Page title guide](guide/router#setting-the-page-title)
4837
+ */
4838
+ class TitleStrategy {
4839
+ /**
4840
+ * @returns The `title` of the deepest primary route.
4841
+ */
4842
+ buildTitle(snapshot) {
4843
+ var _a;
4844
+ let pageTitle;
4845
+ let route = snapshot.root;
4846
+ while (route !== undefined) {
4847
+ pageTitle = (_a = this.getResolvedTitleForRoute(route)) !== null && _a !== void 0 ? _a : pageTitle;
4848
+ route = route.children.find(child => child.outlet === PRIMARY_OUTLET);
4849
+ }
4850
+ return pageTitle;
4851
+ }
4852
+ /**
4853
+ * Given an `ActivatedRouteSnapshot`, returns the final value of the
4854
+ * `Route.title` property, which can either be a static string or a resolved value.
4855
+ */
4856
+ getResolvedTitleForRoute(snapshot) {
4857
+ return snapshot.data[RouteTitleKey];
4858
+ }
4859
+ }
4860
+ TitleStrategy.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.2", ngImport: i0, type: TitleStrategy, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
4861
+ TitleStrategy.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.0.2", ngImport: i0, type: TitleStrategy, providedIn: 'root', useFactory: () => inject(DefaultTitleStrategy) });
4862
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.2", ngImport: i0, type: TitleStrategy, decorators: [{
4863
+ type: Injectable,
4864
+ args: [{ providedIn: 'root', useFactory: () => inject(DefaultTitleStrategy) }]
4865
+ }] });
4866
+ /**
4867
+ * The default `TitleStrategy` used by the router that updates the title using the `Title` service.
4868
+ */
4869
+ class DefaultTitleStrategy extends TitleStrategy {
4870
+ constructor(title) {
4871
+ super();
4872
+ this.title = title;
4873
+ }
4874
+ /**
4875
+ * Sets the title of the browser to the given value.
4876
+ *
4877
+ * @param title The `pageTitle` from the deepest primary route.
4878
+ */
4879
+ updateTitle(snapshot) {
4880
+ const title = this.buildTitle(snapshot);
4881
+ if (title !== undefined) {
4882
+ this.title.setTitle(title);
4883
+ }
4884
+ }
4885
+ }
4886
+ DefaultTitleStrategy.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.2", ngImport: i0, type: DefaultTitleStrategy, deps: [{ token: i1.Title }], target: i0.ɵɵFactoryTarget.Injectable });
4887
+ DefaultTitleStrategy.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.0.2", ngImport: i0, type: DefaultTitleStrategy, providedIn: 'root' });
4888
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.2", ngImport: i0, type: DefaultTitleStrategy, decorators: [{
4889
+ type: Injectable,
4890
+ args: [{ providedIn: 'root' }]
4891
+ }], ctorParameters: function () { return [{ type: i1.Title }]; } });
4892
+
4893
+ /**
4894
+ * @license
4895
+ * Copyright Google LLC All Rights Reserved.
4896
+ *
4897
+ * Use of this source code is governed by an MIT-style license that can be
4898
+ * found in the LICENSE file at https://angular.io/license
4899
+ */
4900
+ /**
4901
+ * @description
4902
+ *
4903
+ * Provides a way to customize when activated routes get reused.
4904
+ *
4905
+ * @publicApi
4906
+ */
4907
+ class RouteReuseStrategy {
4908
+ }
4909
+ RouteReuseStrategy.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.2", ngImport: i0, type: RouteReuseStrategy, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
4910
+ RouteReuseStrategy.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.0.2", ngImport: i0, type: RouteReuseStrategy, providedIn: 'root', useFactory: () => inject(DefaultRouteReuseStrategy) });
4911
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.2", ngImport: i0, type: RouteReuseStrategy, decorators: [{
4912
+ type: Injectable,
4913
+ args: [{ providedIn: 'root', useFactory: () => inject(DefaultRouteReuseStrategy) }]
4914
+ }] });
4915
+ /**
4916
+ * @description
4917
+ *
4918
+ * This base route reuse strategy only reuses routes when the matched router configs are
4919
+ * identical. This prevents components from being destroyed and recreated
4920
+ * when just the route parameters, query parameters or fragment change
4921
+ * (that is, the existing component is _reused_).
4922
+ *
4923
+ * This strategy does not store any routes for later reuse.
4924
+ *
4925
+ * Angular uses this strategy by default.
4926
+ *
4927
+ *
4928
+ * It can be used as a base class for custom route reuse strategies, i.e. you can create your own
4929
+ * class that extends the `BaseRouteReuseStrategy` one.
4930
+ * @publicApi
4931
+ */
4932
+ class BaseRouteReuseStrategy {
4933
+ /**
4934
+ * Whether the given route should detach for later reuse.
4935
+ * Always returns false for `BaseRouteReuseStrategy`.
4936
+ * */
4937
+ shouldDetach(route) {
4938
+ return false;
4939
+ }
4940
+ /**
4941
+ * A no-op; the route is never stored since this strategy never detaches routes for later re-use.
4942
+ */
4943
+ store(route, detachedTree) { }
4944
+ /** Returns `false`, meaning the route (and its subtree) is never reattached */
4945
+ shouldAttach(route) {
4946
+ return false;
4947
+ }
4948
+ /** Returns `null` because this strategy does not store routes for later re-use. */
4949
+ retrieve(route) {
4950
+ return null;
4951
+ }
4952
+ /**
4953
+ * Determines if a route should be reused.
4954
+ * This strategy returns `true` when the future route config and current route config are
4955
+ * identical.
4956
+ */
4957
+ shouldReuseRoute(future, curr) {
4958
+ return future.routeConfig === curr.routeConfig;
4959
+ }
4960
+ }
4961
+ class DefaultRouteReuseStrategy extends BaseRouteReuseStrategy {
4962
+ }
4963
+ DefaultRouteReuseStrategy.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.2", ngImport: i0, type: DefaultRouteReuseStrategy, deps: null, target: i0.ɵɵFactoryTarget.Injectable });
4964
+ DefaultRouteReuseStrategy.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.0.2", ngImport: i0, type: DefaultRouteReuseStrategy, providedIn: 'root' });
4965
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.2", ngImport: i0, type: DefaultRouteReuseStrategy, decorators: [{
4966
+ type: Injectable,
4967
+ args: [{ providedIn: 'root' }]
4968
+ }] });
4969
+
4970
+ /**
4971
+ * @license
4972
+ * Copyright Google LLC All Rights Reserved.
4973
+ *
4974
+ * Use of this source code is governed by an MIT-style license that can be
4975
+ * found in the LICENSE file at https://angular.io/license
4976
+ */
4977
+ const NG_DEV_MODE$3 = typeof ngDevMode === 'undefined' || !!ngDevMode;
4978
+ /**
4979
+ * A [DI token](guide/glossary/#di-token) for the router service.
4980
+ *
4981
+ * @publicApi
4982
+ */
4983
+ const ROUTER_CONFIGURATION = new InjectionToken(NG_DEV_MODE$3 ? 'router config' : '', {
4984
+ providedIn: 'root',
4985
+ factory: () => ({}),
4986
+ });
4987
+
4988
+ /**
4989
+ * @license
4990
+ * Copyright Google LLC All Rights Reserved.
4991
+ *
4992
+ * Use of this source code is governed by an MIT-style license that can be
4993
+ * found in the LICENSE file at https://angular.io/license
4994
+ */
4995
+ /**
4996
+ * @description
4997
+ *
4998
+ * Provides a way to migrate AngularJS applications to Angular.
4999
+ *
5000
+ * @publicApi
5001
+ */
5002
+ class UrlHandlingStrategy {
5003
+ }
5004
+ UrlHandlingStrategy.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.2", ngImport: i0, type: UrlHandlingStrategy, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
5005
+ UrlHandlingStrategy.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.0.2", ngImport: i0, type: UrlHandlingStrategy, providedIn: 'root', useFactory: () => inject(DefaultUrlHandlingStrategy) });
5006
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.2", ngImport: i0, type: UrlHandlingStrategy, decorators: [{
5007
+ type: Injectable,
5008
+ args: [{ providedIn: 'root', useFactory: () => inject(DefaultUrlHandlingStrategy) }]
5009
+ }] });
5010
+ /**
5011
+ * @publicApi
5012
+ */
5013
+ class DefaultUrlHandlingStrategy {
5014
+ shouldProcessUrl(url) {
5015
+ return true;
5016
+ }
5017
+ extract(url) {
5018
+ return url;
5019
+ }
5020
+ merge(newUrlPart, wholeUrl) {
5021
+ return newUrlPart;
5022
+ }
5023
+ }
5024
+ DefaultUrlHandlingStrategy.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.2", ngImport: i0, type: DefaultUrlHandlingStrategy, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
5025
+ DefaultUrlHandlingStrategy.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.0.2", ngImport: i0, type: DefaultUrlHandlingStrategy, providedIn: 'root' });
5026
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.2", ngImport: i0, type: DefaultUrlHandlingStrategy, decorators: [{
5027
+ type: Injectable,
5028
+ args: [{ providedIn: 'root' }]
5029
+ }] });
5030
+
5031
+ /**
5032
+ * @license
5033
+ * Copyright Google LLC All Rights Reserved.
5034
+ *
5035
+ * Use of this source code is governed by an MIT-style license that can be
5036
+ * found in the LICENSE file at https://angular.io/license
5037
+ */
5038
+ const NG_DEV_MODE$2 = typeof ngDevMode === 'undefined' || !!ngDevMode;
5039
+ function defaultErrorHandler(error) {
5040
+ throw error;
5041
+ }
5042
+ function defaultMalformedUriErrorHandler(error, urlSerializer, url) {
5043
+ return urlSerializer.parse('/');
5044
+ }
5045
+ /**
5046
+ * The equivalent `IsActiveMatchOptions` options for `Router.isActive` is called with `true`
5047
+ * (exact = true).
5048
+ */
5049
+ const exactMatchOptions = {
5050
+ paths: 'exact',
5051
+ fragment: 'ignored',
5052
+ matrixParams: 'ignored',
5053
+ queryParams: 'exact'
5054
+ };
5055
+ /**
5056
+ * The equivalent `IsActiveMatchOptions` options for `Router.isActive` is called with `false`
5057
+ * (exact = false).
5058
+ */
5059
+ const subsetMatchOptions = {
5060
+ paths: 'subset',
5061
+ fragment: 'ignored',
5062
+ matrixParams: 'ignored',
5063
+ queryParams: 'subset'
5064
+ };
5065
+ function assignExtraOptionsToRouter(opts, router) {
5066
+ if (opts.errorHandler) {
5067
+ router.errorHandler = opts.errorHandler;
5068
+ }
5069
+ if (opts.malformedUriErrorHandler) {
5070
+ router.malformedUriErrorHandler = opts.malformedUriErrorHandler;
5071
+ }
5072
+ if (opts.onSameUrlNavigation) {
5073
+ router.onSameUrlNavigation = opts.onSameUrlNavigation;
5074
+ }
5075
+ if (opts.paramsInheritanceStrategy) {
5076
+ router.paramsInheritanceStrategy = opts.paramsInheritanceStrategy;
5077
+ }
5078
+ if (opts.urlUpdateStrategy) {
5079
+ router.urlUpdateStrategy = opts.urlUpdateStrategy;
5080
+ }
5081
+ if (opts.canceledNavigationResolution) {
5082
+ router.canceledNavigationResolution = opts.canceledNavigationResolution;
5083
+ }
5084
+ }
4704
5085
  function setupRouter() {
4705
5086
  var _a, _b;
4706
5087
  const urlSerializer = inject(UrlSerializer);
@@ -4710,18 +5091,7 @@ function setupRouter() {
4710
5091
  const compiler = inject(Compiler);
4711
5092
  const config = (_a = inject(ROUTES, { optional: true })) !== null && _a !== void 0 ? _a : [];
4712
5093
  const opts = (_b = inject(ROUTER_CONFIGURATION, { optional: true })) !== null && _b !== void 0 ? _b : {};
4713
- const defaultTitleStrategy = inject(DefaultTitleStrategy);
4714
- const titleStrategy = inject(TitleStrategy, { optional: true });
4715
- const urlHandlingStrategy = inject(UrlHandlingStrategy, { optional: true });
4716
- const routeReuseStrategy = inject(RouteReuseStrategy, { optional: true });
4717
5094
  const router = new Router(null, urlSerializer, contexts, location, injector, compiler, flatten(config));
4718
- if (urlHandlingStrategy) {
4719
- router.urlHandlingStrategy = urlHandlingStrategy;
4720
- }
4721
- if (routeReuseStrategy) {
4722
- router.routeReuseStrategy = routeReuseStrategy;
4723
- }
4724
- router.titleStrategy = titleStrategy !== null && titleStrategy !== void 0 ? titleStrategy : defaultTitleStrategy;
4725
5095
  assignExtraOptionsToRouter(opts, router);
4726
5096
  return router;
4727
5097
  }
@@ -4742,16 +5112,15 @@ class Router {
4742
5112
  * Creates the router service.
4743
5113
  */
4744
5114
  // TODO: vsavkin make internal after the final is out.
4745
- constructor(rootComponentType, urlSerializer, rootContexts, location, injector, compiler, config) {
5115
+ constructor(
5116
+ /** @internal */
5117
+ rootComponentType, urlSerializer, rootContexts, location, injector, compiler, config) {
4746
5118
  this.rootComponentType = rootComponentType;
4747
5119
  this.urlSerializer = urlSerializer;
4748
5120
  this.rootContexts = rootContexts;
4749
5121
  this.location = location;
4750
5122
  this.config = config;
4751
- this.lastSuccessfulNavigation = null;
4752
- this.currentNavigation = null;
4753
5123
  this.disposed = false;
4754
- this.navigationId = 0;
4755
5124
  /**
4756
5125
  * The id of the currently active page in the router.
4757
5126
  * Updated to the transition's target id on a successful navigation.
@@ -4762,10 +5131,6 @@ class Router {
4762
5131
  */
4763
5132
  this.currentPageId = 0;
4764
5133
  this.isNgZoneEnabled = false;
4765
- /**
4766
- * An event stream for routing events in this NgModule.
4767
- */
4768
- this.events = new Subject();
4769
5134
  /**
4770
5135
  * A handler for navigation errors in this NgModule.
4771
5136
  */
@@ -4794,11 +5159,15 @@ class Router {
4794
5159
  * A strategy for extracting and merging URLs.
4795
5160
  * Used for AngularJS to Angular migrations.
4796
5161
  */
4797
- this.urlHandlingStrategy = new DefaultUrlHandlingStrategy();
5162
+ this.urlHandlingStrategy = inject(UrlHandlingStrategy);
4798
5163
  /**
4799
5164
  * A strategy for re-using routes.
4800
5165
  */
4801
- this.routeReuseStrategy = new DefaultRouteReuseStrategy();
5166
+ this.routeReuseStrategy = inject(RouteReuseStrategy);
5167
+ /**
5168
+ * A strategy for setting the title based on the `routerState`.
5169
+ */
5170
+ this.titleStrategy = inject(TitleStrategy);
4802
5171
  /**
4803
5172
  * How to handle a navigation request to the current URL. One of:
4804
5173
  *
@@ -4849,48 +5218,31 @@ class Router {
4849
5218
  * Note: the 'computed' option is incompatible with any `UrlHandlingStrategy` which only
4850
5219
  * handles a portion of the URL because the history restoration navigates to the previous place in
4851
5220
  * the browser history rather than simply resetting a portion of the URL.
4852
- *
4853
- * The default value is `replace`.
4854
- *
4855
- */
4856
- this.canceledNavigationResolution = 'replace';
4857
- const onLoadStart = (r) => this.triggerEvent(new RouteConfigLoadStart(r));
4858
- const onLoadEnd = (r) => this.triggerEvent(new RouteConfigLoadEnd(r));
4859
- this.configLoader = injector.get(RouterConfigLoader);
4860
- this.configLoader.onLoadEndListener = onLoadEnd;
4861
- this.configLoader.onLoadStartListener = onLoadStart;
4862
- this.ngModule = injector.get(NgModuleRef);
4863
- this.console = injector.get(ɵConsole);
4864
- const ngZone = injector.get(NgZone);
4865
- this.isNgZoneEnabled = ngZone instanceof NgZone && NgZone.isInAngularZone();
4866
- this.resetConfig(config);
4867
- this.currentUrlTree = new UrlTree();
4868
- this.rawUrlTree = this.currentUrlTree;
4869
- this.browserUrlTree = this.currentUrlTree;
4870
- this.routerState = createEmptyState(this.currentUrlTree, this.rootComponentType);
4871
- this.transitions = new BehaviorSubject({
4872
- id: 0,
4873
- targetPageId: 0,
4874
- currentUrlTree: this.currentUrlTree,
4875
- currentRawUrl: this.currentUrlTree,
4876
- extractedUrl: this.urlHandlingStrategy.extract(this.currentUrlTree),
4877
- urlAfterRedirects: this.urlHandlingStrategy.extract(this.currentUrlTree),
4878
- rawUrl: this.currentUrlTree,
4879
- extras: {},
4880
- resolve: null,
4881
- reject: null,
4882
- promise: Promise.resolve(true),
4883
- source: 'imperative',
4884
- restoredState: null,
4885
- currentSnapshot: this.routerState.snapshot,
4886
- targetSnapshot: null,
4887
- currentRouterState: this.routerState,
4888
- targetRouterState: null,
4889
- guards: { canActivateChecks: [], canDeactivateChecks: [] },
4890
- guardsResult: null,
5221
+ *
5222
+ * The default value is `replace`.
5223
+ *
5224
+ */
5225
+ this.canceledNavigationResolution = 'replace';
5226
+ this.navigationTransitions = inject(NavigationTransitions);
5227
+ this.console = injector.get(ɵConsole);
5228
+ const ngZone = injector.get(NgZone);
5229
+ this.isNgZoneEnabled = ngZone instanceof NgZone && NgZone.isInAngularZone();
5230
+ this.resetConfig(config);
5231
+ this.currentUrlTree = new UrlTree();
5232
+ this.rawUrlTree = this.currentUrlTree;
5233
+ this.browserUrlTree = this.currentUrlTree;
5234
+ this.routerState = createEmptyState(this.currentUrlTree, this.rootComponentType);
5235
+ this.navigationTransitions.setupNavigations(this).subscribe(t => {
5236
+ this.lastSuccessfulId = t.id;
5237
+ this.currentPageId = t.targetPageId;
5238
+ }, e => {
5239
+ this.console.warn(`Unhandled Navigation Error: ${e}`);
4891
5240
  });
4892
- this.navigations = this.setupNavigations(this.transitions);
4893
- this.processNavigations();
5241
+ }
5242
+ // TODO(b/260747083): This should not exist and navigationId should be private in
5243
+ // `NavigationTransitions`
5244
+ get navigationId() {
5245
+ return this.navigationTransitions.navigationId;
4894
5246
  }
4895
5247
  /**
4896
5248
  * The ɵrouterPageId of whatever page is currently active in the browser history. This is
@@ -4901,281 +5253,15 @@ class Router {
4901
5253
  var _a;
4902
5254
  return (_a = this.location.getState()) === null || _a === void 0 ? void 0 : _a.ɵrouterPageId;
4903
5255
  }
4904
- setupNavigations(transitions) {
4905
- const eventsSubject = this.events;
4906
- return transitions.pipe(filter(t => t.id !== 0),
4907
- // Extract URL
4908
- map(t => (Object.assign(Object.assign({}, t), { extractedUrl: this.urlHandlingStrategy.extract(t.rawUrl) }))),
4909
- // Using switchMap so we cancel executing navigations when a new one comes in
4910
- switchMap(overallTransitionState => {
4911
- let completed = false;
4912
- let errored = false;
4913
- return of(overallTransitionState)
4914
- .pipe(
4915
- // Store the Navigation object
4916
- tap(t => {
4917
- this.currentNavigation = {
4918
- id: t.id,
4919
- initialUrl: t.rawUrl,
4920
- extractedUrl: t.extractedUrl,
4921
- trigger: t.source,
4922
- extras: t.extras,
4923
- previousNavigation: this.lastSuccessfulNavigation ? Object.assign(Object.assign({}, this.lastSuccessfulNavigation), { previousNavigation: null }) :
4924
- null
4925
- };
4926
- }), switchMap(t => {
4927
- const browserUrlTree = this.browserUrlTree.toString();
4928
- const urlTransition = !this.navigated ||
4929
- t.extractedUrl.toString() !== browserUrlTree ||
4930
- // Navigations which succeed or ones which fail and are cleaned up
4931
- // correctly should result in `browserUrlTree` and `currentUrlTree`
4932
- // matching. If this is not the case, assume something went wrong and
4933
- // try processing the URL again.
4934
- browserUrlTree !== this.currentUrlTree.toString();
4935
- const processCurrentUrl = (this.onSameUrlNavigation === 'reload' ? true : urlTransition) &&
4936
- this.urlHandlingStrategy.shouldProcessUrl(t.rawUrl);
4937
- if (processCurrentUrl) {
4938
- // If the source of the navigation is from a browser event, the URL is
4939
- // already updated. We already need to sync the internal state.
4940
- if (isBrowserTriggeredNavigation(t.source)) {
4941
- this.browserUrlTree = t.extractedUrl;
4942
- }
4943
- return of(t).pipe(
4944
- // Fire NavigationStart event
4945
- switchMap(t => {
4946
- const transition = this.transitions.getValue();
4947
- eventsSubject.next(new NavigationStart(t.id, this.serializeUrl(t.extractedUrl), t.source, t.restoredState));
4948
- if (transition !== this.transitions.getValue()) {
4949
- return EMPTY;
4950
- }
4951
- // This delay is required to match old behavior that forced
4952
- // navigation to always be async
4953
- return Promise.resolve(t);
4954
- }),
4955
- // ApplyRedirects
4956
- applyRedirects(this.ngModule.injector, this.configLoader, this.urlSerializer, this.config),
4957
- // Update the currentNavigation
4958
- // `urlAfterRedirects` is guaranteed to be set after this point
4959
- tap(t => {
4960
- this.currentNavigation = Object.assign(Object.assign({}, this.currentNavigation), { finalUrl: t.urlAfterRedirects });
4961
- overallTransitionState.urlAfterRedirects = t.urlAfterRedirects;
4962
- }),
4963
- // Recognize
4964
- recognize(this.ngModule.injector, this.rootComponentType, this.config, this.urlSerializer, this.paramsInheritanceStrategy),
4965
- // Update URL if in `eager` update mode
4966
- tap(t => {
4967
- overallTransitionState.targetSnapshot = t.targetSnapshot;
4968
- if (this.urlUpdateStrategy === 'eager') {
4969
- if (!t.extras.skipLocationChange) {
4970
- const rawUrl = this.urlHandlingStrategy.merge(t.urlAfterRedirects, t.rawUrl);
4971
- this.setBrowserUrl(rawUrl, t);
4972
- }
4973
- this.browserUrlTree = t.urlAfterRedirects;
4974
- }
4975
- // Fire RoutesRecognized
4976
- const routesRecognized = new RoutesRecognized(t.id, this.serializeUrl(t.extractedUrl), this.serializeUrl(t.urlAfterRedirects), t.targetSnapshot);
4977
- eventsSubject.next(routesRecognized);
4978
- }));
4979
- }
4980
- else {
4981
- const processPreviousUrl = urlTransition && this.rawUrlTree &&
4982
- this.urlHandlingStrategy.shouldProcessUrl(this.rawUrlTree);
4983
- /* When the current URL shouldn't be processed, but the previous one
4984
- * was, we handle this "error condition" by navigating to the
4985
- * previously successful URL, but leaving the URL intact.*/
4986
- if (processPreviousUrl) {
4987
- const { id, extractedUrl, source, restoredState, extras } = t;
4988
- const navStart = new NavigationStart(id, this.serializeUrl(extractedUrl), source, restoredState);
4989
- eventsSubject.next(navStart);
4990
- const targetSnapshot = createEmptyState(extractedUrl, this.rootComponentType).snapshot;
4991
- overallTransitionState = Object.assign(Object.assign({}, t), { targetSnapshot, urlAfterRedirects: extractedUrl, extras: Object.assign(Object.assign({}, extras), { skipLocationChange: false, replaceUrl: false }) });
4992
- return of(overallTransitionState);
4993
- }
4994
- else {
4995
- /* When neither the current or previous URL can be processed, do
4996
- * nothing other than update router's internal reference to the
4997
- * current "settled" URL. This way the next navigation will be coming
4998
- * from the current URL in the browser.
4999
- */
5000
- this.rawUrlTree = t.rawUrl;
5001
- t.resolve(null);
5002
- return EMPTY;
5003
- }
5004
- }
5005
- }),
5006
- // --- GUARDS ---
5007
- tap(t => {
5008
- const guardsStart = new GuardsCheckStart(t.id, this.serializeUrl(t.extractedUrl), this.serializeUrl(t.urlAfterRedirects), t.targetSnapshot);
5009
- this.triggerEvent(guardsStart);
5010
- }), map(t => {
5011
- overallTransitionState = Object.assign(Object.assign({}, t), { guards: getAllRouteGuards(t.targetSnapshot, t.currentSnapshot, this.rootContexts) });
5012
- return overallTransitionState;
5013
- }), checkGuards(this.ngModule.injector, (evt) => this.triggerEvent(evt)), tap(t => {
5014
- overallTransitionState.guardsResult = t.guardsResult;
5015
- if (isUrlTree(t.guardsResult)) {
5016
- throw redirectingNavigationError(this.urlSerializer, t.guardsResult);
5017
- }
5018
- const guardsEnd = new GuardsCheckEnd(t.id, this.serializeUrl(t.extractedUrl), this.serializeUrl(t.urlAfterRedirects), t.targetSnapshot, !!t.guardsResult);
5019
- this.triggerEvent(guardsEnd);
5020
- }), filter(t => {
5021
- if (!t.guardsResult) {
5022
- this.restoreHistory(t);
5023
- this.cancelNavigationTransition(t, '', 3 /* NavigationCancellationCode.GuardRejected */);
5024
- return false;
5025
- }
5026
- return true;
5027
- }),
5028
- // --- RESOLVE ---
5029
- switchTap(t => {
5030
- if (t.guards.canActivateChecks.length) {
5031
- return of(t).pipe(tap(t => {
5032
- const resolveStart = new ResolveStart(t.id, this.serializeUrl(t.extractedUrl), this.serializeUrl(t.urlAfterRedirects), t.targetSnapshot);
5033
- this.triggerEvent(resolveStart);
5034
- }), switchMap(t => {
5035
- let dataResolved = false;
5036
- return of(t).pipe(resolveData(this.paramsInheritanceStrategy, this.ngModule.injector), tap({
5037
- next: () => dataResolved = true,
5038
- complete: () => {
5039
- if (!dataResolved) {
5040
- this.restoreHistory(t);
5041
- this.cancelNavigationTransition(t, NG_DEV_MODE$2 ?
5042
- `At least one route resolver didn't emit any value.` :
5043
- '', 2 /* NavigationCancellationCode.NoDataFromResolver */);
5044
- }
5045
- }
5046
- }));
5047
- }), tap(t => {
5048
- const resolveEnd = new ResolveEnd(t.id, this.serializeUrl(t.extractedUrl), this.serializeUrl(t.urlAfterRedirects), t.targetSnapshot);
5049
- this.triggerEvent(resolveEnd);
5050
- }));
5051
- }
5052
- return undefined;
5053
- }),
5054
- // --- LOAD COMPONENTS ---
5055
- switchTap((t) => {
5056
- const loadComponents = (route) => {
5057
- var _a;
5058
- const loaders = [];
5059
- if (((_a = route.routeConfig) === null || _a === void 0 ? void 0 : _a.loadComponent) &&
5060
- !route.routeConfig._loadedComponent) {
5061
- loaders.push(this.configLoader.loadComponent(route.routeConfig)
5062
- .pipe(tap(loadedComponent => {
5063
- route.component = loadedComponent;
5064
- }), map(() => void 0)));
5065
- }
5066
- for (const child of route.children) {
5067
- loaders.push(...loadComponents(child));
5068
- }
5069
- return loaders;
5070
- };
5071
- return combineLatest(loadComponents(t.targetSnapshot.root))
5072
- .pipe(defaultIfEmpty(), take(1));
5073
- }), switchTap(() => this.afterPreactivation()), map((t) => {
5074
- const targetRouterState = createRouterState(this.routeReuseStrategy, t.targetSnapshot, t.currentRouterState);
5075
- overallTransitionState = Object.assign(Object.assign({}, t), { targetRouterState });
5076
- return (overallTransitionState);
5077
- }),
5078
- /* Once here, we are about to activate synchronously. The assumption is
5079
- this will succeed, and user code may read from the Router service.
5080
- Therefore before activation, we need to update router properties storing
5081
- the current URL and the RouterState, as well as updated the browser URL.
5082
- All this should happen *before* activating. */
5083
- tap((t) => {
5084
- this.currentUrlTree = t.urlAfterRedirects;
5085
- this.rawUrlTree =
5086
- this.urlHandlingStrategy.merge(t.urlAfterRedirects, t.rawUrl);
5087
- this.routerState = t.targetRouterState;
5088
- if (this.urlUpdateStrategy === 'deferred') {
5089
- if (!t.extras.skipLocationChange) {
5090
- this.setBrowserUrl(this.rawUrlTree, t);
5091
- }
5092
- this.browserUrlTree = t.urlAfterRedirects;
5093
- }
5094
- }), activateRoutes(this.rootContexts, this.routeReuseStrategy, (evt) => this.triggerEvent(evt)), tap({
5095
- next() {
5096
- completed = true;
5097
- },
5098
- complete() {
5099
- completed = true;
5100
- }
5101
- }), finalize(() => {
5102
- var _a;
5103
- /* When the navigation stream finishes either through error or success,
5104
- * we set the `completed` or `errored` flag. However, there are some
5105
- * situations where we could get here without either of those being set.
5106
- * For instance, a redirect during NavigationStart. Therefore, this is a
5107
- * catch-all to make sure the NavigationCancel event is fired when a
5108
- * navigation gets cancelled but not caught by other means. */
5109
- if (!completed && !errored) {
5110
- const cancelationReason = NG_DEV_MODE$2 ?
5111
- `Navigation ID ${overallTransitionState
5112
- .id} is not equal to the current navigation id ${this.navigationId}` :
5113
- '';
5114
- this.cancelNavigationTransition(overallTransitionState, cancelationReason, 1 /* NavigationCancellationCode.SupersededByNewNavigation */);
5115
- }
5116
- // Only clear current navigation if it is still set to the one that
5117
- // finalized.
5118
- if (((_a = this.currentNavigation) === null || _a === void 0 ? void 0 : _a.id) === overallTransitionState.id) {
5119
- this.currentNavigation = null;
5120
- }
5121
- }), catchError((e) => {
5122
- var _a;
5123
- errored = true;
5124
- /* This error type is issued during Redirect, and is handled as a
5125
- * cancellation rather than an error. */
5126
- if (isNavigationCancelingError$1(e)) {
5127
- if (!isRedirectingNavigationCancelingError$1(e)) {
5128
- // Set property only if we're not redirecting. If we landed on a page
5129
- // and redirect to `/` route, the new navigation is going to see the
5130
- // `/` isn't a change from the default currentUrlTree and won't
5131
- // navigate. This is only applicable with initial navigation, so
5132
- // setting `navigated` only when not redirecting resolves this
5133
- // scenario.
5134
- this.navigated = true;
5135
- this.restoreHistory(overallTransitionState, true);
5136
- }
5137
- const navCancel = new NavigationCancel(overallTransitionState.id, this.serializeUrl(overallTransitionState.extractedUrl), e.message, e.cancellationCode);
5138
- eventsSubject.next(navCancel);
5139
- // When redirecting, we need to delay resolving the navigation
5140
- // promise and push it to the redirect navigation
5141
- if (!isRedirectingNavigationCancelingError$1(e)) {
5142
- overallTransitionState.resolve(false);
5143
- }
5144
- else {
5145
- const mergedTree = this.urlHandlingStrategy.merge(e.url, this.rawUrlTree);
5146
- const extras = {
5147
- skipLocationChange: overallTransitionState.extras.skipLocationChange,
5148
- // The URL is already updated at this point if we have 'eager' URL
5149
- // updates or if the navigation was triggered by the browser (back
5150
- // button, URL bar, etc). We want to replace that item in history
5151
- // if the navigation is rejected.
5152
- replaceUrl: this.urlUpdateStrategy === 'eager' ||
5153
- isBrowserTriggeredNavigation(overallTransitionState.source)
5154
- };
5155
- this.scheduleNavigation(mergedTree, 'imperative', null, extras, {
5156
- resolve: overallTransitionState.resolve,
5157
- reject: overallTransitionState.reject,
5158
- promise: overallTransitionState.promise
5159
- });
5160
- }
5161
- /* All other errors should reset to the router's internal URL reference
5162
- * to the pre-error state. */
5163
- }
5164
- else {
5165
- this.restoreHistory(overallTransitionState, true);
5166
- const navError = new NavigationError(overallTransitionState.id, this.serializeUrl(overallTransitionState.extractedUrl), e, (_a = overallTransitionState.targetSnapshot) !== null && _a !== void 0 ? _a : undefined);
5167
- eventsSubject.next(navError);
5168
- try {
5169
- overallTransitionState.resolve(this.errorHandler(e));
5170
- }
5171
- catch (ee) {
5172
- overallTransitionState.reject(ee);
5173
- }
5174
- }
5175
- return EMPTY;
5176
- }));
5177
- // TODO(jasonaden): remove cast once g3 is on updated TypeScript
5178
- }));
5256
+ /**
5257
+ * An event stream for routing events.
5258
+ */
5259
+ get events() {
5260
+ // TODO(atscott): This _should_ be events.asObservable(). However, this change requires internal
5261
+ // cleanup: tests are doing `(route.events as Subject<Event>).next(...)`. This isn't
5262
+ // allowed/supported but we still have to fix these or file bugs against the teams before making
5263
+ // the change.
5264
+ return this.navigationTransitions.events;
5179
5265
  }
5180
5266
  /**
5181
5267
  * @internal
@@ -5187,15 +5273,12 @@ class Router {
5187
5273
  // this will simplify the lifecycle of the router.
5188
5274
  this.routerState.root.component = this.rootComponentType;
5189
5275
  }
5190
- setTransition(t) {
5191
- this.transitions.next(Object.assign(Object.assign({}, this.transitions.value), t));
5192
- }
5193
5276
  /**
5194
5277
  * Sets up the location change listener and performs the initial navigation.
5195
5278
  */
5196
5279
  initialNavigation() {
5197
5280
  this.setUpLocationChangeListener();
5198
- if (this.navigationId === 0) {
5281
+ if (!this.navigationTransitions.hasRequestedNavigation) {
5199
5282
  this.navigateByUrl(this.location.path(true), { replaceUrl: true });
5200
5283
  }
5201
5284
  }
@@ -5217,11 +5300,18 @@ class Router {
5217
5300
  setTimeout(() => {
5218
5301
  var _a;
5219
5302
  const extras = { replaceUrl: true };
5220
- // Navigations coming from Angular router have a navigationId state
5221
- // property. When this exists, restore the state.
5222
- const state = ((_a = event.state) === null || _a === void 0 ? void 0 : _a.navigationId) ? event.state : null;
5223
- if (state) {
5224
- const stateCopy = Object.assign({}, state);
5303
+ // TODO: restoredState should always include the entire state, regardless
5304
+ // of navigationId. This requires a breaking change to update the type on
5305
+ // NavigationStart’s restoredState, which currently requires navigationId
5306
+ // to always be present. The Router used to only restore history state if
5307
+ // a navigationId was present.
5308
+ // The stored navigationId is used by the RouterScroller to retrieve the scroll
5309
+ // position for the page.
5310
+ const restoredState = ((_a = event.state) === null || _a === void 0 ? void 0 : _a.navigationId) ? event.state : null;
5311
+ // Separate to NavigationStart.restoredState, we must also restore the state to
5312
+ // history.state and generate a new navigationId, since it will be overwritten
5313
+ if (event.state) {
5314
+ const stateCopy = Object.assign({}, event.state);
5225
5315
  delete stateCopy.navigationId;
5226
5316
  delete stateCopy.ɵrouterPageId;
5227
5317
  if (Object.keys(stateCopy).length !== 0) {
@@ -5229,7 +5319,7 @@ class Router {
5229
5319
  }
5230
5320
  }
5231
5321
  const urlTree = this.parseUrl(event['url']);
5232
- this.scheduleNavigation(urlTree, source, state, extras);
5322
+ this.scheduleNavigation(urlTree, source, restoredState, extras);
5233
5323
  }, 0);
5234
5324
  }
5235
5325
  });
@@ -5244,11 +5334,7 @@ class Router {
5244
5334
  * and `null` when idle.
5245
5335
  */
5246
5336
  getCurrentNavigation() {
5247
- return this.currentNavigation;
5248
- }
5249
- /** @internal */
5250
- triggerEvent(event) {
5251
- this.events.next(event);
5337
+ return this.navigationTransitions.currentNavigation;
5252
5338
  }
5253
5339
  /**
5254
5340
  * Resets the route configuration used for navigation and generating links.
@@ -5278,7 +5364,7 @@ class Router {
5278
5364
  }
5279
5365
  /** Disposes of the router. */
5280
5366
  dispose() {
5281
- this.transitions.complete();
5367
+ this.navigationTransitions.complete();
5282
5368
  if (this.locationSubscription) {
5283
5369
  this.locationSubscription.unsubscribe();
5284
5370
  this.locationSubscription = undefined;
@@ -5463,21 +5549,7 @@ class Router {
5463
5549
  return result;
5464
5550
  }, {});
5465
5551
  }
5466
- processNavigations() {
5467
- this.navigations.subscribe(t => {
5468
- var _a;
5469
- this.navigated = true;
5470
- this.lastSuccessfulId = t.id;
5471
- this.currentPageId = t.targetPageId;
5472
- this.events
5473
- .next(new NavigationEnd(t.id, this.serializeUrl(t.extractedUrl), this.serializeUrl(this.currentUrlTree)));
5474
- this.lastSuccessfulNavigation = this.currentNavigation;
5475
- (_a = this.titleStrategy) === null || _a === void 0 ? void 0 : _a.updateTitle(this.routerState.snapshot);
5476
- t.resolve(true);
5477
- }, e => {
5478
- this.console.warn(`Unhandled Navigation Error: ${e}`);
5479
- });
5480
- }
5552
+ /** @internal */
5481
5553
  scheduleNavigation(rawUrl, source, restoredState, extras, priorPromise) {
5482
5554
  var _a, _b;
5483
5555
  if (this.disposed) {
@@ -5497,7 +5569,6 @@ class Router {
5497
5569
  reject = rej;
5498
5570
  });
5499
5571
  }
5500
- const id = ++this.navigationId;
5501
5572
  let targetPageId;
5502
5573
  if (this.canceledNavigationResolution === 'computed') {
5503
5574
  const isInitialPage = this.currentPageId === 0;
@@ -5525,13 +5596,12 @@ class Router {
5525
5596
  // This is unused when `canceledNavigationResolution` is not computed.
5526
5597
  targetPageId = 0;
5527
5598
  }
5528
- this.setTransition({
5529
- id,
5599
+ this.navigationTransitions.handleNavigationRequest({
5530
5600
  targetPageId,
5531
5601
  source,
5532
5602
  restoredState,
5533
5603
  currentUrlTree: this.currentUrlTree,
5534
- currentRawUrl: this.rawUrlTree,
5604
+ currentRawUrl: this.currentUrlTree,
5535
5605
  rawUrl,
5536
5606
  extras,
5537
5607
  resolve,
@@ -5546,10 +5616,11 @@ class Router {
5546
5616
  return Promise.reject(e);
5547
5617
  });
5548
5618
  }
5549
- setBrowserUrl(url, t) {
5619
+ /** @internal */
5620
+ setBrowserUrl(url, transition) {
5550
5621
  const path = this.urlSerializer.serialize(url);
5551
- const state = Object.assign(Object.assign({}, t.extras.state), this.generateNgRouterState(t.id, t.targetPageId));
5552
- if (this.location.isCurrentPathEqualTo(path) || !!t.extras.replaceUrl) {
5622
+ const state = Object.assign(Object.assign({}, transition.extras.state), this.generateNgRouterState(transition.id, transition.targetPageId));
5623
+ if (this.location.isCurrentPathEqualTo(path) || !!transition.extras.replaceUrl) {
5553
5624
  this.location.replaceState(path, '', state);
5554
5625
  }
5555
5626
  else {
@@ -5559,29 +5630,31 @@ class Router {
5559
5630
  /**
5560
5631
  * Performs the necessary rollback action to restore the browser URL to the
5561
5632
  * state before the transition.
5633
+ * @internal
5562
5634
  */
5563
- restoreHistory(t, restoringFromCaughtError = false) {
5635
+ restoreHistory(transition, restoringFromCaughtError = false) {
5564
5636
  var _a, _b;
5565
5637
  if (this.canceledNavigationResolution === 'computed') {
5566
- const targetPagePosition = this.currentPageId - t.targetPageId;
5638
+ const targetPagePosition = this.currentPageId - transition.targetPageId;
5567
5639
  // The navigator change the location before triggered the browser event,
5568
5640
  // so we need to go back to the current url if the navigation is canceled.
5569
5641
  // Also, when navigation gets cancelled while using url update strategy eager, then we need to
5570
5642
  // go back. Because, when `urlUpdateStrategy` is `eager`; `setBrowserUrl` method is called
5571
5643
  // before any verification.
5572
- const browserUrlUpdateOccurred = (t.source === 'popstate' || this.urlUpdateStrategy === 'eager' ||
5573
- this.currentUrlTree === ((_a = this.currentNavigation) === null || _a === void 0 ? void 0 : _a.finalUrl));
5644
+ const browserUrlUpdateOccurred = (transition.source === 'popstate' || this.urlUpdateStrategy === 'eager' ||
5645
+ this.currentUrlTree === ((_a = this.getCurrentNavigation()) === null || _a === void 0 ? void 0 : _a.finalUrl));
5574
5646
  if (browserUrlUpdateOccurred && targetPagePosition !== 0) {
5575
5647
  this.location.historyGo(targetPagePosition);
5576
5648
  }
5577
- else if (this.currentUrlTree === ((_b = this.currentNavigation) === null || _b === void 0 ? void 0 : _b.finalUrl) && targetPagePosition === 0) {
5649
+ else if (this.currentUrlTree === ((_b = this.getCurrentNavigation()) === null || _b === void 0 ? void 0 : _b.finalUrl) &&
5650
+ targetPagePosition === 0) {
5578
5651
  // We got to the activation stage (where currentUrlTree is set to the navigation's
5579
5652
  // finalUrl), but we weren't moving anywhere in history (skipLocationChange or replaceUrl).
5580
5653
  // We still need to reset the router state back to what it was when the navigation started.
5581
- this.resetState(t);
5654
+ this.resetState(transition);
5582
5655
  // TODO(atscott): resetting the `browserUrlTree` should really be done in `resetState`.
5583
5656
  // Investigate if this can be done by running TGP.
5584
- this.browserUrlTree = t.currentUrlTree;
5657
+ this.browserUrlTree = transition.currentUrlTree;
5585
5658
  this.resetUrlToCurrentUrlTree();
5586
5659
  }
5587
5660
  else {
@@ -5595,7 +5668,7 @@ class Router {
5595
5668
  // reject. For 'eager' navigations, it seems like we also really should reset the state
5596
5669
  // because the navigation was cancelled. Investigate if this can be done by running TGP.
5597
5670
  if (restoringFromCaughtError) {
5598
- this.resetState(t);
5671
+ this.resetState(transition);
5599
5672
  }
5600
5673
  this.resetUrlToCurrentUrlTree();
5601
5674
  }
@@ -5613,11 +5686,6 @@ class Router {
5613
5686
  resetUrlToCurrentUrlTree() {
5614
5687
  this.location.replaceState(this.urlSerializer.serialize(this.rawUrlTree), '', this.generateNgRouterState(this.lastSuccessfulId, this.currentPageId));
5615
5688
  }
5616
- cancelNavigationTransition(t, reason, code) {
5617
- const navCancel = new NavigationCancel(t.id, this.serializeUrl(t.extractedUrl), reason, code);
5618
- this.triggerEvent(navCancel);
5619
- t.resolve(false);
5620
- }
5621
5689
  generateNgRouterState(navigationId, routerPageId) {
5622
5690
  if (this.canceledNavigationResolution === 'computed') {
5623
5691
  return { navigationId, ɵrouterPageId: routerPageId };
@@ -5625,9 +5693,9 @@ class Router {
5625
5693
  return { navigationId };
5626
5694
  }
5627
5695
  }
5628
- Router.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: Router, deps: "invalid", target: i0.ɵɵFactoryTarget.Injectable });
5629
- Router.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: Router, providedIn: 'root', useFactory: setupRouter });
5630
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: Router, decorators: [{
5696
+ Router.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.2", ngImport: i0, type: Router, deps: "invalid", target: i0.ɵɵFactoryTarget.Injectable });
5697
+ Router.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.0.2", ngImport: i0, type: Router, providedIn: 'root', useFactory: setupRouter });
5698
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.2", ngImport: i0, type: Router, decorators: [{
5631
5699
  type: Injectable,
5632
5700
  args: [{
5633
5701
  providedIn: 'root',
@@ -5642,9 +5710,6 @@ function validateCommands(commands) {
5642
5710
  }
5643
5711
  }
5644
5712
  }
5645
- function isBrowserTriggeredNavigation(source) {
5646
- return source !== 'imperative';
5647
- }
5648
5713
 
5649
5714
  /**
5650
5715
  * @description
@@ -5921,9 +5986,9 @@ class RouterLink {
5921
5986
  });
5922
5987
  }
5923
5988
  }
5924
- RouterLink.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.0", 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 });
5925
- RouterLink.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.0.0", type: RouterLink, isStandalone: true, selector: "[routerLink]", inputs: { target: "target", queryParams: "queryParams", fragment: "fragment", queryParamsHandling: "queryParamsHandling", state: "state", relativeTo: "relativeTo", preserveFragment: "preserveFragment", skipLocationChange: "skipLocationChange", replaceUrl: "replaceUrl", 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 });
5926
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: RouterLink, decorators: [{
5989
+ RouterLink.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.2", 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 });
5990
+ RouterLink.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.0.2", type: RouterLink, isStandalone: true, selector: "[routerLink]", inputs: { target: "target", queryParams: "queryParams", fragment: "fragment", queryParamsHandling: "queryParamsHandling", state: "state", relativeTo: "relativeTo", preserveFragment: "preserveFragment", skipLocationChange: "skipLocationChange", replaceUrl: "replaceUrl", 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 });
5991
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.2", ngImport: i0, type: RouterLink, decorators: [{
5927
5992
  type: Directive,
5928
5993
  args: [{
5929
5994
  selector: '[routerLink]',
@@ -6152,9 +6217,9 @@ class RouterLinkActive {
6152
6217
  return this.link && isActiveCheckFn(this.link) || this.links.some(isActiveCheckFn);
6153
6218
  }
6154
6219
  }
6155
- RouterLinkActive.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: RouterLinkActive, deps: [{ token: Router }, { token: i0.ElementRef }, { token: i0.Renderer2 }, { token: i0.ChangeDetectorRef }, { token: RouterLink, optional: true }], target: i0.ɵɵFactoryTarget.Directive });
6156
- RouterLinkActive.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.0.0", 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 });
6157
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: RouterLinkActive, decorators: [{
6220
+ RouterLinkActive.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.2", ngImport: i0, type: RouterLinkActive, deps: [{ token: Router }, { token: i0.ElementRef }, { token: i0.Renderer2 }, { token: i0.ChangeDetectorRef }, { token: RouterLink, optional: true }], target: i0.ɵɵFactoryTarget.Directive });
6221
+ RouterLinkActive.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.0.2", 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 });
6222
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.2", ngImport: i0, type: RouterLinkActive, decorators: [{
6158
6223
  type: Directive,
6159
6224
  args: [{
6160
6225
  selector: '[routerLinkActive]',
@@ -6216,9 +6281,9 @@ class PreloadAllModules {
6216
6281
  return fn().pipe(catchError(() => of(null)));
6217
6282
  }
6218
6283
  }
6219
- PreloadAllModules.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: PreloadAllModules, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
6220
- PreloadAllModules.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: PreloadAllModules, providedIn: 'root' });
6221
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: PreloadAllModules, decorators: [{
6284
+ PreloadAllModules.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.2", ngImport: i0, type: PreloadAllModules, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
6285
+ PreloadAllModules.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.0.2", ngImport: i0, type: PreloadAllModules, providedIn: 'root' });
6286
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.2", ngImport: i0, type: PreloadAllModules, decorators: [{
6222
6287
  type: Injectable,
6223
6288
  args: [{ providedIn: 'root' }]
6224
6289
  }] });
@@ -6236,9 +6301,9 @@ class NoPreloading {
6236
6301
  return of(null);
6237
6302
  }
6238
6303
  }
6239
- NoPreloading.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: NoPreloading, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
6240
- NoPreloading.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: NoPreloading, providedIn: 'root' });
6241
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: NoPreloading, decorators: [{
6304
+ NoPreloading.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.2", ngImport: i0, type: NoPreloading, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
6305
+ NoPreloading.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.0.2", ngImport: i0, type: NoPreloading, providedIn: 'root' });
6306
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.2", ngImport: i0, type: NoPreloading, decorators: [{
6242
6307
  type: Injectable,
6243
6308
  args: [{ providedIn: 'root' }]
6244
6309
  }] });
@@ -6334,18 +6399,19 @@ class RouterPreloader {
6334
6399
  });
6335
6400
  }
6336
6401
  }
6337
- RouterPreloader.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: RouterPreloader, deps: [{ token: Router }, { token: i0.Compiler }, { token: i0.EnvironmentInjector }, { token: PreloadingStrategy }, { token: RouterConfigLoader }], target: i0.ɵɵFactoryTarget.Injectable });
6338
- RouterPreloader.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: RouterPreloader, providedIn: 'root' });
6339
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: RouterPreloader, decorators: [{
6402
+ RouterPreloader.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.2", ngImport: i0, type: RouterPreloader, deps: [{ token: Router }, { token: i0.Compiler }, { token: i0.EnvironmentInjector }, { token: PreloadingStrategy }, { token: RouterConfigLoader }], target: i0.ɵɵFactoryTarget.Injectable });
6403
+ RouterPreloader.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.0.2", ngImport: i0, type: RouterPreloader, providedIn: 'root' });
6404
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.2", ngImport: i0, type: RouterPreloader, decorators: [{
6340
6405
  type: Injectable,
6341
6406
  args: [{ providedIn: 'root' }]
6342
6407
  }], ctorParameters: function () { return [{ type: Router }, { type: i0.Compiler }, { type: i0.EnvironmentInjector }, { type: PreloadingStrategy }, { type: RouterConfigLoader }]; } });
6343
6408
 
6344
6409
  const ROUTER_SCROLLER = new InjectionToken('');
6345
6410
  class RouterScroller {
6346
- constructor(router,
6347
- /** @docsNotRequired */ viewportScroller, zone, options = {}) {
6348
- this.router = router;
6411
+ /** @nodoc */
6412
+ constructor(urlSerializer, transitions, viewportScroller, zone, options = {}) {
6413
+ this.urlSerializer = urlSerializer;
6414
+ this.transitions = transitions;
6349
6415
  this.viewportScroller = viewportScroller;
6350
6416
  this.zone = zone;
6351
6417
  this.options = options;
@@ -6368,7 +6434,7 @@ class RouterScroller {
6368
6434
  this.scrollEventsSubscription = this.consumeScrollEvents();
6369
6435
  }
6370
6436
  createScrollEvents() {
6371
- return this.router.events.subscribe(e => {
6437
+ return this.transitions.events.subscribe(e => {
6372
6438
  if (e instanceof NavigationStart) {
6373
6439
  // store the scroll position of the current stable navigations.
6374
6440
  this.store[this.lastId] = this.viewportScroller.getScrollPosition();
@@ -6377,12 +6443,12 @@ class RouterScroller {
6377
6443
  }
6378
6444
  else if (e instanceof NavigationEnd) {
6379
6445
  this.lastId = e.id;
6380
- this.scheduleScrollEvent(e, this.router.parseUrl(e.urlAfterRedirects).fragment);
6446
+ this.scheduleScrollEvent(e, this.urlSerializer.parse(e.urlAfterRedirects).fragment);
6381
6447
  }
6382
6448
  });
6383
6449
  }
6384
6450
  consumeScrollEvents() {
6385
- return this.router.events.subscribe(e => {
6451
+ return this.transitions.events.subscribe(e => {
6386
6452
  if (!(e instanceof Scroll))
6387
6453
  return;
6388
6454
  // a popstate event. The pop state event will always ignore anchor scrolling.
@@ -6412,26 +6478,23 @@ class RouterScroller {
6412
6478
  // component by executing its update block of the template function.
6413
6479
  setTimeout(() => {
6414
6480
  this.zone.run(() => {
6415
- this.router.triggerEvent(new Scroll(routerEvent, this.lastSource === 'popstate' ? this.store[this.restoredId] : null, anchor));
6481
+ this.transitions.events.next(new Scroll(routerEvent, this.lastSource === 'popstate' ? this.store[this.restoredId] : null, anchor));
6416
6482
  });
6417
6483
  }, 0);
6418
6484
  });
6419
6485
  }
6420
6486
  /** @nodoc */
6421
6487
  ngOnDestroy() {
6422
- if (this.routerEventsSubscription) {
6423
- this.routerEventsSubscription.unsubscribe();
6424
- }
6425
- if (this.scrollEventsSubscription) {
6426
- this.scrollEventsSubscription.unsubscribe();
6427
- }
6488
+ var _a, _b;
6489
+ (_a = this.routerEventsSubscription) === null || _a === void 0 ? void 0 : _a.unsubscribe();
6490
+ (_b = this.scrollEventsSubscription) === null || _b === void 0 ? void 0 : _b.unsubscribe();
6428
6491
  }
6429
6492
  }
6430
- RouterScroller.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: RouterScroller, deps: "invalid", target: i0.ɵɵFactoryTarget.Injectable });
6431
- RouterScroller.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: RouterScroller });
6432
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: RouterScroller, decorators: [{
6493
+ RouterScroller.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.2", ngImport: i0, type: RouterScroller, deps: "invalid", target: i0.ɵɵFactoryTarget.Injectable });
6494
+ RouterScroller.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.0.2", ngImport: i0, type: RouterScroller });
6495
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.2", ngImport: i0, type: RouterScroller, decorators: [{
6433
6496
  type: Injectable
6434
- }], ctorParameters: function () { return [{ type: Router }, { type: i3.ViewportScroller }, { type: i0.NgZone }, { type: undefined }]; } });
6497
+ }], ctorParameters: function () { return [{ type: UrlSerializer }, { type: NavigationTransitions }, { type: i3.ViewportScroller }, { type: i0.NgZone }, { type: undefined }]; } });
6435
6498
 
6436
6499
  /**
6437
6500
  * @license
@@ -6568,10 +6631,11 @@ function withInMemoryScrolling(options = {}) {
6568
6631
  const providers = [{
6569
6632
  provide: ROUTER_SCROLLER,
6570
6633
  useFactory: () => {
6571
- const router = inject(Router);
6572
6634
  const viewportScroller = inject(ViewportScroller);
6573
6635
  const zone = inject(NgZone);
6574
- return new RouterScroller(router, viewportScroller, zone, options);
6636
+ const transitions = inject(NavigationTransitions);
6637
+ const urlSerializer = inject(UrlSerializer);
6638
+ return new RouterScroller(urlSerializer, transitions, viewportScroller, zone, options);
6575
6639
  },
6576
6640
  }];
6577
6641
  return routerFeature(4 /* RouterFeatureKind.InMemoryScrollingFeature */, providers);
@@ -6592,8 +6656,10 @@ function getBootstrapListener() {
6592
6656
  (_a = injector.get(ROUTER_PRELOADER, null, InjectFlags.Optional)) === null || _a === void 0 ? void 0 : _a.setUpPreloading();
6593
6657
  (_b = injector.get(ROUTER_SCROLLER, null, InjectFlags.Optional)) === null || _b === void 0 ? void 0 : _b.init();
6594
6658
  router.resetRootComponentType(ref.componentTypes[0]);
6595
- bootstrapDone.next();
6596
- bootstrapDone.complete();
6659
+ if (!bootstrapDone.closed) {
6660
+ bootstrapDone.next();
6661
+ bootstrapDone.unsubscribe();
6662
+ }
6597
6663
  };
6598
6664
  }
6599
6665
  /**
@@ -6641,7 +6707,6 @@ function withEnabledBlockingInitialNavigation() {
6641
6707
  deps: [Injector],
6642
6708
  useFactory: (injector) => {
6643
6709
  const locationInitialized = injector.get(LOCATION_INITIALIZED, Promise.resolve());
6644
- let initNavigation = false;
6645
6710
  /**
6646
6711
  * Performs the given action once the router finishes its next/current navigation.
6647
6712
  *
@@ -6676,21 +6741,13 @@ function withEnabledBlockingInitialNavigation() {
6676
6741
  // Unblock APP_INITIALIZER in case the initial navigation was canceled or errored
6677
6742
  // without a redirect.
6678
6743
  resolve(true);
6679
- initNavigation = true;
6680
6744
  });
6681
6745
  router.afterPreactivation = () => {
6682
6746
  // Unblock APP_INITIALIZER once we get to `afterPreactivation`. At this point, we
6683
6747
  // assume activation will complete successfully (even though this is not
6684
6748
  // guaranteed).
6685
6749
  resolve(true);
6686
- // only the initial navigation should be delayed until bootstrapping is done.
6687
- if (!initNavigation) {
6688
- return bootstrapDone.closed ? of(void 0) : bootstrapDone;
6689
- // subsequent navigations should not be delayed
6690
- }
6691
- else {
6692
- return of(void 0);
6693
- }
6750
+ return bootstrapDone.closed ? of(void 0) : bootstrapDone;
6694
6751
  };
6695
6752
  router.initialNavigation();
6696
6753
  });
@@ -6980,10 +7037,10 @@ class RouterModule {
6980
7037
  };
6981
7038
  }
6982
7039
  }
6983
- RouterModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: RouterModule, deps: [{ token: ROUTER_FORROOT_GUARD, optional: true }], target: i0.ɵɵFactoryTarget.NgModule });
6984
- RouterModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "15.0.0", ngImport: i0, type: RouterModule, imports: [RouterOutlet, RouterLink, RouterLinkActive, ɵEmptyOutletComponent], exports: [RouterOutlet, RouterLink, RouterLinkActive, ɵEmptyOutletComponent] });
6985
- RouterModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: RouterModule, imports: [ɵEmptyOutletComponent] });
6986
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: RouterModule, decorators: [{
7040
+ RouterModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.2", ngImport: i0, type: RouterModule, deps: [{ token: ROUTER_FORROOT_GUARD, optional: true }], target: i0.ɵɵFactoryTarget.NgModule });
7041
+ RouterModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "15.0.2", ngImport: i0, type: RouterModule, imports: [RouterOutlet, RouterLink, RouterLinkActive, ɵEmptyOutletComponent], exports: [RouterOutlet, RouterLink, RouterLinkActive, ɵEmptyOutletComponent] });
7042
+ RouterModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "15.0.2", ngImport: i0, type: RouterModule, imports: [ɵEmptyOutletComponent] });
7043
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.2", ngImport: i0, type: RouterModule, decorators: [{
6987
7044
  type: NgModule,
6988
7045
  args: [{
6989
7046
  imports: ROUTER_DIRECTIVES,
@@ -7005,14 +7062,15 @@ function provideRouterScroller() {
7005
7062
  return {
7006
7063
  provide: ROUTER_SCROLLER,
7007
7064
  useFactory: () => {
7008
- const router = inject(Router);
7009
7065
  const viewportScroller = inject(ViewportScroller);
7010
7066
  const zone = inject(NgZone);
7011
7067
  const config = inject(ROUTER_CONFIGURATION);
7068
+ const transitions = inject(NavigationTransitions);
7069
+ const urlSerializer = inject(UrlSerializer);
7012
7070
  if (config.scrollOffset) {
7013
7071
  viewportScroller.setOffset(config.scrollOffset);
7014
7072
  }
7015
- return new RouterScroller(router, viewportScroller, zone, config);
7073
+ return new RouterScroller(urlSerializer, transitions, viewportScroller, zone, config);
7016
7074
  },
7017
7075
  };
7018
7076
  }
@@ -7070,7 +7128,7 @@ function provideRouterInitializer() {
7070
7128
  /**
7071
7129
  * @publicApi
7072
7130
  */
7073
- const VERSION = new Version('15.0.0');
7131
+ const VERSION = new Version('15.0.2');
7074
7132
 
7075
7133
  /**
7076
7134
  * @license