Title: [295491] trunk/Source
Revision
295491
Author
[email protected]
Date
2022-06-13 10:15:16 -0700 (Mon, 13 Jun 2022)

Log Message

AX ITM: Fix for accessibility/Mac/aria-errormessage.html in isolated tree mode.
https://bugs.webkit.org/show_bug.cgi?id=241398

Test: accessibility/Mac/aria-errormessage.html

Reviewed by Chris Fleizach and Tyler Wilcock.

This test was failing because the elements that are referenced as error messages are <span> elements, which are ignored on the mac platform. Therefore there was no isolated object created for those elements and AXIsolatedTree::objectsForIDs will not return them. This patch solves this problem by creating orphan isolated objects in AXIsolatedTree:objectsForIDs if there is no isolated object for the requested AXID, and the corresponding live objects exists.

Canonical link: https://commits.webkit.org/251496@main

Modified Paths

Diff

Modified: trunk/Source/WebCore/accessibility/AXObjectCache.cpp (295490 => 295491)


--- trunk/Source/WebCore/accessibility/AXObjectCache.cpp	2022-06-13 16:11:21 UTC (rev 295490)
+++ trunk/Source/WebCore/accessibility/AXObjectCache.cpp	2022-06-13 17:15:16 UTC (rev 295491)
@@ -958,7 +958,7 @@
 
     return axIDs.map([this] (const auto& axID) -> RefPtr<AXCoreObject> {
         ASSERT(axID.isValid());
-        return objectFromAXID(axID);
+        return objectForID(axID);
     });
 }
 
@@ -3843,6 +3843,7 @@
         }
         targetsIterator->value.append(target->objectID());
     }
