@angular/router 15.0.0-rc.4 → 15.0.1

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 (38) hide show
  1. package/esm2020/src/components/empty_outlet.mjs +3 -3
  2. package/esm2020/src/directives/router_link.mjs +3 -3
  3. package/esm2020/src/directives/router_link_active.mjs +3 -3
  4. package/esm2020/src/directives/router_outlet.mjs +5 -5
  5. package/esm2020/src/index.mjs +1 -1
  6. package/esm2020/src/models.mjs +1 -1
  7. package/esm2020/src/navigation_transition.mjs +320 -0
  8. package/esm2020/src/operators/activate_routes.mjs +1 -1
  9. package/esm2020/src/operators/apply_redirects.mjs +1 -1
  10. package/esm2020/src/operators/check_guards.mjs +1 -1
  11. package/esm2020/src/operators/recognize.mjs +1 -1
  12. package/esm2020/src/operators/resolve_data.mjs +1 -1
  13. package/esm2020/src/page_title_strategy.mjs +6 -6
  14. package/esm2020/src/private_export.mjs +1 -1
  15. package/esm2020/src/provide_router.mjs +6 -13
  16. package/esm2020/src/route_reuse_strategy.mjs +15 -1
  17. package/esm2020/src/router.mjs +66 -347
  18. package/esm2020/src/router_config_loader.mjs +3 -3
  19. package/esm2020/src/router_module.mjs +4 -4
  20. package/esm2020/src/router_outlet_context.mjs +3 -3
  21. package/esm2020/src/router_preloader.mjs +9 -9
  22. package/esm2020/src/router_scroller.mjs +3 -3
  23. package/esm2020/src/url_handling_strategy.mjs +15 -1
  24. package/esm2020/src/url_tree.mjs +3 -3
  25. package/esm2020/src/version.mjs +1 -1
  26. package/esm2020/testing/src/router_testing_module.mjs +4 -4
  27. package/fesm2015/router.mjs +448 -402
  28. package/fesm2015/router.mjs.map +1 -1
  29. package/fesm2015/testing.mjs +5 -5
  30. package/fesm2015/upgrade.mjs +1 -1
  31. package/fesm2020/router.mjs +462 -411
  32. package/fesm2020/router.mjs.map +1 -1
  33. package/fesm2020/testing.mjs +5 -5
  34. package/fesm2020/upgrade.mjs +1 -1
  35. package/index.d.ts +17 -60
  36. package/package.json +4 -4
  37. package/testing/index.d.ts +1 -1
  38. package/upgrade/index.d.ts +1 -1
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license Angular v15.0.0-rc.4
2
+ * @license Angular v15.0.1
3
3
  * (c) 2010-2022 Google LLC. https://angular.io/
4
4
  * License: MIT
5
5
  */
@@ -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-rc.4", ngImport: i0, type: UrlSerializer, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
465
- UrlSerializer.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.0.0-rc.4", ngImport: i0, type: UrlSerializer, providedIn: 'root', useFactory: () => new DefaultUrlSerializer() });
466
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.0-rc.4", ngImport: i0, type: UrlSerializer, decorators: [{
464
+ UrlSerializer.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.1", ngImport: i0, type: UrlSerializer, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
465
+ UrlSerializer.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.0.1", ngImport: i0, type: UrlSerializer, providedIn: 'root', useFactory: () => new DefaultUrlSerializer() });
466
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.1", 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
  *
@@ -997,11 +997,11 @@ class Navigation {
997
997
  this.numberOfDoubleDots = numberOfDoubleDots;
998
998
  this.commands = commands;
999
999
  if (isAbsolute && commands.length > 0 && isMatrixParams(commands[0])) {
1000
- throw new ɵRuntimeError(4003 /* RuntimeErrorCode.ROOT_SEGMENT_MATRIX_PARAMS */, NG_DEV_MODE$8 && 'Root segment cannot have matrix parameters');
1000
+ throw new ɵRuntimeError(4003 /* RuntimeErrorCode.ROOT_SEGMENT_MATRIX_PARAMS */, NG_DEV_MODE$9 && 'Root segment cannot have matrix parameters');
1001
1001
  }
1002
1002
  const cmdWithOutlet = commands.find(isCommandWithOutlets);
1003
1003
  if (cmdWithOutlet && cmdWithOutlet !== last(commands)) {
1004
- throw new ɵRuntimeError(4004 /* RuntimeErrorCode.MISPLACED_OUTLETS_COMMAND */, NG_DEV_MODE$8 && '{outlets:{}} has to be the last command');
1004
+ throw new ɵRuntimeError(4004 /* RuntimeErrorCode.MISPLACED_OUTLETS_COMMAND */, NG_DEV_MODE$9 && '{outlets:{}} has to be the last command');
1005
1005
  }
1006
1006
  }
1007
1007
  toRoot() {
@@ -1100,7 +1100,7 @@ function createPositionApplyingDoubleDots(group, index, numberOfDoubleDots) {
1100
1100
  dd -= ci;
1101
1101
  g = g.parent;
1102
1102
  if (!g) {
1103
- throw new ɵRuntimeError(4005 /* RuntimeErrorCode.INVALID_DOUBLE_DOTS */, NG_DEV_MODE$8 && 'Invalid number of \'../\'');
1103
+ throw new ɵRuntimeError(4005 /* RuntimeErrorCode.INVALID_DOUBLE_DOTS */, NG_DEV_MODE$9 && 'Invalid number of \'../\'');
1104
1104
  }
1105
1105
  ci = g.segments.length;
1106
1106
  }
@@ -2380,9 +2380,9 @@ class ChildrenOutletContexts {
2380
2380
  return this.contexts.get(childName) || null;
2381
2381
  }
2382
2382
  }
2383
- ChildrenOutletContexts.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.0-rc.4", ngImport: i0, type: ChildrenOutletContexts, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
2384
- ChildrenOutletContexts.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.0.0-rc.4", ngImport: i0, type: ChildrenOutletContexts, providedIn: 'root' });
2385
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.0-rc.4", ngImport: i0, type: ChildrenOutletContexts, decorators: [{
2383
+ ChildrenOutletContexts.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.1", ngImport: i0, type: ChildrenOutletContexts, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
2384
+ ChildrenOutletContexts.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.0.1", ngImport: i0, type: ChildrenOutletContexts, providedIn: 'root' });
2385
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.1", ngImport: i0, type: ChildrenOutletContexts, decorators: [{
2386
2386
  type: Injectable,
2387
2387
  args: [{ providedIn: 'root' }]
2388
2388
  }] });
@@ -2394,7 +2394,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.0-rc.4", ng
2394
2394
  * Use of this source code is governed by an MIT-style license that can be
2395
2395
  * found in the LICENSE file at https://angular.io/license
2396
2396
  */
2397
- const NG_DEV_MODE$7 = typeof ngDevMode === 'undefined' || ngDevMode;
2397
+ const NG_DEV_MODE$8 = typeof ngDevMode === 'undefined' || ngDevMode;
2398
2398
  /**
2399
2399
  * @description
2400
2400
  *
@@ -2533,12 +2533,12 @@ class RouterOutlet {
2533
2533
  */
2534
2534
  get component() {
2535
2535
  if (!this.activated)
2536
- throw new ɵRuntimeError(4012 /* RuntimeErrorCode.OUTLET_NOT_ACTIVATED */, NG_DEV_MODE$7 && 'Outlet is not activated');
2536
+ throw new ɵRuntimeError(4012 /* RuntimeErrorCode.OUTLET_NOT_ACTIVATED */, NG_DEV_MODE$8 && 'Outlet is not activated');
2537
2537
  return this.activated.instance;
2538
2538
  }
2539
2539
  get activatedRoute() {
2540
2540
  if (!this.activated)
2541
- throw new ɵRuntimeError(4012 /* RuntimeErrorCode.OUTLET_NOT_ACTIVATED */, NG_DEV_MODE$7 && 'Outlet is not activated');
2541
+ throw new ɵRuntimeError(4012 /* RuntimeErrorCode.OUTLET_NOT_ACTIVATED */, NG_DEV_MODE$8 && 'Outlet is not activated');
2542
2542
  return this._activatedRoute;
2543
2543
  }
2544
2544
  get activatedRouteData() {
@@ -2552,7 +2552,7 @@ class RouterOutlet {
2552
2552
  */
2553
2553
  detach() {
2554
2554
  if (!this.activated)
2555
- throw new ɵRuntimeError(4012 /* RuntimeErrorCode.OUTLET_NOT_ACTIVATED */, NG_DEV_MODE$7 && 'Outlet is not activated');
2555
+ throw new ɵRuntimeError(4012 /* RuntimeErrorCode.OUTLET_NOT_ACTIVATED */, NG_DEV_MODE$8 && 'Outlet is not activated');
2556
2556
  this.location.detach();
2557
2557
  const cmp = this.activated;
2558
2558
  this.activated = null;
@@ -2580,11 +2580,11 @@ class RouterOutlet {
2580
2580
  }
2581
2581
  activateWith(activatedRoute, resolverOrInjector) {
2582
2582
  if (this.isActivated) {
2583
- throw new ɵRuntimeError(4013 /* RuntimeErrorCode.OUTLET_ALREADY_ACTIVATED */, NG_DEV_MODE$7 && 'Cannot activate an already activated outlet');
2583
+ throw new ɵRuntimeError(4013 /* RuntimeErrorCode.OUTLET_ALREADY_ACTIVATED */, NG_DEV_MODE$8 && 'Cannot activate an already activated outlet');
2584
2584
  }
2585
2585
  this._activatedRoute = activatedRoute;
2586
2586
  const location = this.location;
2587
- const snapshot = activatedRoute._futureSnapshot;
2587
+ const snapshot = activatedRoute.snapshot;
2588
2588
  const component = snapshot.component;
2589
2589
  const childContexts = this.parentContexts.getOrCreateContext(this.name).children;
2590
2590
  const injector = new OutletInjector(activatedRoute, childContexts, location.injector);
@@ -2602,9 +2602,9 @@ class RouterOutlet {
2602
2602
  this.activateEvents.emit(this.activated.instance);
2603
2603
  }
2604
2604
  }
2605
- RouterOutlet.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.0-rc.4", ngImport: i0, type: RouterOutlet, deps: [], target: i0.ɵɵFactoryTarget.Directive });
2606
- RouterOutlet.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.0.0-rc.4", 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 });
2607
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.0-rc.4", ngImport: i0, type: RouterOutlet, decorators: [{
2605
+ RouterOutlet.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.1", ngImport: i0, type: RouterOutlet, deps: [], target: i0.ɵɵFactoryTarget.Directive });
2606
+ RouterOutlet.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.0.1", 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 });
2607
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.1", ngImport: i0, type: RouterOutlet, decorators: [{
2608
2608
  type: Directive,
2609
2609
  args: [{
2610
2610
  selector: 'router-outlet',
@@ -2664,9 +2664,9 @@ function isComponentFactoryResolver(item) {
2664
2664
  */
2665
2665
  class ɵEmptyOutletComponent {
2666
2666
  }
2667
- ɵEmptyOutletComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.0-rc.4", ngImport: i0, type: ɵEmptyOutletComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
2668
- ɵEmptyOutletComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.0.0-rc.4", 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"] }] });
2669
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.0-rc.4", ngImport: i0, type: ɵEmptyOutletComponent, decorators: [{
2667
+ ɵEmptyOutletComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.1", ngImport: i0, type: ɵEmptyOutletComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
2668
+ ɵEmptyOutletComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.0.1", 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"] }] });
2669
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.1", ngImport: i0, type: ɵEmptyOutletComponent, decorators: [{
2670
2670
  type: Component,
