Branch: refs/heads/main
Home: https://github.com/WebKit/WebKit
Commit: c2efc73ec496407f393d9b8edb6f8e7fca48241c
https://github.com/WebKit/WebKit/commit/c2efc73ec496407f393d9b8edb6f8e7fca48241c
Author: Rupin Mittal <[email protected]>
Date: 2026-08-15 (Sat, 15 Aug 2026)
Changed paths:
M LayoutTests/TestExpectations
M
LayoutTests/http/tests/navigation-api/different-origin-entries-removed-after-bfcache-expected.txt
M
LayoutTests/http/tests/navigation-api/different-origin-entries-removed-after-bfcache.html
A
LayoutTests/http/tests/navigation-api/in-flight-navigation-aborted-when-entering-bfcache-expected.txt
A
LayoutTests/http/tests/navigation-api/in-flight-navigation-aborted-when-entering-bfcache.html
A
LayoutTests/http/tests/navigation-api/resources/in-flight-navigation-popup.html
M
LayoutTests/imported/w3c/web-platform-tests/navigation-api/navigate-event/defer/tentative/defer-back-expected.txt
M
LayoutTests/imported/w3c/web-platform-tests/navigation-api/navigate-event/navigation-back-cross-document-preventDefault-expected.txt
M Source/WebCore/loader/FrameLoader.cpp
M Source/WebCore/page/LocalDOMWindow.cpp
M Source/WebCore/page/Navigation.cpp
M Source/WebCore/page/Navigation.h
Log Message:
-----------
[Navigation API] navigation-back-cross-document-preventDefault.html is failing
https://bugs.webkit.org/show_bug.cgi?id=300006
rdar://161203519
Reviewed by Basuke Suzuki.
The very last assert in this test is failing: assert_true(navigate_called);
For a cross-document traversal of the top-level frame, the navigate event must
be
fired on the document being navigated away from, right after beforeunload.
Currently,
if the document being navigated to is being restored from the BFCache, dispatch
is
deferred until after CachedPage::restore(). By then m_frame->document() is the
restored
document, so the event landed on that document's Navigation object. This means
that the
navigate event is (wrongly) never fired on the document that we navigated away
from.
We fix this by not deferring the firing of the navigate event:
(1) FrameLoader::continueLoadAfterNavigationPolicy() no longer leaves
m_pendingNavigationAPIItem set if the item we're navigating to comes from
the BFCache.
It fires the navigate event.
(2) FrameLoader::commitProvisionalLoad() no longer has to check if a pending
item is set
and fire the navigate event.
After we make this change, the navigate event is correctly fired on the
document that
we're navigating away from. Our test passes and another test defer-back.html is
also fixed.
But running the test shows that there is a unhandled AbortError. This is
preexisting but
needs to be fixed as well.
According to the spec "For cross-document navigations ... both promises will
never settle."
But FrameLoader::closeURL() (which is called when we navigate away from a
document) calls
FrameLoader::stopLoading() with UnloadEventPolicy::UnloadOnly and then
stopLoading() calls
abortOngoingNavigationIfNeeded() which rejects the promises (and leads to the
AbortError).
To fix this we:
(1) Amend the condition in FrameLoader::stopLoading() not abort the ongoing
navigation if
the document is going into the BFCache.
(2) This leaves a live ongoing navigation on the cached document, and when the
document is
reactivated, the next time a navigate event is fired on it, that stale
ongoing navigation
will be aborted (Navigation::innerDispatchNavigateEvent() calls
abortOngoingNavigationIfNeeded()). So the AbortError is simply deferred. To
fix this,
we discard this ongoing navigation and related state when caching the
document.
(3) A document can be navigated away from and put into the back/forward cache
while a
different, earlier navigation of its own is still in flight — one that
called intercept(),
and is therefore same-document (The new in-flight layout test covers this).
Those promises
should reject rather than hang: that navigation was genuinely pending and
can
never complete now the document is being deactivated. So for this case we
abort rather than
discard, which rejects the tracker's promises and also rejects and clears
navigation.transition.
The abort cannot happen in discardOngoingNavigationForBackForwardCache()
because this
runs from CachedFrame's constructor inside a ScriptDisallowedScope, and
sborting
dispatches events, which is not allowed. So the abort happens in a later
function,
FrameLoader::stopLoading().
These changes break different-origin-entries-removed-after-bfcache.html because
it was wrongly depending on the navigate event to be fired on the navigated-to
document. So we amend it to not depend on that wrong behavior and also to test
that the navigate event is not fired on the document being navigated to.
* LayoutTests/TestExpectations:
*
LayoutTests/http/tests/navigation-api/different-origin-entries-removed-after-bfcache.html:
*
LayoutTests/http/tests/navigation-api/different-origin-entries-removed-after-bfcache-expected.txt:
*
LayoutTests/http/tests/navigation-api/in-flight-navigation-aborted-when-entering-bfcache-expected.txt:
Added.
*
LayoutTests/http/tests/navigation-api/in-flight-navigation-aborted-when-entering-bfcache.html:
Added.
*
LayoutTests/http/tests/navigation-api/resources/in-flight-navigation-popup.html:
Added.
*
LayoutTests/imported/w3c/web-platform-tests/navigation-api/navigate-event/defer/tentative/defer-back-expected.txt:
*
LayoutTests/imported/w3c/web-platform-tests/navigation-api/navigate-event/navigation-back-cross-document-preventDefault-expected.txt:
* Source/WebCore/loader/FrameLoader.cpp:
(WebCore::FrameLoader::stopLoading):
(WebCore::FrameLoader::commitProvisionalLoad):
(WebCore::FrameLoader::continueLoadAfterNavigationPolicy):
(WebCore::FrameLoader::continueLoadAfterNewWindowPolicy): Deleted.
* Source/WebCore/page/LocalDOMWindow.cpp:
(WebCore::LocalDOMWindow::suspendForBackForwardCache):
* Source/WebCore/page/Navigation.cpp:
(WebCore::Navigation::discardOngoingNavigationForBackForwardCache):
* Source/WebCore/page/Navigation.h:
Canonical link: https://commits.webkit.org/319242@main
To unsubscribe from these emails, change your notification settings at
https://github.com/WebKit/WebKit/settings/notifications