- 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);