2671
2671
  args: [{
2672
2672
  template: `<router-outlet></router-outlet>`,
@@ -3578,7 +3578,7 @@ function noLeftoversInUrl(segmentGroup, segments, outlet) {
3578
3578
  * Use of this source code is governed by an MIT-style license that can be
3579
3579
  * found in the LICENSE file at https://angular.io/license
3580
3580
  */
3581
- const NG_DEV_MODE$6 = typeof ngDevMode === 'undefined' || ngDevMode;
3581
+ const NG_DEV_MODE$7 = typeof ngDevMode === 'undefined' || ngDevMode;
3582
3582
  class NoMatch$1 {
3583
3583
  constructor(segmentGroup) {
3584
3584
  this.segmentGroup = segmentGroup || null;
@@ -3596,11 +3596,11 @@ function absoluteRedirect(newTree) {
3596
3596
  return throwError(new AbsoluteRedirect(newTree));
3597
3597
  }
3598
3598
  function namedOutletsRedirect(redirectTo) {
3599
- return throwError(new ɵRuntimeError(4000 /* RuntimeErrorCode.NAMED_OUTLET_REDIRECT */, NG_DEV_MODE$6 &&
3599
+ return throwError(new ɵRuntimeError(4000 /* RuntimeErrorCode.NAMED_OUTLET_REDIRECT */, NG_DEV_MODE$7 &&
3600
3600
  `Only absolute redirects can have named outlets. redirectTo: '${redirectTo}'`));
3601
3601
  }
3602
3602
  function canLoadFails(route) {
3603
- return throwError(navigationCancelingError(NG_DEV_MODE$6 &&
3603
+ return throwError(navigationCancelingError(NG_DEV_MODE$7 &&
3604
3604
  `Cannot load children because the guard of the route "path: '${route.path}'" returned false`, 3 /* NavigationCancellationCode.GuardRejected */));
3605
3605
  }
3606
3606
  /**
@@ -3660,7 +3660,7 @@ class ApplyRedirects {
3660
3660
  }));
3661
3661
  }
3662
3662
  noMatchError(e) {
3663
- return new ɵRuntimeError(4002 /* RuntimeErrorCode.NO_MATCH */, NG_DEV_MODE$6 && `Cannot match any routes. URL Segment: '${e.segmentGroup}'`);
3663
+ return new ɵRuntimeError(4002 /* RuntimeErrorCode.NO_MATCH */, NG_DEV_MODE$7 && `Cannot match any routes. URL Segment: '${e.segmentGroup}'`);
3664
3664
  }
3665
3665
  createUrlTree(rootCandidate, queryParams, fragment) {
3666
3666
  const root = createRoot(rootCandidate);
@@ -3875,7 +3875,7 @@ class ApplyRedirects {
3875
3875
  findPosParam(redirectTo, redirectToUrlSegment, posParams) {
3876
3876
  const pos = posParams[redirectToUrlSegment.path.substring(1)];
3877
3877
  if (!pos)
3878
- throw new ɵRuntimeError(4001 /* RuntimeErrorCode.MISSING_REDIRECT */, NG_DEV_MODE$6 &&
3878
+ throw new ɵRuntimeError(4001 /* RuntimeErrorCode.MISSING_REDIRECT */, NG_DEV_MODE$7 &&
3879
3879
  `Cannot redirect to '${redirectTo}'. Cannot find '${redirectToUrlSegment.path}'.`);
3880
3880
  return pos;
3881
3881
  }
@@ -3911,7 +3911,7 @@ function applyRedirects(environmentInjector, configLoader, urlSerializer, config
3911
3911
  * Use of this source code is governed by an MIT-style license that can be
3912
3912
  * found in the LICENSE file at https://angular.io/license
3913
3913
  */
3914
- const NG_DEV_MODE$5 = typeof ngDevMode === 'undefined' || !!ngDevMode;
3914
+ const NG_DEV_MODE$6 = typeof ngDevMode === 'undefined' || !!ngDevMode;
3915
3915
  class NoMatch {
3916
3916
  }
3917
3917
  function newObservableError(e) {
@@ -3999,7 +3999,7 @@ class Recognizer {
3999
3999
  // multiple activated results for the same outlet. We should merge the children of
4000
4000
  // these results so the final return value is only one `TreeNode` per outlet.
4001
4001
  const mergedChildren = mergeEmptyPathMatches(children);
4002
- if (NG_DEV_MODE$5) {
4002
+ if (NG_DEV_MODE$6) {
4003
4003
  // This should really never happen - we are only taking the first match for each
4004
4004
  // outlet and merge the empty path matches.
4005
4005
  checkOutletNameUniqueness(mergedChildren);
@@ -4154,7 +4154,7 @@ function checkOutletNameUniqueness(nodes) {
4154
4154
  if (routeWithSameOutletName) {
4155
4155
  const p = routeWithSameOutletName.url.map(s => s.toString()).join('/');
4156
4156
  const c = n.value.url.map(s => s.toString()).join('/');
4157
- 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}'.`);
4157
+ 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}'.`);
4158
4158
  }
4159
4159
  names[n.value.outlet] = n.value;
4160
4160
  });
@@ -4285,6 +4285,312 @@ function switchTap(next) {
4285
4285
  });
4286
4286
  }
4287
4287
 
4288
+ /**
4289
+ * @license
4290
+ * Copyright Google LLC All Rights Reserved.
4291
+ *
4292
+ * Use of this source code is governed by an MIT-style license that can be
4293
+ * found in the LICENSE file at https://angular.io/license
4294
+ */
4295
+ const NG_DEV_MODE$5 = typeof ngDevMode === 'undefined' || !!ngDevMode;
4296
+ class NavigationTransitions {
4297
+ constructor(router) {
4298
+ this.router = router;
4299
+ this.currentNavigation = null;
4300
+ }
4301
+ setupNavigations(transitions) {
4302
+ const eventsSubject = this.router.events;
4303
+ return transitions.pipe(filter(t => t.id !== 0),
4304
+ // Extract URL
4305
+ map(t => ({ ...t, extractedUrl: this.router.urlHandlingStrategy.extract(t.rawUrl) })),
4306
+ // Using switchMap so we cancel executing navigations when a new one comes in
4307
+ switchMap(overallTransitionState => {
4308
+ let completed = false;
4309
+ let errored = false;
4310
+ return of(overallTransitionState)
4311
+ .pipe(
4312
+ // Store the Navigation object
4313
+ tap(t => {
4314
+ this.currentNavigation = {
4315
+ id: t.id,
4316
+ initialUrl: t.rawUrl,
4317
+ extractedUrl: t.extractedUrl,
4318
+ trigger: t.source,
4319
+ extras: t.extras,
4320
+ previousNavigation: !this.router.lastSuccessfulNavigation ? null : {
4321
+ ...this.router.lastSuccessfulNavigation,
4322
+ previousNavigation: null,
4323
+ },
4324
+ };
4325
+ }), switchMap(t => {
4326
+ const browserUrlTree = this.router.browserUrlTree.toString();
4327
+ const urlTransition = !this.router.navigated ||
4328
+ t.extractedUrl.toString() !== browserUrlTree ||
4329
+ // Navigations which succeed or ones which fail and are cleaned up
4330
+ // correctly should result in `browserUrlTree` and `currentUrlTree`
4331
+ // matching. If this is not the case, assume something went wrong and
4332
+ // try processing the URL again.
4333
+ browserUrlTree !== this.router.currentUrlTree.toString();
4334
+ const processCurrentUrl = (this.router.onSameUrlNavigation === 'reload' ? true :
4335
+ urlTransition) &&
4336
+ this.router.urlHandlingStrategy.shouldProcessUrl(t.rawUrl);
4337
+ if (processCurrentUrl) {
4338
+ // If the source of the navigation is from a browser event, the URL is
4339
+ // already updated. We already need to sync the internal state.
4340
+ if (isBrowserTriggeredNavigation(t.source)) {
4341
+ this.router.browserUrlTree = t.extractedUrl;
4342
+ }
4343
+ return of(t).pipe(
4344
+ // Fire NavigationStart event
4345
+ switchMap(t => {
4346
+ const transition = this.router.transitions.getValue();
4347
+ eventsSubject.next(new NavigationStart(t.id, this.router.serializeUrl(t.extractedUrl), t.source, t.restoredState));
4348
+ if (transition !== this.router.transitions.getValue()) {
4349
+ return EMPTY;
4350
+ }
4351
+ // This delay is required to match old behavior that forced
4352
+ // navigation to always be async
4353
+ return Promise.resolve(t);
4354
+ }),
4355
+ // ApplyRedirects
4356
+ applyRedirects(this.router.ngModule.injector, this.router.configLoader, this.router.urlSerializer, this.router.config),
4357
+ // Update the currentNavigation
4358
+ // `urlAfterRedirects` is guaranteed to be set after this point
4359
+ tap(t => {
4360
+ this.currentNavigation = {
4361
+ ...this.currentNavigation,
4362
+ finalUrl: t.urlAfterRedirects
4363
+ };
4364
+ overallTransitionState.urlAfterRedirects = t.urlAfterRedirects;
4365
+ }),
4366
+ // Recognize
4367
+ recognize(this.router.ngModule.injector, this.router.rootComponentType, this.router.config, this.router.urlSerializer, this.router.paramsInheritanceStrategy),
4368
+ // Update URL if in `eager` update mode
4369
+ tap(t => {
4370
+ overallTransitionState.targetSnapshot = t.targetSnapshot;
4371
+ if (this.router.urlUpdateStrategy === 'eager') {
4372
+ if (!t.extras.skipLocationChange) {
4373
+ const rawUrl = this.router.urlHandlingStrategy.merge(t.urlAfterRedirects, t.rawUrl);
4374
+ this.router.setBrowserUrl(rawUrl, t);
4375
+ }
4376
+ this.router.browserUrlTree = t.urlAfterRedirects;
4377
+ }
4378
+ // Fire RoutesRecognized
4379
+ const routesRecognized = new RoutesRecognized(t.id, this.router.serializeUrl(t.extractedUrl), this.router.serializeUrl(t.urlAfterRedirects), t.targetSnapshot);
4380
+ eventsSubject.next(routesRecognized);
4381
+ }));
4382
+ }
4383
+ else {
4384
+ const processPreviousUrl = urlTransition && this.router.rawUrlTree &&
4385
+ this.router.urlHandlingStrategy.shouldProcessUrl(this.router.rawUrlTree);
4386
+ /* When the current URL shouldn't be processed, but the previous one
4387
+ * was, we handle this "error condition" by navigating to the
4388
+ * previously successful URL, but leaving the URL intact.*/
4389
+ if (processPreviousUrl) {
4390
+ const { id, extractedUrl, source, restoredState, extras } = t;
4391
+ const navStart = new NavigationStart(id, this.router.serializeUrl(extractedUrl), source, restoredState);
4392
+ eventsSubject.next(navStart);
4393
+ const targetSnapshot = createEmptyState(extractedUrl, this.router.rootComponentType)
4394
+ .snapshot;
4395
+ overallTransitionState = {
4396
+ ...t,
4397
+ targetSnapshot,
4398
+ urlAfterRedirects: extractedUrl,
4399
+ extras: { ...extras, skipLocationChange: false, replaceUrl: false },
4400
+ };
4401
+ return of(overallTransitionState);
4402
+ }
4403
+ else {
4404
+ /* When neither the current or previous URL can be processed, do
4405
+ * nothing other than update router's internal reference to the
4406
+ * current "settled" URL. This way the next navigation will be coming
4407
+ * from the current URL in the browser.
4408
+ */
4409
+ this.router.rawUrlTree = t.rawUrl;
4410
+ t.resolve(null);
4411
+ return EMPTY;
4412
+ }
4413
+ }
4414
+ }),
4415
+ // --- GUARDS ---
4416
+ tap(t => {
4417
+ const guardsStart = new GuardsCheckStart(t.id, this.router.serializeUrl(t.extractedUrl), this.router.serializeUrl(t.urlAfterRedirects), t.targetSnapshot);
4418
+ this.router.triggerEvent(guardsStart);
4419
+ }), map(t => {
4420
+ overallTransitionState = {
4421
+ ...t,
4422
+ guards: getAllRouteGuards(t.targetSnapshot, t.currentSnapshot, this.router.rootContexts)
4423
+ };
4424
+ return overallTransitionState;
4425
+ }), checkGuards(this.router.ngModule.injector, (evt) => this.router.triggerEvent(evt)), tap(t => {
4426
+ overallTransitionState.guardsResult = t.guardsResult;
4427
+ if (isUrlTree(t.guardsResult)) {
4428
+ throw redirectingNavigationError(this.router.urlSerializer, t.guardsResult);
4429
+ }
4430
+ const guardsEnd = new GuardsCheckEnd(t.id, this.router.serializeUrl(t.extractedUrl), this.router.serializeUrl(t.urlAfterRedirects), t.targetSnapshot, !!t.guardsResult);
4431
+ this.router.triggerEvent(guardsEnd);
4432
+ }), filter(t => {
4433
+ if (!t.guardsResult) {
4434
+ this.router.restoreHistory(t);
4435
+ this.router.cancelNavigationTransition(t, '', 3 /* NavigationCancellationCode.GuardRejected */);
4436
+ return false;
4437
+ }
4438
+ return true;
4439
+ }),
4440
+ // --- RESOLVE ---
4441
+ switchTap(t => {
4442
+ if (t.guards.canActivateChecks.length) {
4443
+ return of(t).pipe(tap(t => {
4444
+ const resolveStart = new ResolveStart(t.id, this.router.serializeUrl(t.extractedUrl), this.router.serializeUrl(t.urlAfterRedirects), t.targetSnapshot);
4445
+ this.router.triggerEvent(resolveStart);
4446
+ }), switchMap(t => {
4447
+ let dataResolved = false;
4448
+ return of(t).pipe(resolveData(this.router.paramsInheritanceStrategy, this.router.ngModule.injector), tap({
4449
+ next: () => dataResolved = true,
4450
+ complete: () => {
4451
+ if (!dataResolved) {
4452
+ this.router.restoreHistory(t);
4453
+ this.router.cancelNavigationTransition(t, NG_DEV_MODE$5 ?
4454
+ `At least one route resolver didn't emit any value.` :
4455
+ '', 2 /* NavigationCancellationCode.NoDataFromResolver */);
4456
+ }
4457
+ }
4458
+ }));
4459
+ }), tap(t => {
4460
+ const resolveEnd = new ResolveEnd(t.id, this.router.serializeUrl(t.extractedUrl), this.router.serializeUrl(t.urlAfterRedirects), t.targetSnapshot);
4461
+ this.router.triggerEvent(resolveEnd);
4462
+ }));
4463
+ }
4464
+ return undefined;
4465
+ }),
4466
+ // --- LOAD COMPONENTS ---
4467
+ switchTap((t) => {
4468
+ const loadComponents = (route) => {
4469
+ const loaders = [];
4470
+ if (route.routeConfig?.loadComponent &&
4471
+ !route.routeConfig._loadedComponent) {
4472
+ loaders.push(this.router.configLoader.loadComponent(route.routeConfig)
4473
+ .pipe(tap(loadedComponent => {
4474
+ route.component = loadedComponent;
4475
+ }), map(() => void 0)));
4476
+ }
4477
+ for (const child of route.children) {
4478
+ loaders.push(...loadComponents(child));
4479
+ }
4480
+ return loaders;
4481
+ };
4482
+ return combineLatest(loadComponents(t.targetSnapshot.root))
4483
+ .pipe(defaultIfEmpty(), take(1));
4484
+ }), switchTap(() => this.router.afterPreactivation()), map((t) => {
4485
+ const targetRouterState = createRouterState(this.router.routeReuseStrategy, t.targetSnapshot, t.currentRouterState);
4486
+ overallTransitionState = { ...t, targetRouterState };
4487
+ return (overallTransitionState);
4488
+ }),
4489
+ /* Once here, we are about to activate synchronously. The assumption is
4490
+ this will succeed, and user code may read from the Router service.
4491
+ Therefore before activation, we need to update router properties storing
4492
+ the current URL and the RouterState, as well as updated the browser URL.
4493
+ All this should happen *before* activating. */
4494
+ tap((t) => {
4495
+ this.router.currentUrlTree = t.urlAfterRedirects;
4496
+ this.router.rawUrlTree = this.router.urlHandlingStrategy.merge(t.urlAfterRedirects, t.rawUrl);
4497
+ this.router.routerState =
4498
+ t.targetRouterState;
4499
+ if (this.router.urlUpdateStrategy === 'deferred') {
4500
+ if (!t.extras.skipLocationChange) {
4501
+ this.router.setBrowserUrl(this.router.rawUrlTree, t);
4502
+ }
4503
+ this.router.browserUrlTree = t.urlAfterRedirects;
4504
+ }
4505
+ }), activateRoutes(this.router.rootContexts, this.router.routeReuseStrategy, (evt) => this.router.triggerEvent(evt)), tap({
4506
+ next() {
4507
+ completed = true;
4508
+ },
4509
+ complete() {
4510
+ completed = true;
4511
+ }
4512
+ }), finalize(() => {
4513
+ /* When the navigation stream finishes either through error or success,
4514
+ * we set the `completed` or `errored` flag. However, there are some
4515
+ * situations where we could get here without either of those being set.
4516
+ * For instance, a redirect during NavigationStart. Therefore, this is a
4517
+ * catch-all to make sure the NavigationCancel event is fired when a
4518
+ * navigation gets cancelled but not caught by other means. */
4519
+ if (!completed && !errored) {
4520
+ const cancelationReason = NG_DEV_MODE$5 ?
4521
+ `Navigation ID ${overallTransitionState
4522
+ .id} is not equal to the current navigation id ${this.router.navigationId}` :
4523
+ '';
4524
+ this.router.cancelNavigationTransition(overallTransitionState, cancelationReason, 1 /* NavigationCancellationCode.SupersededByNewNavigation */);
4525
+ }
4526
+ // Only clear current navigation if it is still set to the one that
4527
+ // finalized.
4528
+ if (this.currentNavigation?.id === overallTransitionState.id) {
4529
+ this.currentNavigation = null;
4530
+ }
4531
+ }), catchError((e) => {
4532
+ errored = true;
4533
+ /* This error type is issued during Redirect, and is handled as a
4534
+ * cancellation rather than an error. */
4535
+ if (isNavigationCancelingError$1(e)) {
4536
+ if (!isRedirectingNavigationCancelingError$1(e)) {
4537
+ // Set property only if we're not redirecting. If we landed on a page
4538
+ // and redirect to `/` route, the new navigation is going to see the
4539
+ // `/` isn't a change from the default currentUrlTree and won't
4540
+ // navigate. This is only applicable with initial navigation, so
4541
+ // setting `navigated` only when not redirecting resolves this
4542
+ // scenario.
4543
+ this.router.navigated = true;
4544
+ this.router.restoreHistory(overallTransitionState, true);
4545
+ }
4546
+ const navCancel = new NavigationCancel(overallTransitionState.id, this.router.serializeUrl(overallTransitionState.extractedUrl), e.message, e.cancellationCode);
4547
+ eventsSubject.next(navCancel);
4548
+ // When redirecting, we need to delay resolving the navigation
4549
+ // promise and push it to the redirect navigation
4550
+ if (!isRedirectingNavigationCancelingError$1(e)) {
4551
+ overallTransitionState.resolve(false);
4552
+ }
4553
+ else {
4554
+ const mergedTree = this.router.urlHandlingStrategy.merge(e.url, this.router.rawUrlTree);
4555
+ const extras = {
4556
+ skipLocationChange: overallTransitionState.extras.skipLocationChange,
4557
+ // The URL is already updated at this point if we have 'eager' URL
4558
+ // updates or if the navigation was triggered by the browser (back
4559
+ // button, URL bar, etc). We want to replace that item in history
4560
+ // if the navigation is rejected.
4561
+ replaceUrl: this.router.urlUpdateStrategy === 'eager' ||
4562
+ isBrowserTriggeredNavigation(overallTransitionState.source)
4563
+ };
4564
+ this.router.scheduleNavigation(mergedTree, 'imperative', null, extras, {
4565
+ resolve: overallTransitionState.resolve,
4566
+ reject: overallTransitionState.reject,
4567
+ promise: overallTransitionState.promise
4568
+ });
4569
+ }
4570
+ /* All other errors should reset to the router's internal URL reference
4571
+ * to the pre-error state. */
4572
+ }
4573
+ else {
4574
+ this.router.restoreHistory(overallTransitionState, true);
4575
+ const navError = new NavigationError(overallTransitionState.id, this.router.serializeUrl(overallTransitionState.extractedUrl), e, overallTransitionState.targetSnapshot ?? undefined);
4576
+ eventsSubject.next(navError);
4577
+ try {
4578
+ overallTransitionState.resolve(this.router.errorHandler(e));
4579
+ }
4580
+ catch (ee) {
4581
+ overallTransitionState.reject(ee);
4582
+ }
4583
+ }
4584
+ return EMPTY;
4585
+ }));
4586
+ // TODO(jasonaden): remove cast once g3 is on updated TypeScript
4587
+ }));
4588
+ }
4589
+ }
4590
+ function isBrowserTriggeredNavigation(source) {
4591
+ return source !== 'imperative';
4592
+ }
4593
+
4288
4594
  /**
4289
4595
  * @license
4290
4596
  * Copyright Google LLC All Rights Reserved.
@@ -4336,9 +4642,9 @@ class TitleStrategy {
4336
4642
  return snapshot.data[RouteTitleKey];
4337
4643
  }
4338
4644
  }
4339
- TitleStrategy.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.0-rc.4", ngImport: i0, type: TitleStrategy, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
4340
- TitleStrategy.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.0.0-rc.4", ngImport: i0, type: TitleStrategy, providedIn: 'root', useFactory: () => inject(DefaultTitleStrategy) });
4341
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.0-rc.4", ngImport: i0, type: TitleStrategy, decorators: [{
4645
+ TitleStrategy.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.1", ngImport: i0, type: TitleStrategy, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
4646
+ TitleStrategy.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.0.1", ngImport: i0, type: TitleStrategy, providedIn: 'root', useFactory: () => inject(DefaultTitleStrategy) });
4647
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.1", ngImport: i0, type: TitleStrategy, decorators: [{
4342
4648
  type: Injectable,
4343
4649
  args: [{ providedIn: 'root', useFactory: () => inject(DefaultTitleStrategy) }]
4344
4650
  }] });
@@ -4362,9 +4668,9 @@ class DefaultTitleStrategy extends TitleStrategy {
4362
4668
  }
4363
4669
  }
4364
4670
  }
4365
- DefaultTitleStrategy.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.0-rc.4", ngImport: i0, type: DefaultTitleStrategy, deps: [{ token: i1.Title }], target: i0.ɵɵFactoryTarget.Injectable });
4366
- DefaultTitleStrategy.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.0.0-rc.4", ngImport: i0, type: DefaultTitleStrategy, providedIn: 'root' });
4367
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.0-rc.4", ngImport: i0, type: DefaultTitleStrategy, decorators: [{
4671
+ DefaultTitleStrategy.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.1", ngImport: i0, type: DefaultTitleStrategy, deps: [{ token: i1.Title }], target: i0.ɵɵFactoryTarget.Injectable });
4672
+ DefaultTitleStrategy.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.0.1", ngImport: i0, type: DefaultTitleStrategy, providedIn: 'root' });
4673
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.1", ngImport: i0, type: DefaultTitleStrategy, decorators: [{
4368
4674
  type: Injectable,
4369
4675
  args: [{ providedIn: 'root' }]
4370
4676
  }], ctorParameters: function () { return [{ type: i1.Title }]; } });
@@ -4385,6 +4691,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.0-rc.4", ng
4385
4691
  */
4386
4692
  class RouteReuseStrategy {
4387
4693
  }
4694
+ RouteReuseStrategy.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.1", ngImport: i0, type: RouteReuseStrategy, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
4695
+ RouteReuseStrategy.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.0.1", ngImport: i0, type: RouteReuseStrategy, providedIn: 'root', useFactory: () => inject(DefaultRouteReuseStrategy) });
4696
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.1", ngImport: i0, type: RouteReuseStrategy, decorators: [{
4697
+ type: Injectable,
4698
+ args: [{ providedIn: 'root', useFactory: () => inject(DefaultRouteReuseStrategy) }]
4699
+ }] });
4388
4700
  /**
4389
4701
  * @description
4390
4702
  *
@@ -4433,6 +4745,12 @@ class BaseRouteReuseStrategy {
4433
4745
  }
4434
4746
  class DefaultRouteReuseStrategy extends BaseRouteReuseStrategy {
4435
4747
  }
4748
+ DefaultRouteReuseStrategy.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.1", ngImport: i0, type: DefaultRouteReuseStrategy, deps: null, target: i0.ɵɵFactoryTarget.Injectable });
4749
+ DefaultRouteReuseStrategy.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.0.1", ngImport: i0, type: DefaultRouteReuseStrategy, providedIn: 'root' });
4750
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.1", ngImport: i0, type: DefaultRouteReuseStrategy, decorators: [{
4751
+ type: Injectable,
4752
+ args: [{ providedIn: 'root' }]
4753
+ }] });
4436
4754
 
4437
4755
  /**
4438
4756
  * @license
@@ -4574,9 +4892,9 @@ class RouterConfigLoader {
4574
4892
  }));
4575
4893
  }
4576
4894
  }
4577
- RouterConfigLoader.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.0-rc.4", ngImport: i0, type: RouterConfigLoader, deps: [{ token: i0.Injector }, { token: i0.Compiler }], target: i0.ɵɵFactoryTarget.Injectable });
4578
- RouterConfigLoader.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.0.0-rc.4", ngImport: i0, type: RouterConfigLoader, providedIn: 'root' });
4579
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.0-rc.4", ngImport: i0, type: RouterConfigLoader, decorators: [{
4895
+ RouterConfigLoader.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.1", ngImport: i0, type: RouterConfigLoader, deps: [{ token: i0.Injector }, { token: i0.Compiler }], target: i0.ɵɵFactoryTarget.Injectable });
4896
+ RouterConfigLoader.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.0.1", ngImport: i0, type: RouterConfigLoader, providedIn: 'root' });
4897
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.1", ngImport: i0, type: RouterConfigLoader, decorators: [{
4580
4898
  type: Injectable,
4581
4899
  args: [{ providedIn: 'root' }]
4582
4900
  }], ctorParameters: function () { return [{ type: i0.Injector }, { type: i0.Compiler }]; } });
@@ -4608,6 +4926,12 @@ function maybeUnwrapDefaultExport(input) {
4608
4926
  */
4609
4927
  class UrlHandlingStrategy {
4610
4928
  }
4929
+ UrlHandlingStrategy.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.1", ngImport: i0, type: UrlHandlingStrategy, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
4930
+ UrlHandlingStrategy.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.0.1", ngImport: i0, type: UrlHandlingStrategy, providedIn: 'root', useFactory: () => inject(DefaultUrlHandlingStrategy) });
4931
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.1", ngImport: i0, type: UrlHandlingStrategy, decorators: [{
4932
+ type: Injectable,
4933
+ args: [{ providedIn: 'root', useFactory: () => inject(DefaultUrlHandlingStrategy) }]
4934
+ }] });
4611
4935
  /**
4612
4936
  * @publicApi
4613
4937
  */
@@ -4622,6 +4946,12 @@ class DefaultUrlHandlingStrategy {
4622
4946
  return newUrlPart;
4623
4947
  }
4624
4948
  }
4949
+ DefaultUrlHandlingStrategy.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.1", ngImport: i0, type: DefaultUrlHandlingStrategy, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
4950
+ DefaultUrlHandlingStrategy.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.0.1", ngImport: i0, type: DefaultUrlHandlingStrategy, providedIn: 'root' });
4951
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.1", ngImport: i0, type: DefaultUrlHandlingStrategy, decorators: [{
4952
+ type: Injectable,
4953
+ args: [{ providedIn: 'root' }]
4954
+ }] });
4625
4955
 
