@angular/router 12.1.0 → 12.1.4
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/bundles/router-testing.umd.js +1 -1
- package/bundles/router-upgrade.umd.js +1 -1
- package/bundles/router.umd.js +120 -48
- package/bundles/router.umd.js.map +1 -1
- package/esm2015/src/events.js +5 -3
- package/esm2015/src/router.js +108 -43
- package/esm2015/src/router_state.js +1 -1
- package/esm2015/src/version.js +1 -1
- package/fesm2015/router.js +113 -46
- package/fesm2015/router.js.map +1 -1
- package/fesm2015/testing.js +1 -1
- package/fesm2015/upgrade.js +1 -1
- package/package.json +4 -4
- package/router.d.ts +27 -16
- package/router.metadata.json +1 -1
- package/testing/testing.d.ts +4 -4
- package/testing.d.ts +1 -1
- package/upgrade/upgrade.d.ts +1 -1
- package/upgrade.d.ts +1 -1
package/bundles/router.umd.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @license Angular v12.1.
|
|
2
|
+
* @license Angular v12.1.4
|
|
3
3
|
* (c) 2010-2021 Google LLC. https://angular.io/
|
|
4
4
|
* License: MIT
|
|
5
5
|
*/
|
|
@@ -342,12 +342,14 @@
|
|
|
342
342
|
* The following code shows how a class subscribes to router events.
|
|
343
343
|
*
|
|
344
344
|
* ```ts
|
|
345
|
+
* import {Event, RouterEvent, Router} from '@angular/router';
|
|
346
|
+
*
|
|
345
347
|
* class MyService {
|
|
346
|
-
* constructor(public router: Router
|
|
348
|
+
* constructor(public router: Router) {
|
|
347
349
|
* router.events.pipe(
|
|
348
350
|
* filter((e: Event): e is RouterEvent => e instanceof RouterEvent)
|
|
349
351
|
* ).subscribe((e: RouterEvent) => {
|
|
350
|
-
*
|
|
352
|
+
* // Do something
|
|
351
353
|
* });
|
|
352
354
|
* }
|
|
353
355
|
* }
|
|
@@ -4472,6 +4474,10 @@
|
|
|
4472
4474
|
/**
|
|
4473
4475
|
* The id of the currently active page in the router.
|
|
4474
4476
|
* Updated to the transition's target id on a successful navigation.
|
|
4477
|
+
*
|
|
4478
|
+
* This is used to track what page the router last activated. When an attempted navigation fails,
|
|
4479
|
+
* the router can then use this to compute how to restore the state back to the previously active
|
|
4480
|
+
* page.
|
|
4475
4481
|
*/
|
|
4476
4482
|
this.currentPageId = 0;
|
|
4477
4483
|
this.isNgZoneEnabled = false;
|
|
@@ -4604,6 +4610,19 @@
|
|
|
4604
4610
|
this.navigations = this.setupNavigations(this.transitions);
|
|
4605
4611
|
this.processNavigations();
|
|
4606
4612
|
}
|
|
4613
|
+
Object.defineProperty(Router.prototype, "browserPageId", {
|
|
4614
|
+
/**
|
|
4615
|
+
* The ɵrouterPageId of whatever page is currently active in the browser history. This is
|
|
4616
|
+
* important for computing the target page id for new navigations because we need to ensure each
|
|
4617
|
+
* page id in the browser history is 1 more than the previous entry.
|
|
4618
|
+
*/
|
|
4619
|
+
get: function () {
|
|
4620
|
+
var _a;
|
|
4621
|
+
return (_a = this.location.getState()) === null || _a === void 0 ? void 0 : _a.ɵrouterPageId;
|
|
4622
|
+
},
|
|
4623
|
+
enumerable: false,
|
|
4624
|
+
configurable: true
|
|
4625
|
+
});
|
|
4607
4626
|
Router.prototype.setupNavigations = function (transitions) {
|
|
4608
4627
|
var _this = this;
|
|
4609
4628
|
var eventsSubject = this.events;
|
|
@@ -4693,7 +4712,7 @@
|
|
|
4693
4712
|
}),
|
|
4694
4713
|
// Before Preactivation
|
|
4695
4714
|
switchTap(function (t) {
|
|
4696
|
-
var targetSnapshot = t.targetSnapshot, navigationId = t.id, appliedUrlTree = t.extractedUrl, rawUrlTree = t.rawUrl,
|
|
4715
|
+
var targetSnapshot = t.targetSnapshot, navigationId = t.id, appliedUrlTree = t.extractedUrl, rawUrlTree = t.rawUrl, _c = t.extras, skipLocationChange = _c.skipLocationChange, replaceUrl = _c.replaceUrl;
|
|
4697
4716
|
return _this.hooks.beforePreactivation(targetSnapshot, {
|
|
4698
4717
|
navigationId: navigationId,
|
|
4699
4718
|
appliedUrlTree: appliedUrlTree,
|
|
@@ -4716,6 +4735,7 @@
|
|
|
4716
4735
|
_this.triggerEvent(guardsEnd);
|
|
4717
4736
|
}), operators.filter(function (t) {
|
|
4718
4737
|
if (!t.guardsResult) {
|
|
4738
|
+
_this.restoreHistory(t);
|
|
4719
4739
|
_this.cancelNavigationTransition(t, '');
|
|
4720
4740
|
return false;
|
|
4721
4741
|
}
|
|
@@ -4733,6 +4753,7 @@
|
|
|
4733
4753
|
next: function () { return dataResolved = true; },
|
|
4734
4754
|
complete: function () {
|
|
4735
4755
|
if (!dataResolved) {
|
|
4756
|
+
_this.restoreHistory(t);
|
|
4736
4757
|
_this.cancelNavigationTransition(t, "At least one route resolver didn't emit any value.");
|
|
4737
4758
|
}
|
|
4738
4759
|
}
|
|
@@ -4746,7 +4767,7 @@
|
|
|
4746
4767
|
}),
|
|
4747
4768
|
// --- AFTER PREACTIVATION ---
|
|
4748
4769
|
switchTap(function (t) {
|
|
4749
|
-
var targetSnapshot = t.targetSnapshot, navigationId = t.id, appliedUrlTree = t.extractedUrl, rawUrlTree = t.rawUrl,
|
|
4770
|
+
var targetSnapshot = t.targetSnapshot, navigationId = t.id, appliedUrlTree = t.extractedUrl, rawUrlTree = t.rawUrl, _c = t.extras, skipLocationChange = _c.skipLocationChange, replaceUrl = _c.replaceUrl;
|
|
4750
4771
|
return _this.hooks.afterPreactivation(targetSnapshot, {
|
|
4751
4772
|
navigationId: navigationId,
|
|
4752
4773
|
appliedUrlTree: appliedUrlTree,
|
|
@@ -4790,20 +4811,46 @@
|
|
|
4790
4811
|
* event is fired when a navigation gets cancelled but not caught by other
|
|
4791
4812
|
* means. */
|
|
4792
4813
|
if (!completed && !errored) {
|
|
4793
|
-
|
|
4794
|
-
|
|
4795
|
-
|
|
4796
|
-
|
|
4797
|
-
|
|
4798
|
-
|
|
4799
|
-
|
|
4800
|
-
|
|
4814
|
+
var cancelationReason = "Navigation ID " + t.id + " is not equal to the current navigation id " + _this.navigationId;
|
|
4815
|
+
if (_this.canceledNavigationResolution === 'replace') {
|
|
4816
|
+
// Must reset to current URL tree here to ensure history.state is set. On
|
|
4817
|
+
// a fresh page load, if a new navigation comes in before a successful
|
|
4818
|
+
// navigation completes, there will be nothing in
|
|
4819
|
+
// history.state.navigationId. This can cause sync problems with
|
|
4820
|
+
// AngularJS sync code which looks for a value here in order to determine
|
|
4821
|
+
// whether or not to handle a given popstate event or to leave it to the
|
|
4822
|
+
// Angular router.
|
|
4823
|
+
_this.restoreHistory(t);
|
|
4824
|
+
_this.cancelNavigationTransition(t, cancelationReason);
|
|
4825
|
+
}
|
|
4826
|
+
else {
|
|
4827
|
+
// We cannot trigger a `location.historyGo` if the
|
|
4828
|
+
// cancellation was due to a new navigation before the previous could
|
|
4829
|
+
// complete. This is because `location.historyGo` triggers a `popstate`
|
|
4830
|
+
// which would also trigger another navigation. Instead, treat this as a
|
|
4831
|
+
// redirect and do not reset the state.
|
|
4832
|
+
_this.cancelNavigationTransition(t, cancelationReason);
|
|
4833
|
+
// TODO(atscott): The same problem happens here with a fresh page load
|
|
4834
|
+
// and a new navigation before that completes where we won't set a page
|
|
4835
|
+
// id.
|
|
4836
|
+
}
|
|
4801
4837
|
}
|
|
4802
4838
|
// currentNavigation should always be reset to null here. If navigation was
|
|
4803
4839
|
// successful, lastSuccessfulTransition will have already been set. Therefore
|
|
4804
4840
|
// we can safely set currentNavigation to null here.
|
|
4805
4841
|
_this.currentNavigation = null;
|
|
4806
4842
|
}), operators.catchError(function (e) {
|
|
4843
|
+
// TODO(atscott): The NavigationTransition `t` used here does not accurately
|
|
4844
|
+
// reflect the current state of the whole transition because some operations
|
|
4845
|
+
// return a new object rather than modifying the one in the outermost
|
|
4846
|
+
// `switchMap`.
|
|
4847
|
+
// The fix can likely be to:
|
|
4848
|
+
// 1. Rename the outer `t` variable so it's not shadowed all the time and
|
|
4849
|
+
// confusing
|
|
4850
|
+
// 2. Keep reassigning to the outer variable after each stage to ensure it
|
|
4851
|
+
// gets updated. Or change the implementations to not return a copy.
|
|
4852
|
+
// Not changed yet because it affects existing code and would need to be
|
|
4853
|
+
// tested more thoroughly.
|
|
4807
4854
|
errored = true;
|
|
4808
4855
|
/* This error type is issued during Redirect, and is handled as a
|
|
4809
4856
|
* cancellation rather than an error. */
|
|
@@ -4816,7 +4863,7 @@
|
|
|
4816
4863
|
// This is only applicable with initial navigation, so setting
|
|
4817
4864
|
// `navigated` only when not redirecting resolves this scenario.
|
|
4818
4865
|
_this.navigated = true;
|
|
4819
|
-
_this.
|
|
4866
|
+
_this.restoreHistory(t, true);
|
|
4820
4867
|
}
|
|
4821
4868
|
var navCancel = new NavigationCancel(t.id, _this.serializeUrl(t.extractedUrl), e.message);
|
|
4822
4869
|
eventsSubject.next(navCancel);
|
|
@@ -4843,7 +4890,7 @@
|
|
|
4843
4890
|
* the pre-error state. */
|
|
4844
4891
|
}
|
|
4845
4892
|
else {
|
|
4846
|
-
_this.
|
|
4893
|
+
_this.restoreHistory(t, true);
|
|
4847
4894
|
var navError = new NavigationError(t.id, _this.serializeUrl(t.extractedUrl), e);
|
|
4848
4895
|
eventsSubject.next(navError);
|
|
4849
4896
|
try {
|
|
@@ -4901,9 +4948,9 @@
|
|
|
4901
4948
|
if (!this.locationSubscription) {
|
|
4902
4949
|
this.locationSubscription = this.location.subscribe(function (event) {
|
|
4903
4950
|
var currentChange = _this.extractLocationChangeInfoFromEvent(event);
|
|
4951
|
+
// The `setTimeout` was added in #12160 and is likely to support Angular/AngularJS
|
|
4952
|
+
// hybrid apps.
|
|
4904
4953
|
if (_this.shouldScheduleNavigation(_this.lastLocationChangeInfo, currentChange)) {
|
|
4905
|
-
// The `setTimeout` was added in #12160 and is likely to support Angular/AngularJS
|
|
4906
|
-
// hybrid apps.
|
|
4907
4954
|
setTimeout(function () {
|
|
4908
4955
|
var source = currentChange.source, state = currentChange.state, urlTree = currentChange.urlTree;
|
|
4909
4956
|
var extras = { replaceUrl: true };
|
|
@@ -5111,14 +5158,7 @@
|
|
|
5111
5158
|
}
|
|
5112
5159
|
var urlTree = isUrlTree(url) ? url : this.parseUrl(url);
|
|
5113
5160
|
var mergedTree = this.urlHandlingStrategy.merge(urlTree, this.rawUrlTree);
|
|
5114
|
-
|
|
5115
|
-
if (this.canceledNavigationResolution === 'computed') {
|
|
5116
|
-
var isInitialPage = this.currentPageId === 0;
|
|
5117
|
-
if (isInitialPage || extras.skipLocationChange || extras.replaceUrl) {
|
|
5118
|
-
restoredState = this.location.getState();
|
|
5119
|
-
}
|
|
5120
|
-
}
|
|
5121
|
-
return this.scheduleNavigation(mergedTree, 'imperative', restoredState, extras);
|
|
5161
|
+
return this.scheduleNavigation(mergedTree, 'imperative', null, extras);
|
|
5122
5162
|
};
|
|
5123
5163
|
/**
|
|
5124
5164
|
* Navigate based on the provided array of commands and a starting point.
|
|
@@ -5211,6 +5251,7 @@
|
|
|
5211
5251
|
});
|
|
5212
5252
|
};
|
|
5213
5253
|
Router.prototype.scheduleNavigation = function (rawUrl, source, restoredState, extras, priorPromise) {
|
|
5254
|
+
var _a, _b;
|
|
5214
5255
|
if (this.disposed) {
|
|
5215
5256
|
return Promise.resolve(false);
|
|
5216
5257
|
}
|
|
@@ -5254,13 +5295,25 @@
|
|
|
5254
5295
|
var id = ++this.navigationId;
|
|
5255
5296
|
var targetPageId;
|
|
5256
5297
|
if (this.canceledNavigationResolution === 'computed') {
|
|
5298
|
+
var isInitialPage = this.currentPageId === 0;
|
|
5299
|
+
if (isInitialPage) {
|
|
5300
|
+
restoredState = this.location.getState();
|
|
5301
|
+
}
|
|
5257
5302
|
// If the `ɵrouterPageId` exist in the state then `targetpageId` should have the value of
|
|
5258
|
-
// `ɵrouterPageId
|
|
5303
|
+
// `ɵrouterPageId`. This is the case for something like a page refresh where we assign the
|
|
5304
|
+
// target id to the previously set value for that page.
|
|
5259
5305
|
if (restoredState && restoredState.ɵrouterPageId) {
|
|
5260
5306
|
targetPageId = restoredState.ɵrouterPageId;
|
|
5261
5307
|
}
|
|
5262
5308
|
else {
|
|
5263
|
-
|
|
5309
|
+
// If we're replacing the URL or doing a silent navigation, we do not want to increment the
|
|
5310
|
+
// page id because we aren't pushing a new entry to history.
|
|
5311
|
+
if (extras.replaceUrl || extras.skipLocationChange) {
|
|
5312
|
+
targetPageId = (_a = this.browserPageId) !== null && _a !== void 0 ? _a : 0;
|
|
5313
|
+
}
|
|
5314
|
+
else {
|
|
5315
|
+
targetPageId = ((_b = this.browserPageId) !== null && _b !== void 0 ? _b : 0) + 1;
|
|
5316
|
+
}
|
|
5264
5317
|
}
|
|
5265
5318
|
}
|
|
5266
5319
|
else {
|
|
@@ -5298,41 +5351,60 @@
|
|
|
5298
5351
|
this.location.go(path, '', state);
|
|
5299
5352
|
}
|
|
5300
5353
|
};
|
|
5301
|
-
Router.prototype.resetStateAndUrl = function (storedState, storedUrl, rawUrl) {
|
|
5302
|
-
this.routerState = storedState;
|
|
5303
|
-
this.currentUrlTree = storedUrl;
|
|
5304
|
-
this.rawUrlTree = this.urlHandlingStrategy.merge(this.currentUrlTree, rawUrl);
|
|
5305
|
-
this.resetUrlToCurrentUrlTree();
|
|
5306
|
-
};
|
|
5307
|
-
Router.prototype.resetUrlToCurrentUrlTree = function () {
|
|
5308
|
-
this.location.replaceState(this.urlSerializer.serialize(this.rawUrlTree), '', this.generateNgRouterState(this.lastSuccessfulId, this.currentPageId));
|
|
5309
|
-
};
|
|
5310
5354
|
/**
|
|
5311
|
-
*
|
|
5312
|
-
*
|
|
5313
|
-
* state before the transition
|
|
5314
|
-
* - triggers the `NavigationCancel` event
|
|
5315
|
-
* - resolves the transition promise with `false`
|
|
5355
|
+
* Performs the necessary rollback action to restore the browser URL to the
|
|
5356
|
+
* state before the transition.
|
|
5316
5357
|
*/
|
|
5317
|
-
Router.prototype.
|
|
5358
|
+
Router.prototype.restoreHistory = function (t, restoringFromCaughtError) {
|
|
5359
|
+
if (restoringFromCaughtError === void 0) { restoringFromCaughtError = false; }
|
|
5360
|
+
var _a, _b;
|
|
5318
5361
|
if (this.canceledNavigationResolution === 'computed') {
|
|
5362
|
+
var targetPagePosition = this.currentPageId - t.targetPageId;
|
|
5319
5363
|
// The navigator change the location before triggered the browser event,
|
|
5320
5364
|
// so we need to go back to the current url if the navigation is canceled.
|
|
5321
5365
|
// Also, when navigation gets cancelled while using url update strategy eager, then we need to
|
|
5322
5366
|
// go back. Because, when `urlUpdateSrategy` is `eager`; `setBrowserUrl` method is called
|
|
5323
5367
|
// before any verification.
|
|
5324
|
-
|
|
5325
|
-
|
|
5368
|
+
var browserUrlUpdateOccurred = (t.source === 'popstate' || this.urlUpdateStrategy === 'eager' ||
|
|
5369
|
+
this.currentUrlTree === ((_a = this.currentNavigation) === null || _a === void 0 ? void 0 : _a.finalUrl));
|
|
5370
|
+
if (browserUrlUpdateOccurred && targetPagePosition !== 0) {
|
|
5326
5371
|
this.location.historyGo(targetPagePosition);
|
|
5327
5372
|
}
|
|
5373
|
+
else if (this.currentUrlTree === ((_b = this.currentNavigation) === null || _b === void 0 ? void 0 : _b.finalUrl) && targetPagePosition === 0) {
|
|
5374
|
+
// We got to the activation stage (where currentUrlTree is set to the navigation's
|
|
5375
|
+
// finalUrl), but we weren't moving anywhere in history (skipLocationChange or replaceUrl).
|
|
5376
|
+
// We still need to reset the router state back to what it was when the navigation started.
|
|
5377
|
+
this.resetState(t);
|
|
5378
|
+
// TODO(atscott): resetting the `browserUrlTree` should really be done in `resetState`.
|
|
5379
|
+
// Investigate if this can be done by running TGP.
|
|
5380
|
+
this.browserUrlTree = t.currentUrlTree;
|
|
5381
|
+
this.resetUrlToCurrentUrlTree();
|
|
5382
|
+
}
|
|
5328
5383
|
else {
|
|
5329
|
-
//
|
|
5330
|
-
//
|
|
5384
|
+
// The browser URL and router state was not updated before the navigation cancelled so
|
|
5385
|
+
// there's no restoration needed.
|
|
5331
5386
|
}
|
|
5332
5387
|
}
|
|
5333
|
-
else {
|
|
5388
|
+
else if (this.canceledNavigationResolution === 'replace') {
|
|
5389
|
+
// TODO(atscott): It seems like we should _always_ reset the state here. It would be a no-op
|
|
5390
|
+
// for `deferred` navigations that haven't change the internal state yet because guards
|
|
5391
|
+
// reject. For 'eager' navigations, it seems like we also really should reset the state
|
|
5392
|
+
// because the navigation was cancelled. Investigate if this can be done by running TGP.
|
|
5393
|
+
if (restoringFromCaughtError) {
|
|
5394
|
+
this.resetState(t);
|
|
5395
|
+
}
|
|
5334
5396
|
this.resetUrlToCurrentUrlTree();
|
|
5335
5397
|
}
|
|
5398
|
+
};
|
|
5399
|
+
Router.prototype.resetState = function (t) {
|
|
5400
|
+
this.routerState = t.currentRouterState;
|
|
5401
|
+
this.currentUrlTree = t.currentUrlTree;
|
|
5402
|
+
this.rawUrlTree = this.urlHandlingStrategy.merge(this.currentUrlTree, t.rawUrl);
|
|
5403
|
+
};
|
|
5404
|
+
Router.prototype.resetUrlToCurrentUrlTree = function () {
|
|
5405
|
+
this.location.replaceState(this.urlSerializer.serialize(this.rawUrlTree), '', this.generateNgRouterState(this.lastSuccessfulId, this.currentPageId));
|
|
5406
|
+
};
|
|
5407
|
+
Router.prototype.cancelNavigationTransition = function (t, reason) {
|
|
5336
5408
|
var navCancel = new NavigationCancel(t.id, this.serializeUrl(t.extractedUrl), reason);
|
|
5337
5409
|
this.triggerEvent(navCancel);
|
|
5338
5410
|
t.resolve(false);
|
|
@@ -6655,7 +6727,7 @@
|
|
|
6655
6727
|
/**
|
|
6656
6728
|
* @publicApi
|
|
6657
6729
|
*/
|
|
6658
|
-
var VERSION = new core.Version('12.1.
|
|
6730
|
+
var VERSION = new core.Version('12.1.4');
|
|
6659
6731
|
|
|
6660
6732
|
/**
|
|
6661
6733
|
* @license
|