Repository: WebKit/WebKit
Pull request #43403: AX: For every clearChildren-addChildren cycle, we create new AccessibilityImageMapLink instances and never clean them up, causing a memory leak
Author: login: twilco
Labels: name: Accessibility
description: For bugs related to accessibility.
Created: 2025-04-01T20:58:29Z | Merged: 2025-04-04T22:23:29Z

#### eed31338f551e7934e2a8901262a1238cb8b1142
<pre>
AX: For every clearChildren-addChildren cycle, we create new AccessibilityImageMapLink instances and never clean them up, causing a memory leak
<a href="https://bugs.webkit.org/show_bug.cgi?id=284125">https://bugs.webkit.org/show_bug.cgi?id=284125</a>
<a href="https://rdar.apple.com/141013232">rdar://141013232</a>

Reviewed by Joshua Hoffman.

Like most other things generated by AXObjectCache::create(AccessibilityRole), AccessibilityImageMapLinks are never
are not persisted between clear-children add-children cycles, and are never passed in a call to AXObjectCache::remove,
meaning they leak forever.

Fix this by making AccessibilityImageMapLink subclass AccessibilityNodeObject, inherently tying their lifetime to the
HTMLAreaElement that they represent.

This commit also eliminates redundant role ImageMapLink. There is no reason for this role to exist over other existing
roles, WebCoreLink and Link.

* LayoutTests/accessibility/image-map-title-causes-crash-expected.txt:
* LayoutTests/accessibility/image-map-title-causes-crash.html:
* LayoutTests/imported/w3c/web-platform-tests/html-aam/fragile/area-role-expected.txt:
* LayoutTests/platform/glib/accessibility/image-map2-expected.txt:
* Source/WebCore/SaferCPPExpectations/UncountedCallArgsCheckerExpectations:
* Source/WebCore/SaferCPPExpectations/UncountedLocalVarsCheckerExpectations:
* Source/WebCore/accessibility/AXCoreObject.cpp:
(WebCore::AXCoreObject::isLink const):
(WebCore::AXCoreObject::isImplicitlyInteractive const):
* Source/WebCore/accessibility/AXCoreObject.h:
(WebCore::accessibilityRoleToString):
* Source/WebCore/accessibility/AXObjectCache.cpp:
(WebCore::AXObjectCache::focusedImageMapUIElement):
(WebCore::AXObjectCache::createFromNode):
(WebCore::AXObjectCache::getOrCreate):
(WebCore::AXObjectCache::create):
* Source/WebCore/accessibility/AccessibilityImageMapLink.cpp:
(WebCore::AccessibilityImageMapLink::AccessibilityImageMapLink):
(WebCore::AccessibilityImageMapLink::create):
(WebCore::AccessibilityImageMapLink::parentObject const):
(WebCore::AccessibilityImageMapLink::determineAccessibilityRole):
(WebCore::AccessibilityImageMapLink::anchorElement const):
(WebCore::AccessibilityImageMapLink::url const):
(WebCore::AccessibilityImageMapLink::imageMapLinkRenderer const):
(WebCore::AccessibilityImageMapLink::elementPath const):
(WebCore::AccessibilityImageMapLink::elementRect const):
(WebCore::AccessibilityImageMapLink::setHTMLAreaElement): Deleted.
(WebCore::AccessibilityImageMapLink::detachFromParent): Deleted.
* Source/WebCore/accessibility/AccessibilityImageMapLink.h:
* Source/WebCore/accessibility/AccessibilityRenderObject.cpp:
(WebCore::AccessibilityRenderObject::documentLinks):
(WebCore::AccessibilityRenderObject::addImageMapChildren):
(WebCore::AccessibilityRenderObject::addChildren):
* Source/WebCore/accessibility/atspi/AccessibilityAtspi.cpp:
* Source/WebCore/accessibility/atspi/AccessibilityObjectAtspi.cpp:
(WebCore::atspiRole):
* Source/WebCore/accessibility/cocoa/AXCoreObjectCocoa.mm:
(WebCore::Accessibility::createPlatformRoleMap):
* Source/WebCore/accessibility/ios/WebAccessibilityObjectWrapperIOS.mm:
(-[WebAccessibilityObjectWrapper accessibilityCanFuzzyHitTest]):
(-[WebAccessibilityObjectWrapper determineIsAccessibilityElement]):
* Source/WebCore/accessibility/mac/WebAccessibilityObjectWrapperMac.mm:
(children):

Canonical link: <a href="https://commits.webkit.org/293278@main">https://commits.webkit.org/293278@main</a>
</pre>
<!--EWS-Status-Bubble-Start-->
https://github.com/WebKit/WebKit/commit/4d8c7ea231b698b91624de8cdba9aa98d5be26e7