4626
4956
  /**
4627
4957
  * @license
@@ -4685,18 +5015,7 @@ function setupRouter() {
4685
5015
  const compiler = inject(Compiler);
4686
5016
  const config = inject(ROUTES, { optional: true }) ?? [];
4687
5017
  const opts = inject(ROUTER_CONFIGURATION, { optional: true }) ?? {};
4688
- const defaultTitleStrategy = inject(DefaultTitleStrategy);
4689
- const titleStrategy = inject(TitleStrategy, { optional: true });
4690
- const urlHandlingStrategy = inject(UrlHandlingStrategy, { optional: true });
4691
- const routeReuseStrategy = inject(RouteReuseStrategy, { optional: true });
4692
5018
  const router = new Router(null, urlSerializer, contexts, location, injector, compiler, flatten(config));
4693
- if (urlHandlingStrategy) {
4694
- router.urlHandlingStrategy = urlHandlingStrategy;
4695
- }
4696
- if (routeReuseStrategy) {
4697
- router.routeReuseStrategy = routeReuseStrategy;
4698
- }
4699
- router.titleStrategy = titleStrategy ?? defaultTitleStrategy;
4700
5019
  assignExtraOptionsToRouter(opts, router);
4701
5020
  return router;
4702
5021
  }
@@ -4717,15 +5036,24 @@ class Router {
4717
5036
  * Creates the router service.
4718
5037
  */