+    m_relationTargets.add(target->objectID());
 
     if (addingSymmetricRelation == AddingSymmetricRelation::No) {
         if (auto symmetric = symmetricRelation(relationType); symmetric != AXRelationType::None)
@@ -3859,6 +3860,7 @@
     relationsNeedUpdate(false);
     AXLOG("Updating relations.");
     m_relations.clear();
+    m_relationTargets.clear();
 
     struct RelationOrigin {
         Element* originElement { nullptr };
@@ -3919,6 +3921,12 @@
     return m_relations;
 }
 
+const HashSet<AXID>& AXObjectCache::relationTargetIDs()
+{
+    updateRelationsIfNeeded();
+    return m_relationTargets;
+}
+
 std::optional<Vector<AXID>> AXObjectCache::relatedObjectIDsFor(const AXCoreObject& object, AXRelationType relationType)
 {
     updateRelationsIfNeeded();

Modified: trunk/Source/WebCore/accessibility/AXObjectCache.h (295490 => 295491)


--- trunk/Source/WebCore/accessibility/AXObjectCache.h	2022-06-13 16:11:21 UTC (rev 295490)
+++ trunk/Source/WebCore/accessibility/AXObjectCache.h	2022-06-13 17:15:16 UTC (rev 295491)
@@ -223,7 +223,7 @@
     bool nodeIsTextControl(const Node*);
 
     AXID platformGenerateAXID() const;
-    AccessibilityObject* objectFromAXID(AXID id) const { return m_objects.get(id); }
+    AccessibilityObject* objectForID(const AXID& id) const { return m_objects.get(id); }
     Vector<RefPtr<AXCoreObject>> objectsForIDs(const Vector<AXID>&) const;
 
     // Text marker utilities.
@@ -510,6 +510,7 @@
     void updateRelationsIfNeeded();
     void relationsNeedUpdate(bool);
     HashMap<AXID, AXRelations> relations();
+    const HashSet<AXID>& relationTargetIDs();
 
     Document& m_document;
     const std::optional<PageIdentifier> m_pageID; // constant for object's lifetime.
@@ -571,6 +572,7 @@
     // Relationships between objects.
     HashMap<AXID, AXRelations> m_relations;
     bool m_relationsNeedUpdate { true };
+    HashSet<AXID> m_relationTargets;
 
 #if USE(ATSPI)
     ListHashSet<RefPtr<AXCoreObject>> m_deferredParentChangedList;

Modified: trunk/Source/WebCore/accessibility/isolatedtree/AXIsolatedObject.cpp (295490 => 295491)


--- trunk/Source/WebCore/accessibility/isolatedtree/AXIsolatedObject.cpp	2022-06-13 16:11:21 UTC (rev 295490)
+++ trunk/Source/WebCore/accessibility/isolatedtree/AXIsolatedObject.cpp	2022-06-13 17:15:16 UTC (rev 295491)
@@ -76,8 +76,6 @@
 {
     ASSERT(is<AccessibilityObject>(coreObject));
     auto& object = downcast<AccessibilityObject>(coreObject);
-    // We should never create an isolated object from an ignored object.
-    ASSERT(!object.accessibilityIsIgnored());
 
     setProperty(AXPropertyName::ARIALandmarkRoleDescription, object.ariaLandmarkRoleDescription().isolatedCopy());
     setProperty(AXPropertyName::AccessibilityDescription, object.accessibilityDescription().isolatedCopy());
@@ -413,7 +411,7 @@
         return nullptr;
 
     auto* axObjectCache = this->axObjectCache();
-    return axObjectCache ? axObjectCache->objectFromAXID(m_id) : nullptr;
+    return axObjectCache ? axObjectCache->objectForID(m_id) : nullptr;
 }
 
 void AXIsolatedObject::setMathscripts(AXPropertyName propertyName, AXCoreObject& object)

Modified: trunk/Source/WebCore/accessibility/isolatedtree/AXIsolatedTree.cpp (295490 => 295491)


--- trunk/Source/WebCore/accessibility/isolatedtree/AXIsolatedTree.cpp	2022-06-13 16:11:21 UTC (rev 295490)
+++ trunk/Source/WebCore/accessibility/isolatedtree/AXIsolatedTree.cpp	2022-06-13 17:15:16 UTC (rev 295491)
@@ -145,7 +145,7 @@
     return nullptr;
 }
 
-RefPtr<AXIsolatedObject> AXIsolatedTree::nodeForID(AXID axID) const
+RefPtr<AXIsolatedObject> AXIsolatedTree::nodeForID(const AXID& axID) const
 {
     // In isolated tree mode 2, only access m_readerThreadNodeMap on the AX thread.
     ASSERT(m_usedOnAXThread ? !isMainThread() : isMainThread());
@@ -155,17 +155,42 @@
     return axID.isValid() ? m_readerThreadNodeMap.get(axID) : nullptr;
 }
 
-Vector<RefPtr<AXCoreObject>> AXIsolatedTree::objectsForIDs(const Vector<AXID>& axIDs) const
+Vector<RefPtr<AXCoreObject>> AXIsolatedTree::objectsForIDs(const Vector<AXID>& axIDs)
 {
     AXTRACE("AXIsolatedTree::objectsForIDs"_s);
+    ASSERT(!isMainThread());
+
     Vector<RefPtr<AXCoreObject>> result;
     result.reserveInitialCapacity(axIDs.size());
     for (auto& axID : axIDs) {
-        if (auto object = nodeForID(axID))
+        auto object = nodeForID(axID);
+        if (object) {
             result.uncheckedAppend(object);
+            continue;
+        }
+
+        // There is no isolated object for this AXID. This can happen if the corresponding live object is ignored.
+        // If there is a live object for this ID and it is an ignored target of a relationship, create an isolated object for it.
+        object = Accessibility::retrieveValueFromMainThread<RefPtr<AXIsolatedObject>>([&axID, this] () -> RefPtr<AXIsolatedObject> {
+            auto* cache = axObjectCache();
+            if (!cache || !cache->relationTargetIDs().contains(axID))
+                return nullptr;
+
+            auto* axObject = cache->objectForID(axID);
+            if (!axObject || !axObject->accessibilityIsIgnored())
+                return nullptr;
+
+            auto object = AXIsolatedObject::create(*axObject, const_cast<AXIsolatedTree*>(this));
+            ASSERT(axObject->wrapper());
+            object->attachPlatformWrapper(axObject->wrapper());
+            return object;
+        });
+        if (object) {
+            m_readerThreadNodeMap.add(axID, *object);
+            result.uncheckedAppend(object);
+        }
     }
     result.shrinkToFit();
-
     return result;
 }
 
@@ -263,9 +288,10 @@
         if (auto* cache = axObjectCache()) {
             resolvedAppends.reserveInitialCapacity(m_unresolvedPendingAppends.size());
             for (const auto& unresolvedAppend : m_unresolvedPendingAppends) {
-                if (auto* axObject = cache->objectFromAXID(unresolvedAppend.key))
+                if (auto* axObject = cache->objectForID(unresolvedAppend.key)) {
                     if (auto nodeChange = nodeChangeForObject(*axObject, unresolvedAppend.value))
                         resolvedAppends.uncheckedAppend(WTFMove(*nodeChange));
+                }
             }
             m_unresolvedPendingAppends.clear();
         }

Modified: trunk/Source/WebCore/accessibility/isolatedtree/AXIsolatedTree.h (295490 => 295491)


--- trunk/Source/WebCore/accessibility/isolatedtree/AXIsolatedTree.h	2022-06-13 16:11:21 UTC (rev 295490)
+++ trunk/Source/WebCore/accessibility/isolatedtree/AXIsolatedTree.h	2022-06-13 17:15:16 UTC (rev 295491)
@@ -332,8 +332,8 @@
 
     RefPtr<AXIsolatedObject> rootNode();
     RefPtr<AXIsolatedObject> focusedNode();
-    RefPtr<AXIsolatedObject> nodeForID(AXID) const;
-    Vector<RefPtr<AXCoreObject>> objectsForIDs(const Vector<AXID>&) const;
+    RefPtr<AXIsolatedObject> nodeForID(const AXID&) const;
+    Vector<RefPtr<AXCoreObject>> objectsForIDs(const Vector<AXID>&);
 
     struct NodeChange {
         Ref<AXIsolatedObject> isolatedObject;

Modified: trunk/Source/WebKitLegacy/win/AccessibleBase.cpp (295490 => 295491)


--- trunk/Source/WebKitLegacy/win/AccessibleBase.cpp	2022-06-13 16:11:21 UTC (rev 295490)
+++ trunk/Source/WebKitLegacy/win/AccessibleBase.cpp	2022-06-13 17:15:16 UTC (rev 295491)
@@ -1039,7 +1039,7 @@
         if (!document)
             return E_FAIL;
 
-        childObj = document->axObjectCache()->objectFromAXID(makeObjectIdentifier<AXIDType>(-vChild.lVal));
+        childObj = document->axObjectCache()->objectForID(makeObjectIdentifier<AXIDType>(-vChild.lVal));
     } else {
         size_t childIndex = static_cast<size_t>(vChild.lVal - 1);
 
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to