@@ -37,7 +37,7 @@ export default class FrameNavigations extends TypedEventEmitter<IFrameNavigation
3737
3838 public logger : IBoundLog ;
3939
40- private loaderIds = new Set < string > ( ) ;
40+ private historyByLoaderId : { [ loaderId : string ] : INavigation } = { } ;
4141
4242 private nextNavigationReason : { url : string ; reason : NavigationReason } ;
4343
@@ -73,7 +73,7 @@ export default class FrameNavigations extends TypedEventEmitter<IFrameNavigation
7373 resourceId : createPromise ( ) ,
7474 browserRequestId,
7575 } ;
76- if ( loaderId ) this . loaderIds . add ( loaderId ) ;
76+ if ( loaderId ) this . historyByLoaderId [ loaderId ] = nextTop ;
7777
7878 this . checkStoredNavigationReason ( nextTop , url ) ;
7979
@@ -149,7 +149,7 @@ export default class FrameNavigations extends TypedEventEmitter<IFrameNavigation
149149 else if (
150150 top . stateChanges . has ( LocationStatus . HttpRequested ) === true &&
151151 // add new entries for redirects
152- ( ! this . loaderIds . has ( loaderId ) || redirectedFromUrl )
152+ ( ! this . historyByLoaderId [ loaderId ] || redirectedFromUrl )
153153 ) {
154154 this . onNavigationRequested ( reason , url , lastCommandId , loaderId , browserRequestId ) ;
155155 }
@@ -184,7 +184,7 @@ export default class FrameNavigations extends TypedEventEmitter<IFrameNavigation
184184 }
185185
186186 public onLoadStateChanged (
187- incomingStatus : LoadStatus . DomContentLoaded | LoadStatus . Load ,
187+ incomingStatus : LoadStatus . DomContentLoaded | LoadStatus . Load | LoadStatus . ContentPaint ,
188188 url : string ,
189189 loaderId : string ,
190190 statusChangeDate ?: Date ,
@@ -194,7 +194,8 @@ export default class FrameNavigations extends TypedEventEmitter<IFrameNavigation
194194 if ( ! loaderId ) {
195195 for ( let i = this . history . length - 1 ; i >= 0 ; i -= 1 ) {
196196 const nav = this . history [ i ] ;
197- if ( nav && nav . finalUrl === url && nav . stateChanges . has ( LoadStatus . HttpResponded ) ) {
197+ const isUrlMatch = nav . finalUrl === url || nav . requestedUrl === url ;
198+ if ( isUrlMatch && nav . stateChanges . has ( LoadStatus . HttpResponded ) ) {
198199 loaderId = nav . loaderId ;
199200 break ;
200201 }
@@ -219,7 +220,8 @@ export default class FrameNavigations extends TypedEventEmitter<IFrameNavigation
219220
220221 public assignLoaderId ( navigation : INavigation , loaderId : string , url ?: string ) : void {
221222 if ( ! loaderId ) return ;
222- this . loaderIds . add ( loaderId ) ;
223+
224+ this . historyByLoaderId [ loaderId ] = navigation ;
223225 navigation . loaderId = loaderId ;
224226 if (
225227 url &&
@@ -232,13 +234,17 @@ export default class FrameNavigations extends TypedEventEmitter<IFrameNavigation
232234
233235 public getLastLoadedNavigation ( ) : INavigation {
234236 let navigation : INavigation ;
237+ let hasInPageNav = false ;
235238 for ( let i = this . history . length - 1 ; i >= 0 ; i -= 1 ) {
236239 navigation = this . history [ i ] ;
237- if (
238- navigation . stateChanges . has ( LoadStatus . DomContentLoaded ) &&
239- navigation . navigationReason !== 'inPage' &&
240- ! ! navigation . finalUrl
241- ) {
240+ if ( navigation . navigationReason === 'inPage' ) {
241+ hasInPageNav = true ;
242+ continue ;
243+ }
244+ if ( ! navigation . finalUrl || ! navigation . stateChanges . has ( LoadStatus . HttpResponded ) ) continue ;
245+
246+ // if we have an in-page nav, return the first non "inPage" url. Otherwise, use if DomContentLoaded was triggered
247+ if ( hasInPageNav || navigation . stateChanges . has ( LoadStatus . DomContentLoaded ) ) {
242248 return navigation ;
243249 }
244250 }
@@ -257,18 +263,7 @@ export default class FrameNavigations extends TypedEventEmitter<IFrameNavigation
257263 }
258264
259265 private findMatchingNavigation ( loaderId : string ) : INavigation {
260- const navigation = this . top ;
261- if ( ! navigation ) return undefined ;
262- if ( loaderId && navigation . loaderId && navigation . loaderId !== loaderId ) {
263- // find the right loader id
264- for ( let i = this . history . length - 1 ; i >= 0 ; i -= 1 ) {
265- const nav = this . history [ i ] ;
266- if ( nav && nav . loaderId === loaderId ) {
267- return nav ;
268- }
269- }
270- }
271- return navigation ;
266+ return this . historyByLoaderId [ loaderId ] ?? this . top ;
272267 }
273268
274269 private recordRedirect ( requestedUrl : string , finalUrl : string , loaderId : string ) : INavigation {
@@ -281,6 +276,7 @@ export default class FrameNavigations extends TypedEventEmitter<IFrameNavigation
281276 }
282277
283278 // find the right loader id
279+ // NOTE: loop through history since loaderId is reused across requests in a redirect
284280 for ( let i = this . history . length - 1 ; i >= 0 ; i -= 1 ) {
285281 const navigation = this . history [ i ] ;
286282 if ( navigation && navigation . loaderId === loaderId ) {
@@ -301,16 +297,24 @@ export default class FrameNavigations extends TypedEventEmitter<IFrameNavigation
301297 loaderId ?: string ,
302298 statusChangeDate ?: Date ,
303299 ) : void {
300+ this . logger . info ( 'FrameNavigations.changeNavigationState' , {
301+ newStatus,
302+ loaderId,
303+ statusChangeDate,
304+ } ) ;
304305 const navigation = this . findMatchingNavigation ( loaderId ) ;
305306 if ( ! navigation ) return ;
307+ if ( ! navigation . loaderId && loaderId ) {
308+ navigation . loaderId = loaderId ;
309+ this . historyByLoaderId [ loaderId ] = navigation ;
310+ }
306311 if ( navigation . stateChanges . has ( newStatus ) ) {
307312 if ( statusChangeDate && statusChangeDate < navigation . stateChanges . get ( newStatus ) ) {
308313 navigation . stateChanges . set ( newStatus , statusChangeDate ) ;
309314 }
310315 return ;
311316 }
312317 this . recordStatusChange ( navigation , newStatus , statusChangeDate ) ;
313- if ( loaderId ) this . loaderIds . add ( loaderId ) ;
314318 }
315319
316320 private recordStatusChange (
0 commit comments