4719
5038
  // TODO: vsavkin make internal after the final is out.
4720
- constructor(rootComponentType, urlSerializer, rootContexts, location, injector, compiler, config) {
5039
+ constructor(
5040
+ /** @internal */
5041
+ rootComponentType,
5042
+ /** @internal */
5043
+ urlSerializer,
5044
+ /** @internal */
5045
+ rootContexts,
5046
+ /** @internal */
5047
+ location, injector, compiler, config) {
4721
5048
  this.rootComponentType = rootComponentType;
4722
5049
  this.urlSerializer = urlSerializer;
4723
5050
  this.rootContexts = rootContexts;
4724
5051
  this.location = location;
4725
5052
  this.config = config;
5053
+ /** @internal */
4726
5054
  this.lastSuccessfulNavigation = null;
4727
- this.currentNavigation = null;
4728
5055
  this.disposed = false;
5056
+ /** @internal */
4729
5057
  this.navigationId = 0;
4730
5058
  /**
4731
5059
  * The id of the currently active page in the router.
@@ -4769,11 +5097,15 @@ class Router {
4769
5097
  * A strategy for extracting and merging URLs.
4770
5098
  * Used for AngularJS to Angular migrations.
4771
5099
  */
4772
- this.urlHandlingStrategy = new DefaultUrlHandlingStrategy();
5100
+ this.urlHandlingStrategy = inject(UrlHandlingStrategy);
4773
5101
  /**
4774
5102
  * A strategy for re-using routes.
4775
5103
  */
4776
- this.routeReuseStrategy = new DefaultRouteReuseStrategy();
5104
+ this.routeReuseStrategy = inject(RouteReuseStrategy);
5105
+ /**
5106
+ * A strategy for setting the title based on the `routerState`.
5107
+ */
5108
+ this.titleStrategy = inject(TitleStrategy);
4777
5109
  /**
4778
5110
  * How to handle a navigation request to the current URL. One of:
4779
5111
  *
@@ -4829,6 +5161,7 @@ class Router {
4829
5161
  *
4830
5162
  */
4831
5163
  this.canceledNavigationResolution = 'replace';
5164
+ this.navigationTransitions = new NavigationTransitions(this);
4832
5165
  const onLoadStart = (r) => this.triggerEvent(new RouteConfigLoadStart(r));
4833
5166
  const onLoadEnd = (r) => this.triggerEvent(new RouteConfigLoadEnd(r));
4834
5167
  this.configLoader = injector.get(RouterConfigLoader);
@@ -4847,7 +5180,6 @@ class Router {
4847
5180
  id: 0,
4848
5181
  targetPageId: 0,
4849
5182
  currentUrlTree: this.currentUrlTree,
4850
- currentRawUrl: this.currentUrlTree,
4851
5183
  extractedUrl: this.urlHandlingStrategy.extract(this.currentUrlTree),
4852
5184
  urlAfterRedirects: this.urlHandlingStrategy.extract(this.currentUrlTree),
4853
5185
  rawUrl: this.currentUrlTree,
@@ -4864,7 +5196,7 @@ class Router {
4864
5196
  guards: { canActivateChecks: [], canDeactivateChecks: [] },
4865
5197
  guardsResult: null,
4866
5198
  });
4867
- this.navigations = this.setupNavigations(this.transitions);
5199
+ this.navigations = this.navigationTransitions.setupNavigations(this.transitions);
4868
5200
  this.processNavigations();
4869
5201
  }
4870
5202
  /**
@@ -4875,291 +5207,6 @@ class Router {
4875
5207
  get browserPageId() {
4876
5208
  return this.location.getState()?.ɵrouterPageId;
4877
5209
  }
4878
- setupNavigations(transitions) {
4879
- const eventsSubject = this.events;
4880
- return transitions.pipe(filter(t => t.id !== 0),
4881
- // Extract URL
4882
- map(t => ({ ...t, extractedUrl: this.urlHandlingStrategy.extract(t.rawUrl) })),
4883
- // Using switchMap so we cancel executing navigations when a new one comes in
4884
- switchMap(overallTransitionState => {
4885
- let completed = false;
4886
- let errored = false;
4887
- return of(overallTransitionState)
4888
- .pipe(
4889
- // Store the Navigation object
4890
- tap(t => {
4891
- this.currentNavigation = {
4892
- id: t.id,
4893
- initialUrl: t.rawUrl,
4894
- extractedUrl: t.extractedUrl,
4895
- trigger: t.source,
4896
- extras: t.extras,
4897
- previousNavigation: this.lastSuccessfulNavigation ?
4898
- { ...this.lastSuccessfulNavigation, previousNavigation: null } :
4899
- null
4900
- };
4901
- }), switchMap(t => {
4902
- const browserUrlTree = this.browserUrlTree.toString();
4903
- const urlTransition = !this.navigated ||
4904
- t.extractedUrl.toString() !== browserUrlTree ||
4905
- // Navigations which succeed or ones which fail and are cleaned up
4906
- // correctly should result in `browserUrlTree` and `currentUrlTree`
4907
- // matching. If this is not the case, assume something went wrong and
4908
- // try processing the URL again.
4909
- browserUrlTree !== this.currentUrlTree.toString();
4910
- const processCurrentUrl = (this.onSameUrlNavigation === 'reload' ? true : urlTransition) &&
4911
- this.urlHandlingStrategy.shouldProcessUrl(t.rawUrl);
4912
- if (processCurrentUrl) {
4913
- // If the source of the navigation is from a browser event, the URL is
4914
- // already updated. We already need to sync the internal state.
4915
- if (isBrowserTriggeredNavigation(t.source)) {
4916
- this.browserUrlTree = t.extractedUrl;
4917
- }
4918
- return of(t).pipe(
4919
- // Fire NavigationStart event
4920
- switchMap(t => {
4921
- const transition = this.transitions.getValue();
4922
- eventsSubject.next(new NavigationStart(t.id, this.serializeUrl(t.extractedUrl), t.source, t.restoredState));
4923
- if (transition !== this.transitions.getValue()) {
4924
- return EMPTY;
4925
- }
4926
- // This delay is required to match old behavior that forced
4927
- // navigation to always be async
4928
- return Promise.resolve(t);
4929
- }),
4930
- // ApplyRedirects
4931
- applyRedirects(this.ngModule.injector, this.configLoader, this.urlSerializer, this.config),
4932
- // Update the currentNavigation
4933
- // `urlAfterRedirects` is guaranteed to be set after this point
4934
- tap(t => {
4935
- this.currentNavigation = {
4936
- ...this.currentNavigation,
4937
- finalUrl: t.urlAfterRedirects
4938
- };
4939
- overallTransitionState.urlAfterRedirects = t.urlAfterRedirects;
4940
- }),
4941
- // Recognize
4942
- recognize(this.ngModule.injector, this.rootComponentType, this.config, this.urlSerializer, this.paramsInheritanceStrategy),
4943
- // Update URL if in `eager` update mode
4944
- tap(t => {
4945
- overallTransitionState.targetSnapshot = t.targetSnapshot;
4946
- if (this.urlUpdateStrategy === 'eager') {
4947
- if (!t.extras.skipLocationChange) {
4948
- const rawUrl = this.urlHandlingStrategy.merge(t.urlAfterRedirects, t.rawUrl);
4949
- this.setBrowserUrl(rawUrl, t);
4950
- }
4951
- this.browserUrlTree = t.urlAfterRedirects;
4952
- }
4953
- // Fire RoutesRecognized
4954
- const routesRecognized = new RoutesRecognized(t.id, this.serializeUrl(t.extractedUrl), this.serializeUrl(t.urlAfterRedirects), t.targetSnapshot);
4955
- eventsSubject.next(routesRecognized);
4956
- }));
4957
- }
4958
- else {
4959
- const processPreviousUrl = urlTransition && this.rawUrlTree &&
4960
- this.urlHandlingStrategy.shouldProcessUrl(this.rawUrlTree);
4961
- /* When the current URL shouldn't be processed, but the previous one
4962
- * was, we handle this "error condition" by navigating to the
4963
- * previously successful URL, but leaving the URL intact.*/
4964
- if (processPreviousUrl) {
4965
- const { id, extractedUrl, source, restoredState, extras } = t;
4966
- const navStart = new NavigationStart(id, this.serializeUrl(extractedUrl), source, restoredState);
4967
- eventsSubject.next(navStart);
4968
- const targetSnapshot = createEmptyState(extractedUrl, this.rootComponentType).snapshot;
4969
- overallTransitionState = {
4970
- ...t,
4971
- targetSnapshot,
4972
- urlAfterRedirects: extractedUrl,
4973
- extras: { ...extras, skipLocationChange: false, replaceUrl: false },
4974
- };
4975
- return of(overallTransitionState);
4976
- }
4977
- else {
4978
- /* When neither the current or previous URL can be processed, do
4979
- * nothing other than update router's internal reference to the
4980
- * current "settled" URL. This way the next navigation will be coming
4981
- * from the current URL in the browser.
4982
- */
4983
- this.rawUrlTree = t.rawUrl;
4984
- t.resolve(null);
4985
- return EMPTY;
4986
- }
4987
- }
4988
- }),
4989
- // --- GUARDS ---
4990
- tap(t => {
4991
- const guardsStart = new GuardsCheckStart(t.id, this.serializeUrl(t.extractedUrl), this.serializeUrl(t.urlAfterRedirects), t.targetSnapshot);
4992
- this.triggerEvent(guardsStart);
4993
- }), map(t => {
4994
- overallTransitionState = {
4995
- ...t,
4996
- guards: getAllRouteGuards(t.targetSnapshot, t.currentSnapshot, this.rootContexts)
4997
- };
4998
- return overallTransitionState;
4999
- }), checkGuards(this.ngModule.injector, (evt) => this.triggerEvent(evt)), tap(t => {
5000
- overallTransitionState.guardsResult = t.guardsResult;
5001
- if (isUrlTree(t.guardsResult)) {
5002
- throw redirectingNavigationError(this.urlSerializer, t.guardsResult);
5003
- }
5004
- const guardsEnd = new GuardsCheckEnd(t.id, this.serializeUrl(t.extractedUrl), this.serializeUrl(t.urlAfterRedirects), t.targetSnapshot, !!t.guardsResult);
5005
- this.triggerEvent(guardsEnd);
5006
- }), filter(t => {
5007
- if (!t.guardsResult) {
5008
- this.restoreHistory(t);
5009
- this.cancelNavigationTransition(t, '', 3 /* NavigationCancellationCode.GuardRejected */);
5010
- return false;
5011
- }
5012
- return true;
5013
- }),
5014
- // --- RESOLVE ---
5015
- switchTap(t => {
5016
- if (t.guards.canActivateChecks.length) {
5017
- return of(t).pipe(tap(t => {
5018
- const resolveStart = new ResolveStart(t.id, this.serializeUrl(t.extractedUrl), this.serializeUrl(t.urlAfterRedirects), t.targetSnapshot);
5019
- this.triggerEvent(resolveStart);
5020
- }), switchMap(t => {
5021
- let dataResolved = false;
5022
- return of(t).pipe(resolveData(this.paramsInheritanceStrategy, this.ngModule.injector), tap({
5023
- next: () => dataResolved = true,
5024
- complete: () => {
5025
- if (!dataResolved) {
5026
- this.restoreHistory(t);
5027
- this.cancelNavigationTransition(t, NG_DEV_MODE$2 ?
5028
- `At least one route resolver didn't emit any value.` :
5029
- '', 2 /* NavigationCancellationCode.NoDataFromResolver */);
5030
- }
5031
- }
5032
- }));
5033
- }), tap(t => {
5034
- const resolveEnd = new ResolveEnd(t.id, this.serializeUrl(t.extractedUrl), this.serializeUrl(t.urlAfterRedirects), t.targetSnapshot);
5035
- this.triggerEvent(resolveEnd);
5036
- }));
5037
- }
5038
- return undefined;
5039
- }),
5040
- // --- LOAD COMPONENTS ---
5041
- switchTap((t) => {
5042
- const loadComponents = (route) => {
5043
- const loaders = [];
5044
- if (route.routeConfig?.loadComponent &&
5045
- !route.routeConfig._loadedComponent) {
5046
- loaders.push(this.configLoader.loadComponent(route.routeConfig)
5047
- .pipe(tap(loadedComponent => {
5048
- route.component = loadedComponent;
5049
- }), map(() => void 0)));
5050
- }
5051
- for (const child of route.children) {
5052
- loaders.push(...loadComponents(child));
5053
- }
5054
- return loaders;
5055
- };
5056
- return combineLatest(loadComponents(t.targetSnapshot.root))
5057
- .pipe(defaultIfEmpty(), take(1));
5058
- }), switchTap(() => this.afterPreactivation()), map((t) => {
5059
- const targetRouterState = createRouterState(this.routeReuseStrategy, t.targetSnapshot, t.currentRouterState);
5060
- overallTransitionState = { ...t, targetRouterState };
5061
- return (overallTransitionState);
5062
- }),
5063
- /* Once here, we are about to activate synchronously. The assumption is
5064
- this will succeed, and user code may read from the Router service.
5065
- Therefore before activation, we need to update router properties storing
5066
- the current URL and the RouterState, as well as updated the browser URL.
5067
- All this should happen *before* activating. */
5068
- tap((t) => {
5069
- this.currentUrlTree = t.urlAfterRedirects;
5070
- this.rawUrlTree =
5071
- this.urlHandlingStrategy.merge(t.urlAfterRedirects, t.rawUrl);
5072
- this.routerState = t.targetRouterState;
5073
- if (this.urlUpdateStrategy === 'deferred') {
5074
- if (!t.extras.skipLocationChange) {
5075
- this.setBrowserUrl(this.rawUrlTree, t);
5076
- }
5077
- this.browserUrlTree = t.urlAfterRedirects;
5078
- }
5079
- }), activateRoutes(this.rootContexts, this.routeReuseStrategy, (evt) => this.triggerEvent(evt)), tap({
5080
- next() {
5081
- completed = true;
5082
- },
5083
- complete() {
5084
- completed = true;
5085
- }
5086
- }), finalize(() => {
5087
- /* When the navigation stream finishes either through error or success,
5088
- * we set the `completed` or `errored` flag. However, there are some
5089
- * situations where we could get here without either of those being set.
5090
- * For instance, a redirect during NavigationStart. Therefore, this is a
5091
- * catch-all to make sure the NavigationCancel event is fired when a
5092
- * navigation gets cancelled but not caught by other means. */
5093
- if (!completed && !errored) {
5094
- const cancelationReason = NG_DEV_MODE$2 ?
5095
- `Navigation ID ${overallTransitionState
5096
- .id} is not equal to the current navigation id ${this.navigationId}` :
5097
- '';
5098
- this.cancelNavigationTransition(overallTransitionState, cancelationReason, 1 /* NavigationCancellationCode.SupersededByNewNavigation */);
5099
- }
5100
- // Only clear current navigation if it is still set to the one that
5101
- // finalized.
5102
- if (this.currentNavigation?.id === overallTransitionState.id) {
5103
- this.currentNavigation = null;
5104
- }
5105
- }), catchError((e) => {
5106
- errored = true;
5107
- /* This error type is issued during Redirect, and is handled as a
5108
- * cancellation rather than an error. */
5109
- if (isNavigationCancelingError$1(e)) {
5110
- if (!isRedirectingNavigationCancelingError$1(e)) {
5111
- // Set property only if we're not redirecting. If we landed on a page
5112
- // and redirect to `/` route, the new navigation is going to see the
5113
- // `/` isn't a change from the default currentUrlTree and won't
5114
- // navigate. This is only applicable with initial navigation, so
5115
- // setting `navigated` only when not redirecting resolves this
5116
- // scenario.
5117
- this.navigated = true;
5118
- this.restoreHistory(overallTransitionState, true);
5119
- }
5120
- const navCancel = new NavigationCancel(overallTransitionState.id, this.serializeUrl(overallTransitionState.extractedUrl), e.message, e.cancellationCode);
5121
- eventsSubject.next(navCancel);
5122
- // When redirecting, we need to delay resolving the navigation
5123
- // promise and push it to the redirect navigation
5124
- if (!isRedirectingNavigationCancelingError$1(e)) {
5125
- overallTransitionState.resolve(false);
5126
- }
5127
- else {
5128
- const mergedTree = this.urlHandlingStrategy.merge(e.url, this.rawUrlTree);
5129
- const extras = {
5130
- skipLocationChange: overallTransitionState.extras.skipLocationChange,
5131
- // The URL is already updated at this point if we have 'eager' URL
5132
- // updates or if the navigation was triggered by the browser (back
5133
- // button, URL bar, etc). We want to replace that item in history
5134
- // if the navigation is rejected.
5135
- replaceUrl: this.urlUpdateStrategy === 'eager' ||
5136
- isBrowserTriggeredNavigation(overallTransitionState.source)
5137
- };
5138
- this.scheduleNavigation(mergedTree, 'imperative', null, extras, {
5139
- resolve: overallTransitionState.resolve,
5140
- reject: overallTransitionState.reject,
5141
- promise: overallTransitionState.promise
5142
- });
5143
- }
5144
- /* All other errors should reset to the router's internal URL reference
5145
- * to the pre-error state. */
5146
- }
5147
- else {
5148
- this.restoreHistory(overallTransitionState, true);
5149
- const navError = new NavigationError(overallTransitionState.id, this.serializeUrl(overallTransitionState.extractedUrl), e, overallTransitionState.targetSnapshot ?? undefined);
5150
- eventsSubject.next(navError);
5151
- try {
5152
- overallTransitionState.resolve(this.errorHandler(e));
5153
- }
5154
- catch (ee) {
5155
- overallTransitionState.reject(ee);
5156
- }
5157
- }
5158
- return EMPTY;
5159
- }));
5160
- // TODO(jasonaden): remove cast once g3 is on updated TypeScript
5161
- }));
5162
- }
5163
5210
  /**
5164
5211
  * @internal
5165
5212
  * TODO: this should be removed once the constructor of the router made internal
@@ -5199,11 +5246,18 @@ class Router {
5199
5246
  // hybrid apps.
5200
5247
  setTimeout(() => {
5201
5248
  const extras = { replaceUrl: true };
5202
- // Navigations coming from Angular router have a navigationId state
5203
- // property. When this exists, restore the state.
5204
- const state = event.state?.navigationId ? event.state : null;
5205
- if (state) {
5206
- const stateCopy = { ...state };
5249
+ // TODO: restoredState should always include the entire state, regardless
5250
+ // of navigationId. This requires a breaking change to update the type on
5251
+ // NavigationStart’s restoredState, which currently requires navigationId
5252
+ // to always be present. The Router used to only restore history state if
5253
+ // a navigationId was present.
5254
+ // The stored navigationId is used by the RouterScroller to retrieve the scroll
5255
+ // position for the page.
5256
+ const restoredState = event.state?.navigationId ? event.state : null;
5257
+ // Separate to NavigationStart.restoredState, we must also restore the state to
5258
+ // history.state and generate a new navigationId, since it will be overwritten
5259
+ if (event.state) {
5260
+ const stateCopy = { ...event.state };
5207
5261
  delete stateCopy.navigationId;
5208
5262
  delete stateCopy.ɵrouterPageId;
5209
5263
  if (Object.keys(stateCopy).length !== 0) {
@@ -5211,7 +5265,7 @@ class Router {
5211
5265
  }
5212
5266
  }
5213
5267
  const urlTree = this.parseUrl(event['url']);
5214
- this.scheduleNavigation(urlTree, source, state, extras);
5268
+ this.scheduleNavigation(urlTree, source, restoredState, extras);
5215
5269
  }, 0);
5216
5270
  }
5217
5271
  });
@@ -5226,7 +5280,7 @@ class Router {
5226
5280
  * and `null` when idle.
5227
5281
  */
