@coolon/angular-ui-powerups 0.0.116 → 0.0.117

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.
@@ -4,7 +4,7 @@ import { FormsModule } from '@angular/forms';
4
4
  import { MatInputModule, MatFormFieldModule, MatSelectModule, MatButtonModule, MatDialogModule, MatTabsModule as MatTabsModule$1, MatProgressSpinnerModule, MatDialog } from '@angular/material';
5
5
  import { MatTabsModule } from '@angular/material/tabs';
6
6
  import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
7
- import { GarbageCollector, DelegatingValueModel, assert, UnaryCommand, lang, Dsl, Logger, DelegatingFormValueModel, UseDelegate, ValueModel, ListModel, StoreInListModel, DelegatingListModel, Deferred, MutableStream, MutableValueModel, MutableListModel, DebugContext, Binding, Guard, StoreInValueModel, Command, ValueHolder } from '@coolon/pectin';
7
+ import { GarbageCollector, DelegatingValueModel, assert, UnaryCommand, lang, Dsl, Logger, DelegatingFormValueModel, UseDelegate, ValueModel, ListModel, StoreInListModel, DelegatingListModel, Deferred, MutableStream, MutableValueModel, MutableListModel, Binding, Guard, StoreInValueModel, Command, ValueHolder } from '@coolon/pectin';
8
8
  import { __decorate, __metadata, __awaiter } from 'tslib';
9
9
  import { PortalModule } from '@angular/cdk/portal';
10
10
  import { RouterModule, UrlSegment, NavigationStart, NavigationEnd, NavigationError, NavigationCancel, Router, UrlSerializer } from '@angular/router';
