@angular/router 14.1.0-next.0 → 14.1.0-next.3

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 (35) hide show
  1. package/esm2020/src/apply_redirects.mjs +30 -56
  2. package/esm2020/src/components/empty_outlet.mjs +3 -3
  3. package/esm2020/src/directives/router_link.mjs +6 -6
  4. package/esm2020/src/directives/router_link_active.mjs +3 -3
  5. package/esm2020/src/directives/router_outlet.mjs +8 -5
  6. package/esm2020/src/index.mjs +1 -1
  7. package/esm2020/src/models.mjs +1 -1
  8. package/esm2020/src/operators/check_guards.mjs +48 -4
  9. package/esm2020/src/operators/recognize.mjs +3 -3
  10. package/esm2020/src/page_title_strategy.mjs +3 -3
  11. package/esm2020/src/private_export.mjs +2 -2
  12. package/esm2020/src/recognize.mjs +133 -110
  13. package/esm2020/src/router.mjs +8 -37
  14. package/esm2020/src/router_config_loader.mjs +3 -3
  15. package/esm2020/src/router_module.mjs +151 -136
  16. package/esm2020/src/router_preloader.mjs +16 -4
  17. package/esm2020/src/router_scroller.mjs +6 -5
  18. package/esm2020/src/utils/config_matching.mjs +16 -2
  19. package/esm2020/src/utils/type_guards.mjs +4 -1
  20. package/esm2020/src/version.mjs +1 -1
  21. package/esm2020/testing/src/router_testing_module.mjs +8 -8
  22. package/fesm2015/router.mjs +840 -778
  23. package/fesm2015/router.mjs.map +1 -1
  24. package/fesm2015/testing.mjs +8 -8
  25. package/fesm2015/testing.mjs.map +1 -1
  26. package/fesm2015/upgrade.mjs +1 -1
  27. package/fesm2020/router.mjs +835 -779
  28. package/fesm2020/router.mjs.map +1 -1
  29. package/fesm2020/testing.mjs +8 -8
  30. package/fesm2020/testing.mjs.map +1 -1
  31. package/fesm2020/upgrade.mjs +1 -1
  32. package/index.d.ts +117 -1
  33. package/package.json +4 -4
  34. package/testing/index.d.ts +2 -2
  35. package/upgrade/index.d.ts +1 -1
@@ -1,15 +1,15 @@
1
1
  /**
2
- * @license Angular v14.1.0-next.0
2
+ * @license Angular v14.1.0-next.3
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, EventEmitter, Directive, Attribute, Output, Component, createEnvironmentInjector, ɵisStandalone, ComponentFactoryResolver, InjectionToken, InjectFlags, NgModuleFactory, Injectable, NgModuleRef, ɵConsole, NgZone, ɵcoerceToBoolean, Input, HostListener, HostBinding, Optional, ContentChildren, Injector, Compiler, NgProbeToken, ANALYZE_FOR_ENTRY_COMPONENTS, SkipSelf, Inject, APP_INITIALIZER, APP_BOOTSTRAP_LISTENER, NgModule, ApplicationRef, Version } from '@angular/core';
9
- import { from, of, BehaviorSubject, combineLatest, throwError, EmptyError, concat, defer, Observable, EMPTY, ConnectableObservable, Subject } from 'rxjs';
10
- import { map, switchMap, take, startWith, scan, filter, catchError, concatMap, last as last$1, first, mergeMap, tap, takeLast, mapTo, finalize, refCount, defaultIfEmpty, mergeAll } from 'rxjs/operators';
8
+ import { ɵisObservable, ɵisPromise, EventEmitter, Directive, Attribute, Output, Component, createEnvironmentInjector, ɵisStandalone, ComponentFactoryResolver, InjectionToken, InjectFlags, NgModuleFactory, Injectable, NgModuleRef, ɵConsole, NgZone, ɵcoerceToBoolean, Input, HostListener, HostBinding, Optional, ContentChildren, Injector, Compiler, NgProbeToken, ANALYZE_FOR_ENTRY_COMPONENTS, SkipSelf, inject, APP_INITIALIZER, APP_BOOTSTRAP_LISTENER, NgModule, Inject, ApplicationRef, ENVIRONMENT_INITIALIZER, Version } from '@angular/core';
9
+ import { from, of, BehaviorSubject, combineLatest, concat, defer, pipe, throwError, EmptyError, Observable, EMPTY, ConnectableObservable, Subject } from 'rxjs';
10
+ import { map, switchMap, take, startWith, scan, filter, mergeMap, first, concatMap, tap, catchError, last as last$1, takeWhile, defaultIfEmpty, takeLast, mapTo, finalize, refCount, mergeAll } from 'rxjs/operators';
11
11
  import * as i3 from '@angular/common';
12
- import { Location, LocationStrategy, PlatformLocation, APP_BASE_HREF, ViewportScroller, HashLocationStrategy, PathLocationStrategy, LOCATION_INITIALIZED } from '@angular/common';
12
+ import { Location, LocationStrategy, HashLocationStrategy, PathLocationStrategy, ViewportScroller, LOCATION_INITIALIZED } from '@angular/common';
13
13
  import * as i1 from '@angular/platform-browser';
14
14
 
15
15
  /**
@@ -2395,7 +2395,11 @@ class RouterOutlet {
2395
2395
  }
2396
2396
  /** @nodoc */
2397
2397
  ngOnDestroy() {
2398
- this.parentContexts.onChildOutletDestroyed(this.name);
2398
+ var _a;
2399
+ // Ensure that the registered outlet is this one before removing it on the context.
2400
+ if (((_a = this.parentContexts.getContext(this.name)) === null || _a === void 0 ? void 0 : _a.outlet) === this) {
2401
+ this.parentContexts.onChildOutletDestroyed(this.name);
2402
+ }
2399
2403
  }
2400
2404
  /** @nodoc */
2401
2405
  ngOnInit() {
@@ -2493,9 +2497,9 @@ class RouterOutlet {
2493
2497
  this.activateEvents.emit(this.activated.instance);
2494
2498
  }
2495
2499
  }
2496
- RouterOutlet.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.0-next.0", ngImport: i0, type: RouterOutlet, deps: [{ token: ChildrenOutletContexts }, { token: i0.ViewContainerRef }, { token: 'name', attribute: true }, { token: i0.ChangeDetectorRef }, { token: i0.EnvironmentInjector }], target: i0.ɵɵFactoryTarget.Directive });
2497
- RouterOutlet.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "14.1.0-next.0", type: RouterOutlet, selector: "router-outlet", outputs: { activateEvents: "activate", deactivateEvents: "deactivate", attachEvents: "attach", detachEvents: "detach" }, exportAs: ["outlet"], ngImport: i0 });
2498
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.0-next.0", ngImport: i0, type: RouterOutlet, decorators: [{
2500
+ RouterOutlet.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.0-next.3", ngImport: i0, type: RouterOutlet, deps: [{ token: ChildrenOutletContexts }, { token: i0.ViewContainerRef }, { token: 'name', attribute: true }, { token: i0.ChangeDetectorRef }, { token: i0.EnvironmentInjector }], target: i0.ɵɵFactoryTarget.Directive });
2501
+ RouterOutlet.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "14.1.0-next.3", type: RouterOutlet, selector: "router-outlet", outputs: { activateEvents: "activate", deactivateEvents: "deactivate", attachEvents: "attach", detachEvents: "detach" }, exportAs: ["outlet"], ngImport: i0 });
2502
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.0-next.3", ngImport: i0, type: RouterOutlet, decorators: [{
2499
2503
  type: Directive,
2500
2504
  args: [{ selector: 'router-outlet', exportAs: 'outlet' }]
2501
2505
  }], ctorParameters: function () {
@@ -2554,9 +2558,9 @@ function isComponentFactoryResolver(item) {
2554
2558
  */
2555
2559
  class ɵEmptyOutletComponent {
2556
2560
  }
2557
- ɵEmptyOutletComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.0-next.0", ngImport: i0, type: ɵEmptyOutletComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
2558
- ɵEmptyOutletComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.1.0-next.0", type: ɵEmptyOutletComponent, selector: "ng-component", ngImport: i0, template: `<router-outlet></router-outlet>`, isInline: true, dependencies: [{ kind: "directive", type: RouterOutlet, selector: "router-outlet", outputs: ["activate", "deactivate", "attach", "detach"], exportAs: ["outlet"] }] });
2559
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.0-next.0", ngImport: i0, type: ɵEmptyOutletComponent, decorators: [{
2561
+ ɵEmptyOutletComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.0-next.3", ngImport: i0, type: ɵEmptyOutletComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
2562
+ ɵEmptyOutletComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.1.0-next.3", type: ɵEmptyOutletComponent, selector: "ng-component", ngImport: i0, template: `<router-outlet></router-outlet>`, isInline: true, dependencies: [{ kind: "directive", type: RouterOutlet, selector: "router-outlet", outputs: ["activate", "deactivate", "attach", "detach"], exportAs: ["outlet"] }] });
2563
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.0-next.3", ngImport: i0, type: ɵEmptyOutletComponent, decorators: [{
2560
2564
  type: Component,
2561
2565
  args: [{ template: `<router-outlet></router-outlet>` }]
2562
2566
  }] });
@@ -2929,6 +2933,146 @@ class ActivateRoutes {
2929
2933
  }
2930
2934
  }
2931
2935
 
2936
+ /**
2937
+ * @license
2938
+ * Copyright Google LLC All Rights Reserved.
2939
+ *
2940
+ * Use of this source code is governed by an MIT-style license that can be
2941
+ * found in the LICENSE file at https://angular.io/license
2942
+ */
2943
+ class CanActivate {
2944
+ constructor(path) {
2945
+ this.path = path;
2946
+ this.route = this.path[this.path.length - 1];
2947
+ }
2948
+ }
2949
+ class CanDeactivate {
2950
+ constructor(component, route) {
2951
+ this.component = component;
2952
+ this.route = route;
2953
+ }
2954
+ }
2955
+ function getAllRouteGuards(future, curr, parentContexts) {
2956
+ const futureRoot = future._root;
2957
+ const currRoot = curr ? curr._root : null;
2958
+ return getChildRouteGuards(futureRoot, currRoot, parentContexts, [futureRoot.value]);
2959
+ }
2960
+ function getCanActivateChild(p) {
2961
+ const canActivateChild = p.routeConfig ? p.routeConfig.canActivateChild : null;
2962
+ if (!canActivateChild || canActivateChild.length === 0)
2963
+ return null;
2964
+ return { node: p, guards: canActivateChild };
2965
+ }
2966
+ function getToken(token, snapshot, fallbackInjector) {
2967
+ const routeInjector = getClosestRouteInjector(snapshot);
2968
+ const injector = routeInjector !== null && routeInjector !== void 0 ? routeInjector : fallbackInjector;
2969
+ return injector.get(token);
2970
+ }
2971
+ function getChildRouteGuards(futureNode, currNode, contexts, futurePath, checks = {
2972
+ canDeactivateChecks: [],
2973
+ canActivateChecks: []
2974
+ }) {
2975
+ const prevChildren = nodeChildrenAsMap(currNode);
2976
+ // Process the children of the future route
2977
+ futureNode.children.forEach(c => {
2978
+ getRouteGuards(c, prevChildren[c.value.outlet], contexts, futurePath.concat([c.value]), checks);
2979
+ delete prevChildren[c.value.outlet];
2980
+ });
2981
+ // Process any children left from the current route (not active for the future route)
2982
+ forEach(prevChildren, (v, k) => deactivateRouteAndItsChildren(v, contexts.getContext(k), checks));
2983
+ return checks;
2984
+ }
2985
+ function getRouteGuards(futureNode, currNode, parentContexts, futurePath, checks = {
2986
+ canDeactivateChecks: [],
2987
+ canActivateChecks: []
2988
+ }) {
2989
+ const future = futureNode.value;
2990
+ const curr = currNode ? currNode.value : null;
2991
+ const context = parentContexts ? parentContexts.getContext(futureNode.value.outlet) : null;
2992
+ // reusing the node
2993
+ if (curr && future.routeConfig === curr.routeConfig) {
2994
+ const shouldRun = shouldRunGuardsAndResolvers(curr, future, future.routeConfig.runGuardsAndResolvers);
2995
+ if (shouldRun) {
2996
+ checks.canActivateChecks.push(new CanActivate(futurePath));
2997
+ }
2998
+ else {
2999
+ // we need to set the data
3000
+ future.data = curr.data;
3001
+ future._resolvedData = curr._resolvedData;
3002
+ }
3003
+ // If we have a component, we need to go through an outlet.
3004
+ if (future.component) {
3005
+ getChildRouteGuards(futureNode, currNode, context ? context.children : null, futurePath, checks);
3006
+ // if we have a componentless route, we recurse but keep the same outlet map.
3007
+ }
3008
+ else {
3009
+ getChildRouteGuards(futureNode, currNode, parentContexts, futurePath, checks);
3010
+ }
3011
+ if (shouldRun && context && context.outlet && context.outlet.isActivated) {
3012
+ checks.canDeactivateChecks.push(new CanDeactivate(context.outlet.component, curr));
3013
+ }
3014
+ }
3015
+ else {
3016
+ if (curr) {
3017
+ deactivateRouteAndItsChildren(currNode, context, checks);
3018
+ }
3019
+ checks.canActivateChecks.push(new CanActivate(futurePath));
3020
+ // If we have a component, we need to go through an outlet.
3021
+ if (future.component) {
3022
+ getChildRouteGuards(futureNode, null, context ? context.children : null, futurePath, checks);
3023
+ // if we have a componentless route, we recurse but keep the same outlet map.
3024
+ }
3025
+ else {
3026
+ getChildRouteGuards(futureNode, null, parentContexts, futurePath, checks);
3027
+ }
3028
+ }
3029
+ return checks;
3030
+ }
3031
+ function shouldRunGuardsAndResolvers(curr, future, mode) {
3032
+ if (typeof mode === 'function') {
3033
+ return mode(curr, future);
3034
+ }
3035
+ switch (mode) {
3036
+ case 'pathParamsChange':
3037
+ return !equalPath(curr.url, future.url);
3038
+ case 'pathParamsOrQueryParamsChange':
3039
+ return !equalPath(curr.url, future.url) ||
3040
+ !shallowEqual(curr.queryParams, future.queryParams);
3041
+ case 'always':
3042
+ return true;
3043
+ case 'paramsOrQueryParamsChange':
3044
+ return !equalParamsAndUrlSegments(curr, future) ||
3045
+ !shallowEqual(curr.queryParams, future.queryParams);
3046
+ case 'paramsChange':
3047
+ default:
3048
+ return !equalParamsAndUrlSegments(curr, future);
3049
+ }
3050
+ }
3051
+ function deactivateRouteAndItsChildren(route, context, checks) {
3052
+ const children = nodeChildrenAsMap(route);
3053
+ const r = route.value;
3054
+ forEach(children, (node, childName) => {
3055
+ if (!r.component) {
3056
+ deactivateRouteAndItsChildren(node, context, checks);
3057
+ }
3058
+ else if (context) {
3059
+ deactivateRouteAndItsChildren(node, context.children.getContext(childName), checks);
3060
+ }
3061
+ else {
3062
+ deactivateRouteAndItsChildren(node, null, checks);
3063
+ }
3064
+ });
3065
+ if (!r.component) {
3066
+ checks.canDeactivateChecks.push(new CanDeactivate(null, r));
3067
+ }
3068
+ else if (context && context.outlet && context.outlet.isActivated) {
3069
+ checks.canDeactivateChecks.push(new CanDeactivate(context.outlet.component, r));
3070
+ }
3071
+ else {
3072
+ checks.canDeactivateChecks.push(new CanDeactivate(null, r));
3073
+ }
3074
+ }
3075
+
2932
3076
  /**
2933
3077
  * @license
2934
3078
  * Copyright Google LLC All Rights Reserved.
@@ -2970,6 +3114,9 @@ function isCanActivateChild(guard) {
2970
3114
  function isCanDeactivate(guard) {
2971
3115
  return guard && isFunction(guard.canDeactivate);
2972
3116
  }
3117
+ function isCanMatch(guard) {
3118
+ return guard && isFunction(guard.canMatch);
3119
+ }
2973
3120
 
2974
3121
  /**
2975
3122
  * @license
@@ -3017,91 +3164,276 @@ function prioritizedGuardValue() {
3017
3164
  * Use of this source code is governed by an MIT-style license that can be
3018
3165
  * found in the LICENSE file at https://angular.io/license
3019
3166
  */
