@angular/router 14.0.0-next.9 → 14.0.0-rc.0
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/create_url_tree.mjs +25 -11
- 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 +14 -24
- package/esm2020/src/page_title_strategy.mjs +3 -3
- package/esm2020/src/recognize.mjs +24 -6
- package/esm2020/src/router.mjs +43 -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 +4 -4
- package/esm2020/src/url_tree.mjs +1 -1
- package/esm2020/src/utils/config.mjs +71 -11
- package/esm2020/src/utils/config_matching.mjs +4 -1
- 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 +917 -670
- package/fesm2015/router.mjs.map +1 -1
- package/fesm2015/testing.mjs +5 -5
- package/fesm2015/upgrade.mjs +1 -1
- package/fesm2020/router.mjs +902 -673
- 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 -3730
- package/package.json +9 -9
- 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/fesm2015/router.mjs
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @license Angular v14.0.0-
|
|
2
|
+
* @license Angular v14.0.0-rc.0
|
|
3
3
|
* (c) 2010-2022 Google LLC. https://angular.io/
|
|
4
4
|
* License: MIT
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
import * as i0 from '@angular/core';
|
|
8
|
-
import { ɵisObservable, ɵisPromise, EventEmitter, Directive, Attribute, Output, Component,
|
|
8
|
+
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';
|
|
9
9
|
import { from, of, BehaviorSubject, combineLatest, throwError, EmptyError, concat, defer, Observable, EMPTY, ConnectableObservable, Subject } from 'rxjs';
|
|
10
|
-
import { map, switchMap, take, startWith, scan, filter, catchError, concatMap, last as last$1, first, mergeMap, tap, takeLast,
|
|
10
|
+
import { map, switchMap, take, startWith, scan, filter, catchError, concatMap, last as last$1, first, mergeMap, tap, takeLast, mapTo, finalize, refCount, defaultIfEmpty, mergeAll } from 'rxjs/operators';
|
|
11
11
|
import * as i3 from '@angular/common';
|
|
12
12
|
import { Location, LocationStrategy, PlatformLocation, APP_BASE_HREF, ViewportScroller, HashLocationStrategy, PathLocationStrategy, LOCATION_INITIALIZED } from '@angular/common';
|
|
13
13
|
import * as i1 from '@angular/platform-browser';
|
|
@@ -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,54 @@ 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
|
+
var _a, _b, _c, _d;
|
|
435
|
+
if (!('type' in routerEvent)) {
|
|
436
|
+
return `Unknown Router Event: ${routerEvent.constructor.name}`;
|
|
437
|
+
}
|
|
438
|
+
switch (routerEvent.type) {
|
|
439
|
+
case 14 /* EventType.ActivationEnd */:
|
|
440
|
+
return `ActivationEnd(path: '${((_a = routerEvent.snapshot.routeConfig) === null || _a === void 0 ? void 0 : _a.path) || ''}')`;
|
|
441
|
+
case 13 /* EventType.ActivationStart */:
|
|
442
|
+
return `ActivationStart(path: '${((_b = routerEvent.snapshot.routeConfig) === null || _b === void 0 ? void 0 : _b.path) || ''}')`;
|
|
443
|
+
case 12 /* EventType.ChildActivationEnd */:
|
|
444
|
+
return `ChildActivationEnd(path: '${((_c = routerEvent.snapshot.routeConfig) === null || _c === void 0 ? void 0 : _c.path) || ''}')`;
|
|
445
|
+
case 11 /* EventType.ChildActivationStart */:
|
|
446
|
+
return `ChildActivationStart(path: '${((_d = routerEvent.snapshot.routeConfig) === null || _d === void 0 ? void 0 : _d.path) || ''}')`;
|
|
447
|
+
case 8 /* EventType.GuardsCheckEnd */:
|
|
448
|
+
return `GuardsCheckEnd(id: ${routerEvent.id}, url: '${routerEvent.url}', urlAfterRedirects: '${routerEvent.urlAfterRedirects}', state: ${routerEvent.state}, shouldActivate: ${routerEvent.shouldActivate})`;
|
|
449
|
+
case 7 /* EventType.GuardsCheckStart */:
|
|
450
|
+
return `GuardsCheckStart(id: ${routerEvent.id}, url: '${routerEvent.url}', urlAfterRedirects: '${routerEvent.urlAfterRedirects}', state: ${routerEvent.state})`;
|
|
451
|
+
case 2 /* EventType.NavigationCancel */:
|
|
452
|
+
return `NavigationCancel(id: ${routerEvent.id}, url: '${routerEvent.url}')`;
|
|
453
|
+
case 1 /* EventType.NavigationEnd */:
|
|
454
|
+
return `NavigationEnd(id: ${routerEvent.id}, url: '${routerEvent.url}', urlAfterRedirects: '${routerEvent.urlAfterRedirects}')`;
|
|
455
|
+
case 3 /* EventType.NavigationError */:
|
|
456
|
+
return `NavigationError(id: ${routerEvent.id}, url: '${routerEvent.url}', error: ${routerEvent.error})`;
|
|
457
|
+
case 0 /* EventType.NavigationStart */:
|
|
458
|
+
return `NavigationStart(id: ${routerEvent.id}, url: '${routerEvent.url}')`;
|
|
459
|
+
case 6 /* EventType.ResolveEnd */:
|
|
460
|
+
return `ResolveEnd(id: ${routerEvent.id}, url: '${routerEvent.url}', urlAfterRedirects: '${routerEvent.urlAfterRedirects}', state: ${routerEvent.state})`;
|
|
461
|
+
case 5 /* EventType.ResolveStart */:
|
|
462
|
+
return `ResolveStart(id: ${routerEvent.id}, url: '${routerEvent.url}', urlAfterRedirects: '${routerEvent.urlAfterRedirects}', state: ${routerEvent.state})`;
|
|
463
|
+
case 10 /* EventType.RouteConfigLoadEnd */:
|
|
464
|
+
return `RouteConfigLoadEnd(path: ${routerEvent.route.path})`;
|
|
465
|
+
case 9 /* EventType.RouteConfigLoadStart */:
|
|
466
|
+
return `RouteConfigLoadStart(path: ${routerEvent.route.path})`;
|
|
467
|
+
case 4 /* EventType.RoutesRecognized */:
|
|
468
|
+
return `RoutesRecognized(id: ${routerEvent.id}, url: '${routerEvent.url}', urlAfterRedirects: '${routerEvent.urlAfterRedirects}', state: ${routerEvent.state})`;
|
|
469
|
+
case 15 /* EventType.Scroll */:
|
|
470
|
+
const pos = routerEvent.position ? `${routerEvent.position[0]}, ${routerEvent.position[1]}` : null;
|
|
471
|
+
return `Scroll(anchor: '${routerEvent.anchor}', position: '${pos}')`;
|
|
472
|
+
}
|
|
473
|
+
}
|
|
417
474
|
|
|
418
475
|
/**
|
|
419
476
|
* @license
|
|
@@ -1362,7 +1419,6 @@ class ActivatedRoute {
|
|
|
1362
1419
|
/** The outlet name of the route, a constant. */
|
|
1363
1420
|
outlet,
|
|
1364
1421
|
/** The component of the route, a constant. */
|
|
1365
|
-
// TODO(vsavkin): remove |string
|
|
1366
1422
|
component, futureSnapshot) {
|
|
1367
1423
|
this.url = url;
|
|
1368
1424
|
this.params = params;
|
|
@@ -1454,9 +1510,10 @@ function inheritedParamsDataResolve(route, paramsInheritanceStrategy = 'emptyOnl
|
|
|
1454
1510
|
/** @internal */
|
|
1455
1511
|
function flattenInherited(pathFromRoot) {
|
|
1456
1512
|
return pathFromRoot.reduce((res, curr) => {
|
|
1513
|
+
var _a;
|
|
1457
1514
|
const params = Object.assign(Object.assign({}, res.params), curr.params);
|
|
1458
1515
|
const data = Object.assign(Object.assign({}, res.data), curr.data);
|
|
1459
|
-
const resolve = Object.assign(Object.assign({}, res.resolve), curr._resolvedData);
|
|
1516
|
+
const resolve = Object.assign(Object.assign(Object.assign(Object.assign({}, curr.data), res.resolve), (_a = curr.routeConfig) === null || _a === void 0 ? void 0 : _a.data), curr._resolvedData);
|
|
1460
1517
|
return { params, data, resolve };
|
|
1461
1518
|
}, { params: {}, data: {}, resolve: {} });
|
|
1462
1519
|
}
|
|
@@ -1517,7 +1574,7 @@ class ActivatedRouteSnapshot {
|
|
|
1517
1574
|
/** The outlet name of the route */
|
|
1518
1575
|
outlet,
|
|
1519
1576
|
/** The component of the route */
|
|
1520
|
-
component, routeConfig, urlSegment, lastPathIndex, resolve) {
|
|
1577
|
+
component, routeConfig, urlSegment, lastPathIndex, resolve, correctedLastPathIndex) {
|
|
1521
1578
|
this.url = url;
|
|
1522
1579
|
this.params = params;
|
|
1523
1580
|
this.queryParams = queryParams;
|
|
@@ -1528,6 +1585,7 @@ class ActivatedRouteSnapshot {
|
|
|
1528
1585
|
this.routeConfig = routeConfig;
|
|
1529
1586
|
this._urlSegment = urlSegment;
|
|
1530
1587
|
this._lastPathIndex = lastPathIndex;
|
|
1588
|
+
this._correctedLastPathIndex = correctedLastPathIndex !== null && correctedLastPathIndex !== void 0 ? correctedLastPathIndex : lastPathIndex;
|
|
1531
1589
|
this._resolve = resolve;
|
|
1532
1590
|
}
|
|
1533
1591
|
/** The root of the router state */
|
|
@@ -1712,6 +1770,7 @@ function createActivatedRoute(c) {
|
|
|
1712
1770
|
* found in the LICENSE file at https://angular.io/license
|
|
1713
1771
|
*/
|
|
1714
1772
|
function createUrlTree(route, urlTree, commands, queryParams, fragment) {
|
|
1773
|
+
var _a, _b;
|
|
1715
1774
|
if (commands.length === 0) {
|
|
1716
1775
|
return tree(urlTree.root, urlTree.root, urlTree.root, queryParams, fragment);
|
|
1717
1776
|
}
|
|
@@ -1719,11 +1778,27 @@ function createUrlTree(route, urlTree, commands, queryParams, fragment) {
|
|
|
1719
1778
|
if (nav.toRoot()) {
|
|
1720
1779
|
return tree(urlTree.root, urlTree.root, new UrlSegmentGroup([], {}), queryParams, fragment);
|
|
1721
1780
|
}
|
|
1722
|
-
|
|
1723
|
-
|
|
1724
|
-
|
|
1725
|
-
|
|
1726
|
-
|
|
1781
|
+
function createTreeUsingPathIndex(lastPathIndex) {
|
|
1782
|
+
var _a;
|
|
1783
|
+
const startingPosition = findStartingPosition(nav, urlTree, (_a = route.snapshot) === null || _a === void 0 ? void 0 : _a._urlSegment, lastPathIndex);
|
|
1784
|
+
const segmentGroup = startingPosition.processChildren ?
|
|
1785
|
+
updateSegmentGroupChildren(startingPosition.segmentGroup, startingPosition.index, nav.commands) :
|
|
1786
|
+
updateSegmentGroup(startingPosition.segmentGroup, startingPosition.index, nav.commands);
|
|
1787
|
+
return tree(urlTree.root, startingPosition.segmentGroup, segmentGroup, queryParams, fragment);
|
|
1788
|
+
}
|
|
1789
|
+
// Note: The types should disallow `snapshot` from being `undefined` but due to test mocks, this
|
|
1790
|
+
// may be the case. Since we try to access it at an earlier point before the refactor to add the
|
|
1791
|
+
// warning for `relativeLinkResolution: 'legacy'`, this may cause failures in tests where it
|
|
1792
|
+
// didn't before.
|
|
1793
|
+
const result = createTreeUsingPathIndex((_a = route.snapshot) === null || _a === void 0 ? void 0 : _a._lastPathIndex);
|
|
1794
|
+
// Check if application is relying on `relativeLinkResolution: 'legacy'`
|
|
1795
|
+
if (typeof ngDevMode === 'undefined' || !!ngDevMode) {
|
|
1796
|
+
const correctedResult = createTreeUsingPathIndex((_b = route.snapshot) === null || _b === void 0 ? void 0 : _b._correctedLastPathIndex);
|
|
1797
|
+
if (correctedResult.toString() !== result.toString()) {
|
|
1798
|
+
console.warn(`relativeLinkResolution: 'legacy' is deprecated and will be removed in a future version of Angular. The link to ${result.toString()} will change to ${correctedResult.toString()} if the code is not updated before then.`);
|
|
1799
|
+
}
|
|
1800
|
+
}
|
|
1801
|
+
return result;
|
|
1727
1802
|
}
|
|
1728
1803
|
function isMatrixParams(command) {
|
|
1729
1804
|
return typeof command === 'object' && command != null && !command.outlets && !command.segmentPath;
|
|
@@ -1828,12 +1903,11 @@ class Position {
|
|
|
1828
1903
|
this.index = index;
|
|
1829
1904
|
}
|
|
1830
1905
|
}
|
|
1831
|
-
function findStartingPosition(nav, tree,
|
|
1906
|
+
function findStartingPosition(nav, tree, segmentGroup, lastPathIndex) {
|
|
1832
1907
|
if (nav.isAbsolute) {
|
|
1833
1908
|
return new Position(tree.root, true, 0);
|
|
1834
1909
|
}
|
|
1835
|
-
if (
|
|
1836
|
-
const segmentGroup = route.snapshot._urlSegment;
|
|
1910
|
+
if (lastPathIndex === -1) {
|
|
1837
1911
|
// Pathless ActivatedRoute has _lastPathIndex === -1 but should not process children
|
|
1838
1912
|
// see issue #26224, #13011, #35687
|
|
1839
1913
|
// However, if the ActivatedRoute is the root we should process children like above.
|
|
@@ -1841,8 +1915,8 @@ function findStartingPosition(nav, tree, route) {
|
|
|
1841
1915
|
return new Position(segmentGroup, processChildren, 0);
|
|
1842
1916
|
}
|
|
1843
1917
|
const modifier = isMatrixParams(nav.commands[0]) ? 0 : 1;
|
|
1844
|
-
const index =
|
|
1845
|
-
return createPositionApplyingDoubleDots(
|
|
1918
|
+
const index = lastPathIndex + modifier;
|
|
1919
|
+
return createPositionApplyingDoubleDots(segmentGroup, index, nav.numberOfDoubleDots);
|
|
1846
1920
|
}
|
|
1847
1921
|
function createPositionApplyingDoubleDots(group, index, numberOfDoubleDots) {
|
|
1848
1922
|
let g = group;
|
|
@@ -2005,181 +2079,76 @@ function compare(path, params, segment) {
|
|
|
2005
2079
|
* Use of this source code is governed by an MIT-style license that can be
|
|
2006
2080
|
* found in the LICENSE file at https://angular.io/license
|
|
2007
2081
|
*/
|
|
2008
|
-
|
|
2009
|
-
|
|
2010
|
-
|
|
2011
|
-
|
|
2012
|
-
|
|
2013
|
-
class
|
|
2014
|
-
constructor(
|
|
2015
|
-
this.
|
|
2016
|
-
this.
|
|
2017
|
-
|
|
2018
|
-
|
|
2019
|
-
|
|
2020
|
-
|
|
2021
|
-
|
|
2022
|
-
|
|
2023
|
-
this.
|
|
2024
|
-
|
|
2025
|
-
this.activateChildRoutes(futureRoot, currRoot, parentContexts);
|
|
2026
|
-
}
|
|
2027
|
-
// De-activate the child route that are not re-used for the future state
|
|
2028
|
-
deactivateChildRoutes(futureNode, currNode, contexts) {
|
|
2029
|
-
const children = nodeChildrenAsMap(currNode);
|
|
2030
|
-
// Recurse on the routes active in the future state to de-activate deeper children
|
|
2031
|
-
futureNode.children.forEach(futureChild => {
|
|
2032
|
-
const childOutletName = futureChild.value.outlet;
|
|
2033
|
-
this.deactivateRoutes(futureChild, children[childOutletName], contexts);
|
|
2034
|
-
delete children[childOutletName];
|
|
2035
|
-
});
|
|
2036
|
-
// De-activate the routes that will not be re-used
|
|
2037
|
-
forEach(children, (v, childName) => {
|
|
2038
|
-
this.deactivateRouteAndItsChildren(v, contexts);
|
|
2039
|
-
});
|
|
2040
|
-
}
|
|
2041
|
-
deactivateRoutes(futureNode, currNode, parentContext) {
|
|
2042
|
-
const future = futureNode.value;
|
|
2043
|
-
const curr = currNode ? currNode.value : null;
|
|
2044
|
-
if (future === curr) {
|
|
2045
|
-
// Reusing the node, check to see if the children need to be de-activated
|
|
2046
|
-
if (future.component) {
|
|
2047
|
-
// If we have a normal route, we need to go through an outlet.
|
|
2048
|
-
const context = parentContext.getContext(future.outlet);
|
|
2049
|
-
if (context) {
|
|
2050
|
-
this.deactivateChildRoutes(futureNode, currNode, context.children);
|
|
2051
|
-
}
|
|
2052
|
-
}
|
|
2053
|
-
else {
|
|
2054
|
-
// if we have a componentless route, we recurse but keep the same outlet map.
|
|
2055
|
-
this.deactivateChildRoutes(futureNode, currNode, parentContext);
|
|
2056
|
-
}
|
|
2057
|
-
}
|
|
2058
|
-
else {
|
|
2059
|
-
if (curr) {
|
|
2060
|
-
// Deactivate the current route which will not be re-used
|
|
2061
|
-
this.deactivateRouteAndItsChildren(currNode, parentContext);
|
|
2062
|
-
}
|
|
2063
|
-
}
|
|
2082
|
+
/**
|
|
2083
|
+
* Store contextual information about a `RouterOutlet`
|
|
2084
|
+
*
|
|
2085
|
+
* @publicApi
|
|
2086
|
+
*/
|
|
2087
|
+
class OutletContext {
|
|
2088
|
+
constructor() {
|
|
2089
|
+
this.outlet = null;
|
|
2090
|
+
this.route = null;
|
|
2091
|
+
/**
|
|
2092
|
+
* @deprecated Passing a resolver to retrieve a component factory is not required and is
|
|
2093
|
+
* deprecated since v14.
|
|
2094
|
+
*/
|
|
2095
|
+
this.resolver = null;
|
|
2096
|
+
this.injector = null;
|
|
2097
|
+
this.children = new ChildrenOutletContexts();
|
|
2098
|
+
this.attachRef = null;
|
|
2064
2099
|
}
|
|
2065
|
-
|
|
2066
|
-
|
|
2067
|
-
|
|
2068
|
-
|
|
2069
|
-
|
|
2070
|
-
|
|
2071
|
-
|
|
2072
|
-
|
|
2073
|
-
|
|
2100
|
+
}
|
|
2101
|
+
/**
|
|
2102
|
+
* Store contextual information about the children (= nested) `RouterOutlet`
|
|
2103
|
+
*
|
|
2104
|
+
* @publicApi
|
|
2105
|
+
*/
|
|
2106
|
+
class ChildrenOutletContexts {
|
|
2107
|
+
constructor() {
|
|
2108
|
+
// contexts for child outlets, by name.
|
|
2109
|
+
this.contexts = new Map();
|
|
2074
2110
|
}
|
|
2075
|
-
|
|
2076
|
-
|
|
2077
|
-
const
|
|
2078
|
-
|
|
2079
|
-
|
|
2080
|
-
this.deactivateRouteAndItsChildren(children[childOutlet], contexts);
|
|
2081
|
-
}
|
|
2082
|
-
if (context && context.outlet) {
|
|
2083
|
-
const componentRef = context.outlet.detach();
|
|
2084
|
-
const contexts = context.children.onOutletDeactivated();
|
|
2085
|
-
this.routeReuseStrategy.store(route.value.snapshot, { componentRef, route, contexts });
|
|
2086
|
-
}
|
|
2111
|
+
/** Called when a `RouterOutlet` directive is instantiated */
|
|
2112
|
+
onChildOutletCreated(childName, outlet) {
|
|
2113
|
+
const context = this.getOrCreateContext(childName);
|
|
2114
|
+
context.outlet = outlet;
|
|
2115
|
+
this.contexts.set(childName, context);
|
|
2087
2116
|
}
|
|
2088
|
-
|
|
2089
|
-
|
|
2090
|
-
|
|
2091
|
-
|
|
2092
|
-
|
|
2093
|
-
|
|
2094
|
-
|
|
2095
|
-
|
|
2096
|
-
|
|
2097
|
-
if (context && context.outlet) {
|
|
2098
|
-
// Destroy the component
|
|
2099
|
-
context.outlet.deactivate();
|
|
2100
|
-
// Destroy the contexts for all the outlets that were in the component
|
|
2101
|
-
context.children.onOutletDeactivated();
|
|
2102
|
-
// Clear the information about the attached component on the context but keep the reference to
|
|
2103
|
-
// the outlet.
|
|
2117
|
+
/**
|
|
2118
|
+
* Called when a `RouterOutlet` directive is destroyed.
|
|
2119
|
+
* We need to keep the context as the outlet could be destroyed inside a NgIf and might be
|
|
2120
|
+
* re-created later.
|
|
2121
|
+
*/
|
|
2122
|
+
onChildOutletDestroyed(childName) {
|
|
2123
|
+
const context = this.getContext(childName);
|
|
2124
|
+
if (context) {
|
|
2125
|
+
context.outlet = null;
|
|
2104
2126
|
context.attachRef = null;
|
|
2105
|
-
context.resolver = null;
|
|
2106
|
-
context.route = null;
|
|
2107
2127
|
}
|
|
2108
2128
|
}
|
|
2109
|
-
|
|
2110
|
-
|
|
2111
|
-
|
|
2112
|
-
|
|
2113
|
-
|
|
2114
|
-
|
|
2115
|
-
|
|
2116
|
-
|
|
2117
|
-
}
|
|
2129
|
+
/**
|
|
2130
|
+
* Called when the corresponding route is deactivated during navigation.
|
|
2131
|
+
* Because the component get destroyed, all children outlet are destroyed.
|
|
2132
|
+
*/
|
|
2133
|
+
onOutletDeactivated() {
|
|
2134
|
+
const contexts = this.contexts;
|
|
2135
|
+
this.contexts = new Map();
|
|
2136
|
+
return contexts;
|
|
2118
2137
|
}
|
|
2119
|
-
|
|
2120
|
-
|
|
2121
|
-
|
|
2122
|
-
|
|
2123
|
-
|
|
2124
|
-
if (
|
|
2125
|
-
|
|
2126
|
-
|
|
2127
|
-
const context = parentContexts.getOrCreateContext(future.outlet);
|
|
2128
|
-
this.activateChildRoutes(futureNode, currNode, context.children);
|
|
2129
|
-
}
|
|
2130
|
-
else {
|
|
2131
|
-
// if we have a componentless route, we recurse but keep the same outlet map.
|
|
2132
|
-
this.activateChildRoutes(futureNode, currNode, parentContexts);
|
|
2133
|
-
}
|
|
2134
|
-
}
|
|
2135
|
-
else {
|
|
2136
|
-
if (future.component) {
|
|
2137
|
-
// if we have a normal route, we need to place the component into the outlet and recurse.
|
|
2138
|
-
const context = parentContexts.getOrCreateContext(future.outlet);
|
|
2139
|
-
if (this.routeReuseStrategy.shouldAttach(future.snapshot)) {
|
|
2140
|
-
const stored = this.routeReuseStrategy.retrieve(future.snapshot);
|
|
2141
|
-
this.routeReuseStrategy.store(future.snapshot, null);
|
|
2142
|
-
context.children.onOutletReAttached(stored.contexts);
|
|
2143
|
-
context.attachRef = stored.componentRef;
|
|
2144
|
-
context.route = stored.route.value;
|
|
2145
|
-
if (context.outlet) {
|
|
2146
|
-
// Attach right away when the outlet has already been instantiated
|
|
2147
|
-
// Otherwise attach from `RouterOutlet.ngOnInit` when it is instantiated
|
|
2148
|
-
context.outlet.attach(stored.componentRef, stored.route.value);
|
|
2149
|
-
}
|
|
2150
|
-
advanceActivatedRoute(stored.route.value);
|
|
2151
|
-
this.activateChildRoutes(futureNode, null, context.children);
|
|
2152
|
-
}
|
|
2153
|
-
else {
|
|
2154
|
-
const config = parentLoadedConfig(future.snapshot);
|
|
2155
|
-
const cmpFactoryResolver = config ? config.module.componentFactoryResolver : null;
|
|
2156
|
-
context.attachRef = null;
|
|
2157
|
-
context.route = future;
|
|
2158
|
-
context.resolver = cmpFactoryResolver;
|
|
2159
|
-
if (context.outlet) {
|
|
2160
|
-
// Activate the outlet when it has already been instantiated
|
|
2161
|
-
// Otherwise it will get activated from its `ngOnInit` when instantiated
|
|
2162
|
-
context.outlet.activateWith(future, cmpFactoryResolver);
|
|
2163
|
-
}
|
|
2164
|
-
this.activateChildRoutes(futureNode, null, context.children);
|
|
2165
|
-
}
|
|
2166
|
-
}
|
|
2167
|
-
else {
|
|
2168
|
-
// if we have a componentless route, we recurse but keep the same outlet map.
|
|
2169
|
-
this.activateChildRoutes(futureNode, null, parentContexts);
|
|
2170
|
-
}
|
|
2138
|
+
onOutletReAttached(contexts) {
|
|
2139
|
+
this.contexts = contexts;
|
|
2140
|
+
}
|
|
2141
|
+
getOrCreateContext(childName) {
|
|
2142
|
+
let context = this.getContext(childName);
|
|
2143
|
+
if (!context) {
|
|
2144
|
+
context = new OutletContext();
|
|
2145
|
+
this.contexts.set(childName, context);
|
|
2171
2146
|
}
|
|
2147
|
+
return context;
|
|
2172
2148
|
}
|
|
2173
|
-
|
|
2174
|
-
|
|
2175
|
-
for (let s = snapshot.parent; s; s = s.parent) {
|
|
2176
|
-
const route = s.routeConfig;
|
|
2177
|
-
if (route && route._loadedConfig)
|
|
2178
|
-
return route._loadedConfig;
|
|
2179
|
-
if (route && route.component)
|
|
2180
|
-
return null;
|
|
2149
|
+
getContext(childName) {
|
|
2150
|
+
return this.contexts.get(childName) || null;
|
|
2181
2151
|
}
|
|
2182
|
-
return null;
|
|
2183
2152
|
}
|
|
2184
2153
|
|
|
2185
2154
|
/**
|
|
@@ -2189,182 +2158,13 @@ function parentLoadedConfig(snapshot) {
|
|
|
2189
2158
|
* Use of this source code is governed by an MIT-style license that can be
|
|
2190
2159
|
* found in the LICENSE file at https://angular.io/license
|
|
2191
2160
|
*/
|
|
2192
|
-
class LoadedRouterConfig {
|
|
2193
|
-
constructor(routes, module) {
|
|
2194
|
-
this.routes = routes;
|
|
2195
|
-
this.module = module;
|
|
2196
|
-
}
|
|
2197
|
-
}
|
|
2198
|
-
|
|
2199
2161
|
/**
|
|
2200
|
-
* @
|
|
2201
|
-
* Copyright Google LLC All Rights Reserved.
|
|
2162
|
+
* @description
|
|
2202
2163
|
*
|
|
2203
|
-
*
|
|
2204
|
-
* found in the LICENSE file at https://angular.io/license
|
|
2205
|
-
*/
|
|
2206
|
-
/**
|
|
2207
|
-
* Simple function check, but generic so type inference will flow. Example:
|
|
2164
|
+
* Acts as a placeholder that Angular dynamically fills based on the current router state.
|
|
2208
2165
|
*
|
|
2209
|
-
*
|
|
2210
|
-
*
|
|
2211
|
-
* }
|
|
2212
|
-
*
|
|
2213
|
-
* if (isFunction<product>(fn)) {
|
|
2214
|
-
* return fn(1, 2);
|
|
2215
|
-
* } else {
|
|
2216
|
-
* throw "Must provide the `product` function";
|
|
2217
|
-
* }
|
|
2218
|
-
*/
|
|
2219
|
-
function isFunction(v) {
|
|
2220
|
-
return typeof v === 'function';
|
|
2221
|
-
}
|
|
2222
|
-
function isBoolean(v) {
|
|
2223
|
-
return typeof v === 'boolean';
|
|
2224
|
-
}
|
|
2225
|
-
function isUrlTree(v) {
|
|
2226
|
-
return v instanceof UrlTree;
|
|
2227
|
-
}
|
|
2228
|
-
function isCanLoad(guard) {
|
|
2229
|
-
return guard && isFunction(guard.canLoad);
|
|
2230
|
-
}
|
|
2231
|
-
function isCanActivate(guard) {
|
|
2232
|
-
return guard && isFunction(guard.canActivate);
|
|
2233
|
-
}
|
|
2234
|
-
function isCanActivateChild(guard) {
|
|
2235
|
-
return guard && isFunction(guard.canActivateChild);
|
|
2236
|
-
}
|
|
2237
|
-
function isCanDeactivate(guard) {
|
|
2238
|
-
return guard && isFunction(guard.canDeactivate);
|
|
2239
|
-
}
|
|
2240
|
-
|
|
2241
|
-
/**
|
|
2242
|
-
* @license
|
|
2243
|
-
* Copyright Google LLC All Rights Reserved.
|
|
2244
|
-
*
|
|
2245
|
-
* Use of this source code is governed by an MIT-style license that can be
|
|
2246
|
-
* found in the LICENSE file at https://angular.io/license
|
|
2247
|
-
*/
|
|
2248
|
-
const INITIAL_VALUE = Symbol('INITIAL_VALUE');
|
|
2249
|
-
function prioritizedGuardValue() {
|
|
2250
|
-
return switchMap(obs => {
|
|
2251
|
-
return combineLatest(obs.map(o => o.pipe(take(1), startWith(INITIAL_VALUE))))
|
|
2252
|
-
.pipe(scan((acc, list) => {
|
|
2253
|
-
let isPending = false;
|
|
2254
|
-
return list.reduce((innerAcc, val, i) => {
|
|
2255
|
-
if (innerAcc !== INITIAL_VALUE)
|
|
2256
|
-
return innerAcc;
|
|
2257
|
-
// Toggle pending flag if any values haven't been set yet
|
|
2258
|
-
if (val === INITIAL_VALUE)
|
|
2259
|
-
isPending = true;
|
|
2260
|
-
// Any other return values are only valid if we haven't yet hit a pending
|
|
2261
|
-
// call. This guarantees that in the case of a guard at the bottom of the
|
|
2262
|
-
// tree that returns a redirect, we will wait for the higher priority
|
|
2263
|
-
// guard at the top to finish before performing the redirect.
|
|
2264
|
-
if (!isPending) {
|
|
2265
|
-
// Early return when we hit a `false` value as that should always
|
|
2266
|
-
// cancel navigation
|
|
2267
|
-
if (val === false)
|
|
2268
|
-
return val;
|
|
2269
|
-
if (i === list.length - 1 || isUrlTree(val)) {
|
|
2270
|
-
return val;
|
|
2271
|
-
}
|
|
2272
|
-
}
|
|
2273
|
-
return innerAcc;
|
|
2274
|
-
}, acc);
|
|
2275
|
-
}, INITIAL_VALUE), filter(item => item !== INITIAL_VALUE), map(item => isUrlTree(item) ? item : item === true), //
|
|
2276
|
-
take(1));
|
|
2277
|
-
});
|
|
2278
|
-
}
|
|
2279
|
-
|
|
2280
|
-
/**
|
|
2281
|
-
* @license
|
|
2282
|
-
* Copyright Google LLC All Rights Reserved.
|
|
2283
|
-
*
|
|
2284
|
-
* Use of this source code is governed by an MIT-style license that can be
|
|
2285
|
-
* found in the LICENSE file at https://angular.io/license
|
|
2286
|
-
*/
|
|
2287
|
-
/**
|
|
2288
|
-
* Store contextual information about a `RouterOutlet`
|
|
2289
|
-
*
|
|
2290
|
-
* @publicApi
|
|
2291
|
-
*/
|
|
2292
|
-
class OutletContext {
|
|
2293
|
-
constructor() {
|
|
2294
|
-
this.outlet = null;
|
|
2295
|
-
this.route = null;
|
|
2296
|
-
this.resolver = null;
|
|
2297
|
-
this.children = new ChildrenOutletContexts();
|
|
2298
|
-
this.attachRef = null;
|
|
2299
|
-
}
|
|
2300
|
-
}
|
|
2301
|
-
/**
|
|
2302
|
-
* Store contextual information about the children (= nested) `RouterOutlet`
|
|
2303
|
-
*
|
|
2304
|
-
* @publicApi
|
|
2305
|
-
*/
|
|
2306
|
-
class ChildrenOutletContexts {
|
|
2307
|
-
constructor() {
|
|
2308
|
-
// contexts for child outlets, by name.
|
|
2309
|
-
this.contexts = new Map();
|
|
2310
|
-
}
|
|
2311
|
-
/** Called when a `RouterOutlet` directive is instantiated */
|
|
2312
|
-
onChildOutletCreated(childName, outlet) {
|
|
2313
|
-
const context = this.getOrCreateContext(childName);
|
|
2314
|
-
context.outlet = outlet;
|
|
2315
|
-
this.contexts.set(childName, context);
|
|
2316
|
-
}
|
|
2317
|
-
/**
|
|
2318
|
-
* Called when a `RouterOutlet` directive is destroyed.
|
|
2319
|
-
* We need to keep the context as the outlet could be destroyed inside a NgIf and might be
|
|
2320
|
-
* re-created later.
|
|
2321
|
-
*/
|
|
2322
|
-
onChildOutletDestroyed(childName) {
|
|
2323
|
-
const context = this.getContext(childName);
|
|
2324
|
-
if (context) {
|
|
2325
|
-
context.outlet = null;
|
|
2326
|
-
context.attachRef = null;
|
|
2327
|
-
}
|
|
2328
|
-
}
|
|
2329
|
-
/**
|
|
2330
|
-
* Called when the corresponding route is deactivated during navigation.
|
|
2331
|
-
* Because the component get destroyed, all children outlet are destroyed.
|
|
2332
|
-
*/
|
|
2333
|
-
onOutletDeactivated() {
|
|
2334
|
-
const contexts = this.contexts;
|
|
2335
|
-
this.contexts = new Map();
|
|
2336
|
-
return contexts;
|
|
2337
|
-
}
|
|
2338
|
-
onOutletReAttached(contexts) {
|
|
2339
|
-
this.contexts = contexts;
|
|
2340
|
-
}
|
|
2341
|
-
getOrCreateContext(childName) {
|
|
2342
|
-
let context = this.getContext(childName);
|
|
2343
|
-
if (!context) {
|
|
2344
|
-
context = new OutletContext();
|
|
2345
|
-
this.contexts.set(childName, context);
|
|
2346
|
-
}
|
|
2347
|
-
return context;
|
|
2348
|
-
}
|
|
2349
|
-
getContext(childName) {
|
|
2350
|
-
return this.contexts.get(childName) || null;
|
|
2351
|
-
}
|
|
2352
|
-
}
|
|
2353
|
-
|
|
2354
|
-
/**
|
|
2355
|
-
* @license
|
|
2356
|
-
* Copyright Google LLC All Rights Reserved.
|
|
2357
|
-
*
|
|
2358
|
-
* Use of this source code is governed by an MIT-style license that can be
|
|
2359
|
-
* found in the LICENSE file at https://angular.io/license
|
|
2360
|
-
*/
|
|
2361
|
-
/**
|
|
2362
|
-
* @description
|
|
2363
|
-
*
|
|
2364
|
-
* Acts as a placeholder that Angular dynamically fills based on the current router state.
|
|
2365
|
-
*
|
|
2366
|
-
* Each outlet can have a unique name, determined by the optional `name` attribute.
|
|
2367
|
-
* The name cannot be set or changed dynamically. If not set, default value is "primary".
|
|
2166
|
+
* Each outlet can have a unique name, determined by the optional `name` attribute.
|
|
2167
|
+
* The name cannot be set or changed dynamically. If not set, default value is "primary".
|
|
2368
2168
|
*
|
|
2369
2169
|
* ```
|
|
2370
2170
|
* <router-outlet></router-outlet>
|
|
@@ -2410,11 +2210,11 @@ class ChildrenOutletContexts {
|
|
|
2410
2210
|
* @publicApi
|
|
2411
2211
|
*/
|
|
2412
2212
|
class RouterOutlet {
|
|
2413
|
-
constructor(parentContexts, location,
|
|
2213
|
+
constructor(parentContexts, location, name, changeDetector, environmentInjector) {
|
|
2414
2214
|
this.parentContexts = parentContexts;
|
|
2415
2215
|
this.location = location;
|
|
2416
|
-
this.resolver = resolver;
|
|
2417
2216
|
this.changeDetector = changeDetector;
|
|
2217
|
+
this.environmentInjector = environmentInjector;
|
|
2418
2218
|
this.activated = null;
|
|
2419
2219
|
this._activatedRoute = null;
|
|
2420
2220
|
this.activateEvents = new EventEmitter();
|
|
@@ -2449,7 +2249,7 @@ class RouterOutlet {
|
|
|
2449
2249
|
}
|
|
2450
2250
|
else {
|
|
2451
2251
|
// otherwise the component defined in the configuration is created
|
|
2452
|
-
this.activateWith(context.route, context.
|
|
2252
|
+
this.activateWith(context.route, context.injector);
|
|
2453
2253
|
}
|
|
2454
2254
|
}
|
|
2455
2255
|
}
|
|
@@ -2508,34 +2308,40 @@ class RouterOutlet {
|
|
|
2508
2308
|
this.deactivateEvents.emit(c);
|
|
2509
2309
|
}
|
|
2510
2310
|
}
|
|
2511
|
-
activateWith(activatedRoute,
|
|
2311
|
+
activateWith(activatedRoute, resolverOrInjector) {
|
|
2512
2312
|
if (this.isActivated) {
|
|
2513
2313
|
throw new Error('Cannot activate an already activated outlet');
|
|
2514
2314
|
}
|
|
2515
2315
|
this._activatedRoute = activatedRoute;
|
|
2316
|
+
const location = this.location;
|
|
2516
2317
|
const snapshot = activatedRoute._futureSnapshot;
|
|
2517
|
-
const component = snapshot.
|
|
2518
|
-
resolver = resolver || this.resolver;
|
|
2519
|
-
const factory = resolver.resolveComponentFactory(component);
|
|
2318
|
+
const component = snapshot.component;
|
|
2520
2319
|
const childContexts = this.parentContexts.getOrCreateContext(this.name).children;
|
|
2521
|
-
const injector = new OutletInjector(activatedRoute, childContexts,
|
|
2522
|
-
|
|
2320
|
+
const injector = new OutletInjector(activatedRoute, childContexts, location.injector);
|
|
2321
|
+
if (resolverOrInjector && isComponentFactoryResolver(resolverOrInjector)) {
|
|
2322
|
+
const factory = resolverOrInjector.resolveComponentFactory(component);
|
|
2323
|
+
this.activated = location.createComponent(factory, location.length, injector);
|
|
2324
|
+
}
|
|
2325
|
+
else {
|
|
2326
|
+
const environmentInjector = resolverOrInjector !== null && resolverOrInjector !== void 0 ? resolverOrInjector : this.environmentInjector;
|
|
2327
|
+
this.activated = location.createComponent(component, { index: location.length, injector, environmentInjector });
|
|
2328
|
+
}
|
|
2523
2329
|
// Calling `markForCheck` to make sure we will run the change detection when the
|
|
2524
2330
|
// `RouterOutlet` is inside a `ChangeDetectionStrategy.OnPush` component.
|
|
2525
2331
|
this.changeDetector.markForCheck();
|
|
2526
2332
|
this.activateEvents.emit(this.activated.instance);
|
|
2527
2333
|
}
|
|
2528
2334
|
}
|
|
2529
|
-
RouterOutlet.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.0-
|
|
2530
|
-
RouterOutlet.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "
|
|
2531
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.0-
|
|
2335
|
+
RouterOutlet.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.0-rc.0", ngImport: i0, type: RouterOutlet, deps: [{ token: ChildrenOutletContexts }, { token: i0.ViewContainerRef }, { token: 'name', attribute: true }, { token: i0.ChangeDetectorRef }, { token: i0.EnvironmentInjector }], target: i0.ɵɵFactoryTarget.Directive });
|
|
2336
|
+
RouterOutlet.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "14.0.0-rc.0", type: RouterOutlet, selector: "router-outlet", outputs: { activateEvents: "activate", deactivateEvents: "deactivate", attachEvents: "attach", detachEvents: "detach" }, exportAs: ["outlet"], ngImport: i0 });
|
|
2337
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.0-rc.0", ngImport: i0, type: RouterOutlet, decorators: [{
|
|
2532
2338
|
type: Directive,
|
|
2533
2339
|
args: [{ selector: 'router-outlet', exportAs: 'outlet' }]
|
|
2534
2340
|
}], ctorParameters: function () {
|
|
2535
|
-
return [{ type: ChildrenOutletContexts }, { type: i0.ViewContainerRef }, { type:
|
|
2341
|
+
return [{ type: ChildrenOutletContexts }, { type: i0.ViewContainerRef }, { type: undefined, decorators: [{
|
|
2536
2342
|
type: Attribute,
|
|
2537
2343
|
args: ['name']
|
|
2538
|
-
}] }, { type: i0.ChangeDetectorRef }];
|
|
2344
|
+
}] }, { type: i0.ChangeDetectorRef }, { type: i0.EnvironmentInjector }];
|
|
2539
2345
|
}, propDecorators: { activateEvents: [{
|
|
2540
2346
|
type: Output,
|
|
2541
2347
|
args: ['activate']
|
|
@@ -2562,7 +2368,387 @@ class OutletInjector {
|
|
|
2562
2368
|
if (token === ChildrenOutletContexts) {
|
|
2563
2369
|
return this.childContexts;
|
|
2564
2370
|
}
|
|
2565
|
-
return this.parent.get(token, notFoundValue);
|
|
2371
|
+
return this.parent.get(token, notFoundValue);
|
|
2372
|
+
}
|
|
2373
|
+
}
|
|
2374
|
+
function isComponentFactoryResolver(item) {
|
|
2375
|
+
return !!item.resolveComponentFactory;
|
|
2376
|
+
}
|
|
2377
|
+
|
|
2378
|
+
/**
|
|
2379
|
+
* @license
|
|
2380
|
+
* Copyright Google LLC All Rights Reserved.
|
|
2381
|
+
*
|
|
2382
|
+
* Use of this source code is governed by an MIT-style license that can be
|
|
2383
|
+
* found in the LICENSE file at https://angular.io/license
|
|
2384
|
+
*/
|
|
2385
|
+
/**
|
|
2386
|
+
* This component is used internally within the router to be a placeholder when an empty
|
|
2387
|
+
* router-outlet is needed. For example, with a config such as:
|
|
2388
|
+
*
|
|
2389
|
+
* `{path: 'parent', outlet: 'nav', children: [...]}`
|
|
2390
|
+
*
|
|
2391
|
+
* In order to render, there needs to be a component on this config, which will default
|
|
2392
|
+
* to this `EmptyOutletComponent`.
|
|
2393
|
+
*/
|
|
2394
|
+
class ɵEmptyOutletComponent {
|
|
2395
|
+
}
|
|
2396
|
+
ɵEmptyOutletComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.0-rc.0", ngImport: i0, type: ɵEmptyOutletComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2397
|
+
ɵEmptyOutletComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.0.0-rc.0", type: ɵEmptyOutletComponent, selector: "ng-component", ngImport: i0, template: `<router-outlet></router-outlet>`, isInline: true, dependencies: [{ kind: "directive", type: RouterOutlet, selector: "router-outlet", outputs: ["activate", "deactivate", "attach", "detach"], exportAs: ["outlet"] }] });
|
|
2398
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.0-rc.0", ngImport: i0, type: ɵEmptyOutletComponent, decorators: [{
|
|
2399
|
+
type: Component,
|
|
2400
|
+
args: [{ template: `<router-outlet></router-outlet>` }]
|
|
2401
|
+
}] });
|
|
2402
|
+
|
|
2403
|
+
/**
|
|
2404
|
+
* @license
|
|
2405
|
+
* Copyright Google LLC All Rights Reserved.
|
|
2406
|
+
*
|
|
2407
|
+
* Use of this source code is governed by an MIT-style license that can be
|
|
2408
|
+
* found in the LICENSE file at https://angular.io/license
|
|
2409
|
+
*/
|
|
2410
|
+
function getLoadedRoutes(route) {
|
|
2411
|
+
return route._loadedRoutes;
|
|
2412
|
+
}
|
|
2413
|
+
function getLoadedInjector(route) {
|
|
2414
|
+
return route._loadedInjector;
|
|
2415
|
+
}
|
|
2416
|
+
function getLoadedComponent(route) {
|
|
2417
|
+
return route._loadedComponent;
|
|
2418
|
+
}
|
|
2419
|
+
function getProvidersInjector(route) {
|
|
2420
|
+
return route._injector;
|
|
2421
|
+
}
|
|
2422
|
+
function validateConfig(config, parentPath = '', requireStandaloneComponents = false) {
|
|
2423
|
+
// forEach doesn't iterate undefined values
|
|
2424
|
+
for (let i = 0; i < config.length; i++) {
|
|
2425
|
+
const route = config[i];
|
|
2426
|
+
const fullPath = getFullPath(parentPath, route);
|
|
2427
|
+
validateNode(route, fullPath, requireStandaloneComponents);
|
|
2428
|
+
}
|
|
2429
|
+
}
|
|
2430
|
+
function assertStandalone(fullPath, component) {
|
|
2431
|
+
if (component && !ɵisStandalone(component)) {
|
|
2432
|
+
throw new Error(`Invalid configuration of route '${fullPath}'. The component must be standalone.`);
|
|
2433
|
+
}
|
|
2434
|
+
}
|
|
2435
|
+
function validateNode(route, fullPath, requireStandaloneComponents) {
|
|
2436
|
+
if (typeof ngDevMode === 'undefined' || ngDevMode) {
|
|
2437
|
+
if (!route) {
|
|
2438
|
+
throw new Error(`
|
|
2439
|
+
Invalid configuration of route '${fullPath}': Encountered undefined route.
|
|
2440
|
+
The reason might be an extra comma.
|
|
2441
|
+
|
|
2442
|
+
Example:
|
|
2443
|
+
const routes: Routes = [
|
|
2444
|
+
{ path: '', redirectTo: '/dashboard', pathMatch: 'full' },
|
|
2445
|
+
{ path: 'dashboard', component: DashboardComponent },, << two commas
|
|
2446
|
+
{ path: 'detail/:id', component: HeroDetailComponent }
|
|
2447
|
+
];
|
|
2448
|
+
`);
|
|
2449
|
+
}
|
|
2450
|
+
if (Array.isArray(route)) {
|
|
2451
|
+
throw new Error(`Invalid configuration of route '${fullPath}': Array cannot be specified`);
|
|
2452
|
+
}
|
|
2453
|
+
if (!route.component && !route.loadComponent && !route.children && !route.loadChildren &&
|
|
2454
|
+
(route.outlet && route.outlet !== PRIMARY_OUTLET)) {
|
|
2455
|
+
throw new Error(`Invalid configuration of route '${fullPath}': a componentless route without children or loadChildren cannot have a named outlet set`);
|
|
2456
|
+
}
|
|
2457
|
+
if (route.redirectTo && route.children) {
|
|
2458
|
+
throw new Error(`Invalid configuration of route '${fullPath}': redirectTo and children cannot be used together`);
|
|
2459
|
+
}
|
|
2460
|
+
if (route.redirectTo && route.loadChildren) {
|
|
2461
|
+
throw new Error(`Invalid configuration of route '${fullPath}': redirectTo and loadChildren cannot be used together`);
|
|
2462
|
+
}
|
|
2463
|
+
if (route.children && route.loadChildren) {
|
|
2464
|
+
throw new Error(`Invalid configuration of route '${fullPath}': children and loadChildren cannot be used together`);
|
|
2465
|
+
}
|
|
2466
|
+
if (route.redirectTo && (route.component || route.loadComponent)) {
|
|
2467
|
+
throw new Error(`Invalid configuration of route '${fullPath}': redirectTo and component/loadComponent cannot be used together`);
|
|
2468
|
+
}
|
|
2469
|
+
if (route.component && route.loadComponent) {
|
|
2470
|
+
throw new Error(`Invalid configuration of route '${fullPath}': component and loadComponent cannot be used together`);
|
|
2471
|
+
}
|
|
2472
|
+
if (route.redirectTo && route.canActivate) {
|
|
2473
|
+
throw new Error(`Invalid configuration of route '${fullPath}': redirectTo and canActivate cannot be used together. Redirects happen before activation ` +
|
|
2474
|
+
`so canActivate will never be executed.`);
|
|
2475
|
+
}
|
|
2476
|
+
if (route.path && route.matcher) {
|
|
2477
|
+
throw new Error(`Invalid configuration of route '${fullPath}': path and matcher cannot be used together`);
|
|
2478
|
+
}
|
|
2479
|
+
if (route.redirectTo === void 0 && !route.component && !route.loadComponent &&
|
|
2480
|
+
!route.children && !route.loadChildren) {
|
|
2481
|
+
throw new Error(`Invalid configuration of route '${fullPath}'. One of the following must be provided: component, loadComponent, redirectTo, children or loadChildren`);
|
|
2482
|
+
}
|
|
2483
|
+
if (route.path === void 0 && route.matcher === void 0) {
|
|
2484
|
+
throw new Error(`Invalid configuration of route '${fullPath}': routes must have either a path or a matcher specified`);
|
|
2485
|
+
}
|
|
2486
|
+
if (typeof route.path === 'string' && route.path.charAt(0) === '/') {
|
|
2487
|
+
throw new Error(`Invalid configuration of route '${fullPath}': path cannot start with a slash`);
|
|
2488
|
+
}
|
|
2489
|
+
if (route.path === '' && route.redirectTo !== void 0 && route.pathMatch === void 0) {
|
|
2490
|
+
const exp = `The default value of 'pathMatch' is 'prefix', but often the intent is to use 'full'.`;
|
|
2491
|
+
throw new Error(`Invalid configuration of route '{path: "${fullPath}", redirectTo: "${route.redirectTo}"}': please provide 'pathMatch'. ${exp}`);
|
|
2492
|
+
}
|
|
2493
|
+
if (requireStandaloneComponents) {
|
|
2494
|
+
assertStandalone(fullPath, route.component);
|
|
2495
|
+
}
|
|
2496
|
+
}
|
|
2497
|
+
if (route.children) {
|
|
2498
|
+
validateConfig(route.children, fullPath, requireStandaloneComponents);
|
|
2499
|
+
}
|
|
2500
|
+
}
|
|
2501
|
+
function getFullPath(parentPath, currentRoute) {
|
|
2502
|
+
if (!currentRoute) {
|
|
2503
|
+
return parentPath;
|
|
2504
|
+
}
|
|
2505
|
+
if (!parentPath && !currentRoute.path) {
|
|
2506
|
+
return '';
|
|
2507
|
+
}
|
|
2508
|
+
else if (parentPath && !currentRoute.path) {
|
|
2509
|
+
return `${parentPath}/`;
|
|
2510
|
+
}
|
|
2511
|
+
else if (!parentPath && currentRoute.path) {
|
|
2512
|
+
return currentRoute.path;
|
|
2513
|
+
}
|
|
2514
|
+
else {
|
|
2515
|
+
return `${parentPath}/${currentRoute.path}`;
|
|
2516
|
+
}
|
|
2517
|
+
}
|
|
2518
|
+
/**
|
|
2519
|
+
* Makes a copy of the config and adds any default required properties.
|
|
2520
|
+
*/
|
|
2521
|
+
function standardizeConfig(r) {
|
|
2522
|
+
const children = r.children && r.children.map(standardizeConfig);
|
|
2523
|
+
const c = children ? Object.assign(Object.assign({}, r), { children }) : Object.assign({}, r);
|
|
2524
|
+
if ((!c.component && !c.loadComponent) && (children || c.loadChildren) &&
|
|
2525
|
+
(c.outlet && c.outlet !== PRIMARY_OUTLET)) {
|
|
2526
|
+
c.component = ɵEmptyOutletComponent;
|
|
2527
|
+
}
|
|
2528
|
+
return c;
|
|
2529
|
+
}
|
|
2530
|
+
/** Returns the `route.outlet` or PRIMARY_OUTLET if none exists. */
|
|
2531
|
+
function getOutlet(route) {
|
|
2532
|
+
return route.outlet || PRIMARY_OUTLET;
|
|
2533
|
+
}
|
|
2534
|
+
/**
|
|
2535
|
+
* Sorts the `routes` such that the ones with an outlet matching `outletName` come first.
|
|
2536
|
+
* The order of the configs is otherwise preserved.
|
|
2537
|
+
*/
|
|
2538
|
+
function sortByMatchingOutlets(routes, outletName) {
|
|
2539
|
+
const sortedConfig = routes.filter(r => getOutlet(r) === outletName);
|
|
2540
|
+
sortedConfig.push(...routes.filter(r => getOutlet(r) !== outletName));
|
|
2541
|
+
return sortedConfig;
|
|
2542
|
+
}
|
|
2543
|
+
/**
|
|
2544
|
+
* Gets the first injector in the snapshot's parent tree.
|
|
2545
|
+
*
|
|
2546
|
+
* If the `Route` has a static list of providers, the returned injector will be the one created from
|
|
2547
|
+
* those. If it does not exist, the returned injector may come from the parents, which may be from a
|
|
2548
|
+
* loaded config or their static providers.
|
|
2549
|
+
*
|
|
2550
|
+
* Returns `null` if there is neither this nor any parents have a stored injector.
|
|
2551
|
+
*
|
|
2552
|
+
* Generally used for retrieving the injector to use for getting tokens for guards/resolvers and
|
|
2553
|
+
* also used for getting the correct injector to use for creating components.
|
|
2554
|
+
*/
|
|
2555
|
+
function getClosestRouteInjector(snapshot) {
|
|
2556
|
+
var _a;
|
|
2557
|
+
if (!snapshot)
|
|
2558
|
+
return null;
|
|
2559
|
+
// If the current route has its own injector, which is created from the static providers on the
|
|
2560
|
+
// route itself, we should use that. Otherwise, we start at the parent since we do not want to
|
|
2561
|
+
// include the lazy loaded injector from this route.
|
|
2562
|
+
if ((_a = snapshot.routeConfig) === null || _a === void 0 ? void 0 : _a._injector) {
|
|
2563
|
+
return snapshot.routeConfig._injector;
|
|
2564
|
+
}
|
|
2565
|
+
for (let s = snapshot.parent; s; s = s.parent) {
|
|
2566
|
+
const route = s.routeConfig;
|
|
2567
|
+
// Note that the order here is important. `_loadedInjector` stored on the route with
|
|
2568
|
+
// `loadChildren: () => NgModule` so it applies to child routes with priority. The `_injector`
|
|
2569
|
+
// is created from the static providers on that parent route, so it applies to the children as
|
|
2570
|
+
// well, but only if there is no lazy loaded NgModuleRef injector.
|
|
2571
|
+
if (route === null || route === void 0 ? void 0 : route._loadedInjector)
|
|
2572
|
+
return route._loadedInjector;
|
|
2573
|
+
if (route === null || route === void 0 ? void 0 : route._injector)
|
|
2574
|
+
return route._injector;
|
|
2575
|
+
}
|
|
2576
|
+
return null;
|
|
2577
|
+
}
|
|
2578
|
+
|
|
2579
|
+
/**
|
|
2580
|
+
* @license
|
|
2581
|
+
* Copyright Google LLC All Rights Reserved.
|
|
2582
|
+
*
|
|
2583
|
+
* Use of this source code is governed by an MIT-style license that can be
|
|
2584
|
+
* found in the LICENSE file at https://angular.io/license
|
|
2585
|
+
*/
|
|
2586
|
+
const activateRoutes = (rootContexts, routeReuseStrategy, forwardEvent) => map(t => {
|
|
2587
|
+
new ActivateRoutes(routeReuseStrategy, t.targetRouterState, t.currentRouterState, forwardEvent)
|
|
2588
|
+
.activate(rootContexts);
|
|
2589
|
+
return t;
|
|
2590
|
+
});
|
|
2591
|
+
class ActivateRoutes {
|
|
2592
|
+
constructor(routeReuseStrategy, futureState, currState, forwardEvent) {
|
|
2593
|
+
this.routeReuseStrategy = routeReuseStrategy;
|
|
2594
|
+
this.futureState = futureState;
|
|
2595
|
+
this.currState = currState;
|
|
2596
|
+
this.forwardEvent = forwardEvent;
|
|
2597
|
+
}
|
|
2598
|
+
activate(parentContexts) {
|
|
2599
|
+
const futureRoot = this.futureState._root;
|
|
2600
|
+
const currRoot = this.currState ? this.currState._root : null;
|
|
2601
|
+
this.deactivateChildRoutes(futureRoot, currRoot, parentContexts);
|
|
2602
|
+
advanceActivatedRoute(this.futureState.root);
|
|
2603
|
+
this.activateChildRoutes(futureRoot, currRoot, parentContexts);
|
|
2604
|
+
}
|
|
2605
|
+
// De-activate the child route that are not re-used for the future state
|
|
2606
|
+
deactivateChildRoutes(futureNode, currNode, contexts) {
|
|
2607
|
+
const children = nodeChildrenAsMap(currNode);
|
|
2608
|
+
// Recurse on the routes active in the future state to de-activate deeper children
|
|
2609
|
+
futureNode.children.forEach(futureChild => {
|
|
2610
|
+
const childOutletName = futureChild.value.outlet;
|
|
2611
|
+
this.deactivateRoutes(futureChild, children[childOutletName], contexts);
|
|
2612
|
+
delete children[childOutletName];
|
|
2613
|
+
});
|
|
2614
|
+
// De-activate the routes that will not be re-used
|
|
2615
|
+
forEach(children, (v, childName) => {
|
|
2616
|
+
this.deactivateRouteAndItsChildren(v, contexts);
|
|
2617
|
+
});
|
|
2618
|
+
}
|
|
2619
|
+
deactivateRoutes(futureNode, currNode, parentContext) {
|
|
2620
|
+
const future = futureNode.value;
|
|
2621
|
+
const curr = currNode ? currNode.value : null;
|
|
2622
|
+
if (future === curr) {
|
|
2623
|
+
// Reusing the node, check to see if the children need to be de-activated
|
|
2624
|
+
if (future.component) {
|
|
2625
|
+
// If we have a normal route, we need to go through an outlet.
|
|
2626
|
+
const context = parentContext.getContext(future.outlet);
|
|
2627
|
+
if (context) {
|
|
2628
|
+
this.deactivateChildRoutes(futureNode, currNode, context.children);
|
|
2629
|
+
}
|
|
2630
|
+
}
|
|
2631
|
+
else {
|
|
2632
|
+
// if we have a componentless route, we recurse but keep the same outlet map.
|
|
2633
|
+
this.deactivateChildRoutes(futureNode, currNode, parentContext);
|
|
2634
|
+
}
|
|
2635
|
+
}
|
|
2636
|
+
else {
|
|
2637
|
+
if (curr) {
|
|
2638
|
+
// Deactivate the current route which will not be re-used
|
|
2639
|
+
this.deactivateRouteAndItsChildren(currNode, parentContext);
|
|
2640
|
+
}
|
|
2641
|
+
}
|
|
2642
|
+
}
|
|
2643
|
+
deactivateRouteAndItsChildren(route, parentContexts) {
|
|
2644
|
+
// If there is no component, the Route is never attached to an outlet (because there is no
|
|
2645
|
+
// component to attach).
|
|
2646
|
+
if (route.value.component && this.routeReuseStrategy.shouldDetach(route.value.snapshot)) {
|
|
2647
|
+
this.detachAndStoreRouteSubtree(route, parentContexts);
|
|
2648
|
+
}
|
|
2649
|
+
else {
|
|
2650
|
+
this.deactivateRouteAndOutlet(route, parentContexts);
|
|
2651
|
+
}
|
|
2652
|
+
}
|
|
2653
|
+
detachAndStoreRouteSubtree(route, parentContexts) {
|
|
2654
|
+
const context = parentContexts.getContext(route.value.outlet);
|
|
2655
|
+
const contexts = context && route.value.component ? context.children : parentContexts;
|
|
2656
|
+
const children = nodeChildrenAsMap(route);
|
|
2657
|
+
for (const childOutlet of Object.keys(children)) {
|
|
2658
|
+
this.deactivateRouteAndItsChildren(children[childOutlet], contexts);
|
|
2659
|
+
}
|
|
2660
|
+
if (context && context.outlet) {
|
|
2661
|
+
const componentRef = context.outlet.detach();
|
|
2662
|
+
const contexts = context.children.onOutletDeactivated();
|
|
2663
|
+
this.routeReuseStrategy.store(route.value.snapshot, { componentRef, route, contexts });
|
|
2664
|
+
}
|
|
2665
|
+
}
|
|
2666
|
+
deactivateRouteAndOutlet(route, parentContexts) {
|
|
2667
|
+
const context = parentContexts.getContext(route.value.outlet);
|
|
2668
|
+
// The context could be `null` if we are on a componentless route but there may still be
|
|
2669
|
+
// children that need deactivating.
|
|
2670
|
+
const contexts = context && route.value.component ? context.children : parentContexts;
|
|
2671
|
+
const children = nodeChildrenAsMap(route);
|
|
2672
|
+
for (const childOutlet of Object.keys(children)) {
|
|
2673
|
+
this.deactivateRouteAndItsChildren(children[childOutlet], contexts);
|
|
2674
|
+
}
|
|
2675
|
+
if (context && context.outlet) {
|
|
2676
|
+
// Destroy the component
|
|
2677
|
+
context.outlet.deactivate();
|
|
2678
|
+
// Destroy the contexts for all the outlets that were in the component
|
|
2679
|
+
context.children.onOutletDeactivated();
|
|
2680
|
+
// Clear the information about the attached component on the context but keep the reference to
|
|
2681
|
+
// the outlet.
|
|
2682
|
+
context.attachRef = null;
|
|
2683
|
+
context.resolver = null;
|
|
2684
|
+
context.route = null;
|
|
2685
|
+
}
|
|
2686
|
+
}
|
|
2687
|
+
activateChildRoutes(futureNode, currNode, contexts) {
|
|
2688
|
+
const children = nodeChildrenAsMap(currNode);
|
|
2689
|
+
futureNode.children.forEach(c => {
|
|
2690
|
+
this.activateRoutes(c, children[c.value.outlet], contexts);
|
|
2691
|
+
this.forwardEvent(new ActivationEnd(c.value.snapshot));
|
|
2692
|
+
});
|
|
2693
|
+
if (futureNode.children.length) {
|
|
2694
|
+
this.forwardEvent(new ChildActivationEnd(futureNode.value.snapshot));
|
|
2695
|
+
}
|
|
2696
|
+
}
|
|
2697
|
+
activateRoutes(futureNode, currNode, parentContexts) {
|
|
2698
|
+
var _a;
|
|
2699
|
+
const future = futureNode.value;
|
|
2700
|
+
const curr = currNode ? currNode.value : null;
|
|
2701
|
+
advanceActivatedRoute(future);
|
|
2702
|
+
// reusing the node
|
|
2703
|
+
if (future === curr) {
|
|
2704
|
+
if (future.component) {
|
|
2705
|
+
// If we have a normal route, we need to go through an outlet.
|
|
2706
|
+
const context = parentContexts.getOrCreateContext(future.outlet);
|
|
2707
|
+
this.activateChildRoutes(futureNode, currNode, context.children);
|
|
2708
|
+
}
|
|
2709
|
+
else {
|
|
2710
|
+
// if we have a componentless route, we recurse but keep the same outlet map.
|
|
2711
|
+
this.activateChildRoutes(futureNode, currNode, parentContexts);
|
|
2712
|
+
}
|
|
2713
|
+
}
|
|
2714
|
+
else {
|
|
2715
|
+
if (future.component) {
|
|
2716
|
+
// if we have a normal route, we need to place the component into the outlet and recurse.
|
|
2717
|
+
const context = parentContexts.getOrCreateContext(future.outlet);
|
|
2718
|
+
if (this.routeReuseStrategy.shouldAttach(future.snapshot)) {
|
|
2719
|
+
const stored = this.routeReuseStrategy.retrieve(future.snapshot);
|
|
2720
|
+
this.routeReuseStrategy.store(future.snapshot, null);
|
|
2721
|
+
context.children.onOutletReAttached(stored.contexts);
|
|
2722
|
+
context.attachRef = stored.componentRef;
|
|
2723
|
+
context.route = stored.route.value;
|
|
2724
|
+
if (context.outlet) {
|
|
2725
|
+
// Attach right away when the outlet has already been instantiated
|
|
2726
|
+
// Otherwise attach from `RouterOutlet.ngOnInit` when it is instantiated
|
|
2727
|
+
context.outlet.attach(stored.componentRef, stored.route.value);
|
|
2728
|
+
}
|
|
2729
|
+
advanceActivatedRoute(stored.route.value);
|
|
2730
|
+
this.activateChildRoutes(futureNode, null, context.children);
|
|
2731
|
+
}
|
|
2732
|
+
else {
|
|
2733
|
+
const injector = getClosestRouteInjector(future.snapshot);
|
|
2734
|
+
const cmpFactoryResolver = (_a = injector === null || injector === void 0 ? void 0 : injector.get(ComponentFactoryResolver)) !== null && _a !== void 0 ? _a : null;
|
|
2735
|
+
context.attachRef = null;
|
|
2736
|
+
context.route = future;
|
|
2737
|
+
context.resolver = cmpFactoryResolver;
|
|
2738
|
+
context.injector = injector;
|
|
2739
|
+
if (context.outlet) {
|
|
2740
|
+
// Activate the outlet when it has already been instantiated
|
|
2741
|
+
// Otherwise it will get activated from its `ngOnInit` when instantiated
|
|
2742
|
+
context.outlet.activateWith(future, context.injector);
|
|
2743
|
+
}
|
|
2744
|
+
this.activateChildRoutes(futureNode, null, context.children);
|
|
2745
|
+
}
|
|
2746
|
+
}
|
|
2747
|
+
else {
|
|
2748
|
+
// if we have a componentless route, we recurse but keep the same outlet map.
|
|
2749
|
+
this.activateChildRoutes(futureNode, null, parentContexts);
|
|
2750
|
+
}
|
|
2751
|
+
}
|
|
2566
2752
|
}
|
|
2567
2753
|
}
|
|
2568
2754
|
|
|
@@ -2574,22 +2760,39 @@ class OutletInjector {
|
|
|
2574
2760
|
* found in the LICENSE file at https://angular.io/license
|
|
2575
2761
|
*/
|
|
2576
2762
|
/**
|
|
2577
|
-
*
|
|
2578
|
-
* router-outlet is needed. For example, with a config such as:
|
|
2763
|
+
* Simple function check, but generic so type inference will flow. Example:
|
|
2579
2764
|
*
|
|
2580
|
-
*
|
|
2765
|
+
* function product(a: number, b: number) {
|
|
2766
|
+
* return a * b;
|
|
2767
|
+
* }
|
|
2581
2768
|
*
|
|
2582
|
-
*
|
|
2583
|
-
*
|
|
2769
|
+
* if (isFunction<product>(fn)) {
|
|
2770
|
+
* return fn(1, 2);
|
|
2771
|
+
* } else {
|
|
2772
|
+
* throw "Must provide the `product` function";
|
|
2773
|
+
* }
|
|
2584
2774
|
*/
|
|
2585
|
-
|
|
2775
|
+
function isFunction(v) {
|
|
2776
|
+
return typeof v === 'function';
|
|
2777
|
+
}
|
|
2778
|
+
function isBoolean(v) {
|
|
2779
|
+
return typeof v === 'boolean';
|
|
2780
|
+
}
|
|
2781
|
+
function isUrlTree(v) {
|
|
2782
|
+
return v instanceof UrlTree;
|
|
2783
|
+
}
|
|
2784
|
+
function isCanLoad(guard) {
|
|
2785
|
+
return guard && isFunction(guard.canLoad);
|
|
2786
|
+
}
|
|
2787
|
+
function isCanActivate(guard) {
|
|
2788
|
+
return guard && isFunction(guard.canActivate);
|
|
2789
|
+
}
|
|
2790
|
+
function isCanActivateChild(guard) {
|
|
2791
|
+
return guard && isFunction(guard.canActivateChild);
|
|
2792
|
+
}
|
|
2793
|
+
function isCanDeactivate(guard) {
|
|
2794
|
+
return guard && isFunction(guard.canDeactivate);
|
|
2586
2795
|
}
|
|
2587
|
-
ɵEmptyOutletComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.0-next.9", ngImport: i0, type: ɵEmptyOutletComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2588
|
-
ɵEmptyOutletComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "14.0.0-next.9", 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"] }] });
|
|
2589
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.0-next.9", ngImport: i0, type: ɵEmptyOutletComponent, decorators: [{
|
|
2590
|
-
type: Component,
|
|
2591
|
-
args: [{ template: `<router-outlet></router-outlet>` }]
|
|
2592
|
-
}] });
|
|
2593
2796
|
|
|
2594
2797
|
/**
|
|
2595
2798
|
* @license
|
|
@@ -2598,113 +2801,36 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.0-next.9",
|
|
|
2598
2801
|
* Use of this source code is governed by an MIT-style license that can be
|
|
2599
2802
|
* found in the LICENSE file at https://angular.io/license
|
|
2600
2803
|
*/
|
|
2601
|
-
|
|
2602
|
-
|
|
2603
|
-
|
|
2604
|
-
|
|
2605
|
-
|
|
2606
|
-
|
|
2607
|
-
|
|
2608
|
-
|
|
2609
|
-
|
|
2610
|
-
|
|
2611
|
-
|
|
2612
|
-
|
|
2613
|
-
|
|
2614
|
-
|
|
2615
|
-
|
|
2616
|
-
|
|
2617
|
-
|
|
2618
|
-
|
|
2619
|
-
|
|
2620
|
-
|
|
2621
|
-
|
|
2622
|
-
|
|
2623
|
-
|
|
2624
|
-
|
|
2625
|
-
|
|
2626
|
-
|
|
2627
|
-
|
|
2628
|
-
|
|
2629
|
-
|
|
2630
|
-
|
|
2631
|
-
if (route.redirectTo && route.children) {
|
|
2632
|
-
throw new Error(`Invalid configuration of route '${fullPath}': redirectTo and children cannot be used together`);
|
|
2633
|
-
}
|
|
2634
|
-
if (route.redirectTo && route.loadChildren) {
|
|
2635
|
-
throw new Error(`Invalid configuration of route '${fullPath}': redirectTo and loadChildren cannot be used together`);
|
|
2636
|
-
}
|
|
2637
|
-
if (route.children && route.loadChildren) {
|
|
2638
|
-
throw new Error(`Invalid configuration of route '${fullPath}': children and loadChildren cannot be used together`);
|
|
2639
|
-
}
|
|
2640
|
-
if (route.redirectTo && route.component) {
|
|
2641
|
-
throw new Error(`Invalid configuration of route '${fullPath}': redirectTo and component cannot be used together`);
|
|
2642
|
-
}
|
|
2643
|
-
if (route.redirectTo && route.canActivate) {
|
|
2644
|
-
throw new Error(`Invalid configuration of route '${fullPath}': redirectTo and canActivate cannot be used together. Redirects happen before activation ` +
|
|
2645
|
-
`so canActivate will never be executed.`);
|
|
2646
|
-
}
|
|
2647
|
-
if (route.path && route.matcher) {
|
|
2648
|
-
throw new Error(`Invalid configuration of route '${fullPath}': path and matcher cannot be used together`);
|
|
2649
|
-
}
|
|
2650
|
-
if (route.redirectTo === void 0 && !route.component && !route.children && !route.loadChildren) {
|
|
2651
|
-
throw new Error(`Invalid configuration of route '${fullPath}'. One of the following must be provided: component, redirectTo, children or loadChildren`);
|
|
2652
|
-
}
|
|
2653
|
-
if (route.path === void 0 && route.matcher === void 0) {
|
|
2654
|
-
throw new Error(`Invalid configuration of route '${fullPath}': routes must have either a path or a matcher specified`);
|
|
2655
|
-
}
|
|
2656
|
-
if (typeof route.path === 'string' && route.path.charAt(0) === '/') {
|
|
2657
|
-
throw new Error(`Invalid configuration of route '${fullPath}': path cannot start with a slash`);
|
|
2658
|
-
}
|
|
2659
|
-
if (route.path === '' && route.redirectTo !== void 0 && route.pathMatch === void 0) {
|
|
2660
|
-
const exp = `The default value of 'pathMatch' is 'prefix', but often the intent is to use 'full'.`;
|
|
2661
|
-
throw new Error(`Invalid configuration of route '{path: "${fullPath}", redirectTo: "${route.redirectTo}"}': please provide 'pathMatch'. ${exp}`);
|
|
2662
|
-
}
|
|
2663
|
-
}
|
|
2664
|
-
if (route.children) {
|
|
2665
|
-
validateConfig(route.children, fullPath);
|
|
2666
|
-
}
|
|
2667
|
-
}
|
|
2668
|
-
function getFullPath(parentPath, currentRoute) {
|
|
2669
|
-
if (!currentRoute) {
|
|
2670
|
-
return parentPath;
|
|
2671
|
-
}
|
|
2672
|
-
if (!parentPath && !currentRoute.path) {
|
|
2673
|
-
return '';
|
|
2674
|
-
}
|
|
2675
|
-
else if (parentPath && !currentRoute.path) {
|
|
2676
|
-
return `${parentPath}/`;
|
|
2677
|
-
}
|
|
2678
|
-
else if (!parentPath && currentRoute.path) {
|
|
2679
|
-
return currentRoute.path;
|
|
2680
|
-
}
|
|
2681
|
-
else {
|
|
2682
|
-
return `${parentPath}/${currentRoute.path}`;
|
|
2683
|
-
}
|
|
2684
|
-
}
|
|
2685
|
-
/**
|
|
2686
|
-
* Makes a copy of the config and adds any default required properties.
|
|
2687
|
-
*/
|
|
2688
|
-
function standardizeConfig(r) {
|
|
2689
|
-
const children = r.children && r.children.map(standardizeConfig);
|
|
2690
|
-
const c = children ? Object.assign(Object.assign({}, r), { children }) : Object.assign({}, r);
|
|
2691
|
-
if (!c.component && (children || c.loadChildren) && (c.outlet && c.outlet !== PRIMARY_OUTLET)) {
|
|
2692
|
-
c.component = ɵEmptyOutletComponent;
|
|
2693
|
-
}
|
|
2694
|
-
return c;
|
|
2695
|
-
}
|
|
2696
|
-
/** Returns the `route.outlet` or PRIMARY_OUTLET if none exists. */
|
|
2697
|
-
function getOutlet(route) {
|
|
2698
|
-
return route.outlet || PRIMARY_OUTLET;
|
|
2699
|
-
}
|
|
2700
|
-
/**
|
|
2701
|
-
* Sorts the `routes` such that the ones with an outlet matching `outletName` come first.
|
|
2702
|
-
* The order of the configs is otherwise preserved.
|
|
2703
|
-
*/
|
|
2704
|
-
function sortByMatchingOutlets(routes, outletName) {
|
|
2705
|
-
const sortedConfig = routes.filter(r => getOutlet(r) === outletName);
|
|
2706
|
-
sortedConfig.push(...routes.filter(r => getOutlet(r) !== outletName));
|
|
2707
|
-
return sortedConfig;
|
|
2804
|
+
const INITIAL_VALUE = Symbol('INITIAL_VALUE');
|
|
2805
|
+
function prioritizedGuardValue() {
|
|
2806
|
+
return switchMap(obs => {
|
|
2807
|
+
return combineLatest(obs.map(o => o.pipe(take(1), startWith(INITIAL_VALUE))))
|
|
2808
|
+
.pipe(scan((acc, list) => {
|
|
2809
|
+
let isPending = false;
|
|
2810
|
+
return list.reduce((innerAcc, val, i) => {
|
|
2811
|
+
if (innerAcc !== INITIAL_VALUE)
|
|
2812
|
+
return innerAcc;
|
|
2813
|
+
// Toggle pending flag if any values haven't been set yet
|
|
2814
|
+
if (val === INITIAL_VALUE)
|
|
2815
|
+
isPending = true;
|
|
2816
|
+
// Any other return values are only valid if we haven't yet hit a pending
|
|
2817
|
+
// call. This guarantees that in the case of a guard at the bottom of the
|
|
2818
|
+
// tree that returns a redirect, we will wait for the higher priority
|
|
2819
|
+
// guard at the top to finish before performing the redirect.
|
|
2820
|
+
if (!isPending) {
|
|
2821
|
+
// Early return when we hit a `false` value as that should always
|
|
2822
|
+
// cancel navigation
|
|
2823
|
+
if (val === false)
|
|
2824
|
+
return val;
|
|
2825
|
+
if (i === list.length - 1 || isUrlTree(val)) {
|
|
2826
|
+
return val;
|
|
2827
|
+
}
|
|
2828
|
+
}
|
|
2829
|
+
return innerAcc;
|
|
2830
|
+
}, acc);
|
|
2831
|
+
}, INITIAL_VALUE), filter(item => item !== INITIAL_VALUE), map(item => isUrlTree(item) ? item : item === true), //
|
|
2832
|
+
take(1));
|
|
2833
|
+
});
|
|
2708
2834
|
}
|
|
2709
2835
|
|
|
2710
2836
|
/**
|
|
@@ -2782,6 +2908,9 @@ function addEmptyPathsToChildrenIfNeeded(segmentGroup, consumedSegments, slicedS
|
|
|
2782
2908
|
s._sourceSegment = segmentGroup;
|
|
2783
2909
|
if (relativeLinkResolution === 'legacy') {
|
|
2784
2910
|
s._segmentIndexShift = segmentGroup.segments.length;
|
|
2911
|
+
if (typeof ngDevMode === 'undefined' || !!ngDevMode) {
|
|
2912
|
+
s._segmentIndexShiftCorrected = consumedSegments.length;
|
|
2913
|
+
}
|
|
2785
2914
|
}
|
|
2786
2915
|
else {
|
|
2787
2916
|
s._segmentIndexShift = consumedSegments.length;
|
|
@@ -2882,17 +3011,17 @@ function canLoadFails(route) {
|
|
|
2882
3011
|
*
|
|
2883
3012
|
* Lazy modules are loaded along the way.
|
|
2884
3013
|
*/
|
|
2885
|
-
function applyRedirects$1(
|
|
2886
|
-
return new ApplyRedirects(
|
|
3014
|
+
function applyRedirects$1(injector, configLoader, urlSerializer, urlTree, config) {
|
|
3015
|
+
return new ApplyRedirects(injector, configLoader, urlSerializer, urlTree, config).apply();
|
|
2887
3016
|
}
|
|
2888
3017
|
class ApplyRedirects {
|
|
2889
|
-
constructor(
|
|
3018
|
+
constructor(injector, configLoader, urlSerializer, urlTree, config) {
|
|
3019
|
+
this.injector = injector;
|
|
2890
3020
|
this.configLoader = configLoader;
|
|
2891
3021
|
this.urlSerializer = urlSerializer;
|
|
2892
3022
|
this.urlTree = urlTree;
|
|
2893
3023
|
this.config = config;
|
|
2894
3024
|
this.allowRedirects = true;
|
|
2895
|
-
this.ngModule = moduleInjector.get(NgModuleRef);
|
|
2896
3025
|
}
|
|
2897
3026
|
apply() {
|
|
2898
3027
|
const splitGroup = split(this.urlTree.root, [], [], this.config).segmentGroup;
|
|
@@ -2903,7 +3032,7 @@ class ApplyRedirects {
|
|
|
2903
3032
|
// them. We should be able to remove this logic as a "breaking change" but should do some more
|
|
2904
3033
|
// investigation into the failures first.
|
|
2905
3034
|
const rootSegmentGroup = new UrlSegmentGroup(splitGroup.segments, splitGroup.children);
|
|
2906
|
-
const expanded$ = this.expandSegmentGroup(this.
|
|
3035
|
+
const expanded$ = this.expandSegmentGroup(this.injector, this.config, rootSegmentGroup, PRIMARY_OUTLET);
|
|
2907
3036
|
const urlTrees$ = expanded$.pipe(map((rootSegmentGroup) => {
|
|
2908
3037
|
return this.createUrlTree(squashSegmentGroup(rootSegmentGroup), this.urlTree.queryParams, this.urlTree.fragment);
|
|
2909
3038
|
}));
|
|
@@ -2922,7 +3051,7 @@ class ApplyRedirects {
|
|
|
2922
3051
|
}));
|
|
2923
3052
|
}
|
|
2924
3053
|
match(tree) {
|
|
2925
|
-
const expanded$ = this.expandSegmentGroup(this.
|
|
3054
|
+
const expanded$ = this.expandSegmentGroup(this.injector, this.config, tree.root, PRIMARY_OUTLET);
|
|
2926
3055
|
const mapped$ = expanded$.pipe(map((rootSegmentGroup) => {
|
|
2927
3056
|
return this.createUrlTree(squashSegmentGroup(rootSegmentGroup), tree.queryParams, tree.fragment);
|
|
2928
3057
|
}));
|
|
@@ -2942,15 +3071,15 @@ class ApplyRedirects {
|
|
|
2942
3071
|
rootCandidate;
|
|
2943
3072
|
return new UrlTree(root, queryParams, fragment);
|
|
2944
3073
|
}
|
|
2945
|
-
expandSegmentGroup(
|
|
3074
|
+
expandSegmentGroup(injector, routes, segmentGroup, outlet) {
|
|
2946
3075
|
if (segmentGroup.segments.length === 0 && segmentGroup.hasChildren()) {
|
|
2947
|
-
return this.expandChildren(
|
|
3076
|
+
return this.expandChildren(injector, routes, segmentGroup)
|
|
2948
3077
|
.pipe(map((children) => new UrlSegmentGroup([], children)));
|
|
2949
3078
|
}
|
|
2950
|
-
return this.expandSegment(
|
|
3079
|
+
return this.expandSegment(injector, segmentGroup, routes, segmentGroup.segments, outlet, true);
|
|
2951
3080
|
}
|
|
2952
3081
|
// Recursively expand segment groups for all the child outlets
|
|
2953
|
-
expandChildren(
|
|
3082
|
+
expandChildren(injector, routes, segmentGroup) {
|
|
2954
3083
|
// Expand outlets one at a time, starting with the primary outlet. We need to do it this way
|
|
2955
3084
|
// because an absolute redirect from the primary outlet takes precedence.
|
|
2956
3085
|
const childOutlets = [];
|
|
@@ -2969,16 +3098,26 @@ class ApplyRedirects {
|
|
|
2969
3098
|
// first, followed by routes for other outlets, which might match if they have an
|
|
2970
3099
|
// empty path.
|
|
2971
3100
|
const sortedRoutes = sortByMatchingOutlets(routes, childOutlet);
|
|
2972
|
-
return this.expandSegmentGroup(
|
|
3101
|
+
return this.expandSegmentGroup(injector, sortedRoutes, child, childOutlet)
|
|
2973
3102
|
.pipe(map(s => ({ segment: s, outlet: childOutlet })));
|
|
2974
3103
|
}), scan((children, expandedChild) => {
|
|
2975
3104
|
children[expandedChild.outlet] = expandedChild.segment;
|
|
2976
3105
|
return children;
|
|
2977
3106
|
}, {}), last$1());
|
|
2978
3107
|
}
|
|
2979
|
-
expandSegment(
|
|
2980
|
-
return from(routes).pipe(concatMap(
|
|
2981
|
-
|
|
3108
|
+
expandSegment(injector, segmentGroup, routes, segments, outlet, allowRedirects) {
|
|
3109
|
+
return from(routes).pipe(concatMap(r => {
|
|
3110
|
+
var _a;
|
|
3111
|
+
if (r.providers && !r._injector) {
|
|
3112
|
+
r._injector = createEnvironmentInjector(r.providers, injector, `Route: ${r.path}`);
|
|
3113
|
+
}
|
|
3114
|
+
// We specifically _do not_ want to include the _loadedInjector here. The loaded injector
|
|
3115
|
+
// only applies to the route's children, not the route itself. Note that this distinction
|
|
3116
|
+
// only applies here to any tokens we try to retrieve during this phase. At the moment,
|
|
3117
|
+
// that only includes `canLoad`, which won't run again once the child module is loaded. As
|
|
3118
|
+
// a result, this makes no difference right now, but could in the future if there are more
|
|
3119
|
+
// actions here that need DI (for example, a canMatch guard).
|
|
3120
|
+
const expanded$ = this.expandSegmentAgainstRoute((_a = r._injector) !== null && _a !== void 0 ? _a : injector, segmentGroup, routes, r, segments, outlet, allowRedirects);
|
|
2982
3121
|
return expanded$.pipe(catchError((e) => {
|
|
2983
3122
|
if (e instanceof NoMatch$1) {
|
|
2984
3123
|
return of(null);
|
|
@@ -2995,35 +3134,35 @@ class ApplyRedirects {
|
|
|
2995
3134
|
throw e;
|
|
2996
3135
|
}));
|
|
2997
3136
|
}
|
|
2998
|
-
expandSegmentAgainstRoute(
|
|
3137
|
+
expandSegmentAgainstRoute(injector, segmentGroup, routes, route, paths, outlet, allowRedirects) {
|
|
2999
3138
|
if (!isImmediateMatch(route, segmentGroup, paths, outlet)) {
|
|
3000
3139
|
return noMatch(segmentGroup);
|
|
3001
3140
|
}
|
|
3002
3141
|
if (route.redirectTo === undefined) {
|
|
3003
|
-
return this.matchSegmentAgainstRoute(
|
|
3142
|
+
return this.matchSegmentAgainstRoute(injector, segmentGroup, route, paths, outlet);
|
|
3004
3143
|
}
|
|
3005
3144
|
if (allowRedirects && this.allowRedirects) {
|
|
3006
|
-
return this.expandSegmentAgainstRouteUsingRedirect(
|
|
3145
|
+
return this.expandSegmentAgainstRouteUsingRedirect(injector, segmentGroup, routes, route, paths, outlet);
|
|
3007
3146
|
}
|
|
3008
3147
|
return noMatch(segmentGroup);
|
|
3009
3148
|
}
|
|
3010
|
-
expandSegmentAgainstRouteUsingRedirect(
|
|
3149
|
+
expandSegmentAgainstRouteUsingRedirect(injector, segmentGroup, routes, route, segments, outlet) {
|
|
3011
3150
|
if (route.path === '**') {
|
|
3012
|
-
return this.expandWildCardWithParamsAgainstRouteUsingRedirect(
|
|
3151
|
+
return this.expandWildCardWithParamsAgainstRouteUsingRedirect(injector, routes, route, outlet);
|
|
3013
3152
|
}
|
|
3014
|
-
return this.expandRegularSegmentAgainstRouteUsingRedirect(
|
|
3153
|
+
return this.expandRegularSegmentAgainstRouteUsingRedirect(injector, segmentGroup, routes, route, segments, outlet);
|
|
3015
3154
|
}
|
|
3016
|
-
expandWildCardWithParamsAgainstRouteUsingRedirect(
|
|
3155
|
+
expandWildCardWithParamsAgainstRouteUsingRedirect(injector, routes, route, outlet) {
|
|
3017
3156
|
const newTree = this.applyRedirectCommands([], route.redirectTo, {});
|
|
3018
3157
|
if (route.redirectTo.startsWith('/')) {
|
|
3019
3158
|
return absoluteRedirect(newTree);
|
|
3020
3159
|
}
|
|
3021
3160
|
return this.lineralizeSegments(route, newTree).pipe(mergeMap((newSegments) => {
|
|
3022
3161
|
const group = new UrlSegmentGroup(newSegments, {});
|
|
3023
|
-
return this.expandSegment(
|
|
3162
|
+
return this.expandSegment(injector, group, routes, newSegments, outlet, false);
|
|
3024
3163
|
}));
|
|
3025
3164
|
}
|
|
3026
|
-
expandRegularSegmentAgainstRouteUsingRedirect(
|
|
3165
|
+
expandRegularSegmentAgainstRouteUsingRedirect(injector, segmentGroup, routes, route, segments, outlet) {
|
|
3027
3166
|
const { matched, consumedSegments, remainingSegments, positionalParamSegments } = match(segmentGroup, route, segments);
|
|
3028
3167
|
if (!matched)
|
|
3029
3168
|
return noMatch(segmentGroup);
|
|
@@ -3032,16 +3171,18 @@ class ApplyRedirects {
|
|
|
3032
3171
|
return absoluteRedirect(newTree);
|
|
3033
3172
|
}
|
|
3034
3173
|
return this.lineralizeSegments(route, newTree).pipe(mergeMap((newSegments) => {
|
|
3035
|
-
return this.expandSegment(
|
|
3174
|
+
return this.expandSegment(injector, segmentGroup, routes, newSegments.concat(remainingSegments), outlet, false);
|
|
3036
3175
|
}));
|
|
3037
3176
|
}
|
|
3038
|
-
matchSegmentAgainstRoute(
|
|
3177
|
+
matchSegmentAgainstRoute(injector, rawSegmentGroup, route, segments, outlet) {
|
|
3039
3178
|
if (route.path === '**') {
|
|
3040
3179
|
if (route.loadChildren) {
|
|
3041
|
-
const loaded$ = route.
|
|
3042
|
-
|
|
3180
|
+
const loaded$ = route._loadedRoutes ?
|
|
3181
|
+
of({ routes: route._loadedRoutes, injector: route._loadedInjector }) :
|
|
3182
|
+
this.configLoader.loadChildren(injector, route);
|
|
3043
3183
|
return loaded$.pipe(map((cfg) => {
|
|
3044
|
-
route.
|
|
3184
|
+
route._loadedRoutes = cfg.routes;
|
|
3185
|
+
route._loadedInjector = cfg.injector;
|
|
3045
3186
|
return new UrlSegmentGroup(segments, {});
|
|
3046
3187
|
}));
|
|
3047
3188
|
}
|
|
@@ -3050,55 +3191,56 @@ class ApplyRedirects {
|
|
|
3050
3191
|
const { matched, consumedSegments, remainingSegments } = match(rawSegmentGroup, route, segments);
|
|
3051
3192
|
if (!matched)
|
|
3052
3193
|
return noMatch(rawSegmentGroup);
|
|
3053
|
-
const childConfig$ = this.getChildConfig(
|
|
3194
|
+
const childConfig$ = this.getChildConfig(injector, route, segments);
|
|
3054
3195
|
return childConfig$.pipe(mergeMap((routerConfig) => {
|
|
3055
|
-
|
|
3196
|
+
var _a;
|
|
3197
|
+
const childInjector = (_a = routerConfig.injector) !== null && _a !== void 0 ? _a : injector;
|
|
3056
3198
|
const childConfig = routerConfig.routes;
|
|
3057
3199
|
const { segmentGroup: splitSegmentGroup, slicedSegments } = split(rawSegmentGroup, consumedSegments, remainingSegments, childConfig);
|
|
3058
3200
|
// See comment on the other call to `split` about why this is necessary.
|
|
3059
3201
|
const segmentGroup = new UrlSegmentGroup(splitSegmentGroup.segments, splitSegmentGroup.children);
|
|
3060
3202
|
if (slicedSegments.length === 0 && segmentGroup.hasChildren()) {
|
|
3061
|
-
const expanded$ = this.expandChildren(
|
|
3203
|
+
const expanded$ = this.expandChildren(childInjector, childConfig, segmentGroup);
|
|
3062
3204
|
return expanded$.pipe(map((children) => new UrlSegmentGroup(consumedSegments, children)));
|
|
3063
3205
|
}
|
|
3064
3206
|
if (childConfig.length === 0 && slicedSegments.length === 0) {
|
|
3065
3207
|
return of(new UrlSegmentGroup(consumedSegments, {}));
|
|
3066
3208
|
}
|
|
3067
3209
|
const matchedOnOutlet = getOutlet(route) === outlet;
|
|
3068
|
-
const expanded$ = this.expandSegment(
|
|
3210
|
+
const expanded$ = this.expandSegment(childInjector, segmentGroup, childConfig, slicedSegments, matchedOnOutlet ? PRIMARY_OUTLET : outlet, true);
|
|
3069
3211
|
return expanded$.pipe(map((cs) => new UrlSegmentGroup(consumedSegments.concat(cs.segments), cs.children)));
|
|
3070
3212
|
}));
|
|
3071
3213
|
}
|
|
3072
|
-
getChildConfig(
|
|
3214
|
+
getChildConfig(injector, route, segments) {
|
|
3073
3215
|
if (route.children) {
|
|
3074
3216
|
// The children belong to the same module
|
|
3075
|
-
return of(
|
|
3217
|
+
return of({ routes: route.children, injector });
|
|
3076
3218
|
}
|
|
3077
3219
|
if (route.loadChildren) {
|
|
3078
3220
|
// lazy children belong to the loaded module
|
|
3079
|
-
if (route.
|
|
3080
|
-
return of(route.
|
|
3221
|
+
if (route._loadedRoutes !== undefined) {
|
|
3222
|
+
return of({ routes: route._loadedRoutes, injector: route._loadedInjector });
|
|
3081
3223
|
}
|
|
3082
|
-
return this.runCanLoadGuards(
|
|
3224
|
+
return this.runCanLoadGuards(injector, route, segments)
|
|
3083
3225
|
.pipe(mergeMap((shouldLoadResult) => {
|
|
3084
3226
|
if (shouldLoadResult) {
|
|
3085
|
-
return this.configLoader.
|
|
3086
|
-
.pipe(
|
|
3087
|
-
route.
|
|
3088
|
-
|
|
3227
|
+
return this.configLoader.loadChildren(injector, route)
|
|
3228
|
+
.pipe(tap((cfg) => {
|
|
3229
|
+
route._loadedRoutes = cfg.routes;
|
|
3230
|
+
route._loadedInjector = cfg.injector;
|
|
3089
3231
|
}));
|
|
3090
3232
|
}
|
|
3091
3233
|
return canLoadFails(route);
|
|
3092
3234
|
}));
|
|
3093
3235
|
}
|
|
3094
|
-
return of(
|
|
3236
|
+
return of({ routes: [], injector });
|
|
3095
3237
|
}
|
|
3096
|
-
runCanLoadGuards(
|
|
3238
|
+
runCanLoadGuards(injector, route, segments) {
|
|
3097
3239
|
const canLoad = route.canLoad;
|
|
3098
3240
|
if (!canLoad || canLoad.length === 0)
|
|
3099
3241
|
return of(true);
|
|
3100
3242
|
const canLoadObservables = canLoad.map((injectionToken) => {
|
|
3101
|
-
const guard =
|
|
3243
|
+
const guard = injector.get(injectionToken);
|
|
3102
3244
|
let guardVal;
|
|
3103
3245
|
if (isCanLoad(guard)) {
|
|
3104
3246
|
guardVal = guard.canLoad(route, segments);
|
|
@@ -3226,8 +3368,8 @@ function squashSegmentGroup(segmentGroup) {
|
|
|
3226
3368
|
* Use of this source code is governed by an MIT-style license that can be
|
|
3227
3369
|
* found in the LICENSE file at https://angular.io/license
|
|
3228
3370
|
*/
|
|
3229
|
-
function applyRedirects(
|
|
3230
|
-
return switchMap(t => applyRedirects$1(
|
|
3371
|
+
function applyRedirects(environmentInjector, configLoader, urlSerializer, config) {
|
|
3372
|
+
return switchMap(t => applyRedirects$1(environmentInjector, configLoader, urlSerializer, t.extractedUrl, config)
|
|
3231
3373
|
.pipe(map(urlAfterRedirects => (Object.assign(Object.assign({}, t), { urlAfterRedirects })))));
|
|
3232
3374
|
}
|
|
3233
3375
|
|
|
@@ -3261,21 +3403,11 @@ function getCanActivateChild(p) {
|
|
|
3261
3403
|
return null;
|
|
3262
3404
|
return { node: p, guards: canActivateChild };
|
|
3263
3405
|
}
|
|
3264
|
-
function getToken(token, snapshot,
|
|
3265
|
-
const
|
|
3266
|
-
const injector =
|
|
3406
|
+
function getToken(token, snapshot, fallbackInjector) {
|
|
3407
|
+
const routeInjector = getClosestRouteInjector(snapshot);
|
|
3408
|
+
const injector = routeInjector !== null && routeInjector !== void 0 ? routeInjector : fallbackInjector;
|
|
3267
3409
|
return injector.get(token);
|
|
3268
3410
|
}
|
|
3269
|
-
function getClosestLoadedConfig(snapshot) {
|
|
3270
|
-
if (!snapshot)
|
|
3271
|
-
return null;
|
|
3272
|
-
for (let s = snapshot.parent; s; s = s.parent) {
|
|
3273
|
-
const route = s.routeConfig;
|
|
3274
|
-
if (route && route._loadedConfig)
|
|
3275
|
-
return route._loadedConfig;
|
|
3276
|
-
}
|
|
3277
|
-
return null;
|
|
3278
|
-
}
|
|
3279
3411
|
function getChildRouteGuards(futureNode, currNode, contexts, futurePath, checks = {
|
|
3280
3412
|
canDeactivateChecks: [],
|
|
3281
3413
|
canActivateChecks: []
|
|
@@ -3519,6 +3651,7 @@ function runCanDeactivate(component, currARS, currRSS, futureRSS, moduleInjector
|
|
|
3519
3651
|
* Use of this source code is governed by an MIT-style license that can be
|
|
3520
3652
|
* found in the LICENSE file at https://angular.io/license
|
|
3521
3653
|
*/
|
|
3654
|
+
const NG_DEV_MODE$2 = typeof ngDevMode === 'undefined' || !!ngDevMode;
|
|
3522
3655
|
class NoMatch {
|
|
3523
3656
|
}
|
|
3524
3657
|
function newObservableError(e) {
|
|
@@ -3627,6 +3760,7 @@ class Recognizer {
|
|
|
3627
3760
|
return null;
|
|
3628
3761
|
}
|
|
3629
3762
|
processSegmentAgainstRoute(route, rawSegment, segments, outlet) {
|
|
3763
|
+
var _a, _b, _c, _d;
|
|
3630
3764
|
if (route.redirectTo || !isImmediateMatch(route, rawSegment, segments, outlet))
|
|
3631
3765
|
return null;
|
|
3632
3766
|
let snapshot;
|
|
@@ -3634,7 +3768,13 @@ class Recognizer {
|
|
|
3634
3768
|
let remainingSegments = [];
|
|
3635
3769
|
if (route.path === '**') {
|
|
3636
3770
|
const params = segments.length > 0 ? last(segments).parameters : {};
|
|
3637
|
-
|
|
3771
|
+
const pathIndexShift = getPathIndexShift(rawSegment) + segments.length;
|
|
3772
|
+
snapshot = new ActivatedRouteSnapshot(segments, params, Object.freeze(Object.assign({}, this.urlTree.queryParams)), this.urlTree.fragment, getData(route), getOutlet(route), (_b = (_a = route.component) !== null && _a !== void 0 ? _a : route._loadedComponent) !== null && _b !== void 0 ? _b : null, route, getSourceSegmentGroup(rawSegment), pathIndexShift, getResolve(route),
|
|
3773
|
+
// NG_DEV_MODE is used to prevent the getCorrectedPathIndexShift function from affecting
|
|
3774
|
+
// production bundle size. This value is intended only to surface a warning to users
|
|
3775
|
+
// depending on `relativeLinkResolution: 'legacy'` in dev mode.
|
|
3776
|
+
(NG_DEV_MODE$2 ? getCorrectedPathIndexShift(rawSegment) + segments.length :
|
|
3777
|
+
pathIndexShift));
|
|
3638
3778
|
}
|
|
3639
3779
|
else {
|
|
3640
3780
|
const result = match(rawSegment, route, segments);
|
|
@@ -3643,7 +3783,9 @@ class Recognizer {
|
|
|
3643
3783
|
}
|
|
3644
3784
|
consumedSegments = result.consumedSegments;
|
|
3645
3785
|
remainingSegments = result.remainingSegments;
|
|
3646
|
-
|
|
3786
|
+
const pathIndexShift = getPathIndexShift(rawSegment) + consumedSegments.length;
|
|
3787
|
+
snapshot = new ActivatedRouteSnapshot(consumedSegments, result.parameters, Object.freeze(Object.assign({}, this.urlTree.queryParams)), this.urlTree.fragment, getData(route), getOutlet(route), (_d = (_c = route.component) !== null && _c !== void 0 ? _c : route._loadedComponent) !== null && _d !== void 0 ? _d : null, route, getSourceSegmentGroup(rawSegment), pathIndexShift, getResolve(route), (NG_DEV_MODE$2 ? getCorrectedPathIndexShift(rawSegment) + consumedSegments.length :
|
|
3788
|
+
pathIndexShift));
|
|
3647
3789
|
}
|
|
3648
3790
|
const childConfig = getChildConfig(route);
|
|
3649
3791
|
const { segmentGroup, slicedSegments } = split(rawSegment, consumedSegments, remainingSegments,
|
|
@@ -3691,7 +3833,7 @@ function getChildConfig(route) {
|
|
|
3691
3833
|
return route.children;
|
|
3692
3834
|
}
|
|
3693
3835
|
if (route.loadChildren) {
|
|
3694
|
-
return route.
|
|
3836
|
+
return route._loadedRoutes;
|
|
3695
3837
|
}
|
|
3696
3838
|
return [];
|
|
3697
3839
|
}
|
|
@@ -3752,11 +3894,22 @@ function getSourceSegmentGroup(segmentGroup) {
|
|
|
3752
3894
|
return s;
|
|
3753
3895
|
}
|
|
3754
3896
|
function getPathIndexShift(segmentGroup) {
|
|
3897
|
+
var _a, _b;
|
|
3898
|
+
let s = segmentGroup;
|
|
3899
|
+
let res = (_a = s._segmentIndexShift) !== null && _a !== void 0 ? _a : 0;
|
|
3900
|
+
while (s._sourceSegment) {
|
|
3901
|
+
s = s._sourceSegment;
|
|
3902
|
+
res += (_b = s._segmentIndexShift) !== null && _b !== void 0 ? _b : 0;
|
|
3903
|
+
}
|
|
3904
|
+
return res - 1;
|
|
3905
|
+
}
|
|
3906
|
+
function getCorrectedPathIndexShift(segmentGroup) {
|
|
3907
|
+
var _a, _b, _c, _d;
|
|
3755
3908
|
let s = segmentGroup;
|
|
3756
|
-
let res = (s.
|
|
3909
|
+
let res = (_b = (_a = s._segmentIndexShiftCorrected) !== null && _a !== void 0 ? _a : s._segmentIndexShift) !== null && _b !== void 0 ? _b : 0;
|
|
3757
3910
|
while (s._sourceSegment) {
|
|
3758
3911
|
s = s._sourceSegment;
|
|
3759
|
-
res += (s.
|
|
3912
|
+
res += (_d = (_c = s._segmentIndexShiftCorrected) !== null && _c !== void 0 ? _c : s._segmentIndexShift) !== null && _d !== void 0 ? _d : 0;
|
|
3760
3913
|
}
|
|
3761
3914
|
return res - 1;
|
|
3762
3915
|
}
|
|
@@ -3806,19 +3959,16 @@ function resolveData(paramsInheritanceStrategy, moduleInjector) {
|
|
|
3806
3959
|
function runResolve(futureARS, futureRSS, paramsInheritanceStrategy, moduleInjector) {
|
|
3807
3960
|
const config = futureARS.routeConfig;
|
|
3808
3961
|
const resolve = futureARS._resolve;
|
|
3809
|
-
|
|
3810
|
-
|
|
3811
|
-
if (typeof config.title === 'string' || config.title === null) {
|
|
3812
|
-
data[RouteTitle] = config.title;
|
|
3813
|
-
}
|
|
3814
|
-
else {
|
|
3815
|
-
resolve[RouteTitle] = config.title;
|
|
3816
|
-
}
|
|
3962
|
+
if ((config === null || config === void 0 ? void 0 : config.title) !== undefined && !hasStaticTitle(config)) {
|
|
3963
|
+
resolve[RouteTitle] = config.title;
|
|
3817
3964
|
}
|
|
3818
3965
|
return resolveNode(resolve, futureARS, futureRSS, moduleInjector)
|
|
3819
3966
|
.pipe(map((resolvedData) => {
|
|
3820
3967
|
futureARS._resolvedData = resolvedData;
|
|
3821
|
-
futureARS.data =
|
|
3968
|
+
futureARS.data = inheritedParamsDataResolve(futureARS, paramsInheritanceStrategy).resolve;
|
|
3969
|
+
if (config && hasStaticTitle(config)) {
|
|
3970
|
+
futureARS.data[RouteTitle] = config.title;
|
|
3971
|
+
}
|
|
3822
3972
|
return null;
|
|
3823
3973
|
}));
|
|
3824
3974
|
}
|
|
@@ -3829,16 +3979,9 @@ function resolveNode(resolve, futureARS, futureRSS, moduleInjector) {
|
|
|
3829
3979
|
}
|
|
3830
3980
|
const data = {};
|
|
3831
3981
|
return from(keys).pipe(mergeMap(key => getResolver(resolve[key], futureARS, futureRSS, moduleInjector)
|
|
3832
|
-
.pipe(
|
|
3982
|
+
.pipe(first(), tap((value) => {
|
|
3833
3983
|
data[key] = value;
|
|
3834
|
-
}))), takeLast(1),
|
|
3835
|
-
// Ensure all resolvers returned values, otherwise don't emit any "next" and just complete
|
|
3836
|
-
// the chain which will cancel navigation
|
|
3837
|
-
if (getDataKeys(data).length === keys.length) {
|
|
3838
|
-
return of(data);
|
|
3839
|
-
}
|
|
3840
|
-
return EMPTY;
|
|
3841
|
-
}));
|
|
3984
|
+
}))), takeLast(1), mapTo(data), catchError((e) => e instanceof EmptyError ? EMPTY : throwError(e)));
|
|
3842
3985
|
}
|
|
3843
3986
|
function getDataKeys(obj) {
|
|
3844
3987
|
return [...Object.keys(obj), ...Object.getOwnPropertySymbols(obj)];
|
|
@@ -3848,6 +3991,9 @@ function getResolver(injectionToken, futureARS, futureRSS, moduleInjector) {
|
|
|
3848
3991
|
return resolver.resolve ? wrapIntoObservable(resolver.resolve(futureARS, futureRSS)) :
|
|
3849
3992
|
wrapIntoObservable(resolver(futureARS, futureRSS));
|
|
3850
3993
|
}
|
|
3994
|
+
function hasStaticTitle(config) {
|
|
3995
|
+
return typeof config.title === 'string' || config.title === null;
|
|
3996
|
+
}
|
|
3851
3997
|
|
|
3852
3998
|
/**
|
|
3853
3999
|
* @license
|
|
@@ -3944,6 +4090,7 @@ class DefaultRouteReuseStrategy extends BaseRouteReuseStrategy {
|
|
|
3944
4090
|
* Use of this source code is governed by an MIT-style license that can be
|
|
3945
4091
|
* found in the LICENSE file at https://angular.io/license
|
|
3946
4092
|
*/
|
|
4093
|
+
const NG_DEV_MODE$1 = typeof ngDevMode === 'undefined' || !!ngDevMode;
|
|
3947
4094
|
/**
|
|
3948
4095
|
* The [DI token](guide/glossary/#di-token) for a router configuration.
|
|
3949
4096
|
*
|
|
@@ -3956,43 +4103,85 @@ class DefaultRouteReuseStrategy extends BaseRouteReuseStrategy {
|
|
|
3956
4103
|
*/
|
|
3957
4104
|
const ROUTES = new InjectionToken('ROUTES');
|
|
3958
4105
|
class RouterConfigLoader {
|
|
3959
|
-
constructor(injector, compiler
|
|
4106
|
+
constructor(injector, compiler) {
|
|
3960
4107
|
this.injector = injector;
|
|
3961
4108
|
this.compiler = compiler;
|
|
3962
|
-
this.
|
|
3963
|
-
this.
|
|
4109
|
+
this.componentLoaders = new WeakMap();
|
|
4110
|
+
this.childrenLoaders = new WeakMap();
|
|
4111
|
+
}
|
|
4112
|
+
loadComponent(route) {
|
|
4113
|
+
if (this.componentLoaders.get(route)) {
|
|
4114
|
+
return this.componentLoaders.get(route);
|
|
4115
|
+
}
|
|
4116
|
+
else if (route._loadedComponent) {
|
|
4117
|
+
return of(route._loadedComponent);
|
|
4118
|
+
}
|
|
4119
|
+
if (this.onLoadStartListener) {
|
|
4120
|
+
this.onLoadStartListener(route);
|
|
4121
|
+
}
|
|
4122
|
+
const loadRunner = wrapIntoObservable(route.loadComponent())
|
|
4123
|
+
.pipe(tap(component => {
|
|
4124
|
+
var _a;
|
|
4125
|
+
if (this.onLoadEndListener) {
|
|
4126
|
+
this.onLoadEndListener(route);
|
|
4127
|
+
}
|
|
4128
|
+
NG_DEV_MODE$1 && assertStandalone((_a = route.path) !== null && _a !== void 0 ? _a : '', component);
|
|
4129
|
+
route._loadedComponent = component;
|
|
4130
|
+
}), finalize(() => {
|
|
4131
|
+
this.componentLoaders.delete(route);
|
|
4132
|
+
}));
|
|
4133
|
+
// Use custom ConnectableObservable as share in runners pipe increasing the bundle size too much
|
|
4134
|
+
const loader = new ConnectableObservable(loadRunner, () => new Subject()).pipe(refCount());
|
|
4135
|
+
this.componentLoaders.set(route, loader);
|
|
4136
|
+
return loader;
|
|
3964
4137
|
}
|
|
3965
|
-
|
|
3966
|
-
if (route
|
|
3967
|
-
return route
|
|
4138
|
+
loadChildren(parentInjector, route) {
|
|
4139
|
+
if (this.childrenLoaders.get(route)) {
|
|
4140
|
+
return this.childrenLoaders.get(route);
|
|
4141
|
+
}
|
|
4142
|
+
else if (route._loadedRoutes) {
|
|
4143
|
+
return of({ routes: route._loadedRoutes, injector: route._loadedInjector });
|
|
3968
4144
|
}
|
|
3969
4145
|
if (this.onLoadStartListener) {
|
|
3970
4146
|
this.onLoadStartListener(route);
|
|
3971
4147
|
}
|
|
3972
|
-
const
|
|
3973
|
-
const loadRunner =
|
|
4148
|
+
const moduleFactoryOrRoutes$ = this.loadModuleFactoryOrRoutes(route.loadChildren);
|
|
4149
|
+
const loadRunner = moduleFactoryOrRoutes$.pipe(map((factoryOrRoutes) => {
|
|
3974
4150
|
if (this.onLoadEndListener) {
|
|
3975
4151
|
this.onLoadEndListener(route);
|
|
3976
4152
|
}
|
|
3977
|
-
|
|
3978
|
-
//
|
|
3979
|
-
|
|
3980
|
-
|
|
3981
|
-
|
|
3982
|
-
|
|
3983
|
-
|
|
3984
|
-
|
|
3985
|
-
|
|
3986
|
-
|
|
4153
|
+
// This injector comes from the `NgModuleRef` when lazy loading an `NgModule`. There is no
|
|
4154
|
+
// injector associated with lazy loading a `Route` array.
|
|
4155
|
+
let injector;
|
|
4156
|
+
let rawRoutes;
|
|
4157
|
+
let requireStandaloneComponents = false;
|
|
4158
|
+
if (Array.isArray(factoryOrRoutes)) {
|
|
4159
|
+
rawRoutes = factoryOrRoutes;
|
|
4160
|
+
requireStandaloneComponents = true;
|
|
4161
|
+
}
|
|
4162
|
+
else {
|
|
4163
|
+
injector = factoryOrRoutes.create(parentInjector).injector;
|
|
4164
|
+
// When loading a module that doesn't provide `RouterModule.forChild()` preloader
|
|
4165
|
+
// will get stuck in an infinite loop. The child module's Injector will look to
|
|
4166
|
+
// its parent `Injector` when it doesn't find any ROUTES so it will return routes
|
|
4167
|
+
// for it's parent module instead.
|
|
4168
|
+
rawRoutes = flatten(injector.get(ROUTES, [], InjectFlags.Self | InjectFlags.Optional));
|
|
4169
|
+
}
|
|
4170
|
+
const routes = rawRoutes.map(standardizeConfig);
|
|
4171
|
+
NG_DEV_MODE$1 && validateConfig(routes, route.path, requireStandaloneComponents);
|
|
4172
|
+
return { routes, injector };
|
|
4173
|
+
}), finalize(() => {
|
|
4174
|
+
this.childrenLoaders.delete(route);
|
|
3987
4175
|
}));
|
|
3988
4176
|
// Use custom ConnectableObservable as share in runners pipe increasing the bundle size too much
|
|
3989
|
-
|
|
4177
|
+
const loader = new ConnectableObservable(loadRunner, () => new Subject())
|
|
3990
4178
|
.pipe(refCount());
|
|
3991
|
-
|
|
4179
|
+
this.childrenLoaders.set(route, loader);
|
|
4180
|
+
return loader;
|
|
3992
4181
|
}
|
|
3993
|
-
|
|
4182
|
+
loadModuleFactoryOrRoutes(loadChildren) {
|
|
3994
4183
|
return wrapIntoObservable(loadChildren()).pipe(mergeMap((t) => {
|
|
3995
|
-
if (t instanceof NgModuleFactory) {
|
|
4184
|
+
if (t instanceof NgModuleFactory || Array.isArray(t)) {
|
|
3996
4185
|
return of(t);
|
|
3997
4186
|
}
|
|
3998
4187
|
else {
|
|
@@ -4001,6 +4190,11 @@ class RouterConfigLoader {
|
|
|
4001
4190
|
}));
|
|
4002
4191
|
}
|
|
4003
4192
|
}
|
|
4193
|
+
RouterConfigLoader.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.0-rc.0", ngImport: i0, type: RouterConfigLoader, deps: [{ token: i0.Injector }, { token: i0.Compiler }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
4194
|
+
RouterConfigLoader.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.0.0-rc.0", ngImport: i0, type: RouterConfigLoader });
|
|
4195
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.0-rc.0", ngImport: i0, type: RouterConfigLoader, decorators: [{
|
|
4196
|
+
type: Injectable
|
|
4197
|
+
}], ctorParameters: function () { return [{ type: i0.Injector }, { type: i0.Compiler }]; } });
|
|
4004
4198
|
|
|
4005
4199
|
/**
|
|
4006
4200
|
* @license
|
|
@@ -4033,6 +4227,7 @@ class DefaultUrlHandlingStrategy {
|
|
|
4033
4227
|
}
|
|
4034
4228
|
}
|
|
4035
4229
|
|
|
4230
|
+
const NG_DEV_MODE = typeof ngDevMode === 'undefined' || !!ngDevMode;
|
|
4036
4231
|
function defaultErrorHandler(error) {
|
|
4037
4232
|
throw error;
|
|
4038
4233
|
}
|
|
@@ -4175,6 +4370,8 @@ class Router {
|
|
|
4175
4370
|
/**
|
|
4176
4371
|
* Enables a bug fix that corrects relative link resolution in components with empty paths.
|
|
4177
4372
|
* @see `RouterModule`
|
|
4373
|
+
*
|
|
4374
|
+
* @deprecated
|
|
4178
4375
|
*/
|
|
4179
4376
|
this.relativeLinkResolution = 'corrected';
|
|
4180
4377
|
/**
|
|
@@ -4202,6 +4399,9 @@ class Router {
|
|
|
4202
4399
|
this.canceledNavigationResolution = 'replace';
|
|
4203
4400
|
const onLoadStart = (r) => this.triggerEvent(new RouteConfigLoadStart(r));
|
|
4204
4401
|
const onLoadEnd = (r) => this.triggerEvent(new RouteConfigLoadEnd(r));
|
|
4402
|
+
this.configLoader = injector.get(RouterConfigLoader);
|
|
4403
|
+
this.configLoader.onLoadEndListener = onLoadEnd;
|
|
4404
|
+
this.configLoader.onLoadStartListener = onLoadStart;
|
|
4205
4405
|
this.ngModule = injector.get(NgModuleRef);
|
|
4206
4406
|
this.console = injector.get(ɵConsole);
|
|
4207
4407
|
const ngZone = injector.get(NgZone);
|
|
@@ -4210,7 +4410,6 @@ class Router {
|
|
|
4210
4410
|
this.currentUrlTree = createEmptyUrlTree();
|
|
4211
4411
|
this.rawUrlTree = this.currentUrlTree;
|
|
4212
4412
|
this.browserUrlTree = this.currentUrlTree;
|
|
4213
|
-
this.configLoader = new RouterConfigLoader(injector, compiler, onLoadStart, onLoadEnd);
|
|
4214
4413
|
this.routerState = createEmptyState(this.currentUrlTree, this.rootComponentType);
|
|
4215
4414
|
this.transitions = new BehaviorSubject({
|
|
4216
4415
|
id: 0,
|
|
@@ -4408,6 +4607,26 @@ class Router {
|
|
|
4408
4607
|
skipLocationChange: !!skipLocationChange,
|
|
4409
4608
|
replaceUrl: !!replaceUrl,
|
|
4410
4609
|
});
|
|
4610
|
+
}),
|
|
4611
|
+
// --- LOAD COMPONENTS ---
|
|
4612
|
+
switchTap((t) => {
|
|
4613
|
+
const loadComponents = (route) => {
|
|
4614
|
+
var _a;
|
|
4615
|
+
const loaders = [];
|
|
4616
|
+
if (((_a = route.routeConfig) === null || _a === void 0 ? void 0 : _a.loadComponent) &&
|
|
4617
|
+
!route.routeConfig._loadedComponent) {
|
|
4618
|
+
loaders.push(this.configLoader.loadComponent(route.routeConfig)
|
|
4619
|
+
.pipe(tap(loadedComponent => {
|
|
4620
|
+
route.component = loadedComponent;
|
|
4621
|
+
}), map(() => void 0)));
|
|
4622
|
+
}
|
|
4623
|
+
for (const child of route.children) {
|
|
4624
|
+
loaders.push(...loadComponents(child));
|
|
4625
|
+
}
|
|
4626
|
+
return loaders;
|
|
4627
|
+
};
|
|
4628
|
+
return combineLatest(loadComponents(t.targetSnapshot.root))
|
|
4629
|
+
.pipe(defaultIfEmpty(), take(1));
|
|
4411
4630
|
}), map((t) => {
|
|
4412
4631
|
const targetRouterState = createRouterState(this.routeReuseStrategy, t.targetSnapshot, t.currentRouterState);
|
|
4413
4632
|
return (Object.assign(Object.assign({}, t), { targetRouterState }));
|
|
@@ -4487,23 +4706,17 @@ class Router {
|
|
|
4487
4706
|
t.resolve(false);
|
|
4488
4707
|
}
|
|
4489
4708
|
else {
|
|
4490
|
-
|
|
4491
|
-
|
|
4492
|
-
|
|
4493
|
-
|
|
4494
|
-
|
|
4495
|
-
|
|
4496
|
-
|
|
4497
|
-
|
|
4498
|
-
|
|
4499
|
-
|
|
4500
|
-
|
|
4501
|
-
// the navigation is rejected.
|
|
4502
|
-
replaceUrl: this.urlUpdateStrategy === 'eager' ||
|
|
4503
|
-
isBrowserTriggeredNavigation(t.source)
|
|
4504
|
-
};
|
|
4505
|
-
this.scheduleNavigation(mergedTree, 'imperative', null, extras, { resolve: t.resolve, reject: t.reject, promise: t.promise });
|
|
4506
|
-
}, 0);
|
|
4709
|
+
const mergedTree = this.urlHandlingStrategy.merge(e.url, this.rawUrlTree);
|
|
4710
|
+
const extras = {
|
|
4711
|
+
skipLocationChange: t.extras.skipLocationChange,
|
|
4712
|
+
// The URL is already updated at this point if we have 'eager' URL
|
|
4713
|
+
// updates or if the navigation was triggered by the browser (back
|
|
4714
|
+
// button, URL bar, etc). We want to replace that item in history if
|
|
4715
|
+
// the navigation is rejected.
|
|
4716
|
+
replaceUrl: this.urlUpdateStrategy === 'eager' ||
|
|
4717
|
+
isBrowserTriggeredNavigation(t.source)
|
|
4718
|
+
};
|
|
4719
|
+
this.scheduleNavigation(mergedTree, 'imperative', null, extras, { resolve: t.resolve, reject: t.reject, promise: t.promise });
|
|
4507
4720
|
}
|
|
4508
4721
|
/* All other errors should reset to the router's internal URL reference to
|
|
4509
4722
|
* the pre-error state. */
|
|
@@ -4614,7 +4827,7 @@ class Router {
|
|
|
4614
4827
|
* ```
|
|
4615
4828
|
*/
|
|
4616
4829
|
resetConfig(config) {
|
|
4617
|
-
validateConfig(config);
|
|
4830
|
+
NG_DEV_MODE && validateConfig(config);
|
|
4618
4831
|
this.config = config.map(standardizeConfig);
|
|
4619
4832
|
this.navigated = false;
|
|
4620
4833
|
this.lastSuccessfulId = -1;
|
|
@@ -4972,9 +5185,9 @@ class Router {
|
|
|
4972
5185
|
return { navigationId };
|
|
4973
5186
|
}
|
|
4974
5187
|
}
|
|
4975
|
-
Router.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.0-
|
|
4976
|
-
Router.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.0.0-
|
|
4977
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.0-
|
|
5188
|
+
Router.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.0-rc.0", ngImport: i0, type: Router, deps: "invalid", target: i0.ɵɵFactoryTarget.Injectable });
|
|
5189
|
+
Router.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.0.0-rc.0", ngImport: i0, type: Router });
|
|
5190
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.0-rc.0", ngImport: i0, type: Router, decorators: [{
|
|
4978
5191
|
type: Injectable
|
|
4979
5192
|
}], ctorParameters: function () { return [{ type: i0.Type }, { type: UrlSerializer }, { type: ChildrenOutletContexts }, { type: i3.Location }, { type: i0.Injector }, { type: i0.Compiler }, { type: undefined }]; } });
|
|
4980
5193
|
function validateCommands(commands) {
|
|
@@ -5166,9 +5379,9 @@ class RouterLink {
|
|
|
5166
5379
|
});
|
|
5167
5380
|
}
|
|
5168
5381
|
}
|
|
5169
|
-
RouterLink.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.0-
|
|
5170
|
-
RouterLink.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "
|
|
5171
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.0-
|
|
5382
|
+
RouterLink.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.0-rc.0", ngImport: i0, type: RouterLink, deps: [{ token: Router }, { token: ActivatedRoute }, { token: 'tabindex', attribute: true }, { token: i0.Renderer2 }, { token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Directive });
|
|
5383
|
+
RouterLink.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "14.0.0-rc.0", type: RouterLink, selector: ":not(a):not(area)[routerLink]", inputs: { queryParams: "queryParams", fragment: "fragment", queryParamsHandling: "queryParamsHandling", preserveFragment: "preserveFragment", skipLocationChange: "skipLocationChange", replaceUrl: "replaceUrl", state: "state", relativeTo: "relativeTo", routerLink: "routerLink" }, host: { listeners: { "click": "onClick()" } }, usesOnChanges: true, ngImport: i0 });
|
|
5384
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.0-rc.0", ngImport: i0, type: RouterLink, decorators: [{
|
|
5172
5385
|
type: Directive,
|
|
5173
5386
|
args: [{ selector: ':not(a):not(area)[routerLink]' }]
|
|
5174
5387
|
}], ctorParameters: function () {
|
|
@@ -5287,9 +5500,9 @@ class RouterLinkWithHref {
|
|
|
5287
5500
|
});
|
|
5288
5501
|
}
|
|
5289
5502
|
}
|
|
5290
|
-
RouterLinkWithHref.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.0-
|
|
5291
|
-
RouterLinkWithHref.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "
|
|
5292
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.0-
|
|
5503
|
+
RouterLinkWithHref.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.0-rc.0", ngImport: i0, type: RouterLinkWithHref, deps: [{ token: Router }, { token: ActivatedRoute }, { token: i3.LocationStrategy }], target: i0.ɵɵFactoryTarget.Directive });
|
|
5504
|
+
RouterLinkWithHref.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "14.0.0-rc.0", type: RouterLinkWithHref, selector: "a[routerLink],area[routerLink]", inputs: { target: "target", queryParams: "queryParams", fragment: "fragment", queryParamsHandling: "queryParamsHandling", preserveFragment: "preserveFragment", skipLocationChange: "skipLocationChange", replaceUrl: "replaceUrl", state: "state", relativeTo: "relativeTo", routerLink: "routerLink" }, host: { listeners: { "click": "onClick($event.button,$event.ctrlKey,$event.shiftKey,$event.altKey,$event.metaKey)" }, properties: { "attr.target": "this.target", "attr.href": "this.href" } }, usesOnChanges: true, ngImport: i0 });
|
|
5505
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.0-rc.0", ngImport: i0, type: RouterLinkWithHref, decorators: [{
|
|
5293
5506
|
type: Directive,
|
|
5294
5507
|
args: [{ selector: 'a[routerLink],area[routerLink]' }]
|
|
5295
5508
|
}], ctorParameters: function () { return [{ type: Router }, { type: ActivatedRoute }, { type: i3.LocationStrategy }]; }, propDecorators: { target: [{
|
|
@@ -5386,6 +5599,16 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.0-next.9",
|
|
|
5386
5599
|
* </div>
|
|
5387
5600
|
* ```
|
|
5388
5601
|
*
|
|
5602
|
+
* The `RouterLinkActive` directive can also be used to set the aria-current attribute
|
|
5603
|
+
* to provide an alternative distinction for active elements to visually impaired users.
|
|
5604
|
+
*
|
|
5605
|
+
* For example, the following code adds the 'active' class to the Home Page link when it is
|
|
5606
|
+
* indeed active and in such case also sets its aria-current attribute to 'page':
|
|
5607
|
+
*
|
|
5608
|
+
* ```
|
|
5609
|
+
* <a routerLink="/" routerLinkActive="active" ariaCurrentWhenActive="page">Home Page</a>
|
|
5610
|
+
* ```
|
|
5611
|
+
*
|
|
5389
5612
|
* @ngModule RouterModule
|
|
5390
5613
|
*
|
|
5391
5614
|
* @publicApi
|
|
@@ -5481,6 +5704,12 @@ class RouterLinkActive {
|
|
|
5481
5704
|
this.renderer.removeClass(this.element.nativeElement, c);
|
|
5482
5705
|
}
|
|
5483
5706
|
});
|
|
5707
|
+
if (hasActiveLinks && this.ariaCurrentWhenActive !== undefined) {
|
|
5708
|
+
this.renderer.setAttribute(this.element.nativeElement, 'aria-current', this.ariaCurrentWhenActive.toString());
|
|
5709
|
+
}
|
|
5710
|
+
else {
|
|
5711
|
+
this.renderer.removeAttribute(this.element.nativeElement, 'aria-current');
|
|
5712
|
+
}
|
|
5484
5713
|
// Emit on isActiveChange after classes are updated
|
|
5485
5714
|
this.isActiveChange.emit(hasActiveLinks);
|
|
5486
5715
|
}
|
|
@@ -5500,9 +5729,9 @@ class RouterLinkActive {
|
|
|
5500
5729
|
this.links.some(isActiveCheckFn) || this.linksWithHrefs.some(isActiveCheckFn);
|
|
5501
5730
|
}
|
|
5502
5731
|
}
|
|
5503
|
-
RouterLinkActive.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.0-
|
|
5504
|
-
RouterLinkActive.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "
|
|
5505
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.0-
|
|
5732
|
+
RouterLinkActive.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.0-rc.0", ngImport: i0, type: RouterLinkActive, deps: [{ token: Router }, { token: i0.ElementRef }, { token: i0.Renderer2 }, { token: i0.ChangeDetectorRef }, { token: RouterLink, optional: true }, { token: RouterLinkWithHref, optional: true }], target: i0.ɵɵFactoryTarget.Directive });
|
|
5733
|
+
RouterLinkActive.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "14.0.0-rc.0", type: RouterLinkActive, selector: "[routerLinkActive]", inputs: { routerLinkActiveOptions: "routerLinkActiveOptions", ariaCurrentWhenActive: "ariaCurrentWhenActive", routerLinkActive: "routerLinkActive" }, outputs: { isActiveChange: "isActiveChange" }, queries: [{ propertyName: "links", predicate: RouterLink, descendants: true }, { propertyName: "linksWithHrefs", predicate: RouterLinkWithHref, descendants: true }], exportAs: ["routerLinkActive"], usesOnChanges: true, ngImport: i0 });
|
|
5734
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.0-rc.0", ngImport: i0, type: RouterLinkActive, decorators: [{
|
|
5506
5735
|
type: Directive,
|
|
5507
5736
|
args: [{
|
|
5508
5737
|
selector: '[routerLinkActive]',
|
|
@@ -5522,6 +5751,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.0-next.9",
|
|
|
5522
5751
|
args: [RouterLinkWithHref, { descendants: true }]
|
|
5523
5752
|
}], routerLinkActiveOptions: [{
|
|
5524
5753
|
type: Input
|
|
5754
|
+
}], ariaCurrentWhenActive: [{
|
|
5755
|
+
type: Input
|
|
5525
5756
|
}], isActiveChange: [{
|
|
5526
5757
|
type: Output
|
|
5527
5758
|
}], routerLinkActive: [{
|
|
@@ -5606,9 +5837,9 @@ class DefaultTitleStrategy extends TitleStrategy {
|
|
|
5606
5837
|
}
|
|
5607
5838
|
}
|
|
5608
5839
|
}
|
|
5609
|
-
DefaultTitleStrategy.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.0-
|
|
5610
|
-
DefaultTitleStrategy.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.0.0-
|
|
5611
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.0-
|
|
5840
|
+
DefaultTitleStrategy.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.0-rc.0", ngImport: i0, type: DefaultTitleStrategy, deps: [{ token: i1.Title }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
5841
|
+
DefaultTitleStrategy.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.0.0-rc.0", ngImport: i0, type: DefaultTitleStrategy, providedIn: 'root' });
|
|
5842
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.0-rc.0", ngImport: i0, type: DefaultTitleStrategy, decorators: [{
|
|
5612
5843
|
type: Injectable,
|
|
5613
5844
|
args: [{ providedIn: 'root' }]
|
|
5614
5845
|
}], ctorParameters: function () { return [{ type: i1.Title }]; } });
|
|
@@ -5672,13 +5903,11 @@ class NoPreloading {
|
|
|
5672
5903
|
* @publicApi
|
|
5673
5904
|
*/
|
|
5674
5905
|
class RouterPreloader {
|
|
5675
|
-
constructor(router, compiler, injector, preloadingStrategy) {
|
|
5906
|
+
constructor(router, compiler, injector, preloadingStrategy, loader) {
|
|
5676
5907
|
this.router = router;
|
|
5677
5908
|
this.injector = injector;
|
|
5678
5909
|
this.preloadingStrategy = preloadingStrategy;
|
|
5679
|
-
|
|
5680
|
-
const onEndLoad = (r) => router.triggerEvent(new RouteConfigLoadEnd(r));
|
|
5681
|
-
this.loader = new RouterConfigLoader(injector, compiler, onStartLoad, onEndLoad);
|
|
5910
|
+
this.loader = loader;
|
|
5682
5911
|
}
|
|
5683
5912
|
setUpPreloading() {
|
|
5684
5913
|
this.subscription =
|
|
@@ -5687,8 +5916,7 @@ class RouterPreloader {
|
|
|
5687
5916
|
.subscribe(() => { });
|
|
5688
5917
|
}
|
|
5689
5918
|
preload() {
|
|
5690
|
-
|
|
5691
|
-
return this.processRoutes(ngModule, this.router.config);
|
|
5919
|
+
return this.processRoutes(this.injector, this.router.config);
|
|
5692
5920
|
}
|
|
5693
5921
|
/** @nodoc */
|
|
5694
5922
|
ngOnDestroy() {
|
|
@@ -5696,41 +5924,61 @@ class RouterPreloader {
|
|
|
5696
5924
|
this.subscription.unsubscribe();
|
|
5697
5925
|
}
|
|
5698
5926
|
}
|
|
5699
|
-
processRoutes(
|
|
5927
|
+
processRoutes(injector, routes) {
|
|
5928
|
+
var _a, _b, _c;
|
|
5700
5929
|
const res = [];
|
|
5701
5930
|
for (const route of routes) {
|
|
5702
|
-
|
|
5703
|
-
|
|
5704
|
-
|
|
5705
|
-
res.push(this.processRoutes(childConfig.module, childConfig.routes));
|
|
5706
|
-
// no config loaded, fetch the config
|
|
5931
|
+
if (route.providers && !route._injector) {
|
|
5932
|
+
route._injector =
|
|
5933
|
+
createEnvironmentInjector(route.providers, injector, `Route: ${route.path}`);
|
|
5707
5934
|
}
|
|
5708
|
-
|
|
5709
|
-
|
|
5710
|
-
|
|
5935
|
+
const injectorForCurrentRoute = (_a = route._injector) !== null && _a !== void 0 ? _a : injector;
|
|
5936
|
+
const injectorForChildren = (_b = route._loadedInjector) !== null && _b !== void 0 ? _b : injectorForCurrentRoute;
|
|
5937
|
+
if ((route.loadChildren && !route._loadedRoutes) ||
|
|
5938
|
+
(route.loadComponent && !route._loadedComponent)) {
|
|
5939
|
+
res.push(this.preloadConfig(injectorForCurrentRoute, route));
|
|
5711
5940
|
}
|
|
5712
|
-
else if (route.children) {
|
|
5713
|
-
res.push(this.processRoutes(
|
|
5941
|
+
else if (route.children || route._loadedRoutes) {
|
|
5942
|
+
res.push(this.processRoutes(injectorForChildren, ((_c = route.children) !== null && _c !== void 0 ? _c : route._loadedRoutes)));
|
|
5714
5943
|
}
|
|
5715
5944
|
}
|
|
5716
|
-
return from(res).pipe(mergeAll()
|
|
5945
|
+
return from(res).pipe(mergeAll());
|
|
5717
5946
|
}
|
|
5718
|
-
preloadConfig(
|
|
5947
|
+
preloadConfig(injector, route) {
|
|
5719
5948
|
return this.preloadingStrategy.preload(route, () => {
|
|
5720
|
-
|
|
5721
|
-
|
|
5722
|
-
|
|
5723
|
-
|
|
5724
|
-
|
|
5949
|
+
let loadedChildren$;
|
|
5950
|
+
if (route.loadChildren && route.canLoad === undefined) {
|
|
5951
|
+
loadedChildren$ = this.loader.loadChildren(injector, route);
|
|
5952
|
+
}
|
|
5953
|
+
else {
|
|
5954
|
+
loadedChildren$ = of(null);
|
|
5955
|
+
}
|
|
5956
|
+
const recursiveLoadChildren$ = loadedChildren$.pipe(mergeMap((config) => {
|
|
5957
|
+
var _a;
|
|
5958
|
+
if (config === null) {
|
|
5959
|
+
return of(void 0);
|
|
5960
|
+
}
|
|
5961
|
+
route._loadedRoutes = config.routes;
|
|
5962
|
+
route._loadedInjector = config.injector;
|
|
5963
|
+
// If the loaded config was a module, use that as the module/module injector going
|
|
5964
|
+
// forward. Otherwise, continue using the current module/module injector.
|
|
5965
|
+
return this.processRoutes((_a = config.injector) !== null && _a !== void 0 ? _a : injector, config.routes);
|
|
5725
5966
|
}));
|
|
5967
|
+
if (route.loadComponent && !route._loadedComponent) {
|
|
5968
|
+
const loadComponent$ = this.loader.loadComponent(route);
|
|
5969
|
+
return from([recursiveLoadChildren$, loadComponent$]).pipe(mergeAll());
|
|
5970
|
+
}
|
|
5971
|
+
else {
|
|
5972
|
+
return recursiveLoadChildren$;
|
|
5973
|
+
}
|
|
5726
5974
|
});
|
|
5727
5975
|
}
|
|
5728
5976
|
}
|
|
5729
|
-
RouterPreloader.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.0-
|
|
5730
|
-
RouterPreloader.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.0.0-
|
|
5731
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.0-
|
|
5977
|
+
RouterPreloader.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.0-rc.0", ngImport: i0, type: RouterPreloader, deps: [{ token: Router }, { token: i0.Compiler }, { token: i0.EnvironmentInjector }, { token: PreloadingStrategy }, { token: RouterConfigLoader }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
5978
|
+
RouterPreloader.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.0.0-rc.0", ngImport: i0, type: RouterPreloader });
|
|
5979
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.0-rc.0", ngImport: i0, type: RouterPreloader, decorators: [{
|
|
5732
5980
|
type: Injectable
|
|
5733
|
-
}], ctorParameters: function () { return [{ type: Router }, { type: i0.Compiler }, { type: i0.
|
|
5981
|
+
}], ctorParameters: function () { return [{ type: Router }, { type: i0.Compiler }, { type: i0.EnvironmentInjector }, { type: PreloadingStrategy }, { type: RouterConfigLoader }]; } });
|
|
5734
5982
|
|
|
5735
5983
|
class RouterScroller {
|
|
5736
5984
|
constructor(router,
|
|
@@ -5807,9 +6055,9 @@ class RouterScroller {
|
|
|
5807
6055
|
}
|
|
5808
6056
|
}
|
|
5809
6057
|
}
|
|
5810
|
-
RouterScroller.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.0-
|
|
5811
|
-
RouterScroller.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.0.0-
|
|
5812
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.0-
|
|
6058
|
+
RouterScroller.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.0-rc.0", ngImport: i0, type: RouterScroller, deps: "invalid", target: i0.ɵɵFactoryTarget.Injectable });
|
|
6059
|
+
RouterScroller.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.0.0-rc.0", ngImport: i0, type: RouterScroller });
|
|
6060
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.0-rc.0", ngImport: i0, type: RouterScroller, decorators: [{
|
|
5813
6061
|
type: Injectable
|
|
5814
6062
|
}], ctorParameters: function () { return [{ type: Router }, { type: i3.ViewportScroller }, { type: undefined }]; } });
|
|
5815
6063
|
|
|
@@ -5852,6 +6100,7 @@ const ROUTER_PROVIDERS = [
|
|
|
5852
6100
|
NoPreloading,
|
|
5853
6101
|
PreloadAllModules,
|
|
5854
6102
|
{ provide: ROUTER_CONFIGURATION, useValue: { enableTracing: false } },
|
|
6103
|
+
RouterConfigLoader,
|
|
5855
6104
|
];
|
|
5856
6105
|
function routerNgProbeToken() {
|
|
5857
6106
|
return new NgProbeToken('Router', Router);
|
|
@@ -5950,10 +6199,10 @@ class RouterModule {
|
|
|
5950
6199
|
return { ngModule: RouterModule, providers: [provideRoutes(routes)] };
|
|
5951
6200
|
}
|
|
5952
6201
|
}
|
|
5953
|
-
RouterModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.0-
|
|
5954
|
-
RouterModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "
|
|
5955
|
-
RouterModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "14.0.0-
|
|
5956
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.0-
|
|
6202
|
+
RouterModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.0-rc.0", ngImport: i0, type: RouterModule, deps: [{ token: ROUTER_FORROOT_GUARD, optional: true }, { token: Router, optional: true }], target: i0.ɵɵFactoryTarget.NgModule });
|
|
6203
|
+
RouterModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "14.0.0-rc.0", ngImport: i0, type: RouterModule, declarations: [RouterOutlet, RouterLink, RouterLinkWithHref, RouterLinkActive, ɵEmptyOutletComponent], exports: [RouterOutlet, RouterLink, RouterLinkWithHref, RouterLinkActive, ɵEmptyOutletComponent] });
|
|
6204
|
+
RouterModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "14.0.0-rc.0", ngImport: i0, type: RouterModule });
|
|
6205
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.0-rc.0", ngImport: i0, type: RouterModule, decorators: [{
|
|
5957
6206
|
type: NgModule,
|
|
5958
6207
|
args: [{
|
|
5959
6208
|
declarations: ROUTER_DIRECTIVES,
|
|
@@ -6017,12 +6266,12 @@ function setupRouter(urlSerializer, contexts, location, injector, compiler, conf
|
|
|
6017
6266
|
}
|
|
6018
6267
|
router.titleStrategy = titleStrategy !== null && titleStrategy !== void 0 ? titleStrategy : defaultTitleStrategy;
|
|
6019
6268
|
assignExtraOptionsToRouter(opts, router);
|
|
6020
|
-
if (opts.enableTracing) {
|
|
6269
|
+
if ((typeof ngDevMode === 'undefined' || ngDevMode) && opts.enableTracing) {
|
|
6021
6270
|
router.events.subscribe((e) => {
|
|
6022
6271
|
var _a, _b;
|
|
6023
6272
|
// tslint:disable:no-console
|
|
6024
6273
|
(_a = console.group) === null || _a === void 0 ? void 0 : _a.call(console, `Router Event: ${e.constructor.name}`);
|
|
6025
|
-
console.log(e
|
|
6274
|
+
console.log(stringifyEvent(e));
|
|
6026
6275
|
console.log(e);
|
|
6027
6276
|
(_b = console.groupEnd) === null || _b === void 0 ? void 0 : _b.call(console);
|
|
6028
6277
|
// tslint:enable:no-console
|
|
@@ -6089,9 +6338,7 @@ class RouterInitializer {
|
|
|
6089
6338
|
router.setUpLocationChangeListener();
|
|
6090
6339
|
resolve(true);
|
|
6091
6340
|
}
|
|
6092
|
-
else if (
|
|
6093
|
-
// TODO: enabled is deprecated as of v11, can be removed in v13
|
|
6094
|
-
opts.initialNavigation === 'enabled' || opts.initialNavigation === 'enabledBlocking') {
|
|
6341
|
+
else if (opts.initialNavigation === 'enabledBlocking') {
|
|
6095
6342
|
router.hooks.afterPreactivation = () => {
|
|
6096
6343
|
// only the initial navigation should be delayed
|
|
6097
6344
|
if (!this.initNavigation) {
|
|
@@ -6135,9 +6382,9 @@ class RouterInitializer {
|
|
|
6135
6382
|
this.destroyed = true;
|
|
6136
6383
|
}
|
|
6137
6384
|
}
|
|
6138
|
-
RouterInitializer.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.0-
|
|
6139
|
-
RouterInitializer.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.0.0-
|
|
6140
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.0-
|
|
6385
|
+
RouterInitializer.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.0-rc.0", 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-rc.0", ngImport: i0, type: RouterInitializer });
|
|
6387
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.0-rc.0", ngImport: i0, type: RouterInitializer, decorators: [{
|
|
6141
6388
|
type: Injectable
|
|
6142
6389
|
}], ctorParameters: function () { return [{ type: i0.Injector }]; } });
|
|
6143
6390
|
function getAppInitializer(r) {
|
|
@@ -6177,7 +6424,7 @@ function provideRouterInitializer() {
|
|
|
6177
6424
|
/**
|
|
6178
6425
|
* @publicApi
|
|
6179
6426
|
*/
|
|
6180
|
-
const VERSION = new Version('14.0.0-
|
|
6427
|
+
const VERSION = new Version('14.0.0-rc.0');
|
|
6181
6428
|
|
|
6182
6429
|
/**
|
|
6183
6430
|
* @license
|