@angular/router 12.0.4 → 12.0.5

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.
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license Angular v12.0.4
2
+ * @license Angular v12.0.5
3
3
  * (c) 2010-2021 Google LLC. https://angular.io/
4
4
  * License: MIT
5
5
  */
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license Angular v12.0.4
2
+ * @license Angular v12.0.5
3
3
  * (c) 2010-2021 Google LLC. https://angular.io/
4
4
  * License: MIT
5
5
  */
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license Angular v12.0.4
2
+ * @license Angular v12.0.5
3
3
  * (c) 2010-2021 Google LLC. https://angular.io/
4
4
  * License: MIT
5
5
  */
@@ -4463,6 +4463,11 @@
4463
4463
  */
4464
4464
  this.lastLocationChangeInfo = null;
4465
4465
  this.navigationId = 0;
4466
+ /**
4467
+ * The id of the currently active page in the router.
4468
+ * Updated to the transition's target id on a successful navigation.
4469
+ */
4470
+ this.currentPageId = 0;
4466
4471
  this.isNgZoneEnabled = false;
4467
4472
  /**
4468
4473
  * An event stream for routing events in this NgModule.
@@ -4539,6 +4544,24 @@
4539
4544
  * @see `RouterModule`
4540
4545
  */
4541
4546
  this.relativeLinkResolution = 'corrected';
4547
+ /**
4548
+ * Configures how the Router attempts to restore state when a navigation is cancelled.
4549
+ *
4550
+ * 'replace' - Always uses `location.replaceState` to set the browser state to the state of the
4551
+ * router before the navigation started.
4552
+ *
4553
+ * 'computed' - Will always return to the same state that corresponds to the actual Angular route
4554
+ * when the navigation gets cancelled right after triggering a `popstate` event.
4555
+ *
4556
+ * The default value is `replace`
4557
+ *
4558
+ * @internal
4559
+ */
4560
+ // TODO(atscott): Determine how/when/if to make this public API
4561
+ // This shouldn’t be an option at all but may need to be in order to allow migration without a
4562
+ // breaking change. We need to determine if it should be made into public api (or if we forgo
4563
+ // the option and release as a breaking change bug fix in a major version).
4564
+ this.canceledNavigationResolution = 'replace';
4542
4565
  var onLoadStart = function (r) { return _this.triggerEvent(new RouteConfigLoadStart(r)); };
4543
4566
  var onLoadEnd = function (r) { return _this.triggerEvent(new RouteConfigLoadEnd(r)); };
4544
4567
  this.ngModule = injector.get(core.NgModuleRef);
@@ -4553,6 +4576,7 @@
4553
4576
  this.routerState = createEmptyState(this.currentUrlTree, this.rootComponentType);
4554
4577
  this.transitions = new rxjs.BehaviorSubject({
4555
4578
  id: 0,
4579
+ targetPageId: 0,
4556
4580
  currentUrlTree: this.currentUrlTree,
4557
4581
  currentRawUrl: this.currentUrlTree,
4558
4582
  extractedUrl: this.urlHandlingStrategy.extract(this.currentUrlTree),
@@ -4626,7 +4650,7 @@
4626
4650
  operators.tap(function (t) {
4627
4651
  if (_this.urlUpdateStrategy === 'eager') {
4628
4652
  if (!t.extras.skipLocationChange) {
4629
- _this.setBrowserUrl(t.urlAfterRedirects, !!t.extras.replaceUrl, t.id, t.extras.state);
4653
+ _this.setBrowserUrl(t.urlAfterRedirects, t);
4630
4654
  }
4631
4655
  _this.browserUrlTree = t.urlAfterRedirects;
4632
4656
  }
@@ -4686,10 +4710,7 @@
4686
4710
  _this.triggerEvent(guardsEnd);
4687
4711
  }), operators.filter(function (t) {
4688
4712
  if (!t.guardsResult) {
4689
- _this.resetUrlToCurrentUrlTree();
4690
- var navCancel = new NavigationCancel(t.id, _this.serializeUrl(t.extractedUrl), '');
4691
- eventsSubject.next(navCancel);
4692
- t.resolve(false);
4713
+ _this.cancelNavigationTransition(t, '');
4693
4714
  return false;
4694
4715
  }
4695
4716
  return true;
@@ -4706,9 +4727,7 @@
4706
4727
  next: function () { return dataResolved = true; },
4707
4728
  complete: function () {
4708
4729
  if (!dataResolved) {
4709
- var navCancel = new NavigationCancel(t.id, _this.serializeUrl(t.extractedUrl), "At least one route resolver didn't emit any value.");
4710
- eventsSubject.next(navCancel);
4711
- t.resolve(false);
4730
+ _this.cancelNavigationTransition(t, "At least one route resolver didn't emit any value.");
4712
4731
  }
4713
4732
  }
4714
4733
  }));
@@ -4745,7 +4764,7 @@
4745
4764
  _this.routerState = t.targetRouterState;
4746
4765
  if (_this.urlUpdateStrategy === 'deferred') {
4747
4766
  if (!t.extras.skipLocationChange) {
4748
- _this.setBrowserUrl(_this.rawUrlTree, !!t.extras.replaceUrl, t.id, t.extras.state);
4767
+ _this.setBrowserUrl(_this.rawUrlTree, t);
4749
4768
  }
4750
4769
  _this.browserUrlTree = t.urlAfterRedirects;
4751
4770
  }
@@ -4772,10 +4791,7 @@
4772
4791
  // sync code which looks for a value here in order to determine whether or
4773
4792
  // not to handle a given popstate event or to leave it to the Angular
4774
4793
  // router.
4775
- _this.resetUrlToCurrentUrlTree();
4776
- var navCancel = new NavigationCancel(t.id, _this.serializeUrl(t.extractedUrl), "Navigation ID " + t.id + " is not equal to the current navigation id " + _this.navigationId);
4777
- eventsSubject.next(navCancel);
4778
- t.resolve(false);
4794
+ _this.cancelNavigationTransition(t, "Navigation ID " + t.id + " is not equal to the current navigation id " + _this.navigationId);
4779
4795
  }