3020
- const noMatch$1 = {
3021
- matched: false,
3022
- consumedSegments: [],
3023
- remainingSegments: [],
3024
- parameters: {},
3025
- positionalParamSegments: {}
3026
- };
3027
- function match(segmentGroup, route, segments) {
3028
- var _a;
3029
- if (route.path === '') {
3030
- if (route.pathMatch === 'full' && (segmentGroup.hasChildren() || segments.length > 0)) {
3031
- return Object.assign({}, noMatch$1);
3167
+ function checkGuards(moduleInjector, forwardEvent) {
3168
+ return mergeMap(t => {
3169
+ const { targetSnapshot, currentSnapshot, guards: { canActivateChecks, canDeactivateChecks } } = t;
3170
+ if (canDeactivateChecks.length === 0 && canActivateChecks.length === 0) {
3171
+ return of(Object.assign(Object.assign({}, t), { guardsResult: true }));
3032
3172
  }
3033
- return {
3034
- matched: true,
3035
- consumedSegments: [],
3036
- remainingSegments: segments,
3037
- parameters: {},
3038
- positionalParamSegments: {}
3039
- };
3040
- }
3041
- const matcher = route.matcher || defaultUrlMatcher;
3042
- const res = matcher(segments, segmentGroup, route);
3043
- if (!res)
3044
- return Object.assign({}, noMatch$1);
3045
- const posParams = {};
3046
- forEach(res.posParams, (v, k) => {
3047
- posParams[k] = v.path;
3173
+ return runCanDeactivateChecks(canDeactivateChecks, targetSnapshot, currentSnapshot, moduleInjector)
3174
+ .pipe(mergeMap(canDeactivate => {
3175
+ return canDeactivate && isBoolean(canDeactivate) ?
3176
+ runCanActivateChecks(targetSnapshot, canActivateChecks, moduleInjector, forwardEvent) :
3177
+ of(canDeactivate);
3178
+ }), map(guardsResult => (Object.assign(Object.assign({}, t), { guardsResult }))));
3048
3179
  });
3049
- const parameters = res.consumed.length > 0 ? Object.assign(Object.assign({}, posParams), res.consumed[res.consumed.length - 1].parameters) :
3050
- posParams;
3051
- return {
3052
- matched: true,
3053
- consumedSegments: res.consumed,
3054
- remainingSegments: segments.slice(res.consumed.length),
3055
- // TODO(atscott): investigate combining parameters and positionalParamSegments
3056
- parameters,
3057
- positionalParamSegments: (_a = res.posParams) !== null && _a !== void 0 ? _a : {}
3058
- };
3059
3180
  }
3060
- function split(segmentGroup, consumedSegments, slicedSegments, config, relativeLinkResolution = 'corrected') {
3061
- if (slicedSegments.length > 0 &&
3062
- containsEmptyPathMatchesWithNamedOutlets(segmentGroup, slicedSegments, config)) {
3063
- const s = new UrlSegmentGroup(consumedSegments, createChildrenForEmptyPaths(segmentGroup, consumedSegments, config, new UrlSegmentGroup(slicedSegments, segmentGroup.children)));
3064
- s._sourceSegment = segmentGroup;
3065
- s._segmentIndexShift = consumedSegments.length;
3066
- return { segmentGroup: s, slicedSegments: [] };
3067
- }
3068
- if (slicedSegments.length === 0 &&
3069
- containsEmptyPathMatches(segmentGroup, slicedSegments, config)) {
3070
- const s = new UrlSegmentGroup(segmentGroup.segments, addEmptyPathsToChildrenIfNeeded(segmentGroup, consumedSegments, slicedSegments, config, segmentGroup.children, relativeLinkResolution));
3071
- s._sourceSegment = segmentGroup;
3072
- s._segmentIndexShift = consumedSegments.length;
3073
- return { segmentGroup: s, slicedSegments };
3074
- }
3075
- const s = new UrlSegmentGroup(segmentGroup.segments, segmentGroup.children);
3076
- s._sourceSegment = segmentGroup;
3077
- s._segmentIndexShift = consumedSegments.length;
3078
- return { segmentGroup: s, slicedSegments };
3181
+ function runCanDeactivateChecks(checks, futureRSS, currRSS, moduleInjector) {
3182
+ return from(checks).pipe(mergeMap(check => runCanDeactivate(check.component, check.route, currRSS, futureRSS, moduleInjector)), first(result => {
3183
+ return result !== true;
3184
+ }, true));
3079
3185
  }
3080
- function addEmptyPathsToChildrenIfNeeded(segmentGroup, consumedSegments, slicedSegments, routes, children, relativeLinkResolution) {
3081
- const res = {};
3082
- for (const r of routes) {
3083
- if (emptyPathMatch(segmentGroup, slicedSegments, r) && !children[getOutlet(r)]) {
3084
- const s = new UrlSegmentGroup([], {});
3085
- s._sourceSegment = segmentGroup;
3086
- if (relativeLinkResolution === 'legacy') {
3087
- s._segmentIndexShift = segmentGroup.segments.length;
3088
- if (typeof ngDevMode === 'undefined' || !!ngDevMode) {
3089
- s._segmentIndexShiftCorrected = consumedSegments.length;
3090
- }
3091
- }
3092
- else {
3093
- s._segmentIndexShift = consumedSegments.length;
3094
- }
3095
- res[getOutlet(r)] = s;
3096
- }
3186
+ function runCanActivateChecks(futureSnapshot, checks, moduleInjector, forwardEvent) {
3187
+ return from(checks).pipe(concatMap((check) => {
3188
+ return concat(fireChildActivationStart(check.route.parent, forwardEvent), fireActivationStart(check.route, forwardEvent), runCanActivateChild(futureSnapshot, check.path, moduleInjector), runCanActivate(futureSnapshot, check.route, moduleInjector));
3189
+ }), first(result => {
3190
+ return result !== true;
3191
+ }, true));
3192
+ }
3193
+ /**
3194
+ * This should fire off `ActivationStart` events for each route being activated at this
3195
+ * level.
3196
+ * In other words, if you're activating `a` and `b` below, `path` will contain the
3197
+ * `ActivatedRouteSnapshot`s for both and we will fire `ActivationStart` for both. Always
3198
+ * return
3199
+ * `true` so checks continue to run.
3200
+ */
3201
+ function fireActivationStart(snapshot, forwardEvent) {
3202
+ if (snapshot !== null && forwardEvent) {
3203
+ forwardEvent(new ActivationStart(snapshot));
3097
3204
  }
3098
- return Object.assign(Object.assign({}, children), res);
3205
+ return of(true);
3099
3206
  }
3100
- function createChildrenForEmptyPaths(segmentGroup, consumedSegments, routes, primarySegment) {
3101
- const res = {};
3102
- res[PRIMARY_OUTLET] = primarySegment;
3103
- primarySegment._sourceSegment = segmentGroup;
3104
- primarySegment._segmentIndexShift = consumedSegments.length;
3207
+ /**
3208
+ * This should fire off `ChildActivationStart` events for each route being activated at this
3209
+ * level.
3210
+ * In other words, if you're activating `a` and `b` below, `path` will contain the
3211
+ * `ActivatedRouteSnapshot`s for both and we will fire `ChildActivationStart` for both. Always
3212
+ * return
3213
+ * `true` so checks continue to run.
3214
+ */
3215
+ function fireChildActivationStart(snapshot, forwardEvent) {
3216
+ if (snapshot !== null && forwardEvent) {
3217
+ forwardEvent(new ChildActivationStart(snapshot));
3218
+ }
3219
+ return of(true);
3220
+ }
3221
+ function runCanActivate(futureRSS, futureARS, moduleInjector) {
3222
+ const canActivate = futureARS.routeConfig ? futureARS.routeConfig.canActivate : null;
3223
+ if (!canActivate || canActivate.length === 0)
3224
+ return of(true);
3225
+ const canActivateObservables = canActivate.map((c) => {
3226
+ return defer(() => {
3227
+ const guard = getToken(c, futureARS, moduleInjector);
3228
+ let observable;
3229
+ if (isCanActivate(guard)) {
3230
+ observable = wrapIntoObservable(guard.canActivate(futureARS, futureRSS));
3231
+ }
3232
+ else if (isFunction(guard)) {
3233
+ observable = wrapIntoObservable(guard(futureARS, futureRSS));
3234
+ }
3235
+ else {
3236
+ throw new Error('Invalid CanActivate guard');
3237
+ }
3238
+ return observable.pipe(first());
3239
+ });
3240
+ });
3241
+ return of(canActivateObservables).pipe(prioritizedGuardValue());
3242
+ }
3243
+ function runCanActivateChild(futureRSS, path, moduleInjector) {
3244
+ const futureARS = path[path.length - 1];
3245
+ const canActivateChildGuards = path.slice(0, path.length - 1)
3246
+ .reverse()
3247
+ .map(p => getCanActivateChild(p))
3248
+ .filter(_ => _ !== null);
3249
+ const canActivateChildGuardsMapped = canActivateChildGuards.map((d) => {
3250
+ return defer(() => {
3251
+ const guardsMapped = d.guards.map((c) => {
3252
+ const guard = getToken(c, d.node, moduleInjector);
3253
+ let observable;
3254
+ if (isCanActivateChild(guard)) {
3255
+ observable = wrapIntoObservable(guard.canActivateChild(futureARS, futureRSS));
3256
+ }
3257
+ else if (isFunction(guard)) {
3258
+ observable = wrapIntoObservable(guard(futureARS, futureRSS));
3259
+ }
3260
+ else {
3261
+ throw new Error('Invalid CanActivateChild guard');
3262
+ }
3263
+ return observable.pipe(first());
3264
+ });
3265
+ return of(guardsMapped).pipe(prioritizedGuardValue());
3266
+ });
3267
+ });
3268
+ return of(canActivateChildGuardsMapped).pipe(prioritizedGuardValue());
3269
+ }
3270
+ function runCanDeactivate(component, currARS, currRSS, futureRSS, moduleInjector) {
3271
+ const canDeactivate = currARS && currARS.routeConfig ? currARS.routeConfig.canDeactivate : null;
3272
+ if (!canDeactivate || canDeactivate.length === 0)
3273
+ return of(true);
3274
+ const canDeactivateObservables = canDeactivate.map((c) => {
3275
+ const guard = getToken(c, currARS, moduleInjector);
3276
+ let observable;
3277
+ if (isCanDeactivate(guard)) {
3278
+ observable = wrapIntoObservable(guard.canDeactivate(component, currARS, currRSS, futureRSS));
3279
+ }
3280
+ else if (isFunction(guard)) {
3281
+ observable = wrapIntoObservable(guard(component, currARS, currRSS, futureRSS));
3282
+ }
3283
+ else {
3284
+ throw new Error('Invalid CanDeactivate guard');
3285
+ }
3286
+ return observable.pipe(first());
3287
+ });
3288
+ return of(canDeactivateObservables).pipe(prioritizedGuardValue());
3289
+ }
3290
+ function runCanLoadGuards(injector, route, segments, urlSerializer) {
3291
+ const canLoad = route.canLoad;
3292
+ if (canLoad === undefined || canLoad.length === 0) {
3293
+ return of(true);
3294
+ }
3295
+ const canLoadObservables = canLoad.map((injectionToken) => {
3296
+ const guard = injector.get(injectionToken);
3297
+ let guardVal;
3298
+ if (isCanLoad(guard)) {
3299
+ guardVal = guard.canLoad(route, segments);
3300
+ }
3301
+ else if (isFunction(guard)) {
3302
+ guardVal = guard(route, segments);
3303
+ }
3304
+ else {
3305
+ throw new Error('Invalid CanLoad guard');
3306
+ }
3307
+ return wrapIntoObservable(guardVal);
3308
+ });
3309
+ return of(canLoadObservables)
3310
+ .pipe(prioritizedGuardValue(), redirectIfUrlTree(urlSerializer));
3311
+ }
3312
+ function redirectIfUrlTree(urlSerializer) {
3313
+ return pipe(tap((result) => {
3314
+ if (!isUrlTree(result))
3315
+ return;
3316
+ const error = navigationCancelingError(`Redirecting to "${urlSerializer.serialize(result)}"`);
3317
+ error.url = result;
3318
+ throw error;
3319
+ }), map(result => result === true));
3320
+ }
3321
+ function runCanMatchGuards(injector, route, segments, urlSerializer) {
3322
+ const canMatch = route.canMatch;
3323
+ if (!canMatch || canMatch.length === 0)
3324
+ return of(true);
3325
+ const canMatchObservables = canMatch.map(injectionToken => {
3326
+ const guard = injector.get(injectionToken);
3327
+ const guardVal = isCanMatch(guard) ? guard.canMatch(route, segments) : guard(route, segments);
3328
+ return wrapIntoObservable(guardVal);
3329
+ });
3330
+ return of(canMatchObservables)
3331
+ .pipe(prioritizedGuardValue(), redirectIfUrlTree(urlSerializer));
3332
+ }
3333
+
3334
+ /**
3335
+ * @license
3336
+ * Copyright Google LLC All Rights Reserved.
3337
+ *
3338
+ * Use of this source code is governed by an MIT-style license that can be
3339
+ * found in the LICENSE file at https://angular.io/license
3340
+ */
3341
+ const noMatch$1 = {
3342
+ matched: false,
3343
+ consumedSegments: [],
3344
+ remainingSegments: [],
3345
+ parameters: {},
3346
+ positionalParamSegments: {}
3347
+ };
3348
+ function matchWithChecks(segmentGroup, route, segments, injector, urlSerializer) {
3349
+ const result = match(segmentGroup, route, segments);
3350
+ if (!result.matched) {
3351
+ return of(result);
3352
+ }
3353
+ // Only create the Route's `EnvironmentInjector` if it matches the attempted
3354
+ // navigation
3355
+ injector = getOrCreateRouteInjectorIfNeeded(route, injector);
3356
+ return runCanMatchGuards(injector, route, segments, urlSerializer)
3357
+ .pipe(map((v) => v === true ? result : Object.assign({}, noMatch$1)));
3358
+ }
3359
+ function match(segmentGroup, route, segments) {
3360
+ var _a;
3361
+ if (route.path === '') {
3362
+ if (route.pathMatch === 'full' && (segmentGroup.hasChildren() || segments.length > 0)) {
3363
+ return Object.assign({}, noMatch$1);
3364
+ }
3365
+ return {
3366
+ matched: true,
3367
+ consumedSegments: [],
3368
+ remainingSegments: segments,
3369
+ parameters: {},
3370
+ positionalParamSegments: {}
3371
+ };
3372
+ }
3373
+ const matcher = route.matcher || defaultUrlMatcher;
3374
+ const res = matcher(segments, segmentGroup, route);
3375
+ if (!res)
3376
+ return Object.assign({}, noMatch$1);
3377
+ const posParams = {};
3378
+ forEach(res.posParams, (v, k) => {
3379
+ posParams[k] = v.path;
3380
+ });
3381
+ const parameters = res.consumed.length > 0 ? Object.assign(Object.assign({}, posParams), res.consumed[res.consumed.length - 1].parameters) :
3382
+ posParams;
3383
+ return {
3384
+ matched: true,
3385
+ consumedSegments: res.consumed,
3386
+ remainingSegments: segments.slice(res.consumed.length),
3387
+ // TODO(atscott): investigate combining parameters and positionalParamSegments
3388
+ parameters,
3389
+ positionalParamSegments: (_a = res.posParams) !== null && _a !== void 0 ? _a : {}
3390
+ };
3391
+ }
3392
+ function split(segmentGroup, consumedSegments, slicedSegments, config, relativeLinkResolution = 'corrected') {
3393
+ if (slicedSegments.length > 0 &&
3394
+ containsEmptyPathMatchesWithNamedOutlets(segmentGroup, slicedSegments, config)) {
3395
+ const s = new UrlSegmentGroup(consumedSegments, createChildrenForEmptyPaths(segmentGroup, consumedSegments, config, new UrlSegmentGroup(slicedSegments, segmentGroup.children)));
3396
+ s._sourceSegment = segmentGroup;
3397
+ s._segmentIndexShift = consumedSegments.length;
3398
+ return { segmentGroup: s, slicedSegments: [] };
3399
+ }
3400
+ if (slicedSegments.length === 0 &&
3401
+ containsEmptyPathMatches(segmentGroup, slicedSegments, config)) {
3402
+ const s = new UrlSegmentGroup(segmentGroup.segments, addEmptyPathsToChildrenIfNeeded(segmentGroup, consumedSegments, slicedSegments, config, segmentGroup.children, relativeLinkResolution));
3403
+ s._sourceSegment = segmentGroup;
3404
+ s._segmentIndexShift = consumedSegments.length;
3405
+ return { segmentGroup: s, slicedSegments };
3406
+ }
3407
+ const s = new UrlSegmentGroup(segmentGroup.segments, segmentGroup.children);
3408
+ s._sourceSegment = segmentGroup;
3409
+ s._segmentIndexShift = consumedSegments.length;
3410
+ return { segmentGroup: s, slicedSegments };
3411
+ }
3412
+ function addEmptyPathsToChildrenIfNeeded(segmentGroup, consumedSegments, slicedSegments, routes, children, relativeLinkResolution) {
3413
+ const res = {};
3414
+ for (const r of routes) {
3415
+ if (emptyPathMatch(segmentGroup, slicedSegments, r) && !children[getOutlet(r)]) {
3416
+ const s = new UrlSegmentGroup([], {});
3417
+ s._sourceSegment = segmentGroup;
3418
+ if (relativeLinkResolution === 'legacy') {
3419
+ s._segmentIndexShift = segmentGroup.segments.length;
3420
+ if (typeof ngDevMode === 'undefined' || !!ngDevMode) {
3421
+ s._segmentIndexShiftCorrected = consumedSegments.length;
3422
+ }
3423
+ }
3424
+ else {
3425
+ s._segmentIndexShift = consumedSegments.length;
3426
+ }
3427
+ res[getOutlet(r)] = s;
3428
+ }
3429
+ }
3430
+ return Object.assign(Object.assign({}, children), res);
3431
+ }
3432
+ function createChildrenForEmptyPaths(segmentGroup, consumedSegments, routes, primarySegment) {
3433
+ const res = {};
3434
+ res[PRIMARY_OUTLET] = primarySegment;
3435
+ primarySegment._sourceSegment = segmentGroup;
3436
+ primarySegment._segmentIndexShift = consumedSegments.length;
3105
3437
  for (const r of routes) {
3106
3438
  if (r.path === '' && getOutlet(r) !== PRIMARY_OUTLET) {
3107
3439
  const s = new UrlSegmentGroup([], {});
@@ -3355,29 +3687,32 @@ class ApplyRedirects {
3355
3687
  }
3356
3688
  return of(new UrlSegmentGroup(segments, {}));
3357
3689
  }
3358
- const { matched, consumedSegments, remainingSegments } = match(rawSegmentGroup, route, segments);
3359
- if (!matched)
3360
- return noMatch(rawSegmentGroup);
3361
- // Only create the Route's `EnvironmentInjector` if it matches the attempted navigation
3362
- injector = getOrCreateRouteInjectorIfNeeded(route, injector);
3363
- const childConfig$ = this.getChildConfig(injector, route, segments);
3364
- return childConfig$.pipe(mergeMap((routerConfig) => {
3690
+ return matchWithChecks(rawSegmentGroup, route, segments, injector, this.urlSerializer)
3691
+ .pipe(switchMap(({ matched, consumedSegments, remainingSegments }) => {
3365
3692
  var _a;
3366
- const childInjector = (_a = routerConfig.injector) !== null && _a !== void 0 ? _a : injector;
3367
- const childConfig = routerConfig.routes;
3368
- const { segmentGroup: splitSegmentGroup, slicedSegments } = split(rawSegmentGroup, consumedSegments, remainingSegments, childConfig);
3369
- // See comment on the other call to `split` about why this is necessary.
3370
- const segmentGroup = new UrlSegmentGroup(splitSegmentGroup.segments, splitSegmentGroup.children);
3371
- if (slicedSegments.length === 0 && segmentGroup.hasChildren()) {
3372
- const expanded$ = this.expandChildren(childInjector, childConfig, segmentGroup);
3373
- return expanded$.pipe(map((children) => new UrlSegmentGroup(consumedSegments, children)));
3374
- }
3375
- if (childConfig.length === 0 && slicedSegments.length === 0) {
3376
- return of(new UrlSegmentGroup(consumedSegments, {}));
3377
- }
3378
- const matchedOnOutlet = getOutlet(route) === outlet;
3379
- const expanded$ = this.expandSegment(childInjector, segmentGroup, childConfig, slicedSegments, matchedOnOutlet ? PRIMARY_OUTLET : outlet, true);
3380
- return expanded$.pipe(map((cs) => new UrlSegmentGroup(consumedSegments.concat(cs.segments), cs.children)));
3693
+ if (!matched)
3694
+ return noMatch(rawSegmentGroup);
3695
+ // If the route has an injector created from providers, we should start using that.
3696
+ injector = (_a = route._injector) !== null && _a !== void 0 ? _a : injector;
3697
+ const childConfig$ = this.getChildConfig(injector, route, segments);
3698
+ return childConfig$.pipe(mergeMap((routerConfig) => {
3699
+ var _a;
3700
+ const childInjector = (_a = routerConfig.injector) !== null && _a !== void 0 ? _a : injector;
3701
+ const childConfig = routerConfig.routes;
3702
+ const { segmentGroup: splitSegmentGroup, slicedSegments } = split(rawSegmentGroup, consumedSegments, remainingSegments, childConfig);
3703
+ // See comment on the other call to `split` about why this is necessary.
3704
+ const segmentGroup = new UrlSegmentGroup(splitSegmentGroup.segments, splitSegmentGroup.children);
3705
+ if (slicedSegments.length === 0 && segmentGroup.hasChildren()) {
3706
+ const expanded$ = this.expandChildren(childInjector, childConfig, segmentGroup);
3707
+ return expanded$.pipe(map((children) => new UrlSegmentGroup(consumedSegments, children)));
3708
+ }
3709
+ if (childConfig.length === 0 && slicedSegments.length === 0) {
3710
+ return of(new UrlSegmentGroup(consumedSegments, {}));
3711
+ }
3712
+ const matchedOnOutlet = getOutlet(route) === outlet;
3713
+ const expanded$ = this.expandSegment(childInjector, segmentGroup, childConfig, slicedSegments, matchedOnOutlet ? PRIMARY_OUTLET : outlet, true);
3714
+ return expanded$.pipe(map((cs) => new UrlSegmentGroup(consumedSegments.concat(cs.segments), cs.children)));
3715
+ }));
3381
3716
  }));
3382
3717
  }
3383
3718
  getChildConfig(injector, route, segments) {
@@ -3390,7 +3725,7 @@ class ApplyRedirects {
3390
3725
  if (route._loadedRoutes !== undefined) {
3391
3726
  return of({ routes: route._loadedRoutes, injector: route._loadedInjector });
3392
3727
  }
3393
- return this.runCanLoadGuards(injector, route, segments)
3728
+ return runCanLoadGuards(injector, route, segments, this.urlSerializer)
3394
3729
  .pipe(mergeMap((shouldLoadResult) => {
3395
3730
  if (shouldLoadResult) {
3396
3731
  return this.configLoader.loadChildren(injector, route)
@@ -3404,33 +3739,6 @@ class ApplyRedirects {
3404
3739
  }
3405
3740
  return of({ routes: [], injector });
3406
3741
  }
3407
- runCanLoadGuards(injector, route, segments) {
3408
- const canLoad = route.canLoad;
3409
- if (!canLoad || canLoad.length === 0)
3410
- return of(true);
3411
- const canLoadObservables = canLoad.map((injectionToken) => {
3412
- const guard = injector.get(injectionToken);
3413
- let guardVal;
3414
- if (isCanLoad(guard)) {
3415
- guardVal = guard.canLoad(route, segments);
3416
- }
3417
- else if (isFunction(guard)) {
3418
- guardVal = guard(route, segments);
3419
- }
3420
- else {
3421
- throw new Error('Invalid CanLoad guard');
3422
- }
3423
- return wrapIntoObservable(guardVal);
3424
- });
3425
- return of(canLoadObservables)
3426
- .pipe(prioritizedGuardValue(), tap((result) => {
3427
- if (!isUrlTree(result))
3428
- return;
3429
- const error = navigationCancelingError(`Redirecting to "${this.urlSerializer.serialize(result)}"`);
3430
- error.url = result;
3431
- throw error;
3432
- }), map(result => result === true));
3433
- }
3434
3742
  lineralizeSegments(route, urlTree) {
3435
3743
  let res = [];
3436
3744
  let c = urlTree.root;
@@ -3443,341 +3751,58 @@ class ApplyRedirects {
3443
3751
  return namedOutletsRedirect(route.redirectTo);
3444
3752
  }
3445
3753
  c = c.children[PRIMARY_OUTLET];
3446
- }
3447
- }
3448
- applyRedirectCommands(segments, redirectTo, posParams) {
3449
- return this.applyRedirectCreatreUrlTree(redirectTo, this.urlSerializer.parse(redirectTo), segments, posParams);
3450
- }
3451
- applyRedirectCreatreUrlTree(redirectTo, urlTree, segments, posParams) {
3452
- const newRoot = this.createSegmentGroup(redirectTo, urlTree.root, segments, posParams);
3453
- return new UrlTree(newRoot, this.createQueryParams(urlTree.queryParams, this.urlTree.queryParams), urlTree.fragment);
3454
- }
3455
- createQueryParams(redirectToParams, actualParams) {
3456
- const res = {};
3457
- forEach(redirectToParams, (v, k) => {
3458
- const copySourceValue = typeof v === 'string' && v.startsWith(':');
3459
- if (copySourceValue) {
3460
- const sourceName = v.substring(1);
3461
- res[k] = actualParams[sourceName];
3462
- }
3463
- else {
3464
- res[k] = v;
3465
- }
3466
- });
3467
- return res;
3468
- }
3469
- createSegmentGroup(redirectTo, group, segments, posParams) {
3470
- const updatedSegments = this.createSegments(redirectTo, group.segments, segments, posParams);
3471
- let children = {};
3472
- forEach(group.children, (child, name) => {
3473
- children[name] = this.createSegmentGroup(redirectTo, child, segments, posParams);
3474
- });
3475
- return new UrlSegmentGroup(updatedSegments, children);
3476
- }
3477
- createSegments(redirectTo, redirectToSegments, actualSegments, posParams) {
3478
- return redirectToSegments.map(s => s.path.startsWith(':') ? this.findPosParam(redirectTo, s, posParams) :
3479
- this.findOrReturn(s, actualSegments));
3480
- }
3481
- findPosParam(redirectTo, redirectToUrlSegment, posParams) {
3482
- const pos = posParams[redirectToUrlSegment.path.substring(1)];
3483
- if (!pos)
3484
- throw new Error(`Cannot redirect to '${redirectTo}'. Cannot find '${redirectToUrlSegment.path}'.`);
3485
- return pos;
3486
- }
3487
- findOrReturn(redirectToUrlSegment, actualSegments) {
3488
- let idx = 0;
3489
- for (const s of actualSegments) {
3490
- if (s.path === redirectToUrlSegment.path) {
3491
- actualSegments.splice(idx);
3492
- return s;
3493
- }
3494
- idx++;
3495
- }
3496
- return redirectToUrlSegment;
3497
- }
3498
- }
3499
-
3500
- /**
3501
- * @license
3502
- * Copyright Google LLC All Rights Reserved.
3503
- *
3504
- * Use of this source code is governed by an MIT-style license that can be
3505
- * found in the LICENSE file at https://angular.io/license
3506
- */
3507
- function applyRedirects(environmentInjector, configLoader, urlSerializer, config) {
3508
- return switchMap(t => applyRedirects$1(environmentInjector, configLoader, urlSerializer, t.extractedUrl, config)
3509
- .pipe(map(urlAfterRedirects => (Object.assign(Object.assign({}, t), { urlAfterRedirects })))));
3510
- }
3511
-
3512
- /**
3513
- * @license
3514
- * Copyright Google LLC All Rights Reserved.
3515
- *
3516
- * Use of this source code is governed by an MIT-style license that can be
3517
- * found in the LICENSE file at https://angular.io/license
3518
- */
3519
- class CanActivate {
3520
- constructor(path) {
3521
- this.path = path;
3522
- this.route = this.path[this.path.length - 1];
3523
- }
3524
- }
3525
- class CanDeactivate {
3526
- constructor(component, route) {
3527
- this.component = component;
3528
- this.route = route;
3529
- }
3530
- }
3531
- function getAllRouteGuards(future, curr, parentContexts) {
3532
- const futureRoot = future._root;
3533
- const currRoot = curr ? curr._root : null;
3534
- return getChildRouteGuards(futureRoot, currRoot, parentContexts, [futureRoot.value]);
3535
- }
3536
- function getCanActivateChild(p) {
3537
- const canActivateChild = p.routeConfig ? p.routeConfig.canActivateChild : null;
3538
- if (!canActivateChild || canActivateChild.length === 0)
3539
- return null;
3540
- return { node: p, guards: canActivateChild };
3541
- }
3542
- function getToken(token, snapshot, fallbackInjector) {
3543
- const routeInjector = getClosestRouteInjector(snapshot);
3544
- const injector = routeInjector !== null && routeInjector !== void 0 ? routeInjector : fallbackInjector;
3545
- return injector.get(token);
3546
- }
3547
- function getChildRouteGuards(futureNode, currNode, contexts, futurePath, checks = {
3548
- canDeactivateChecks: [],
3549
- canActivateChecks: []
3550
- }) {
3551
- const prevChildren = nodeChildrenAsMap(currNode);
3552
- // Process the children of the future route
3553
- futureNode.children.forEach(c => {
3554
- getRouteGuards(c, prevChildren[c.value.outlet], contexts, futurePath.concat([c.value]), checks);
3555
- delete prevChildren[c.value.outlet];
3556
- });
3557
- // Process any children left from the current route (not active for the future route)
3558
- forEach(prevChildren, (v, k) => deactivateRouteAndItsChildren(v, contexts.getContext(k), checks));
3559
- return checks;
3560
- }
3561
- function getRouteGuards(futureNode, currNode, parentContexts, futurePath, checks = {
3562
- canDeactivateChecks: [],
3563
- canActivateChecks: []
3564
- }) {
3565
- const future = futureNode.value;
3566
- const curr = currNode ? currNode.value : null;
3567
- const context = parentContexts ? parentContexts.getContext(futureNode.value.outlet) : null;
3568
- // reusing the node
3569
- if (curr && future.routeConfig === curr.routeConfig) {
3570
- const shouldRun = shouldRunGuardsAndResolvers(curr, future, future.routeConfig.runGuardsAndResolvers);
3571
- if (shouldRun) {
3572
- checks.canActivateChecks.push(new CanActivate(futurePath));
3573
- }
3574
- else {
3575
- // we need to set the data
3576
- future.data = curr.data;
3577
- future._resolvedData = curr._resolvedData;
3578
- }
3579
- // If we have a component, we need to go through an outlet.
3580
- if (future.component) {
3581
- getChildRouteGuards(futureNode, currNode, context ? context.children : null, futurePath, checks);
3582
- // if we have a componentless route, we recurse but keep the same outlet map.
3583
- }
3584
- else {
3585
- getChildRouteGuards(futureNode, currNode, parentContexts, futurePath, checks);
3586
- }
3587
- if (shouldRun && context && context.outlet && context.outlet.isActivated) {
3588
- checks.canDeactivateChecks.push(new CanDeactivate(context.outlet.component, curr));
3589
- }
3590
- }
3591
- else {
3592
- if (curr) {
3593
- deactivateRouteAndItsChildren(currNode, context, checks);
3594
- }
3595
- checks.canActivateChecks.push(new CanActivate(futurePath));
3596
- // If we have a component, we need to go through an outlet.
3597
- if (future.component) {
3598
- getChildRouteGuards(futureNode, null, context ? context.children : null, futurePath, checks);
3599
- // if we have a componentless route, we recurse but keep the same outlet map.
3600
- }
3601
- else {
3602
- getChildRouteGuards(futureNode, null, parentContexts, futurePath, checks);
3603
- }
3604
- }
3605
- return checks;
3606
- }
3607
- function shouldRunGuardsAndResolvers(curr, future, mode) {
3608
- if (typeof mode === 'function') {
3609
- return mode(curr, future);
3610
- }
3611
- switch (mode) {
3612
- case 'pathParamsChange':
3613
- return !equalPath(curr.url, future.url);
3614
- case 'pathParamsOrQueryParamsChange':
3615
- return !equalPath(curr.url, future.url) ||
3616
- !shallowEqual(curr.queryParams, future.queryParams);
3617
- case 'always':
3618
- return true;
3619
- case 'paramsOrQueryParamsChange':
3620
- return !equalParamsAndUrlSegments(curr, future) ||
3621
- !shallowEqual(curr.queryParams, future.queryParams);
3622
- case 'paramsChange':
3623
- default:
3624
- return !equalParamsAndUrlSegments(curr, future);
3625
- }
3626
- }
3627
- function deactivateRouteAndItsChildren(route, context, checks) {
3628
- const children = nodeChildrenAsMap(route);
3629
- const r = route.value;
3630
- forEach(children, (node, childName) => {
3631
- if (!r.component) {
3632
- deactivateRouteAndItsChildren(node, context, checks);
3633
- }
3634
- else if (context) {
3635
- deactivateRouteAndItsChildren(node, context.children.getContext(childName), checks);
3636
- }
3637
- else {
3638
- deactivateRouteAndItsChildren(node, null, checks);
3639
- }
3640
- });
3641
- if (!r.component) {
3642
- checks.canDeactivateChecks.push(new CanDeactivate(null, r));
3643
- }
3644
- else if (context && context.outlet && context.outlet.isActivated) {
3645
- checks.canDeactivateChecks.push(new CanDeactivate(context.outlet.component, r));
3646
- }
3647
- else {
3648
- checks.canDeactivateChecks.push(new CanDeactivate(null, r));
3649
- }
3650
- }
3651
-
3652
- /**
3653
- * @license
3654
- * Copyright Google LLC All Rights Reserved.
3655
- *
3656
- * Use of this source code is governed by an MIT-style license that can be
3657
- * found in the LICENSE file at https://angular.io/license
3658
- */
3659
- function checkGuards(moduleInjector, forwardEvent) {
3660
- return mergeMap(t => {
3661
- const { targetSnapshot, currentSnapshot, guards: { canActivateChecks, canDeactivateChecks } } = t;
3662
- if (canDeactivateChecks.length === 0 && canActivateChecks.length === 0) {
3663
- return of(Object.assign(Object.assign({}, t), { guardsResult: true }));
3664
- }
3665
- return runCanDeactivateChecks(canDeactivateChecks, targetSnapshot, currentSnapshot, moduleInjector)
3666
- .pipe(mergeMap(canDeactivate => {
3667
- return canDeactivate && isBoolean(canDeactivate) ?
3668
- runCanActivateChecks(targetSnapshot, canActivateChecks, moduleInjector, forwardEvent) :
3669
- of(canDeactivate);
3670
- }), map(guardsResult => (Object.assign(Object.assign({}, t), { guardsResult }))));
3671
- });
3672
- }
3673
- function runCanDeactivateChecks(checks, futureRSS, currRSS, moduleInjector) {
3674
- return from(checks).pipe(mergeMap(check => runCanDeactivate(check.component, check.route, currRSS, futureRSS, moduleInjector)), first(result => {
3675
- return result !== true;
3676
- }, true));
3677
- }
3678
- function runCanActivateChecks(futureSnapshot, checks, moduleInjector, forwardEvent) {
3679
- return from(checks).pipe(concatMap((check) => {
3680
- return concat(fireChildActivationStart(check.route.parent, forwardEvent), fireActivationStart(check.route, forwardEvent), runCanActivateChild(futureSnapshot, check.path, moduleInjector), runCanActivate(futureSnapshot, check.route, moduleInjector));
3681
- }), first(result => {
3682
- return result !== true;
3683
- }, true));
3684
- }
3685
- /**
3686
- * This should fire off `ActivationStart` events for each route being activated at this
3687
- * level.
3688
- * In other words, if you're activating `a` and `b` below, `path` will contain the
3689
- * `ActivatedRouteSnapshot`s for both and we will fire `ActivationStart` for both. Always
3690
- * return
3691
- * `true` so checks continue to run.
3692
- */
3693
- function fireActivationStart(snapshot, forwardEvent) {
3694
- if (snapshot !== null && forwardEvent) {
3695
- forwardEvent(new ActivationStart(snapshot));
3696
- }
3697
- return of(true);
3698
- }
3699
- /**
3700
- * This should fire off `ChildActivationStart` events for each route being activated at this
3701
- * level.
3702
- * In other words, if you're activating `a` and `b` below, `path` will contain the
3703
- * `ActivatedRouteSnapshot`s for both and we will fire `ChildActivationStart` for both. Always
3704
- * return
3705
- * `true` so checks continue to run.
3706
- */
3707
- function fireChildActivationStart(snapshot, forwardEvent) {
3708
- if (snapshot !== null && forwardEvent) {
3709
- forwardEvent(new ChildActivationStart(snapshot));
3710
- }
3711
- return of(true);
3712
- }
3713
- function runCanActivate(futureRSS, futureARS, moduleInjector) {
3714
- const canActivate = futureARS.routeConfig ? futureARS.routeConfig.canActivate : null;
3715
- if (!canActivate || canActivate.length === 0)
3716
- return of(true);
3717
- const canActivateObservables = canActivate.map((c) => {
3718
- return defer(() => {
3719
- const guard = getToken(c, futureARS, moduleInjector);
3720
- let observable;
3721
- if (isCanActivate(guard)) {
3722
- observable = wrapIntoObservable(guard.canActivate(futureARS, futureRSS));
3723
- }
3724
- else if (isFunction(guard)) {
3725
- observable = wrapIntoObservable(guard(futureARS, futureRSS));
3754
+ }
3755
+ }
3756
+ applyRedirectCommands(segments, redirectTo, posParams) {
3757
+ return this.applyRedirectCreatreUrlTree(redirectTo, this.urlSerializer.parse(redirectTo), segments, posParams);
3758
+ }
3759
+ applyRedirectCreatreUrlTree(redirectTo, urlTree, segments, posParams) {
3760
+ const newRoot = this.createSegmentGroup(redirectTo, urlTree.root, segments, posParams);
3761
+ return new UrlTree(newRoot, this.createQueryParams(urlTree.queryParams, this.urlTree.queryParams), urlTree.fragment);
3762
+ }
3763
+ createQueryParams(redirectToParams, actualParams) {
3764
+ const res = {};
3765
+ forEach(redirectToParams, (v, k) => {
3766
+ const copySourceValue = typeof v === 'string' && v.startsWith(':');
3767
+ if (copySourceValue) {
3768
+ const sourceName = v.substring(1);
3769
+ res[k] = actualParams[sourceName];
3726
3770
  }
3727
3771
  else {
3728
- throw new Error('Invalid CanActivate guard');
3772
+ res[k] = v;
3729
3773
  }
3730
- return observable.pipe(first());
3731
3774
  });
3732
- });
3733
- return of(canActivateObservables).pipe(prioritizedGuardValue());
3734
- }
3735
- function runCanActivateChild(futureRSS, path, moduleInjector) {
3736
- const futureARS = path[path.length - 1];
3737
- const canActivateChildGuards = path.slice(0, path.length - 1)
3738
- .reverse()
3739
- .map(p => getCanActivateChild(p))
3740
- .filter(_ => _ !== null);
3741
- const canActivateChildGuardsMapped = canActivateChildGuards.map((d) => {
3742
- return defer(() => {
3743
- const guardsMapped = d.guards.map((c) => {
3744
- const guard = getToken(c, d.node, moduleInjector);
3745
- let observable;
3746
- if (isCanActivateChild(guard)) {
3747
- observable = wrapIntoObservable(guard.canActivateChild(futureARS, futureRSS));
3748
- }
3749
- else if (isFunction(guard)) {
3750
- observable = wrapIntoObservable(guard(futureARS, futureRSS));
3751
- }
3752
- else {
3753
- throw new Error('Invalid CanActivateChild guard');
3754
- }
3755
- return observable.pipe(first());
3756
- });
3757
- return of(guardsMapped).pipe(prioritizedGuardValue());
3775
+ return res;
3776
+ }
3777
+ createSegmentGroup(redirectTo, group, segments, posParams) {
3778
+ const updatedSegments = this.createSegments(redirectTo, group.segments, segments, posParams);
3779
+ let children = {};
3780
+ forEach(group.children, (child, name) => {
3781
+ children[name] = this.createSegmentGroup(redirectTo, child, segments, posParams);
3758
3782
  });
3759
- });
3760
- return of(canActivateChildGuardsMapped).pipe(prioritizedGuardValue());
3761
- }
3762
- function runCanDeactivate(component, currARS, currRSS, futureRSS, moduleInjector) {
3763
- const canDeactivate = currARS && currARS.routeConfig ? currARS.routeConfig.canDeactivate : null;
3764
- if (!canDeactivate || canDeactivate.length === 0)
3765
- return of(true);
3766
- const canDeactivateObservables = canDeactivate.map((c) => {
3767
- const guard = getToken(c, currARS, moduleInjector);
3768
- let observable;
3769
- if (isCanDeactivate(guard)) {
3770
- observable = wrapIntoObservable(guard.canDeactivate(component, currARS, currRSS, futureRSS));
3771
- }
3772
- else if (isFunction(guard)) {
3773
- observable = wrapIntoObservable(guard(component, currARS, currRSS, futureRSS));
3774
- }
3775
- else {
3776
- throw new Error('Invalid CanDeactivate guard');
3783
+ return new UrlSegmentGroup(updatedSegments, children);
3784
+ }
3785
+ createSegments(redirectTo, redirectToSegments, actualSegments, posParams) {
3786
+ return redirectToSegments.map(s => s.path.startsWith(':') ? this.findPosParam(redirectTo, s, posParams) :
3787
+ this.findOrReturn(s, actualSegments));
3788
+ }
3789
+ findPosParam(redirectTo, redirectToUrlSegment, posParams) {
3790
+ const pos = posParams[redirectToUrlSegment.path.substring(1)];
3791
+ if (!pos)
3792
+ throw new Error(`Cannot redirect to '${redirectTo}'. Cannot find '${redirectToUrlSegment.path}'.`);
3793
+ return pos;
3794
+ }
3795
+ findOrReturn(redirectToUrlSegment, actualSegments) {
3796
+ let idx = 0;
3797
+ for (const s of actualSegments) {
3798
+ if (s.path === redirectToUrlSegment.path) {
3799
+ actualSegments.splice(idx);
3800
+ return s;
3801
+ }
3802
+ idx++;
3777
3803
  }
3778
- return observable.pipe(first());
3779
- });
3780
- return of(canDeactivateObservables).pipe(prioritizedGuardValue());
3804
+ return redirectToUrlSegment;
3805
+ }
3781
3806
  }
3782
3807
 
3783
3808
  /**
@@ -3787,53 +3812,64 @@ function runCanDeactivate(component, currARS, currRSS, futureRSS, moduleInjector
3787
3812
  * Use of this source code is governed by an MIT-style license that can be
3788
3813
  * found in the LICENSE file at https://angular.io/license
3789
3814
  */
3790
- const NG_DEV_MODE$2 = typeof ngDevMode === 'undefined' || !!ngDevMode;
3815
+ function applyRedirects(environmentInjector, configLoader, urlSerializer, config) {
3816
+ return switchMap(t => applyRedirects$1(environmentInjector, configLoader, urlSerializer, t.extractedUrl, config)
3817
+ .pipe(map(urlAfterRedirects => (Object.assign(Object.assign({}, t), { urlAfterRedirects })))));
3818
+ }
3819
+
3820
+ /**
3821
+ * @license
3822
+ * Copyright Google LLC All Rights Reserved.
3823
+ *
3824
+ * Use of this source code is governed by an MIT-style license that can be
3825
+ * found in the LICENSE file at https://angular.io/license
3826
+ */
3827
+ const NG_DEV_MODE$3 = typeof ngDevMode === 'undefined' || !!ngDevMode;
3791
3828
  class NoMatch {
3792
3829
  }
3793
3830
  function newObservableError(e) {
3794
3831
  // TODO(atscott): This pattern is used throughout the router code and can be `throwError` instead.
3795
3832
  return new Observable((obs) => obs.error(e));
3796
3833
  }
3797
- function recognize$1(rootComponentType, config, urlTree, url, paramsInheritanceStrategy = 'emptyOnly', relativeLinkResolution = 'legacy') {
3798
- try {
3799
- const result = new Recognizer(rootComponentType, config, urlTree, url, paramsInheritanceStrategy, relativeLinkResolution)
3800
- .recognize();
3834
+ function recognize$1(injector, rootComponentType, config, urlTree, url, urlSerializer, paramsInheritanceStrategy = 'emptyOnly', relativeLinkResolution = 'legacy') {
3835
+ return new Recognizer(injector, rootComponentType, config, urlTree, url, paramsInheritanceStrategy, relativeLinkResolution, urlSerializer)
3836
+ .recognize()
3837
+ .pipe(switchMap(result => {
3801
3838
  if (result === null) {
3802
3839
  return newObservableError(new NoMatch());
3803
3840
  }
3804
3841
  else {
3805
3842
  return of(result);
3806
3843
  }
3807
- }
3808
- catch (e) {
3809
- // Catch the potential error from recognize due to duplicate outlet matches and return as an
3810
- // `Observable` error instead.
3811
- return newObservableError(e);
3812
- }
3844
+ }));
3813
3845
  }
3814
3846
  class Recognizer {
3815
- constructor(rootComponentType, config, urlTree, url, paramsInheritanceStrategy, relativeLinkResolution) {
3847
+ constructor(injector, rootComponentType, config, urlTree, url, paramsInheritanceStrategy, relativeLinkResolution, urlSerializer) {
3848
+ this.injector = injector;
3816
3849
  this.rootComponentType = rootComponentType;
3817
3850
  this.config = config;
3818
3851
  this.urlTree = urlTree;
3819
3852
  this.url = url;
3820
3853
  this.paramsInheritanceStrategy = paramsInheritanceStrategy;
3821
3854
  this.relativeLinkResolution = relativeLinkResolution;
3855
+ this.urlSerializer = urlSerializer;
3822
3856
  }
3823
3857
  recognize() {
3824
3858
  const rootSegmentGroup = split(this.urlTree.root, [], [], this.config.filter(c => c.redirectTo === undefined), this.relativeLinkResolution)
3825
3859
  .segmentGroup;
3826
- const children = this.processSegmentGroup(this.config, rootSegmentGroup, PRIMARY_OUTLET);
3827
- if (children === null) {
3828
- return null;
3829
- }
3830
- // Use Object.freeze to prevent readers of the Router state from modifying it outside of a
3831
- // navigation, resulting in the router being out of sync with the browser.
3832
- const root = new ActivatedRouteSnapshot([], Object.freeze({}), Object.freeze(Object.assign({}, this.urlTree.queryParams)), this.urlTree.fragment, {}, PRIMARY_OUTLET, this.rootComponentType, null, this.urlTree.root, -1, {});
3833
- const rootNode = new TreeNode(root, children);
3834
- const routeState = new RouterStateSnapshot(this.url, rootNode);
3835
- this.inheritParamsAndData(routeState._root);
3836
- return routeState;
3860
+ return this.processSegmentGroup(this.injector, this.config, rootSegmentGroup, PRIMARY_OUTLET)
3861
+ .pipe(map(children => {
3862
+ if (children === null) {
3863
+ return null;
3864
+ }
3865
+ // Use Object.freeze to prevent readers of the Router state from modifying it outside of a
3866
+ // navigation, resulting in the router being out of sync with the browser.
3867
+ const root = new ActivatedRouteSnapshot([], Object.freeze({}), Object.freeze(Object.assign({}, this.urlTree.queryParams)), this.urlTree.fragment, {}, PRIMARY_OUTLET, this.rootComponentType, null, this.urlTree.root, -1, {});
3868
+ const rootNode = new TreeNode(root, children);
3869
+ const routeState = new RouterStateSnapshot(this.url, rootNode);
3870
+ this.inheritParamsAndData(routeState._root);
3871
+ return routeState;
3872
+ }));
3837
3873
  }
3838
3874
  inheritParamsAndData(routeNode) {
3839
3875
  const route = routeNode.value;
@@ -3842,11 +3878,11 @@ class Recognizer {
3842
3878
  route.data = Object.freeze(i.data);
3843
3879
  routeNode.children.forEach(n => this.inheritParamsAndData(n));
3844
3880
  }
3845
- processSegmentGroup(config, segmentGroup, outlet) {
3881
+ processSegmentGroup(injector, config, segmentGroup, outlet) {
3846
3882
  if (segmentGroup.segments.length === 0 && segmentGroup.hasChildren()) {
3847
- return this.processChildren(config, segmentGroup);
3883
+ return this.processChildren(injector, config, segmentGroup);
3848
3884
  }
3849
- return this.processSegment(config, segmentGroup, segmentGroup.segments, outlet);
3885
+ return this.processSegment(injector, config, segmentGroup, segmentGroup.segments, outlet);
3850
3886
  }
3851
3887
  /**
3852
3888
  * Matches every child outlet in the `segmentGroup` to a `Route` in the config. Returns `null` if
@@ -3856,103 +3892,129 @@ class Recognizer {
3856
3892
  * @param segmentGroup - The `UrlSegmentGroup` whose children need to be matched against the
3857
3893
  * config.
3858
3894
  */
3859
- processChildren(config, segmentGroup) {
3860
- const children = [];
3861
- for (const childOutlet of Object.keys(segmentGroup.children)) {
3895
+ processChildren(injector, config, segmentGroup) {
3896
+ return from(Object.keys(segmentGroup.children))
3897
+ .pipe(concatMap(childOutlet => {
3862
3898
  const child = segmentGroup.children[childOutlet];
3863
- // Sort the config so that routes with outlets that match the one being activated appear
3864
- // first, followed by routes for other outlets, which might match if they have an empty path.
3899
+ // Sort the config so that routes with outlets that match the one being activated
3900
+ // appear first, followed by routes for other outlets, which might match if they have
3901
+ // an empty path.
3865
3902
  const sortedConfig = sortByMatchingOutlets(config, childOutlet);
3866
- const outletChildren = this.processSegmentGroup(sortedConfig, child, childOutlet);
3867
- if (outletChildren === null) {
3868
- // Configs must match all segment children so because we did not find a match for this
3869
- // outlet, return `null`.
3903
+ return this.processSegmentGroup(injector, sortedConfig, child, childOutlet);
3904
+ }), scan((children, outletChildren) => {
3905
+ if (!children || !outletChildren)
3870
3906
  return null;
3871
- }
3872
3907
  children.push(...outletChildren);
3873
- }
3874
- // Because we may have matched two outlets to the same empty path segment, we can have multiple
3875
- // activated results for the same outlet. We should merge the children of these results so the
3876
- // final return value is only one `TreeNode` per outlet.
3877
- const mergedChildren = mergeEmptyPathMatches(children);
3878
- if (typeof ngDevMode === 'undefined' || ngDevMode) {
3879
- // This should really never happen - we are only taking the first match for each outlet and
3880
- // merge the empty path matches.
3881
- checkOutletNameUniqueness(mergedChildren);
3882
- }
3883
- sortActivatedRouteSnapshots(mergedChildren);
3884
- return mergedChildren;
3885
- }
3886
- processSegment(config, segmentGroup, segments, outlet) {
3887
- for (const r of config) {
3888
- const children = this.processSegmentAgainstRoute(r, segmentGroup, segments, outlet);
3889
- if (children !== null) {
3890
- return children;
3908
+ return children;
3909
+ }), takeWhile(children => children !== null), defaultIfEmpty(null), last$1(), map(children => {
3910
+ if (children === null)
3911
+ return null;
3912
+ // Because we may have matched two outlets to the same empty path segment, we can have
3913
+ // multiple activated results for the same outlet. We should merge the children of
3914
+ // these results so the final return value is only one `TreeNode` per outlet.
3915
+ const mergedChildren = mergeEmptyPathMatches(children);
3916
+ if (typeof ngDevMode === 'undefined' || ngDevMode) {
3917
+ // This should really never happen - we are only taking the first match for each
3918
+ // outlet and merge the empty path matches.
3919
+ checkOutletNameUniqueness(mergedChildren);
3891
3920
  }
3892
- }
3893
- if (noLeftoversInUrl(segmentGroup, segments, outlet)) {
3894
- return [];
3895
- }
3896
- return null;
3921
+ sortActivatedRouteSnapshots(mergedChildren);
3922
+ return mergedChildren;
3923
+ }));
3924
+ }
3925
+ processSegment(injector, routes, segmentGroup, segments, outlet) {
3926
+ return from(routes).pipe(concatMap(r => {
3927
+ var _a;
3928
+ return this.processSegmentAgainstRoute((_a = r._injector) !== null && _a !== void 0 ? _a : injector, r, segmentGroup, segments, outlet);
3929
+ }), first((x) => !!x), catchError(e => {
3930
+ if (e instanceof EmptyError) {
3931
+ if (noLeftoversInUrl(segmentGroup, segments, outlet)) {
3932
+ return of([]);
3933
+ }
3934
+ return of(null);
3935
+ }
3936
+ throw e;
3937
+ }));
3897
3938
  }
3898
- processSegmentAgainstRoute(route, rawSegment, segments, outlet) {
3899
- var _a, _b, _c, _d;
3939
+ processSegmentAgainstRoute(injector, route, rawSegment, segments, outlet) {
3940
+ var _a, _b;
3900
3941
  if (route.redirectTo || !isImmediateMatch(route, rawSegment, segments, outlet))
3901
- return null;
3902
- let snapshot;
3903
- let consumedSegments = [];
3904
- let remainingSegments = [];
3942
+ return of(null);
3943
+ let matchResult;
3905
3944
  if (route.path === '**') {
3906
3945
  const params = segments.length > 0 ? last(segments).parameters : {};
3907
3946
  const pathIndexShift = getPathIndexShift(rawSegment) + segments.length;
3908
- snapshot = new ActivatedRouteSnapshot(segments, params, Object.freeze(Object.assign({}, this.urlTree.queryParams)), this.urlTree.fragment, getData(route), getOutlet(route), (_b = (_a = route.component) !== null && _a !== void 0 ? _a : route._loadedComponent) !== null && _b !== void 0 ? _b : null, route, getSourceSegmentGroup(rawSegment), pathIndexShift, getResolve(route),
3947
+ const snapshot = new ActivatedRouteSnapshot(segments, params, Object.freeze(Object.assign({}, this.urlTree.queryParams)), this.urlTree.fragment, getData(route), getOutlet(route), (_b = (_a = route.component) !== null && _a !== void 0 ? _a : route._loadedComponent) !== null && _b !== void 0 ? _b : null, route, getSourceSegmentGroup(rawSegment), pathIndexShift, getResolve(route),
3909
3948
  // NG_DEV_MODE is used to prevent the getCorrectedPathIndexShift function from affecting
3910
3949
  // production bundle size. This value is intended only to surface a warning to users
3911
3950
  // depending on `relativeLinkResolution: 'legacy'` in dev mode.
3912
- (NG_DEV_MODE$2 ? getCorrectedPathIndexShift(rawSegment) + segments.length :
3951
+ (NG_DEV_MODE$3 ? getCorrectedPathIndexShift(rawSegment) + segments.length :
3913
3952
  pathIndexShift));
3953
+ matchResult = of({
3954
+ snapshot,
3955
+ consumedSegments: [],
3956
+ remainingSegments: [],
3957
+ });
3914
3958
  }
3915
3959
  else {
3916
- const result = match(rawSegment, route, segments);
3917
- if (!result.matched) {
3918
- return null;
3919
- }
3920
- consumedSegments = result.consumedSegments;
3921
- remainingSegments = result.remainingSegments;
3922
- const pathIndexShift = getPathIndexShift(rawSegment) + consumedSegments.length;
3923
- snapshot = new ActivatedRouteSnapshot(consumedSegments, result.parameters, Object.freeze(Object.assign({}, this.urlTree.queryParams)), this.urlTree.fragment, getData(route), getOutlet(route), (_d = (_c = route.component) !== null && _c !== void 0 ? _c : route._loadedComponent) !== null && _d !== void 0 ? _d : null, route, getSourceSegmentGroup(rawSegment), pathIndexShift, getResolve(route), (NG_DEV_MODE$2 ? getCorrectedPathIndexShift(rawSegment) + consumedSegments.length :
3924
- pathIndexShift));
3960
+ matchResult =
3961
+ matchWithChecks(rawSegment, route, segments, injector, this.urlSerializer)
3962
+ .pipe(map(({ matched, consumedSegments, remainingSegments, parameters }) => {
3963
+ var _a, _b;
3964
+ if (!matched) {
3965
+ return null;
3966
+ }
3967
+ const pathIndexShift = getPathIndexShift(rawSegment) + consumedSegments.length;
3968
+ const snapshot = new ActivatedRouteSnapshot(consumedSegments, parameters, Object.freeze(Object.assign({}, this.urlTree.queryParams)), this.urlTree.fragment, getData(route), getOutlet(route), (_b = (_a = route.component) !== null && _a !== void 0 ? _a : route._loadedComponent) !== null && _b !== void 0 ? _b : null, route, getSourceSegmentGroup(rawSegment), pathIndexShift, getResolve(route), (NG_DEV_MODE$3 ?
3969
+ getCorrectedPathIndexShift(rawSegment) + consumedSegments.length :
3970
+ pathIndexShift));
3971
+ return { snapshot, consumedSegments, remainingSegments };
3972
+ }));
3925
3973
  }
3926
- const childConfig = getChildConfig(route);
3927
- const { segmentGroup, slicedSegments } = split(rawSegment, consumedSegments, remainingSegments,
3928
- // Filter out routes with redirectTo because we are trying to create activated route
3929
- // snapshots and don't handle redirects here. That should have been done in
3930
- // `applyRedirects`.
3931
- childConfig.filter(c => c.redirectTo === undefined), this.relativeLinkResolution);
3932
- if (slicedSegments.length === 0 && segmentGroup.hasChildren()) {
3933
- const children = this.processChildren(childConfig, segmentGroup);
3934
- if (children === null) {
3935
- return null;
3974
+ return matchResult.pipe(switchMap((result) => {
3975
+ var _a, _b;
3976
+ if (result === null) {
3977
+ return of(null);
3936
3978
  }
3937
- return [new TreeNode(snapshot, children)];
3938
- }
3939
- if (childConfig.length === 0 && slicedSegments.length === 0) {
3940
- return [new TreeNode(snapshot, [])];
3941
- }
3942
- const matchedOnOutlet = getOutlet(route) === outlet;
3943
- // If we matched a config due to empty path match on a different outlet, we need to continue
3944
- // passing the current outlet for the segment rather than switch to PRIMARY.
3945
- // Note that we switch to primary when we have a match because outlet configs look like this:
3946
- // {path: 'a', outlet: 'a', children: [
3947
- // {path: 'b', component: B},
3948
- // {path: 'c', component: C},
3949
- // ]}
3950
- // Notice that the children of the named outlet are configured with the primary outlet
3951
- const children = this.processSegment(childConfig, segmentGroup, slicedSegments, matchedOnOutlet ? PRIMARY_OUTLET : outlet);
3952
- if (children === null) {
3953
- return null;
3954
- }
3955
- return [new TreeNode(snapshot, children)];
3979
+ const { snapshot, consumedSegments, remainingSegments } = result;
3980
+ // If the route has an injector created from providers, we should start using that.
3981
+ injector = (_a = route._injector) !== null && _a !== void 0 ? _a : injector;
3982
+ const childInjector = (_b = route._loadedInjector) !== null && _b !== void 0 ? _b : injector;
3983
+ const childConfig = getChildConfig(route);
3984
+ const { segmentGroup, slicedSegments } = split(rawSegment, consumedSegments, remainingSegments,
3985
+ // Filter out routes with redirectTo because we are trying to create activated route
3986
+ // snapshots and don't handle redirects here. That should have been done in
3987
+ // `applyRedirects`.
3988
+ childConfig.filter(c => c.redirectTo === undefined), this.relativeLinkResolution);
3989
+ if (slicedSegments.length === 0 && segmentGroup.hasChildren()) {
3990
+ return this.processChildren(childInjector, childConfig, segmentGroup).pipe(map(children => {
3991
+ if (children === null) {
3992
+ return null;
3993
+ }
3994
+ return [new TreeNode(snapshot, children)];
3995
+ }));
3996
+ }
3997
+ if (childConfig.length === 0 && slicedSegments.length === 0) {
3998
+ return of([new TreeNode(snapshot, [])]);
3999
+ }
4000
+ const matchedOnOutlet = getOutlet(route) === outlet;
4001
+ // If we matched a config due to empty path match on a different outlet, we need to
4002
+ // continue passing the current outlet for the segment rather than switch to PRIMARY.
4003
+ // Note that we switch to primary when we have a match because outlet configs look like
4004
+ // this: {path: 'a', outlet: 'a', children: [
4005
+ // {path: 'b', component: B},
4006
+ // {path: 'c', component: C},
4007
+ // ]}
4008
+ // Notice that the children of the named outlet are configured with the primary outlet
4009
+ return this
4010
+ .processSegment(childInjector, childConfig, segmentGroup, slicedSegments, matchedOnOutlet ? PRIMARY_OUTLET : outlet)
4011
+ .pipe(map(children => {
4012
+ if (children === null) {
4013
+ return null;
4014
+ }
4015
+ return [new TreeNode(snapshot, children)];
4016
+ }));
4017
+ }));
3956
4018
  }
3957
4019
  }
3958
4020
  function sortActivatedRouteSnapshots(nodes) {
@@ -3978,9 +4040,9 @@ function hasEmptyPathConfig(node) {
3978
4040
  return config && config.path === '' && config.redirectTo === undefined;
3979
4041
  }
3980
4042
  /**
3981
- * Finds `TreeNode`s with matching empty path route configs and merges them into `TreeNode` with the
3982
- * children from each duplicate. This is necessary because different outlets can match a single
3983
- * empty path route config and the results need to then be merged.
4043
+ * Finds `TreeNode`s with matching empty path route configs and merges them into `TreeNode` with
4044
+ * the children from each duplicate. This is necessary because different outlets can match a
4045
+ * single empty path route config and the results need to then be merged.
3984
4046
  */
3985
4047
  function mergeEmptyPathMatches(nodes) {
3986
4048
  const result = [];
@@ -4001,9 +4063,9 @@ function mergeEmptyPathMatches(nodes) {
4001
4063
  }
4002
4064
  }
4003
4065
  // For each node which has children from multiple sources, we need to recompute a new `TreeNode`
4004
- // by also merging those children. This is necessary when there are multiple empty path configs in
4005
- // a row. Put another way: whenever we combine children of two nodes, we need to also check if any
4006
- // of those children can be combined into a single node as well.
4066
+ // by also merging those children. This is necessary when there are multiple empty path configs
4067
+ // in a row. Put another way: whenever we combine children of two nodes, we need to also check
4068
+ // if any of those children can be combined into a single node as well.
4007
4069
  for (const mergedNode of mergedNodes) {
4008
4070
  const mergedChildren = mergeEmptyPathMatches(mergedNode.children);
4009
4071
  result.push(new TreeNode(mergedNode.value, mergedChildren));
@@ -4063,8 +4125,8 @@ function getResolve(route) {
4063
4125
  * Use of this source code is governed by an MIT-style license that can be
4064
4126
  * found in the LICENSE file at https://angular.io/license
4065
4127
  */
4066
- function recognize(rootComponentType, config, serializer, paramsInheritanceStrategy, relativeLinkResolution) {
4067
- return mergeMap(t => recognize$1(rootComponentType, config, t.urlAfterRedirects, serializer(t.urlAfterRedirects), paramsInheritanceStrategy, relativeLinkResolution)
4128
+ function recognize(injector, rootComponentType, config, serializer, paramsInheritanceStrategy, relativeLinkResolution) {
4129
+ return mergeMap(t => recognize$1(injector, rootComponentType, config, t.urlAfterRedirects, serializer.serialize(t.urlAfterRedirects), serializer, paramsInheritanceStrategy, relativeLinkResolution)
4068
4130
  .pipe(map(targetSnapshot => (Object.assign(Object.assign({}, t), { targetSnapshot })))));
4069
4131
  }
4070
4132
 
@@ -4226,7 +4288,7 @@ class DefaultRouteReuseStrategy extends BaseRouteReuseStrategy {
4226
4288
  * Use of this source code is governed by an MIT-style license that can be
4227
4289
  * found in the LICENSE file at https://angular.io/license
4228
4290
  */
4229
- const NG_DEV_MODE$1 = typeof ngDevMode === 'undefined' || !!ngDevMode;
4291
+ const NG_DEV_MODE$2 = typeof ngDevMode === 'undefined' || !!ngDevMode;
4230
4292
  /**
4231
4293
  * The [DI token](guide/glossary/#di-token) for a router configuration.
4232
4294
  *
@@ -4261,7 +4323,7 @@ class RouterConfigLoader {
4261
4323
  if (this.onLoadEndListener) {
4262
4324
  this.onLoadEndListener(route);
4263
4325
  }
4264
- NG_DEV_MODE$1 && assertStandalone((_a = route.path) !== null && _a !== void 0 ? _a : '', component);
4326
+ NG_DEV_MODE$2 && assertStandalone((_a = route.path) !== null && _a !== void 0 ? _a : '', component);
4265
4327
  route._loadedComponent = component;
4266
4328
  }), finalize(() => {
4267
4329
  this.componentLoaders.delete(route);
@@ -4304,7 +4366,7 @@ class RouterConfigLoader {
4304
4366
  rawRoutes = flatten(injector.get(ROUTES, [], InjectFlags.Self | InjectFlags.Optional));
4305
4367
  }
4306
4368
  const routes = rawRoutes.map(standardizeConfig);
4307
- NG_DEV_MODE$1 && validateConfig(routes, route.path, requireStandaloneComponents);
4369
+ NG_DEV_MODE$2 && validateConfig(routes, route.path, requireStandaloneComponents);
4308
4370
  return { routes, injector };
4309
4371
  }), finalize(() => {
4310
4372
  this.childrenLoaders.delete(route);
@@ -4326,9 +4388,9 @@ class RouterConfigLoader {
4326
4388
  }));
4327
4389
  }
4328
4390
  }
4329
- RouterConfigLoader.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.0-next.0", ngImport: i0, type: RouterConfigLoader, deps: [{ token: i0.Injector }, { token: i0.Compiler }], target: i0.ɵɵFactoryTarget.Injectable });
4330
- RouterConfigLoader.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.1.0-next.0", ngImport: i0, type: RouterConfigLoader });
4331
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.0-next.0", ngImport: i0, type: RouterConfigLoader, decorators: [{
4391
+ RouterConfigLoader.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.0-next.3", ngImport: i0, type: RouterConfigLoader, deps: [{ token: i0.Injector }, { token: i0.Compiler }], target: i0.ɵɵFactoryTarget.Injectable });
4392
+ RouterConfigLoader.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.1.0-next.3", ngImport: i0, type: RouterConfigLoader });
4393
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.0-next.3", ngImport: i0, type: RouterConfigLoader, decorators: [{
4332
4394
  type: Injectable
4333
4395
  }], ctorParameters: function () { return [{ type: i0.Injector }, { type: i0.Compiler }]; } });
4334
4396
 
@@ -4363,19 +4425,13 @@ class DefaultUrlHandlingStrategy {
4363
4425
  }
4364
4426
  }
4365
4427
 
4366
- const NG_DEV_MODE = typeof ngDevMode === 'undefined' || !!ngDevMode;
4428
+ const NG_DEV_MODE$1 = typeof ngDevMode === 'undefined' || !!ngDevMode;
4367
4429
  function defaultErrorHandler(error) {
4368
4430
  throw error;
4369
4431
  }
4370
4432
  function defaultMalformedUriErrorHandler(error, urlSerializer, url) {
4371
4433
  return urlSerializer.parse('/');
4372
4434
  }
4373
- /**
4374
- * @internal
4375
- */
4376
- function defaultRouterHook(snapshot, runExtras) {
4377
- return of(null);
4378
- }
4379
4435
  /**
4380
4436
  * The equivalent `IsActiveMatchOptions` options for `Router.isActive` is called with `true`
4381
4437
  * (exact = true).
@@ -4455,13 +4511,12 @@ class Router {
4455
4511
  this.navigated = false;
4456
4512
  this.lastSuccessfulId = -1;
4457
4513
  /**
4458
- * Hooks that enable you to pause navigation,
4459
- * either before or after the preactivation phase.
4514
+ * Hook that enables you to pause navigation after the preactivation phase.
4460
4515
  * Used by `RouterModule`.
4461
4516
  *
4462
4517
  * @internal
4463
4518
  */
4464
- this.hooks = { beforePreactivation: defaultRouterHook, afterPreactivation: defaultRouterHook };
4519
+ this.afterPreactivation = () => of(void 0);
4465
4520
  /**
4466
4521
  * A strategy for extracting and merging URLs.
4467
4522
  * Used for AngularJS to Angular migrations.
@@ -4638,7 +4693,7 @@ class Router {
4638
4693
  this.currentNavigation = Object.assign(Object.assign({}, this.currentNavigation), { finalUrl: t.urlAfterRedirects });
4639
4694
  }),
4640
4695
  // Recognize
4641
- recognize(this.rootComponentType, this.config, (url) => this.serializeUrl(url), this.paramsInheritanceStrategy, this.relativeLinkResolution),
4696
+ recognize(this.ngModule.injector, this.rootComponentType, this.config, this.urlSerializer, this.paramsInheritanceStrategy, this.relativeLinkResolution),
4642
4697
  // Update URL if in `eager` update mode
4643
4698
  tap(t => {
4644
4699
  if (this.urlUpdateStrategy === 'eager') {
@@ -4678,17 +4733,6 @@ class Router {
4678
4733
  }
4679
4734
  }
4680
4735
  }),
4681
- // Before Preactivation
4682
- switchTap(t => {
4683
- const { targetSnapshot, id: navigationId, extractedUrl: appliedUrlTree, rawUrl: rawUrlTree, extras: { skipLocationChange, replaceUrl } } = t;
4684
- return this.hooks.beforePreactivation(targetSnapshot, {
4685
- navigationId,
4686
- appliedUrlTree,
4687
- rawUrlTree,
4688
- skipLocationChange: !!skipLocationChange,
4689
- replaceUrl: !!replaceUrl,
4690
- });
4691
- }),
4692
4736
  // --- GUARDS ---
4693
4737
  tap(t => {
4694
4738
  const guardsStart = new GuardsCheckStart(t.id, this.serializeUrl(t.extractedUrl), this.serializeUrl(t.urlAfterRedirects), t.targetSnapshot);
@@ -4732,18 +4776,7 @@ class Router {
4732
4776
  }));
4733
4777
  }
4734
4778
  return undefined;
4735
- }),
4736
- // --- AFTER PREACTIVATION ---
4737
- switchTap((t) => {
4738
- const { targetSnapshot, id: navigationId, extractedUrl: appliedUrlTree, rawUrl: rawUrlTree, extras: { skipLocationChange, replaceUrl } } = t;
4739
- return this.hooks.afterPreactivation(targetSnapshot, {
4740
- navigationId,
4741
- appliedUrlTree,
4742
- rawUrlTree,
4743
- skipLocationChange: !!skipLocationChange,
4744
- replaceUrl: !!replaceUrl,
4745
- });
4746
- }),
4779
+ }), switchTap(() => this.afterPreactivation()),
4747
4780
  // --- LOAD COMPONENTS ---
4748
4781
  switchTap((t) => {
4749
4782
  const loadComponents = (route) => {
@@ -4963,7 +4996,7 @@ class Router {
4963
4996
  * ```
4964
4997
  */
4965
4998
  resetConfig(config) {
4966
- NG_DEV_MODE && validateConfig(config);
4999
+ NG_DEV_MODE$1 && validateConfig(config);
4967
5000
  this.config = config.map(standardizeConfig);
4968
5001
  this.navigated = false;
4969
5002
  this.lastSuccessfulId = -1;
@@ -5321,9 +5354,9 @@ class Router {
5321
5354
  return { navigationId };
5322
5355
  }
5323
5356
  }
5324
- Router.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.0-next.0", ngImport: i0, type: Router, deps: "invalid", target: i0.ɵɵFactoryTarget.Injectable });
5325
- Router.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.1.0-next.0", ngImport: i0, type: Router });
5326
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.0-next.0", ngImport: i0, type: Router, decorators: [{
5357
+ Router.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.0-next.3", ngImport: i0, type: Router, deps: "invalid", target: i0.ɵɵFactoryTarget.Injectable });
5358
+ Router.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.1.0-next.3", ngImport: i0, type: Router });
5359
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.0-next.3", ngImport: i0, type: Router, decorators: [{
5327
5360
  type: Injectable
5328
5361
  }], ctorParameters: function () { return [{ type: i0.Type }, { type: UrlSerializer }, { type: ChildrenOutletContexts }, { type: i3.Location }, { type: i0.Injector }, { type: i0.Compiler }, { type: undefined }]; } });
5329
5362
  function validateCommands(commands) {
@@ -5515,9 +5548,9 @@ class RouterLink {
5515
5548
  });
5516
5549
  }
5517
5550
  }
5518
- RouterLink.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.0-next.0", ngImport: i0, type: RouterLink, deps: [{ token: Router }, { token: ActivatedRoute }, { token: 'tabindex', attribute: true }, { token: i0.Renderer2 }, { token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Directive });
5519
- RouterLink.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "14.1.0-next.0", type: RouterLink, selector: ":not(a):not(area)[routerLink]", inputs: { queryParams: "queryParams", fragment: "fragment", queryParamsHandling: "queryParamsHandling", preserveFragment: "preserveFragment", skipLocationChange: "skipLocationChange", replaceUrl: "replaceUrl", state: "state", relativeTo: "relativeTo", routerLink: "routerLink" }, host: { listeners: { "click": "onClick()" } }, usesOnChanges: true, ngImport: i0 });
5520
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.0-next.0", ngImport: i0, type: RouterLink, decorators: [{
5551
+ RouterLink.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.0-next.3", ngImport: i0, type: RouterLink, deps: [{ token: Router }, { token: ActivatedRoute }, { token: 'tabindex', attribute: true }, { token: i0.Renderer2 }, { token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Directive });
5552
+ RouterLink.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "14.1.0-next.3", type: RouterLink, selector: ":not(a):not(area)[routerLink]", inputs: { queryParams: "queryParams", fragment: "fragment", queryParamsHandling: "queryParamsHandling", preserveFragment: "preserveFragment", skipLocationChange: "skipLocationChange", replaceUrl: "replaceUrl", state: "state", relativeTo: "relativeTo", routerLink: "routerLink" }, host: { listeners: { "click": "onClick()" } }, usesOnChanges: true, ngImport: i0 });
5553
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.0-next.3", ngImport: i0, type: RouterLink, decorators: [{
5521
5554
  type: Directive,
5522
5555
  args: [{ selector: ':not(a):not(area)[routerLink]' }]
5523
5556
  }], ctorParameters: function () {
@@ -5636,9 +5669,9 @@ class RouterLinkWithHref {
5636
5669
  });
5637
5670
  }
5638
5671
  }
5639
- RouterLinkWithHref.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.0-next.0", ngImport: i0, type: RouterLinkWithHref, deps: [{ token: Router }, { token: ActivatedRoute }, { token: i3.LocationStrategy }], target: i0.ɵɵFactoryTarget.Directive });
5640
- RouterLinkWithHref.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "14.1.0-next.0", type: RouterLinkWithHref, selector: "a[routerLink],area[routerLink]", inputs: { target: "target", queryParams: "queryParams", fragment: "fragment", queryParamsHandling: "queryParamsHandling", preserveFragment: "preserveFragment", skipLocationChange: "skipLocationChange", replaceUrl: "replaceUrl", state: "state", relativeTo: "relativeTo", routerLink: "routerLink" }, host: { listeners: { "click": "onClick($event.button,$event.ctrlKey,$event.shiftKey,$event.altKey,$event.metaKey)" }, properties: { "attr.target": "this.target", "attr.href": "this.href" } }, usesOnChanges: true, ngImport: i0 });
5641
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.0-next.0", ngImport: i0, type: RouterLinkWithHref, decorators: [{
5672
+ RouterLinkWithHref.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.0-next.3", ngImport: i0, type: RouterLinkWithHref, deps: [{ token: Router }, { token: ActivatedRoute }, { token: i3.LocationStrategy }], target: i0.ɵɵFactoryTarget.Directive });
5673
+ RouterLinkWithHref.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "14.1.0-next.3", type: RouterLinkWithHref, selector: "a[routerLink],area[routerLink]", inputs: { target: "target", queryParams: "queryParams", fragment: "fragment", queryParamsHandling: "queryParamsHandling", preserveFragment: "preserveFragment", skipLocationChange: "skipLocationChange", replaceUrl: "replaceUrl", state: "state", relativeTo: "relativeTo", routerLink: "routerLink" }, host: { listeners: { "click": "onClick($event.button,$event.ctrlKey,$event.shiftKey,$event.altKey,$event.metaKey)" }, properties: { "attr.target": "this.target", "attr.href": "this.href" } }, usesOnChanges: true, ngImport: i0 });
5674
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.0-next.3", ngImport: i0, type: RouterLinkWithHref, decorators: [{
5642
5675
  type: Directive,
5643
5676
  args: [{ selector: 'a[routerLink],area[routerLink]' }]
5644
5677
  }], ctorParameters: function () { return [{ type: Router }, { type: ActivatedRoute }, { type: i3.LocationStrategy }]; }, propDecorators: { target: [{
@@ -5865,9 +5898,9 @@ class RouterLinkActive {
5865
5898
  this.links.some(isActiveCheckFn) || this.linksWithHrefs.some(isActiveCheckFn);
5866
5899
  }
5867
5900
  }
5868
- RouterLinkActive.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.0-next.0", ngImport: i0, type: RouterLinkActive, deps: [{ token: Router }, { token: i0.ElementRef }, { token: i0.Renderer2 }, { token: i0.ChangeDetectorRef }, { token: RouterLink, optional: true }, { token: RouterLinkWithHref, optional: true }], target: i0.ɵɵFactoryTarget.Directive });
5869
- RouterLinkActive.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "14.1.0-next.0", type: RouterLinkActive, selector: "[routerLinkActive]", inputs: { routerLinkActiveOptions: "routerLinkActiveOptions", ariaCurrentWhenActive: "ariaCurrentWhenActive", routerLinkActive: "routerLinkActive" }, outputs: { isActiveChange: "isActiveChange" }, queries: [{ propertyName: "links", predicate: RouterLink, descendants: true }, { propertyName: "linksWithHrefs", predicate: RouterLinkWithHref, descendants: true }], exportAs: ["routerLinkActive"], usesOnChanges: true, ngImport: i0 });
5870
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.0-next.0", ngImport: i0, type: RouterLinkActive, decorators: [{
5901
+ RouterLinkActive.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.0-next.3", ngImport: i0, type: RouterLinkActive, deps: [{ token: Router }, { token: i0.ElementRef }, { token: i0.Renderer2 }, { token: i0.ChangeDetectorRef }, { token: RouterLink, optional: true }, { token: RouterLinkWithHref, optional: true }], target: i0.ɵɵFactoryTarget.Directive });
5902
+ RouterLinkActive.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "14.1.0-next.3", type: RouterLinkActive, selector: "[routerLinkActive]", inputs: { routerLinkActiveOptions: "routerLinkActiveOptions", ariaCurrentWhenActive: "ariaCurrentWhenActive", routerLinkActive: "routerLinkActive" }, outputs: { isActiveChange: "isActiveChange" }, queries: [{ propertyName: "links", predicate: RouterLink, descendants: true }, { propertyName: "linksWithHrefs", predicate: RouterLinkWithHref, descendants: true }], exportAs: ["routerLinkActive"], usesOnChanges: true, ngImport: i0 });
5903
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.0-next.3", ngImport: i0, type: RouterLinkActive, decorators: [{
5871
5904
  type: Directive,
5872
5905
  args: [{
5873
5906
  selector: '[routerLinkActive]',
@@ -5973,9 +6006,9 @@ class DefaultTitleStrategy extends TitleStrategy {
5973
6006
  }
5974
6007
  }
5975
6008
  }
5976
- DefaultTitleStrategy.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.0-next.0", ngImport: i0, type: DefaultTitleStrategy, deps: [{ token: i1.Title }], target: i0.ɵɵFactoryTarget.Injectable });
5977
- DefaultTitleStrategy.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.1.0-next.0", ngImport: i0, type: DefaultTitleStrategy, providedIn: 'root' });
5978
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.0-next.0", ngImport: i0, type: DefaultTitleStrategy, decorators: [{
6009
+ DefaultTitleStrategy.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.0-next.3", ngImport: i0, type: DefaultTitleStrategy, deps: [{ token: i1.Title }], target: i0.ɵɵFactoryTarget.Injectable });
6010
+ DefaultTitleStrategy.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.1.0-next.3", ngImport: i0, type: DefaultTitleStrategy, providedIn: 'root' });
6011
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.0-next.3", ngImport: i0, type: DefaultTitleStrategy, decorators: [{
5979
6012
  type: Injectable,
5980
6013
  args: [{ providedIn: 'root' }]
5981
6014
  }], ctorParameters: function () { return [{ type: i1.Title }]; } });
@@ -6012,6 +6045,12 @@ class PreloadAllModules {
6012
6045
  return fn().pipe(catchError(() => of(null)));
6013
6046
  }
6014
6047
  }
6048
+ PreloadAllModules.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.0-next.3", ngImport: i0, type: PreloadAllModules, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
6049
+ PreloadAllModules.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.1.0-next.3", ngImport: i0, type: PreloadAllModules, providedIn: 'root' });
6050
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.0-next.3", ngImport: i0, type: PreloadAllModules, decorators: [{
6051
+ type: Injectable,
6052
+ args: [{ providedIn: 'root' }]
6053
+ }] });
6015
6054
  /**
6016
6055
  * @description
6017
6056
  *
@@ -6026,6 +6065,12 @@ class NoPreloading {
6026
6065
  return of(null);
6027
6066
  }
6028
6067
  }
6068
+ NoPreloading.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.0-next.3", ngImport: i0, type: NoPreloading, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
6069
+ NoPreloading.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.1.0-next.3", ngImport: i0, type: NoPreloading, providedIn: 'root' });
6070
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.0-next.3", ngImport: i0, type: NoPreloading, decorators: [{
6071
+ type: Injectable,
6072
+ args: [{ providedIn: 'root' }]
6073
+ }] });
6029
6074
  /**
6030
6075
  * The preloader optimistically loads all router configurations to
6031
6076
  * make navigations into lazily-loaded sections of the application faster.
@@ -6110,12 +6155,13 @@ class RouterPreloader {
6110
6155
  });
6111
6156
  }
6112
6157
  }
6113
- RouterPreloader.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.0-next.0", ngImport: i0, type: RouterPreloader, deps: [{ token: Router }, { token: i0.Compiler }, { token: i0.EnvironmentInjector }, { token: PreloadingStrategy }, { token: RouterConfigLoader }], target: i0.ɵɵFactoryTarget.Injectable });
6114
- RouterPreloader.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.1.0-next.0", ngImport: i0, type: RouterPreloader });
6115
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.0-next.0", ngImport: i0, type: RouterPreloader, decorators: [{
6158
+ RouterPreloader.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.0-next.3", ngImport: i0, type: RouterPreloader, deps: [{ token: Router }, { token: i0.Compiler }, { token: i0.EnvironmentInjector }, { token: PreloadingStrategy }, { token: RouterConfigLoader }], target: i0.ɵɵFactoryTarget.Injectable });
6159
+ RouterPreloader.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.1.0-next.3", ngImport: i0, type: RouterPreloader });
6160
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.0-next.3", ngImport: i0, type: RouterPreloader, decorators: [{
6116
6161
  type: Injectable
6117
6162
  }], ctorParameters: function () { return [{ type: Router }, { type: i0.Compiler }, { type: i0.EnvironmentInjector }, { type: PreloadingStrategy }, { type: RouterConfigLoader }]; } });
6118
6163
 
6164
+ const ROUTER_SCROLLER = new InjectionToken('');
6119
6165
  class RouterScroller {
6120
6166
  constructor(router,
6121
6167
  /** @docsNotRequired */ viewportScroller, options = {}) {
@@ -6191,9 +6237,9 @@ class RouterScroller {
6191
6237
  }
6192
6238
  }
6193
6239
  }
6194
- RouterScroller.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.0-next.0", ngImport: i0, type: RouterScroller, deps: "invalid", target: i0.ɵɵFactoryTarget.Injectable });
6195
- RouterScroller.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.1.0-next.0", ngImport: i0, type: RouterScroller });
6196
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.0-next.0", ngImport: i0, type: RouterScroller, decorators: [{
6240
+ RouterScroller.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.0-next.3", ngImport: i0, type: RouterScroller, deps: "invalid", target: i0.ɵɵFactoryTarget.Injectable });
6241
+ RouterScroller.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.1.0-next.3", ngImport: i0, type: RouterScroller });
6242
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.0-next.3", ngImport: i0, type: RouterScroller, decorators: [{
6197
6243
  type: Injectable
6198
6244
  }], ctorParameters: function () { return [{ type: Router }, { type: i3.ViewportScroller }, { type: undefined }]; } });
