Skip to content
This repository was archived by the owner on Jan 30, 2025. It is now read-only.

Commit b7b5696

Browse files
committed
Fix remote frame detach logic
When a website contains an iframe where its src is not from the same origin of the current frame (e.g. embedded youtube video), we get two events from chrome. Firstly we get a detach, and then an attach. The detach we need to handle differently and leave the attach as is. In the detach, instead of removing the frame that the detach event points to, we need to keep it but clean up any child frames it may reference. The detach (with swap reason) signals that a remote frame (that will be rendered by a new process) will be attached to the referenced frame. Later we will receive an attach frame event that Later we will receive an attach frame event that references the same frame as the detach as its parent, and this will be the new remote child frame. Fixes: #669
1 parent b63341b commit b7b5696

File tree

2 files changed

+13
-3
lines changed

2 files changed

+13
-3
lines changed

common/frame_manager.go

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import (
1515

1616
"github.com/chromedp/cdproto/cdp"
1717
"github.com/chromedp/cdproto/network"
18+
cdppage "github.com/chromedp/cdproto/page"
1819
)
1920

2021
// FrameManager manages all frames in a page and their life-cycles, it's a purely internal component.
@@ -166,7 +167,7 @@ func (m *FrameManager) frameAttached(frameID cdp.FrameID, parentFrameID cdp.Fram
166167
}
167168
}
168169

169-
func (m *FrameManager) frameDetached(frameID cdp.FrameID) {
170+
func (m *FrameManager) frameDetached(frameID cdp.FrameID, reason cdppage.FrameDetachedReason) {
170171
m.logger.Debugf("FrameManager:frameDetached", "fmid:%d fid:%v", m.ID(), frameID)
171172

172173
frame := m.getFrameByID(frameID)
@@ -176,7 +177,16 @@ func (m *FrameManager) frameDetached(frameID cdp.FrameID) {
176177
m.ID(), frameID)
177178
return
178179
}
179-
// TODO: possible data race? the frame may have gone.
180+
181+
if reason == cdppage.FrameDetachedReasonSwap {
182+
// When a local frame is swapped out for a remote
183+
// frame, we want to keep the current frame which is
184+
// still referenced by the (incoming) remote frame, but
185+
// remove all its child frames.
186+
m.removeChildFramesRecursively(frame)
187+
return
188+
}
189+
180190
m.removeFramesRecursively(frame)
181191
}
182192

common/frame_session.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -639,7 +639,7 @@ func (fs *FrameSession) onFrameDetached(frameID cdp.FrameID, reason cdppage.Fram
639639
"sid:%v tid:%v fid:%v reason:%s",
640640
fs.session.ID(), fs.targetID, frameID, reason)
641641

642-
fs.manager.frameDetached(frameID)
642+
fs.manager.frameDetached(frameID, reason)
643643
}
644644

645645
func (fs *FrameSession) onFrameNavigated(frame *cdp.Frame, initial bool) {

0 commit comments

Comments
 (0)