Branch: refs/heads/main
Home: https://github.com/WebKit/WebKit
Commit: 1e83941265e7ca16a9739688fda0f7482cf51c53
https://github.com/WebKit/WebKit/commit/1e83941265e7ca16a9739688fda0f7482cf51c53
Author: Kiet Ho <[email protected]>
Date: 2026-02-25 (Wed, 25 Feb 2026)
Changed paths:
A LayoutTests/http/tests/site-isolation/pagehide-event-expected.txt
A LayoutTests/http/tests/site-isolation/pagehide-event-iframe-expected.txt
A LayoutTests/http/tests/site-isolation/pagehide-event-iframe.html
A LayoutTests/http/tests/site-isolation/pagehide-event.html
A
LayoutTests/http/tests/site-isolation/resources/pagehide-event-subpage.html
M Source/WebCore/page/RemoteFrame.cpp
M Source/WebCore/page/RemoteFrame.h
M Source/WebKit/WebProcess/WebPage/WebFrame.cpp
Log Message:
-----------
[Site Isolation] Make dispatching pagehide event work
rdar://169910652
https://bugs.webkit.org/show_bug.cgi?id=307268
Reviewed by Ryosuke Niwa.
WebFrame::loadDidCommitInAnotherProcess is called when the frame is loaded in
another
process. It replaces the Frame object in the current process from LocalFrame to
RemoteFrame, because the newly loaded frame now lives in the other process. The
process looks like this:
(1) disconnect the old LocalFrame from its owner element
(2) create a new RemoteFrame that connects to the owner element, using
RemoteFrame::createSubframeWithContentsInAnotherProcess
(3) replace the old LocalFrame in the frame tree with the new RemoteFrame using
FrameTree::replaceChild. replaceChild() detaches the old LocalFrame
from its parent using FrameLoader::detachFromParent.
(1) needs to happen before (2), because (2) attaches the new RemoteFrame to the
owner element, so it must not be attached to anything beforehand.
But (1) also detaches the document in the LocalFrame from the frame itself
(Frame::disconnectOwnerElement -> LocalFrame::frameWasDisconnectedFromOwner ->
Document::detachFromFrame). Then in (3), when FrameLoader::detachFromParent() is
called, it tries to dispatch pagehide event (FrameLoader::detachFromParent ->
FrameLoader::closeURL -> FrameLoader::stopLoading ->
FrameLoader::dispatchUnloadEvents ->
Document::dispatchPagehideEvent), but the dispatch fails because the document is
already detached from the frame.
To fix this, this patch breaks (2) into two steps:
* create a new RemoteFrame without connecting to an owner element
* connect the newly created RemoteFrame to an owner element
Then, we rearrange the process so that when (3) dispatches pagehide event,
the document is still attached to the frame:
* create a new RemoteFrame without connecting to the owner element (yet)
* replace the old LocalFrame with the new RemoteFrame in the frame tree using
FrameTree::replaceChild. Since we haven't disconnect the old LocalFrame from
its
owner element, the document inside is still attached to the frame, so pagehide
can be dispatched.
* now we disconnect the owner element from the old LocalFrame and connect it to
the new RemoteFrame
Tests: http/tests/site-isolation/pagehide-event-iframe.html
http/tests/site-isolation/pagehide-event.html
imported/w3c/web-platform-tests/html/browsers/browsing-the-web/history-traversal/pageswap/pageswap-cross-origin.sub.html
* LayoutTests/http/tests/site-isolation/pagehide-event-expected.txt: Added.
* LayoutTests/http/tests/site-isolation/pagehide-event-iframe-expected.txt:
Added.
* LayoutTests/http/tests/site-isolation/pagehide-event-iframe.html: Added.
* LayoutTests/http/tests/site-isolation/pagehide-event.html: Added.
* LayoutTests/http/tests/site-isolation/resources/pagehide-event-subpage.html:
Added.
* Source/WebCore/page/RemoteFrame.cpp:
(WebCore::RemoteFrame::createSubframe):
(WebCore::RemoteFrame::createSubframeWithContentsInAnotherProcess):
- Remote constructor that's no longer needed.
* Source/WebCore/page/RemoteFrame.h:
* Source/WebKit/WebProcess/WebPage/WebFrame.cpp:
(WebKit::WebFrame::createRemoteSubframe):
(WebKit::WebFrame::loadDidCommitInAnotherProcess):
Canonical link: https://commits.webkit.org/308194@main
To unsubscribe from these emails, change your notification settings at
https://github.com/WebKit/WebKit/settings/notifications