6199
6245
 
@@ -6204,6 +6250,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.0-next.0",
6204
6250
  * Use of this source code is governed by an MIT-style license that can be
6205
6251
  * found in the LICENSE file at https://angular.io/license
6206
6252
  */
6253
+ const NG_DEV_MODE = typeof ngDevMode === 'undefined' || ngDevMode;
6207
6254
  /**
6208
6255
  * The directives defined in the `RouterModule`.
6209
6256
  */
@@ -6213,11 +6260,15 @@ const ROUTER_DIRECTIVES = [RouterOutlet, RouterLink, RouterLinkWithHref, RouterL
6213
6260
  *
6214
6261
  * @publicApi
6215
6262
  */
6216
- const ROUTER_CONFIGURATION = new InjectionToken('ROUTER_CONFIGURATION');
6263
+ const ROUTER_CONFIGURATION = new InjectionToken(NG_DEV_MODE ? 'router config' : 'ROUTER_CONFIGURATION', {
6264
+ providedIn: 'root',
6265
+ factory: () => ({}),
6266
+ });
6217
6267
  /**
6218
6268
  * @docsNotRequired
6219
6269
  */
6220
- const ROUTER_FORROOT_GUARD = new InjectionToken('ROUTER_FORROOT_GUARD');
6270
+ const ROUTER_FORROOT_GUARD = new InjectionToken(NG_DEV_MODE ? 'router duplicate forRoot guard' : 'ROUTER_FORROOT_GUARD');
6271
+ const ROUTER_PRELOADER = new InjectionToken(NG_DEV_MODE ? 'router preloader' : '');
6221
6272
  const ROUTER_PROVIDERS = [
6222
6273
  Location,
6223
6274
  { provide: UrlSerializer, useClass: DefaultUrlSerializer },
@@ -6232,10 +6283,6 @@ const ROUTER_PROVIDERS = [
6232
6283
  },
6233
6284
  ChildrenOutletContexts,
6234
6285
  { provide: ActivatedRoute, useFactory: rootRoute, deps: [Router] },
6235
- RouterPreloader,
6236
- NoPreloading,
6237
- PreloadAllModules,
6238
- { provide: ROUTER_CONFIGURATION, useValue: { enableTracing: false } },
6239
6286
  RouterConfigLoader,
6240
6287
  ];
6241
6288
  function routerNgProbeToken() {
@@ -6288,6 +6335,7 @@ class RouterModule {
6288
6335
  ngModule: RouterModule,
6289
6336
  providers: [
6290
6337
  ROUTER_PROVIDERS,
6338
+ NG_DEV_MODE ? ((config === null || config === void 0 ? void 0 : config.enableTracing) ? provideTracing() : []) : [],
6291
6339
  provideRoutes(routes),
6292
6340
  {
6293
6341
  provide: ROUTER_FORROOT_GUARD,
@@ -6295,22 +6343,11 @@ class RouterModule {
6295
6343
  deps: [[Router, new Optional(), new SkipSelf()]]
6296
6344
  },
6297
6345
  { provide: ROUTER_CONFIGURATION, useValue: config ? config : {} },
6298
- {
6299
- provide: LocationStrategy,
6300
- useFactory: provideLocationStrategy,
6301
- deps: [PlatformLocation, [new Inject(APP_BASE_HREF), new Optional()], ROUTER_CONFIGURATION]
6302
- },
6303
- {
6304
- provide: RouterScroller,
6305
- useFactory: createRouterScroller,
6306
- deps: [Router, ViewportScroller, ROUTER_CONFIGURATION]
6307
- },
6308
- {
6309
- provide: PreloadingStrategy,
6310
- useExisting: config && config.preloadingStrategy ? config.preloadingStrategy :
6311
- NoPreloading
6312
- },
6346
+ (config === null || config === void 0 ? void 0 : config.useHash) ? provideHashLocationStrategy() : providePathLocationStrategy(),
6347
+ provideRouterScroller(),
6348
+ (config === null || config === void 0 ? void 0 : config.preloadingStrategy) ? providePreloading(config.preloadingStrategy) : [],
6313
6349
  { provide: NgProbeToken, multi: true, useFactory: routerNgProbeToken },
6350
+ (config === null || config === void 0 ? void 0 : config.initialNavigation) ? provideInitialNavigation(config) : [],
6314
6351
  provideRouterInitializer(),
6315
6352
  ],
6316
6353
  };
@@ -6335,10 +6372,10 @@ class RouterModule {
6335
6372
  return { ngModule: RouterModule, providers: [provideRoutes(routes)] };
6336
6373
  }
6337
6374
  }
6338
- RouterModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.0-next.0", ngImport: i0, type: RouterModule, deps: [{ token: ROUTER_FORROOT_GUARD, optional: true }, { token: Router, optional: true }], target: i0.ɵɵFactoryTarget.NgModule });
6339
- RouterModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "14.1.0-next.0", ngImport: i0, type: RouterModule, declarations: [RouterOutlet, RouterLink, RouterLinkWithHref, RouterLinkActive, ɵEmptyOutletComponent], exports: [RouterOutlet, RouterLink, RouterLinkWithHref, RouterLinkActive, ɵEmptyOutletComponent] });
6340
- RouterModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "14.1.0-next.0", ngImport: i0, type: RouterModule });
6341
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.0-next.0", ngImport: i0, type: RouterModule, decorators: [{
6375
+ RouterModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.0-next.3", ngImport: i0, type: RouterModule, deps: [{ token: ROUTER_FORROOT_GUARD, optional: true }, { token: Router, optional: true }], target: i0.ɵɵFactoryTarget.NgModule });
6376
+ RouterModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "14.1.0-next.3", ngImport: i0, type: RouterModule, declarations: [RouterOutlet, RouterLink, RouterLinkWithHref, RouterLinkActive, ɵEmptyOutletComponent], exports: [RouterOutlet, RouterLink, RouterLinkWithHref, RouterLinkActive, ɵEmptyOutletComponent] });
6377
+ RouterModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "14.1.0-next.3", ngImport: i0, type: RouterModule });
6378
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.0-next.3", ngImport: i0, type: RouterModule, decorators: [{
6342
6379
  type: NgModule,
