Branch: refs/heads/main
Home: https://github.com/WebKit/WebKit
Commit: 16dc6bfd11c1dc99d785ada5b4b5f0af08dd63fb
https://github.com/WebKit/WebKit/commit/16dc6bfd11c1dc99d785ada5b4b5f0af08dd63fb
Author: Brady Eidson <[email protected]>
Date: 2026-04-20 (Mon, 20 Apr 2026)
Changed paths:
M Source/WTF/wtf/cocoa/RuntimeApplicationChecksCocoa.h
M Source/WebCore/history/HistoryItem.cpp
M Source/WebCore/history/HistoryItem.h
M Source/WebCore/loader/FrameLoader.cpp
M Source/WebCore/loader/HistoryController.cpp
M Source/WebKit/Shared/LoadParameters.h
M Source/WebKit/Shared/LoadParameters.serialization.in
M Source/WebKit/Shared/WebBackForwardListFrameItem.cpp
M Source/WebKit/UIProcess/API/C/WKBackForwardListRef.cpp
M Source/WebKit/UIProcess/API/Cocoa/WKBackForwardList.mm
M Source/WebKit/UIProcess/WebBackForwardList.cpp
M Source/WebKit/UIProcess/WebBackForwardList.h
M Source/WebKit/UIProcess/WebPageProxy.cpp
M Source/WebKit/UIProcess/WebPageProxy.h
M Source/WebKit/WebProcess/WebPage/WebPage.cpp
M Tools/TestWebKitAPI/Tests/WebKit/WKWebView/ProcessSwapOnNavigation.mm
M Tools/TestWebKitAPI/Tests/WebKit/WKWebView/WKBackForwardListTests.mm
Log Message:
-----------
Back button unexpectedly enabled in newly opened tab
rdar://174798415
https://bugs.webkit.org/show_bug.cgi?id=310243
Reviewed by Chris Dumez.
Normally, navigating a page to a new URL will push a new back/forward history
entry.
Browsers detect client redirects that occur during the loading process (i.e.
before the load event)
and update the existing back/forward item instead of creating new ones for the
location change.
Some sites do something like this "quick client redirect" but subtly
asynchronous. For example, via
a promise chain that sometimes can resolve synchronously, but often does not,
even if it resolves
very shortly after the load event. This causes the location change to actually
happen after the load
event, and therefore its treated as a new navigation that warrants creating a
new back/forward item.
This leads to an annoying user experience for users when, for example, a new
window or tab ends up
with multiple items in the back/forward list, leading to an enabled back
button, confusing the user.
In https://commits.webkit.org/259437@main we added logic that skips some items
created by JS when
going back or forward. This was a fix to guard against malicious JS trying to
hijack the list.
But the same logic can be applied here - Tracking items that are created
without user interaction
and treating them differently.
The fix in 259437@main was incomplete as it only applied to "goBack" and
"goForward" to protect
against hijacking swipe gestures. It did not apply to getting the items in the
lists or to the
"goToItem:" API.
This change expands that fix to all API access of the back/forward list,
presenting an entirely
different view of the list to the client application then JavaScript will see
in the `history`
interface. Additionally, it sets the flag in one more case when one of these
"quick redirects"
occurs but after the load event.
This type of "presenting a different back/forward list to the app than what
JavaScript sees" has
precedent in other browser engines and is probably a good mechanism to have
going forward.
Finally, it also tests the new behavior both via JavaScript and the WebKit API
to make sure that
the back/forward list is represented differently to each.
Test: Tools/TestWebKitAPI/Tests/WebKit/WKWebView/WKBackForwardListTests.mm
* Source/WTF/wtf/cocoa/RuntimeApplicationChecksCocoa.h:
* Source/WebCore/history/HistoryItem.cpp:
(WebCore::HistoryItem::setWasCreatedByJSWithoutUserInteraction):
* Source/WebCore/history/HistoryItem.h:
(WebCore::HistoryItem::setWasCreatedByJSWithoutUserInteraction): Deleted.
* Source/WebCore/loader/HistoryController.cpp:
(WebCore::HistoryController::updateForStandardLoad):
* Source/WebKit/UIProcess/API/C/WKBackForwardListRef.cpp:
(WKBackForwardListGetBackItem):
(WKBackForwardListGetForwardItem):
* Source/WebKit/UIProcess/API/Cocoa/WKBackForwardList.mm:
(-[WKBackForwardList backItem]):
(-[WKBackForwardList forwardItem]):
* Source/WebKit/UIProcess/WebBackForwardList.cpp:
(shouldSkipItemsForWebKitAPI):
(WebKit::WebBackForwardList::backItem const):
(WebKit::WebBackForwardList::forwardItem const):
(WebKit::WebBackForwardList::itemAtDeltaFromCurrentIndex const):
(WebKit::WebBackForwardList::backListAsAPIArrayWithLimit const):
(WebKit::WebBackForwardList::forwardListAsAPIArrayWithLimit const):
(WebKit::WebBackForwardList::itemStartingAtIndexSkippingItemsAddedByJSWithoutUserGesture
const):
(WebKit::WebBackForwardList::backForwardUpdateItem):
(WebKit::WebBackForwardList::backForwardItemAtIndexForWebContent):
(WebKit::WebBackForwardListWrapper::backItem const):
(WebKit::WebBackForwardListWrapper::forwardItem const):
(WebKit::WebBackForwardListWrapper::itemAtDeltaFromCurrentIndex const):
* Source/WebKit/UIProcess/WebBackForwardList.h:
* Source/WebKit/UIProcess/WebPageProxy.cpp:
(WebKit::WebPageProxy::didChangeBackForwardList):
(WebKit::WebPageProxy::updateCanGoBackAndForward):
* Source/WebKit/UIProcess/WebPageProxy.h:
* Tools/TestWebKitAPI/Tests/WebKit/WKWebView/WKBackForwardListTests.mm:
(TEST(WKBackForwardList,
BackForwardNavigationSkipsPromiseRedirectWithoutUserInteraction)):
Canonical link: https://commits.webkit.org/311615@main
To unsubscribe from these emails, change your notification settings at
https://github.com/WebKit/WebKit/settings/notifications