@@ -21,7 +21,7 @@ import {applyRedirects} from './apply_redirects';
21
21
import { LoadedRouterConfig , QueryParamsHandling , Route , Routes , validateConfig } from './config' ;
22
22
import { createRouterState } from './create_router_state' ;
23
23
import { createUrlTree } from './create_url_tree' ;
24
- import { ActivationEnd , ChildActivationEnd , Event , GuardsCheckEnd , GuardsCheckStart , NavigationCancel , NavigationEnd , NavigationError , NavigationStart , ResolveEnd , ResolveStart , RouteConfigLoadEnd , RouteConfigLoadStart , RoutesRecognized } from './events' ;
24
+ import { ActivationEnd , ChildActivationEnd , Event , GuardsCheckEnd , GuardsCheckStart , NavigationCancel , NavigationEnd , NavigationError , NavigationStart , NavigationTrigger , ResolveEnd , ResolveStart , RouteConfigLoadEnd , RouteConfigLoadStart , RoutesRecognized } from './events' ;
25
25
import { PreActivation } from './pre_activation' ;
26
26
import { recognize } from './recognize' ;
27
27
import { DefaultRouteReuseStrategy , DetachedRouteHandleInternal , RouteReuseStrategy } from './route_reuse_strategy' ;
@@ -164,16 +164,15 @@ function defaultErrorHandler(error: any): any {
164
164
throw error ;
165
165
}
166
166
167
- type NavigationSource = 'imperative' | 'popstate' | 'hashchange' ;
168
-
169
167
type NavigationParams = {
170
168
id : number ,
171
169
rawUrl : UrlTree ,
172
170
extras : NavigationExtras ,
173
171
resolve : any ,
174
172
reject : any ,
175
173
promise : Promise < boolean > ,
176
- source : NavigationSource ,
174
+ source : NavigationTrigger ,
175
+ state : { navigationId : number } | null
177
176
} ;
178
177
179
178
/**
@@ -223,6 +222,7 @@ export class Router {
223
222
* Indicates if at least one navigation happened.
224
223
*/
225
224
navigated : boolean = false ;
225
+ private lastSuccessfulId : number = - 1 ;
226
226
227
227
/**
228
228
* Used by RouterModule. This allows us to
@@ -311,8 +311,12 @@ export class Router {
311
311
if ( ! this . locationSubscription ) {
312
312
this . locationSubscription = < any > this . location . subscribe ( Zone . current . wrap ( ( change : any ) => {
313
313
const rawUrlTree = this . urlSerializer . parse ( change [ 'url' ] ) ;
314
- const source : NavigationSource = change [ 'type' ] === 'popstate' ? 'popstate' : 'hashchange' ;
315
- setTimeout ( ( ) => { this . scheduleNavigation ( rawUrlTree , source , { replaceUrl : true } ) ; } , 0 ) ;
314
+ const source : NavigationTrigger = change [ 'type' ] === 'popstate' ? 'popstate' : 'hashchange' ;
315
+ const state = change . state && change . state . navigationId ?
316
+ { navigationId : change . state . navigationId } :
317
+ null ;
318
+ setTimeout (
319
+ ( ) => { this . scheduleNavigation ( rawUrlTree , source , state , { replaceUrl : true } ) ; } , 0 ) ;
316
320
} ) ) ;
317
321
}
318
322
}
@@ -341,6 +345,7 @@ export class Router {
341
345
validateConfig ( config ) ;
342
346
this . config = config ;
343
347
this . navigated = false ;
348
+ this . lastSuccessfulId = - 1 ;
344
349
}
345
350
346
351
/** @docsNotRequired */
@@ -449,7 +454,7 @@ export class Router {
449
454
const urlTree = url instanceof UrlTree ? url : this . parseUrl ( url ) ;
450
455
const mergedTree = this . urlHandlingStrategy . merge ( urlTree , this . rawUrlTree ) ;
451
456
452
- return this . scheduleNavigation ( mergedTree , 'imperative' , extras ) ;
457
+ return this . scheduleNavigation ( mergedTree , 'imperative' , null , extras ) ;
453
458
}
454
459
455
460
/**
@@ -522,8 +527,9 @@ export class Router {
522
527
. subscribe ( ( ) => { } ) ;
523
528
}
524
529
525
- private scheduleNavigation ( rawUrl : UrlTree , source : NavigationSource , extras : NavigationExtras ) :
526
- Promise < boolean > {
530
+ private scheduleNavigation (
531
+ rawUrl : UrlTree , source : NavigationTrigger , state : { navigationId : number } | null ,
532
+ extras : NavigationExtras ) : Promise < boolean > {
527
533
const lastNavigation = this . navigations . value ;
528
534
529
535
// If the user triggers a navigation imperatively (e.g., by using navigateByUrl),
@@ -558,21 +564,22 @@ export class Router {
558
564
} ) ;
559
565
560
566
const id = ++ this . navigationId ;
561
- this . navigations . next ( { id, source, rawUrl, extras, resolve, reject, promise} ) ;
567
+ this . navigations . next ( { id, source, state , rawUrl, extras, resolve, reject, promise} ) ;
562
568
563
569
// Make sure that the error is propagated even though `processNavigations` catch
564
570
// handler does not rethrow
565
571
return promise . catch ( ( e : any ) => Promise . reject ( e ) ) ;
566
572
}
567
573
568
- private executeScheduledNavigation ( { id, rawUrl, extras, resolve, reject} : NavigationParams ) :
569
- void {
574
+ private executeScheduledNavigation ( { id, rawUrl, extras, resolve, reject, source ,
575
+ state } : NavigationParams ) : void {
570
576
const url = this . urlHandlingStrategy . extract ( rawUrl ) ;
571
577
const urlTransition = ! this . navigated || url . toString ( ) !== this . currentUrlTree . toString ( ) ;
572
578
573
579
if ( ( this . onSameUrlNavigation === 'reload' ? true : urlTransition ) &&
574
580
this . urlHandlingStrategy . shouldProcessUrl ( rawUrl ) ) {
575
- ( this . events as Subject < Event > ) . next ( new NavigationStart ( id , this . serializeUrl ( url ) ) ) ;
581
+ ( this . events as Subject < Event > )
582
+ . next ( new NavigationStart ( id , this . serializeUrl ( url ) , source , state ) ) ;
576
583
Promise . resolve ( )
577
584
. then (
578
585
( _ ) => this . runNavigate (
@@ -584,7 +591,8 @@ export class Router {
584
591
} else if (
585
592
urlTransition && this . rawUrlTree &&
586
593
this . urlHandlingStrategy . shouldProcessUrl ( this . rawUrlTree ) ) {
587
- ( this . events as Subject < Event > ) . next ( new NavigationStart ( id , this . serializeUrl ( url ) ) ) ;
594
+ ( this . events as Subject < Event > )
595
+ . next ( new NavigationStart ( id , this . serializeUrl ( url ) , source , state ) ) ;
588
596
Promise . resolve ( )
589
597
. then (
590
598
( _ ) => this . runNavigate (
@@ -727,9 +735,9 @@ export class Router {
727
735
if ( ! skipLocationChange ) {
728
736
const path = this . urlSerializer . serialize ( this . rawUrlTree ) ;
729
737
if ( this . location . isCurrentPathEqualTo ( path ) || replaceUrl ) {
730
- this . location . replaceState ( path ) ;
738
+ this . location . replaceState ( path , '' , { navigationId : id } ) ;
731
739
} else {
732
- this . location . go ( path ) ;
740
+ this . location . go ( path , '' , { navigationId : id } ) ;
733
741
}
734
742
}
735
743
@@ -743,6 +751,7 @@ export class Router {
743
751
( ) => {
744
752
if ( navigationIsSuccessful ) {
745
753
this . navigated = true ;
754
+ this . lastSuccessfulId = id ;
746
755
( this . events as Subject < Event > )
747
756
. next ( new NavigationEnd (
748
757
id , this . serializeUrl ( url ) , this . serializeUrl ( this . currentUrlTree ) ) ) ;
@@ -784,7 +793,8 @@ export class Router {
784
793
}
785
794
786
795
private resetUrlToCurrentUrlTree ( ) : void {
787
- this . location . replaceState ( this . urlSerializer . serialize ( this . rawUrlTree ) ) ;
796
+ this . location . replaceState (
797
+ this . urlSerializer . serialize ( this . rawUrlTree ) , '' , { navigationId : this . lastSuccessfulId } ) ;
788
798
}
789
799
}
790
800
0 commit comments