6343
6380
  args: [{
6344
6381
  declarations: ROUTER_DIRECTIVES,
@@ -6354,18 +6391,28 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.0-next.0",
6354
6391
  type: Optional
6355
6392
  }] }];
6356
6393
  } });
6357
- function createRouterScroller(router, viewportScroller, config) {
6358
- if (config.scrollOffset) {
6359
- viewportScroller.setOffset(config.scrollOffset);
6360
- }
6361
- return new RouterScroller(router, viewportScroller, config);
6394
+ function provideRouterScroller() {
6395
+ return {
6396
+ provide: ROUTER_SCROLLER,
6397
+ useFactory: () => {
6398
+ const router = inject(Router);
6399
+ const viewportScroller = inject(ViewportScroller);
6400
+ const config = inject(ROUTER_CONFIGURATION);
6401
+ if (config.scrollOffset) {
6402
+ viewportScroller.setOffset(config.scrollOffset);
6403
+ }
6404
+ return new RouterScroller(router, viewportScroller, config);
6405
+ },
6406
+ };
6407
+ }
6408
+ function provideHashLocationStrategy() {
6409
+ return { provide: LocationStrategy, useClass: HashLocationStrategy };
6362
6410
  }
6363
- function provideLocationStrategy(platformLocationStrategy, baseHref, options = {}) {
6364
- return options.useHash ? new HashLocationStrategy(platformLocationStrategy, baseHref) :
6365
- new PathLocationStrategy(platformLocationStrategy, baseHref);
6411
+ function providePathLocationStrategy() {
6412
+ return { provide: LocationStrategy, useClass: PathLocationStrategy };
6366
6413
  }
6367
6414
  function provideForRootGuard(router) {
6368
- if ((typeof ngDevMode === 'undefined' || ngDevMode) && router) {
6415
+ if (NG_DEV_MODE && router) {
6369
6416
  throw new Error(`RouterModule.forRoot() called twice. Lazy loaded modules should use RouterModule.forChild() instead.`);
6370
6417
  }
6371
6418
  return 'guarded';
@@ -6402,17 +6449,6 @@ function setupRouter(urlSerializer, contexts, location, injector, compiler, conf
6402
6449
  }
6403
6450
  router.titleStrategy = titleStrategy !== null && titleStrategy !== void 0 ? titleStrategy : defaultTitleStrategy;
6404
6451
  assignExtraOptionsToRouter(opts, router);
6405
- if ((typeof ngDevMode === 'undefined' || ngDevMode) && opts.enableTracing) {
6406
- router.events.subscribe((e) => {
6407
- var _a, _b;
6408
- // tslint:disable:no-console
6409
- (_a = console.group) === null || _a === void 0 ? void 0 : _a.call(console, `Router Event: ${e.constructor.name}`);
6410
- console.log(stringifyEvent(e));
6411
- console.log(e);
6412
- (_b = console.groupEnd) === null || _b === void 0 ? void 0 : _b.call(console);
6413
- // tslint:enable:no-console
6414
- });
6415
- }
6416
6452
  return router;
6417
6453
  }
6418
6454
  function assignExtraOptionsToRouter(opts, router) {
@@ -6441,112 +6477,138 @@ function assignExtraOptionsToRouter(opts, router) {
6441
6477
  function rootRoute(router) {
6442
6478
  return router.routerState.root;
6443
6479
  }
6444
- /**
6445
- * Router initialization requires two steps:
6446
- *
6447
- * First, we start the navigation in a `APP_INITIALIZER` to block the bootstrap if
6448
- * a resolver or a guard executes asynchronously.
6449
- *
6450
- * Next, we actually run activation in a `BOOTSTRAP_LISTENER`, using the
6451
- * `afterPreactivation` hook provided by the router.
6452
- * The router navigation starts, reaches the point when preactivation is done, and then
6453
- * pauses. It waits for the hook to be resolved. We then resolve it only in a bootstrap listener.
6454
- */
6455
- class RouterInitializer {
6456
- constructor(injector) {
6457
- this.injector = injector;
6458
- this.initNavigation = false;
6459
- this.destroyed = false;
6460
- this.resultOfPreactivationDone = new Subject();
6461
- }
6462
- appInitializer() {
6463
- const p = this.injector.get(LOCATION_INITIALIZED, Promise.resolve(null));
6464
- return p.then(() => {
6465
- // If the injector was destroyed, the DI lookups below will fail.
6466
- if (this.destroyed) {
6467
- return Promise.resolve(true);
6468
- }
6469
- let resolve = null;
6470
- const res = new Promise(r => resolve = r);
6471
- const router = this.injector.get(Router);
6472
- const opts = this.injector.get(ROUTER_CONFIGURATION);
6473
- if (opts.initialNavigation === 'disabled') {
6474
- router.setUpLocationChangeListener();
6475
- resolve(true);
6476
- }
6477
- else if (opts.initialNavigation === 'enabledBlocking') {
6478
- router.hooks.afterPreactivation = () => {
6479
- // only the initial navigation should be delayed
6480
- if (!this.initNavigation) {
6481
- this.initNavigation = true;
6482
- resolve(true);
6483
- return this.resultOfPreactivationDone;
6484
- // subsequent navigations should not be delayed
6485
- }
6486
- else {
6487
- return of(null);
6488
- }
6489
- };
6490
- router.initialNavigation();
6491
- }
6492
- else {
6493
- resolve(true);
6494
- }
6495
- return res;
6496
- });
6497
- }
6498
- bootstrapListener(bootstrappedComponentRef) {
6499
- const opts = this.injector.get(ROUTER_CONFIGURATION);
6500
- const preloader = this.injector.get(RouterPreloader);
6501
- const routerScroller = this.injector.get(RouterScroller);
6502
- const router = this.injector.get(Router);
6503
- const ref = this.injector.get(ApplicationRef);
6480
+ function getBootstrapListener() {
6481
+ const injector = inject(Injector);
6482
+ return (bootstrappedComponentRef) => {
6483
+ var _a, _b;
6484
+ const ref = injector.get(ApplicationRef);
6504
6485
  if (bootstrappedComponentRef !== ref.components[0]) {
6505
6486
  return;
6506
6487
  }
6488
+ const router = injector.get(Router);
6489
+ const bootstrapDone = injector.get(BOOTSTRAP_DONE);
6507
6490
  // Default case
6508
- if (opts.initialNavigation === 'enabledNonBlocking' || opts.initialNavigation === undefined) {
6491
+ if (injector.get(INITIAL_NAVIGATION, null, InjectFlags.Optional) === null) {
6509
6492
  router.initialNavigation();
6510
6493
  }
6511
- preloader.setUpPreloading();
6512
- routerScroller.init();
6494
+ (_a = injector.get(ROUTER_PRELOADER, null, InjectFlags.Optional)) === null || _a === void 0 ? void 0 : _a.setUpPreloading();
6495
+ (_b = injector.get(ROUTER_SCROLLER, null, InjectFlags.Optional)) === null || _b === void 0 ? void 0 : _b.init();
6513
6496
  router.resetRootComponentType(ref.componentTypes[0]);
6514
- this.resultOfPreactivationDone.next(null);
6515
- this.resultOfPreactivationDone.complete();
6516
- }
6517
- ngOnDestroy() {
6518
- this.destroyed = true;
6519
- }
6520
- }
6521
- RouterInitializer.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.0-next.0", ngImport: i0, type: RouterInitializer, deps: [{ token: i0.Injector }], target: i0.ɵɵFactoryTarget.Injectable });
6522
- RouterInitializer.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.1.0-next.0", ngImport: i0, type: RouterInitializer });
6523
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.0-next.0", ngImport: i0, type: RouterInitializer, decorators: [{
6524
- type: Injectable
6525
- }], ctorParameters: function () { return [{ type: i0.Injector }]; } });
6526
- function getAppInitializer(r) {
6527
- return r.appInitializer.bind(r);
6528
- }
6529
- function getBootstrapListener(r) {
6530
- return r.bootstrapListener.bind(r);
6497
+ bootstrapDone.next();
6498
+ bootstrapDone.complete();
6499
+ };
6531
6500
  }
6501
+ // TODO(atscott): This should not be in the public API
6532
6502
  /**
6533
6503
  * A [DI token](guide/glossary/#di-token) for the router initializer that
6534
6504
  * is called after the app is bootstrapped.
6535
6505
  *
6536
6506
  * @publicApi
6537
6507
  */
6538
- const ROUTER_INITIALIZER = new InjectionToken('Router Initializer');
6508
+ const ROUTER_INITIALIZER = new InjectionToken(NG_DEV_MODE ? 'Router Initializer' : '');
6509
+ function provideInitialNavigation(config) {
6510
+ return [
6511
+ config.initialNavigation === 'disabled' ? provideDisabledInitialNavigation() : [],
6512
+ config.initialNavigation === 'enabledBlocking' ? provideEnabledBlockingInitialNavigation() : [],
6513
+ ];
6514
+ }
6539
6515
  function provideRouterInitializer() {
6540
6516
  return [
6541
- RouterInitializer,
6517
+ // ROUTER_INITIALIZER token should be removed. It's public API but shouldn't be. We can just
6518
+ // have `getBootstrapListener` directly attached to APP_BOOTSTRAP_LISTENER.
6519
+ { provide: ROUTER_INITIALIZER, useFactory: getBootstrapListener },
6520
+ { provide: APP_BOOTSTRAP_LISTENER, multi: true, useExisting: ROUTER_INITIALIZER },
6521
+ ];
6522
+ }
6523
+ /**
6524
+ * A subject used to indicate that the bootstrapping phase is done. When initial navigation is
6525
+ * `enabledBlocking`, the first navigation waits until bootstrapping is finished before continuing
6526
+ * to the activation phase.
6527
+ */
6528
+ const BOOTSTRAP_DONE = new InjectionToken(NG_DEV_MODE ? 'bootstrap done indicator' : '', {
6529
+ factory: () => {
6530
+ return new Subject();
6531
+ }
6532
+ });
6533
+ function provideEnabledBlockingInitialNavigation() {
6534
+ return [
6535
+ { provide: INITIAL_NAVIGATION, useValue: 'enabledBlocking' },
6542
6536
  {
6543
6537
  provide: APP_INITIALIZER,
6544
6538
  multi: true,
6545
- useFactory: getAppInitializer,
6546
- deps: [RouterInitializer]
6539
+ deps: [Injector],
6540
+ useFactory: (injector) => {
6541
+ const locationInitialized = injector.get(LOCATION_INITIALIZED, Promise.resolve(null));
6542
+ let initNavigation = false;
6543
+ return () => {
6544
+ return locationInitialized.then(() => {
6545
+ return new Promise(resolve => {
6546
+ const router = injector.get(Router);
6547
+ const bootstrapDone = injector.get(BOOTSTRAP_DONE);
6548
+ router.afterPreactivation = () => {
6549
+ // only the initial navigation should be delayed
6550
+ if (!initNavigation) {
6551
+ initNavigation = true;
6552
+ resolve(true);
6553
+ return bootstrapDone;
6554
+ // subsequent navigations should not be delayed
6555
+ }
6556
+ else {
6557
+ return of(void 0);
6558
+ }
6559
+ };
6560
+ router.initialNavigation();
6561
+ });
6562
+ });
6563
+ };
6564
+ }
6547
6565
  },
6548
- { provide: ROUTER_INITIALIZER, useFactory: getBootstrapListener, deps: [RouterInitializer] },
6549
- { provide: APP_BOOTSTRAP_LISTENER, multi: true, useExisting: ROUTER_INITIALIZER },
6566
+ ];
6567
+ }
6568
+ const INITIAL_NAVIGATION = new InjectionToken(NG_DEV_MODE ? 'initial navigation' : '');
6569
+ function provideDisabledInitialNavigation() {
6570
+ return [
6571
+ {
6572
+ provide: APP_INITIALIZER,
6573
+ multi: true,
6574
+ useFactory: () => {
6575
+ const router = inject(Router);
6576
+ return () => {
6577
+ router.setUpLocationChangeListener();
6578
+ };
6579
+ }
6580
+ },
6581
+ { provide: INITIAL_NAVIGATION, useValue: 'disabled' }
6582
+ ];
6583
+ }
6584
+ function provideTracing() {
6585
+ if (NG_DEV_MODE) {
6586
+ return [{
6587
+ provide: ENVIRONMENT_INITIALIZER,
6588
+ multi: true,
6589
+ useFactory: () => {
6590
+ const router = inject(Router);
6591
+ return () => router.events.subscribe((e) => {
6592
+ var _a, _b;
6593
+ // tslint:disable:no-console
6594
+ (_a = console.group) === null || _a === void 0 ? void 0 : _a.call(console, `Router Event: ${e.constructor.name}`);
6595
+ console.log(stringifyEvent(e));
6596
+ console.log(e);
6597
+ (_b = console.groupEnd) === null || _b === void 0 ? void 0 : _b.call(console);
6598
+ // tslint:enable:no-console
6599
+ });
6600
+ }
6601
+ }];
6602
+ }
6603
+ else {
6604
+ return [];
6605
+ }
6606
+ }
6607
+ function providePreloading(preloadingStrategy) {
6608
+ return [
6609
+ RouterPreloader,
6610
+ { provide: ROUTER_PRELOADER, useExisting: RouterPreloader },
6611
+ { provide: PreloadingStrategy, useExisting: preloadingStrategy },
6550
6612
  ];
6551
6613
  }
6552
6614
 
@@ -6560,7 +6622,7 @@ function provideRouterInitializer() {
6560
6622
  /**
6561
6623
  * @publicApi
6562
6624
  */
6563
- const VERSION = new Version('14.1.0-next.0');
6625
+ const VERSION = new Version('14.1.0-next.3');
6564
6626
 
6565
6627
  /**
6566
6628
  * @license
@@ -6599,5 +6661,5 @@ const VERSION = new Version('14.1.0-next.0');
6599
6661
  * Generated bundle index. Do not edit.
6600
6662
  */
6601
6663
 
6602
- export { ActivatedRoute, ActivatedRouteSnapshot, ActivationEnd, ActivationStart, BaseRouteReuseStrategy, ChildActivationEnd, ChildActivationStart, ChildrenOutletContexts, DefaultTitleStrategy, DefaultUrlSerializer, GuardsCheckEnd, GuardsCheckStart, NavigationCancel, NavigationEnd, NavigationError, NavigationStart, NoPreloading, OutletContext, PRIMARY_OUTLET, PreloadAllModules, PreloadingStrategy, ROUTER_CONFIGURATION, ROUTER_INITIALIZER, ROUTES, ResolveEnd, ResolveStart, RouteConfigLoadEnd, RouteConfigLoadStart, RouteReuseStrategy, Router, RouterEvent, RouterLink, RouterLinkActive, RouterLinkWithHref, RouterModule, RouterOutlet, RouterPreloader, RouterState, RouterStateSnapshot, RoutesRecognized, Scroll, TitleStrategy, UrlHandlingStrategy, UrlSegment, UrlSegmentGroup, UrlSerializer, UrlTree, VERSION, convertToParamMap, createUrlTreeFromSnapshot, provideRoutes, ɵEmptyOutletComponent, ROUTER_PROVIDERS as ɵROUTER_PROVIDERS, assignExtraOptionsToRouter as ɵassignExtraOptionsToRouter, flatten as ɵflatten };
6664
+ export { ActivatedRoute, ActivatedRouteSnapshot, ActivationEnd, ActivationStart, BaseRouteReuseStrategy, ChildActivationEnd, ChildActivationStart, ChildrenOutletContexts, DefaultTitleStrategy, DefaultUrlSerializer, GuardsCheckEnd, GuardsCheckStart, NavigationCancel, NavigationEnd, NavigationError, NavigationStart, NoPreloading, OutletContext, PRIMARY_OUTLET, PreloadAllModules, PreloadingStrategy, ROUTER_CONFIGURATION, ROUTER_INITIALIZER, ROUTES, ResolveEnd, ResolveStart, RouteConfigLoadEnd, RouteConfigLoadStart, RouteReuseStrategy, Router, RouterEvent, RouterLink, RouterLinkActive, RouterLinkWithHref, RouterModule, RouterOutlet, RouterPreloader, RouterState, RouterStateSnapshot, RoutesRecognized, Scroll, TitleStrategy, UrlHandlingStrategy, UrlSegment, UrlSegmentGroup, UrlSerializer, UrlTree, VERSION, convertToParamMap, createUrlTreeFromSnapshot, provideRoutes, ɵEmptyOutletComponent, ROUTER_PROVIDERS as ɵROUTER_PROVIDERS, assignExtraOptionsToRouter as ɵassignExtraOptionsToRouter, flatten as ɵflatten, providePreloading as ɵprovidePreloading };
6603
6665
  //# sourceMappingURL=router.mjs.map