Branch: refs/heads/main
Home: https://github.com/WebKit/WebKit
Commit: c1e16773122e8d52ef7b55c00404eb530575f4a4
https://github.com/WebKit/WebKit/commit/c1e16773122e8d52ef7b55c00404eb530575f4a4
Author: Tyler Wilcock <[email protected]>
Date: 2026-02-26 (Thu, 26 Feb 2026)
Changed paths:
M LayoutTests/accessibility/ax-object-destroyed-on-reload-expected.txt
M LayoutTests/accessibility/ax-object-destroyed-on-reload.html
A
LayoutTests/http/tests/site-isolation/accessibility/cross-process-search-headings-expected.txt
A
LayoutTests/http/tests/site-isolation/accessibility/cross-process-search-headings.html
A
LayoutTests/http/tests/site-isolation/accessibility/cross-process-search-nested-iframes-expected.txt
A
LayoutTests/http/tests/site-isolation/accessibility/cross-process-search-nested-iframes.html
A
LayoutTests/http/tests/site-isolation/accessibility/cross-process-search-traversal-expected.txt
A
LayoutTests/http/tests/site-isolation/accessibility/cross-process-search-traversal.html
A
LayoutTests/http/tests/site-isolation/accessibility/resources/iframe-with-headings.html
A
LayoutTests/http/tests/site-isolation/accessibility/resources/nested-iframe-inner.html
A
LayoutTests/http/tests/site-isolation/accessibility/resources/nested-iframe-middle.html
M
LayoutTests/platform/ios/accessibility/ax-object-destroyed-on-reload-expected.txt
M Source/WebCore/Headers.cmake
M Source/WebCore/Sources.txt
M Source/WebCore/WebCore.xcodeproj/project.pbxproj
A Source/WebCore/accessibility/AXAnnouncementTypes.h
M Source/WebCore/accessibility/AXCoreObject.cpp
M Source/WebCore/accessibility/AXCoreObject.h
A Source/WebCore/accessibility/AXCrossProcessSearch.cpp
A Source/WebCore/accessibility/AXCrossProcessSearch.h
M Source/WebCore/accessibility/AXLiveRegionManager.h
M Source/WebCore/accessibility/AXLogger.cpp
M Source/WebCore/accessibility/AXObjectCache.cpp
M Source/WebCore/accessibility/AXObjectCache.h
M Source/WebCore/accessibility/AXRemoteFrame.h
M Source/WebCore/accessibility/AXSearchManager.cpp
M Source/WebCore/accessibility/AXSearchManager.h
M Source/WebCore/accessibility/AXStitchUtilities.h
M Source/WebCore/accessibility/AccessibilityMockObject.h
M Source/WebCore/accessibility/AccessibilityNodeObject.cpp
M Source/WebCore/accessibility/AccessibilityObject.cpp
M Source/WebCore/accessibility/AccessibilityObject.h
A Source/WebCore/accessibility/AccessibilityRemoteToken.h
M Source/WebCore/accessibility/AccessibilityRenderObject.cpp
M Source/WebCore/accessibility/AccessibilityScrollView.cpp
M Source/WebCore/accessibility/AccessibilityScrollView.h
A Source/WebCore/accessibility/AccessibilitySearchCriteriaIPC.h
M Source/WebCore/accessibility/ios/WebAccessibilityObjectWrapperIOS.mm
M Source/WebCore/accessibility/isolatedtree/AXIsolatedObject.cpp
M Source/WebCore/accessibility/isolatedtree/AXIsolatedObject.h
M Source/WebCore/accessibility/isolatedtree/AXIsolatedTree.cpp
M Source/WebCore/accessibility/isolatedtree/AXIsolatedTree.h
M Source/WebCore/accessibility/isolatedtree/mac/AXIsolatedObjectMac.mm
M Source/WebCore/accessibility/mac/WebAccessibilityObjectWrapperMac.mm
M Source/WebCore/page/ChromeClient.cpp
M Source/WebCore/page/ChromeClient.h
M Source/WebCore/page/FrameTree.h
M Source/WebKit/Scripts/webkit/messages.py
M Source/WebKit/Shared/WebCoreArgumentCoders.serialization.in
M Source/WebKit/UIProcess/WebPageProxy.cpp
M Source/WebKit/UIProcess/WebPageProxy.h
M Source/WebKit/UIProcess/WebPageProxy.messages.in
M Source/WebKit/WebProcess/WebCoreSupport/WebChromeClient.cpp
M Source/WebKit/WebProcess/WebCoreSupport/WebChromeClient.h
M Source/WebKit/WebProcess/WebPage/Cocoa/WebPageCocoa.mm
M Source/WebKit/WebProcess/WebPage/WebPage.h
M Source/WebKit/WebProcess/WebPage/WebPage.messages.in
M Tools/WebKitTestRunner/InjectedBundle/AccessibilityUIElement.cpp
M Tools/WebKitTestRunner/InjectedBundle/AccessibilityUIElement.h
M Tools/WebKitTestRunner/InjectedBundle/Bindings/AccessibilityUIElement.idl
M
Tools/WebKitTestRunner/InjectedBundle/atspi/AccessibilityUIElementAtspi.cpp
M Tools/WebKitTestRunner/InjectedBundle/atspi/AccessibilityUIElementAtspi.h
M Tools/WebKitTestRunner/InjectedBundle/ios/AccessibilityUIElementIOS.h
M Tools/WebKitTestRunner/InjectedBundle/ios/AccessibilityUIElementIOS.mm
M Tools/WebKitTestRunner/InjectedBundle/mac/AccessibilityUIElementMac.h
M Tools/WebKitTestRunner/InjectedBundle/mac/AccessibilityUIElementMac.mm
M
Tools/WebKitTestRunner/InjectedBundle/playstation/AccessibilityUIElementPlayStation.cpp
M
Tools/WebKitTestRunner/InjectedBundle/playstation/AccessibilityUIElementPlayStation.h
M Tools/WebKitTestRunner/InjectedBundle/win/AccessibilityUIElementWin.cpp
M Tools/WebKitTestRunner/InjectedBundle/win/AccessibilityUIElementWin.h
Log Message:
-----------
AX: On macOS with site isolation enabled, VoiceOver cannot traverse into
iframes because UIElementsForSearchPredicate only searches within the same
process
https://bugs.webkit.org/show_bug.cgi?id=307994
rdar://170487304
Reviewed by Joshua Hoffman.
This change implements cross-process accessibility search to support VoiceOver
navigation across site-isolated iframes. When a search encounters a remote
frame,
it sends async IPC to the child process to continue the search, then continues
its
search in its own process. The parent process is also queried via async IPC,
since the search may require moving beyond this frame (e.g. asking for the next
element at the last element in an iframe). When children + parent processes
return
results, we merge them back in tree order, resolving AccessibilityRemoteToken
results into
NSAccessibilityRemoteUIElements as necessary.
The search uses a single absolute deadline established when the top-level
search begins,
rather than giving each nested frame its own independent timeout. When
dispatching to child
frames, the remaining time until the deadline (minus IPC overhead buffer) is
passed along,
ensuring deeply nested frame hierarchies share the original timeout budget.
This prevents
timeout multiplication where N levels of nesting would otherwise allow N ×
timeout total
wait time, while still guaranteeing each frame gets at least a minimum search
duration.
Other key changes:
- Add AXCrossProcessSearch.{h,cpp} with coordination infrastructure for
parallel
IPC dispatch and cascading timeouts (described above) across nested frames
- Refactor AXSearchManager to return AccessibilitySearchResultStream that
records
both local results and remote frame placeholders in tree order
- Add ChromeClient methods for performAccessibilitySearchInRemoteFrame() and
continueAccessibilitySearchFromChildFrame() to enable bidirectional search.
- Add uiElementsForSearchPredicate() test helper for verifying multi-result
searches.
- Track accessibility enabled state in WebPageCreationParameters so
newly-created
web processes for site-isolated frames start with accessibility being
enabled.
This was required to make my three new tests pass because accessibility
must be
enabled by the time they got a cross-process accessibility search request.
- Searched frames are tracked by ID and will not be searched multiple times.
New tests were added to exercise various interesting scenarios:
- http/tests/site-isolation/accessibility/cross-process-search-headings.html
* Ensures proper merging of local and remote results.
-
http/tests/site-isolation/accessibility/cross-process-search-nested-iframes.html
* Verifies search progresses through multiple layers of iframes.
- http/tests/site-isolation/accessibility/cross-process-search-traversal.html
* Ensures that we can traverse all the way forwards and back through
the all content on the page.
* LayoutTests/accessibility/ax-object-destroyed-on-reload-expected.txt:
* LayoutTests/accessibility/ax-object-destroyed-on-reload.html:
*
LayoutTests/http/tests/site-isolation/accessibility/cross-process-search-headings-expected.txt:
Added.
*
LayoutTests/http/tests/site-isolation/accessibility/cross-process-search-headings.html:
Added.
*
LayoutTests/http/tests/site-isolation/accessibility/cross-process-search-nested-iframes-expected.txt:
Added.
*
LayoutTests/http/tests/site-isolation/accessibility/cross-process-search-nested-iframes.html:
Added.
*
LayoutTests/http/tests/site-isolation/accessibility/cross-process-search-traversal-expected.txt:
Added.
*
LayoutTests/http/tests/site-isolation/accessibility/cross-process-search-traversal.html:
Added.
*
LayoutTests/http/tests/site-isolation/accessibility/resources/iframe-with-headings.html:
Added.
*
LayoutTests/http/tests/site-isolation/accessibility/resources/nested-iframe-inner.html:
Added.
*
LayoutTests/http/tests/site-isolation/accessibility/resources/nested-iframe-middle.html:
Added.
*
LayoutTests/platform/ios/accessibility/ax-object-destroyed-on-reload-expected.txt:
* Source/WebCore/Headers.cmake:
* Source/WebCore/Sources.txt:
* Source/WebCore/WebCore.xcodeproj/project.pbxproj:
* Source/WebCore/accessibility/AXAnnouncementTypes.h: Added.
* Source/WebCore/accessibility/AXCoreObject.cpp:
(WebCore::AXCoreObject::partialOrder):
(WebCore::AXCoreObject::findMatchingObjectsWithin):
* Source/WebCore/accessibility/AXCoreObject.h:
* Source/WebCore/accessibility/AXCrossProcessSearch.cpp: Added.
(WebCore::canDoRemoteSearch):
(WebCore::spinRunLoopUntil):
(WebCore::AXCrossProcessSearchCoordinator::waitWithTimeout):
(WebCore::mergeStreamResults):
(WebCore::computeRemainingTimeout):
(WebCore::dispatchRemoteFrameSearch):
(WebCore::performCrossProcessSearch):
(WebCore::performSearchWithCrossProcessCoordination):
(WebCore::mergeParentSearchResults):
(WebCore::ParentFrameSearchContext::signal):
(WebCore::ParentFrameSearchContext::waitWithTimeout):
(WebCore::ParentFrameSearchContext::markParentDispatched):
(WebCore::ParentFrameSearchContext::didDispatchParent const):
(WebCore::ParentFrameSearchContext::setParentTokens):
(WebCore::ParentFrameSearchContext::takeParentTokens):
(WebCore::performSearchWithParentCoordination):
* Source/WebCore/accessibility/AXCrossProcessSearch.h: Added.
(WebCore::AXCrossProcessSearchCoordinator::create):
(WebCore::AXCrossProcessSearchCoordinator::addPendingRequest):
(WebCore::AXCrossProcessSearchCoordinator::markSearchComplete):
(WebCore::AXCrossProcessSearchCoordinator::responseReceived):
(WebCore::AXCrossProcessSearchCoordinator::storeRemoteResults):
(WebCore::AXCrossProcessSearchCoordinator::takeRemoteResults):
(WebCore::AXCrossProcessSearchCoordinator::markFrameAsSearched):
(WebCore::AXCrossProcessSearchCoordinator::checkCompletion):
* Source/WebCore/accessibility/AXLiveRegionManager.h:
(): Deleted.
* Source/WebCore/accessibility/AXLogger.cpp:
(WebCore::operator<<):
(WebCore::streamAXCoreObject):
* Source/WebCore/accessibility/AXObjectCache.cpp:
(WebCore::AXObjectCache::getOrCreateSlow):
* Source/WebCore/accessibility/AXObjectCache.h:
(WebCore::AccessibilityRemoteToken::AccessibilityRemoteToken): Deleted.
* Source/WebCore/accessibility/AXRemoteFrame.h:
* Source/WebCore/accessibility/AXSearchManager.cpp:
(WebCore::AXSearchManager::findMatchingObjectsAsStream):
(WebCore::AXSearchManager::findMatchingObjectsInternalAsStream):
(WebCore::AXSearchManager::findMatchingRange):
(WebCore::AXSearchManager::matchWithResultsLimit): Deleted.
(WebCore::AXSearchManager::findMatchingObjectsInternal): Deleted.
* Source/WebCore/accessibility/AXSearchManager.h:
(WebCore::AccessibilitySearchCriteriaIPC::AccessibilitySearchCriteriaIPC):
(WebCore::AccessibilitySearchCriteriaIPC::toSearchCriteria const):
(WebCore::SearchResultEntry::localResult):
(WebCore::SearchResultEntry::remoteFrame):
(WebCore::SearchResultEntry::isLocalResult const):
(WebCore::SearchResultEntry::isRemoteFrame const):
(WebCore::SearchResultEntry::objectIfLocalResult const):
(WebCore::SearchResultEntry::frameID const):
(WebCore::SearchResultEntry::streamIndex const):
(WebCore::SearchResultEntry::SearchResultEntry):
(WebCore::AccessibilitySearchResultStream::appendLocalResult):
(WebCore::AccessibilitySearchResultStream::appendRemoteFrame):
(WebCore::AccessibilitySearchResultStream::entries const):
(WebCore::AccessibilitySearchResultStream::entryCount const):
(WebCore::AccessibilitySearchResultStream::setResultsLimit):
(WebCore::AccessibilitySearchResultStream::resultsLimit const):
(WebCore::AccessibilitySearchResultStream::nextIndex const):
(WebCore::AccessibilitySearchResult::local):
(WebCore::AccessibilitySearchResult::remote):
(WebCore::AccessibilitySearchResult::isLocal const):
(WebCore::AccessibilitySearchResult::isRemote const):
(WebCore::AccessibilitySearchResult::objectIfLocalResult const):
(WebCore::AccessibilitySearchResult::remoteToken const):
(WebCore::AccessibilitySearchResult::AccessibilitySearchResult):
(WebCore::AXSearchManager::findMatchingObjects): Deleted.
* Source/WebCore/accessibility/AXStitchUtilities.h:
* Source/WebCore/accessibility/AccessibilityMockObject.h:
* Source/WebCore/accessibility/AccessibilityNodeObject.cpp:
* Source/WebCore/accessibility/AccessibilityObject.cpp:
(WebCore::AccessibilityObject::findMatchingObjectsWithin):
(WebCore::AccessibilityObject::findMatchingObjects): Deleted.
* Source/WebCore/accessibility/AccessibilityObject.h:
* Source/WebCore/accessibility/AccessibilityRemoteToken.h: Added.
(WebCore::AccessibilityRemoteToken::AccessibilityRemoteToken):
* Source/WebCore/accessibility/AccessibilityRenderObject.cpp:
* Source/WebCore/accessibility/AccessibilityScrollView.cpp:
(WebCore::AccessibilityScrollView::detachRemoteParts):
* Source/WebCore/accessibility/AccessibilityScrollView.h:
* Source/WebCore/accessibility/AccessibilitySearchCriteriaIPC.h: Added.
* Source/WebCore/accessibility/ios/WebAccessibilityObjectWrapperIOS.mm:
(-[WebAccessibilityObjectWrapper accessibilityFindMatchingObjects:]):
* Source/WebCore/accessibility/isolatedtree/AXIsolatedObject.cpp:
(WebCore::AXIsolatedObject::findMatchingObjects): Deleted.
* Source/WebCore/accessibility/isolatedtree/AXIsolatedObject.h:
* Source/WebCore/accessibility/isolatedtree/AXIsolatedTree.cpp:
(WebCore::AXIsolatedTree::applyPendingChangesLocked):
* Source/WebCore/accessibility/isolatedtree/AXIsolatedTree.h:
* Source/WebCore/accessibility/isolatedtree/mac/AXIsolatedObjectMac.mm:
(WebCore::appendPlatformProperties):
* Source/WebCore/accessibility/mac/WebAccessibilityObjectWrapperMac.mm:
(remoteElementFromToken):
(searchResultsToNSArray):
(performSearchWithRemoteFrames):
(-[WebAccessibilityObjectWrapper
_accessibilityHitTestResolvingRemoteFrame:callback:]):
(-[WebAccessibilityObjectWrapper accessibilityAttributeValue:forParameter:]):
* Source/WebCore/page/ChromeClient.cpp:
(WebCore::ChromeClient::performAccessibilitySearchInRemoteFrame):
(WebCore::ChromeClient::continueAccessibilitySearchFromChildFrame):
* Source/WebCore/page/ChromeClient.h:
* Source/WebCore/page/FrameTree.h:
* Source/WebKit/Scripts/webkit/messages.py:
(headers_for_type):
* Source/WebKit/Shared/WebCoreArgumentCoders.serialization.in:
* Source/WebKit/UIProcess/WebPageProxy.cpp:
(WebKit::WebPageProxy::performAccessibilitySearchInRemoteFrame):
(WebKit::WebPageProxy::continueAccessibilitySearchFromChildFrame):
* Source/WebKit/UIProcess/WebPageProxy.h:
* Source/WebKit/UIProcess/WebPageProxy.messages.in:
* Source/WebKit/WebProcess/WebCoreSupport/WebChromeClient.cpp:
(WebKit::WebChromeClient::performAccessibilitySearchInRemoteFrame):
(WebKit::WebChromeClient::continueAccessibilitySearchFromChildFrame):
* Source/WebKit/WebProcess/WebCoreSupport/WebChromeClient.h:
* Source/WebKit/WebProcess/WebPage/Cocoa/WebPageCocoa.mm:
(WebKit::tokenFromWrapper):
(WebKit::convertSearchResultsToRemoteTokens):
(WebKit::WebPage::performAccessibilitySearchInRemoteFrame):
(WebKit::WebPage::continueAccessibilitySearchInParentFrame):
* Source/WebKit/WebProcess/WebPage/WebPage.h:
* Source/WebKit/WebProcess/WebPage/WebPage.messages.in:
* Tools/WebKitTestRunner/InjectedBundle/AccessibilityUIElement.cpp:
(WTR::AccessibilityUIElement::uiElementsForSearchPredicate):
* Tools/WebKitTestRunner/InjectedBundle/AccessibilityUIElement.h:
* Tools/WebKitTestRunner/InjectedBundle/Bindings/AccessibilityUIElement.idl:
* Tools/WebKitTestRunner/InjectedBundle/atspi/AccessibilityUIElementAtspi.cpp:
(WTR::AccessibilityUIElementAtspi::uiElementsForSearchPredicate):
* Tools/WebKitTestRunner/InjectedBundle/atspi/AccessibilityUIElementAtspi.h:
* Tools/WebKitTestRunner/InjectedBundle/ios/AccessibilityUIElementIOS.h:
* Tools/WebKitTestRunner/InjectedBundle/ios/AccessibilityUIElementIOS.mm:
(WTR::AccessibilityUIElementIOS::uiElementsForSearchPredicate):
* Tools/WebKitTestRunner/InjectedBundle/mac/AccessibilityUIElementMac.h:
* Tools/WebKitTestRunner/InjectedBundle/mac/AccessibilityUIElementMac.mm:
(WTR::AccessibilityUIElementMac::attributeValue const):
(WTR::AccessibilityUIElementMac::allAttributes):
(WTR::AccessibilityUIElementMac::setBoolAttributeValue):
(WTR::AccessibilityUIElementMac::setValue):
(WTR::AccessibilityUIElementMac::isAttributeSupported):
(WTR::AccessibilityUIElementMac::isValid const):
(WTR::AccessibilityUIElementMac::uiElementsForSearchPredicate):
(WTR::AccessibilityUIElementMac::setSelectedTextRange):
(WTR::AccessibilityUIElementMac::invokeCustomActionAtIndex):
(WTR::AccessibilityUIElementMac::setSelectedTextMarkerRange):
(WTR::AccessibilityUIElementMac::setSelectedChild const):
(WTR::AccessibilityUIElementMac::setSelectedChildAtIndex const):
(WTR::AccessibilityUIElementMac::removeSelectionAtIndex const):
(WTR::AccessibilityUIElementMac::takeFocus):
(WTR::AccessibilityUIElementMac::resetSelectedTextMarkerRange):
*
Tools/WebKitTestRunner/InjectedBundle/playstation/AccessibilityUIElementPlayStation.cpp:
(WTR::AccessibilityUIElementPlayStation::uiElementsForSearchPredicate):
*
Tools/WebKitTestRunner/InjectedBundle/playstation/AccessibilityUIElementPlayStation.h:
* Tools/WebKitTestRunner/InjectedBundle/win/AccessibilityUIElementWin.cpp:
(WTR::AccessibilityUIElementWin::uiElementsForSearchPredicate):
* Tools/WebKitTestRunner/InjectedBundle/win/AccessibilityUIElementWin.h:
Canonical link: https://commits.webkit.org/308321@main
To unsubscribe from these emails, change your notification settings at
https://github.com/WebKit/WebKit/settings/notifications