| Misc | iOS, visionOS, tvOS & watchOS  | macOS  | Linux |  Windows |
| ----- | ---------------------- | ------- |  ----- |  --------- |
| [✅ 🧪 style](https://ews-build.webkit.org/#/builders/38/builds/97992 "Passed style check") | [✅ 🛠 ios](https://ews-build.webkit.org/#/builders/131/builds/17623 "Built successfully") | [✅ 🛠 mac](https://ews-build.webkit.org/#/builders/138/builds/7850 "Built successfully") | [✅ 🛠 wpe](https://ews-build.webkit.org/#/builders/5/builds/103107 "Built successfully") | [✅ 🛠 win](https://ews-build.webkit.org/#/builders/59/builds/48521 "Built successfully") 
| [✅ 🧪 bindings](https://ews-build.webkit.org/#/builders/9/builds/100037 "Passed tests") | [✅ 🛠 ios-sim](https://ews-build.webkit.org/#/builders/130/builds/17915 "Built successfully") | [✅ 🛠 mac-AS-debug](https://ews-build.webkit.org/#/builders/123/builds/26074 "Built successfully") | [❌ 🧪 wpe-wk2](https://ews-build.webkit.org/#/builders/34/builds/74607 "Found 1 new test failure: imported/w3c/web-platform-tests/css/css-view-transitions/active-view-transition-type-on-non-root.html (failure)") | [✅ 🧪 win-tests](https://ews-build.webkit.org/#/builders/60/builds/31798 "Passed tests") 
| [✅ 🧪 webkitperl](https://ews-build.webkit.org/#/builders/11/builds/100996 "Passed tests") | [❌ 🧪 ios-wk2](https://ews-build.webkit.org/#/builders/132/builds/13573 "Found 1 new test failure: fast/forms/ios/focus-input-via-button.html (failure)") | [✅ 🧪 api-mac](https://ews-build.webkit.org/#/builders/18/builds/88554 "Passed tests") | [✅ 🧪 api-wpe](https://ews-build.webkit.org/#/builders/41/builds/54967 "Passed tests") | 
| | [✅ 🧪 ios-wk2-wpt](https://ews-build.webkit.org/#/builders/133/builds/13353 "Passed tests") | [✅ 🧪 mac-wk1](https://ews-build.webkit.org/#/builders/135/builds/6484 "Passed tests") | [✅ 🛠 wpe-cairo](https://ews-build.webkit.org/#/builders/65/builds/47963 "Built successfully") | 
| | [✅ 🧪 api-ios](https://ews-build.webkit.org/#/builders/13/builds/83335 "Passed tests") | [✅ 🧪 mac-wk2](https://ews-build.webkit.org/#/builders/136/builds/6567 "Passed tests") | [✅ 🛠 gtk](https://ews-build.webkit.org/#/builders/2/builds/105485 "Built successfully") | 
| | [✅ 🛠 vision](https://ews-build.webkit.org/#/builders/128/builds/25078 "Built successfully") | [✅ 🧪 mac-AS-debug-wk2](https://ews-build.webkit.org/#/builders/122/builds/18264 "Passed tests") | [✅ 🧪 gtk-wk2](https://ews-build.webkit.org/#/builders/1/builds/83595 "Passed tests") | 
| | [✅ 🛠 vision-sim](https://ews-build.webkit.org/#/builders/121/builds/25451 "Built successfully") | [✅ 🧪 mac-wk2-stress](https://ews-build.webkit.org/#/builders/8/builds/84732 "Passed tests") | [✅ 🧪 api-gtk](https://ews-build.webkit.org/#/builders/21/builds/83047 "Passed tests") | 
| [✅ 🛠 🧪 merge](https://ews-build.webkit.org/#/builders/19/builds/21059 "Built successfully and passed tests") | [✅ 🧪 vision-wk2](https://ews-build.webkit.org/#/builders/126/builds/27691 "Passed tests") | [✅ 🧪 mac-intel-wk2](https://ews-build.webkit.org/#/builders/137/builds/5367 "Passed tests") | [✅ 🛠 playstation](https://ews-build.webkit.org/#/builders/134/builds/18701 "Built successfully") | 
| | [✅ 🛠 tv](https://ews-build.webkit.org/#/builders/127/builds/25037 "Built successfully") | [✅ 🛠 mac-safer-cpp](https://ews-build.webkit.org/#/builders/120/builds/30211 "Built successfully") | | 
| | [✅ 🛠 tv-sim](https://ews-build.webkit.org/#/builders/125/builds/24857 "Built successfully") | | | 
| | [✅ 🛠 watch](https://ews-build.webkit.org/#/builders/129/builds/28173 "Built successfully") | | | 
| | [✅ 🛠 watch-sim](https://ews-build.webkit.org/#/builders/124/builds/26432 "Built successfully") | | | 
<!--EWS-Status-Bubble-End-->


Diff:
diff --git a/LayoutTests/accessibility/image-map-title-causes-crash-expected.txt b/LayoutTests/accessibility/image-map-title-causes-crash-expected.txt
index b8255f9db7cd..1d9b1517f5d5 100644
--- a/LayoutTests/accessibility/image-map-title-causes-crash-expected.txt
+++ b/LayoutTests/accessibility/image-map-title-causes-crash-expected.txt
@@ -1,10 +1,8 @@
- 1
-Requesting the title of an AccessibilityImageMapLink can cause a crash when the map's area element has been removed.
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+This test ensures that we don't crash when requesting the title of all objects after dynamic area element removal.
 
+PASS: No crash.
 
 PASS successfullyParsed is true
 
 TEST COMPLETE
-
+ 1
diff --git a/LayoutTests/accessibility/image-map-title-causes-crash.html b/LayoutTests/accessibility/image-map-title-causes-crash.html
index 5a84855e4206..a57fc02e5726 100644
--- a/LayoutTests/accessibility/image-map-title-causes-crash.html
+++ b/LayoutTests/accessibility/image-map-title-causes-crash.html
@@ -1,47 +1,42 @@
 <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
 <html>
 <head>
-<script>
-
-    function removeAreaElement() {
-        document.getElementById("test").innerHTML=1
-    }
-
-    function queryTitleOnDecendants(accessibilityObject) {
-        accessibilityObject.title
-
-        var count = accessibilityObject.childrenCount;
-        for (var i = 0; i < count; ++i)
-            queryTitleOnDecendants(accessibilityObject.childAtIndex(i));
-    }
-</script>
-<script src="../resources/js-test-pre.js"></script>
+<script src="../resources/accessibility-helper.js"></script>
+<script src="../resources/js-test.js"></script>
 </head>
 <body>
 
 <img usemap="#map">
-<map name="map" id="test"><area href="javascript:document.getElementById('result').innerHTML='area clicked'" /></map>
+<map name="map" id="map"><area href="javascript:document.getElementById('result').innerHTML='area clicked'" /></map>
+    
+<script>
+var output = "This test ensures that we don't crash when requesting the title of all objects after dynamic area element removal.\n\n";
 
-<p id="description"></p>
-<div id="console"></div>
+function queryTitleOnDescendants(object) {
+    object.title;
 
-<script>
-    description("Requesting the title of an AccessibilityImageMapLink can cause a crash when the map's area element has been removed.");
-
-    if (window.accessibilityController) {
-        // First build up full accessibility tree.
-        document.body.focus();
-        queryTitleOnDecendants(accessibilityController.focusedElement);
-        
-        removeAreaElement()
-        
-        // Now call request the title for each accessibility object.
-        document.body.focus();
-        queryTitleOnDecendants(accessibilityController.focusedElement);
-    }
+    var count = object.childrenCount;
+    for (var i = 0; i < count; ++i)
+        queryTitleOnDescendants(object.childAtIndex(i));
+}
 
-</script>
+if (window.accessibilityController) {
+    window.jsTestIsAsync = true;
+
+    var webarea = accessibilityController.rootElement.childAtIndex(0);
+    queryTitleOnDescendants(webarea);
 
-<script src="../resources/js-test-post.js"></script>
+    // Remove the <area>, replacing it with a static text of "1".
+    document.getElementById("map").innerHTML = 1;
+    setTimeout(async function() {
+        queryTitleOnDescendants(webarea);
+        output += "PASS: No crash.\n";
+
+        debug(output);
+        finishJSTest();
+    }, 0);
+}
+</script>
 </body>
 </html>
+
diff --git a/LayoutTests/imported/w3c/web-platform-tests/html-aam/fragile/area-role-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/html-aam/fragile/area-role-expected.txt
index 0319932d8037..307042c9d862 100644
--- a/LayoutTests/imported/w3c/web-platform-tests/html-aam/fragile/area-role-expected.txt
+++ b/LayoutTests/imported/w3c/web-platform-tests/html-aam/fragile/area-role-expected.txt
@@ -1,5 +1,5 @@
 
 
-FAIL el-area assert_equals: <area shape="rect" coords="0,0,15,15" href="#" alt="x" data-testname="el-area" data-expectedrole="link" class="ex"> expected "link" but got ""
+PASS el-area
 PASS el-area-no-href
 
diff --git a/LayoutTests/platform/glib/accessibility/image-map2-expected.txt b/LayoutTests/platform/glib/accessibility/image-map2-expected.txt
index 8f4753d2079b..84b49598cfdf 100644
--- a/LayoutTests/platform/glib/accessibility/image-map2-expected.txt
+++ b/LayoutTests/platform/glib/accessibility/image-map2-expected.txt
@@ -22,12 +22,12 @@ AXPlatformAttributes: computed-role:generic, tag:div
 AXRole: AXLink
 AXParent: AXWebArea
 AXChildren: 0
-AXPosition: { 18.0000, 55.0000 }
+AXPosition: { 18.0000, 54.0000 }
 AXSize: { 123.000, 62.0000 }
 AXTitle: Link1
 AXDescription:
 AXValue:
-AXFocusable: 0
+AXFocusable: 1
 AXFocused: 0
 AXSelectable: 0
 AXSelected: 0
@@ -42,12 +42,12 @@ AXPlatformAttributes: computed-role:link, tag:area
 AXRole: AXLink
 AXParent: AXWebArea
 AXChildren: 0
-AXPosition: { 20.0000, 119.000 }
+AXPosition: { 20.0000, 118.000 }
 AXSize: { 122.000, 14.0000 }
 AXTitle: Link2
 AXDescription:
 AXValue:
-AXFocusable: 0
+AXFocusable: 1
 AXFocused: 0
 AXSelectable: 0
 AXSelected: 0
diff --git a/Source/WebCore/SaferCPPExpectations/UncountedCallArgsCheckerExpectations b/Source/WebCore/SaferCPPExpectations/UncountedCallArgsCheckerExpectations
index 9f71ac57c9aa..8f044b07ea3d 100644
--- a/Source/WebCore/SaferCPPExpectations/UncountedCallArgsCheckerExpectations
+++ b/Source/WebCore/SaferCPPExpectations/UncountedCallArgsCheckerExpectations
@@ -238,7 +238,6 @@ accessibility/AXObjectCache.cpp
 accessibility/AXObjectCache.h
 accessibility/AXSearchManager.cpp
 accessibility/AXTextMarker.cpp
-accessibility/AccessibilityImageMapLink.cpp
 accessibility/AccessibilityList.cpp
 accessibility/AccessibilityListBox.cpp
 accessibility/AccessibilityListBoxOption.cpp
diff --git a/Source/WebCore/SaferCPPExpectations/UncountedLocalVarsCheckerExpectations b/Source/WebCore/SaferCPPExpectations/UncountedLocalVarsCheckerExpectations
index 09d433353ab5..55653454d936 100644
--- a/Source/WebCore/SaferCPPExpectations/UncountedLocalVarsCheckerExpectations
+++ b/Source/WebCore/SaferCPPExpectations/UncountedLocalVarsCheckerExpectations
@@ -94,7 +94,6 @@ accessibility/AXRemoteFrame.cpp
 accessibility/AXSearchManager.cpp
 accessibility/AXTextMarker.cpp
 accessibility/AccessibilityARIAGridRow.cpp
-accessibility/AccessibilityImageMapLink.cpp
 accessibility/AccessibilityList.cpp
 accessibility/AccessibilityListBox.cpp
 accessibility/AccessibilityListBoxOption.cpp
diff --git a/Source/WebCore/accessibility/AXCoreObject.cpp b/Source/WebCore/accessibility/AXCoreObject.cpp
index cc9aededdbd6..b0dd0c6cdf5f 100644
--- a/Source/WebCore/accessibility/AXCoreObject.cpp
+++ b/Source/WebCore/accessibility/AXCoreObject.cpp
@@ -39,7 +39,7 @@ namespace WebCore {
 bool AXCoreObject::isLink() const
 {
     auto role = roleValue();
-    return role == AccessibilityRole::Link || role == AccessibilityRole::WebCoreLink || role == AccessibilityRole::ImageMapLink;
+    return role == AccessibilityRole::Link || role == AccessibilityRole::WebCoreLink;
 }
 
 bool AXCoreObject::isList() const
@@ -108,7 +108,6 @@ bool AXCoreObject::isImplicitlyInteractive() const
     case AccessibilityRole::ComboBox:
     case AccessibilityRole::DateTime:
     case AccessibilityRole::Details:
-    case AccessibilityRole::ImageMapLink:
     case AccessibilityRole::LandmarkSearch:
     case AccessibilityRole::Link:
     case AccessibilityRole::ListBox:
diff --git a/Source/WebCore/accessibility/AXCoreObject.h b/Source/WebCore/accessibility/AXCoreObject.h
index fe984dd21a8b..cc6158e7c04b 100644
--- a/Source/WebCore/accessibility/AXCoreObject.h
+++ b/Source/WebCore/accessibility/AXCoreObject.h
@@ -178,7 +178,6 @@ enum class AccessibilityRole : uint8_t {
     Inline,
     Image,
     ImageMap,
-    ImageMapLink,
     Insertion,
     Label,
     LandmarkBanner,
@@ -371,8 +370,6 @@ ALWAYS_INLINE String accessibilityRoleToString(AccessibilityRole role)
         return "Image"_s;
     case AccessibilityRole::ImageMap:
         return "ImageMap"_s;
-    case AccessibilityRole::ImageMapLink:
-        return "ImageMapLink"_s;
     case AccessibilityRole::Insertion:
         return "Insertion"_s;
     case AccessibilityRole::Label:
diff --git a/Source/WebCore/accessibility/AXObjectCache.cpp b/Source/WebCore/accessibility/AXObjectCache.cpp
index edc076ece84b..0895200165cd 100644
--- a/Source/WebCore/accessibility/AXObjectCache.cpp
+++ b/Source/WebCore/accessibility/AXObjectCache.cpp
@@ -504,7 +504,7 @@ AccessibilityObject* AXObjectCache::focusedImageMapUIElement(HTMLAreaElement& ar
     
     for (const auto& child : axRenderImage->unignoredChildren()) {
         auto* imageMapLink = dynamicDowncast<AccessibilityImageMapLink>(child.get());
-        if (imageMapLink && imageMapLink->areaElement() == &areaElement)
+        if (imageMapLink && imageMapLink->node() == &areaElement)
             return imageMapLink;
     }
     return nullptr;
@@ -844,6 +844,8 @@ Ref<AccessibilityNodeObject> AXObjectCache::createFromNode(Node& node)
             return AccessibilityARIAGridRow::create(AXID::generate(), *element);
         if (isAccessibilityARIAGridCell(*element))
             return AccessibilityARIAGridCell::create(AXID::generate(), *element);
+        if (auto* areaElement = dynamicDowncast<HTMLAreaElement>(*element))
+            return AccessibilityImageMapLink::create(AXID::generate(), *areaElement);
     }
     return AccessibilityNodeObject::create(AXID::generate(), node);
 }
@@ -945,7 +947,8 @@ AccessibilityObject* AXObjectCache::getOrCreate(Node& node, IsPartOfRelation isP
         auto* element = dynamicDowncast<Element>(node);
         bool hasDisplayContents = element && element->hasDisplayContents();
         bool isPopover = element && element->hasAttributeWithoutSynchronization(popoverAttr);
-        if (!inCanvasSubtree && !insideMeterElement && !hasDisplayContents && !isPopover && !isNodeFocused(node))
+        bool isAreaElement = is<HTMLAreaElement>(element);
+        if (!inCanvasSubtree && !insideMeterElement && !hasDisplayContents && !isPopover && !isNodeFocused(node) && !isAreaElement)
             return nullptr;
     }
 
@@ -1091,9 +1094,6 @@ AccessibilityObject* AXObjectCache::create(AccessibilityRole role)
 {
     RefPtr<AccessibilityObject> object;
     switch (role) {
-    case AccessibilityRole::ImageMapLink:
-        object = AccessibilityImageMapLink::create(AXID::generate());
-        break;
     case AccessibilityRole::Column:
         object = AccessibilityTableColumn::create(AXID::generate());
         break;
diff --git a/Source/WebCore/accessibility/AccessibilityImageMapLink.cpp b/Source/WebCore/accessibility/AccessibilityImageMapLink.cpp
index 6758c784922b..81977051d3c6 100644
--- a/Source/WebCore/accessibility/AccessibilityImageMapLink.cpp
+++ b/Source/WebCore/accessibility/AccessibilityImageMapLink.cpp
@@ -30,59 +30,40 @@
 #include "AccessibilityImageMapLink.h"
 
 #include "AXObjectCache.h"
-#include "AccessibilityRenderObject.h"
-#include "Document.h"
-#include "HTMLNames.h"
-#include "RenderBoxModelObject.h"
+#include "ElementAncestorIteratorInlines.h"
+#include "HTMLImageElement.h"
 
 namespace WebCore {
     
-using namespace HTMLNames;
-
-AccessibilityImageMapLink::AccessibilityImageMapLink(AXID axID)
-    : AccessibilityMockObject(axID)
-    , m_areaElement(nullptr)
-    , m_mapElement(nullptr)
+AccessibilityImageMapLink::AccessibilityImageMapLink(AXID axID, HTMLAreaElement& element)
+    : AccessibilityNodeObject(axID, &element)
 {
 }
 
 AccessibilityImageMapLink::~AccessibilityImageMapLink() = default;
 
-Ref<AccessibilityImageMapLink> AccessibilityImageMapLink::create(AXID axID)
+Ref<AccessibilityImageMapLink> AccessibilityImageMapLink::create(AXID axID, HTMLAreaElement& element)
 {
-    return adoptRef(*new AccessibilityImageMapLink(axID));
-}
-
-void AccessibilityImageMapLink::setHTMLAreaElement(HTMLAreaElement* element)
-{
-    if (element == m_areaElement)
-        return;
-    m_areaElement = element;
-    // AccessibilityImageMapLink::determineAccessibilityRole() depends on m_areaElement, so re-compute it now.
-    updateRole();
+    return adoptRef(*new AccessibilityImageMapLink(axID, element));
 }
 
 AccessibilityObject* AccessibilityImageMapLink::parentObject() const
 {
-    if (m_parent)
-        return m_parent.get();
-    
-    if (!m_mapElement.get() || !m_mapElement->renderer())
+    RefPtr node = this->node();
+    if (!node)
         return nullptr;
-    
-    return m_mapElement->document().axObjectCache()->getOrCreate(m_mapElement->renderer());
+
+    RefPtr map = ancestorsOfType<HTMLMapElement>(*node).first();
+    WeakPtr cache = axObjectCache();
+    return map && cache ? cache->getOrCreate(map->imageElement().get()) : nullptr;
 }
-    
+
 AccessibilityRole AccessibilityImageMapLink::determineAccessibilityRole()
 {
-    if (!m_areaElement)
-        return AccessibilityRole::WebCoreLink;
-    
-    const AtomString& ariaRole = getAttribute(roleAttr);
-    if (!ariaRole.isEmpty())
-        return AccessibilityObject::ariaRoleToWebCoreRole(ariaRole);
+    if ((m_ariaRole = determineAriaRoleAttribute()) != AccessibilityRole::Unknown)
+        return m_ariaRole;
 
-    return AccessibilityRole::WebCoreLink;
+    return !url().isEmpty() ? AccessibilityRole::WebCoreLink : AccessibilityRole::Generic;
 }
     
 Element* AccessibilityImageMapLink::actionElement() const
@@ -92,15 +73,14 @@ Element* AccessibilityImageMapLink::actionElement() const
     
 Element* AccessibilityImageMapLink::anchorElement() const
 {
-    return m_areaElement.get();
+    ASSERT(!node() || is<HTMLAreaElement>(node()));
+    return dynamicDowncast<Element>(node());
 }
 
 URL AccessibilityImageMapLink::url() const
 {
-    if (!m_areaElement.get())
-        return URL();
-    
-    return m_areaElement->href();
+    RefPtr areaElement = downcast<HTMLAreaElement>(node());
+    return areaElement ? areaElement->href() : URL();
 }
 
 void AccessibilityImageMapLink::accessibilityText(Vector<AccessibilityText>& textOrder) const
@@ -145,37 +125,25 @@ String AccessibilityImageMapLink::title() const
 
 RenderElement* AccessibilityImageMapLink::imageMapLinkRenderer() const
 {
-    if (!m_mapElement || !m_areaElement)
+    RefPtr node = this->node();
+    if (!node)
         return nullptr;
-
-    if (auto* parent = dynamicDowncast<AccessibilityRenderObject>(m_parent.get()))
-        return downcast<RenderElement>(parent->renderer());
-    return m_mapElement->renderer();
-}
-
-void AccessibilityImageMapLink::detachFromParent()
-{
-    AccessibilityMockObject::detachFromParent();
-    m_areaElement = nullptr;
-    m_mapElement = nullptr;
+    RefPtr map = ancestorsOfType<HTMLMapElement>(*node).first();
+    return map ? map->renderer() : nullptr;
 }
 
 Path AccessibilityImageMapLink::elementPath() const
 {
-    auto renderer = imageMapLinkRenderer();
-    if (!renderer)
-        return Path();
-    
-    return m_areaElement->computePath(*renderer);
+    CheckedPtr renderer = imageMapLinkRenderer();
+    RefPtr areaElement = dynamicDowncast<HTMLAreaElement>(node());
+    return renderer && areaElement ? areaElement->computePath(*renderer) : Path();
 }
     
 LayoutRect AccessibilityImageMapLink::elementRect() const
 {
-    auto renderer = imageMapLinkRenderer();
-    if (!renderer)
-        return LayoutRect();
-    
-    return m_areaElement->computeRect(renderer);
+    CheckedPtr renderer = imageMapLinkRenderer();
+    RefPtr areaElement = dynamicDowncast<HTMLAreaElement>(node());
+    return renderer && areaElement ? areaElement->computeRect(renderer.get()) : LayoutRect();
 }
     
 } // namespace WebCore
diff --git a/Source/WebCore/accessibility/AccessibilityImageMapLink.h b/Source/WebCore/accessibility/AccessibilityImageMapLink.h
index 1d2384c06239..5fb1dac64cd8 100644
--- a/Source/WebCore/accessibility/AccessibilityImageMapLink.h
+++ b/Source/WebCore/accessibility/AccessibilityImageMapLink.h
@@ -34,19 +34,11 @@
 
 namespace WebCore {
     
-class AccessibilityImageMapLink final : public AccessibilityMockObject {
+class AccessibilityImageMapLink final : public AccessibilityNodeObject {
 public:
-    static Ref<AccessibilityImageMapLink> create(AXID);
+    static Ref<AccessibilityImageMapLink> create(AXID, HTMLAreaElement&);
     virtual ~AccessibilityImageMapLink();
     
-    void setHTMLAreaElement(HTMLAreaElement*);
-    HTMLAreaElement* areaElement() const { return m_areaElement.get(); }
-    
-    void setHTMLMapElement(HTMLMapElement* element) { m_mapElement = element; }    
-    HTMLMapElement* mapElement() const { return m_mapElement.get(); }
-    
-    Node* node() const final { return m_areaElement.get(); }
-
     AccessibilityRole determineAccessibilityRole() final;
     bool isEnabled() const final { return true; }
 
@@ -60,17 +52,13 @@ class AccessibilityImageMapLink final : public AccessibilityMockObject {
     LayoutRect elementRect() const final;
 
 private:
-    explicit AccessibilityImageMapLink(AXID);
+    explicit AccessibilityImageMapLink(AXID, HTMLAreaElement&);
 
-    void detachFromParent() final;
     Path elementPath() const final;
     RenderElement* imageMapLinkRenderer() const;
     void accessibilityText(Vector<AccessibilityText>&) const final;
     bool isImageMapLink() const final { return true; }
     bool supportsPath() const final { return true; }
-
-    WeakPtr<HTMLAreaElement, WeakPtrImplWithEventTargetData> m_areaElement;
-    WeakPtr<HTMLMapElement, WeakPtrImplWithEventTargetData> m_mapElement;
 };
     
 } // namespace WebCore
diff --git a/Source/WebCore/accessibility/AccessibilityObject.cpp b/Source/WebCore/accessibility/AccessibilityObject.cpp
index c8939c3b3149..98276d9959f6 100644
--- a/Source/WebCore/accessibility/AccessibilityObject.cpp
+++ b/Source/WebCore/accessibility/AccessibilityObject.cpp
@@ -609,6 +609,18 @@ void AccessibilityObject::insertChild(AccessibilityObject& child, unsigned index
         }
     }
 
+    if (UNLIKELY(is<HTMLAreaElement>(child.node()))) {
+        // Despite the DOM parent for <area> elements being <map>, we expose <area> elements as children
+        // of the <img> using the <map>. This provides a better experience for AT users, e.g. a screenreader
+        // would hear "image map" or "group" plus the image description, then the links, which provides the
+        // added context for what the links represent.
+        //
+        // Due to the difference in DOM vs. expected AX hierarchy, make sure area elements are only inserted
+        // by their associated image as children.
+        if (child.parentObject() != this)
+            return;
+    }
+
     // If the parent is asking for this child's children, then either it's the first time (and clearing is a no-op),
     // or its visibility has changed. In the latter case, this child may have a stale child cached.
     // This can prevent aria-hidden changes from working correctly. Hence, whenever a parent is getting children, ensure data is not stale.
diff --git a/Source/WebCore/accessibility/AccessibilityRenderObject.cpp b/Source/WebCore/accessibility/AccessibilityRenderObject.cpp
index b987c4fee655..64eccf316f5e 100644
--- a/Source/WebCore/accessibility/AccessibilityRenderObject.cpp
+++ b/Source/WebCore/accessibility/AccessibilityRenderObject.cpp
@@ -1711,14 +1711,6 @@ AXCoreObject::AccessibilityChildrenVector AccessibilityRenderObject::documentLin
                         if (is<AccessibilityImageMapLink>(child) && !result.contains(child))
                             result.append(child);
                     }
-                } else {
-                    // We couldn't retrieve the already existing image-map links from the parent image, so create a new one.
-                    ASSERT_NOT_REACHED("Unexpectedly missing image-map link parent AX object.");
-                    auto& areaObject = downcast<AccessibilityImageMapLink>(*cache->create(AccessibilityRole::ImageMapLink));
-                    areaObject.setHTMLAreaElement(uncheckedDowncast<HTMLAreaElement>(current));
-                    areaObject.setHTMLMapElement(parentMap);
-                    areaObject.setParent(associatedAXImage(*parentMap));
-                    result.append(areaObject);
                 }
             }
         }
@@ -2316,18 +2308,14 @@ void AccessibilityRenderObject::addImageMapChildren()
     if (!map)
         return;
 
+    WeakPtr cache = axObjectCache();
+    if (!cache)
+        return;
     for (auto& area : descendantsOfType<HTMLAreaElement>(*map)) {
         // add an <area> element for this child if it has a link
         if (!area.isLink())
             continue;
-        auto& areaObject = uncheckedDowncast<AccessibilityImageMapLink>(*axObjectCache()->create(AccessibilityRole::ImageMapLink));
-        areaObject.setHTMLAreaElement(&area);
-        areaObject.setHTMLMapElement(map.get());
-        areaObject.setParent(this);
-        if (!areaObject.isIgnored())
-            addChild(areaObject);
-        else
-            axObjectCache()->remove(areaObject.objectID());
+        addChild(cache->getOrCreate(area));
     }
 }
 
diff --git a/Source/WebCore/accessibility/atspi/AccessibilityAtspi.cpp b/Source/WebCore/accessibility/atspi/AccessibilityAtspi.cpp
index 3942bd04eef8..c30421dbfe4a 100644
--- a/Source/WebCore/accessibility/atspi/AccessibilityAtspi.cpp
+++ b/Source/WebCore/accessibility/atspi/AccessibilityAtspi.cpp
@@ -658,7 +658,6 @@ static constexpr std::pair<AccessibilityRole, RoleNameEntry> roleNames[] = {
     { AccessibilityRole::Inline, { "text", N_("text") } },
     { AccessibilityRole::Image, { "image", N_("image") } },
     { AccessibilityRole::ImageMap, { "image map", N_("image map") } },
-    { AccessibilityRole::ImageMapLink, { "link", N_("link") } },
     { AccessibilityRole::Insertion, { "content insertion", N_("content insertion") } },
     { AccessibilityRole::Label, { "label", N_("label") } },
     { AccessibilityRole::LandmarkBanner, { "landmark", N_("landmark") } },
diff --git a/Source/WebCore/accessibility/atspi/AccessibilityObjectAtspi.cpp b/Source/WebCore/accessibility/atspi/AccessibilityObjectAtspi.cpp
index 42481e99e12e..160b792701fe 100644
--- a/Source/WebCore/accessibility/atspi/AccessibilityObjectAtspi.cpp
+++ b/Source/WebCore/accessibility/atspi/AccessibilityObjectAtspi.cpp
@@ -251,7 +251,6 @@ static Atspi::Role atspiRole(AccessibilityRole role)
         return Atspi::Role::TableCell;
     case AccessibilityRole::Link:
     case AccessibilityRole::WebCoreLink:
-    case AccessibilityRole::ImageMapLink:
         return Atspi::Role::Link;
     case AccessibilityRole::ImageMap:
         return Atspi::Role::ImageMap;
diff --git a/Source/WebCore/accessibility/cocoa/AXCoreObjectCocoa.mm b/Source/WebCore/accessibility/cocoa/AXCoreObjectCocoa.mm
index d1233d590a0b..f62cfca14875 100644
--- a/Source/WebCore/accessibility/cocoa/AXCoreObjectCocoa.mm
+++ b/Source/WebCore/accessibility/cocoa/AXCoreObjectCocoa.mm
@@ -396,7 +396,6 @@ PlatformRoleMap createPlatformRoleMap()
         { AccessibilityRole::Grid, NSAccessibilityTableRole },
         { AccessibilityRole::TreeGrid, NSAccessibilityTableRole },
         { AccessibilityRole::WebCoreLink, NSAccessibilityLinkRole },
-        { AccessibilityRole::ImageMapLink, NSAccessibilityLinkRole },
         { AccessibilityRole::ImageMap, NSAccessibilityImageMapRole },
         { AccessibilityRole::ListMarker, NSAccessibilityListMarkerRole },
         { AccessibilityRole::WebArea, NSAccessibilityWebAreaRole },
diff --git a/Source/WebCore/accessibility/ios/WebAccessibilityObjectWrapperIOS.mm b/Source/WebCore/accessibility/ios/WebAccessibilityObjectWrapperIOS.mm
index 137d610e400f..fa5a9ded727b 100644
--- a/Source/WebCore/accessibility/ios/WebAccessibilityObjectWrapperIOS.mm
+++ b/Source/WebCore/accessibility/ios/WebAccessibilityObjectWrapperIOS.mm
@@ -310,7 +310,6 @@ - (BOOL)accessibilityCanFuzzyHitTest
     case AccessibilityRole::ColorWell:
     case AccessibilityRole::ComboBox:
     case AccessibilityRole::Heading:
-    case AccessibilityRole::ImageMapLink:
     case AccessibilityRole::Image:
     case AccessibilityRole::Link:
     case AccessibilityRole::ListBox:
@@ -900,7 +899,6 @@ - (BOOL)determineIsAccessibilityElement
     case AccessibilityRole::RadioButton:
     case AccessibilityRole::Slider:
     case AccessibilityRole::Image:
-    case AccessibilityRole::ImageMapLink:
     case AccessibilityRole::ProgressIndicator:
     case AccessibilityRole::Meter:
     case AccessibilityRole::MenuItem:
diff --git a/Source/WebCore/accessibility/mac/WebAccessibilityObjectWrapperMac.mm b/Source/WebCore/accessibility/mac/WebAccessibilityObjectWrapperMac.mm
index 5800a3a3d7a7..c16721e12e06 100644
--- a/Source/WebCore/accessibility/mac/WebAccessibilityObjectWrapperMac.mm
+++ b/Source/WebCore/accessibility/mac/WebAccessibilityObjectWrapperMac.mm
@@ -1091,7 +1091,7 @@ - (NSBezierPath *)path
     if (backingObject.isTreeItem())
         return makeNSArray(backingObject.ariaTreeItemContent());
 
-    return makeNSArray(backingObject.unignoredChildren());
+    return makeNSArray(unignoredChildren);
 }
 
 static NSString *roleString(AXCoreObject& backingObject)
diff --git a/Source/WebCore/page/InteractionRegion.cpp b/Source/WebCore/page/InteractionRegion.cpp
index 9ba66d3a5773..17eaffb02eb3 100644
--- a/Source/WebCore/page/InteractionRegion.cpp
+++ b/Source/WebCore/page/InteractionRegion.cpp
@@ -109,7 +109,6 @@ static bool shouldAllowAccessibilityRoleAsPointerCursorReplacement(const Element
     switch (AccessibilityObject::ariaRoleToWebCoreRole(element.attributeWithoutSynchronization(HTMLNames::roleAttr))) {
     case AccessibilityRole::Button:
     case AccessibilityRole::Checkbox:
-    case AccessibilityRole::ImageMapLink:
     case AccessibilityRole::Link:
     case AccessibilityRole::WebCoreLink:
     case AccessibilityRole::ListBoxOption:


Reviews:
user: login: fleizach
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-02T20:14:11Z
user: login: fleizach
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-02T20:15:08Z
user: login: twilco
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-02T21:47:01Z
user: login: twilco
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-02T21:47:05Z
user: login: hoffmanjoshua
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-04T18:53:14Z
user: login: hoffmanjoshua
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-04-04T21:20:40Z

Review comments:
diff_hunk: @@ -2618,8 +2606,12 @@ void AccessibilityRenderObject::addChildren()
         // ensuring its contents go on the heap. We should consider rewriting our algorithm
         // to build the accessibility tree to be iterative rather than recursive.
         for (Ref child : composedTreeChildren</* InlineContextCapacity */ 0>(*node)) {
-            if (RefPtr childObject = cache->getOrCreate(child.get()))
-                addChildIfNeeded(*childObject);
+            // <area> elements should only be added via addImageMapChildren(), as their expected hierarchy
+            // differs from the structure of the DOM.
+            if (LIKELY(!is<HTMLAreaElement>(child))) {
path: Source/WebCore/accessibility/AccessibilityRenderObject.cpp
user: login: fleizach
body: is there a way to avoid this special case at this point in adding children? is this the only element type that needs to do this special behavior?
created_at: 2025-04-02T20:14:11Z
author_association: CONTRIBUTOR
diff_hunk: @@ -1079,6 +1079,8 @@ - (NSBezierPath *)path
 
 static NSArray *children(AXCoreObject& backingObject)
 {
+    // FIXME: This function calls unignored children multiple times, which is inefficient.
path: Source/WebCore/accessibility/mac/WebAccessibilityObjectWrapperMac.mm
user: login: fleizach
body: Can we just replace the usage on line 1098 with the original call to unignored children?
created_at: 2025-04-02T20:15:08Z
author_association: CONTRIBUTOR
diff_hunk: @@ -1079,6 +1079,8 @@ - (NSBezierPath *)path
 
 static NSArray *children(AXCoreObject& backingObject)
 {
+    // FIXME: This function calls unignored children multiple times, which is inefficient.
path: Source/WebCore/accessibility/mac/WebAccessibilityObjectWrapperMac.mm
user: login: twilco
body: Yes! I've done so in the latest commit.
created_at: 2025-04-02T21:47:01Z
author_association: CONTRIBUTOR
diff_hunk: @@ -2618,8 +2606,12 @@ void AccessibilityRenderObject::addChildren()
         // ensuring its contents go on the heap. We should consider rewriting our algorithm
         // to build the accessibility tree to be iterative rather than recursive.
         for (Ref child : composedTreeChildren</* InlineContextCapacity */ 0>(*node)) {
-            if (RefPtr childObject = cache->getOrCreate(child.get()))
-                addChildIfNeeded(*childObject);
+            // <area> elements should only be added via addImageMapChildren(), as their expected hierarchy
+            // differs from the structure of the DOM.
+            if (LIKELY(!is<HTMLAreaElement>(child))) {
path: Source/WebCore/accessibility/AccessibilityRenderObject.cpp
user: login: twilco
body: I don't think there's a way to avoid a special-case somewhere, since we have explicitly chosen to provide a better user experience by exposing a different accessibility tree structure than what is in the DOM.

But you are right that we probably need this for other object types too — you could imagine that we would want this for `display:contents` elements too. So I moved the logic into `AccessibilityObject::insertChild`, which we funnel everything through. Thanks for the catch!
created_at: 2025-04-02T21:47:05Z
author_association: CONTRIBUTOR
diff_hunk: @@ -635,6 +635,18 @@ void AccessibilityObject::insertChild(AccessibilityObject& child, unsigned index
         }
     }
 
+    if (UNLIKELY(is<HTMLAreaElement>(child.node()))) {
+        // Despite the DOM parent for <area> elements being <map>, we expose <area> elements as children
path: Source/WebCore/accessibility/AccessibilityObject.cpp
user: login: hoffmanjoshua
body: Appreciate this explanation here!
created_at: 2025-04-04T18:53:14Z
author_association: CONTRIBUTOR

PR comments:
user: login: webkit-early-warning-system
created_at: 2025-04-01T20:58:35Z
body: EWS run on previous version of this PR (hash https://github.com/WebKit/WebKit/commit/7229c173a3d1b6720fac24cac072ad95122377bd)<details>

| Misc | iOS, visionOS, tvOS & watchOS  | macOS  | Linux |  Windows |
| ----- | ---------------------- | ------- |  ----- |  --------- |
| [✅ 🧪 style](https://ews-build.webkit.org/#/builders/38/builds/97782 "Passed style check") | [✅ 🛠 ios](https://ews-build.webkit.org/#/builders/131/builds/17407 "Built successfully") | [✅ 🛠 mac](https://ews-build.webkit.org/#/builders/138/builds/7624 "Built successfully") | [❌ 🛠 wpe](https://ews-build.webkit.org/#/builders/5/builds/102894 "Hash 7229c173 for PR 43403 does not build (failure)") | [  ~~🛠 win~~](https://ews-build.webkit.org/#/builders/59/builds/48311 "The change is no longer eligible for processing. Commit was outdated when EWS attempted to process it.") 
| [✅ 🧪 bindings](https://ews-build.webkit.org/#/builders/9/builds/99827 "Passed tests") | [  ~~🛠 ios-sim~~](https://ews-build.webkit.org/#/builders/130/builds/17701 "The change is no longer eligible for processing. Commit was outdated when EWS attempted to process it.") | [❌ 🛠 mac-AS-debug](https://ews-build.webkit.org/#/builders/123/builds/25860 "Hash 7229c173 for PR 43403 does not build (failure)") | [❌ 🧪 wpe-wk2](https://ews-build.webkit.org/#/builders/5/builds/102894 "Hash 7229c173 for PR 43403 does not build (failure)") | [  ~~🧪 win-tests~~](https://ews-build.webkit.org/#/builders/59/builds/48311 "The change is no longer eligible for processing. Commit was outdated when EWS attempted to process it.") 
| [✅ 🧪 webkitperl](https://ews-build.webkit.org/#/builders/11/builds/100785 "Passed tests") | [  ~~🧪 ios-wk2~~](https://ews-build.webkit.org/#/builders/130/builds/17701 "The change is no longer eligible for processing. Commit was outdated when EWS attempted to process it.") | [⏳ 🧪 api-mac](https://ews-build.webkit.org/#/builders/API-Tests-macOS-EWS "Waiting to run tests") | [❌ 🧪 api-wpe](https://ews-build.webkit.org/#/builders/5/builds/102894 "Hash 7229c173 for PR 43403 does not build (failure)") | 
| | [  ~~🧪 ios-wk2-wpt~~](https://ews-build.webkit.org/#/builders/130/builds/17701 "The change is no longer eligible for processing. Commit was outdated when EWS attempted to process it.") | [⏳ 🧪 mac-wk1](https://ews-build.webkit.org/#/builders/macOS-Sonoma-Release-WK1-Tests-EWS "Waiting to run tests") | [✅ 🛠 wpe-cairo](https://ews-build.webkit.org/#/builders/65/builds/47754 "Built successfully") | 
| | [  ~~🧪 api-ios~~](https://ews-build.webkit.org/#/builders/130/builds/17701 "The change is no longer eligible for processing. Commit was outdated when EWS attempted to process it.") | [⏳ 🧪 mac-wk2](https://ews-build.webkit.org/#/builders/macOS-Sonoma-Release-WK2-Tests-EWS "Waiting to run tests") | [  ~~🛠 gtk~~](https://ews-build.webkit.org/#/builders/2/builds/105132 "The change is no longer eligible for processing. Commit was outdated when EWS attempted to process it.") | 
| | [  ~~🛠 vision~~](https://ews-build.webkit.org/#/builders/128/builds/24862 "The change is no longer eligible for processing. Commit was outdated when EWS attempted to process it.") | [❌ 🧪 mac-AS-debug-wk2](https://ews-build.webkit.org/#/builders/123/builds/25860 "Hash 7229c173 for PR 43403 does not build (failure)") | [  ~~🧪 gtk-wk2~~](https://ews-build.webkit.org/#/builders/2/builds/105132 "The change is no longer eligible for processing. Commit was outdated when EWS attempted to process it.") | 
| | [  ~~🛠 vision-sim~~](https://ews-build.webkit.org/#/builders/121/builds/25234 "The change is no longer eligible for processing. Commit was outdated when EWS attempted to process it.") | [✅ 🧪 mac-wk2-stress](https://ews-build.webkit.org/#/builders/8/builds/84545 "Passed tests") | [  ~~🧪 api-gtk~~](https://ews-build.webkit.org/#/builders/2/builds/105132 "The change is no longer eligible for processing. Commit was outdated when EWS attempted to process it.") | 
| | [⏳ 🧪 vision-wk2 ](https://ews-build.webkit.org/#/builders/visionOS-2-Simulator-WK2-Tests-EWS "Waiting in queue, processing has not started yet") | [⏳ 🧪 mac-intel-wk2](https://ews-build.webkit.org/#/builders/macOS-Sonoma-Release-WK2-Intel-Tests-EWS "Waiting to run tests") | [  ~~🛠 playstation~~](https://ews-build.webkit.org/#/builders/134/builds/18469 "The change is no longer eligible for processing. Commit was outdated when EWS attempted to process it.") | 
| | [  ~~🛠 tv~~](https://ews-build.webkit.org/#/builders/127/builds/24823 "The change is no longer eligible for processing. Commit was outdated when EWS attempted to process it.") | [  ~~🛠 mac-safer-cpp~~](https://ews-build.webkit.org/#/builders/120/builds/29992 "The change is no longer eligible for processing. Commit was outdated when EWS attempted to process it.") | | 
| | [  ~~🛠 tv-sim~~](https://ews-build.webkit.org/#/builders/125/builds/24645 "The change is no longer eligible for processing. Commit was outdated when EWS attempted to process it.") | | | 
| | [  ~~🛠 watch~~](https://ews-build.webkit.org/#/builders/129/builds/27959 "The change is no longer eligible for processing. Commit was outdated when EWS attempted to process it.") | | | 
| | [  ~~🛠 watch-sim~~](https://ews-build.webkit.org/#/builders/124/builds/26219 "The change is no longer eligible for processing. Commit was outdated when EWS attempted to process it.") | | | </details>
author_association: COLLABORATOR
user: login: webkit-early-warning-system
created_at: 2025-04-01T21:39:31Z
body: EWS run on previous version of this PR (hash https://github.com/WebKit/WebKit/commit/64a2abfab2ff92a8f2a0ebbafb6e3895b43fcd19)<details>

| Misc | iOS, visionOS, tvOS & watchOS  | macOS  | Linux |  Windows |
| ----- | ---------------------- | ------- |  ----- |  --------- |
| [✅ 🧪 style](https://ews-build.webkit.org/#/builders/38/builds/97798 "Passed style check") | [✅ 🛠 ios](https://ews-build.webkit.org/#/builders/131/builds/17423 "Built successfully") | [✅ 🛠 mac](https://ews-build.webkit.org/#/builders/138/builds/7640 "Built successfully") | [✅ 🛠 wpe](https://ews-build.webkit.org/#/builders/5/builds/102910 "Built successfully") | [✅ 🛠 win](https://ews-build.webkit.org/#/builders/59/builds/48327 "Built successfully") 
| [✅ 🧪 bindings](https://ews-build.webkit.org/#/builders/9/builds/99843 "Passed tests") | [✅ 🛠 ios-sim](https://ews-build.webkit.org/#/builders/130/builds/17717 "Built successfully") | [✅ 🛠 mac-AS-debug](https://ews-build.webkit.org/#/builders/123/builds/25876 "Built successfully") | [❌ 🧪 wpe-wk2](https://ews-build.webkit.org/#/builders/34/builds/74478 "Found 4 new test failures: accessibility/image-map-title-causes-crash.html accessibility/image-map2.html imported/w3c/web-platform-tests/html-aam/fragile/area-role.html imported/w3c/web-platform-tests/html/semantics/forms/constraints/infinite_backtracking.html (failure)") | [✅ 🧪 win-tests](https://ews-build.webkit.org/#/builders/60/builds/31659 "Passed tests") 
| [✅ 🧪 webkitperl](https://ews-build.webkit.org/#/builders/11/builds/100801 "Passed tests") | [✅ 🧪 ios-wk2](https://ews-build.webkit.org/#/builders/132/builds/13429 "Passed tests") | [✅ 🧪 api-mac](https://ews-build.webkit.org/#/builders/18/builds/88386 "Passed tests") | [✅ 🧪 api-wpe](https://ews-build.webkit.org/#/builders/41/builds/54833 "Passed tests") | 
| | [❌ 🧪 ios-wk2-wpt](https://ews-build.webkit.org/#/builders/133/builds/13206 "Found 1 new test failure: imported/w3c/web-platform-tests/html-aam/fragile/area-role.html (failure)") | [❌ 🧪 mac-wk1](https://ews-build.webkit.org/#/builders/135/builds/6306 "Found 1 new test failure: imported/w3c/web-platform-tests/html-aam/fragile/area-role.html (failure)") | [✅ 🛠 wpe-cairo](https://ews-build.webkit.org/#/builders/65/builds/47770 "Built successfully") | 
| | [✅ 🧪 api-ios](https://ews-build.webkit.org/#/builders/13/builds/83196 "Passed tests") | [❌ 🧪 mac-wk2](https://ews-build.webkit.org/#/builders/136/builds/6382 "Found 1 new test failure: imported/w3c/web-platform-tests/html-aam/fragile/area-role.html (failure)") | [  ~~🛠 gtk~~](https://ews-build.webkit.org/#/builders/2/builds/105290 "The change is no longer eligible for processing. Commit was outdated when EWS attempted to process it.") | 
| | [✅ 🛠 vision](https://ews-build.webkit.org/#/builders/128/builds/24878 "Built successfully") | [⏳ 🧪 mac-AS-debug-wk2](https://ews-build.webkit.org/#/builders/macOS-Sequoia-Debug-WK2-Tests-EWS "Waiting to run tests") | [  ~~🧪 gtk-wk2~~](https://ews-build.webkit.org/#/builders/2/builds/105290 "The change is no longer eligible for processing. Commit was outdated when EWS attempted to process it.") | 
| | [✅ 🛠 vision-sim](https://ews-build.webkit.org/#/builders/121/builds/25250 "Built successfully") | [✅ 🧪 mac-wk2-stress](https://ews-build.webkit.org/#/builders/8/builds/84554 "Passed tests") | [  ~~🧪 api-gtk~~](https://ews-build.webkit.org/#/builders/2/builds/105290 "The change is no longer eligible for processing. Commit was outdated when EWS attempted to process it.") | 
| | [✅ 🧪 vision-wk2](https://ews-build.webkit.org/#/builders/126/builds/27537 "Passed tests") | [❌ 🧪 mac-intel-wk2](https://ews-build.webkit.org/#/builders/137/builds/5212 "Found 1 new test failure: imported/w3c/web-platform-tests/html-aam/fragile/area-role.html (failure)") | [✅ 🛠 playstation](https://ews-build.webkit.org/#/builders/134/builds/18485 "Built successfully") | 
| | [✅ 🛠 tv](https://ews-build.webkit.org/#/builders/127/builds/24839 "Built successfully") | [  ~~🛠 mac-safer-cpp~~](https://ews-build.webkit.org/#/builders/120/builds/30008 "The change is no longer eligible for processing. Commit was outdated when EWS attempted to process it.") | | 
| | [✅ 🛠 tv-sim](https://ews-build.webkit.org/#/builders/125/builds/24661 "Built successfully") | | | 
| | [✅ 🛠 watch](https://ews-build.webkit.org/#/builders/129/builds/27975 "Built successfully") | | | 
| | [✅ 🛠 watch-sim](https://ews-build.webkit.org/#/builders/124/builds/26235 "Built successfully") | | | </details>
author_association: COLLABORATOR
user: login: webkit-early-warning-system
created_at: 2025-04-02T05:04:58Z
body: EWS run on previous version of this PR (hash https://github.com/WebKit/WebKit/commit/08c526a39a94a5d01779e653873d4caf65d476ac)<details>

| Misc | iOS, visionOS, tvOS & watchOS  | macOS  | Linux |  Windows |
| ----- | ---------------------- | ------- |  ----- |  --------- |
| [✅ 🧪 style](https://ews-build.webkit.org/#/builders/38/builds/97872 "Passed style check") | [✅ 🛠 ios](https://ews-build.webkit.org/#/builders/131/builds/17497 "Built successfully") | [✅ 🛠 mac](https://ews-build.webkit.org/#/builders/138/builds/7718 "Built successfully") | [✅ 🛠 wpe](https://ews-build.webkit.org/#/builders/5/builds/102986 "Built successfully") | [✅ 🛠 win](https://ews-build.webkit.org/#/builders/59/builds/48401 "Built successfully") 
| [✅ 🧪 bindings](https://ews-build.webkit.org/#/builders/9/builds/99917 "Passed tests") | [✅ 🛠 ios-sim](https://ews-build.webkit.org/#/builders/130/builds/17791 "Built successfully") | [✅ 🛠 mac-AS-debug](https://ews-build.webkit.org/#/builders/123/builds/25950 "Built successfully") | [  ~~🧪 wpe-wk2~~](https://ews-build.webkit.org/#/builders/34/builds/74516 "The change is no longer eligible for processing. Commit was outdated when EWS attempted to process it.") | [✅ 🧪 win-tests](https://ews-build.webkit.org/#/builders/60/builds/31696 "Passed tests") 
| [✅ 🧪 webkitperl](https://ews-build.webkit.org/#/builders/11/builds/100875 "Passed tests") | [⏳ 🧪 ios-wk2](https://ews-build.webkit.org/#/builders/iOS-18-Simulator-WK2-Tests-EWS "Waiting to run tests") | [⏳ 🧪 api-mac](https://ews-build.webkit.org/#/builders/API-Tests-macOS-EWS "Waiting to run tests") | [✅ 🧪 api-wpe](https://ews-build.webkit.org/#/builders/41/builds/54873 "Passed tests") | 
| | [⏳ 🧪 ios-wk2-wpt](https://ews-build.webkit.org/#/builders/iOS-18-Simulator-WPT-WK2-Tests-EWS "Waiting to run tests") | [  ~~🧪 mac-wk1~~](https://ews-build.webkit.org/#/builders/135/builds/6379 "The change is no longer eligible for processing. Commit was outdated when EWS attempted to process it.") | [✅ 🛠 wpe-cairo](https://ews-build.webkit.org/#/builders/65/builds/47844 "Built successfully") | 
| | [⏳ 🧪 api-ios](https://ews-build.webkit.org/#/builders/API-Tests-iOS-Simulator-EWS "Waiting to run tests") | [  ~~🧪 mac-wk2~~](https://ews-build.webkit.org/#/builders/136/builds/6452 "The change is no longer eligible for processing. Commit was outdated when EWS attempted to process it.") | [  ~~🛠 gtk~~](https://ews-build.webkit.org/#/builders/2/builds/105364 "The change is no longer eligible for processing. Commit was outdated when EWS attempted to process it.") | 
| | [✅ 🛠 vision](https://ews-build.webkit.org/#/builders/128/builds/24952 "Built successfully") | [⏳ 🧪 mac-AS-debug-wk2](https://ews-build.webkit.org/#/builders/macOS-Sequoia-Debug-WK2-Tests-EWS "Waiting to run tests") | [  ~~🧪 gtk-wk2~~](https://ews-build.webkit.org/#/builders/2/builds/105364 "The change is no longer eligible for processing. Commit was outdated when EWS attempted to process it.") | 
| | [✅ 🛠 vision-sim](https://ews-build.webkit.org/#/builders/121/builds/25324 "Built successfully") | [  ~~🧪 mac-wk2-stress~~](https://ews-build.webkit.org/#/builders/8/builds/84628 "The change is no longer eligible for processing. Commit was outdated when EWS attempted to process it.") | [  ~~🧪 api-gtk~~](https://ews-build.webkit.org/#/builders/2/builds/105364 "The change is no longer eligible for processing. Commit was outdated when EWS attempted to process it.") | 
| | [✅ 🧪 vision-wk2](https://ews-build.webkit.org/#/builders/126/builds/27588 "Passed tests") | [⏳ 🧪 mac-intel-wk2](https://ews-build.webkit.org/#/builders/macOS-Sonoma-Release-WK2-Intel-Tests-EWS "Waiting to run tests") | [  ~~🛠 playstation~~](https://ews-build.webkit.org/#/builders/134/builds/18563 "The change is no longer eligible for processing. Commit was outdated when EWS attempted to process it.") | 
| | [✅ 🛠 tv](https://ews-build.webkit.org/#/builders/127/builds/24913 "Built successfully") | [  ~~🛠 mac-safer-cpp~~](https://ews-build.webkit.org/#/builders/120/builds/30082 "The change is no longer eligible for processing. Commit was outdated when EWS attempted to process it.") | | 
| | [✅ 🛠 tv-sim](https://ews-build.webkit.org/#/builders/125/builds/24735 "Built successfully") | | | 
| | [✅ 🛠 watch](https://ews-build.webkit.org/#/builders/129/builds/28049 "Built successfully") | | | 
| | [✅ 🛠 watch-sim](https://ews-build.webkit.org/#/builders/124/builds/26309 "Built successfully") | | | </details>
author_association: COLLABORATOR
user: login: webkit-early-warning-system
created_at: 2025-04-02T05:26:09Z
body: EWS run on previous version of this PR (hash https://github.com/WebKit/WebKit/commit/c56a51be6542e351a9ddcb3743d07ae2b5476635)<details>

| Misc | iOS, visionOS, tvOS & watchOS  | macOS  | Linux |  Windows |
| ----- | ---------------------- | ------- |  ----- |  --------- |
| [✅ 🧪 style](https://ews-build.webkit.org/#/builders/38/builds/97874 "Passed style check") | [✅ 🛠 ios](https://ews-build.webkit.org/#/builders/131/builds/17499 "Built successfully") | [✅ 🛠 mac](https://ews-build.webkit.org/#/builders/138/builds/7720 "Built successfully") | [✅ 🛠 wpe](https://ews-build.webkit.org/#/builders/5/builds/102988 "Built successfully") | [✅ 🛠 win](https://ews-build.webkit.org/#/builders/59/builds/48403 "Built successfully") 
| [✅ 🧪 bindings](https://ews-build.webkit.org/#/builders/9/builds/99919 "Passed tests") | [✅ 🛠 ios-sim](https://ews-build.webkit.org/#/builders/130/builds/17793 "Built successfully") | [✅ 🛠 mac-AS-debug](https://ews-build.webkit.org/#/builders/123/builds/25952 "Built successfully") | [❌ 🧪 wpe-wk2](https://ews-build.webkit.org/#/builders/34/builds/74518 "Found 1 new test failure: accessibility/image-map-title-causes-crash.html (failure)") | [✅ 🧪 win-tests](https://ews-build.webkit.org/#/builders/60/builds/31698 "Passed tests") 
| [✅ 🧪 webkitperl](https://ews-build.webkit.org/#/builders/11/builds/100877 "Passed tests") | [❌ 🧪 ios-wk2](https://ews-build.webkit.org/#/builders/132/builds/13469 "Found 1 new test failure: fast/forms/ios/focus-input-via-button.html (failure)") | [✅ 🧪 api-mac](https://ews-build.webkit.org/#/builders/18/builds/88448 "Passed tests") | [✅ 🧪 api-wpe](https://ews-build.webkit.org/#/builders/41/builds/54875 "Passed tests") | 
| | [✅ 🧪 ios-wk2-wpt](https://ews-build.webkit.org/#/builders/133/builds/13244 "Passed tests") | [✅ 🧪 mac-wk1](https://ews-build.webkit.org/#/builders/135/builds/6380 "Passed tests") | [✅ 🛠 wpe-cairo](https://ews-build.webkit.org/#/builders/65/builds/47846 "Built successfully") | 
| | [✅ 🧪 api-ios](https://ews-build.webkit.org/#/builders/13/builds/83231 "Passed tests") | [✅ 🧪 mac-wk2](https://ews-build.webkit.org/#/builders/136/builds/6453 "Passed tests") | [✅ 🛠 gtk](https://ews-build.webkit.org/#/builders/2/builds/105366 "Built successfully") | 
| | [✅ 🛠 vision](https://ews-build.webkit.org/#/builders/128/builds/24954 "Built successfully") | [✅ 🧪 mac-AS-debug-wk2](https://ews-build.webkit.org/#/builders/122/builds/18171 "Passed tests") | [  ~~🧪 gtk-wk2~~](https://ews-build.webkit.org/#/builders/1/builds/83530 "The change is no longer eligible for processing. Commit was outdated when EWS attempted to process it.") | 
| | [✅ 🛠 vision-sim](https://ews-build.webkit.org/#/builders/121/builds/25326 "Built successfully") | [✅ 🧪 mac-wk2-stress](https://ews-build.webkit.org/#/builders/8/builds/84629 "Passed tests") | [✅ 🧪 api-gtk](https://ews-build.webkit.org/#/builders/21/builds/82966 "Passed tests") | 
| | [✅ 🧪 vision-wk2](https://ews-build.webkit.org/#/builders/126/builds/27592 "Passed tests") | [✅ 🧪 mac-intel-wk2](https://ews-build.webkit.org/#/builders/137/builds/5274 "Passed tests") | [✅ 🛠 playstation](https://ews-build.webkit.org/#/builders/134/builds/18565 "Built successfully") | 
| | [✅ 🛠 tv](https://ews-build.webkit.org/#/builders/127/builds/24915 "Built successfully") | [✅ 🛠 mac-safer-cpp](https://ews-build.webkit.org/#/builders/120/builds/30084 "Built successfully") | | 
| | [✅ 🛠 tv-sim](https://ews-build.webkit.org/#/builders/125/builds/24737 "Built successfully") | | | 
| | [✅ 🛠 watch](https://ews-build.webkit.org/#/builders/129/builds/28051 "Built successfully") | | | 
| | [✅ 🛠 watch-sim](https://ews-build.webkit.org/#/builders/124/builds/26311 "Built successfully") | | | </details>
author_association: COLLABORATOR
user: login: webkit-ews-buildbot
created_at: 2025-04-02T13:56:27Z
body: ### Safer C++ Build [#30084](https://ews-build.webkit.org/#/builders/120/builds/30084) (https://github.com/WebKit/WebKit/commit/c56a51be6542e351a9ddcb3743d07ae2b5476635)

:warning: Found 1 fixed file! Please update expectations in `Source/[Project]/SaferCPPExpectations` by running the following command and update your pull request:
- `Tools/Scripts/update-safer-cpp-expectations -p WebCore --UncountedCallArgsChecker accessibility/AccessibilityImageMapLink.cpp --UncountedLocalVarsChecker accessibility/AccessibilityImageMapLink.cpp`
author_association: COLLABORATOR
user: login: webkit-early-warning-system
created_at: 2025-04-02T15:42:16Z
body: EWS run on previous version of this PR (hash https://github.com/WebKit/WebKit/commit/80c87b0fc0a851bca4588ea491d94251e385bc44)<details>

| Misc | iOS, visionOS, tvOS & watchOS  | macOS  | Linux |  Windows |
| ----- | ---------------------- | ------- |  ----- |  --------- |
| [✅ 🧪 style](https://ews-build.webkit.org/#/builders/38/builds/97918 "Passed style check") | [✅ 🛠 ios](https://ews-build.webkit.org/#/builders/131/builds/17543 "Built successfully") | [✅ 🛠 mac](https://ews-build.webkit.org/#/builders/138/builds/7764 "Built successfully") | [✅ 🛠 wpe](https://ews-build.webkit.org/#/builders/5/builds/103032 "Built successfully") | [✅ 🛠 win](https://ews-build.webkit.org/#/builders/59/builds/48448 "Built successfully") 
| [✅ 🧪 bindings](https://ews-build.webkit.org/#/builders/9/builds/99963 "Passed tests") | [✅ 🛠 ios-sim](https://ews-build.webkit.org/#/builders/130/builds/17837 "Built successfully") | [✅ 🛠 mac-AS-debug](https://ews-build.webkit.org/#/builders/123/builds/25996 "Built successfully") | [  ~~🧪 wpe-wk2~~](https://ews-build.webkit.org/#/builders/34/builds/74557 "The change is no longer eligible for processing. Commit was outdated when EWS attempted to process it.") | [✅ 🧪 win-tests](https://ews-build.webkit.org/#/builders/60/builds/31745 "Passed tests") 
| [✅ 🧪 webkitperl](https://ews-build.webkit.org/#/builders/11/builds/100921 "Passed tests") | [✅ 🧪 ios-wk2](https://ews-build.webkit.org/#/builders/132/builds/13512 "Passed tests") | [✅ 🧪 api-mac](https://ews-build.webkit.org/#/builders/18/builds/88488 "Passed tests") | [✅ 🧪 api-wpe](https://ews-build.webkit.org/#/builders/41/builds/54914 "Passed tests") | 
| | [✅ 🧪 ios-wk2-wpt](https://ews-build.webkit.org/#/builders/133/builds/13287 "Passed tests") | [✅ 🧪 mac-wk1](https://ews-build.webkit.org/#/builders/135/builds/6420 "Passed tests") | [✅ 🛠 wpe-cairo](https://ews-build.webkit.org/#/builders/65/builds/47890 "Built successfully") | 
| | [✅ 🧪 api-ios](https://ews-build.webkit.org/#/builders/13/builds/83269 "Passed tests") | [✅ 🧪 mac-wk2](https://ews-build.webkit.org/#/builders/136/builds/6493 "Passed tests") | [✅ 🛠 gtk](https://ews-build.webkit.org/#/builders/2/builds/105410 "Built successfully") | 
| | [✅ 🛠 vision](https://ews-build.webkit.org/#/builders/128/builds/24998 "Built successfully") | [⏳ 🧪 mac-AS-debug-wk2](https://ews-build.webkit.org/#/builders/macOS-Sequoia-Debug-WK2-Tests-EWS "Waiting to run tests") | [⏳ 🧪 gtk-wk2](https://ews-build.webkit.org/#/builders/GTK-WK2-Tests-EWS "Waiting to run tests") | 
| | [✅ 🛠 vision-sim](https://ews-build.webkit.org/#/builders/121/builds/25370 "Built successfully") | [✅ 🧪 mac-wk2-stress](https://ews-build.webkit.org/#/builders/8/builds/84669 "Passed tests") | [✅ 🧪 api-gtk](https://ews-build.webkit.org/#/builders/21/builds/82993 "Passed tests") | 
| | [✅ 🧪 vision-wk2](https://ews-build.webkit.org/#/builders/126/builds/27631 "Passed tests") | [✅ 🧪 mac-intel-wk2](https://ews-build.webkit.org/#/builders/137/builds/5314 "Passed tests") | [✅ 🛠 playstation](https://ews-build.webkit.org/#/builders/134/builds/18621 "Built successfully") | 
| | [✅ 🛠 tv](https://ews-build.webkit.org/#/builders/127/builds/24959 "Built successfully") | [✅ 🛠 mac-safer-cpp](https://ews-build.webkit.org/#/builders/120/builds/30128 "Built successfully") | | 
| | [✅ 🛠 tv-sim](https://ews-build.webkit.org/#/builders/125/builds/24781 "Built successfully") | | | 
| | [✅ 🛠 watch](https://ews-build.webkit.org/#/builders/129/builds/28095 "Built successfully") | | | 
| | [✅ 🛠 watch-sim](https://ews-build.webkit.org/#/builders/124/builds/26355 "Built successfully") | | | </details>
author_association: COLLABORATOR
user: login: webkit-early-warning-system
created_at: 2025-04-02T16:52:22Z
body: EWS run on previous version of this PR (hash https://github.com/WebKit/WebKit/commit/ab438d06d95b3e2273567dfd31acb12db6af01d7)<details>

| Misc | iOS, visionOS, tvOS & watchOS  | macOS  | Linux |  Windows |
| ----- | ---------------------- | ------- |  ----- |  --------- |
| [✅ 🧪 style](https://ews-build.webkit.org/#/builders/38/builds/97929 "Passed style check") | [✅ 🛠 ios](https://ews-build.webkit.org/#/builders/131/builds/17554 "Built successfully") | [✅ 🛠 mac](https://ews-build.webkit.org/#/builders/138/builds/7775 "Built successfully") | [✅ 🛠 wpe](https://ews-build.webkit.org/#/builders/5/builds/103043 "Built successfully") | [✅ 🛠 win](https://ews-build.webkit.org/#/builders/59/builds/48459 "Built successfully") 
| [✅ 🧪 bindings](https://ews-build.webkit.org/#/builders/9/builds/99974 "Passed tests") | [✅ 🛠 ios-sim](https://ews-build.webkit.org/#/builders/130/builds/17848 "Built successfully") | [✅ 🛠 mac-AS-debug](https://ews-build.webkit.org/#/builders/123/builds/26007 "Built successfully") | [  ~~🧪 wpe-wk2~~](https://ews-build.webkit.org/#/builders/34/builds/74565 "The change is no longer eligible for processing. Commit was outdated when EWS attempted to process it.") | [  ~~🧪 win-tests~~](https://ews-build.webkit.org/#/builders/60/builds/31750 "The change is no longer eligible for processing. Commit was outdated when EWS attempted to process it.") 
| [✅ 🧪 webkitperl](https://ews-build.webkit.org/#/builders/11/builds/100932 "Passed tests") | [✅ 🧪 ios-wk2](https://ews-build.webkit.org/#/builders/132/builds/13522 "Passed tests") | [  ~~🧪 api-mac~~](https://ews-build.webkit.org/#/builders/18/builds/88494 "The change is no longer eligible for processing. Commit was outdated when EWS attempted to process it.") | [✅ 🧪 api-wpe](https://ews-build.webkit.org/#/builders/41/builds/54922 "Passed tests") | 
| | [✅ 🧪 ios-wk2-wpt](https://ews-build.webkit.org/#/builders/133/builds/13298 "Passed tests") | [  ~~🧪 mac-wk1~~](https://ews-build.webkit.org/#/builders/135/builds/6426 "The change is no longer eligible for processing. Commit was outdated when EWS attempted to process it.") | [✅ 🛠 wpe-cairo](https://ews-build.webkit.org/#/builders/65/builds/47901 "Built successfully") | 
| | [⏳ 🧪 api-ios](https://ews-build.webkit.org/#/builders/API-Tests-iOS-Simulator-EWS "Waiting to run tests") | [  ~~🧪 mac-wk2~~](https://ews-build.webkit.org/#/builders/136/builds/6499 "The change is no longer eligible for processing. Commit was outdated when EWS attempted to process it.") | [✅ 🛠 gtk](https://ews-build.webkit.org/#/builders/2/builds/105421 "Built successfully") | 
| | [✅ 🛠 vision](https://ews-build.webkit.org/#/builders/128/builds/25009 "Built successfully") | [⏳ 🧪 mac-AS-debug-wk2](https://ews-build.webkit.org/#/builders/macOS-Sequoia-Debug-WK2-Tests-EWS "Waiting to run tests") | [⏳ 🧪 gtk-wk2](https://ews-build.webkit.org/#/builders/GTK-WK2-Tests-EWS "Waiting to run tests") | 
| | [✅ 🛠 vision-sim](https://ews-build.webkit.org/#/builders/121/builds/25381 "Built successfully") | [  ~~🧪 mac-wk2-stress~~](https://ews-build.webkit.org/#/builders/8/builds/84675 "The change is no longer eligible for processing. Commit was outdated when EWS attempted to process it.") | [  ~~🧪 api-gtk~~](https://ews-build.webkit.org/#/builders/21/builds/83001 "The change is no longer eligible for processing. Commit was outdated when EWS attempted to process it.") | 
| | [✅ 🧪 vision-wk2](https://ews-build.webkit.org/#/builders/126/builds/27641 "Passed tests") | [⏳ 🧪 mac-intel-wk2](https://ews-build.webkit.org/#/builders/macOS-Sonoma-Release-WK2-Intel-Tests-EWS "Waiting to run tests") | [✅ 🛠 playstation](https://ews-build.webkit.org/#/builders/134/builds/18633 "Built successfully") | 
| | [✅ 🛠 tv](https://ews-build.webkit.org/#/builders/127/builds/24970 "Built successfully") | [  ~~🛠 mac-safer-cpp~~](https://ews-build.webkit.org/#/builders/120/builds/30139 "The change is no longer eligible for processing. Commit was outdated when EWS attempted to process it.") | | 
| | [✅ 🛠 tv-sim](https://ews-build.webkit.org/#/builders/125/builds/24792 "Built successfully") | | | 
| | [✅ 🛠 watch](https://ews-build.webkit.org/#/builders/129/builds/28106 "Built successfully") | | | 
| | [✅ 🛠 watch-sim](https://ews-build.webkit.org/#/builders/124/builds/26366 "Built successfully") | | | </details>
author_association: COLLABORATOR
user: login: webkit-early-warning-system
created_at: 2025-04-02T17:00:53Z
body: EWS run on previous version of this PR (hash https://github.com/WebKit/WebKit/commit/65445bf820348b3d792a9c4fe0a12433d8d05b67)<details>

| Misc | iOS, visionOS, tvOS & watchOS  | macOS  | Linux |  Windows |
| ----- | ---------------------- | ------- |  ----- |  --------- |
| [✅ 🧪 style](https://ews-build.webkit.org/#/builders/38/builds/97931 "Passed style check") | [✅ 🛠 ios](https://ews-build.webkit.org/#/builders/131/builds/17556 "Built successfully") | [✅ 🛠 mac](https://ews-build.webkit.org/#/builders/138/builds/7777 "Built successfully") | [✅ 🛠 wpe](https://ews-build.webkit.org/#/builders/5/builds/103045 "Built successfully") | [✅ 🛠 win](https://ews-build.webkit.org/#/builders/59/builds/48461 "Built successfully") 
| [✅ 🧪 bindings](https://ews-build.webkit.org/#/builders/9/builds/99976 "Passed tests") | [✅ 🛠 ios-sim](https://ews-build.webkit.org/#/builders/130/builds/17850 "Built successfully") | [✅ 🛠 mac-AS-debug](https://ews-build.webkit.org/#/builders/123/builds/26009 "Built successfully") | [  ~~🧪 wpe-wk2~~](https://ews-build.webkit.org/#/builders/34/builds/74568 "The change is no longer eligible for processing. Commit was outdated when EWS attempted to process it.") | [  ~~🧪 win-tests~~](https://ews-build.webkit.org/#/builders/60/builds/31754 "The change is no longer eligible for processing. Commit was outdated when EWS attempted to process it.") 
| [✅ 🧪 webkitperl](https://ews-build.webkit.org/#/builders/11/builds/100934 "Passed tests") | [  ~~🧪 ios-wk2~~](https://ews-build.webkit.org/#/builders/132/builds/13526 "The change is no longer eligible for processing. Commit was outdated when EWS attempted to process it.") | [  ~~🧪 api-mac~~](https://ews-build.webkit.org/#/builders/18/builds/88500 "The change is no longer eligible for processing. Commit was outdated when EWS attempted to process it.") | [  ~~🧪 api-wpe~~](https://ews-build.webkit.org/#/builders/41/builds/54925 "The change is no longer eligible for processing. Commit was outdated when EWS attempted to process it.") | 
| | [  ~~🧪 ios-wk2-wpt~~](https://ews-build.webkit.org/#/builders/133/builds/13302 "The change is no longer eligible for processing. Commit was outdated when EWS attempted to process it.") | [  ~~🧪 mac-wk1~~](https://ews-build.webkit.org/#/builders/135/builds/6432 "The change is no longer eligible for processing. Commit was outdated when EWS attempted to process it.") | [✅ 🛠 wpe-cairo](https://ews-build.webkit.org/#/builders/65/builds/47903 "Built successfully") | 
| | [  ~~🧪 api-ios~~](https://ews-build.webkit.org/#/builders/13/builds/83279 "The change is no longer eligible for processing. Commit was outdated when EWS attempted to process it.") | [  ~~🧪 mac-wk2~~](https://ews-build.webkit.org/#/builders/136/builds/6505 "The change is no longer eligible for processing. Commit was outdated when EWS attempted to process it.") | [✅ 🛠 gtk](https://ews-build.webkit.org/#/builders/2/builds/105423 "Built successfully") | 
| | [✅ 🛠 vision](https://ews-build.webkit.org/#/builders/128/builds/25011 "Built successfully") | [⏳ 🧪 mac-AS-debug-wk2](https://ews-build.webkit.org/#/builders/macOS-Sequoia-Debug-WK2-Tests-EWS "Waiting to run tests") | [⏳ 🧪 gtk-wk2](https://ews-build.webkit.org/#/builders/GTK-WK2-Tests-EWS "Waiting to run tests") | 
| | [✅ 🛠 vision-sim](https://ews-build.webkit.org/#/builders/121/builds/25383 "Built successfully") | [  ~~🧪 mac-wk2-stress~~](https://ews-build.webkit.org/#/builders/8/builds/84681 "The change is no longer eligible for processing. Commit was outdated when EWS attempted to process it.") | [  ~~🧪 api-gtk~~](https://ews-build.webkit.org/#/builders/21/builds/83002 "The change is no longer eligible for processing. Commit was outdated when EWS attempted to process it.") | 
| | [  ~~🧪 vision-wk2~~](https://ews-build.webkit.org/#/builders/126/builds/27643 "The change is no longer eligible for processing. Commit was outdated when EWS attempted to process it.") | [⏳ 🧪 mac-intel-wk2](https://ews-build.webkit.org/#/builders/macOS-Sonoma-Release-WK2-Intel-Tests-EWS "Waiting to run tests") | [  ~~🛠 playstation~~](https://ews-build.webkit.org/#/builders/134/builds/18635 "The change is no longer eligible for processing. Commit was outdated when EWS attempted to process it.") | 
| | [✅ 🛠 tv](https://ews-build.webkit.org/#/builders/127/builds/24972 "Built successfully") | [  ~~🛠 mac-safer-cpp~~](https://ews-build.webkit.org/#/builders/120/builds/30141 "The change is no longer eligible for processing. Commit was outdated when EWS attempted to process it.") | | 
| | [  ~~🛠 tv-sim~~](https://ews-build.webkit.org/#/builders/125/builds/24794 "The change is no longer eligible for processing. Commit was outdated when EWS attempted to process it.") | | | 
| | [✅ 🛠 watch](https://ews-build.webkit.org/#/builders/129/builds/28108 "Built successfully") | | | 
| | [✅ 🛠 watch-sim](https://ews-build.webkit.org/#/builders/124/builds/26368 "Built successfully") | | | </details>
author_association: COLLABORATOR
user: login: webkit-early-warning-system
created_at: 2025-04-02T17:05:09Z
body: EWS run on previous version of this PR (hash https://github.com/WebKit/WebKit/commit/39aab87117afae4f708bbfa7a5211d8c442e3461)<details>

| Misc | iOS, visionOS, tvOS & watchOS  | macOS  | Linux |  Windows |
| ----- | ---------------------- | ------- |  ----- |  --------- |
| [✅ 🧪 style](https://ews-build.webkit.org/#/builders/38/builds/97932 "Passed style check") | [✅ 🛠 ios](https://ews-build.webkit.org/#/builders/131/builds/17557 "Built successfully") | [✅ 🛠 mac](https://ews-build.webkit.org/#/builders/138/builds/7778 "Built successfully") | [✅ 🛠 wpe](https://ews-build.webkit.org/#/builders/5/builds/103047 "Built successfully") | [✅ 🛠 win](https://ews-build.webkit.org/#/builders/59/builds/48462 "Built successfully") 
| [✅ 🧪 bindings](https://ews-build.webkit.org/#/builders/9/builds/99977 "Passed tests") | [✅ 🛠 ios-sim](https://ews-build.webkit.org/#/builders/130/builds/17851 "Built successfully") | [✅ 🛠 mac-AS-debug](https://ews-build.webkit.org/#/builders/123/builds/26010 "Built successfully") | [✅ 🧪 wpe-wk2](https://ews-build.webkit.org/#/builders/34/builds/74567 "Passed tests") | [✅ 🧪 win-tests](https://ews-build.webkit.org/#/builders/60/builds/31755 "Passed tests") 
| [✅ 🧪 webkitperl](https://ews-build.webkit.org/#/builders/11/builds/100935 "Passed tests") | [✅ 🧪 ios-wk2](https://ews-build.webkit.org/#/builders/132/builds/13524 "Passed tests") | [✅ 🧪 api-mac](https://ews-build.webkit.org/#/builders/18/builds/88504 "Passed tests") | [✅ 🧪 api-wpe](https://ews-build.webkit.org/#/builders/41/builds/54924 "Passed tests") | 
| | [✅ 🧪 ios-wk2-wpt](https://ews-build.webkit.org/#/builders/133/builds/13300 "Passed tests") | [✅ 🧪 mac-wk1](https://ews-build.webkit.org/#/builders/135/builds/6436 "Passed tests") | [✅ 🛠 wpe-cairo](https://ews-build.webkit.org/#/builders/65/builds/47904 "Built successfully") | 
| | [⏳ 🧪 api-ios](https://ews-build.webkit.org/#/builders/API-Tests-iOS-Simulator-EWS "Waiting to run tests") | [✅ 🧪 mac-wk2](https://ews-build.webkit.org/#/builders/136/builds/6509 "Passed tests") | [✅ 🛠 gtk](https://ews-build.webkit.org/#/builders/2/builds/105425 "Built successfully") | 
| | [✅ 🛠 vision](https://ews-build.webkit.org/#/builders/128/builds/25012 "Built successfully") | [![loading](https://user-images.githubusercontent.com/3098702/171232313-daa606f1-8fd6-4b0f-a20b-2cb93c43d19b.png) 🧪 mac-AS-debug-wk2](https://ews-build.webkit.org/#/builders/122/builds/18229 "Build is being retried. Recent messages:OS: Sequoia (15.3), Xcode: 16.2; Skipping applying patch since patch_id isn't provided; Checked out pull request; Passed layout tests; layout-tests (retry)") | [✅ 🧪 gtk-wk2](https://ews-build.webkit.org/#/builders/1/builds/83569 "Passed tests") | 
| | [✅ 🛠 vision-sim](https://ews-build.webkit.org/#/builders/121/builds/25384 "Built successfully") | [✅ 🧪 mac-wk2-stress](https://ews-build.webkit.org/#/builders/8/builds/84685 "Passed tests") | [✅ 🧪 api-gtk](https://ews-build.webkit.org/#/builders/21/builds/83013 "Passed tests") | 
| | [✅ 🧪 vision-wk2](https://ews-build.webkit.org/#/builders/126/builds/27644 "Passed tests") | [✅ 🧪 mac-intel-wk2](https://ews-build.webkit.org/#/builders/137/builds/5327 "Passed tests") | [✅ 🛠 playstation](https://ews-build.webkit.org/#/builders/134/builds/18636 "Built successfully") | 
| | [✅ 🛠 tv](https://ews-build.webkit.org/#/builders/127/builds/24973 "Built successfully") | [✅ 🛠 mac-safer-cpp](https://ews-build.webkit.org/#/builders/120/builds/30142 "Built successfully") | | 
| | [✅ 🛠 tv-sim](https://ews-build.webkit.org/#/builders/125/builds/24795 "Built successfully") | | | 
| | [✅ 🛠 watch](https://ews-build.webkit.org/#/builders/129/builds/28109 "Built successfully") | | | 
| | [✅ 🛠 watch-sim](https://ews-build.webkit.org/#/builders/124/builds/26369 "Built successfully") | | | </details>
author_association: COLLABORATOR
user: login: webkit-early-warning-system
created_at: 2025-04-02T21:46:51Z
body: EWS run on current version of this PR (hash https://github.com/WebKit/WebKit/commit/4d8c7ea231b698b91624de8cdba9aa98d5be26e7)<details>

| Misc | iOS, visionOS, tvOS & watchOS  | macOS  | Linux |  Windows |
| ----- | ---------------------- | ------- |  ----- |  --------- |
| [✅ 🧪 style](https://ews-build.webkit.org/#/builders/38/builds/97992 "Passed style check") | [✅ 🛠 ios](https://ews-build.webkit.org/#/builders/131/builds/17623 "Built successfully") | [✅ 🛠 mac](https://ews-build.webkit.org/#/builders/138/builds/7850 "Built successfully") | [✅ 🛠 wpe](https://ews-build.webkit.org/#/builders/5/builds/103107 "Built successfully") | [✅ 🛠 win](https://ews-build.webkit.org/#/builders/59/builds/48521 "Built successfully") 
| [✅ 🧪 bindings](https://ews-build.webkit.org/#/builders/9/builds/100037 "Passed tests") | [✅ 🛠 ios-sim](https://ews-build.webkit.org/#/builders/130/builds/17915 "Built successfully") | [✅ 🛠 mac-AS-debug](https://ews-build.webkit.org/#/builders/123/builds/26074 "Built successfully") | [❌ 🧪 wpe-wk2](https://ews-build.webkit.org/#/builders/34/builds/74607 "Found 1 new test failure: imported/w3c/web-platform-tests/css/css-view-transitions/active-view-transition-type-on-non-root.html (failure)") | [✅ 🧪 win-tests](https://ews-build.webkit.org/#/builders/60/builds/31798 "Passed tests") 
| [✅ 🧪 webkitperl](https://ews-build.webkit.org/#/builders/11/builds/100996 "Passed tests") | [❌ 🧪 ios-wk2](https://ews-build.webkit.org/#/builders/132/builds/13573 "Found 1 new test failure: fast/forms/ios/focus-input-via-button.html (failure)") | [✅ 🧪 api-mac](https://ews-build.webkit.org/#/builders/18/builds/88554 "Passed tests") | [✅ 🧪 api-wpe](https://ews-build.webkit.org/#/builders/41/builds/54967 "Passed tests") | 
| | [✅ 🧪 ios-wk2-wpt](https://ews-build.webkit.org/#/builders/133/builds/13353 "Passed tests") | [✅ 🧪 mac-wk1](https://ews-build.webkit.org/#/builders/135/builds/6484 "Passed tests") | [✅ 🛠 wpe-cairo](https://ews-build.webkit.org/#/builders/65/builds/47963 "Built successfully") | 
| | [✅ 🧪 api-ios](https://ews-build.webkit.org/#/builders/13/builds/83335 "Passed tests") | [✅ 🧪 mac-wk2](https://ews-build.webkit.org/#/builders/136/builds/6567 "Passed tests") | [✅ 🛠 gtk](https://ews-build.webkit.org/#/builders/2/builds/105485 "Built successfully") | 
| | [✅ 🛠 vision](https://ews-build.webkit.org/#/builders/128/builds/25078 "Built successfully") | [✅ 🧪 mac-AS-debug-wk2](https://ews-build.webkit.org/#/builders/122/builds/18264 "Passed tests") | [✅ 🧪 gtk-wk2](https://ews-build.webkit.org/#/builders/1/builds/83595 "Passed tests") | 
| | [✅ 🛠 vision-sim](https://ews-build.webkit.org/#/builders/121/builds/25451 "Built successfully") | [✅ 🧪 mac-wk2-stress](https://ews-build.webkit.org/#/builders/8/builds/84732 "Passed tests") | [✅ 🧪 api-gtk](https://ews-build.webkit.org/#/builders/21/builds/83047 "Passed tests") | 
| [✅ 🛠 🧪 merge](https://ews-build.webkit.org/#/builders/19/builds/21059 "Built successfully and passed tests") | [✅ 🧪 vision-wk2](https://ews-build.webkit.org/#/builders/126/builds/27691 "Passed tests") | [✅ 🧪 mac-intel-wk2](https://ews-build.webkit.org/#/builders/137/builds/5367 "Passed tests") | [✅ 🛠 playstation](https://ews-build.webkit.org/#/builders/134/builds/18701 "Built successfully") | 
| | [✅ 🛠 tv](https://ews-build.webkit.org/#/builders/127/builds/25037 "Built successfully") | [✅ 🛠 mac-safer-cpp](https://ews-build.webkit.org/#/builders/120/builds/30211 "Built successfully") | | 
| | [✅ 🛠 tv-sim](https://ews-build.webkit.org/#/builders/125/builds/24857 "Built successfully") | | | 
| | [✅ 🛠 watch](https://ews-build.webkit.org/#/builders/129/builds/28173 "Built successfully") | | | 
| | [✅ 🛠 watch-sim](https://ews-build.webkit.org/#/builders/124/builds/26432 "Built successfully") | | | </details>
author_association: COLLABORATOR
user: login: webkit-commit-queue
created_at: 2025-04-04T22:23:29Z
body: Committed 293278@main (eed31338f551): <https://commits.webkit.org/293278@main>

Reviewed commits have been landed. Closing PR #43403 and removing active labels.
author_association: COLLABORATOR