@@ -20,14 +20,9 @@ import {
2020 ɵPRECOMMIT_HANDLER_SUPPORTED as PRECOMMIT_HANDLER_SUPPORTED ,
2121} from '@angular/common' ;
2222import { StateManager } from './state_manager' ;
23- import {
24- NavigationExtras ,
25- RestoredState ,
26- Navigation as RouterNavigation ,
27- } from '../navigation_transition' ;
23+ import { RestoredState , Navigation as RouterNavigation } from '../navigation_transition' ;
2824import {
2925 BeforeActivateRoutes ,
30- BeforeRoutesRecognized ,
3126 isRedirectingEvent ,
3227 NavigationCancel ,
3328 NavigationCancellationCode ,
@@ -37,6 +32,7 @@ import {
3732 NavigationStart ,
3833 NavigationTrigger ,
3934 PrivateRouterEvents ,
35+ RoutesRecognized ,
4036} from '../events' ;
4137import { Subject , SubscriptionLike } from 'rxjs' ;
4238import { UrlTree } from '../url_tree' ;
@@ -89,7 +85,6 @@ export class NavigationStateManager extends StateManager {
8985 /** Function to resolve the intercepted navigation event. */
9086 resolveHandler ?: ( v : void ) => void ;
9187 navigationEvent ?: NavigateEvent ;
92- commitUrl ?: ( ) => Promise < void > ;
9388 } = { } ;
9489
9590 /**
@@ -129,18 +124,12 @@ export class NavigationStateManager extends StateManager {
129124 url : string ,
130125 state : RestoredState | null | undefined ,
131126 trigger : NavigationTrigger ,
132- extras : NavigationExtras ,
133127 ) => void ,
134128 ) : SubscriptionLike {
135129 this . activeHistoryEntry = this . navigation . currentEntry ! ;
136130 this . nonRouterEntryChangeListener = this . nonRouterCurrentEntryChangeSubject . subscribe (
137131 ( { path, state} ) => {
138- listener (
139- path ,
140- state ,
141- 'popstate' ,
142- ! this . precommitHandlerSupported ? { replaceUrl : true } : { } ,
143- ) ;
132+ listener ( path , state , 'popstate' ) ;
144133 } ,
145134 ) ;
146135 return this . nonRouterEntryChangeListener ;
@@ -161,46 +150,20 @@ export class NavigationStateManager extends StateManager {
161150 this . currentNavigation = { ...this . currentNavigation , routerTransition : transition } ;
162151 if ( e instanceof NavigationStart ) {
163152 this . updateStateMemento ( ) ;
164- // If we have precommit handler support, we can create a navigation
165- // immediately and redirect it later.
166- if ( this . precommitHandlerSupported ) {
167- this . maybeCreateNavigationForTransition ( transition ) ;
168- }
169153 } else if ( e instanceof NavigationSkipped ) {
170154 this . finishNavigation ( ) ;
171155 this . commitTransition ( transition ) ;
172- } else if ( e instanceof BeforeRoutesRecognized ) {
173- transition . routesRecognizeHandler . deferredHandle = new Promise < void > ( async ( resolve ) => {
174- if ( this . urlUpdateStrategy === 'eager' ) {
175- try {
176- this . maybeCreateNavigationForTransition ( transition ) ;
177- await this . currentNavigation . commitUrl ?.( ) ;
178- } catch {
179- // If commit fails (e.g., precommitHandler rejects), abort.
180- // The AbortSignal will notify
181- return ;
182- }
183- }
184- resolve ( ) ;
185- } ) ;
156+ } else if ( e instanceof RoutesRecognized ) {
157+ if ( this . urlUpdateStrategy === 'eager' && ! transition . extras . skipLocationChange ) {
158+ this . createNavigationForTransition ( transition ) ;
159+ }
186160 } else if ( e instanceof BeforeActivateRoutes ) {
187- transition . beforeActivateHandler . deferredHandle = new Promise < void > ( async ( resolve ) => {
188- // If URL update strategy is 'deferred', commit the URL now (before activation).
189- if ( this . urlUpdateStrategy === 'deferred' ) {
190- try {
191- this . maybeCreateNavigationForTransition ( transition ) ;
192- await this . currentNavigation . commitUrl ?.( ) ;
193- } catch {
194- return ;
195- }
196- }
197- // Commit the internal router state.
198- this . commitTransition ( transition ) ;
199- resolve ( ) ;
200- } ) ;
161+ // Commit the internal router state.
162+ this . commitTransition ( transition ) ;
163+ if ( this . urlUpdateStrategy === 'deferred' && ! transition . extras . skipLocationChange ) {
164+ this . createNavigationForTransition ( transition ) ;
165+ }
201166 } else if ( e instanceof NavigationCancel || e instanceof NavigationError ) {
202- // TODO(atscott): We want to keep the navigation event on redirects if
203- // the URL wasn't committed yet rather than cancelling it.
204167 void this . cancel ( transition , e ) ;
205168 } else if ( e instanceof NavigationEnd ) {
206169 const { resolveHandler, removeAbortListener} = this . currentNavigation ;
@@ -220,19 +183,17 @@ export class NavigationStateManager extends StateManager {
220183 }
221184 }
222185
223- private maybeCreateNavigationForTransition ( transition : RouterNavigation ) {
224- const { navigationEvent, commitUrl} = this . currentNavigation ;
186+ private createNavigationForTransition ( transition : RouterNavigation ) {
187+ const { navigationEvent} = this . currentNavigation ;
188+ // If we are currently handling a traversal navigation, we do not need a new navigation for it
189+ // because we are strictly restoring a previous state. If we are instead handling a navigation
190+ // initiated outside the router, we do need to replace it with a router-triggered navigation
191+ // to add the router-specific state.
225192 if (
226- // Presence of commitUrl function indicates the navigateEvent supports redirect
227- commitUrl ||
228- // If we are currently handling a traversal navigation, we do not need a new navigation for it
229- // because we are strictly restoring a previous state. If we are instead handling a navigation
230- // initiated outside the router, we do need to replace it with a router-triggered navigation
231- // to add the router-specific state.
232- ( navigationEvent &&
233- ( navigationEvent . navigationType === 'traverse' ||
234- navigationEvent . navigationType === 'reload' ) &&
235- this . eventAndRouterDestinationsMatch ( navigationEvent , transition ) )
193+ navigationEvent &&
194+ ( navigationEvent . navigationType === 'traverse' ||
195+ navigationEvent . navigationType === 'reload' ) &&
196+ this . eventAndRouterDestinationsMatch ( navigationEvent , transition )
236197 ) {
237198 return ;
238199 }
@@ -297,7 +258,6 @@ export class NavigationStateManager extends StateManager {
297258 * and resolving the post-commit handler promise. Clears the `currentNavigation` state.
298259 */
299260 private finishNavigation ( ) {
300- this . currentNavigation . commitUrl ?.( ) ;
301261 this . currentNavigation ?. resolveHandler ?.( ) ;
302262 this . currentNavigation = { } ;
303263 }
@@ -426,66 +386,18 @@ export class NavigationStateManager extends StateManager {
426386 resolve : resolveHandler ,
427387 reject : rejectHandler ,
428388 } = promiseWithResolvers < void > ( ) ;
429-
430- const {
431- promise : precommitHandlerPromise ,
432- resolve : resolvePrecommitHandler ,
433- reject : rejectPrecommitHandler ,
434- } = promiseWithResolvers < void > ( ) ;
435- this . currentNavigation . rejectNavigateEvent = ( ) => {
436- event . signal . removeEventListener ( 'abort' , abortHandler ) ;
437- rejectPrecommitHandler ( ) ;
438- rejectHandler ( ) ;
439- } ;
440389 this . currentNavigation . resolveHandler = ( ) => {
441390 this . currentNavigation . removeAbortListener ?.( ) ;
442391 resolveHandler ( ) ;
443392 } ;
393+ this . currentNavigation . rejectNavigateEvent = ( ) => {
394+ this . currentNavigation . removeAbortListener ?.( ) ;
395+ rejectHandler ( ) ;
396+ } ;
444397 // Prevent unhandled promise rejections from internal promises.
445398 handlerPromise . catch ( ( ) => { } ) ;
446- precommitHandlerPromise . catch ( ( ) => { } ) ;
447399 interceptOptions . handler = ( ) => handlerPromise ;
448400
449- if ( this . deferredCommitSupported ( event ) ) {
450- const redirect = new Promise <
451- ( url : string , options : { state : unknown ; history ?: 'push' | 'replace' } ) => void
452- > ( ( resolve ) => {
453- // The `precommitHandler` option is not in the standard DOM types yet
454- ( interceptOptions as any ) . precommitHandler = ( controller : any ) => {
455- resolve ( controller . redirect . bind ( controller ) ) ;
456- return precommitHandlerPromise ;
457- } ;
458- } ) ;
459- // `commitUrl` is a function that will be called by the router's lifecycle
460- // (e.g., in `BeforeRoutesRecognized` or `BeforeActivateRoutes` depending on `urlUpdateStrategy`)
461- // to actually perform the URL change via the Navigation API.
462- this . currentNavigation . commitUrl = async ( ) => {
463- this . currentNavigation . commitUrl = undefined ; // Ensure it's only called once.
464- const transition = this . currentNavigation . routerTransition ;
465-
466- // If not skipping location change, use the `redirect` function (from `precommitHandler`'s
467- // controller) to perform the URL update with the correct state and history action.
468- if ( transition && ! transition . extras . skipLocationChange ) {
469- const internalPath = this . createBrowserPath ( transition ) ;
470- const history =
471- this . location . isCurrentPathEqualTo ( internalPath ) || ! ! transition . extras . replaceUrl
472- ? 'replace'
473- : 'push' ;
474- const state = {
475- ...transition . extras . state ,
476- navigationId : transition . id ,
477- } ;
478- // this might be a path or an actual URL depending on the baseHref
479- const pathOrUrl = this . location . prepareExternalUrl ( internalPath ) ;
480- ( await redirect ) ( pathOrUrl , { state, history} ) ;
481- }
482- resolvePrecommitHandler ( ) ;
483- // Wait for the Navigation API's own `committed` promise if available (part of transition object)
484- // This ensures we respect the browser's timing for when the commit actually happens.
485- return await this . navigation . transition ?. committed ;
486- } ;
487- }
488-
489401 // Intercept the navigation event with the configured options.
490402 event . intercept ( interceptOptions ) ;
491403
@@ -527,16 +439,6 @@ export class NavigationStateManager extends StateManager {
527439 const routerDestination = this . location . prepareExternalUrl ( internalPath ) ;
528440 return new URL ( routerDestination , eventDestination . origin ) . href === eventDestination . href ;
529441 }
530-
531- private deferredCommitSupported ( event : NavigateEvent ) : boolean {
532- return (
533- this . precommitHandlerSupported &&
534- // Cannot defer commit if not cancelable by the Navigation API's rules.
535- event . cancelable &&
536- // Deferring a traversal commit is currently problematic or not fully supported.
537- event . navigationType !== 'traverse'
538- ) ;
539- }
540442}
541443
542444/**
0 commit comments