5228
5282
  getCurrentNavigation() {
5229
- return this.currentNavigation;
5283
+ return this.navigationTransitions.currentNavigation;
5230
5284
  }
5231
5285
  /** @internal */
5232
5286
  triggerEvent(event) {
@@ -5452,13 +5506,14 @@ class Router {
5452
5506
  this.currentPageId = t.targetPageId;
5453
5507
  this.events
5454
5508
  .next(new NavigationEnd(t.id, this.serializeUrl(t.extractedUrl), this.serializeUrl(this.currentUrlTree)));
5455
- this.lastSuccessfulNavigation = this.currentNavigation;
5509
+ this.lastSuccessfulNavigation = this.getCurrentNavigation();
5456
5510
  this.titleStrategy?.updateTitle(this.routerState.snapshot);
5457
5511
  t.resolve(true);
5458
5512
  }, e => {
5459
5513
  this.console.warn(`Unhandled Navigation Error: ${e}`);
5460
5514
  });
5461
5515
  }
5516
+ /** @internal */
5462
5517
  scheduleNavigation(rawUrl, source, restoredState, extras, priorPromise) {
5463
5518
  if (this.disposed) {
5464
5519
  return Promise.resolve(false);
@@ -5511,7 +5566,6 @@ class Router {
5511
5566
  source,
5512
5567
  restoredState,
5513
5568
  currentUrlTree: this.currentUrlTree,
5514
- currentRawUrl: this.rawUrlTree,
5515
5569
  rawUrl,
5516
5570
  extras,
5517
5571
  resolve,
@@ -5526,10 +5580,14 @@ class Router {
5526
5580
  return Promise.reject(e);
5527
5581
  });
5528
5582
  }
5529
- setBrowserUrl(url, t) {
5583
+ /** @internal */
5584
+ setBrowserUrl(url, transition) {
5530
5585
  const path = this.urlSerializer.serialize(url);
5531
- const state = { ...t.extras.state, ...this.generateNgRouterState(t.id, t.targetPageId) };
5532
- if (this.location.isCurrentPathEqualTo(path) || !!t.extras.replaceUrl) {
5586
+ const state = {
5587
+ ...transition.extras.state,
5588
+ ...this.generateNgRouterState(transition.id, transition.targetPageId)
5589
+ };
5590
+ if (this.location.isCurrentPathEqualTo(path) || !!transition.extras.replaceUrl) {
5533
5591
  this.location.replaceState(path, '', state);
5534
5592
  }
5535
5593
  else {
@@ -5539,28 +5597,30 @@ class Router {
5539
5597
  /**
5540
5598
  * Performs the necessary rollback action to restore the browser URL to the
5541
5599
  * state before the transition.
5600
+ * @internal
5542
5601
  */
5543
- restoreHistory(t, restoringFromCaughtError = false) {
5602
+ restoreHistory(transition, restoringFromCaughtError = false) {
5544
5603
  if (this.canceledNavigationResolution === 'computed') {
5545
- const targetPagePosition = this.currentPageId - t.targetPageId;
5604
+ const targetPagePosition = this.currentPageId - transition.targetPageId;
5546
5605
  // The navigator change the location before triggered the browser event,
5547
5606
  // so we need to go back to the current url if the navigation is canceled.
5548
5607
  // Also, when navigation gets cancelled while using url update strategy eager, then we need to
5549
5608
  // go back. Because, when `urlUpdateStrategy` is `eager`; `setBrowserUrl` method is called
5550
5609
  // before any verification.
5551
- const browserUrlUpdateOccurred = (t.source === 'popstate' || this.urlUpdateStrategy === 'eager' ||
5552
- this.currentUrlTree === this.currentNavigation?.finalUrl);
5610
+ const browserUrlUpdateOccurred = (transition.source === 'popstate' || this.urlUpdateStrategy === 'eager' ||
5611
+ this.currentUrlTree === this.getCurrentNavigation()?.finalUrl);
5553
5612
  if (browserUrlUpdateOccurred && targetPagePosition !== 0) {
5554
5613
  this.location.historyGo(targetPagePosition);
5555
5614
  }
5556
- else if (this.currentUrlTree === this.currentNavigation?.finalUrl && targetPagePosition === 0) {
5615
+ else if (this.currentUrlTree === this.getCurrentNavigation()?.finalUrl &&
5616
+ targetPagePosition === 0) {
5557
5617
  // We got to the activation stage (where currentUrlTree is set to the navigation's
5558
5618
  // finalUrl), but we weren't moving anywhere in history (skipLocationChange or replaceUrl).
5559
5619
  // We still need to reset the router state back to what it was when the navigation started.
5560
- this.resetState(t);
5620
+ this.resetState(transition);
5561
5621
  // TODO(atscott): resetting the `browserUrlTree` should really be done in `resetState`.
5562
5622
  // Investigate if this can be done by running TGP.
5563
- this.browserUrlTree = t.currentUrlTree;
5623
+ this.browserUrlTree = transition.currentUrlTree;
5564
5624
  this.resetUrlToCurrentUrlTree();
5565
5625
  }
5566
5626
  else {
@@ -5574,7 +5634,7 @@ class Router {
5574
5634
  // reject. For 'eager' navigations, it seems like we also really should reset the state
5575
5635
  // because the navigation was cancelled. Investigate if this can be done by running TGP.
5576
5636
  if (restoringFromCaughtError) {
5577
- this.resetState(t);
5637
+ this.resetState(transition);
5578
5638
  }
5579
5639
  this.resetUrlToCurrentUrlTree();
5580
5640
  }
@@ -5592,10 +5652,11 @@ class Router {
5592
5652
  resetUrlToCurrentUrlTree() {
5593
5653
  this.location.replaceState(this.urlSerializer.serialize(this.rawUrlTree), '', this.generateNgRouterState(this.lastSuccessfulId, this.currentPageId));
5594
5654
  }
5595
- cancelNavigationTransition(t, reason, code) {
5596
- const navCancel = new NavigationCancel(t.id, this.serializeUrl(t.extractedUrl), reason, code);
5655
+ /** @internal */
5656
+ cancelNavigationTransition(transition, reason, code) {
5657
+ const navCancel = new NavigationCancel(transition.id, this.serializeUrl(transition.extractedUrl), reason, code);
5597
5658
  this.triggerEvent(navCancel);
5598
- t.resolve(false);
5659
+ transition.resolve(false);
5599
5660
  }
5600
5661
  generateNgRouterState(navigationId, routerPageId) {
5601
5662
  if (this.canceledNavigationResolution === 'computed') {
@@ -5604,9 +5665,9 @@ class Router {
5604
5665
  return { navigationId };
5605
5666
  }
5606
5667
  }
5607
- Router.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.0-rc.4", ngImport: i0, type: Router, deps: "invalid", target: i0.ɵɵFactoryTarget.Injectable });
5608
- Router.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.0.0-rc.4", ngImport: i0, type: Router, providedIn: 'root', useFactory: setupRouter });
5609
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.0-rc.4", ngImport: i0, type: Router, decorators: [{
5668
+ Router.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.1", ngImport: i0, type: Router, deps: "invalid", target: i0.ɵɵFactoryTarget.Injectable });
5669
+ Router.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.0.1", ngImport: i0, type: Router, providedIn: 'root', useFactory: setupRouter });
5670
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.1", ngImport: i0, type: Router, decorators: [{
5610
5671
  type: Injectable,
5611
5672
  args: [{
5612
5673
  providedIn: 'root',
@@ -5621,9 +5682,6 @@ function validateCommands(commands) {
5621
5682
  }
5622
5683
  }
5623
5684
  }
5624
- function isBrowserTriggeredNavigation(source) {
5625
- return source !== 'imperative';
5626
- }
5627
5685
 
5628
5686
  /**
5629
5687
  * @license
@@ -5905,9 +5963,9 @@ class RouterLink {
5905
5963
  });
5906
5964
  }
5907
5965
  }
5908
- RouterLink.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.0-rc.4", 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 });
5909
- RouterLink.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.0.0-rc.4", 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 });
5910
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.0-rc.4", ngImport: i0, type: RouterLink, decorators: [{
5966
+ RouterLink.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.1", 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 });
5967
+ RouterLink.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.0.1", 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 });
5968
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.1", ngImport: i0, type: RouterLink, decorators: [{
5911
5969
  type: Directive,
5912
5970
  args: [{
5913
5971
  selector: '[routerLink]',
@@ -6132,9 +6190,9 @@ class RouterLinkActive {
6132
6190
  return this.link && isActiveCheckFn(this.link) || this.links.some(isActiveCheckFn);
6133
6191
  }
6134
6192
  }
6135
- RouterLinkActive.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.0-rc.4", ngImport: i0, type: RouterLinkActive, deps: [{ token: Router }, { token: i0.ElementRef }, { token: i0.Renderer2 }, { token: i0.ChangeDetectorRef }, { token: RouterLink, optional: true }], target: i0.ɵɵFactoryTarget.Directive });
6136
- RouterLinkActive.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.0.0-rc.4", 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 });
6137
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.0-rc.4", ngImport: i0, type: RouterLinkActive, decorators: [{
6193
+ RouterLinkActive.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.1", ngImport: i0, type: RouterLinkActive, deps: [{ token: Router }, { token: i0.ElementRef }, { token: i0.Renderer2 }, { token: i0.ChangeDetectorRef }, { token: RouterLink, optional: true }], target: i0.ɵɵFactoryTarget.Directive });
6194
+ RouterLinkActive.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.0.1", 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 });
6195
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.1", ngImport: i0, type: RouterLinkActive, decorators: [{
6138
6196
  type: Directive,
6139
6197
  args: [{
6140
6198
  selector: '[routerLinkActive]',
@@ -6194,9 +6252,9 @@ class PreloadAllModules {
6194
6252
  return fn().pipe(catchError(() => of(null)));
6195
6253
  }
6196
6254
  }
6197
- PreloadAllModules.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.0-rc.4", ngImport: i0, type: PreloadAllModules, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
6198
- PreloadAllModules.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.0.0-rc.4", ngImport: i0, type: PreloadAllModules, providedIn: 'root' });
6199
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.0-rc.4", ngImport: i0, type: PreloadAllModules, decorators: [{
6255
+ PreloadAllModules.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.1", ngImport: i0, type: PreloadAllModules, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
6256
+ PreloadAllModules.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.0.1", ngImport: i0, type: PreloadAllModules, providedIn: 'root' });
6257
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.1", ngImport: i0, type: PreloadAllModules, decorators: [{
6200
6258
  type: Injectable,
6201
6259
  args: [{ providedIn: 'root' }]
6202
6260
  }] });
@@ -6214,9 +6272,9 @@ class NoPreloading {
6214
6272
  return of(null);
6215
6273
  }
6216
6274
  }
6217
- NoPreloading.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.0-rc.4", ngImport: i0, type: NoPreloading, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
6218
- NoPreloading.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.0.0-rc.4", ngImport: i0, type: NoPreloading, providedIn: 'root' });
6219
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.0-rc.4", ngImport: i0, type: NoPreloading, decorators: [{
6275
+ NoPreloading.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.1", ngImport: i0, type: NoPreloading, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
6276
+ NoPreloading.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.0.1", ngImport: i0, type: NoPreloading, providedIn: 'root' });
6277
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.1", ngImport: i0, type: NoPreloading, decorators: [{
6220
6278
  type: Injectable,
6221
6279
  args: [{ providedIn: 'root' }]
6222
6280
  }] });
@@ -6310,9 +6368,9 @@ class RouterPreloader {
6310
6368
  });
6311
6369
  }
6312
6370
  }
6313
- RouterPreloader.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.0-rc.4", ngImport: i0, type: RouterPreloader, deps: [{ token: Router }, { token: i0.Compiler }, { token: i0.EnvironmentInjector }, { token: PreloadingStrategy }, { token: RouterConfigLoader }], target: i0.ɵɵFactoryTarget.Injectable });
6314
- RouterPreloader.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.0.0-rc.4", ngImport: i0, type: RouterPreloader, providedIn: 'root' });
6315
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.0-rc.4", ngImport: i0, type: RouterPreloader, decorators: [{
6371
+ RouterPreloader.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.1", ngImport: i0, type: RouterPreloader, deps: [{ token: Router }, { token: i0.Compiler }, { token: i0.EnvironmentInjector }, { token: PreloadingStrategy }, { token: RouterConfigLoader }], target: i0.ɵɵFactoryTarget.Injectable });
6372
+ RouterPreloader.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.0.1", ngImport: i0, type: RouterPreloader, providedIn: 'root' });
6373
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.1", ngImport: i0, type: RouterPreloader, decorators: [{
6316
6374
  type: Injectable,
6317
6375
  args: [{ providedIn: 'root' }]
6318
6376
  }], ctorParameters: function () { return [{ type: Router }, { type: i0.Compiler }, { type: i0.EnvironmentInjector }, { type: PreloadingStrategy }, { type: RouterConfigLoader }]; } });
@@ -6410,9 +6468,9 @@ class RouterScroller {
6410
6468
  }
6411
6469
  }
6412
6470
  }
6413
- RouterScroller.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.0-rc.4", ngImport: i0, type: RouterScroller, deps: "invalid", target: i0.ɵɵFactoryTarget.Injectable });
6414
- RouterScroller.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.0.0-rc.4", ngImport: i0, type: RouterScroller });
6415
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.0-rc.4", ngImport: i0, type: RouterScroller, decorators: [{
6471
+ RouterScroller.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.1", ngImport: i0, type: RouterScroller, deps: "invalid", target: i0.ɵɵFactoryTarget.Injectable });
6472
+ RouterScroller.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.0.1", ngImport: i0, type: RouterScroller });
6473
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.1", ngImport: i0, type: RouterScroller, decorators: [{
6416
6474
  type: Injectable
6417
6475
  }], ctorParameters: function () { return [{ type: Router }, { type: i3.ViewportScroller }, { type: i0.NgZone }, { type: undefined }]; } });
6418
6476
 
@@ -6574,8 +6632,10 @@ function getBootstrapListener() {
6574
6632
  injector.get(ROUTER_PRELOADER, null, InjectFlags.Optional)?.setUpPreloading();
6575
6633
  injector.get(ROUTER_SCROLLER, null, InjectFlags.Optional)?.init();
6576
6634
  router.resetRootComponentType(ref.componentTypes[0]);
6577
- bootstrapDone.next();
6578
- bootstrapDone.complete();
6635
+ if (!bootstrapDone.closed) {
6636
+ bootstrapDone.next();
6637
+ bootstrapDone.unsubscribe();
6638
+ }
6579
6639
  };
6580
6640
  }
6581
6641
  /**
@@ -6623,7 +6683,6 @@ function withEnabledBlockingInitialNavigation() {
6623
6683
  deps: [Injector],
6624
6684
  useFactory: (injector) => {
6625
6685
  const locationInitialized = injector.get(LOCATION_INITIALIZED, Promise.resolve());
6626
- let initNavigation = false;
6627
6686
  /**
6628
6687
  * Performs the given action once the router finishes its next/current navigation.
6629
6688
  *
@@ -6658,21 +6717,13 @@ function withEnabledBlockingInitialNavigation() {
6658
6717
  // Unblock APP_INITIALIZER in case the initial navigation was canceled or errored
6659
6718
  // without a redirect.
6660
6719
  resolve(true);
6661
- initNavigation = true;
6662
6720
  });
6663
6721
  router.afterPreactivation = () => {
6664
6722
  // Unblock APP_INITIALIZER once we get to `afterPreactivation`. At this point, we
6665
6723
  // assume activation will complete successfully (even though this is not
6666
6724
  // guaranteed).
6667
6725
  resolve(true);
6668
- // only the initial navigation should be delayed until bootstrapping is done.
6669
- if (!initNavigation) {
6670
- return bootstrapDone.closed ? of(void 0) : bootstrapDone;
6671
- // subsequent navigations should not be delayed
6672
- }
6673
- else {
6674
- return of(void 0);
6675
- }
6726
+ return bootstrapDone.closed ? of(void 0) : bootstrapDone;
6676
6727
  };
6677
6728
  router.initialNavigation();
6678
6729
  });
@@ -6961,10 +7012,10 @@ class RouterModule {
6961
7012
  };
6962
7013
  }
6963
7014
  }
6964
- RouterModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.0-rc.4", ngImport: i0, type: RouterModule, deps: [{ token: ROUTER_FORROOT_GUARD, optional: true }], target: i0.ɵɵFactoryTarget.NgModule });
6965
- RouterModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "15.0.0-rc.4", ngImport: i0, type: RouterModule, imports: [RouterOutlet, RouterLink, RouterLinkActive, ɵEmptyOutletComponent], exports: [RouterOutlet, RouterLink, RouterLinkActive, ɵEmptyOutletComponent] });
6966
- RouterModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "15.0.0-rc.4", ngImport: i0, type: RouterModule, imports: [ɵEmptyOutletComponent] });
6967
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.0-rc.4", ngImport: i0, type: RouterModule, decorators: [{
7015
+ RouterModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.1", ngImport: i0, type: RouterModule, deps: [{ token: ROUTER_FORROOT_GUARD, optional: true }], target: i0.ɵɵFactoryTarget.NgModule });
7016
+ RouterModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "15.0.1", ngImport: i0, type: RouterModule, imports: [RouterOutlet, RouterLink, RouterLinkActive, ɵEmptyOutletComponent], exports: [RouterOutlet, RouterLink, RouterLinkActive, ɵEmptyOutletComponent] });
7017
+ RouterModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "15.0.1", ngImport: i0, type: RouterModule, imports: [ɵEmptyOutletComponent] });
7018
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.1", ngImport: i0, type: RouterModule, decorators: [{
6968
7019
  type: NgModule,
6969
7020
  args: [{
6970
7021
  imports: ROUTER_DIRECTIVES,
@@ -7049,7 +7100,7 @@ function provideRouterInitializer() {
7049
7100
  /**
7050
7101
  * @publicApi
7051
7102
  */
7052
- const VERSION = new Version('15.0.0-rc.4');
7103
+ const VERSION = new Version('15.0.1');
7053
7104
 
7054
7105
  /**
7055
7106
  * @license