@@ -2676,7 +2676,7 @@ class PlaceComponent extends DisposableComponent {
2676
2676
  initialiseBindings(visit) {
2677
2677
  assert.isNil(this.visit);
2678
2678
  this.visit = visit;
2679
- DebugContext.get(this.visit).tag(`${this.placeDefinition.component.name}.visit`);
2679
+ // DebugContext.get(this.visit).tag(`${this.placeDefinition.component.name}.visit`);
2680
2680
  this.placeDefinition.getVisitParameterDefs().forEach((/**
2681
2681
  * @param {?} parameterDef
2682
2682
  * @return {?}
@@ -3061,6 +3061,7 @@ class NavigationState extends GarbageCollector {
3061
3061
  super();
3062
3062
  this.context = context;
3063
3063
  this._visits = new Map();
3064
+ this.debugPropertyKeys = [];
3064
3065
  }
3065
3066
  /**
3066
3067
  * @return {?}
@@ -3197,14 +3198,18 @@ class NavigationState extends GarbageCollector {
3197
3198
  createTransitionStateFor(event) {
3198
3199
  /** @type {?} */
3199
3200
  const popstate = event.navigationTrigger === 'popstate';
3200
- return popstate ?
3201
- this.interactionService.isActive() ?
3202
- new NavigationState.InteractionPopStateTransition(this.context, this.currentRouterUrl()) :
3203
- new NavigationState.PopStateTransition(this.context, this.currentRouterUrl())
3204
- :
3205
- this.interactionService.isActive() ?
3206
- new NavigationState.InteractionTransition(this.context, this.currentRouterUrl()) :
3207
- new NavigationState.NavigationTransition(this.context, this.currentRouterUrl());
3201
+ /** @type {?} */
3202
+ const inInteraction = this.interactionService.isActive();
3203
+ if (popstate) {
3204
+ return inInteraction ?
3205
+ new NavigationState.LeavingInteractionAfterPopStateTransition(this.context, this.currentRouterUrl(), event.url) :
3206
+ new NavigationState.PopStateTransition(this.context, this.currentRouterUrl(), event.url);
3207
+ }
3208
+ else {
3209
+ return inInteraction ?
3210
+ new NavigationState.StartingInteractionTransition(this.context, this.currentRouterUrl()) :
3211
+ new NavigationState.NavigationTransition(this.context, this.currentRouterUrl());
3212
+ }
3208
3213
  }
3209
3214
  /**
3210
3215
  * @protected
@@ -3215,6 +3220,7 @@ class NavigationState extends GarbageCollector {
3215
3220
  new NavigationState.IdleDuringInteraction(this.context, this.currentRouterUrl()) :
3216
3221
  new NavigationState.Idle(this.context);
3217
3222
  }
3223
+ //
3218
3224
  /**
3219
3225
  * @param {?} url
3220
3226
  * @return {?}
@@ -3222,11 +3228,35 @@ class NavigationState extends GarbageCollector {
3222
3228
  resetBrowserLocation(url) {
3223
3229
  this.placeRouter.resetBrowserLocation(url);
3224
3230
  }
3231
+ /**
3232
+ * @param {?} event
3233
+ * @param {?=} reason
3234
+ * @return {?}
3235
+ */
3236
+ ignore(event, reason) {
3237
+ reason = reason ? ` -> ${reason}` : '';
3238
+ Logger.get(this).info(`Ignoring router event${reason}: ${event.constructor.name} -> ${event.url} :: ${this.toString()}`);
3239
+ return this;
3240
+ }
3225
3241
  /**
3226
3242
  * @return {?}
3227
3243
  */
3228
3244
  toString() {
3229
- return this.constructor.name;
3245
+ return `${this.constructor.name}(${this.debugState()})`;
3246
+ }
3247
+ /**
3248
+ * @protected
3249
+ * @param {?=} properties
3250
+ * @return {?}
3251
+ */
3252
+ debugState(properties) {
3253
+ return (properties || this.debugPropertyKeys).map((/**
3254
+ * @param {?} p
3255
+ * @return {?}
3256
+ */
3257
+ p => {
3258
+ return `${p}: ${this[p]}`;
3259
+ })).join(', ');
3230
3260
  }
3231
3261
  }
3232
3262
  if (false) {
@@ -3241,6 +3271,8 @@ if (false) {
3241
3271
  NavigationState.prototype.startingUrl;
3242
3272
  /** @type {?} */
3243
3273
  NavigationState.prototype.isPopState;
3274
+ /** @type {?} */
3275
+ NavigationState.prototype.debugPropertyKeys;
3244
3276
  /**
3245
3277
  * @type {?}
3246
3278
  * @protected
@@ -3302,7 +3334,7 @@ if (false) {
3302
3334
  }
3303
3335
  if (this.placeRouter.hasActiveInteractionIds(event.url)) {
3304
3336
  Logger.get(this).info(`navigation started with interaction outlet -> ${event.url}`);
3305
- return new InteractionTransition(this.context, event.url);
3337
+ return new StartingInteractionTransition(this.context, event.url);
3306
3338
  }
3307
3339
  else {
3308
3340
  return this.createTransitionStateFor(event);
@@ -3377,10 +3409,10 @@ if (false) {
3377
3409
  return new Idle(this.context);
3378
3410
  }
3379
3411
  /**
3380
- * @param {?} locationTriggerUrl
3412
+ * @param {?} newUrl
3381
3413
  * @return {?}
3382
3414
  */
3383
- onBackClickedDuringNavigationInteraction(locationTriggerUrl) {
3415
+ onBackClickedDuringNavigationInteraction(newUrl) {
3384
3416
  Logger.get(this).info(`back button pressed during navigation session interaction promise`);
3385
3417
  // detach the interaction from the session so it doesn't get disposed until the activity has completed.
3386
3418
  /** @type {?} */
@@ -3388,15 +3420,15 @@ if (false) {
3388
3420
  const { when } = Dsl.disposeWith(navigationInteraction);
3389
3421
  // TODO: I need to make the exclusive interaction context disallow nested activities or
3390
3422
  // that would mess things up entirely. Or, can I do a context.abortAll().then(..)
3423
+ Logger.get(this).info('cancelling current navigation activity..');
3391
3424
  navigationInteraction.cancelActiveActivity().then((/**
3392
3425
  * @return {?}
3393
3426
  */
3394
3427
  () => {
3395
3428
  navigationInteraction.dispose();
3396
3429
  }));
3397
- return new CancelledDuringNavigationInteraction(this.context, this.startingUrl, this.isPopState, locationTriggerUrl);
3430
+ return this.createNavigationInteractionCancelledState(newUrl);
3398
3431
  }
3399
- // @Trace()
3400
3432
  /**
3401
3433
  * @param {?} component
3402
3434
  * @param {?} currentUrl
@@ -3418,7 +3450,7 @@ if (false) {
3418
3450
  });
3419
3451
  }
3420
3452
  /**
3421
- * @private
3453
+ * @protected
3422
3454
  * @return {?}
3423
3455
  */
3424
3456
  detachInteractionContext() {
@@ -3444,11 +3476,18 @@ if (false) {
3444
3476
  AbstractNavigationTransition.prototype._interactionContext;
3445
3477
  /** @type {?} */
3446
3478
  AbstractNavigationTransition.prototype.startingUrl;
3479
+ /**
3480
+ * @abstract
3481
+ * @param {?} newUrl
3482
+ * @return {?}
3483
+ */
3484
+ AbstractNavigationTransition.prototype.createNavigationInteractionCancelledState = function (newUrl) { };
3447
3485
  }
3448
3486
  class NavigationTransition extends AbstractNavigationTransition {
3449
3487
  constructor() {
3450
3488
  super(...arguments);
3451
3489
  this.isPopState = false;
3490
+ this.debugPropertyKeys = ['startingUrl'];
3452
3491
  }
3453
3492
  /**
3454
3493
  * @param {?} event
@@ -3466,21 +3505,31 @@ if (false) {
3466
3505
  return new Idle(this.context);
3467
3506
  }
3468
3507
  /**
3508
+ * @param {?} newUrl
3469
3509
  * @return {?}
3470
3510
  */
3471
- toString() {
3472
- return `${this.constructor.name}(startingUrl: ${this.startingUrl})`;
3511
+ createNavigationInteractionCancelledState(newUrl) {
3512
+ return new LinkTriggeredNavigationInteractionCancelled(this.context, this.startingUrl, newUrl);
3473
3513
  }
3474
3514
  }
3475
3515
  NavigationState.NavigationTransition = NavigationTransition;
3476
3516
  if (false) {
3477
3517
  /** @type {?} */
3478
3518
  NavigationTransition.prototype.isPopState;
3519
+ /** @type {?} */
3520
+ NavigationTransition.prototype.debugPropertyKeys;
3479
3521
  }
3480
3522
  class PopStateTransition extends AbstractNavigationTransition {
3481
- constructor() {
3482
- super(...arguments);
3523
+ /**
3524
+ * @param {?} context
3525
+ * @param {?} startingUrl
3526
+ * @param {?} poppedHistoryUrl
3527
+ */
3528
+ constructor(context, startingUrl, poppedHistoryUrl) {
3529
+ super(context, startingUrl);
3530
+ this.poppedHistoryUrl = poppedHistoryUrl;
3483
3531
  this.isPopState = true;
3532
+ this.debugPropertyKeys = ['startingUrl', 'poppedHistoryUrl'];
3484
3533
  }
3485
3534
  /**
3486
3535
  * @param {?} event
@@ -3490,7 +3539,8 @@ if (false) {
3490
3539
  // Angular doesn't preserve the url when a guard cancels the back button.
3491
3540
  // See https://github.com/angular/angular/issues/13586#issuecomment-432795720
3492
3541
  Logger.get(this).info('WORK-AROUND: Updating browser location after pop state - see angular issue #13586');
3493
- this.resetBrowserLocation(this.startingUrl);
3542
+ this.resetBrowserLocation(this.poppedHistoryUrl); // put the popped history item back in.
3543
+ this.resetBrowserLocation(this.startingUrl); // and now put our own url back in.
3494
3544
  return new Idle(this.context);
3495
3545
  }
3496
3546
  /**
@@ -3503,16 +3553,54 @@ if (false) {
3503
3553
  // Angular doesn't preserve the url when a guard cancels the back button.
3504
3554
  // See https://github.com/angular/angular/issues/13586#issuecomment-432795720
3505
3555
  Logger.get(this).info('WORK-AROUND: Updating browser location after pop state - see angular issue #13586');
3506
- this.resetBrowserLocation(this.startingUrl);
3556
+ this.resetBrowserLocation(this.poppedHistoryUrl); // put the popped history item back in.
3557
+ this.resetBrowserLocation(this.startingUrl); // and now put our own url back in.
3507
3558
  }
3508
3559
  return new Idle(this.context);
3509
3560
  }
3561
+ /**
3562
+ * @param {?} locationTriggerUrl
3563
+ * @return {?}
3564
+ */
3565
+ createNavigationInteractionCancelledState(locationTriggerUrl) {
3566
+ return new PopStateTriggeredNavigationInteractionCancelled(this.context, this.startingUrl, locationTriggerUrl, this.poppedHistoryUrl);
3567
+ }
3510
3568
  }
3511
3569
  NavigationState.PopStateTransition = PopStateTransition;
3512
3570
  if (false) {
3513
3571
  /** @type {?} */
3514
3572
  PopStateTransition.prototype.isPopState;
3573
+ /** @type {?} */
3574
+ PopStateTransition.prototype.debugPropertyKeys;
3575
+ /** @type {?} */
3576
+ PopStateTransition.prototype.poppedHistoryUrl;
3515
3577
  }
3578
+ /**
3579
+ * @abstract
3580
+ */
3581
+ class AbstractInteractionTransition extends AbstractNavigationTransition {
3582
+ /**
3583
+ * @param {?} context
3584
+ * @param {?} startingUrl
3585
+ */
3586
+ constructor(context, startingUrl) {
3587
+ super(context, startingUrl);
3588
+ this.startingUrl = startingUrl;
3589
+ this.isTransitional = true;
3590
+ }
3591
+ }
3592
+ NavigationState.AbstractInteractionTransition = AbstractInteractionTransition;
3593
+ if (false) {
3594
+ /** @type {?} */
3595
+ AbstractInteractionTransition.prototype.isTransitional;
3596
+ /** @type {?} */
3597
+ AbstractInteractionTransition.prototype.startingUrl;
3598
+ }
3599
+ // The following states exist to handle all events while any kind of navigation is in progress. That way all other states can
3600
+ // happily ignore interaction contexts.
3601
+ /**
3602
+ * This is the non transitional (i.e. rest) state that is used whenever an interaction context is active.
3603
+ */
3516
3604
  class IdleDuringInteraction extends NavigationState {
3517
3605
  /**
3518
3606
  * @param {?} context
@@ -3523,6 +3611,7 @@ if (false) {
3523
3611
  this.startingUrl = startingUrl;
3524
3612
  this.isTransitional = false;
3525
3613
  this.isPopState = false;
3614
+ this.debugPropertyKeys = ['startingUrl'];
3526
3615
  }
3527
3616
  /**
3528
3617
  * @param {?} visit
@@ -3530,26 +3619,26 @@ if (false) {
3530
3619
  * @return {?}
3531
3620
  */
3532
3621
  onPlaceNavigationStart(visit, initialUrl) {
3622
+ // we're in an interaction and the user clicked back
3533
3623
  /** @type {?} */
3534
- const navigationTransition = new InteractionTransition(this.context, initialUrl);
3624
+ const navigationTransition = new StartingInteractionTransition(this.context, initialUrl);
3535
3625
  navigationTransition.storeVisit(visit);
3536
3626
  return navigationTransition;
3537
3627
  }
3538
- // @Trace()
3539
3628
  /**
3540
3629
  * @param {?} event
3541
3630
  * @return {?}
3542
3631
  */
3543
3632
  onRouterStarted(event) {
3544
- return new InteractionTransition(this.context, event.url);
3633
+ return new StartingInteractionTransition(this.context, event.url);
3545
3634
  }
3546
- // @Trace()
3547
3635
  /**
3548
3636
  * @param {?} event
3549
3637
  * @return {?}
3550
3638
  */
3551
3639
  onPopState(event) {
3552
- return new InteractionPopStateTransition(this.context, event.url);
3640
+ // we're in an interaction and the user clicked back
3641
+ return new LeavingInteractionAfterPopStateTransition(this.context, event.url, event.url);
3553
3642
  }
3554
3643
  }
3555
3644
  NavigationState.IdleDuringInteraction = IdleDuringInteraction;
@@ -3559,39 +3648,21 @@ if (false) {
3559
3648
  /** @type {?} */
3560
3649
  IdleDuringInteraction.prototype.isPopState;
3561
3650
  /** @type {?} */
3562
- IdleDuringInteraction.prototype.startingUrl;
3563
- }
3564
- /**
3565
- * @abstract
3566
- */
3567
- class AbstractInteractionTransition extends AbstractNavigationTransition {
3568
- /**
3569
- * @param {?} context
3570
- * @param {?} startingUrl
3571
- */
3572
- constructor(context, startingUrl) {
3573
- super(context, startingUrl);
3574
- this.startingUrl = startingUrl;
3575
- this.isTransitional = true;
3576
- }
3577
- }
3578
- NavigationState.AbstractInteractionTransition = AbstractInteractionTransition;
3579
- if (false) {
3580
- /** @type {?} */
3581
- AbstractInteractionTransition.prototype.isTransitional;
3651
+ IdleDuringInteraction.prototype.debugPropertyKeys;
3582
3652
  /** @type {?} */
3583
- AbstractInteractionTransition.prototype.startingUrl;
3653
+ IdleDuringInteraction.prototype.startingUrl;
3584
3654
  }
3585
3655
  /**
3586
3656
  * This state exists to handle all events while any kind of navigation is in progress. That way all other states can
3587
3657
  * happily ignore interaction contexts.
3658
+ * NOTE: This state is activated when ever an interaction is started. It might be better to split it into
3659
+ * different states for different scenarios, e.g. starting model, starting model during route guard etc.
3588
3660
  */
3589
- class InteractionTransition extends AbstractInteractionTransition {
3661
+ class StartingInteractionTransition extends AbstractInteractionTransition {
3590
3662
  constructor() {
3591
3663
  super(...arguments);
3592
3664
  this.isPopState = false;
3593
3665
  }
3594
- // @Trace()
3595
3666
  /**
3596
3667
  * @param {?} event
3597
3668
  * @return {?}
@@ -3607,7 +3678,6 @@ if (false) {
3607
3678
  return new Idle(this.context);
3608
3679
  }
3609
3680
  }
3610
- // @Trace()
3611
3681
  /**
3612
3682
  * @param {?} event
3613
3683
  * @return {?}
@@ -3616,7 +3686,6 @@ if (false) {
3616
3686
  // navigation was aborted.
3617
3687
  return new IdleDuringInteraction(this.context, this.startingUrl);
3618
3688
  }
3619
- // @Trace()
3620
3689
  /**
3621
3690
  * @param {?} event
3622
3691
  * @return {?}
@@ -3629,22 +3698,137 @@ if (false) {
3629
3698
  return new Idle(this.context);
3630
3699
  }
3631
3700
  }
3701
+ /**
3702
+ * @param {?} locationTriggerUrl
3703
+ * @return {?}
3704
+ */
3705
+ createNavigationInteractionCancelledState(locationTriggerUrl) {
3706
+ return new LeavingInteractionTransitionCancelled(this.context, this.startingUrl, locationTriggerUrl);
3707
+ }
3632
3708
  }
3633
- NavigationState.InteractionTransition = InteractionTransition;
3709
+ NavigationState.StartingInteractionTransition = StartingInteractionTransition;
3634
3710
  if (false) {
3635
3711
  /** @type {?} */
3636
- InteractionTransition.prototype.isPopState;
3712
+ StartingInteractionTransition.prototype.isPopState;
3713
+ }
3714
+ /**
3715
+ * The sequence of router events are:
3716
+ * Error -> url = url of navigation link
3717
+ * End
3718
+ * onPopState url = current intereaction url sans the query params
3719
+ * Cancel url == same as above.
3720
+ */
3721
+ class LeavingInteractionTransitionCancelled extends NavigationState {
3722
+ /**
3723
+ * @param {?} context
3724
+ * @param {?} startingUrl
3725
+ * @param {?} locationChangeTriggerUrl
3726
+ */
3727
+ constructor(context, startingUrl, locationChangeTriggerUrl) {
3728
+ super(context);
3729
+ this.startingUrl = startingUrl;
3730
+ this.locationChangeTriggerUrl = locationChangeTriggerUrl;
3731
+ this.isPopState = false;
3732
+ this.firstCancelHandled = false;
3733
+ this.popStateHandled = false;
3734
+ this.debugPropertyKeys = ['idle', 'startingUrl', 'poppedHistoryUrl', 'locationChangeTriggerUrl', 'popStateEventUrl', 'firstCancelHandled', 'popStateHandled'];
3735
+ }
3736
+ /**
3737
+ * @return {?}
3738
+ */
3739
+ get isTransitional() {
3740
+ return true;
3741
+ }
3742
+ /**
3743
+ * @param {?} event
3744
+ * @return {?}
3745
+ */
3746
+ onRouterStarted(event) {
3747
+ return this.ignore(event);
3748
+ }
3749
+ /**
3750
+ * @param {?} event
3751
+ * @return {?}
3752
+ */
3753
+ onRouterCancelled(event) {
3754
+ // Angular doesn't preserve the url when a guard cancels the back button.
3755
+ // See https://github.com/angular/angular/issues/13586#issuecomment-432795720
3756
+ Logger.get(this).info('WORK-AROUND: Updating browser location after pop state - see angular issue #13586');
3757
+ if (this.interactionService.isActive()) {
3758
+ /** @type {?} */
3759
+ const interactionIds = this.interactionService.activeInteractionContextIds.value;
3760
+ this.resetBrowserLocation(this.placeRouter.parseUrl(this.startingUrl).updateInteractionIds(interactionIds).url);
3761
+ }
3762
+ else {
3763
+ this.resetBrowserLocation(this.startingUrl); // and now put our own url back in.
3764
+ }
3765
+ return this.createIdleState();
3766
+ }
3767
+ /**
3768
+ * @param {?} event
3769
+ * @return {?}
3770
+ */
3771
+ onRouterEnd(event) {
3772
+ return this.ignore(event);
3773
+ }
3774
+ /**
3775
+ * @param {?} event
3776
+ * @return {?}
3777
+ */
3778
+ onRouterError(event) {
3779
+ return this.ignore(event);
3780
+ }
3781
+ /**
3782
+ * @param {?} event
3783
+ * @return {?}
3784
+ */
3785
+ onPopState(event) {
3786
+ return this.ignore(event);
3787
+ }
3788
+ /**
3789
+ * @param {?} component
3790
+ * @param {?} currentUrl
3791
+ * @param {?} nextUrl
3792
+ * @return {?}
3793
+ */
3794
+ canDeactivatePlace(component, currentUrl, nextUrl) {
3795
+ return __awaiter(this, void 0, void 0, function* () {
3796
+ return false;
3797
+ });
3798
+ }
3799
+ }
3800
+ NavigationState.LeavingInteractionTransitionCancelled = LeavingInteractionTransitionCancelled;
3801
+ if (false) {
3802
+ /** @type {?} */
3803
+ LeavingInteractionTransitionCancelled.prototype.isPopState;
3804
+ /** @type {?} */
3805
+ LeavingInteractionTransitionCancelled.prototype.firstCancelHandled;
3806
+ /** @type {?} */
3807
+ LeavingInteractionTransitionCancelled.prototype.popStateHandled;
3808
+ /** @type {?} */
3809
+ LeavingInteractionTransitionCancelled.prototype.popStateEventUrl;
3810
+ /** @type {?} */
3811
+ LeavingInteractionTransitionCancelled.prototype.debugPropertyKeys;
3812
+ /** @type {?} */
3813
+ LeavingInteractionTransitionCancelled.prototype.startingUrl;
3814
+ /** @type {?} */
3815
+ LeavingInteractionTransitionCancelled.prototype.locationChangeTriggerUrl;
3637
3816
  }
3638
3817
  /**
3639
3818
  * This state exists to handle all events while any kind of navigation is in progress. That way all other states can
3640
3819
  * happily ignore interaction contexts.
3641
3820
  */
3642
- class InteractionPopStateTransition extends AbstractInteractionTransition {
3643
- constructor() {
3644
- super(...arguments);
3821
+ class LeavingInteractionAfterPopStateTransition extends AbstractInteractionTransition {
3822
+ /**
3823
+ * @param {?} context
3824
+ * @param {?} startingUrl
3825
+ * @param {?} poppedHistoryUrl
3826
+ */
3827
+ constructor(context, startingUrl, poppedHistoryUrl) {
3828
+ super(context, startingUrl);
3829
+ this.poppedHistoryUrl = poppedHistoryUrl;
3645
3830
  this.isPopState = true;
3646
3831
  }
3647
- // @Trace()
3648
3832
  /**
3649
3833
  * @param {?} event
3650
3834
  * @return {?}
@@ -3660,7 +3844,6 @@ if (false) {
3660
3844
  return new Idle(this.context);
3661
3845
  }
3662
3846
  }
3663
- // @Trace()
3664
3847
  /**
3665
3848
  * @param {?} event
3666
3849
  * @return {?}
@@ -3673,26 +3856,124 @@ if (false) {
3673
3856
  return new Idle(this.context);
3674
3857
  }
3675
3858
  }
3859
+ /**
3860
+ * @param {?} newUrl
3861
+ * @return {?}
3862
+ */
3863
+ createNavigationInteractionCancelledState(newUrl) {
3864
+ return this.illegalTransition("Leaving interaction after pop-state should't block so should never see a back button click");
3865
+ }
3676
3866
  }
3677
- NavigationState.InteractionPopStateTransition = InteractionPopStateTransition;
3867
+ NavigationState.LeavingInteractionAfterPopStateTransition = LeavingInteractionAfterPopStateTransition;
3678
3868
  if (false) {
3679
3869
  /** @type {?} */
3680
- InteractionPopStateTransition.prototype.isPopState;
3681
- }
3682
- class CancelledDuringNavigationInteraction extends NavigationState {
3870
+ LeavingInteractionAfterPopStateTransition.prototype.isPopState;
3871
+ /** @type {?} */
3872
+ LeavingInteractionAfterPopStateTransition.prototype.poppedHistoryUrl;
3873
+ }
3874
+ // See LeavingInteractionAfterPopStateTransition.createNavigationInteractionCancelledState(...) above.
3875
+ //
3876
+ // export class LeavingInteractionAfterPopStateCancelled extends NavigationState {
3877
+ //
3878
+ // readonly isPopState = false;
3879
+ // firstCancelHandled = false;
3880
+ // popStateHandled = false;
3881
+ // popStateEventUrl: string;
3882
+ // debugPropertyKeys = ['idle', 'startingUrl', 'poppedHistoryUrl', 'locationChangeTriggerUrl', 'popStateEventUrl', 'firstCancelHandled', 'popStateHandled'];
3883
+ //
3884
+ // constructor(context: Context,
3885
+ // readonly startingUrl: string,
3886
+ // readonly locationChangeTriggerUrl: string,
3887
+ // readonly poppedHistoryUrl: string) {
3888
+ // super(context);
3889
+ // }
3890
+ //
3891
+ // get isTransitional() {
3892
+ // return true;
3893
+ // }
3894
+ //
3895
+ // onRouterStarted(event: NavigationStart): NavigationState {
3896
+ // return this.ignore(event);
3897
+ // }
3898
+ //
3899
+ //
3900
+ // onRouterCancelled(event: NavigationCancel): NavigationState {
3901
+ //
3902
+ // // if (this.firstCancelHandled && this.popStateHandled) {
3903
+ // // // Angular doesn't preserve the url when a guard cancels the back button.
3904
+ // // // See https://github.com/angular/angular/issues/13586#issuecomment-432795720
3905
+ // // Logger.get(this).info('WORK-AROUND: Updating browser location after pop state - see angular issue #13586');
3906
+ // // this.resetBrowserLocation(this.locationChangeTriggerUrl); // put the second back click one back in.
3907
+ // // this.resetBrowserLocation(this.poppedHistoryUrl); // put the first back click one back in.
3908
+ // // if (this.interactionService.isActive()) {
3909
+ // // const interactionIds = this.interactionService.activeInteractionContextIds.value;
3910
+ // // this.resetBrowserLocation(this.placeRouter.parseUrl(this.startingUrl).updateInteractionIds(interactionIds).url);
3911
+ // // } else {
3912
+ // // this.resetBrowserLocation(this.startingUrl); // and now put our own url back in.
3913
+ // // }
3914
+ // // return this.createIdleState();
3915
+ // // } else {
3916
+ // // this.firstCancelHandled = true;
3917
+ // return this.ignore(event);
3918
+ // // }
3919
+ // }
3920
+ //
3921
+ //
3922
+ // onRouterEnd(event: NavigationEnd): NavigationState {
3923
+ // return this.ignore(event);
3924
+ // }
3925
+ //
3926
+ //
3927
+ // onRouterError(event: NavigationError): NavigationState {
3928
+ // return this.ignore(event);
3929
+ // }
3930
+ //
3931
+ //
3932
+ // onPopState(event: NavigationStart): NavigationState {
3933
+ // // this.popStateHandled = true;
3934
+ // // this.popStateEventUrl = event.url;
3935
+ // return this.ignore(event);
3936
+ // }
3937
+ //
3938
+ // async canDeactivatePlace(component: PlaceComponent, currentUrl: UrlSnapshot, nextUrl: UrlSnapshot): Promise<boolean | UrlSnapshot> {
3939
+ // return false;
3940
+ // }
3941
+ // }
3942
+ /**
3943
+ * This state handles the scenario where a link navigation triggered an interaction and the user clicked back a to cancel it.
3944
+ * The routing event sequence is different depending on the link that was clicked.
3945
+ *
3946
+ * If the link was the same as the previous history location (i.e. they've gone back via a link rather than clicking back) then the sequence is:
3947
+ *
3948
+ * -> Idle -> NavigationTransition
3949
+ * -> confirm dialog shown.
3950
+ * -> click back
3951
+ * -> NavigationCancel -> clickedLinkUrl === cancel.url
3952
+ * -> NavigationEnd
3953
+ *
3954
+ * Otherwise if the link is different from teh history location then the sequence is:
3955
+ *
3956
+ * -> Idle -> NavigationTransition
3957
+ * -> confirm dialog shown.
3958
+ * -> click back
3959
+ * -> NavigationCancel -> clickedLinkUrl !== cancel.url
3960
+ * -> NavigationEnd
3961
+ * -> PopState
3962
+ * -> NavigationCancel
3963
+ */
3964
+ class LinkTriggeredNavigationInteractionCancelled extends NavigationState {
3683
3965
  /**
3684
3966
  * @param {?} context
3685
3967
  * @param {?} startingUrl
3686
- * @param {?} startingEventWasAPopState
3687
- * @param {?} locationChangeTriggerUrl
3968
+ * @param {?} clickedLinkUrl
3688
3969
  */
3689
- constructor(context, startingUrl, startingEventWasAPopState, locationChangeTriggerUrl) {
3970
+ constructor(context, startingUrl, clickedLinkUrl) {
3690
3971
  super(context);
3691
3972
  this.startingUrl = startingUrl;
3692
- this.startingEventWasAPopState = startingEventWasAPopState;
3693
- this.locationChangeTriggerUrl = locationChangeTriggerUrl;
3973
+ this.clickedLinkUrl = clickedLinkUrl;
3694
3974
  this.isPopState = false;
3695
- this.gotPopStateWithLeavingUrl = false;
3975
+ this.clickedLinkMatchedBackButtonUrl = false;
3976
+ this.debugPropertyKeys = ['idle', 'startingUrl', 'clickedLinkUrl', 'firstCancelEventUrl', 'clickedLinkMatchedBackButtonUrl', 'popStateEventUrl'];
3696
3977
  }
3697
3978
  /**
3698
3979
  * @return {?}
@@ -3707,29 +3988,35 @@ if (false) {
3707
3988
  onRouterStarted(event) {
3708
3989
  return this.ignore(event);
3709
3990
  }
3710
- // @Trace()
3711
3991
  /**
3712
3992
  * @param {?} event
3713
3993
  * @return {?}
3714
3994
  */
3715
3995
  onRouterCancelled(event) {
3716
- // Depending on the state of the router and what was done we get a different
3717
- // sequence of events.
3718
- // If the navigation change was triggered by clicking a link we'll get a cancel with the locationChangeTriggerUrl as the final event.
3719
- // If the navigation change was triggered with a pop state then we'll get an onPopState with the locationChangeTriggerUrl but no cancel event with it.
3720
- if (this.gotPopStateWithLeavingUrl && this.interactionService.isActive()) {
3721
- /** @type {?} */
3722
- const interactionIds = this.interactionService.activeInteractionContextIds.value;
3723
- this.resetBrowserLocation(this.placeRouter.parseUrl(this.startingUrl).updateInteractionIds(interactionIds).url);
3996
+ // TODO: should really split this into two sub states in the first cancel event.
3997
+ if (!this.firstCancelEventUrl) {
3998
+ this.firstCancelEventUrl = event.url;
3999
+ this.clickedLinkMatchedBackButtonUrl = event.url === this.clickedLinkUrl;
4000
+ return this.ignore(event);
4001
+ }
4002
+ else {
4003
+ // we wait for our popped state to come in.
4004
+ if (!this.clickedLinkMatchedBackButtonUrl && this.popStateEventUrl) {
4005
+ return this.finaliseRouting();
4006
+ }
3724
4007
  }
3725
- return this.gotPopStateWithLeavingUrl || this.locationChangeTriggerUrl === event.url ? this.createIdleState() : this.ignore(event);
3726
4008
  }
3727
4009
  /**
3728
4010
  * @param {?} event
3729
4011
  * @return {?}
3730
4012
  */
3731
4013
  onRouterEnd(event) {
3732
- return this.ignore(event);
4014
+ if (this.clickedLinkMatchedBackButtonUrl) {
4015
+ return this.finaliseRouting();
4016
+ }
4017
+ else {
4018
+ return this.ignore(event);
4019
+ }
3733
4020
  }
3734
4021
  /**
3735
4022
  * @param {?} event
@@ -3743,10 +4030,27 @@ if (false) {
3743
4030
  * @return {?}
3744
4031
  */
3745
4032
  onPopState(event) {
3746
- this.gotPopStateWithLeavingUrl = this.gotPopStateWithLeavingUrl || event.url === this.locationChangeTriggerUrl;
4033
+ this.popStateEventUrl = event.url;
3747
4034
  return this.ignore(event);
3748
4035
  }
3749
- // @Trace()
4036
+ /**
4037
+ * @return {?}
4038
+ */
4039
+ finaliseRouting() {
4040
+ Logger.get(this).info('WORK-AROUND: Updating browser location after pop state - see angular issue #13586');
4041
+ this.resetBrowserLocation(this.clickedLinkUrl); // put the back click one back in.
4042
+ if (this.interactionService.isActive()) {
4043
+ /** @type {?} */
4044
+ const interactionIds = this.interactionService.activeInteractionContextIds.value;
4045
+ // Angular doesn't preserve the url when a guard cancels the back button.
4046
+ // See https://github.com/angular/angular/issues/13586#issuecomment-432795720
4047
+ this.resetBrowserLocation(this.placeRouter.parseUrl(this.startingUrl).updateInteractionIds(interactionIds).url);
4048
+ }
4049
+ else {
4050
+ this.resetBrowserLocation(this.startingUrl); // and now put our own url back in.
4051
+ }
4052
+ return this.createIdleState();
4053
+ }
3750
4054
  /**
3751
4055
  * @param {?} component
3752
4056
  * @param {?} currentUrl
@@ -3758,38 +4062,144 @@ if (false) {
3758
4062
  return false;
3759
4063
  });
3760
4064
  }
4065
+ }
4066
+ NavigationState.LinkTriggeredNavigationInteractionCancelled = LinkTriggeredNavigationInteractionCancelled;
4067
+ if (false) {
4068
+ /** @type {?} */
4069
+ LinkTriggeredNavigationInteractionCancelled.prototype.isPopState;
4070
+ /** @type {?} */
4071
+ LinkTriggeredNavigationInteractionCancelled.prototype.firstCancelEventUrl;
4072
+ /** @type {?} */
4073
+ LinkTriggeredNavigationInteractionCancelled.prototype.popStateEventUrl;
4074
+ /** @type {?} */
4075
+ LinkTriggeredNavigationInteractionCancelled.prototype.clickedLinkMatchedBackButtonUrl;
4076
+ /** @type {?} */
4077
+ LinkTriggeredNavigationInteractionCancelled.prototype.debugPropertyKeys;
4078
+ /** @type {?} */
4079
+ LinkTriggeredNavigationInteractionCancelled.prototype.startingUrl;
4080
+ /** @type {?} */
4081
+ LinkTriggeredNavigationInteractionCancelled.prototype.clickedLinkUrl;
4082
+ }
4083
+ /**
4084
+ * This state handles the scenario where a pop state triggered and interaction and the user clickeb back a second time to cancel it.
4085
+ * The sequence of routing events/state transitions is as follows.
4086
+ * -> Idle -> PopStateTransition (poppedHistoryUrl == page to go to, startingUrl = page to stay on )
4087
+ * -> confirm dialog shown.
4088
+ * -> click back
4089
+ * -> PopStateTransition -> CancelledDuringBackButtonNavigationInteraction(trigger url is the page before the popped history url)
4090
+ * -> NavigationCancel (for the previous back)
4091
+ * -> PopState
4092
+ * -> NavigationCancel
4093
+ */
4094
+ class PopStateTriggeredNavigationInteractionCancelled extends NavigationState {
4095
+ /**
4096
+ * @param {?} context
4097
+ * @param {?} startingUrl
4098
+ * @param {?} locationChangeTriggerUrl
4099
+ * @param {?} poppedHistoryUrl
4100
+ */
4101
+ constructor(context, startingUrl, locationChangeTriggerUrl, poppedHistoryUrl) {
4102
+ super(context);
4103
+ this.startingUrl = startingUrl;
4104
+ this.locationChangeTriggerUrl = locationChangeTriggerUrl;
4105
+ this.poppedHistoryUrl = poppedHistoryUrl;
4106
+ this.isPopState = false;
4107
+ this.firstCancelHandled = false;
4108
+ this.popStateHandled = false;
4109
+ this.debugPropertyKeys = ['idle', 'startingUrl', 'poppedHistoryUrl', 'locationChangeTriggerUrl', 'popStateEventUrl', 'firstCancelHandled', 'popStateHandled'];
4110
+ }
4111
+ /**
4112
+ * @return {?}
4113
+ */
4114
+ get isTransitional() {
4115
+ return true;
4116
+ }
3761
4117
  /**
3762
4118
  * @param {?} event
3763
- * @param {?=} reason
3764
4119
  * @return {?}
3765
4120
  */
3766
- ignore(event, reason) {
3767
- reason = reason ? ` -> ${reason}` : '';
3768
- Logger.get(this).info(`ignoring router event${reason}: ${event.constructor.name} -> ${event.url}`);
3769
- return this;
4121
+ onRouterStarted(event) {
4122
+ return this.ignore(event);
4123
+ }
4124
+ /**
4125
+ * @param {?} event
4126
+ * @return {?}
4127
+ */
4128
+ onRouterCancelled(event) {
4129
+ if (this.firstCancelHandled && this.popStateHandled) {
4130
+ // Angular doesn't preserve the url when a guard cancels the back button.
4131
+ // See https://github.com/angular/angular/issues/13586#issuecomment-432795720
4132
+ Logger.get(this).info('WORK-AROUND: Updating browser location after pop state - see angular issue #13586');
4133
+ this.resetBrowserLocation(this.locationChangeTriggerUrl); // put the second back click one back in.
4134
+ this.resetBrowserLocation(this.poppedHistoryUrl); // put the first back click one back in.
4135
+ if (this.interactionService.isActive()) {
4136
+ /** @type {?} */
4137
+ const interactionIds = this.interactionService.activeInteractionContextIds.value;
4138
+ this.resetBrowserLocation(this.placeRouter.parseUrl(this.startingUrl).updateInteractionIds(interactionIds).url);
4139
+ }
4140
+ else {
4141
+ this.resetBrowserLocation(this.startingUrl); // and now put our own url back in.
4142
+ }
4143
+ return this.createIdleState();
4144
+ }
4145
+ else {
4146
+ this.firstCancelHandled = true;
4147
+ return this.ignore(event);
4148
+ }
3770
4149
  }
3771
4150
  /**
4151
+ * @param {?} event
3772
4152
  * @return {?}
3773
4153
  */
3774
- toString() {
3775
- return `${this.constructor.name}(isIdl: ${this.idle}, startingUrl: ${this.startingUrl}, locationChangeTriggerUrl:${this.locationChangeTriggerUrl})`;
4154
+ onRouterEnd(event) {
4155
+ return this.ignore(event);
4156
+ }
4157
+ /**
4158
+ * @param {?} event
4159
+ * @return {?}
4160
+ */
4161
+ onRouterError(event) {
4162
+ return this.ignore(event);
4163
+ }
4164
+ /**
4165
+ * @param {?} event
4166
+ * @return {?}
4167
+ */
4168
+ onPopState(event) {
4169
+ this.popStateHandled = true;
4170
+ this.popStateEventUrl = event.url;
4171
+ return this.ignore(event);
4172
+ }
4173
+ /**
4174
+ * @param {?} component
4175
+ * @param {?} currentUrl
4176
+ * @param {?} nextUrl
4177
+ * @return {?}
4178
+ */
4179
+ canDeactivatePlace(component, currentUrl, nextUrl) {
4180
+ return __awaiter(this, void 0, void 0, function* () {
4181
+ return false;
4182
+ });
3776
4183
  }
3777
4184
  }
3778
- NavigationState.CancelledDuringNavigationInteraction = CancelledDuringNavigationInteraction;
4185
+ NavigationState.PopStateTriggeredNavigationInteractionCancelled = PopStateTriggeredNavigationInteractionCancelled;
3779
4186
  if (false) {
3780
4187
  /** @type {?} */
3781
- CancelledDuringNavigationInteraction.prototype.isPopState;
3782
- /**
3783
- * @type {?}
3784
- * @private
3785
- */
3786
- CancelledDuringNavigationInteraction.prototype.gotPopStateWithLeavingUrl;
4188
+ PopStateTriggeredNavigationInteractionCancelled.prototype.isPopState;
4189
+ /** @type {?} */
4190
+ PopStateTriggeredNavigationInteractionCancelled.prototype.firstCancelHandled;
4191
+ /** @type {?} */
4192
+ PopStateTriggeredNavigationInteractionCancelled.prototype.popStateHandled;
4193
+ /** @type {?} */
4194
+ PopStateTriggeredNavigationInteractionCancelled.prototype.popStateEventUrl;
4195
+ /** @type {?} */
4196
+ PopStateTriggeredNavigationInteractionCancelled.prototype.debugPropertyKeys;
3787
4197
  /** @type {?} */
3788
- CancelledDuringNavigationInteraction.prototype.startingUrl;
4198
+ PopStateTriggeredNavigationInteractionCancelled.prototype.startingUrl;
3789
4199
  /** @type {?} */
3790
- CancelledDuringNavigationInteraction.prototype.startingEventWasAPopState;
4200
+ PopStateTriggeredNavigationInteractionCancelled.prototype.locationChangeTriggerUrl;
3791
4201
  /** @type {?} */
3792
- CancelledDuringNavigationInteraction.prototype.locationChangeTriggerUrl;
4202
+ PopStateTriggeredNavigationInteractionCancelled.prototype.poppedHistoryUrl;
3793
4203
  }
3794
4204
  })(NavigationState || (NavigationState = {}));
3795
4205
 
@@ -6440,7 +6850,8 @@ function RouteId(type, options) {
6440
6850
  /** @type {?} */
6441
6851
  const param = new ParameterDefinition.RouteId(propertyKey.toString(), options, type);
6442
6852
  Klass.get(prototype).addToOwnMetadataList(ROUTE_PARAMETER_LIST_KEY, param);
6443
- UseDelegate({ tag: `@RouteId(${prototype.constructor.name}.${propertyKey.toString()})` })(prototype, propertyKey);
6853
+ // UseDelegate({tag: `@RouteId(${prototype.constructor.name}.${propertyKey.toString()})`})(prototype, propertyKey);
6854
+ UseDelegate()(prototype, propertyKey);
6444
6855
  });
6445
6856
  }
6446
6857
  /**
@@ -6460,7 +6871,8 @@ function VisitParameter(options) {
6460
6871
  /** @type {?} */
6461
6872
  const param = new ParameterDefinition.ValueParameter(propertyKey.toString(), options, opts.getOptional("storeInUrl", null));
6462
6873
  Klass.get(prototype).addToOwnMetadataList(ROUTE_PARAMETER_LIST_KEY, param);
6463
- UseDelegate({ tag: `@VisitParameter(${prototype.constructor.name}.${propertyKey.toString()})` })(prototype, propertyKey);
6874
+ // UseDelegate({tag: `@VisitParameter(${prototype.constructor.name}.${propertyKey.toString()})`})(prototype, propertyKey);
6875
+ UseDelegate()(prototype, propertyKey);
6464
6876
  });
6465
6877
  }
6466
6878
  /**
@@ -6480,7 +6892,8 @@ function VisitParameterList(options) {
6480
6892
  /** @type {?} */
6481
6893
  const param = new ParameterDefinition.ArrayParameter(propertyKey.toString(), options, opts.getOptional("storeInUrl", null));
6482
6894
  Klass.get(prototype).addToOwnMetadataList(ROUTE_PARAMETER_LIST_KEY, param);
6483
- UseDelegate({ tag: `@VisitParameterList(${prototype.constructor.name}.${propertyKey.toString()})` })(prototype, propertyKey);
6895
+ UseDelegate()(prototype, propertyKey);
6896
+ // UseDelegate({tag: `@VisitParameterList(${prototype.constructor.name}.${propertyKey.toString()})`})(prototype, propertyKey);
6484
6897
  });
6485
6898
  }
6486
6899