4780
4796
  // currentNavigation should always be reset to null here. If navigation was
4781
4797
  // successful, lastSuccessfulTransition will have already been set. Therefore
@@ -4888,6 +4904,7 @@
4888
4904
  if (state) {
4889
4905
  var stateCopy = Object.assign({}, state);
4890
4906
  delete stateCopy.navigationId;
4907
+ delete stateCopy.ɵrouterPageId;
4891
4908
  if (Object.keys(stateCopy).length !== 0) {
4892
4909
  extras.state = stateCopy;
4893
4910
  }
@@ -5088,7 +5105,14 @@
5088
5105
  }
5089
5106
  var urlTree = isUrlTree(url) ? url : this.parseUrl(url);
5090
5107
  var mergedTree = this.urlHandlingStrategy.merge(urlTree, this.rawUrlTree);
5091
- return this.scheduleNavigation(mergedTree, 'imperative', null, extras);
5108
+ var restoredState = null;
5109
+ if (this.canceledNavigationResolution === 'computed') {
5110
+ var isInitialPage = this.currentPageId === 0;
5111
+ if (isInitialPage || extras.skipLocationChange || extras.replaceUrl) {
5112
+ restoredState = this.location.getState();
5113
+ }
5114
+ }
5115
+ return this.scheduleNavigation(mergedTree, 'imperative', restoredState, extras);
5092
5116
  };
