Branch: refs/heads/main
Home: https://github.com/WebKit/WebKit
Commit: d86c4e68319ab64a1deaafd7052be2d6694b5f0b
https://github.com/WebKit/WebKit/commit/d86c4e68319ab64a1deaafd7052be2d6694b5f0b
Author: Tyler Wilcock <[email protected]>
Date: 2026-05-22 (Fri, 22 May 2026)
Changed paths:
A
LayoutTests/http/tests/site-isolation/accessibility/client/walk-up-from-iframe-content-expected.txt
A
LayoutTests/http/tests/site-isolation/accessibility/client/walk-up-from-iframe-content.html
M Source/WebKit/WebProcess/WebPage/mac/WebPageMac.mm
Log Message:
-----------
AX Site Isolation: macOS VoiceOver wraps to the top of the page when trying
to navigate past a cross-origin iframe
https://bugs.webkit.org/show_bug.cgi?id=315356
rdar://177714038
Reviewed by Dominic Mazzoni.
This bug occurred because the root scroll area associated with an remote
iframe had an AXProperty::RemoteParent (a WKAccessibilityWebPageObject)
that itself never had its m_parent set, breaking the accessibility tree
and thus preventing VoiceOver from navigating effectively.
This was possible due to this sequence:
1. Pre-warmed iframe process is spawned (Safari prewarms some web
content processes).
2. platformInitializeAccessibility runs in this iframe process,
calling createMockAccessibilityElement() (this creates a
WKAccessibilityWebPageObject).
Note that its m_parent is nil at this point.
3. An accessibility query reaches the iframe process, triggering
AXIsolatedTree::create. The iframe root scrollarea caches an
AXProperty::RemoteParent with a pointer to the
WKAccessibilityWebPageObject from step 2 (whose m_parent is still nil).
4. The parent web content process creates an AXRemoteFrame representing the
iframe web content process. It sends
bindRemoteAccessibilityFrames(parentPid, parentToken)
through the UI process.
5. Iframe's WebPage::bindRemoteAccessibilityFrames runs as result, and calls
registerRemoteFrameAccessibilityTokens. Prior to this commit, this
unconditionally replaced m_mockAccessibilityElement (the
WKAccessibilityWebPageObject)
with a brand new instance, and sets m_parent for the new instance.
6. The iframe's root scroll area still has the old
WKAccessibilityWebPageObject cached in its AXProperty::RemoteFrame
from step #2, with a nil m_parent.
This bug is intermittent, critically depending on whether there was a
prewarmed process available for the iframe web content. If there was not
a prewarmed process available, AXProperty::RemoteParent is set up from
the start with the WKAccessibilityWebPageObject that used to be
unconditionally created in step 5, and the bug did not manifest.
This commit fixes the issue by changing registerRemoteFrameAccessibilityTokens
to only create a new m_mockAccessibilityElement if one doesn't already
exist, preventing the iframe scroll area from being associated with a
stale one that has no parent.
Because the bug depends on prewarming behavior, the added layout test
passes with and without this commit. I couldn't find a good way to
emulate that in our testing environment. Fix manually confirmed in Safari.
*
LayoutTests/http/tests/site-isolation/accessibility/client/walk-up-from-iframe-content-expected.txt:
Added.
*
LayoutTests/http/tests/site-isolation/accessibility/client/walk-up-from-iframe-content.html:
Added.
* Source/WebKit/WebProcess/WebPage/mac/WebPageMac.mm:
(WebKit::WebPage::registerRemoteFrameAccessibilityTokens):
Canonical link: https://commits.webkit.org/313754@main
To unsubscribe from these emails, change your notification settings at
https://github.com/WebKit/WebKit/settings/notifications