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