5093
5117
  /**
5094
5118
  * Navigate based on the provided array of commands and a starting point.
@@ -5171,6 +5195,7 @@
5171
5195
  this.navigations.subscribe(function (t) {
5172
5196
  _this.navigated = true;
5173
5197
  _this.lastSuccessfulId = t.id;
5198
+ _this.currentPageId = t.targetPageId;
5174
5199
  _this.events
5175
5200
  .next(new NavigationEnd(t.id, _this.serializeUrl(t.extractedUrl), _this.serializeUrl(_this.currentUrlTree)));
5176
5201
  _this.lastSuccessfulNavigation = _this.currentNavigation;
@@ -5221,8 +5246,24 @@
5221
5246
  });
5222
5247
  }
5223
5248
  var id = ++this.navigationId;
5249
+ var targetPageId;
5250
+ if (this.canceledNavigationResolution === 'computed') {
5251
+ // If the `ɵrouterPageId` exist in the state then `targetpageId` should have the value of
5252
+ // `ɵrouterPageId`
5253
+ if (restoredState && restoredState.ɵrouterPageId) {
5254
+ targetPageId = restoredState.ɵrouterPageId;
5255
+ }
5256
+ else {
5257
+ targetPageId = this.currentPageId + 1;
5258
+ }
5259
+ }
5260
+ else {
5261
+ // This is unused when `canceledNavigationResolution` is not computed.
5262
+ targetPageId = 0;
5263
+ }
5224
5264
  this.setTransition({
5225
5265
  id: id,
5266
+ targetPageId: targetPageId,
5226
5267
  source: source,
5227
5268
  restoredState: restoredState,
5228
5269
  currentUrlTree: this.currentUrlTree,
@@ -5241,15 +5282,14 @@
5241
5282
  return Promise.reject(e);
5242
5283
  });
5243
5284
  };
5244
- Router.prototype.setBrowserUrl = function (url, replaceUrl, id, state) {
5285
+ Router.prototype.setBrowserUrl = function (url, t) {
5245
5286
  var path = this.urlSerializer.serialize(url);
5246
- state = state || {};
5247
- if (this.location.isCurrentPathEqualTo(path) || replaceUrl) {
5248
- // TODO(jasonaden): Remove first `navigationId` and rely on `ng` namespace.
5249
- this.location.replaceState(path, '', Object.assign(Object.assign({}, state), { navigationId: id }));
5287
+ var state = Object.assign(Object.assign({}, t.extras.state), this.generateNgRouterState(t.id, t.targetPageId));
5288
+ if (this.location.isCurrentPathEqualTo(path) || !!t.extras.replaceUrl) {
5289
+ this.location.replaceState(path, '', state);
5250
5290
  }
5251
5291
  else {
5252
- this.location.go(path, '', Object.assign(Object.assign({}, state), { navigationId: id }));
5292
+ this.location.go(path, '', state);
5253
5293
  }
5254
5294
  };
5255
5295
  Router.prototype.resetStateAndUrl = function (storedState, storedUrl, rawUrl) {
@@ -5259,7 +5299,43 @@
5259
5299
  this.resetUrlToCurrentUrlTree();
5260
5300
  };
5261
5301
  Router.prototype.resetUrlToCurrentUrlTree = function () {
5262
- this.location.replaceState(this.urlSerializer.serialize(this.rawUrlTree), '', { navigationId: this.lastSuccessfulId });
5302
+ this.location.replaceState(this.urlSerializer.serialize(this.rawUrlTree), '', this.generateNgRouterState(this.lastSuccessfulId, this.currentPageId));
5303
+ };
5304
+ /**
5305
+ * Responsible for handling the cancellation of a navigation:
5306
+ * - performs the necessary rollback action to restore the browser URL to the
5307
+ * state before the transition
5308
+ * - triggers the `NavigationCancel` event
5309
+ * - resolves the transition promise with `false`
5310
+ */
5311
+ Router.prototype.cancelNavigationTransition = function (t, reason) {
5312
+ if (this.canceledNavigationResolution === 'computed') {
5313
+ // The navigator change the location before triggered the browser event,
5314
+ // so we need to go back to the current url if the navigation is canceled.
5315
+ // Also, when navigation gets cancelled while using url update strategy eager, then we need to
5316
+ // go back. Because, when `urlUpdateSrategy` is `eager`; `setBrowserUrl` method is called
5317
+ // before any verification.
5318
+ if (t.source === 'popstate' || this.urlUpdateStrategy === 'eager') {
5319
+ var targetPagePosition = this.currentPageId - t.targetPageId;
5320
+ this.location.historyGo(targetPagePosition);
5321
+ }
5322
+ else {
5323
+ // If update is not 'eager' and the transition navigation source isn't 'popstate', then the
5324
+ // navigation was cancelled before any browser url change so nothing needs to be restored.
5325
+ }
5326
+ }
5327
+ else {
5328
+ this.resetUrlToCurrentUrlTree();
5329
+ }
5330
+ var navCancel = new NavigationCancel(t.id, this.serializeUrl(t.extractedUrl), reason);
5331
+ this.triggerEvent(navCancel);
5332
+ t.resolve(false);
5333
+ };
5334
+ Router.prototype.generateNgRouterState = function (navigationId, routerPageId) {
5335
+ if (this.canceledNavigationResolution === 'computed') {
5336
+ return { navigationId: navigationId, ɵrouterPageId: routerPageId };
5337
+ }
5338
+ return { navigationId: navigationId };
5263
5339
  };
5264
5340
  return Router;
5265
5341
  }());
@@ -6565,7 +6641,7 @@
6565
6641
  /**
6566
6642
  * @publicApi
6567
6643
  */
6568
- var VERSION = new core.Version('12.0.4');
6644
+ var VERSION = new core.Version('12.0.5');
6569
6645
 
6570
6646
  /**
6571
6647
  * @license