@@ -89,7 +89,7 @@ export class CRPage implements PageDelegate {
89
89
await Promise . all ( Array . from ( this . _sessions . values ( ) ) . map ( frame => cb ( frame ) ) ) ;
90
90
}
91
91
92
- _sessionForFrame ( frame : frames . Frame ) : FrameSession {
92
+ private _sessionForFrame ( frame : frames . Frame ) : FrameSession {
93
93
// Frame id equals target id.
94
94
while ( ! this . _sessions . has ( frame . _id ) ) {
95
95
const parent = frame . parentFrame ( ) ;
@@ -105,29 +105,6 @@ export class CRPage implements PageDelegate {
105
105
return this . _sessionForFrame ( frame ) ;
106
106
}
107
107
108
- addFrameSession ( targetId : Protocol . Target . TargetID , session : CRSession ) {
109
- // Frame id equals target id.
110
- const frame = this . _page . _frameManager . frame ( targetId ) ;
111
- assert ( frame ) ;
112
- const parentSession = this . _sessionForFrame ( frame ) ;
113
- this . _page . _frameManager . removeChildFramesRecursively ( frame ) ;
114
- const frameSession = new FrameSession ( this , session , targetId , parentSession ) ;
115
- this . _sessions . set ( targetId , frameSession ) ;
116
- frameSession . _initialize ( false ) . catch ( e => e ) ;
117
- }
118
-
119
- removeFrameSession ( targetId : Protocol . Target . TargetID ) {
120
- const frameSession = this . _sessions . get ( targetId ) ;
121
- if ( ! frameSession )
122
- return ;
123
- // Frame id equals target id.
124
- const frame = this . _page . _frameManager . frame ( targetId ) ;
125
- if ( frame )
126
- this . _page . _frameManager . removeChildFramesRecursively ( frame ) ;
127
- frameSession . dispose ( ) ;
128
- this . _sessions . delete ( targetId ) ;
129
- }
130
-
131
108
async pageOrError ( ) : Promise < Page | Error > {
132
109
return this . _pagePromise ;
133
110
}
@@ -340,6 +317,9 @@ class FrameSession {
340
317
private _firstNonInitialNavigationCommittedFulfill = ( ) => { } ;
341
318
private _firstNonInitialNavigationCommittedReject = ( e : Error ) => { } ;
342
319
private _windowId : number | undefined ;
320
+ // Marks the oopif session that remote -> local transition has happened in the parent.
321
+ // See Target.detachedFromTarget handler for details.
322
+ private _swappedIn = false ;
343
323
344
324
constructor ( crPage : CRPage , client : CRSession , targetId : string , parentSession : FrameSession | null ) {
345
325
this . _client = client ;
@@ -471,6 +451,7 @@ class FrameSession {
471
451
dispose ( ) {
472
452
helper . removeEventListeners ( this . _eventListeners ) ;
473
453
this . _networkManager . dispose ( ) ;
454
+ this . _crPage . _sessions . delete ( this . _targetId ) ;
474
455
}
475
456
476
457
async _navigate ( frame : frames . Frame , url : string , referrer : string | undefined ) : Promise < frames . GotoResult > {
@@ -502,8 +483,10 @@ class FrameSession {
502
483
}
503
484
504
485
_onFrameAttached ( frameId : string , parentFrameId : string | null ) {
505
- if ( this . _crPage . _sessions . has ( frameId ) && frameId !== this . _targetId ) {
486
+ const frameSession = this . _crPage . _sessions . get ( frameId ) ;
487
+ if ( frameSession && frameId !== this . _targetId ) {
506
488
// This is a remote -> local frame transition.
489
+ frameSession . _swappedIn = true ;
507
490
const frame = this . _page . _frameManager . frame ( frameId ) ! ;
508
491
this . _page . _frameManager . removeChildFramesRecursively ( frame ) ;
509
492
return ;
@@ -565,7 +548,13 @@ class FrameSession {
565
548
const session = CRConnection . fromSession ( this . _client ) . session ( event . sessionId ) ! ;
566
549
567
550
if ( event . targetInfo . type === 'iframe' ) {
568
- this . _crPage . addFrameSession ( event . targetInfo . targetId , session ) ;
551
+ // Frame id equals target id.
552
+ const targetId = event . targetInfo . targetId ;
553
+ const frame = this . _page . _frameManager . frame ( targetId ) ! ;
554
+ this . _page . _frameManager . removeChildFramesRecursively ( frame ) ;
555
+ const frameSession = new FrameSession ( this . _crPage , session , targetId , this ) ;
556
+ this . _crPage . _sessions . set ( targetId , frameSession ) ;
557
+ frameSession . _initialize ( false ) . catch ( e => e ) ;
569
558
return ;
570
559
}
571
560
@@ -598,8 +587,31 @@ class FrameSession {
598
587
}
599
588
600
589
_onDetachedFromTarget ( event : Protocol . Target . detachedFromTargetPayload ) {
601
- this . _crPage . removeFrameSession ( event . targetId ! ) ;
590
+ // This might be a worker...
602
591
this . _page . _removeWorker ( event . sessionId ) ;
592
+
593
+ // ... or an oopif.
594
+ const childFrameSession = this . _crPage . _sessions . get ( event . targetId ! ) ;
595
+ if ( ! childFrameSession )
596
+ return ;
597
+
598
+ // Usually, we get frameAttached in this session first and mark child as swappedIn.
599
+ if ( childFrameSession . _swappedIn ) {
600
+ childFrameSession . dispose ( ) ;
601
+ return ;
602
+ }
603
+
604
+ // However, sometimes we get detachedFromTarget before frameAttached.
605
+ // In this case we don't know wheter this is a remote frame detach,
606
+ // or just a remote -> local transition. In the latter case, frameAttached
607
+ // is already inflight, so let's make a safe roundtrip to ensure it arrives.
608
+ this . _client . send ( 'Page.enable' ) . catch ( e => null ) . then ( ( ) => {
609
+ // Child was not swapped in - that means frameAttached did not happen and
610
+ // this is remote detach rather than remote -> local swap.
611
+ if ( ! childFrameSession . _swappedIn )
612
+ this . _page . _frameManager . frameDetached ( event . targetId ! ) ;
613
+ childFrameSession . dispose ( ) ;
614
+ } ) ;
603
615
}
604
616
605
617
_onWindowOpen ( event : Protocol . Page . windowOpenPayload ) {
0 commit comments