@angular/router 14.0.0-next.13 → 14.0.0-next.16
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/apply_redirects.mjs +57 -47
- package/esm2020/src/components/empty_outlet.mjs +3 -3
- package/esm2020/src/directives/router_link.mjs +6 -6
- package/esm2020/src/directives/router_link_active.mjs +22 -4
- package/esm2020/src/directives/router_outlet.mjs +25 -16
- package/esm2020/src/events.mjs +57 -1
- package/esm2020/src/index.mjs +1 -1
- package/esm2020/src/models.mjs +2 -7
- package/esm2020/src/operators/activate_routes.mjs +7 -14
- package/esm2020/src/operators/apply_redirects.mjs +3 -3
- package/esm2020/src/operators/resolve_data.mjs +5 -12
- package/esm2020/src/page_title_strategy.mjs +3 -3
- package/esm2020/src/recognize.mjs +4 -4
- package/esm2020/src/router.mjs +41 -25
- package/esm2020/src/router_config_loader.mjs +74 -27
- package/esm2020/src/router_module.mjs +14 -14
- package/esm2020/src/router_outlet_context.mjs +6 -1
- package/esm2020/src/router_preloader.mjs +48 -32
- package/esm2020/src/router_scroller.mjs +3 -3
- package/esm2020/src/router_state.mjs +1 -2
- package/esm2020/src/utils/config.mjs +71 -11
- package/esm2020/src/utils/preactivation.mjs +5 -14
- package/esm2020/src/version.mjs +1 -1
- package/esm2020/testing/src/router_testing_module.mjs +4 -4
- package/fesm2015/router.mjs +855 -651
- package/fesm2015/router.mjs.map +1 -1
- package/fesm2015/testing.mjs +5 -5
- package/fesm2015/upgrade.mjs +1 -1
- package/fesm2020/router.mjs +845 -651
- package/fesm2020/router.mjs.map +1 -1
- package/fesm2020/testing.mjs +5 -5
- package/fesm2020/upgrade.mjs +1 -1
- package/{router.d.ts → index.d.ts} +3858 -3734
- package/package.json +8 -8
- package/testing/{testing.d.ts → index.d.ts} +65 -64
- package/upgrade/{upgrade.d.ts → index.d.ts} +51 -50
- package/testing/package.json +0 -9
- package/upgrade/package.json +0 -10
package/fesm2020/router.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @license Angular v14.0.0-next.
|
|
2
|
+
* @license Angular v14.0.0-next.16
|
|
3
3
|
* (c) 2010-2022 Google LLC. https://angular.io/
|
|
4
4
|
* License: MIT
|
|
5
5
|
*/
|
|
@@ -7,9 +7,9 @@
|
|
|
7
7
|
import * as i3 from '@angular/common';
|
|
8
8
|
import { Location, LocationStrategy, PlatformLocation, APP_BASE_HREF, ViewportScroller, HashLocationStrategy, PathLocationStrategy, LOCATION_INITIALIZED } from '@angular/common';
|
|
9
9
|
import * as i0 from '@angular/core';
|
|
10
|
-
import { ɵisObservable, ɵisPromise, EventEmitter, Directive, Attribute, Output, Component,
|
|
10
|
+
import { ɵisObservable, ɵisPromise, EventEmitter, Directive, Attribute, Output, Component, ɵisStandalone, ComponentFactoryResolver, createEnvironmentInjector, InjectionToken, InjectFlags, NgModuleFactory, Injectable, NgModuleRef, ɵConsole, NgZone, ɵcoerceToBoolean, Input, HostListener, HostBinding, Optional, ContentChildren, Injector, Compiler, NgProbeToken, ANALYZE_FOR_ENTRY_COMPONENTS, SkipSelf, Inject, APP_INITIALIZER, APP_BOOTSTRAP_LISTENER, NgModule, ApplicationRef, Version } from '@angular/core';
|
|
11
11
|
import { from, of, BehaviorSubject, combineLatest, throwError, EmptyError, concat, defer, Observable, EMPTY, ConnectableObservable, Subject } from 'rxjs';
|
|
12
|
-
import { map, switchMap, take, startWith, scan, filter, catchError, concatMap, last as last$1, first, mergeMap, tap, takeLast,
|
|
12
|
+
import { map, switchMap, take, startWith, scan, filter, catchError, concatMap, last as last$1, first, mergeMap, tap, takeLast, mapTo, finalize, refCount, defaultIfEmpty, mergeAll } from 'rxjs/operators';
|
|
13
13
|
import * as i1 from '@angular/platform-browser';
|
|
14
14
|
|
|
15
15
|
/**
|
|
@@ -69,6 +69,7 @@ class NavigationStart extends RouterEvent {
|
|
|
69
69
|
/** @docsNotRequired */
|
|
70
70
|
restoredState = null) {
|
|
71
71
|
super(id, url);
|
|
72
|
+
this.type = 0 /* EventType.NavigationStart */;
|
|
72
73
|
this.navigationTrigger = navigationTrigger;
|
|
73
74
|
this.restoredState = restoredState;
|
|
74
75
|
}
|
|
@@ -96,6 +97,7 @@ class NavigationEnd extends RouterEvent {
|
|
|
96
97
|
urlAfterRedirects) {
|
|
97
98
|
super(id, url);
|
|
98
99
|
this.urlAfterRedirects = urlAfterRedirects;
|
|
100
|
+
this.type = 1 /* EventType.NavigationEnd */;
|
|
99
101
|
}
|
|
100
102
|
/** @docsNotRequired */
|
|
101
103
|
toString() {
|
|
@@ -123,6 +125,7 @@ class NavigationCancel extends RouterEvent {
|
|
|
123
125
|
reason) {
|
|
124
126
|
super(id, url);
|
|
125
127
|
this.reason = reason;
|
|
128
|
+
this.type = 2 /* EventType.NavigationCancel */;
|
|
126
129
|
}
|
|
127
130
|
/** @docsNotRequired */
|
|
128
131
|
toString() {
|
|
@@ -148,6 +151,7 @@ class NavigationError extends RouterEvent {
|
|
|
148
151
|
error) {
|
|
149
152
|
super(id, url);
|
|
150
153
|
this.error = error;
|
|
154
|
+
this.type = 3 /* EventType.NavigationError */;
|
|
151
155
|
}
|
|
152
156
|
/** @docsNotRequired */
|
|
153
157
|
toString() {
|
|
@@ -172,6 +176,7 @@ class RoutesRecognized extends RouterEvent {
|
|
|
172
176
|
super(id, url);
|
|
173
177
|
this.urlAfterRedirects = urlAfterRedirects;
|
|
174
178
|
this.state = state;
|
|
179
|
+
this.type = 4 /* EventType.RoutesRecognized */;
|
|
175
180
|
}
|
|
176
181
|
/** @docsNotRequired */
|
|
177
182
|
toString() {
|
|
@@ -198,6 +203,7 @@ class GuardsCheckStart extends RouterEvent {
|
|
|
198
203
|
super(id, url);
|
|
199
204
|
this.urlAfterRedirects = urlAfterRedirects;
|
|
200
205
|
this.state = state;
|
|
206
|
+
this.type = 7 /* EventType.GuardsCheckStart */;
|
|
201
207
|
}
|
|
202
208
|
toString() {
|
|
203
209
|
return `GuardsCheckStart(id: ${this.id}, url: '${this.url}', urlAfterRedirects: '${this.urlAfterRedirects}', state: ${this.state})`;
|
|
@@ -226,6 +232,7 @@ class GuardsCheckEnd extends RouterEvent {
|
|
|
226
232
|
this.urlAfterRedirects = urlAfterRedirects;
|
|
227
233
|
this.state = state;
|
|
228
234
|
this.shouldActivate = shouldActivate;
|
|
235
|
+
this.type = 8 /* EventType.GuardsCheckEnd */;
|
|
229
236
|
}
|
|
230
237
|
toString() {
|
|
231
238
|
return `GuardsCheckEnd(id: ${this.id}, url: '${this.url}', urlAfterRedirects: '${this.urlAfterRedirects}', state: ${this.state}, shouldActivate: ${this.shouldActivate})`;
|
|
@@ -254,6 +261,7 @@ class ResolveStart extends RouterEvent {
|
|
|
254
261
|
super(id, url);
|
|
255
262
|
this.urlAfterRedirects = urlAfterRedirects;
|
|
256
263
|
this.state = state;
|
|
264
|
+
this.type = 5 /* EventType.ResolveStart */;
|
|
257
265
|
}
|
|
258
266
|
toString() {
|
|
259
267
|
return `ResolveStart(id: ${this.id}, url: '${this.url}', urlAfterRedirects: '${this.urlAfterRedirects}', state: ${this.state})`;
|
|
@@ -278,6 +286,7 @@ class ResolveEnd extends RouterEvent {
|
|
|
278
286
|
super(id, url);
|
|
279
287
|
this.urlAfterRedirects = urlAfterRedirects;
|
|
280
288
|
this.state = state;
|
|
289
|
+
this.type = 6 /* EventType.ResolveEnd */;
|
|
281
290
|
}
|
|
282
291
|
toString() {
|
|
283
292
|
return `ResolveEnd(id: ${this.id}, url: '${this.url}', urlAfterRedirects: '${this.urlAfterRedirects}', state: ${this.state})`;
|
|
@@ -295,6 +304,7 @@ class RouteConfigLoadStart {
|
|
|
295
304
|
/** @docsNotRequired */
|
|
296
305
|
route) {
|
|
297
306
|
this.route = route;
|
|
307
|
+
this.type = 9 /* EventType.RouteConfigLoadStart */;
|
|
298
308
|
}
|
|
299
309
|
toString() {
|
|
300
310
|
return `RouteConfigLoadStart(path: ${this.route.path})`;
|
|
@@ -312,6 +322,7 @@ class RouteConfigLoadEnd {
|
|
|
312
322
|
/** @docsNotRequired */
|
|
313
323
|
route) {
|
|
314
324
|
this.route = route;
|
|
325
|
+
this.type = 10 /* EventType.RouteConfigLoadEnd */;
|
|
315
326
|
}
|
|
316
327
|
toString() {
|
|
317
328
|
return `RouteConfigLoadEnd(path: ${this.route.path})`;
|
|
@@ -330,6 +341,7 @@ class ChildActivationStart {
|
|
|
330
341
|
/** @docsNotRequired */
|
|
331
342
|
snapshot) {
|
|
332
343
|
this.snapshot = snapshot;
|
|
344
|
+
this.type = 11 /* EventType.ChildActivationStart */;
|
|
333
345
|
}
|
|
334
346
|
toString() {
|
|
335
347
|
const path = this.snapshot.routeConfig && this.snapshot.routeConfig.path || '';
|
|
@@ -348,6 +360,7 @@ class ChildActivationEnd {
|
|
|
348
360
|
/** @docsNotRequired */
|
|
349
361
|
snapshot) {
|
|
350
362
|
this.snapshot = snapshot;
|
|
363
|
+
this.type = 12 /* EventType.ChildActivationEnd */;
|
|
351
364
|
}
|
|
352
365
|
toString() {
|
|
353
366
|
const path = this.snapshot.routeConfig && this.snapshot.routeConfig.path || '';
|
|
@@ -367,6 +380,7 @@ class ActivationStart {
|
|
|
367
380
|
/** @docsNotRequired */
|
|
368
381
|
snapshot) {
|
|
369
382
|
this.snapshot = snapshot;
|
|
383
|
+
this.type = 13 /* EventType.ActivationStart */;
|
|
370
384
|
}
|
|
371
385
|
toString() {
|
|
372
386
|
const path = this.snapshot.routeConfig && this.snapshot.routeConfig.path || '';
|
|
@@ -386,6 +400,7 @@ class ActivationEnd {
|
|
|
386
400
|
/** @docsNotRequired */
|
|
387
401
|
snapshot) {
|
|
388
402
|
this.snapshot = snapshot;
|
|
403
|
+
this.type = 14 /* EventType.ActivationEnd */;
|
|
389
404
|
}
|
|
390
405
|
toString() {
|
|
391
406
|
const path = this.snapshot.routeConfig && this.snapshot.routeConfig.path || '';
|
|
@@ -408,12 +423,53 @@ class Scroll {
|
|
|
408
423
|
this.routerEvent = routerEvent;
|
|
409
424
|
this.position = position;
|
|
410
425
|
this.anchor = anchor;
|
|
426
|
+
this.type = 15 /* EventType.Scroll */;
|
|
411
427
|
}
|
|
412
428
|
toString() {
|
|
413
429
|
const pos = this.position ? `${this.position[0]}, ${this.position[1]}` : null;
|
|
414
430
|
return `Scroll(anchor: '${this.anchor}', position: '${pos}')`;
|
|
415
431
|
}
|
|
416
432
|
}
|
|
433
|
+
function stringifyEvent(routerEvent) {
|
|
434
|
+
if (!('type' in routerEvent)) {
|
|
435
|
+
return `Unknown Router Event: ${routerEvent.constructor.name}`;
|
|
436
|
+
}
|
|
437
|
+
switch (routerEvent.type) {
|
|
438
|
+
case 14 /* EventType.ActivationEnd */:
|
|
439
|
+
return `ActivationEnd(path: '${routerEvent.snapshot.routeConfig?.path || ''}')`;
|
|
440
|
+
case 13 /* EventType.ActivationStart */:
|
|
441
|
+
return `ActivationStart(path: '${routerEvent.snapshot.routeConfig?.path || ''}')`;
|
|
442
|
+
case 12 /* EventType.ChildActivationEnd */:
|
|
443
|
+
return `ChildActivationEnd(path: '${routerEvent.snapshot.routeConfig?.path || ''}')`;
|
|
444
|
+
case 11 /* EventType.ChildActivationStart */:
|
|
445
|
+
return `ChildActivationStart(path: '${routerEvent.snapshot.routeConfig?.path || ''}')`;
|
|
446
|
+
case 8 /* EventType.GuardsCheckEnd */:
|
|
447
|
+
return `GuardsCheckEnd(id: ${routerEvent.id}, url: '${routerEvent.url}', urlAfterRedirects: '${routerEvent.urlAfterRedirects}', state: ${routerEvent.state}, shouldActivate: ${routerEvent.shouldActivate})`;
|
|
448
|
+
case 7 /* EventType.GuardsCheckStart */:
|
|
449
|
+
return `GuardsCheckStart(id: ${routerEvent.id}, url: '${routerEvent.url}', urlAfterRedirects: '${routerEvent.urlAfterRedirects}', state: ${routerEvent.state})`;
|
|
450
|
+
case 2 /* EventType.NavigationCancel */:
|
|
451
|
+
return `NavigationCancel(id: ${routerEvent.id}, url: '${routerEvent.url}')`;
|
|
452
|
+
case 1 /* EventType.NavigationEnd */:
|
|
453
|
+
return `NavigationEnd(id: ${routerEvent.id}, url: '${routerEvent.url}', urlAfterRedirects: '${routerEvent.urlAfterRedirects}')`;
|
|
454
|
+
case 3 /* EventType.NavigationError */:
|
|
455
|
+
return `NavigationError(id: ${routerEvent.id}, url: '${routerEvent.url}', error: ${routerEvent.error})`;
|
|
456
|
+
case 0 /* EventType.NavigationStart */:
|
|
457
|
+
return `NavigationStart(id: ${routerEvent.id}, url: '${routerEvent.url}')`;
|
|
458
|
+
case 6 /* EventType.ResolveEnd */:
|
|
459
|
+
return `ResolveEnd(id: ${routerEvent.id}, url: '${routerEvent.url}', urlAfterRedirects: '${routerEvent.urlAfterRedirects}', state: ${routerEvent.state})`;
|
|
460
|
+
case 5 /* EventType.ResolveStart */:
|
|
461
|
+
return `ResolveStart(id: ${routerEvent.id}, url: '${routerEvent.url}', urlAfterRedirects: '${routerEvent.urlAfterRedirects}', state: ${routerEvent.state})`;
|
|
462
|
+
case 10 /* EventType.RouteConfigLoadEnd */:
|
|
463
|
+
return `RouteConfigLoadEnd(path: ${routerEvent.route.path})`;
|
|
464
|
+
case 9 /* EventType.RouteConfigLoadStart */:
|
|
465
|
+
return `RouteConfigLoadStart(path: ${routerEvent.route.path})`;
|
|
466
|
+
case 4 /* EventType.RoutesRecognized */:
|
|
467
|
+
return `RoutesRecognized(id: ${routerEvent.id}, url: '${routerEvent.url}', urlAfterRedirects: '${routerEvent.urlAfterRedirects}', state: ${routerEvent.state})`;
|
|
468
|
+
case 15 /* EventType.Scroll */:
|
|
469
|
+
const pos = routerEvent.position ? `${routerEvent.position[0]}, ${routerEvent.position[1]}` : null;
|
|
470
|
+
return `Scroll(anchor: '${routerEvent.anchor}', position: '${pos}')`;
|
|
471
|
+
}
|
|
472
|
+
}
|
|
417
473
|
|
|
418
474
|
/**
|
|
419
475
|
* @license
|
|
@@ -1362,7 +1418,6 @@ class ActivatedRoute {
|
|
|
1362
1418
|
/** The outlet name of the route, a constant. */
|
|
1363
1419
|
outlet,
|
|
1364
1420
|
/** The component of the route, a constant. */
|
|
1365
|
-
// TODO(vsavkin): remove |string
|
|
1366
1421
|
component, futureSnapshot) {
|
|
1367
1422
|
this.url = url;
|
|
1368
1423
|
this.params = params;
|
|
@@ -2020,181 +2075,76 @@ function compare(path, params, segment) {
|
|
|
2020
2075
|
* Use of this source code is governed by an MIT-style license that can be
|
|
2021
2076
|
* found in the LICENSE file at https://angular.io/license
|
|
2022
2077
|
*/
|
|
2023
|
-
|
|
2024
|
-
|
|
2025
|
-
|
|
2026
|
-
|
|
2027
|
-
|
|
2028
|
-
class
|
|
2029
|
-
constructor(
|
|
2030
|
-
this.
|
|
2031
|
-
this.
|
|
2032
|
-
|
|
2033
|
-
|
|
2034
|
-
|
|
2035
|
-
|
|
2036
|
-
|
|
2037
|
-
|
|
2038
|
-
this.
|
|
2039
|
-
|
|
2040
|
-
this.activateChildRoutes(futureRoot, currRoot, parentContexts);
|
|
2041
|
-
}
|
|
2042
|
-
// De-activate the child route that are not re-used for the future state
|
|
2043
|
-
deactivateChildRoutes(futureNode, currNode, contexts) {
|
|
2044
|
-
const children = nodeChildrenAsMap(currNode);
|
|
2045
|
-
// Recurse on the routes active in the future state to de-activate deeper children
|
|
2046
|
-
futureNode.children.forEach(futureChild => {
|
|
2047
|
-
const childOutletName = futureChild.value.outlet;
|
|
2048
|
-
this.deactivateRoutes(futureChild, children[childOutletName], contexts);
|
|
2049
|
-
delete children[childOutletName];
|
|
2050
|
-
});
|
|
2051
|
-
// De-activate the routes that will not be re-used
|
|
2052
|
-
forEach(children, (v, childName) => {
|
|
2053
|
-
this.deactivateRouteAndItsChildren(v, contexts);
|
|
2054
|
-
});
|
|
2055
|
-
}
|
|
2056
|
-
deactivateRoutes(futureNode, currNode, parentContext) {
|
|
2057
|
-
const future = futureNode.value;
|
|
2058
|
-
const curr = currNode ? currNode.value : null;
|
|
2059
|
-
if (future === curr) {
|
|
2060
|
-
// Reusing the node, check to see if the children need to be de-activated
|
|
2061
|
-
if (future.component) {
|
|
2062
|
-
// If we have a normal route, we need to go through an outlet.
|
|
2063
|
-
const context = parentContext.getContext(future.outlet);
|
|
2064
|
-
if (context) {
|
|
2065
|
-
this.deactivateChildRoutes(futureNode, currNode, context.children);
|
|
2066
|
-
}
|
|
2067
|
-
}
|
|
2068
|
-
else {
|
|
2069
|
-
// if we have a componentless route, we recurse but keep the same outlet map.
|
|
2070
|
-
this.deactivateChildRoutes(futureNode, currNode, parentContext);
|
|
2071
|
-
}
|
|
2072
|
-
}
|
|
2073
|
-
else {
|
|
2074
|
-
if (curr) {
|
|
2075
|
-
// Deactivate the current route which will not be re-used
|
|
2076
|
-
this.deactivateRouteAndItsChildren(currNode, parentContext);
|
|
2077
|
-
}
|
|
2078
|
-
}
|
|
2078
|
+
/**
|
|
2079
|
+
* Store contextual information about a `RouterOutlet`
|
|
2080
|
+
*
|
|
2081
|
+
* @publicApi
|
|
2082
|
+
*/
|
|
2083
|
+
class OutletContext {
|
|
2084
|
+
constructor() {
|
|
2085
|
+
this.outlet = null;
|
|
2086
|
+
this.route = null;
|
|
2087
|
+
/**
|
|
2088
|
+
* @deprecated Passing a resolver to retrieve a component factory is not required and is
|
|
2089
|
+
* deprecated since v14.
|
|
2090
|
+
*/
|
|
2091
|
+
this.resolver = null;
|
|
2092
|
+
this.injector = null;
|
|
2093
|
+
this.children = new ChildrenOutletContexts();
|
|
2094
|
+
this.attachRef = null;
|
|
2079
2095
|
}
|
|
2080
|
-
|
|
2081
|
-
|
|
2082
|
-
|
|
2083
|
-
|
|
2084
|
-
|
|
2085
|
-
|
|
2086
|
-
|
|
2087
|
-
|
|
2088
|
-
|
|
2096
|
+
}
|
|
2097
|
+
/**
|
|
2098
|
+
* Store contextual information about the children (= nested) `RouterOutlet`
|
|
2099
|
+
*
|
|
2100
|
+
* @publicApi
|
|
2101
|
+
*/
|
|
2102
|
+
class ChildrenOutletContexts {
|
|
2103
|
+
constructor() {
|
|
2104
|
+
// contexts for child outlets, by name.
|
|
2105
|
+
this.contexts = new Map();
|
|
2089
2106
|
}
|
|
2090
|
-
|
|
2091
|
-
|
|
2092
|
-
const
|
|
2093
|
-
|
|
2094
|
-
|
|
2095
|
-
this.deactivateRouteAndItsChildren(children[childOutlet], contexts);
|
|
2096
|
-
}
|
|
2097
|
-
if (context && context.outlet) {
|
|
2098
|
-
const componentRef = context.outlet.detach();
|
|
2099
|
-
const contexts = context.children.onOutletDeactivated();
|
|
2100
|
-
this.routeReuseStrategy.store(route.value.snapshot, { componentRef, route, contexts });
|
|
2101
|
-
}
|
|
2107
|
+
/** Called when a `RouterOutlet` directive is instantiated */
|
|
2108
|
+
onChildOutletCreated(childName, outlet) {
|
|
2109
|
+
const context = this.getOrCreateContext(childName);
|
|
2110
|
+
context.outlet = outlet;
|
|
2111
|
+
this.contexts.set(childName, context);
|
|
2102
2112
|
}
|
|
2103
|
-
|
|
2104
|
-
|
|
2105
|
-
|
|
2106
|
-
|
|
2107
|
-
|
|
2108
|
-
|
|
2109
|
-
|
|
2110
|
-
|
|
2111
|
-
|
|
2112
|
-
if (context && context.outlet) {
|
|
2113
|
-
// Destroy the component
|
|
2114
|
-
context.outlet.deactivate();
|
|
2115
|
-
// Destroy the contexts for all the outlets that were in the component
|
|
2116
|
-
context.children.onOutletDeactivated();
|
|
2117
|
-
// Clear the information about the attached component on the context but keep the reference to
|
|
2118
|
-
// the outlet.
|
|
2113
|
+
/**
|
|
2114
|
+
* Called when a `RouterOutlet` directive is destroyed.
|
|
2115
|
+
* We need to keep the context as the outlet could be destroyed inside a NgIf and might be
|
|
2116
|
+
* re-created later.
|
|
2117
|
+
*/
|
|
2118
|
+
onChildOutletDestroyed(childName) {
|
|
2119
|
+
const context = this.getContext(childName);
|
|
2120
|
+
if (context) {
|
|
2121
|
+
context.outlet = null;
|
|
2119
2122
|
context.attachRef = null;
|
|
2120
|
-
context.resolver = null;
|
|
2121
|
-
context.route = null;
|
|
2122
2123
|
}
|
|
2123
2124
|
}
|
|
2124
|
-
|
|
2125
|
-
|
|
2126
|
-
|
|
2127
|
-
|
|
2128
|
-
|
|
2129
|
-
|
|
2130
|
-
|
|
2131
|
-
|
|
2132
|
-
}
|
|
2125
|
+
/**
|
|
2126
|
+
* Called when the corresponding route is deactivated during navigation.
|
|
2127
|
+
* Because the component get destroyed, all children outlet are destroyed.
|
|
2128
|
+
*/
|
|
2129
|
+
onOutletDeactivated() {
|
|
2130
|
+
const contexts = this.contexts;
|
|
2131
|
+
this.contexts = new Map();
|
|
2132
|
+
return contexts;
|
|
2133
2133
|
}
|
|
2134
|
-
|
|
2135
|
-
|
|
2136
|
-
|
|
2137
|
-
|
|
2138
|
-
|
|
2139
|
-
if (
|
|
2140
|
-
|
|
2141
|
-
|
|
2142
|
-
const context = parentContexts.getOrCreateContext(future.outlet);
|
|
2143
|
-
this.activateChildRoutes(futureNode, currNode, context.children);
|
|
2144
|
-
}
|
|
2145
|
-
else {
|
|
2146
|
-
// if we have a componentless route, we recurse but keep the same outlet map.
|
|
2147
|
-
this.activateChildRoutes(futureNode, currNode, parentContexts);
|
|
2148
|
-
}
|
|
2149
|
-
}
|
|
2150
|
-
else {
|
|
2151
|
-
if (future.component) {
|
|
2152
|
-
// if we have a normal route, we need to place the component into the outlet and recurse.
|
|
2153
|
-
const context = parentContexts.getOrCreateContext(future.outlet);
|
|
2154
|
-
if (this.routeReuseStrategy.shouldAttach(future.snapshot)) {
|
|
2155
|
-
const stored = this.routeReuseStrategy.retrieve(future.snapshot);
|
|
2156
|
-
this.routeReuseStrategy.store(future.snapshot, null);
|
|
2157
|
-
context.children.onOutletReAttached(stored.contexts);
|
|
2158
|
-
context.attachRef = stored.componentRef;
|
|
2159
|
-
context.route = stored.route.value;
|
|
2160
|
-
if (context.outlet) {
|
|
2161
|
-
// Attach right away when the outlet has already been instantiated
|
|
2162
|
-
// Otherwise attach from `RouterOutlet.ngOnInit` when it is instantiated
|
|
2163
|
-
context.outlet.attach(stored.componentRef, stored.route.value);
|
|
2164
|
-
}
|
|
2165
|
-
advanceActivatedRoute(stored.route.value);
|
|
2166
|
-
this.activateChildRoutes(futureNode, null, context.children);
|
|
2167
|
-
}
|
|
2168
|
-
else {
|
|
2169
|
-
const config = parentLoadedConfig(future.snapshot);
|
|
2170
|
-
const cmpFactoryResolver = config ? config.module.componentFactoryResolver : null;
|
|
2171
|
-
context.attachRef = null;
|
|
2172
|
-
context.route = future;
|
|
2173
|
-
context.resolver = cmpFactoryResolver;
|
|
2174
|
-
if (context.outlet) {
|
|
2175
|
-
// Activate the outlet when it has already been instantiated
|
|
2176
|
-
// Otherwise it will get activated from its `ngOnInit` when instantiated
|
|
2177
|
-
context.outlet.activateWith(future, cmpFactoryResolver);
|
|
2178
|
-
}
|
|
2179
|
-
this.activateChildRoutes(futureNode, null, context.children);
|
|
2180
|
-
}
|
|
2181
|
-
}
|
|
2182
|
-
else {
|
|
2183
|
-
// if we have a componentless route, we recurse but keep the same outlet map.
|
|
2184
|
-
this.activateChildRoutes(futureNode, null, parentContexts);
|
|
2185
|
-
}
|
|
2134
|
+
onOutletReAttached(contexts) {
|
|
2135
|
+
this.contexts = contexts;
|
|
2136
|
+
}
|
|
2137
|
+
getOrCreateContext(childName) {
|
|
2138
|
+
let context = this.getContext(childName);
|
|
2139
|
+
if (!context) {
|
|
2140
|
+
context = new OutletContext();
|
|
2141
|
+
this.contexts.set(childName, context);
|
|
2186
2142
|
}
|
|
2143
|
+
return context;
|
|
2187
2144
|
}
|
|
2188
|
-
|
|
2189
|
-
|
|
2190
|
-
for (let s = snapshot.parent; s; s = s.parent) {
|
|
2191
|
-
const route = s.routeConfig;
|
|
2192
|
-
if (route && route._loadedConfig)
|
|
2193
|
-
return route._loadedConfig;
|
|
2194
|
-
if (route && route.component)
|
|
2195
|
-
return null;
|
|
2145
|
+
getContext(childName) {
|
|
2146
|
+
return this.contexts.get(childName) || null;
|
|
2196
2147
|
}
|
|
2197
|
-
return null;
|
|
2198
2148
|
}
|
|
2199
2149
|
|
|
2200
2150
|
/**
|
|
@@ -2204,182 +2154,13 @@ function parentLoadedConfig(snapshot) {
|
|
|
2204
2154
|
* Use of this source code is governed by an MIT-style license that can be
|
|
2205
2155
|
* found in the LICENSE file at https://angular.io/license
|
|
2206
2156
|
*/
|
|
2207
|
-
class LoadedRouterConfig {
|
|
2208
|
-
constructor(routes, module) {
|
|
2209
|
-
this.routes = routes;
|
|
2210
|
-
this.module = module;
|
|
2211
|
-
}
|
|
2212
|
-
}
|
|
2213
|
-
|
|
2214
2157
|
/**
|
|
2215
|
-
* @
|
|
2216
|
-
* Copyright Google LLC All Rights Reserved.
|
|
2158
|
+
* @description
|
|
2217
2159
|
*
|
|
2218
|
-
*
|
|
2219
|
-
* found in the LICENSE file at https://angular.io/license
|
|
2220
|
-
*/
|
|
2221
|
-
/**
|
|
2222
|
-
* Simple function check, but generic so type inference will flow. Example:
|
|
2160
|
+
* Acts as a placeholder that Angular dynamically fills based on the current router state.
|
|
2223
2161
|
*
|
|
2224
|
-
*
|
|
2225
|
-
*
|
|
2226
|
-
* }
|
|
2227
|
-
*
|
|
2228
|
-
* if (isFunction<product>(fn)) {
|
|
2229
|
-
* return fn(1, 2);
|
|
2230
|
-
* } else {
|
|
2231
|
-
* throw "Must provide the `product` function";
|
|
2232
|
-
* }
|
|
2233
|
-
*/
|
|
2234
|
-
function isFunction(v) {
|
|
2235
|
-
return typeof v === 'function';
|
|
2236
|
-
}
|
|
2237
|
-
function isBoolean(v) {
|
|
2238
|
-
return typeof v === 'boolean';
|
|
2239
|
-
}
|
|
2240
|
-
function isUrlTree(v) {
|
|
2241
|
-
return v instanceof UrlTree;
|
|
2242
|
-
}
|
|
2243
|
-
function isCanLoad(guard) {
|
|
2244
|
-
return guard && isFunction(guard.canLoad);
|
|
2245
|
-
}
|
|
2246
|
-
function isCanActivate(guard) {
|
|
2247
|
-
return guard && isFunction(guard.canActivate);
|
|
2248
|
-
}
|
|
2249
|
-
function isCanActivateChild(guard) {
|
|
2250
|
-
return guard && isFunction(guard.canActivateChild);
|
|
2251
|
-
}
|
|
2252
|
-
function isCanDeactivate(guard) {
|
|
2253
|
-
return guard && isFunction(guard.canDeactivate);
|
|
2254
|
-
}
|
|
2255
|
-
|
|
2256
|
-
/**
|
|
2257
|
-
* @license
|
|
2258
|
-
* Copyright Google LLC All Rights Reserved.
|
|
2259
|
-
*
|
|
2260
|
-
* Use of this source code is governed by an MIT-style license that can be
|
|
2261
|
-
* found in the LICENSE file at https://angular.io/license
|
|
2262
|
-
*/
|
|
2263
|
-
const INITIAL_VALUE = Symbol('INITIAL_VALUE');
|
|
2264
|
-
function prioritizedGuardValue() {
|
|
2265
|
-
return switchMap(obs => {
|
|
2266
|
-
return combineLatest(obs.map(o => o.pipe(take(1), startWith(INITIAL_VALUE))))
|
|
2267
|
-
.pipe(scan((acc, list) => {
|
|
2268
|
-
let isPending = false;
|
|
2269
|
-
return list.reduce((innerAcc, val, i) => {
|
|
2270
|
-
if (innerAcc !== INITIAL_VALUE)
|
|
2271
|
-
return innerAcc;
|
|
2272
|
-
// Toggle pending flag if any values haven't been set yet
|
|
2273
|
-
if (val === INITIAL_VALUE)
|
|
2274
|
-
isPending = true;
|
|
2275
|
-
// Any other return values are only valid if we haven't yet hit a pending
|
|
2276
|
-
// call. This guarantees that in the case of a guard at the bottom of the
|
|
2277
|
-
// tree that returns a redirect, we will wait for the higher priority
|
|
2278
|
-
// guard at the top to finish before performing the redirect.
|
|
2279
|
-
if (!isPending) {
|
|
2280
|
-
// Early return when we hit a `false` value as that should always
|
|
2281
|
-
// cancel navigation
|
|
2282
|
-
if (val === false)
|
|
2283
|
-
return val;
|
|
2284
|
-
if (i === list.length - 1 || isUrlTree(val)) {
|
|
2285
|
-
return val;
|
|
2286
|
-
}
|
|
2287
|
-
}
|
|
2288
|
-
return innerAcc;
|
|
2289
|
-
}, acc);
|
|
2290
|
-
}, INITIAL_VALUE), filter(item => item !== INITIAL_VALUE), map(item => isUrlTree(item) ? item : item === true), //
|
|
2291
|
-
take(1));
|
|
2292
|
-
});
|
|
2293
|
-
}
|
|
2294
|
-
|
|
2295
|
-
/**
|
|
2296
|
-
* @license
|
|
2297
|
-
* Copyright Google LLC All Rights Reserved.
|
|
2298
|
-
*
|
|
2299
|
-
* Use of this source code is governed by an MIT-style license that can be
|
|
2300
|
-
* found in the LICENSE file at https://angular.io/license
|
|
2301
|
-
*/
|
|
2302
|
-
/**
|
|
2303
|
-
* Store contextual information about a `RouterOutlet`
|
|
2304
|
-
*
|
|
2305
|
-
* @publicApi
|
|
2306
|
-
*/
|
|
2307
|
-
class OutletContext {
|
|
2308
|
-
constructor() {
|
|
2309
|
-
this.outlet = null;
|
|
2310
|
-
this.route = null;
|
|
2311
|
-
this.resolver = null;
|
|
2312
|
-
this.children = new ChildrenOutletContexts();
|
|
2313
|
-
this.attachRef = null;
|
|
2314
|
-
}
|
|
2315
|
-
}
|
|
2316
|
-
/**
|
|
2317
|
-
* Store contextual information about the children (= nested) `RouterOutlet`
|
|
2318
|
-
*
|
|
2319
|
-
* @publicApi
|
|
2320
|
-
*/
|
|
2321
|
-
class ChildrenOutletContexts {
|
|
2322
|
-
constructor() {
|
|
2323
|
-
// contexts for child outlets, by name.
|
|
2324
|
-
this.contexts = new Map();
|
|
2325
|
-
}
|
|
2326
|
-
/** Called when a `RouterOutlet` directive is instantiated */
|
|
2327
|
-
onChildOutletCreated(childName, outlet) {
|
|
2328
|
-
const context = this.getOrCreateContext(childName);
|
|
2329
|
-
context.outlet = outlet;
|
|
2330
|
-
this.contexts.set(childName, context);
|
|
2331
|
-
}
|
|
2332
|
-
/**
|
|
2333
|
-
* Called when a `RouterOutlet` directive is destroyed.
|
|
2334
|
-
* We need to keep the context as the outlet could be destroyed inside a NgIf and might be
|
|
2335
|
-
* re-created later.
|
|
2336
|
-
*/
|
|
2337
|
-
onChildOutletDestroyed(childName) {
|
|
2338
|
-
const context = this.getContext(childName);
|
|
2339
|
-
if (context) {
|
|
2340
|
-
context.outlet = null;
|
|
2341
|
-
context.attachRef = null;
|
|
2342
|
-
}
|
|
2343
|
-
}
|
|
2344
|
-
/**
|
|
2345
|
-
* Called when the corresponding route is deactivated during navigation.
|
|
2346
|
-
* Because the component get destroyed, all children outlet are destroyed.
|
|
2347
|
-
*/
|
|
2348
|
-
onOutletDeactivated() {
|
|
2349
|
-
const contexts = this.contexts;
|
|
2350
|
-
this.contexts = new Map();
|
|
2351
|
-
return contexts;
|
|
2352
|
-
}
|
|
2353
|
-
onOutletReAttached(contexts) {
|
|
2354
|
-
this.contexts = contexts;
|
|
2355
|
-
}
|
|
2356
|
-
getOrCreateContext(childName) {
|
|
2357
|
-
let context = this.getContext(childName);
|
|
2358
|
-
if (!context) {
|
|
2359
|
-
context = new OutletContext();
|
|
2360
|
-
this.contexts.set(childName, context);
|
|
2361
|
-
}
|
|
2362
|
-
return context;
|
|
2363
|
-
}
|
|
2364
|
-
getContext(childName) {
|
|
2365
|
-
return this.contexts.get(childName) || null;
|
|
2366
|
-
}
|
|
2367
|
-
}
|
|
2368
|
-
|
|
2369
|
-
/**
|
|
2370
|
-
* @license
|
|
2371
|
-
* Copyright Google LLC All Rights Reserved.
|
|
2372
|
-
*
|
|
2373
|
-
* Use of this source code is governed by an MIT-style license that can be
|
|
2374
|
-
* found in the LICENSE file at https://angular.io/license
|
|
2375
|
-
*/
|
|
2376
|
-
/**
|
|
2377
|
-
* @description
|
|
2378
|
-
*
|
|
2379
|
-
* Acts as a placeholder that Angular dynamically fills based on the current router state.
|
|
2380
|
-
*
|
|
2381
|
-
* Each outlet can have a unique name, determined by the optional `name` attribute.
|
|
2382
|
-
* The name cannot be set or changed dynamically. If not set, default value is "primary".
|
|
2162
|
+
* Each outlet can have a unique name, determined by the optional `name` attribute.
|
|
2163
|
+
* The name cannot be set or changed dynamically. If not set, default value is "primary".
|
|
2383
2164
|
*
|
|
2384
2165
|
* ```
|
|
2385
2166
|
* <router-outlet></router-outlet>
|
|
@@ -2425,11 +2206,11 @@ class ChildrenOutletContexts {
|
|
|
2425
2206
|
* @publicApi
|
|
2426
2207
|
*/
|
|
2427
2208
|
class RouterOutlet {
|
|
2428
|
-
constructor(parentContexts, location,
|
|
2209
|
+
constructor(parentContexts, location, name, changeDetector, environmentInjector) {
|
|
2429
2210
|
this.parentContexts = parentContexts;
|
|
2430
2211
|
this.location = location;
|
|
2431
|
-
this.resolver = resolver;
|
|
2432
2212
|
this.changeDetector = changeDetector;
|
|
2213
|
+
this.environmentInjector = environmentInjector;
|
|
2433
2214
|
this.activated = null;
|
|
2434
2215
|
this._activatedRoute = null;
|
|
2435
2216
|
this.activateEvents = new EventEmitter();
|
|
@@ -2464,7 +2245,7 @@ class RouterOutlet {
|
|
|
2464
2245
|
}
|
|
2465
2246
|
else {
|
|
2466
2247
|
// otherwise the component defined in the configuration is created
|
|
2467
|
-
this.activateWith(context.route, context.
|
|
2248
|
+
this.activateWith(context.route, context.injector);
|
|
2468
2249
|
}
|
|
2469
2250
|
}
|
|
2470
2251
|
}
|
|
@@ -2523,33 +2304,39 @@ class RouterOutlet {
|
|
|
2523
2304
|
this.deactivateEvents.emit(c);
|
|
2524
2305
|
}
|
|
2525
2306
|
}
|
|
2526
|
-
activateWith(activatedRoute,
|
|
2307
|
+
activateWith(activatedRoute, resolverOrInjector) {
|
|
2527
2308
|
if (this.isActivated) {
|
|
2528
2309
|
throw new Error('Cannot activate an already activated outlet');
|
|
2529
2310
|
}
|
|
2530
2311
|
this._activatedRoute = activatedRoute;
|
|
2312
|
+
const location = this.location;
|
|
2531
2313
|
const snapshot = activatedRoute._futureSnapshot;
|
|
2532
|
-
const component = snapshot.
|
|
2533
|
-
resolver = resolver || this.resolver;
|
|
2534
|
-
const factory = resolver.resolveComponentFactory(component);
|
|
2314
|
+
const component = snapshot.component;
|
|
2535
2315
|
const childContexts = this.parentContexts.getOrCreateContext(this.name).children;
|
|
2536
|
-
const injector = new OutletInjector(activatedRoute, childContexts,
|
|
2537
|
-
|
|
2316
|
+
const injector = new OutletInjector(activatedRoute, childContexts, location.injector);
|
|
2317
|
+
if (resolverOrInjector && isComponentFactoryResolver(resolverOrInjector)) {
|
|
2318
|
+
const factory = resolverOrInjector.resolveComponentFactory(component);
|
|
2319
|
+
this.activated = location.createComponent(factory, location.length, injector);
|
|
2320
|
+
}
|
|
2321
|
+
else {
|
|
2322
|
+
const environmentInjector = resolverOrInjector ?? this.environmentInjector;
|
|
2323
|
+
this.activated = location.createComponent(component, { index: location.length, injector, environmentInjector });
|
|
2324
|
+
}
|
|
2538
2325
|
// Calling `markForCheck` to make sure we will run the change detection when the
|
|
2539
2326
|
// `RouterOutlet` is inside a `ChangeDetectionStrategy.OnPush` component.
|
|
2540
2327
|
this.changeDetector.markForCheck();
|
|
2541
2328
|
this.activateEvents.emit(this.activated.instance);
|
|
2542
2329
|
}
|
|
2543
2330
|
}
|
|
2544
|
-
RouterOutlet.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.0-next.
|
|
2545
|
-
RouterOutlet.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "
|
|
2546
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.0-next.
|
|
2331
|
+
RouterOutlet.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.0-next.16", ngImport: i0, type: RouterOutlet, deps: [{ token: ChildrenOutletContexts }, { token: i0.ViewContainerRef }, { token: 'name', attribute: true }, { token: i0.ChangeDetectorRef }, { token: i0.EnvironmentInjector }], target: i0.ɵɵFactoryTarget.Directive });
|
|
2332
|
+
RouterOutlet.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "14.0.0-next.16", type: RouterOutlet, selector: "router-outlet", outputs: { activateEvents: "activate", deactivateEvents: "deactivate", attachEvents: "attach", detachEvents: "detach" }, exportAs: ["outlet"], ngImport: i0 });
|
|
2333
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.0-next.16", ngImport: i0, type: RouterOutlet, decorators: [{
|
|
2547
2334
|
type: Directive,
|
|
2548
2335
|
args: [{ selector: 'router-outlet', exportAs: 'outlet' }]
|
|
2549
|
-
}], ctorParameters: function () { return [{ type: ChildrenOutletContexts }, { type: i0.ViewContainerRef }, { type:
|
|
2336
|
+
}], ctorParameters: function () { return [{ type: ChildrenOutletContexts }, { type: i0.ViewContainerRef }, { type: undefined, decorators: [{
|
|
2550
2337
|
type: Attribute,
|
|
2551
2338
|
args: ['name']
|
|
2552
|
-
}] }, { type: i0.ChangeDetectorRef }]; }, propDecorators: { activateEvents: [{
|
|
2339
|
+
}] }, { type: i0.ChangeDetectorRef }, { type: i0.EnvironmentInjector }]; }, propDecorators: { activateEvents: [{
|
|
2553
2340
|
type: Output,
|
|
2554
2341
|
args: ['activate']
|
|
2555
2342
|
}], deactivateEvents: [{
|
|
@@ -2572,10 +2359,388 @@ class OutletInjector {
|
|
|
2572
2359
|
if (token === ActivatedRoute) {
|
|
2573
2360
|
return this.route;
|
|
2574
2361
|
}
|
|
2575
|
-
if (token === ChildrenOutletContexts) {
|
|
2576
|
-
return this.childContexts;
|
|
2362
|
+
if (token === ChildrenOutletContexts) {
|
|
2363
|
+
return this.childContexts;
|
|
2364
|
+
}
|
|
2365
|
+
return this.parent.get(token, notFoundValue);
|
|
2366
|
+
}
|
|
2367
|
+
}
|
|
2368
|
+
function isComponentFactoryResolver(item) {
|
|
2369
|
+
return !!item.resolveComponentFactory;
|
|
2370
|
+
}
|
|
2371
|
+
|
|
2372
|
+
/**
|
|
2373
|
+
* @license
|
|
2374
|
+
* Copyright Google LLC All Rights Reserved.
|
|
2375
|
+
*
|
|
2376
|
+
* Use of this source code is governed by an MIT-style license that can be
|
|
2377
|
+
* found in the LICENSE file at https://angular.io/license
|
|
2378
|
+
*/
|
|
2379
|
+
/**
|
|
2380
|
+
* This component is used internally within the router to be a placeholder when an empty
|
|
2381
|
+
* router-outlet is needed. For example, with a config such as:
|
|
2382
|
+
*
|
|
2383
|
+
* `{path: 'parent', outlet: 'nav', children: [...]}`
|
|
2384
|
+
*
|
|
2385
|
+
* In order to render, there needs to be a component on this config, which will default
|
|
2386
|
+
* to this `EmptyOutletComponent`.
|
|
2387
|
+
*/
|
|
2388
|
+
class ɵEmptyOutletComponent {
|
|
2389
|
+
}
|
|
2390
|
+
ɵEmptyOutletComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.0-next.16", ngImport: i0, type: ɵEmptyOutletComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2391
|
+
ɵEmptyOutletComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.0.0-next.16", type: ɵEmptyOutletComponent, selector: "ng-component", ngImport: i0, template: `<router-outlet></router-outlet>`, isInline: true, dependencies: [{ kind: "directive", type: RouterOutlet, selector: "router-outlet", outputs: ["activate", "deactivate", "attach", "detach"], exportAs: ["outlet"] }] });
|
|
2392
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.0-next.16", ngImport: i0, type: ɵEmptyOutletComponent, decorators: [{
|
|
2393
|
+
type: Component,
|
|
2394
|
+
args: [{ template: `<router-outlet></router-outlet>` }]
|
|
2395
|
+
}] });
|
|
2396
|
+
|
|
2397
|
+
/**
|
|
2398
|
+
* @license
|
|
2399
|
+
* Copyright Google LLC All Rights Reserved.
|
|
2400
|
+
*
|
|
2401
|
+
* Use of this source code is governed by an MIT-style license that can be
|
|
2402
|
+
* found in the LICENSE file at https://angular.io/license
|
|
2403
|
+
*/
|
|
2404
|
+
function getLoadedRoutes(route) {
|
|
2405
|
+
return route._loadedRoutes;
|
|
2406
|
+
}
|
|
2407
|
+
function getLoadedInjector(route) {
|
|
2408
|
+
return route._loadedInjector;
|
|
2409
|
+
}
|
|
2410
|
+
function getLoadedComponent(route) {
|
|
2411
|
+
return route._loadedComponent;
|
|
2412
|
+
}
|
|
2413
|
+
function getProvidersInjector(route) {
|
|
2414
|
+
return route._injector;
|
|
2415
|
+
}
|
|
2416
|
+
function validateConfig(config, parentPath = '', requireStandaloneComponents = false) {
|
|
2417
|
+
// forEach doesn't iterate undefined values
|
|
2418
|
+
for (let i = 0; i < config.length; i++) {
|
|
2419
|
+
const route = config[i];
|
|
2420
|
+
const fullPath = getFullPath(parentPath, route);
|
|
2421
|
+
validateNode(route, fullPath, requireStandaloneComponents);
|
|
2422
|
+
}
|
|
2423
|
+
}
|
|
2424
|
+
function assertStandalone(fullPath, component) {
|
|
2425
|
+
if (component && !ɵisStandalone(component)) {
|
|
2426
|
+
throw new Error(`Invalid configuration of route '${fullPath}'. The component must be standalone.`);
|
|
2427
|
+
}
|
|
2428
|
+
}
|
|
2429
|
+
function validateNode(route, fullPath, requireStandaloneComponents) {
|
|
2430
|
+
if (typeof ngDevMode === 'undefined' || ngDevMode) {
|
|
2431
|
+
if (!route) {
|
|
2432
|
+
throw new Error(`
|
|
2433
|
+
Invalid configuration of route '${fullPath}': Encountered undefined route.
|
|
2434
|
+
The reason might be an extra comma.
|
|
2435
|
+
|
|
2436
|
+
Example:
|
|
2437
|
+
const routes: Routes = [
|
|
2438
|
+
{ path: '', redirectTo: '/dashboard', pathMatch: 'full' },
|
|
2439
|
+
{ path: 'dashboard', component: DashboardComponent },, << two commas
|
|
2440
|
+
{ path: 'detail/:id', component: HeroDetailComponent }
|
|
2441
|
+
];
|
|
2442
|
+
`);
|
|
2443
|
+
}
|
|
2444
|
+
if (Array.isArray(route)) {
|
|
2445
|
+
throw new Error(`Invalid configuration of route '${fullPath}': Array cannot be specified`);
|
|
2446
|
+
}
|
|
2447
|
+
if (!route.component && !route.loadComponent && !route.children && !route.loadChildren &&
|
|
2448
|
+
(route.outlet && route.outlet !== PRIMARY_OUTLET)) {
|
|
2449
|
+
throw new Error(`Invalid configuration of route '${fullPath}': a componentless route without children or loadChildren cannot have a named outlet set`);
|
|
2450
|
+
}
|
|
2451
|
+
if (route.redirectTo && route.children) {
|
|
2452
|
+
throw new Error(`Invalid configuration of route '${fullPath}': redirectTo and children cannot be used together`);
|
|
2453
|
+
}
|
|
2454
|
+
if (route.redirectTo && route.loadChildren) {
|
|
2455
|
+
throw new Error(`Invalid configuration of route '${fullPath}': redirectTo and loadChildren cannot be used together`);
|
|
2456
|
+
}
|
|
2457
|
+
if (route.children && route.loadChildren) {
|
|
2458
|
+
throw new Error(`Invalid configuration of route '${fullPath}': children and loadChildren cannot be used together`);
|
|
2459
|
+
}
|
|
2460
|
+
if (route.redirectTo && (route.component || route.loadComponent)) {
|
|
2461
|
+
throw new Error(`Invalid configuration of route '${fullPath}': redirectTo and component/loadComponent cannot be used together`);
|
|
2462
|
+
}
|
|
2463
|
+
if (route.component && route.loadComponent) {
|
|
2464
|
+
throw new Error(`Invalid configuration of route '${fullPath}': component and loadComponent cannot be used together`);
|
|
2465
|
+
}
|
|
2466
|
+
if (route.redirectTo && route.canActivate) {
|
|
2467
|
+
throw new Error(`Invalid configuration of route '${fullPath}': redirectTo and canActivate cannot be used together. Redirects happen before activation ` +
|
|
2468
|
+
`so canActivate will never be executed.`);
|
|
2469
|
+
}
|
|
2470
|
+
if (route.path && route.matcher) {
|
|
2471
|
+
throw new Error(`Invalid configuration of route '${fullPath}': path and matcher cannot be used together`);
|
|
2472
|
+
}
|
|
2473
|
+
if (route.redirectTo === void 0 && !route.component && !route.loadComponent &&
|
|
2474
|
+
!route.children && !route.loadChildren) {
|
|
2475
|
+
throw new Error(`Invalid configuration of route '${fullPath}'. One of the following must be provided: component, loadComponent, redirectTo, children or loadChildren`);
|
|
2476
|
+
}
|
|
2477
|
+
if (route.path === void 0 && route.matcher === void 0) {
|
|
2478
|
+
throw new Error(`Invalid configuration of route '${fullPath}': routes must have either a path or a matcher specified`);
|
|
2479
|
+
}
|
|
2480
|
+
if (typeof route.path === 'string' && route.path.charAt(0) === '/') {
|
|
2481
|
+
throw new Error(`Invalid configuration of route '${fullPath}': path cannot start with a slash`);
|
|
2482
|
+
}
|
|
2483
|
+
if (route.path === '' && route.redirectTo !== void 0 && route.pathMatch === void 0) {
|
|
2484
|
+
const exp = `The default value of 'pathMatch' is 'prefix', but often the intent is to use 'full'.`;
|
|
2485
|
+
throw new Error(`Invalid configuration of route '{path: "${fullPath}", redirectTo: "${route.redirectTo}"}': please provide 'pathMatch'. ${exp}`);
|
|
2486
|
+
}
|
|
2487
|
+
if (requireStandaloneComponents) {
|
|
2488
|
+
assertStandalone(fullPath, route.component);
|
|
2489
|
+
}
|
|
2490
|
+
}
|
|
2491
|
+
if (route.children) {
|
|
2492
|
+
validateConfig(route.children, fullPath, requireStandaloneComponents);
|
|
2493
|
+
}
|
|
2494
|
+
}
|
|
2495
|
+
function getFullPath(parentPath, currentRoute) {
|
|
2496
|
+
if (!currentRoute) {
|
|
2497
|
+
return parentPath;
|
|
2498
|
+
}
|
|
2499
|
+
if (!parentPath && !currentRoute.path) {
|
|
2500
|
+
return '';
|
|
2501
|
+
}
|
|
2502
|
+
else if (parentPath && !currentRoute.path) {
|
|
2503
|
+
return `${parentPath}/`;
|
|
2504
|
+
}
|
|
2505
|
+
else if (!parentPath && currentRoute.path) {
|
|
2506
|
+
return currentRoute.path;
|
|
2507
|
+
}
|
|
2508
|
+
else {
|
|
2509
|
+
return `${parentPath}/${currentRoute.path}`;
|
|
2510
|
+
}
|
|
2511
|
+
}
|
|
2512
|
+
/**
|
|
2513
|
+
* Makes a copy of the config and adds any default required properties.
|
|
2514
|
+
*/
|
|
2515
|
+
function standardizeConfig(r) {
|
|
2516
|
+
const children = r.children && r.children.map(standardizeConfig);
|
|
2517
|
+
const c = children ? { ...r, children } : { ...r };
|
|
2518
|
+
if ((!c.component && !c.loadComponent) && (children || c.loadChildren) &&
|
|
2519
|
+
(c.outlet && c.outlet !== PRIMARY_OUTLET)) {
|
|
2520
|
+
c.component = ɵEmptyOutletComponent;
|
|
2521
|
+
}
|
|
2522
|
+
return c;
|
|
2523
|
+
}
|
|
2524
|
+
/** Returns the `route.outlet` or PRIMARY_OUTLET if none exists. */
|
|
2525
|
+
function getOutlet(route) {
|
|
2526
|
+
return route.outlet || PRIMARY_OUTLET;
|
|
2527
|
+
}
|
|
2528
|
+
/**
|
|
2529
|
+
* Sorts the `routes` such that the ones with an outlet matching `outletName` come first.
|
|
2530
|
+
* The order of the configs is otherwise preserved.
|
|
2531
|
+
*/
|
|
2532
|
+
function sortByMatchingOutlets(routes, outletName) {
|
|
2533
|
+
const sortedConfig = routes.filter(r => getOutlet(r) === outletName);
|
|
2534
|
+
sortedConfig.push(...routes.filter(r => getOutlet(r) !== outletName));
|
|
2535
|
+
return sortedConfig;
|
|
2536
|
+
}
|
|
2537
|
+
/**
|
|
2538
|
+
* Gets the first injector in the snapshot's parent tree.
|
|
2539
|
+
*
|
|
2540
|
+
* If the `Route` has a static list of providers, the returned injector will be the one created from
|
|
2541
|
+
* those. If it does not exist, the returned injector may come from the parents, which may be from a
|
|
2542
|
+
* loaded config or their static providers.
|
|
2543
|
+
*
|
|
2544
|
+
* Returns `null` if there is neither this nor any parents have a stored injector.
|
|
2545
|
+
*
|
|
2546
|
+
* Generally used for retrieving the injector to use for getting tokens for guards/resolvers and
|
|
2547
|
+
* also used for getting the correct injector to use for creating components.
|
|
2548
|
+
*/
|
|
2549
|
+
function getClosestRouteInjector(snapshot) {
|
|
2550
|
+
if (!snapshot)
|
|
2551
|
+
return null;
|
|
2552
|
+
// If the current route has its own injector, which is created from the static providers on the
|
|
2553
|
+
// route itself, we should use that. Otherwise, we start at the parent since we do not want to
|
|
2554
|
+
// include the lazy loaded injector from this route.
|
|
2555
|
+
if (snapshot.routeConfig?._injector) {
|
|
2556
|
+
return snapshot.routeConfig._injector;
|
|
2557
|
+
}
|
|
2558
|
+
for (let s = snapshot.parent; s; s = s.parent) {
|
|
2559
|
+
const route = s.routeConfig;
|
|
2560
|
+
// Note that the order here is important. `_loadedInjector` stored on the route with
|
|
2561
|
+
// `loadChildren: () => NgModule` so it applies to child routes with priority. The `_injector`
|
|
2562
|
+
// is created from the static providers on that parent route, so it applies to the children as
|
|
2563
|
+
// well, but only if there is no lazy loaded NgModuleRef injector.
|
|
2564
|
+
if (route?._loadedInjector)
|
|
2565
|
+
return route._loadedInjector;
|
|
2566
|
+
if (route?._injector)
|
|
2567
|
+
return route._injector;
|
|
2568
|
+
}
|
|
2569
|
+
return null;
|
|
2570
|
+
}
|
|
2571
|
+
|
|
2572
|
+
/**
|
|
2573
|
+
* @license
|
|
2574
|
+
* Copyright Google LLC All Rights Reserved.
|
|
2575
|
+
*
|
|
2576
|
+
* Use of this source code is governed by an MIT-style license that can be
|
|
2577
|
+
* found in the LICENSE file at https://angular.io/license
|
|
2578
|
+
*/
|
|
2579
|
+
const activateRoutes = (rootContexts, routeReuseStrategy, forwardEvent) => map(t => {
|
|
2580
|
+
new ActivateRoutes(routeReuseStrategy, t.targetRouterState, t.currentRouterState, forwardEvent)
|
|
2581
|
+
.activate(rootContexts);
|
|
2582
|
+
return t;
|
|
2583
|
+
});
|
|
2584
|
+
class ActivateRoutes {
|
|
2585
|
+
constructor(routeReuseStrategy, futureState, currState, forwardEvent) {
|
|
2586
|
+
this.routeReuseStrategy = routeReuseStrategy;
|
|
2587
|
+
this.futureState = futureState;
|
|
2588
|
+
this.currState = currState;
|
|
2589
|
+
this.forwardEvent = forwardEvent;
|
|
2590
|
+
}
|
|
2591
|
+
activate(parentContexts) {
|
|
2592
|
+
const futureRoot = this.futureState._root;
|
|
2593
|
+
const currRoot = this.currState ? this.currState._root : null;
|
|
2594
|
+
this.deactivateChildRoutes(futureRoot, currRoot, parentContexts);
|
|
2595
|
+
advanceActivatedRoute(this.futureState.root);
|
|
2596
|
+
this.activateChildRoutes(futureRoot, currRoot, parentContexts);
|
|
2597
|
+
}
|
|
2598
|
+
// De-activate the child route that are not re-used for the future state
|
|
2599
|
+
deactivateChildRoutes(futureNode, currNode, contexts) {
|
|
2600
|
+
const children = nodeChildrenAsMap(currNode);
|
|
2601
|
+
// Recurse on the routes active in the future state to de-activate deeper children
|
|
2602
|
+
futureNode.children.forEach(futureChild => {
|
|
2603
|
+
const childOutletName = futureChild.value.outlet;
|
|
2604
|
+
this.deactivateRoutes(futureChild, children[childOutletName], contexts);
|
|
2605
|
+
delete children[childOutletName];
|
|
2606
|
+
});
|
|
2607
|
+
// De-activate the routes that will not be re-used
|
|
2608
|
+
forEach(children, (v, childName) => {
|
|
2609
|
+
this.deactivateRouteAndItsChildren(v, contexts);
|
|
2610
|
+
});
|
|
2611
|
+
}
|
|
2612
|
+
deactivateRoutes(futureNode, currNode, parentContext) {
|
|
2613
|
+
const future = futureNode.value;
|
|
2614
|
+
const curr = currNode ? currNode.value : null;
|
|
2615
|
+
if (future === curr) {
|
|
2616
|
+
// Reusing the node, check to see if the children need to be de-activated
|
|
2617
|
+
if (future.component) {
|
|
2618
|
+
// If we have a normal route, we need to go through an outlet.
|
|
2619
|
+
const context = parentContext.getContext(future.outlet);
|
|
2620
|
+
if (context) {
|
|
2621
|
+
this.deactivateChildRoutes(futureNode, currNode, context.children);
|
|
2622
|
+
}
|
|
2623
|
+
}
|
|
2624
|
+
else {
|
|
2625
|
+
// if we have a componentless route, we recurse but keep the same outlet map.
|
|
2626
|
+
this.deactivateChildRoutes(futureNode, currNode, parentContext);
|
|
2627
|
+
}
|
|
2628
|
+
}
|
|
2629
|
+
else {
|
|
2630
|
+
if (curr) {
|
|
2631
|
+
// Deactivate the current route which will not be re-used
|
|
2632
|
+
this.deactivateRouteAndItsChildren(currNode, parentContext);
|
|
2633
|
+
}
|
|
2634
|
+
}
|
|
2635
|
+
}
|
|
2636
|
+
deactivateRouteAndItsChildren(route, parentContexts) {
|
|
2637
|
+
// If there is no component, the Route is never attached to an outlet (because there is no
|
|
2638
|
+
// component to attach).
|
|
2639
|
+
if (route.value.component && this.routeReuseStrategy.shouldDetach(route.value.snapshot)) {
|
|
2640
|
+
this.detachAndStoreRouteSubtree(route, parentContexts);
|
|
2641
|
+
}
|
|
2642
|
+
else {
|
|
2643
|
+
this.deactivateRouteAndOutlet(route, parentContexts);
|
|
2644
|
+
}
|
|
2645
|
+
}
|
|
2646
|
+
detachAndStoreRouteSubtree(route, parentContexts) {
|
|
2647
|
+
const context = parentContexts.getContext(route.value.outlet);
|
|
2648
|
+
const contexts = context && route.value.component ? context.children : parentContexts;
|
|
2649
|
+
const children = nodeChildrenAsMap(route);
|
|
2650
|
+
for (const childOutlet of Object.keys(children)) {
|
|
2651
|
+
this.deactivateRouteAndItsChildren(children[childOutlet], contexts);
|
|
2652
|
+
}
|
|
2653
|
+
if (context && context.outlet) {
|
|
2654
|
+
const componentRef = context.outlet.detach();
|
|
2655
|
+
const contexts = context.children.onOutletDeactivated();
|
|
2656
|
+
this.routeReuseStrategy.store(route.value.snapshot, { componentRef, route, contexts });
|
|
2657
|
+
}
|
|
2658
|
+
}
|
|
2659
|
+
deactivateRouteAndOutlet(route, parentContexts) {
|
|
2660
|
+
const context = parentContexts.getContext(route.value.outlet);
|
|
2661
|
+
// The context could be `null` if we are on a componentless route but there may still be
|
|
2662
|
+
// children that need deactivating.
|
|
2663
|
+
const contexts = context && route.value.component ? context.children : parentContexts;
|
|
2664
|
+
const children = nodeChildrenAsMap(route);
|
|
2665
|
+
for (const childOutlet of Object.keys(children)) {
|
|
2666
|
+
this.deactivateRouteAndItsChildren(children[childOutlet], contexts);
|
|
2667
|
+
}
|
|
2668
|
+
if (context && context.outlet) {
|
|
2669
|
+
// Destroy the component
|
|
2670
|
+
context.outlet.deactivate();
|
|
2671
|
+
// Destroy the contexts for all the outlets that were in the component
|
|
2672
|
+
context.children.onOutletDeactivated();
|
|
2673
|
+
// Clear the information about the attached component on the context but keep the reference to
|
|
2674
|
+
// the outlet.
|
|
2675
|
+
context.attachRef = null;
|
|
2676
|
+
context.resolver = null;
|
|
2677
|
+
context.route = null;
|
|
2678
|
+
}
|
|
2679
|
+
}
|
|
2680
|
+
activateChildRoutes(futureNode, currNode, contexts) {
|
|
2681
|
+
const children = nodeChildrenAsMap(currNode);
|
|
2682
|
+
futureNode.children.forEach(c => {
|
|
2683
|
+
this.activateRoutes(c, children[c.value.outlet], contexts);
|
|
2684
|
+
this.forwardEvent(new ActivationEnd(c.value.snapshot));
|
|
2685
|
+
});
|
|
2686
|
+
if (futureNode.children.length) {
|
|
2687
|
+
this.forwardEvent(new ChildActivationEnd(futureNode.value.snapshot));
|
|
2688
|
+
}
|
|
2689
|
+
}
|
|
2690
|
+
activateRoutes(futureNode, currNode, parentContexts) {
|
|
2691
|
+
const future = futureNode.value;
|
|
2692
|
+
const curr = currNode ? currNode.value : null;
|
|
2693
|
+
advanceActivatedRoute(future);
|
|
2694
|
+
// reusing the node
|
|
2695
|
+
if (future === curr) {
|
|
2696
|
+
if (future.component) {
|
|
2697
|
+
// If we have a normal route, we need to go through an outlet.
|
|
2698
|
+
const context = parentContexts.getOrCreateContext(future.outlet);
|
|
2699
|
+
this.activateChildRoutes(futureNode, currNode, context.children);
|
|
2700
|
+
}
|
|
2701
|
+
else {
|
|
2702
|
+
// if we have a componentless route, we recurse but keep the same outlet map.
|
|
2703
|
+
this.activateChildRoutes(futureNode, currNode, parentContexts);
|
|
2704
|
+
}
|
|
2705
|
+
}
|
|
2706
|
+
else {
|
|
2707
|
+
if (future.component) {
|
|
2708
|
+
// if we have a normal route, we need to place the component into the outlet and recurse.
|
|
2709
|
+
const context = parentContexts.getOrCreateContext(future.outlet);
|
|
2710
|
+
if (this.routeReuseStrategy.shouldAttach(future.snapshot)) {
|
|
2711
|
+
const stored = this.routeReuseStrategy.retrieve(future.snapshot);
|
|
2712
|
+
this.routeReuseStrategy.store(future.snapshot, null);
|
|
2713
|
+
context.children.onOutletReAttached(stored.contexts);
|
|
2714
|
+
context.attachRef = stored.componentRef;
|
|
2715
|
+
context.route = stored.route.value;
|
|
2716
|
+
if (context.outlet) {
|
|
2717
|
+
// Attach right away when the outlet has already been instantiated
|
|
2718
|
+
// Otherwise attach from `RouterOutlet.ngOnInit` when it is instantiated
|
|
2719
|
+
context.outlet.attach(stored.componentRef, stored.route.value);
|
|
2720
|
+
}
|
|
2721
|
+
advanceActivatedRoute(stored.route.value);
|
|
2722
|
+
this.activateChildRoutes(futureNode, null, context.children);
|
|
2723
|
+
}
|
|
2724
|
+
else {
|
|
2725
|
+
const injector = getClosestRouteInjector(future.snapshot);
|
|
2726
|
+
const cmpFactoryResolver = injector?.get(ComponentFactoryResolver) ?? null;
|
|
2727
|
+
context.attachRef = null;
|
|
2728
|
+
context.route = future;
|
|
2729
|
+
context.resolver = cmpFactoryResolver;
|
|
2730
|
+
context.injector = injector;
|
|
2731
|
+
if (context.outlet) {
|
|
2732
|
+
// Activate the outlet when it has already been instantiated
|
|
2733
|
+
// Otherwise it will get activated from its `ngOnInit` when instantiated
|
|
2734
|
+
context.outlet.activateWith(future, context.injector);
|
|
2735
|
+
}
|
|
2736
|
+
this.activateChildRoutes(futureNode, null, context.children);
|
|
2737
|
+
}
|
|
2738
|
+
}
|
|
2739
|
+
else {
|
|
2740
|
+
// if we have a componentless route, we recurse but keep the same outlet map.
|
|
2741
|
+
this.activateChildRoutes(futureNode, null, parentContexts);
|
|
2742
|
+
}
|
|
2577
2743
|
}
|
|
2578
|
-
return this.parent.get(token, notFoundValue);
|
|
2579
2744
|
}
|
|
2580
2745
|
}
|
|
2581
2746
|
|
|
@@ -2587,22 +2752,39 @@ class OutletInjector {
|
|
|
2587
2752
|
* found in the LICENSE file at https://angular.io/license
|
|
2588
2753
|
*/
|
|
2589
2754
|
/**
|
|
2590
|
-
*
|
|
2591
|
-
* router-outlet is needed. For example, with a config such as:
|
|
2755
|
+
* Simple function check, but generic so type inference will flow. Example:
|
|
2592
2756
|
*
|
|
2593
|
-
*
|
|
2757
|
+
* function product(a: number, b: number) {
|
|
2758
|
+
* return a * b;
|
|
2759
|
+
* }
|
|
2594
2760
|
*
|
|
2595
|
-
*
|
|
2596
|
-
*
|
|
2761
|
+
* if (isFunction<product>(fn)) {
|
|
2762
|
+
* return fn(1, 2);
|
|
2763
|
+
* } else {
|
|
2764
|
+
* throw "Must provide the `product` function";
|
|
2765
|
+
* }
|
|
2597
2766
|
*/
|
|
2598
|
-
|
|
2767
|
+
function isFunction(v) {
|
|
2768
|
+
return typeof v === 'function';
|
|
2769
|
+
}
|
|
2770
|
+
function isBoolean(v) {
|
|
2771
|
+
return typeof v === 'boolean';
|
|
2772
|
+
}
|
|
2773
|
+
function isUrlTree(v) {
|
|
2774
|
+
return v instanceof UrlTree;
|
|
2775
|
+
}
|
|
2776
|
+
function isCanLoad(guard) {
|
|
2777
|
+
return guard && isFunction(guard.canLoad);
|
|
2778
|
+
}
|
|
2779
|
+
function isCanActivate(guard) {
|
|
2780
|
+
return guard && isFunction(guard.canActivate);
|
|
2781
|
+
}
|
|
2782
|
+
function isCanActivateChild(guard) {
|
|
2783
|
+
return guard && isFunction(guard.canActivateChild);
|
|
2784
|
+
}
|
|
2785
|
+
function isCanDeactivate(guard) {
|
|
2786
|
+
return guard && isFunction(guard.canDeactivate);
|
|
2599
2787
|
}
|
|
2600
|
-
ɵEmptyOutletComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.0-next.13", ngImport: i0, type: ɵEmptyOutletComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2601
|
-
ɵEmptyOutletComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "14.0.0-next.13", type: ɵEmptyOutletComponent, selector: "ng-component", ngImport: i0, template: `<router-outlet></router-outlet>`, isInline: true, directives: [{ type: RouterOutlet, selector: "router-outlet", outputs: ["activate", "deactivate", "attach", "detach"], exportAs: ["outlet"] }] });
|
|
2602
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.0-next.13", ngImport: i0, type: ɵEmptyOutletComponent, decorators: [{
|
|
2603
|
-
type: Component,
|
|
2604
|
-
args: [{ template: `<router-outlet></router-outlet>` }]
|
|
2605
|
-
}] });
|
|
2606
2788
|
|
|
2607
2789
|
/**
|
|
2608
2790
|
* @license
|
|
@@ -2611,113 +2793,36 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.0-next.13",
|
|
|
2611
2793
|
* Use of this source code is governed by an MIT-style license that can be
|
|
2612
2794
|
* found in the LICENSE file at https://angular.io/license
|
|
2613
2795
|
*/
|
|
2614
|
-
|
|
2615
|
-
|
|
2616
|
-
|
|
2617
|
-
|
|
2618
|
-
|
|
2619
|
-
|
|
2620
|
-
|
|
2621
|
-
|
|
2622
|
-
|
|
2623
|
-
|
|
2624
|
-
|
|
2625
|
-
|
|
2626
|
-
|
|
2627
|
-
|
|
2628
|
-
|
|
2629
|
-
|
|
2630
|
-
|
|
2631
|
-
|
|
2632
|
-
|
|
2633
|
-
|
|
2634
|
-
|
|
2635
|
-
|
|
2636
|
-
|
|
2637
|
-
|
|
2638
|
-
|
|
2639
|
-
|
|
2640
|
-
|
|
2641
|
-
|
|
2642
|
-
|
|
2643
|
-
|
|
2644
|
-
if (route.redirectTo && route.children) {
|
|
2645
|
-
throw new Error(`Invalid configuration of route '${fullPath}': redirectTo and children cannot be used together`);
|
|
2646
|
-
}
|
|
2647
|
-
if (route.redirectTo && route.loadChildren) {
|
|
2648
|
-
throw new Error(`Invalid configuration of route '${fullPath}': redirectTo and loadChildren cannot be used together`);
|
|
2649
|
-
}
|
|
2650
|
-
if (route.children && route.loadChildren) {
|
|
2651
|
-
throw new Error(`Invalid configuration of route '${fullPath}': children and loadChildren cannot be used together`);
|
|
2652
|
-
}
|
|
2653
|
-
if (route.redirectTo && route.component) {
|
|
2654
|
-
throw new Error(`Invalid configuration of route '${fullPath}': redirectTo and component cannot be used together`);
|
|
2655
|
-
}
|
|
2656
|
-
if (route.redirectTo && route.canActivate) {
|
|
2657
|
-
throw new Error(`Invalid configuration of route '${fullPath}': redirectTo and canActivate cannot be used together. Redirects happen before activation ` +
|
|
2658
|
-
`so canActivate will never be executed.`);
|
|
2659
|
-
}
|
|
2660
|
-
if (route.path && route.matcher) {
|
|
2661
|
-
throw new Error(`Invalid configuration of route '${fullPath}': path and matcher cannot be used together`);
|
|
2662
|
-
}
|
|
2663
|
-
if (route.redirectTo === void 0 && !route.component && !route.children && !route.loadChildren) {
|
|
2664
|
-
throw new Error(`Invalid configuration of route '${fullPath}'. One of the following must be provided: component, redirectTo, children or loadChildren`);
|
|
2665
|
-
}
|
|
2666
|
-
if (route.path === void 0 && route.matcher === void 0) {
|
|
2667
|
-
throw new Error(`Invalid configuration of route '${fullPath}': routes must have either a path or a matcher specified`);
|
|
2668
|
-
}
|
|
2669
|
-
if (typeof route.path === 'string' && route.path.charAt(0) === '/') {
|
|
2670
|
-
throw new Error(`Invalid configuration of route '${fullPath}': path cannot start with a slash`);
|
|
2671
|
-
}
|
|
2672
|
-
if (route.path === '' && route.redirectTo !== void 0 && route.pathMatch === void 0) {
|
|
2673
|
-
const exp = `The default value of 'pathMatch' is 'prefix', but often the intent is to use 'full'.`;
|
|
2674
|
-
throw new Error(`Invalid configuration of route '{path: "${fullPath}", redirectTo: "${route.redirectTo}"}': please provide 'pathMatch'. ${exp}`);
|
|
2675
|
-
}
|
|
2676
|
-
}
|
|
2677
|
-
if (route.children) {
|
|
2678
|
-
validateConfig(route.children, fullPath);
|
|
2679
|
-
}
|
|
2680
|
-
}
|
|
2681
|
-
function getFullPath(parentPath, currentRoute) {
|
|
2682
|
-
if (!currentRoute) {
|
|
2683
|
-
return parentPath;
|
|
2684
|
-
}
|
|
2685
|
-
if (!parentPath && !currentRoute.path) {
|
|
2686
|
-
return '';
|
|
2687
|
-
}
|
|
2688
|
-
else if (parentPath && !currentRoute.path) {
|
|
2689
|
-
return `${parentPath}/`;
|
|
2690
|
-
}
|
|
2691
|
-
else if (!parentPath && currentRoute.path) {
|
|
2692
|
-
return currentRoute.path;
|
|
2693
|
-
}
|
|
2694
|
-
else {
|
|
2695
|
-
return `${parentPath}/${currentRoute.path}`;
|
|
2696
|
-
}
|
|
2697
|
-
}
|
|
2698
|
-
/**
|
|
2699
|
-
* Makes a copy of the config and adds any default required properties.
|
|
2700
|
-
*/
|
|
2701
|
-
function standardizeConfig(r) {
|
|
2702
|
-
const children = r.children && r.children.map(standardizeConfig);
|
|
2703
|
-
const c = children ? { ...r, children } : { ...r };
|
|
2704
|
-
if (!c.component && (children || c.loadChildren) && (c.outlet && c.outlet !== PRIMARY_OUTLET)) {
|
|
2705
|
-
c.component = ɵEmptyOutletComponent;
|
|
2706
|
-
}
|
|
2707
|
-
return c;
|
|
2708
|
-
}
|
|
2709
|
-
/** Returns the `route.outlet` or PRIMARY_OUTLET if none exists. */
|
|
2710
|
-
function getOutlet(route) {
|
|
2711
|
-
return route.outlet || PRIMARY_OUTLET;
|
|
2712
|
-
}
|
|
2713
|
-
/**
|
|
2714
|
-
* Sorts the `routes` such that the ones with an outlet matching `outletName` come first.
|
|
2715
|
-
* The order of the configs is otherwise preserved.
|
|
2716
|
-
*/
|
|
2717
|
-
function sortByMatchingOutlets(routes, outletName) {
|
|
2718
|
-
const sortedConfig = routes.filter(r => getOutlet(r) === outletName);
|
|
2719
|
-
sortedConfig.push(...routes.filter(r => getOutlet(r) !== outletName));
|
|
2720
|
-
return sortedConfig;
|
|
2796
|
+
const INITIAL_VALUE = Symbol('INITIAL_VALUE');
|
|
2797
|
+
function prioritizedGuardValue() {
|
|
2798
|
+
return switchMap(obs => {
|
|
2799
|
+
return combineLatest(obs.map(o => o.pipe(take(1), startWith(INITIAL_VALUE))))
|
|
2800
|
+
.pipe(scan((acc, list) => {
|
|
2801
|
+
let isPending = false;
|
|
2802
|
+
return list.reduce((innerAcc, val, i) => {
|
|
2803
|
+
if (innerAcc !== INITIAL_VALUE)
|
|
2804
|
+
return innerAcc;
|
|
2805
|
+
// Toggle pending flag if any values haven't been set yet
|
|
2806
|
+
if (val === INITIAL_VALUE)
|
|
2807
|
+
isPending = true;
|
|
2808
|
+
// Any other return values are only valid if we haven't yet hit a pending
|
|
2809
|
+
// call. This guarantees that in the case of a guard at the bottom of the
|
|
2810
|
+
// tree that returns a redirect, we will wait for the higher priority
|
|
2811
|
+
// guard at the top to finish before performing the redirect.
|
|
2812
|
+
if (!isPending) {
|
|
2813
|
+
// Early return when we hit a `false` value as that should always
|
|
2814
|
+
// cancel navigation
|
|
2815
|
+
if (val === false)
|
|
2816
|
+
return val;
|
|
2817
|
+
if (i === list.length - 1 || isUrlTree(val)) {
|
|
2818
|
+
return val;
|
|
2819
|
+
}
|
|
2820
|
+
}
|
|
2821
|
+
return innerAcc;
|
|
2822
|
+
}, acc);
|
|
2823
|
+
}, INITIAL_VALUE), filter(item => item !== INITIAL_VALUE), map(item => isUrlTree(item) ? item : item === true), //
|
|
2824
|
+
take(1));
|
|
2825
|
+
});
|
|
2721
2826
|
}
|
|
2722
2827
|
|
|
2723
2828
|
/**
|
|
@@ -2898,17 +3003,17 @@ function canLoadFails(route) {
|
|
|
2898
3003
|
*
|
|
2899
3004
|
* Lazy modules are loaded along the way.
|
|
2900
3005
|
*/
|
|
2901
|
-
function applyRedirects$1(
|
|
2902
|
-
return new ApplyRedirects(
|
|
3006
|
+
function applyRedirects$1(injector, configLoader, urlSerializer, urlTree, config) {
|
|
3007
|
+
return new ApplyRedirects(injector, configLoader, urlSerializer, urlTree, config).apply();
|
|
2903
3008
|
}
|
|
2904
3009
|
class ApplyRedirects {
|
|
2905
|
-
constructor(
|
|
3010
|
+
constructor(injector, configLoader, urlSerializer, urlTree, config) {
|
|
3011
|
+
this.injector = injector;
|
|
2906
3012
|
this.configLoader = configLoader;
|
|
2907
3013
|
this.urlSerializer = urlSerializer;
|
|
2908
3014
|
this.urlTree = urlTree;
|
|
2909
3015
|
this.config = config;
|
|
2910
3016
|
this.allowRedirects = true;
|
|
2911
|
-
this.ngModule = moduleInjector.get(NgModuleRef);
|
|
2912
3017
|
}
|
|
2913
3018
|
apply() {
|
|
2914
3019
|
const splitGroup = split(this.urlTree.root, [], [], this.config).segmentGroup;
|
|
@@ -2919,7 +3024,7 @@ class ApplyRedirects {
|
|
|
2919
3024
|
// them. We should be able to remove this logic as a "breaking change" but should do some more
|
|
2920
3025
|
// investigation into the failures first.
|
|
2921
3026
|
const rootSegmentGroup = new UrlSegmentGroup(splitGroup.segments, splitGroup.children);
|
|
2922
|
-
const expanded$ = this.expandSegmentGroup(this.
|
|
3027
|
+
const expanded$ = this.expandSegmentGroup(this.injector, this.config, rootSegmentGroup, PRIMARY_OUTLET);
|
|
2923
3028
|
const urlTrees$ = expanded$.pipe(map((rootSegmentGroup) => {
|
|
2924
3029
|
return this.createUrlTree(squashSegmentGroup(rootSegmentGroup), this.urlTree.queryParams, this.urlTree.fragment);
|
|
2925
3030
|
}));
|
|
@@ -2938,7 +3043,7 @@ class ApplyRedirects {
|
|
|
2938
3043
|
}));
|
|
2939
3044
|
}
|
|
2940
3045
|
match(tree) {
|
|
2941
|
-
const expanded$ = this.expandSegmentGroup(this.
|
|
3046
|
+
const expanded$ = this.expandSegmentGroup(this.injector, this.config, tree.root, PRIMARY_OUTLET);
|
|
2942
3047
|
const mapped$ = expanded$.pipe(map((rootSegmentGroup) => {
|
|
2943
3048
|
return this.createUrlTree(squashSegmentGroup(rootSegmentGroup), tree.queryParams, tree.fragment);
|
|
2944
3049
|
}));
|
|
@@ -2958,15 +3063,15 @@ class ApplyRedirects {
|
|
|
2958
3063
|
rootCandidate;
|
|
2959
3064
|
return new UrlTree(root, queryParams, fragment);
|
|
2960
3065
|
}
|
|
2961
|
-
expandSegmentGroup(
|
|
3066
|
+
expandSegmentGroup(injector, routes, segmentGroup, outlet) {
|
|
2962
3067
|
if (segmentGroup.segments.length === 0 && segmentGroup.hasChildren()) {
|
|
2963
|
-
return this.expandChildren(
|
|
3068
|
+
return this.expandChildren(injector, routes, segmentGroup)
|
|
2964
3069
|
.pipe(map((children) => new UrlSegmentGroup([], children)));
|
|
2965
3070
|
}
|
|
2966
|
-
return this.expandSegment(
|
|
3071
|
+
return this.expandSegment(injector, segmentGroup, routes, segmentGroup.segments, outlet, true);
|
|
2967
3072
|
}
|
|
2968
3073
|
// Recursively expand segment groups for all the child outlets
|
|
2969
|
-
expandChildren(
|
|
3074
|
+
expandChildren(injector, routes, segmentGroup) {
|
|
2970
3075
|
// Expand outlets one at a time, starting with the primary outlet. We need to do it this way
|
|
2971
3076
|
// because an absolute redirect from the primary outlet takes precedence.
|
|
2972
3077
|
const childOutlets = [];
|
|
@@ -2985,16 +3090,25 @@ class ApplyRedirects {
|
|
|
2985
3090
|
// first, followed by routes for other outlets, which might match if they have an
|
|
2986
3091
|
// empty path.
|
|
2987
3092
|
const sortedRoutes = sortByMatchingOutlets(routes, childOutlet);
|
|
2988
|
-
return this.expandSegmentGroup(
|
|
3093
|
+
return this.expandSegmentGroup(injector, sortedRoutes, child, childOutlet)
|
|
2989
3094
|
.pipe(map(s => ({ segment: s, outlet: childOutlet })));
|
|
2990
3095
|
}), scan((children, expandedChild) => {
|
|
2991
3096
|
children[expandedChild.outlet] = expandedChild.segment;
|
|
2992
3097
|
return children;
|
|
2993
3098
|
}, {}), last$1());
|
|
2994
3099
|
}
|
|
2995
|
-
expandSegment(
|
|
2996
|
-
return from(routes).pipe(concatMap(
|
|
2997
|
-
|
|
3100
|
+
expandSegment(injector, segmentGroup, routes, segments, outlet, allowRedirects) {
|
|
3101
|
+
return from(routes).pipe(concatMap(r => {
|
|
3102
|
+
if (r.providers && !r._injector) {
|
|
3103
|
+
r._injector = createEnvironmentInjector(r.providers, injector, `Route: ${r.path}`);
|
|
3104
|
+
}
|
|
3105
|
+
// We specifically _do not_ want to include the _loadedInjector here. The loaded injector
|
|
3106
|
+
// only applies to the route's children, not the route itself. Note that this distinction
|
|
3107
|
+
// only applies here to any tokens we try to retrieve during this phase. At the moment,
|
|
3108
|
+
// that only includes `canLoad`, which won't run again once the child module is loaded. As
|
|
3109
|
+
// a result, this makes no difference right now, but could in the future if there are more
|
|
3110
|
+
// actions here that need DI (for example, a canMatch guard).
|
|
3111
|
+
const expanded$ = this.expandSegmentAgainstRoute(r._injector ?? injector, segmentGroup, routes, r, segments, outlet, allowRedirects);
|
|
2998
3112
|
return expanded$.pipe(catchError((e) => {
|
|
2999
3113
|
if (e instanceof NoMatch$1) {
|
|
3000
3114
|
return of(null);
|
|
@@ -3011,35 +3125,35 @@ class ApplyRedirects {
|
|
|
3011
3125
|
throw e;
|
|
3012
3126
|
}));
|
|
3013
3127
|
}
|
|
3014
|
-
expandSegmentAgainstRoute(
|
|
3128
|
+
expandSegmentAgainstRoute(injector, segmentGroup, routes, route, paths, outlet, allowRedirects) {
|
|
3015
3129
|
if (!isImmediateMatch(route, segmentGroup, paths, outlet)) {
|
|
3016
3130
|
return noMatch(segmentGroup);
|
|
3017
3131
|
}
|
|
3018
3132
|
if (route.redirectTo === undefined) {
|
|
3019
|
-
return this.matchSegmentAgainstRoute(
|
|
3133
|
+
return this.matchSegmentAgainstRoute(injector, segmentGroup, route, paths, outlet);
|
|
3020
3134
|
}
|
|
3021
3135
|
if (allowRedirects && this.allowRedirects) {
|
|
3022
|
-
return this.expandSegmentAgainstRouteUsingRedirect(
|
|
3136
|
+
return this.expandSegmentAgainstRouteUsingRedirect(injector, segmentGroup, routes, route, paths, outlet);
|
|
3023
3137
|
}
|
|
3024
3138
|
return noMatch(segmentGroup);
|
|
3025
3139
|
}
|
|
3026
|
-
expandSegmentAgainstRouteUsingRedirect(
|
|
3140
|
+
expandSegmentAgainstRouteUsingRedirect(injector, segmentGroup, routes, route, segments, outlet) {
|
|
3027
3141
|
if (route.path === '**') {
|
|
3028
|
-
return this.expandWildCardWithParamsAgainstRouteUsingRedirect(
|
|
3142
|
+
return this.expandWildCardWithParamsAgainstRouteUsingRedirect(injector, routes, route, outlet);
|
|
3029
3143
|
}
|
|
3030
|
-
return this.expandRegularSegmentAgainstRouteUsingRedirect(
|
|
3144
|
+
return this.expandRegularSegmentAgainstRouteUsingRedirect(injector, segmentGroup, routes, route, segments, outlet);
|
|
3031
3145
|
}
|
|
3032
|
-
expandWildCardWithParamsAgainstRouteUsingRedirect(
|
|
3146
|
+
expandWildCardWithParamsAgainstRouteUsingRedirect(injector, routes, route, outlet) {
|
|
3033
3147
|
const newTree = this.applyRedirectCommands([], route.redirectTo, {});
|
|
3034
3148
|
if (route.redirectTo.startsWith('/')) {
|
|
3035
3149
|
return absoluteRedirect(newTree);
|
|
3036
3150
|
}
|
|
3037
3151
|
return this.lineralizeSegments(route, newTree).pipe(mergeMap((newSegments) => {
|
|
3038
3152
|
const group = new UrlSegmentGroup(newSegments, {});
|
|
3039
|
-
return this.expandSegment(
|
|
3153
|
+
return this.expandSegment(injector, group, routes, newSegments, outlet, false);
|
|
3040
3154
|
}));
|
|
3041
3155
|
}
|
|
3042
|
-
expandRegularSegmentAgainstRouteUsingRedirect(
|
|
3156
|
+
expandRegularSegmentAgainstRouteUsingRedirect(injector, segmentGroup, routes, route, segments, outlet) {
|
|
3043
3157
|
const { matched, consumedSegments, remainingSegments, positionalParamSegments } = match(segmentGroup, route, segments);
|
|
3044
3158
|
if (!matched)
|
|
3045
3159
|
return noMatch(segmentGroup);
|
|
@@ -3048,16 +3162,18 @@ class ApplyRedirects {
|
|
|
3048
3162
|
return absoluteRedirect(newTree);
|
|
3049
3163
|
}
|
|
3050
3164
|
return this.lineralizeSegments(route, newTree).pipe(mergeMap((newSegments) => {
|
|
3051
|
-
return this.expandSegment(
|
|
3165
|
+
return this.expandSegment(injector, segmentGroup, routes, newSegments.concat(remainingSegments), outlet, false);
|
|
3052
3166
|
}));
|
|
3053
3167
|
}
|
|
3054
|
-
matchSegmentAgainstRoute(
|
|
3168
|
+
matchSegmentAgainstRoute(injector, rawSegmentGroup, route, segments, outlet) {
|
|
3055
3169
|
if (route.path === '**') {
|
|
3056
3170
|
if (route.loadChildren) {
|
|
3057
|
-
const loaded$ = route.
|
|
3058
|
-
|
|
3171
|
+
const loaded$ = route._loadedRoutes ?
|
|
3172
|
+
of({ routes: route._loadedRoutes, injector: route._loadedInjector }) :
|
|
3173
|
+
this.configLoader.loadChildren(injector, route);
|
|
3059
3174
|
return loaded$.pipe(map((cfg) => {
|
|
3060
|
-
route.
|
|
3175
|
+
route._loadedRoutes = cfg.routes;
|
|
3176
|
+
route._loadedInjector = cfg.injector;
|
|
3061
3177
|
return new UrlSegmentGroup(segments, {});
|
|
3062
3178
|
}));
|
|
3063
3179
|
}
|
|
@@ -3066,55 +3182,55 @@ class ApplyRedirects {
|
|
|
3066
3182
|
const { matched, consumedSegments, remainingSegments } = match(rawSegmentGroup, route, segments);
|
|
3067
3183
|
if (!matched)
|
|
3068
3184
|
return noMatch(rawSegmentGroup);
|
|
3069
|
-
const childConfig$ = this.getChildConfig(
|
|
3185
|
+
const childConfig$ = this.getChildConfig(injector, route, segments);
|
|
3070
3186
|
return childConfig$.pipe(mergeMap((routerConfig) => {
|
|
3071
|
-
const
|
|
3187
|
+
const childInjector = routerConfig.injector ?? injector;
|
|
3072
3188
|
const childConfig = routerConfig.routes;
|
|
3073
3189
|
const { segmentGroup: splitSegmentGroup, slicedSegments } = split(rawSegmentGroup, consumedSegments, remainingSegments, childConfig);
|
|
3074
3190
|
// See comment on the other call to `split` about why this is necessary.
|
|
3075
3191
|
const segmentGroup = new UrlSegmentGroup(splitSegmentGroup.segments, splitSegmentGroup.children);
|
|
3076
3192
|
if (slicedSegments.length === 0 && segmentGroup.hasChildren()) {
|
|
3077
|
-
const expanded$ = this.expandChildren(
|
|
3193
|
+
const expanded$ = this.expandChildren(childInjector, childConfig, segmentGroup);
|
|
3078
3194
|
return expanded$.pipe(map((children) => new UrlSegmentGroup(consumedSegments, children)));
|
|
3079
3195
|
}
|
|
3080
3196
|
if (childConfig.length === 0 && slicedSegments.length === 0) {
|
|
3081
3197
|
return of(new UrlSegmentGroup(consumedSegments, {}));
|
|
3082
3198
|
}
|
|
3083
3199
|
const matchedOnOutlet = getOutlet(route) === outlet;
|
|
3084
|
-
const expanded$ = this.expandSegment(
|
|
3200
|
+
const expanded$ = this.expandSegment(childInjector, segmentGroup, childConfig, slicedSegments, matchedOnOutlet ? PRIMARY_OUTLET : outlet, true);
|
|
3085
3201
|
return expanded$.pipe(map((cs) => new UrlSegmentGroup(consumedSegments.concat(cs.segments), cs.children)));
|
|
3086
3202
|
}));
|
|
3087
3203
|
}
|
|
3088
|
-
getChildConfig(
|
|
3204
|
+
getChildConfig(injector, route, segments) {
|
|
3089
3205
|
if (route.children) {
|
|
3090
3206
|
// The children belong to the same module
|
|
3091
|
-
return of(
|
|
3207
|
+
return of({ routes: route.children, injector });
|
|
3092
3208
|
}
|
|
3093
3209
|
if (route.loadChildren) {
|
|
3094
3210
|
// lazy children belong to the loaded module
|
|
3095
|
-
if (route.
|
|
3096
|
-
return of(route.
|
|
3211
|
+
if (route._loadedRoutes !== undefined) {
|
|
3212
|
+
return of({ routes: route._loadedRoutes, injector: route._loadedInjector });
|
|
3097
3213
|
}
|
|
3098
|
-
return this.runCanLoadGuards(
|
|
3214
|
+
return this.runCanLoadGuards(injector, route, segments)
|
|
3099
3215
|
.pipe(mergeMap((shouldLoadResult) => {
|
|
3100
3216
|
if (shouldLoadResult) {
|
|
3101
|
-
return this.configLoader.
|
|
3102
|
-
.pipe(
|
|
3103
|
-
route.
|
|
3104
|
-
|
|
3217
|
+
return this.configLoader.loadChildren(injector, route)
|
|
3218
|
+
.pipe(tap((cfg) => {
|
|
3219
|
+
route._loadedRoutes = cfg.routes;
|
|
3220
|
+
route._loadedInjector = cfg.injector;
|
|
3105
3221
|
}));
|
|
3106
3222
|
}
|
|
3107
3223
|
return canLoadFails(route);
|
|
3108
3224
|
}));
|
|
3109
3225
|
}
|
|
3110
|
-
return of(
|
|
3226
|
+
return of({ routes: [], injector });
|
|
3111
3227
|
}
|
|
3112
|
-
runCanLoadGuards(
|
|
3228
|
+
runCanLoadGuards(injector, route, segments) {
|
|
3113
3229
|
const canLoad = route.canLoad;
|
|
3114
3230
|
if (!canLoad || canLoad.length === 0)
|
|
3115
3231
|
return of(true);
|
|
3116
3232
|
const canLoadObservables = canLoad.map((injectionToken) => {
|
|
3117
|
-
const guard =
|
|
3233
|
+
const guard = injector.get(injectionToken);
|
|
3118
3234
|
let guardVal;
|
|
3119
3235
|
if (isCanLoad(guard)) {
|
|
3120
3236
|
guardVal = guard.canLoad(route, segments);
|
|
@@ -3242,8 +3358,8 @@ function squashSegmentGroup(segmentGroup) {
|
|
|
3242
3358
|
* Use of this source code is governed by an MIT-style license that can be
|
|
3243
3359
|
* found in the LICENSE file at https://angular.io/license
|
|
3244
3360
|
*/
|
|
3245
|
-
function applyRedirects(
|
|
3246
|
-
return switchMap(t => applyRedirects$1(
|
|
3361
|
+
function applyRedirects(environmentInjector, configLoader, urlSerializer, config) {
|
|
3362
|
+
return switchMap(t => applyRedirects$1(environmentInjector, configLoader, urlSerializer, t.extractedUrl, config)
|
|
3247
3363
|
.pipe(map(urlAfterRedirects => ({ ...t, urlAfterRedirects }))));
|
|
3248
3364
|
}
|
|
3249
3365
|
|
|
@@ -3277,21 +3393,11 @@ function getCanActivateChild(p) {
|
|
|
3277
3393
|
return null;
|
|
3278
3394
|
return { node: p, guards: canActivateChild };
|
|
3279
3395
|
}
|
|
3280
|
-
function getToken(token, snapshot,
|
|
3281
|
-
const
|
|
3282
|
-
const injector =
|
|
3396
|
+
function getToken(token, snapshot, fallbackInjector) {
|
|
3397
|
+
const routeInjector = getClosestRouteInjector(snapshot);
|
|
3398
|
+
const injector = routeInjector ?? fallbackInjector;
|
|
3283
3399
|
return injector.get(token);
|
|
3284
3400
|
}
|
|
3285
|
-
function getClosestLoadedConfig(snapshot) {
|
|
3286
|
-
if (!snapshot)
|
|
3287
|
-
return null;
|
|
3288
|
-
for (let s = snapshot.parent; s; s = s.parent) {
|
|
3289
|
-
const route = s.routeConfig;
|
|
3290
|
-
if (route && route._loadedConfig)
|
|
3291
|
-
return route._loadedConfig;
|
|
3292
|
-
}
|
|
3293
|
-
return null;
|
|
3294
|
-
}
|
|
3295
3401
|
function getChildRouteGuards(futureNode, currNode, contexts, futurePath, checks = {
|
|
3296
3402
|
canDeactivateChecks: [],
|
|
3297
3403
|
canActivateChecks: []
|
|
@@ -3535,7 +3641,7 @@ function runCanDeactivate(component, currARS, currRSS, futureRSS, moduleInjector
|
|
|
3535
3641
|
* Use of this source code is governed by an MIT-style license that can be
|
|
3536
3642
|
* found in the LICENSE file at https://angular.io/license
|
|
3537
3643
|
*/
|
|
3538
|
-
const NG_DEV_MODE = typeof ngDevMode === 'undefined' || !!ngDevMode;
|
|
3644
|
+
const NG_DEV_MODE$2 = typeof ngDevMode === 'undefined' || !!ngDevMode;
|
|
3539
3645
|
class NoMatch {
|
|
3540
3646
|
}
|
|
3541
3647
|
function newObservableError(e) {
|
|
@@ -3652,11 +3758,11 @@ class Recognizer {
|
|
|
3652
3758
|
if (route.path === '**') {
|
|
3653
3759
|
const params = segments.length > 0 ? last(segments).parameters : {};
|
|
3654
3760
|
const pathIndexShift = getPathIndexShift(rawSegment) + segments.length;
|
|
3655
|
-
snapshot = new ActivatedRouteSnapshot(segments, params, Object.freeze({ ...this.urlTree.queryParams }), this.urlTree.fragment, getData(route), getOutlet(route), route.component, route, getSourceSegmentGroup(rawSegment), pathIndexShift, getResolve(route),
|
|
3761
|
+
snapshot = new ActivatedRouteSnapshot(segments, params, Object.freeze({ ...this.urlTree.queryParams }), this.urlTree.fragment, getData(route), getOutlet(route), route.component ?? route._loadedComponent ?? null, route, getSourceSegmentGroup(rawSegment), pathIndexShift, getResolve(route),
|
|
3656
3762
|
// NG_DEV_MODE is used to prevent the getCorrectedPathIndexShift function from affecting
|
|
3657
3763
|
// production bundle size. This value is intended only to surface a warning to users
|
|
3658
3764
|
// depending on `relativeLinkResolution: 'legacy'` in dev mode.
|
|
3659
|
-
(NG_DEV_MODE ? getCorrectedPathIndexShift(rawSegment) + segments.length :
|
|
3765
|
+
(NG_DEV_MODE$2 ? getCorrectedPathIndexShift(rawSegment) + segments.length :
|
|
3660
3766
|
pathIndexShift));
|
|
3661
3767
|
}
|
|
3662
3768
|
else {
|
|
@@ -3667,7 +3773,7 @@ class Recognizer {
|
|
|
3667
3773
|
consumedSegments = result.consumedSegments;
|
|
3668
3774
|
remainingSegments = result.remainingSegments;
|
|
3669
3775
|
const pathIndexShift = getPathIndexShift(rawSegment) + consumedSegments.length;
|
|
3670
|
-
snapshot = new ActivatedRouteSnapshot(consumedSegments, result.parameters, Object.freeze({ ...this.urlTree.queryParams }), this.urlTree.fragment, getData(route), getOutlet(route), route.component, route, getSourceSegmentGroup(rawSegment), pathIndexShift, getResolve(route), (NG_DEV_MODE ? getCorrectedPathIndexShift(rawSegment) + consumedSegments.length :
|
|
3776
|
+
snapshot = new ActivatedRouteSnapshot(consumedSegments, result.parameters, Object.freeze({ ...this.urlTree.queryParams }), this.urlTree.fragment, getData(route), getOutlet(route), route.component ?? route._loadedComponent ?? null, route, getSourceSegmentGroup(rawSegment), pathIndexShift, getResolve(route), (NG_DEV_MODE$2 ? getCorrectedPathIndexShift(rawSegment) + consumedSegments.length :
|
|
3671
3777
|
pathIndexShift));
|
|
3672
3778
|
}
|
|
3673
3779
|
const childConfig = getChildConfig(route);
|
|
@@ -3716,7 +3822,7 @@ function getChildConfig(route) {
|
|
|
3716
3822
|
return route.children;
|
|
3717
3823
|
}
|
|
3718
3824
|
if (route.loadChildren) {
|
|
3719
|
-
return route.
|
|
3825
|
+
return route._loadedRoutes;
|
|
3720
3826
|
}
|
|
3721
3827
|
return [];
|
|
3722
3828
|
}
|
|
@@ -3860,16 +3966,9 @@ function resolveNode(resolve, futureARS, futureRSS, moduleInjector) {
|
|
|
3860
3966
|
}
|
|
3861
3967
|
const data = {};
|
|
3862
3968
|
return from(keys).pipe(mergeMap(key => getResolver(resolve[key], futureARS, futureRSS, moduleInjector)
|
|
3863
|
-
.pipe(
|
|
3969
|
+
.pipe(first(), tap((value) => {
|
|
3864
3970
|
data[key] = value;
|
|
3865
|
-
}))), takeLast(1),
|
|
3866
|
-
// Ensure all resolvers returned values, otherwise don't emit any "next" and just complete
|
|
3867
|
-
// the chain which will cancel navigation
|
|
3868
|
-
if (getDataKeys(data).length === keys.length) {
|
|
3869
|
-
return of(data);
|
|
3870
|
-
}
|
|
3871
|
-
return EMPTY;
|
|
3872
|
-
}));
|
|
3971
|
+
}))), takeLast(1), mapTo(data), catchError((e) => e instanceof EmptyError ? EMPTY : throwError(e)));
|
|
3873
3972
|
}
|
|
3874
3973
|
function getDataKeys(obj) {
|
|
3875
3974
|
return [...Object.keys(obj), ...Object.getOwnPropertySymbols(obj)];
|
|
@@ -3978,6 +4077,7 @@ class DefaultRouteReuseStrategy extends BaseRouteReuseStrategy {
|
|
|
3978
4077
|
* Use of this source code is governed by an MIT-style license that can be
|
|
3979
4078
|
* found in the LICENSE file at https://angular.io/license
|
|
3980
4079
|
*/
|
|
4080
|
+
const NG_DEV_MODE$1 = typeof ngDevMode === 'undefined' || !!ngDevMode;
|
|
3981
4081
|
/**
|
|
3982
4082
|
* The [DI token](guide/glossary/#di-token) for a router configuration.
|
|
3983
4083
|
*
|
|
@@ -3990,43 +4090,84 @@ class DefaultRouteReuseStrategy extends BaseRouteReuseStrategy {
|
|
|
3990
4090
|
*/
|
|
3991
4091
|
const ROUTES = new InjectionToken('ROUTES');
|
|
3992
4092
|
class RouterConfigLoader {
|
|
3993
|
-
constructor(injector, compiler
|
|
4093
|
+
constructor(injector, compiler) {
|
|
3994
4094
|
this.injector = injector;
|
|
3995
4095
|
this.compiler = compiler;
|
|
3996
|
-
this.
|
|
3997
|
-
this.
|
|
4096
|
+
this.componentLoaders = new WeakMap();
|
|
4097
|
+
this.childrenLoaders = new WeakMap();
|
|
4098
|
+
}
|
|
4099
|
+
loadComponent(route) {
|
|
4100
|
+
if (this.componentLoaders.get(route)) {
|
|
4101
|
+
return this.componentLoaders.get(route);
|
|
4102
|
+
}
|
|
4103
|
+
else if (route._loadedComponent) {
|
|
4104
|
+
return of(route._loadedComponent);
|
|
4105
|
+
}
|
|
4106
|
+
if (this.onLoadStartListener) {
|
|
4107
|
+
this.onLoadStartListener(route);
|
|
4108
|
+
}
|
|
4109
|
+
const loadRunner = wrapIntoObservable(route.loadComponent())
|
|
4110
|
+
.pipe(tap(component => {
|
|
4111
|
+
if (this.onLoadEndListener) {
|
|
4112
|
+
this.onLoadEndListener(route);
|
|
4113
|
+
}
|
|
4114
|
+
NG_DEV_MODE$1 && assertStandalone(route.path ?? '', component);
|
|
4115
|
+
route._loadedComponent = component;
|
|
4116
|
+
}), finalize(() => {
|
|
4117
|
+
this.componentLoaders.delete(route);
|
|
4118
|
+
}));
|
|
4119
|
+
// Use custom ConnectableObservable as share in runners pipe increasing the bundle size too much
|
|
4120
|
+
const loader = new ConnectableObservable(loadRunner, () => new Subject()).pipe(refCount());
|
|
4121
|
+
this.componentLoaders.set(route, loader);
|
|
4122
|
+
return loader;
|
|
3998
4123
|
}
|
|
3999
|
-
|
|
4000
|
-
if (route
|
|
4001
|
-
return route
|
|
4124
|
+
loadChildren(parentInjector, route) {
|
|
4125
|
+
if (this.childrenLoaders.get(route)) {
|
|
4126
|
+
return this.childrenLoaders.get(route);
|
|
4127
|
+
}
|
|
4128
|
+
else if (route._loadedRoutes) {
|
|
4129
|
+
return of({ routes: route._loadedRoutes, injector: route._loadedInjector });
|
|
4002
4130
|
}
|
|
4003
4131
|
if (this.onLoadStartListener) {
|
|
4004
4132
|
this.onLoadStartListener(route);
|
|
4005
4133
|
}
|
|
4006
|
-
const
|
|
4007
|
-
const loadRunner =
|
|
4134
|
+
const moduleFactoryOrRoutes$ = this.loadModuleFactoryOrRoutes(route.loadChildren);
|
|
4135
|
+
const loadRunner = moduleFactoryOrRoutes$.pipe(map((factoryOrRoutes) => {
|
|
4008
4136
|
if (this.onLoadEndListener) {
|
|
4009
4137
|
this.onLoadEndListener(route);
|
|
4010
4138
|
}
|
|
4011
|
-
|
|
4012
|
-
//
|
|
4013
|
-
|
|
4014
|
-
|
|
4015
|
-
|
|
4016
|
-
|
|
4017
|
-
|
|
4018
|
-
|
|
4019
|
-
|
|
4020
|
-
|
|
4139
|
+
// This injector comes from the `NgModuleRef` when lazy loading an `NgModule`. There is no
|
|
4140
|
+
// injector associated with lazy loading a `Route` array.
|
|
4141
|
+
let injector;
|
|
4142
|
+
let rawRoutes;
|
|
4143
|
+
let requireStandaloneComponents = false;
|
|
4144
|
+
if (Array.isArray(factoryOrRoutes)) {
|
|
4145
|
+
rawRoutes = factoryOrRoutes;
|
|
4146
|
+
requireStandaloneComponents = true;
|
|
4147
|
+
}
|
|
4148
|
+
else {
|
|
4149
|
+
injector = factoryOrRoutes.create(parentInjector).injector;
|
|
4150
|
+
// When loading a module that doesn't provide `RouterModule.forChild()` preloader
|
|
4151
|
+
// will get stuck in an infinite loop. The child module's Injector will look to
|
|
4152
|
+
// its parent `Injector` when it doesn't find any ROUTES so it will return routes
|
|
4153
|
+
// for it's parent module instead.
|
|
4154
|
+
rawRoutes = flatten(injector.get(ROUTES, [], InjectFlags.Self | InjectFlags.Optional));
|
|
4155
|
+
}
|
|
4156
|
+
const routes = rawRoutes.map(standardizeConfig);
|
|
4157
|
+
NG_DEV_MODE$1 && validateConfig(routes, route.path, requireStandaloneComponents);
|
|
4158
|
+
return { routes, injector };
|
|
4159
|
+
}), finalize(() => {
|
|
4160
|
+
this.childrenLoaders.delete(route);
|
|
4021
4161
|
}));
|
|
4022
4162
|
// Use custom ConnectableObservable as share in runners pipe increasing the bundle size too much
|
|
4023
|
-
|
|
4163
|
+
const loader = new ConnectableObservable(loadRunner, () => new Subject())
|
|
4024
4164
|
.pipe(refCount());
|
|
4025
|
-
|
|
4165
|
+
this.childrenLoaders.set(route, loader);
|
|
4166
|
+
return loader;
|
|
4026
4167
|
}
|
|
4027
|
-
|
|
4168
|
+
loadModuleFactoryOrRoutes(loadChildren) {
|
|
4028
4169
|
return wrapIntoObservable(loadChildren()).pipe(mergeMap((t) => {
|
|
4029
|
-
if (t instanceof NgModuleFactory) {
|
|
4170
|
+
if (t instanceof NgModuleFactory || Array.isArray(t)) {
|
|
4030
4171
|
return of(t);
|
|
4031
4172
|
}
|
|
4032
4173
|
else {
|
|
@@ -4035,6 +4176,11 @@ class RouterConfigLoader {
|
|
|
4035
4176
|
}));
|
|
4036
4177
|
}
|
|
4037
4178
|
}
|
|
4179
|
+
RouterConfigLoader.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.0-next.16", ngImport: i0, type: RouterConfigLoader, deps: [{ token: i0.Injector }, { token: i0.Compiler }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
4180
|
+
RouterConfigLoader.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.0.0-next.16", ngImport: i0, type: RouterConfigLoader });
|
|
4181
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.0-next.16", ngImport: i0, type: RouterConfigLoader, decorators: [{
|
|
4182
|
+
type: Injectable
|
|
4183
|
+
}], ctorParameters: function () { return [{ type: i0.Injector }, { type: i0.Compiler }]; } });
|
|
4038
4184
|
|
|
4039
4185
|
/**
|
|
4040
4186
|
* @license
|
|
@@ -4074,6 +4220,7 @@ class DefaultUrlHandlingStrategy {
|
|
|
4074
4220
|
* Use of this source code is governed by an MIT-style license that can be
|
|
4075
4221
|
* found in the LICENSE file at https://angular.io/license
|
|
4076
4222
|
*/
|
|
4223
|
+
const NG_DEV_MODE = typeof ngDevMode === 'undefined' || !!ngDevMode;
|
|
4077
4224
|
function defaultErrorHandler(error) {
|
|
4078
4225
|
throw error;
|
|
4079
4226
|
}
|
|
@@ -4245,6 +4392,9 @@ class Router {
|
|
|
4245
4392
|
this.canceledNavigationResolution = 'replace';
|
|
4246
4393
|
const onLoadStart = (r) => this.triggerEvent(new RouteConfigLoadStart(r));
|
|
4247
4394
|
const onLoadEnd = (r) => this.triggerEvent(new RouteConfigLoadEnd(r));
|
|
4395
|
+
this.configLoader = injector.get(RouterConfigLoader);
|
|
4396
|
+
this.configLoader.onLoadEndListener = onLoadEnd;
|
|
4397
|
+
this.configLoader.onLoadStartListener = onLoadStart;
|
|
4248
4398
|
this.ngModule = injector.get(NgModuleRef);
|
|
4249
4399
|
this.console = injector.get(ɵConsole);
|
|
4250
4400
|
const ngZone = injector.get(NgZone);
|
|
@@ -4253,7 +4403,6 @@ class Router {
|
|
|
4253
4403
|
this.currentUrlTree = createEmptyUrlTree();
|
|
4254
4404
|
this.rawUrlTree = this.currentUrlTree;
|
|
4255
4405
|
this.browserUrlTree = this.currentUrlTree;
|
|
4256
|
-
this.configLoader = new RouterConfigLoader(injector, compiler, onLoadStart, onLoadEnd);
|
|
4257
4406
|
this.routerState = createEmptyState(this.currentUrlTree, this.rootComponentType);
|
|
4258
4407
|
this.transitions = new BehaviorSubject({
|
|
4259
4408
|
id: 0,
|
|
@@ -4462,6 +4611,25 @@ class Router {
|
|
|
4462
4611
|
skipLocationChange: !!skipLocationChange,
|
|
4463
4612
|
replaceUrl: !!replaceUrl,
|
|
4464
4613
|
});
|
|
4614
|
+
}),
|
|
4615
|
+
// --- LOAD COMPONENTS ---
|
|
4616
|
+
switchTap((t) => {
|
|
4617
|
+
const loadComponents = (route) => {
|
|
4618
|
+
const loaders = [];
|
|
4619
|
+
if (route.routeConfig?.loadComponent &&
|
|
4620
|
+
!route.routeConfig._loadedComponent) {
|
|
4621
|
+
loaders.push(this.configLoader.loadComponent(route.routeConfig)
|
|
4622
|
+
.pipe(tap(loadedComponent => {
|
|
4623
|
+
route.component = loadedComponent;
|
|
4624
|
+
}), map(() => void 0)));
|
|
4625
|
+
}
|
|
4626
|
+
for (const child of route.children) {
|
|
4627
|
+
loaders.push(...loadComponents(child));
|
|
4628
|
+
}
|
|
4629
|
+
return loaders;
|
|
4630
|
+
};
|
|
4631
|
+
return combineLatest(loadComponents(t.targetSnapshot.root))
|
|
4632
|
+
.pipe(defaultIfEmpty(), take(1));
|
|
4465
4633
|
}), map((t) => {
|
|
4466
4634
|
const targetRouterState = createRouterState(this.routeReuseStrategy, t.targetSnapshot, t.currentRouterState);
|
|
4467
4635
|
return ({ ...t, targetRouterState });
|
|
@@ -4540,23 +4708,17 @@ class Router {
|
|
|
4540
4708
|
t.resolve(false);
|
|
4541
4709
|
}
|
|
4542
4710
|
else {
|
|
4543
|
-
|
|
4544
|
-
|
|
4545
|
-
|
|
4546
|
-
|
|
4547
|
-
|
|
4548
|
-
|
|
4549
|
-
|
|
4550
|
-
|
|
4551
|
-
|
|
4552
|
-
|
|
4553
|
-
|
|
4554
|
-
// the navigation is rejected.
|
|
4555
|
-
replaceUrl: this.urlUpdateStrategy === 'eager' ||
|
|
4556
|
-
isBrowserTriggeredNavigation(t.source)
|
|
4557
|
-
};
|
|
4558
|
-
this.scheduleNavigation(mergedTree, 'imperative', null, extras, { resolve: t.resolve, reject: t.reject, promise: t.promise });
|
|
4559
|
-
}, 0);
|
|
4711
|
+
const mergedTree = this.urlHandlingStrategy.merge(e.url, this.rawUrlTree);
|
|
4712
|
+
const extras = {
|
|
4713
|
+
skipLocationChange: t.extras.skipLocationChange,
|
|
4714
|
+
// The URL is already updated at this point if we have 'eager' URL
|
|
4715
|
+
// updates or if the navigation was triggered by the browser (back
|
|
4716
|
+
// button, URL bar, etc). We want to replace that item in history if
|
|
4717
|
+
// the navigation is rejected.
|
|
4718
|
+
replaceUrl: this.urlUpdateStrategy === 'eager' ||
|
|
4719
|
+
isBrowserTriggeredNavigation(t.source)
|
|
4720
|
+
};
|
|
4721
|
+
this.scheduleNavigation(mergedTree, 'imperative', null, extras, { resolve: t.resolve, reject: t.reject, promise: t.promise });
|
|
4560
4722
|
}
|
|
4561
4723
|
/* All other errors should reset to the router's internal URL reference to
|
|
4562
4724
|
* the pre-error state. */
|
|
@@ -4666,7 +4828,7 @@ class Router {
|
|
|
4666
4828
|
* ```
|
|
4667
4829
|
*/
|
|
4668
4830
|
resetConfig(config) {
|
|
4669
|
-
validateConfig(config);
|
|
4831
|
+
NG_DEV_MODE && validateConfig(config);
|
|
4670
4832
|
this.config = config.map(standardizeConfig);
|
|
4671
4833
|
this.navigated = false;
|
|
4672
4834
|
this.lastSuccessfulId = -1;
|
|
@@ -5021,9 +5183,9 @@ class Router {
|
|
|
5021
5183
|
return { navigationId };
|
|
5022
5184
|
}
|
|
5023
5185
|
}
|
|
5024
|
-
Router.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.0-next.
|
|
5025
|
-
Router.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.0.0-next.
|
|
5026
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.0-next.
|
|
5186
|
+
Router.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.0-next.16", ngImport: i0, type: Router, deps: "invalid", target: i0.ɵɵFactoryTarget.Injectable });
|
|
5187
|
+
Router.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.0.0-next.16", ngImport: i0, type: Router });
|
|
5188
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.0-next.16", ngImport: i0, type: Router, decorators: [{
|
|
5027
5189
|
type: Injectable
|
|
5028
5190
|
}], ctorParameters: function () { return [{ type: i0.Type }, { type: UrlSerializer }, { type: ChildrenOutletContexts }, { type: i3.Location }, { type: i0.Injector }, { type: i0.Compiler }, { type: undefined }]; } });
|
|
5029
5191
|
function validateCommands(commands) {
|
|
@@ -5222,9 +5384,9 @@ class RouterLink {
|
|
|
5222
5384
|
});
|
|
5223
5385
|
}
|
|
5224
5386
|
}
|
|
5225
|
-
RouterLink.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.0-next.
|
|
5226
|
-
RouterLink.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "
|
|
5227
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.0-next.
|
|
5387
|
+
RouterLink.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.0-next.16", ngImport: i0, type: RouterLink, deps: [{ token: Router }, { token: ActivatedRoute }, { token: 'tabindex', attribute: true }, { token: i0.Renderer2 }, { token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Directive });
|
|
5388
|
+
RouterLink.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "14.0.0-next.16", type: RouterLink, selector: ":not(a):not(area)[routerLink]", inputs: { queryParams: "queryParams", fragment: "fragment", queryParamsHandling: "queryParamsHandling", preserveFragment: "preserveFragment", skipLocationChange: "skipLocationChange", replaceUrl: "replaceUrl", state: "state", relativeTo: "relativeTo", routerLink: "routerLink" }, host: { listeners: { "click": "onClick()" } }, usesOnChanges: true, ngImport: i0 });
|
|
5389
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.0-next.16", ngImport: i0, type: RouterLink, decorators: [{
|
|
5228
5390
|
type: Directive,
|
|
5229
5391
|
args: [{ selector: ':not(a):not(area)[routerLink]' }]
|
|
5230
5392
|
}], ctorParameters: function () { return [{ type: Router }, { type: ActivatedRoute }, { type: undefined, decorators: [{
|
|
@@ -5341,9 +5503,9 @@ class RouterLinkWithHref {
|
|
|
5341
5503
|
});
|
|
5342
5504
|
}
|
|
5343
5505
|
}
|
|
5344
|
-
RouterLinkWithHref.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.0-next.
|
|
5345
|
-
RouterLinkWithHref.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "
|
|
5346
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.0-next.
|
|
5506
|
+
RouterLinkWithHref.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.0-next.16", ngImport: i0, type: RouterLinkWithHref, deps: [{ token: Router }, { token: ActivatedRoute }, { token: i3.LocationStrategy }], target: i0.ɵɵFactoryTarget.Directive });
|
|
5507
|
+
RouterLinkWithHref.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "14.0.0-next.16", type: RouterLinkWithHref, selector: "a[routerLink],area[routerLink]", inputs: { target: "target", queryParams: "queryParams", fragment: "fragment", queryParamsHandling: "queryParamsHandling", preserveFragment: "preserveFragment", skipLocationChange: "skipLocationChange", replaceUrl: "replaceUrl", state: "state", relativeTo: "relativeTo", routerLink: "routerLink" }, host: { listeners: { "click": "onClick($event.button,$event.ctrlKey,$event.shiftKey,$event.altKey,$event.metaKey)" }, properties: { "attr.target": "this.target", "attr.href": "this.href" } }, usesOnChanges: true, ngImport: i0 });
|
|
5508
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.0-next.16", ngImport: i0, type: RouterLinkWithHref, decorators: [{
|
|
5347
5509
|
type: Directive,
|
|
5348
5510
|
args: [{ selector: 'a[routerLink],area[routerLink]' }]
|
|
5349
5511
|
}], ctorParameters: function () { return [{ type: Router }, { type: ActivatedRoute }, { type: i3.LocationStrategy }]; }, propDecorators: { target: [{
|
|
@@ -5440,6 +5602,16 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.0-next.13",
|
|
|
5440
5602
|
* </div>
|
|
5441
5603
|
* ```
|
|
5442
5604
|
*
|
|
5605
|
+
* The `RouterLinkActive` directive can also be used to set the aria-current attribute
|
|
5606
|
+
* to provide an alternative distinction for active elements to visually impaired users.
|
|
5607
|
+
*
|
|
5608
|
+
* For example, the following code adds the 'active' class to the Home Page link when it is
|
|
5609
|
+
* indeed active and in such case also sets its aria-current attribute to 'page':
|
|
5610
|
+
*
|
|
5611
|
+
* ```
|
|
5612
|
+
* <a routerLink="/" routerLinkActive="active" ariaCurrentWhenActive="page">Home Page</a>
|
|
5613
|
+
* ```
|
|
5614
|
+
*
|
|
5443
5615
|
* @ngModule RouterModule
|
|
5444
5616
|
*
|
|
5445
5617
|
* @publicApi
|
|
@@ -5533,6 +5705,12 @@ class RouterLinkActive {
|
|
|
5533
5705
|
this.renderer.removeClass(this.element.nativeElement, c);
|
|
5534
5706
|
}
|
|
5535
5707
|
});
|
|
5708
|
+
if (hasActiveLinks && this.ariaCurrentWhenActive !== undefined) {
|
|
5709
|
+
this.renderer.setAttribute(this.element.nativeElement, 'aria-current', this.ariaCurrentWhenActive.toString());
|
|
5710
|
+
}
|
|
5711
|
+
else {
|
|
5712
|
+
this.renderer.removeAttribute(this.element.nativeElement, 'aria-current');
|
|
5713
|
+
}
|
|
5536
5714
|
// Emit on isActiveChange after classes are updated
|
|
5537
5715
|
this.isActiveChange.emit(hasActiveLinks);
|
|
5538
5716
|
}
|
|
@@ -5552,9 +5730,9 @@ class RouterLinkActive {
|
|
|
5552
5730
|
this.links.some(isActiveCheckFn) || this.linksWithHrefs.some(isActiveCheckFn);
|
|
5553
5731
|
}
|
|
5554
5732
|
}
|
|
5555
|
-
RouterLinkActive.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.0-next.
|
|
5556
|
-
RouterLinkActive.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "
|
|
5557
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.0-next.
|
|
5733
|
+
RouterLinkActive.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.0-next.16", ngImport: i0, type: RouterLinkActive, deps: [{ token: Router }, { token: i0.ElementRef }, { token: i0.Renderer2 }, { token: i0.ChangeDetectorRef }, { token: RouterLink, optional: true }, { token: RouterLinkWithHref, optional: true }], target: i0.ɵɵFactoryTarget.Directive });
|
|
5734
|
+
RouterLinkActive.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "14.0.0-next.16", type: RouterLinkActive, selector: "[routerLinkActive]", inputs: { routerLinkActiveOptions: "routerLinkActiveOptions", ariaCurrentWhenActive: "ariaCurrentWhenActive", routerLinkActive: "routerLinkActive" }, outputs: { isActiveChange: "isActiveChange" }, queries: [{ propertyName: "links", predicate: RouterLink, descendants: true }, { propertyName: "linksWithHrefs", predicate: RouterLinkWithHref, descendants: true }], exportAs: ["routerLinkActive"], usesOnChanges: true, ngImport: i0 });
|
|
5735
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.0-next.16", ngImport: i0, type: RouterLinkActive, decorators: [{
|
|
5558
5736
|
type: Directive,
|
|
5559
5737
|
args: [{
|
|
5560
5738
|
selector: '[routerLinkActive]',
|
|
@@ -5572,6 +5750,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.0-next.13",
|
|
|
5572
5750
|
args: [RouterLinkWithHref, { descendants: true }]
|
|
5573
5751
|
}], routerLinkActiveOptions: [{
|
|
5574
5752
|
type: Input
|
|
5753
|
+
}], ariaCurrentWhenActive: [{
|
|
5754
|
+
type: Input
|
|
5575
5755
|
}], isActiveChange: [{
|
|
5576
5756
|
type: Output
|
|
5577
5757
|
}], routerLinkActive: [{
|
|
@@ -5655,9 +5835,9 @@ class DefaultTitleStrategy extends TitleStrategy {
|
|
|
5655
5835
|
}
|
|
5656
5836
|
}
|
|
5657
5837
|
}
|
|
5658
|
-
DefaultTitleStrategy.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.0-next.
|
|
5659
|
-
DefaultTitleStrategy.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.0.0-next.
|
|
5660
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.0-next.
|
|
5838
|
+
DefaultTitleStrategy.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.0-next.16", ngImport: i0, type: DefaultTitleStrategy, deps: [{ token: i1.Title }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
5839
|
+
DefaultTitleStrategy.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.0.0-next.16", ngImport: i0, type: DefaultTitleStrategy, providedIn: 'root' });
|
|
5840
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.0-next.16", ngImport: i0, type: DefaultTitleStrategy, decorators: [{
|
|
5661
5841
|
type: Injectable,
|
|
5662
5842
|
args: [{ providedIn: 'root' }]
|
|
5663
5843
|
}], ctorParameters: function () { return [{ type: i1.Title }]; } });
|
|
@@ -5721,13 +5901,11 @@ class NoPreloading {
|
|
|
5721
5901
|
* @publicApi
|
|
5722
5902
|
*/
|
|
5723
5903
|
class RouterPreloader {
|
|
5724
|
-
constructor(router, compiler, injector, preloadingStrategy) {
|
|
5904
|
+
constructor(router, compiler, injector, preloadingStrategy, loader) {
|
|
5725
5905
|
this.router = router;
|
|
5726
5906
|
this.injector = injector;
|
|
5727
5907
|
this.preloadingStrategy = preloadingStrategy;
|
|
5728
|
-
|
|
5729
|
-
const onEndLoad = (r) => router.triggerEvent(new RouteConfigLoadEnd(r));
|
|
5730
|
-
this.loader = new RouterConfigLoader(injector, compiler, onStartLoad, onEndLoad);
|
|
5908
|
+
this.loader = loader;
|
|
5731
5909
|
}
|
|
5732
5910
|
setUpPreloading() {
|
|
5733
5911
|
this.subscription =
|
|
@@ -5736,8 +5914,7 @@ class RouterPreloader {
|
|
|
5736
5914
|
.subscribe(() => { });
|
|
5737
5915
|
}
|
|
5738
5916
|
preload() {
|
|
5739
|
-
|
|
5740
|
-
return this.processRoutes(ngModule, this.router.config);
|
|
5917
|
+
return this.processRoutes(this.injector, this.router.config);
|
|
5741
5918
|
}
|
|
5742
5919
|
/** @nodoc */
|
|
5743
5920
|
ngOnDestroy() {
|
|
@@ -5745,41 +5922,59 @@ class RouterPreloader {
|
|
|
5745
5922
|
this.subscription.unsubscribe();
|
|
5746
5923
|
}
|
|
5747
5924
|
}
|
|
5748
|
-
processRoutes(
|
|
5925
|
+
processRoutes(injector, routes) {
|
|
5749
5926
|
const res = [];
|
|
5750
5927
|
for (const route of routes) {
|
|
5751
|
-
|
|
5752
|
-
|
|
5753
|
-
|
|
5754
|
-
res.push(this.processRoutes(childConfig.module, childConfig.routes));
|
|
5755
|
-
// no config loaded, fetch the config
|
|
5928
|
+
if (route.providers && !route._injector) {
|
|
5929
|
+
route._injector =
|
|
5930
|
+
createEnvironmentInjector(route.providers, injector, `Route: ${route.path}`);
|
|
5756
5931
|
}
|
|
5757
|
-
|
|
5758
|
-
|
|
5759
|
-
|
|
5932
|
+
const injectorForCurrentRoute = route._injector ?? injector;
|
|
5933
|
+
const injectorForChildren = route._loadedInjector ?? injectorForCurrentRoute;
|
|
5934
|
+
if ((route.loadChildren && !route._loadedRoutes) ||
|
|
5935
|
+
(route.loadComponent && !route._loadedComponent)) {
|
|
5936
|
+
res.push(this.preloadConfig(injectorForCurrentRoute, route));
|
|
5760
5937
|
}
|
|
5761
|
-
else if (route.children) {
|
|
5762
|
-
res.push(this.processRoutes(
|
|
5938
|
+
else if (route.children || route._loadedRoutes) {
|
|
5939
|
+
res.push(this.processRoutes(injectorForChildren, (route.children ?? route._loadedRoutes)));
|
|
5763
5940
|
}
|
|
5764
5941
|
}
|
|
5765
|
-
return from(res).pipe(mergeAll()
|
|
5942
|
+
return from(res).pipe(mergeAll());
|
|
5766
5943
|
}
|
|
5767
|
-
preloadConfig(
|
|
5944
|
+
preloadConfig(injector, route) {
|
|
5768
5945
|
return this.preloadingStrategy.preload(route, () => {
|
|
5769
|
-
|
|
5770
|
-
|
|
5771
|
-
|
|
5772
|
-
|
|
5773
|
-
|
|
5946
|
+
let loadedChildren$;
|
|
5947
|
+
if (route.loadChildren && route.canLoad === undefined) {
|
|
5948
|
+
loadedChildren$ = this.loader.loadChildren(injector, route);
|
|
5949
|
+
}
|
|
5950
|
+
else {
|
|
5951
|
+
loadedChildren$ = of(null);
|
|
5952
|
+
}
|
|
5953
|
+
const recursiveLoadChildren$ = loadedChildren$.pipe(mergeMap((config) => {
|
|
5954
|
+
if (config === null) {
|
|
5955
|
+
return of(void 0);
|
|
5956
|
+
}
|
|
5957
|
+
route._loadedRoutes = config.routes;
|
|
5958
|
+
route._loadedInjector = config.injector;
|
|
5959
|
+
// If the loaded config was a module, use that as the module/module injector going
|
|
5960
|
+
// forward. Otherwise, continue using the current module/module injector.
|
|
5961
|
+
return this.processRoutes(config.injector ?? injector, config.routes);
|
|
5774
5962
|
}));
|
|
5963
|
+
if (route.loadComponent && !route._loadedComponent) {
|
|
5964
|
+
const loadComponent$ = this.loader.loadComponent(route);
|
|
5965
|
+
return from([recursiveLoadChildren$, loadComponent$]).pipe(mergeAll());
|
|
5966
|
+
}
|
|
5967
|
+
else {
|
|
5968
|
+
return recursiveLoadChildren$;
|
|
5969
|
+
}
|
|
5775
5970
|
});
|
|
5776
5971
|
}
|
|
5777
5972
|
}
|
|
5778
|
-
RouterPreloader.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.0-next.
|
|
5779
|
-
RouterPreloader.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.0.0-next.
|
|
5780
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.0-next.
|
|
5973
|
+
RouterPreloader.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.0-next.16", ngImport: i0, type: RouterPreloader, deps: [{ token: Router }, { token: i0.Compiler }, { token: i0.EnvironmentInjector }, { token: PreloadingStrategy }, { token: RouterConfigLoader }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
5974
|
+
RouterPreloader.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.0.0-next.16", ngImport: i0, type: RouterPreloader });
|
|
5975
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.0-next.16", ngImport: i0, type: RouterPreloader, decorators: [{
|
|
5781
5976
|
type: Injectable
|
|
5782
|
-
}], ctorParameters: function () { return [{ type: Router }, { type: i0.Compiler }, { type: i0.
|
|
5977
|
+
}], ctorParameters: function () { return [{ type: Router }, { type: i0.Compiler }, { type: i0.EnvironmentInjector }, { type: PreloadingStrategy }, { type: RouterConfigLoader }]; } });
|
|
5783
5978
|
|
|
5784
5979
|
/**
|
|
5785
5980
|
* @license
|
|
@@ -5863,9 +6058,9 @@ class RouterScroller {
|
|
|
5863
6058
|
}
|
|
5864
6059
|
}
|
|
5865
6060
|
}
|
|
5866
|
-
RouterScroller.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.0-next.
|
|
5867
|
-
RouterScroller.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.0.0-next.
|
|
5868
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.0-next.
|
|
6061
|
+
RouterScroller.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.0-next.16", ngImport: i0, type: RouterScroller, deps: "invalid", target: i0.ɵɵFactoryTarget.Injectable });
|
|
6062
|
+
RouterScroller.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.0.0-next.16", ngImport: i0, type: RouterScroller });
|
|
6063
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.0-next.16", ngImport: i0, type: RouterScroller, decorators: [{
|
|
5869
6064
|
type: Injectable
|
|
5870
6065
|
}], ctorParameters: function () { return [{ type: Router }, { type: i3.ViewportScroller }, { type: undefined }]; } });
|
|
5871
6066
|
|
|
@@ -5908,6 +6103,7 @@ const ROUTER_PROVIDERS = [
|
|
|
5908
6103
|
NoPreloading,
|
|
5909
6104
|
PreloadAllModules,
|
|
5910
6105
|
{ provide: ROUTER_CONFIGURATION, useValue: { enableTracing: false } },
|
|
6106
|
+
RouterConfigLoader,
|
|
5911
6107
|
];
|
|
5912
6108
|
function routerNgProbeToken() {
|
|
5913
6109
|
return new NgProbeToken('Router', Router);
|
|
@@ -6006,10 +6202,10 @@ class RouterModule {
|
|
|
6006
6202
|
return { ngModule: RouterModule, providers: [provideRoutes(routes)] };
|
|
6007
6203
|
}
|
|
6008
6204
|
}
|
|
6009
|
-
RouterModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.0-next.
|
|
6010
|
-
RouterModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "
|
|
6011
|
-
RouterModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "14.0.0-next.
|
|
6012
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.0-next.
|
|
6205
|
+
RouterModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.0-next.16", ngImport: i0, type: RouterModule, deps: [{ token: ROUTER_FORROOT_GUARD, optional: true }, { token: Router, optional: true }], target: i0.ɵɵFactoryTarget.NgModule });
|
|
6206
|
+
RouterModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "14.0.0-next.16", ngImport: i0, type: RouterModule, declarations: [RouterOutlet, RouterLink, RouterLinkWithHref, RouterLinkActive, ɵEmptyOutletComponent], exports: [RouterOutlet, RouterLink, RouterLinkWithHref, RouterLinkActive, ɵEmptyOutletComponent] });
|
|
6207
|
+
RouterModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "14.0.0-next.16", ngImport: i0, type: RouterModule });
|
|
6208
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.0-next.16", ngImport: i0, type: RouterModule, decorators: [{
|
|
6013
6209
|
type: NgModule,
|
|
6014
6210
|
args: [{
|
|
6015
6211
|
declarations: ROUTER_DIRECTIVES,
|
|
@@ -6071,11 +6267,11 @@ function setupRouter(urlSerializer, contexts, location, injector, compiler, conf
|
|
|
6071
6267
|
}
|
|
6072
6268
|
router.titleStrategy = titleStrategy ?? defaultTitleStrategy;
|
|
6073
6269
|
assignExtraOptionsToRouter(opts, router);
|
|
6074
|
-
if (opts.enableTracing) {
|
|
6270
|
+
if ((typeof ngDevMode === 'undefined' || ngDevMode) && opts.enableTracing) {
|
|
6075
6271
|
router.events.subscribe((e) => {
|
|
6076
6272
|
// tslint:disable:no-console
|
|
6077
6273
|
console.group?.(`Router Event: ${e.constructor.name}`);
|
|
6078
|
-
console.log(e
|
|
6274
|
+
console.log(stringifyEvent(e));
|
|
6079
6275
|
console.log(e);
|
|
6080
6276
|
console.groupEnd?.();
|
|
6081
6277
|
// tslint:enable:no-console
|
|
@@ -6142,9 +6338,7 @@ class RouterInitializer {
|
|
|
6142
6338
|
router.setUpLocationChangeListener();
|
|
6143
6339
|
resolve(true);
|
|
6144
6340
|
}
|
|
6145
|
-
else if (
|
|
6146
|
-
// TODO: enabled is deprecated as of v11, can be removed in v13
|
|
6147
|
-
opts.initialNavigation === 'enabled' || opts.initialNavigation === 'enabledBlocking') {
|
|
6341
|
+
else if (opts.initialNavigation === 'enabledBlocking') {
|
|
6148
6342
|
router.hooks.afterPreactivation = () => {
|
|
6149
6343
|
// only the initial navigation should be delayed
|
|
6150
6344
|
if (!this.initNavigation) {
|
|
@@ -6188,9 +6382,9 @@ class RouterInitializer {
|
|
|
6188
6382
|
this.destroyed = true;
|
|
6189
6383
|
}
|
|
6190
6384
|
}
|
|
6191
|
-
RouterInitializer.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.0-next.
|
|
6192
|
-
RouterInitializer.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.0.0-next.
|
|
6193
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.0-next.
|
|
6385
|
+
RouterInitializer.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.0-next.16", ngImport: i0, type: RouterInitializer, deps: [{ token: i0.Injector }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
6386
|
+
RouterInitializer.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.0.0-next.16", ngImport: i0, type: RouterInitializer });
|
|
6387
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.0-next.16", ngImport: i0, type: RouterInitializer, decorators: [{
|
|
6194
6388
|
type: Injectable
|
|
6195
6389
|
}], ctorParameters: function () { return [{ type: i0.Injector }]; } });
|
|
6196
6390
|
function getAppInitializer(r) {
|
|
@@ -6230,7 +6424,7 @@ function provideRouterInitializer() {
|
|
|
6230
6424
|
/**
|
|
6231
6425
|
* @publicApi
|
|
6232
6426
|
*/
|
|
6233
|
-
const VERSION = new Version('14.0.0-next.
|
|
6427
|
+
const VERSION = new Version('14.0.0-next.16');
|
|
6234
6428
|
|
|
6235
6429
|
/**
|
|
6236
6430
|
* @license
|