Branch: refs/heads/main
Home: https://github.com/WebKit/WebKit
Commit: 035a4bdb885da801fc9332853c25038ec4f7823a
https://github.com/WebKit/WebKit/commit/035a4bdb885da801fc9332853c25038ec4f7823a
Author: Basuke Suzuki <[email protected]>
Date: 2025-10-31 (Fri, 31 Oct 2025)
Changed paths:
M
LayoutTests/imported/w3c/web-platform-tests/navigation-api/ordering-and-transition/back-same-document-intercept-reject_currententrychange-expected.txt
M
LayoutTests/imported/w3c/web-platform-tests/navigation-api/ordering-and-transition/back-same-document-intercept_currententrychange-expected.txt
M Source/WebCore/history/HistoryItem.cpp
M Source/WebCore/history/HistoryItem.h
M Source/WebCore/loader/FrameLoader.cpp
M Source/WebCore/page/Navigation.cpp
M Source/WebCore/page/Navigation.h
M Source/WebKit/Shared/WebBackForwardListItem.cpp
Log Message:
-----------
[Navigation API] Fix event ordering for intercepted traverse navigations.
https://bugs.webkit.org/show_bug.cgi?id=301713
rdar://161445256
Reviewed by Alex Christensen.
This patch addresses two interrelated issues with Navigation API traverse
navigations:
1. Event ordering for intercepted traverse navigations
For intercepted traverse navigations, the currententrychange event was firing
in the wrong order
relative to intercept handlers, and the committed promise timing was incorrect.
The timing now matches the HTML Navigation API specification:
- Fire navigate event
- If intercepted, update Navigation API state and fire currententrychange
BEFORE handlers run
- Fulfill committed promise AFTER handlers are invoked (but before they
complete)
- Only reject committed promise if it hasn't been fulfilled yet
This fix is covered by these two wpt tests:
-
navigation-api/ordering-and-transition/back-same-document-intercept-reject.html?currententrychange
-
navigation-api/ordering-and-transition/back-same-document-intercept.html?currententrychange
2. Same-document navigation detection with modified iframe structures
The previous implementation of shouldDoSameDocumentNavigationTo() contained
overly complex
conditional logic that prevented proper same-document detection when Navigation
API intercepts
modified the DOM structure (e.g., adding/removing iframes).
Historical context:
The complex logic dates back to 2010 (bugs 44217 and 46324), when explicit
checks for stateObject,
fragment identifiers, and frame tree structure were added to prevent full page
reloads during
history.pushState() with changing iframe structures. However, these checks all
ultimately reduce
to the same documentSequenceNumber comparison, making them redundant given
correct
documentSequenceNumber management.
The Navigation API intercept case exposed this redundancy: when an intercept
handler modifies the
iframe structure, the old hasSameDocumentTree() check would fail despite both
items having the
same documentSequenceNumber, causing incorrect cross-document navigation.
Technical correctness:
documentSequenceNumber follows a well-defined invariant across all navigation
paths:
- New document load: generates new documentSequenceNumber (clipAtTarget=true)
- Same-document navigation (pushState/fragment/intercept): copies from
previousItem (clipAtTarget=false)
- Client redirect to different URL: reset() generates new documentSequenceNumber
This invariant is maintained in:
- HistoryItem creation via createItemTree()
- Fragment navigation via updateBackForwardListForFragmentScroll()
- pushState/replaceState operations
- Navigation API intercepts
- Client redirects via updateCurrentItem()
The simplified logic relying solely on documentSequenceNumber comparison is
both theoretically
correct and empirically validated by comprehensive test coverage, including the
original 2010
regression tests for iframe structure changes.
Tests: All existing Navigation API and history tests pass, including:
- fast/history/same-document-iframes-changing-pushstate.html (from 2010)
- fast/history/same-document-iframes-changing-fragment.html (from 2010)
*
LayoutTests/imported/w3c/web-platform-tests/navigation-api/ordering-and-transition/back-same-document-intercept-reject_currententrychange-expected.txt:
*
LayoutTests/imported/w3c/web-platform-tests/navigation-api/ordering-and-transition/back-same-document-intercept_currententrychange-expected.txt:
* Source/WebCore/history/HistoryItem.cpp:
(WebCore::HistoryItem::shouldDoSameDocumentNavigationTo const):
(WebCore::HistoryItem::hasSameDocumentTree const): Deleted.
* Source/WebCore/history/HistoryItem.h:
* Source/WebCore/loader/FrameLoader.cpp:
(WebCore::FrameLoader::loadInSameDocument):
* Source/WebCore/page/Navigation.cpp:
(WebCore::Navigation::rejectFinishedPromise):
(WebCore::Navigation::updateForNavigation):
(WebCore::Navigation::innerDispatchNavigateEvent):
* Source/WebCore/page/Navigation.h:
* Source/WebKit/Shared/WebBackForwardListItem.cpp:
(WebKit::WebBackForwardListItem::itemIsInSameDocument const):
(WebKit::childItemWithDocumentSequenceNumber): Deleted.
(WebKit::documentTreesAreEqual): Deleted.
Canonical link: https://commits.webkit.org/302418@main
To unsubscribe from these emails, change your notification settings at
https://github.com/WebKit/WebKit/settings/notifications