Index: third_party/WebKit/Source/modules/accessibility/AXNodeObject.cpp |
diff --git a/third_party/WebKit/Source/modules/accessibility/AXNodeObject.cpp b/third_party/WebKit/Source/modules/accessibility/AXNodeObject.cpp |
index 5976ccf44b0ac11c8c54fd7ffe37b60d541e3fde..ed3a70b003c0d7eedf4480a233aa8bb534606f4e 100644 |
--- a/third_party/WebKit/Source/modules/accessibility/AXNodeObject.cpp |
+++ b/third_party/WebKit/Source/modules/accessibility/AXNodeObject.cpp |
@@ -30,6 +30,7 @@ |
#include "core/InputTypeNames.h" |
#include "core/dom/AccessibleNode.h" |
+#include "core/dom/AccessibleNodeList.h" |
#include "core/dom/Element.h" |
#include "core/dom/FlatTreeTraversal.h" |
#include "core/dom/NodeTraversal.h" |
@@ -268,6 +269,34 @@ class AXSparseAttributeAOMPropertyClient : public AOMPropertyClient { |
sparse_attribute_client_.AddObjectAttribute(attribute, *target_obj); |
} |
+ void AddRelationListProperty(AOMRelationListProperty property, |
+ const AccessibleNodeList& relations) override { |
+ AXObjectVectorAttribute attribute; |
+ switch (property) { |
+ case AOMRelationListProperty::kControls: |
+ attribute = AXObjectVectorAttribute::kAriaControls; |
+ break; |
+ case AOMRelationListProperty::kFlowTo: |
+ attribute = AXObjectVectorAttribute::kAriaFlowTo; |
+ break; |
+ default: |
+ return; |
+ } |
+ |
+ HeapVector<Member<AXObject>> objects; |
+ for (size_t i = 0; i < relations.length(); ++i) { |
+ AccessibleNode* accessible_node = relations.item(i); |
+ if (accessible_node) { |
+ Element* element = accessible_node->element(); |
+ AXObject* ax_element = ax_object_cache_->GetOrCreate(element); |
+ if (ax_element && !ax_element->AccessibilityIsIgnored()) |
+ objects.push_back(ax_element); |
+ } |
+ } |
+ |
+ sparse_attribute_client_.AddObjectVectorAttribute(attribute, objects); |
+ } |
+ |
private: |
Persistent<AXObjectCacheImpl> ax_object_cache_; |
AXSparseAttributeClient& sparse_attribute_client_; |
@@ -773,18 +802,20 @@ AccessibilityRole AXNodeObject::DetermineAriaRoleAttribute() const { |
return kUnknownRole; |
} |
-void AXNodeObject::AccessibilityChildrenFromAttribute( |
- QualifiedName attr, |
+void AXNodeObject::AccessibilityChildrenFromAOMProperty( |
+ AOMRelationListProperty property, |
AXObject::AXObjectVector& children) const { |
HeapVector<Member<Element>> elements; |
- ElementsFromAttribute(elements, attr); |
+ if (!HasAOMPropertyOrARIAAttribute(property, elements)) |
+ return; |
AXObjectCacheImpl& cache = AxObjectCache(); |
for (const auto& element : elements) { |
if (AXObject* child = cache.GetOrCreate(element)) { |
// Only aria-labelledby and aria-describedby can target hidden elements. |
- if (child->AccessibilityIsIgnored() && attr != aria_labelledbyAttr && |
- attr != aria_labeledbyAttr && attr != aria_describedbyAttr) { |
+ if (child->AccessibilityIsIgnored() && |
+ property != AOMRelationListProperty::kLabeledBy && |
+ property != AOMRelationListProperty::kDescribedBy) { |
continue; |
} |
children.push_back(child); |
@@ -2536,14 +2567,30 @@ void AXNodeObject::UpdateAccessibilityRole() { |
void AXNodeObject::ComputeAriaOwnsChildren( |
HeapVector<Member<AXObject>>& owned_children) const { |
- if (!HasAttribute(aria_ownsAttr)) |
+ Vector<String> id_vector; |
+ if (!CanHaveChildren() || IsNativeTextControl() || |
+ HasContentEditableAttributeSet()) { |
+ AxObjectCache().UpdateAriaOwns(this, id_vector, owned_children); |
return; |
+ } |
- Vector<String> id_vector; |
- if (CanHaveChildren() && !IsNativeTextControl() && |
- !HasContentEditableAttributeSet()) |
- TokenVectorFromAttribute(id_vector, aria_ownsAttr); |
+ HeapVector<Member<Element>> elements; |
+ if (HasAOMProperty(AOMRelationListProperty::kOwns, elements)) { |
+ AxObjectCache().UpdateAriaOwns(this, id_vector, owned_children); |
+ |
+ for (const auto& element : elements) { |
+ AXObject* ax_element = ax_object_cache_->GetOrCreate(&*element); |
+ if (ax_element && !ax_element->AccessibilityIsIgnored()) |
+ owned_children.push_back(ax_element); |
+ } |
+ |
+ return; |
+ } |
+ |
+ if (!HasAttribute(aria_ownsAttr)) |
+ return; |
+ TokenVectorFromAttribute(id_vector, aria_ownsAttr); |
AxObjectCache().UpdateAriaOwns(this, id_vector, owned_children); |
} |
@@ -3068,6 +3115,28 @@ String AXNodeObject::Description(AXNameFrom name_from, |
// aria-describedby overrides any other accessible description, from: |
// http://rawgit.com/w3c/aria/master/html-aam/html-aam.html |
+ // AOM version. |
+ HeapVector<Member<Element>> elements; |
+ if (HasAOMProperty(AOMRelationListProperty::kDescribedBy, elements)) { |
+ AXObjectSet visited; |
+ description = TextFromElements(true, visited, elements, related_objects); |
+ if (!description.IsNull()) { |
+ if (description_sources) { |
+ DescriptionSource& source = description_sources->back(); |
+ source.type = description_from; |
+ source.related_objects = *related_objects; |
+ source.text = description; |
+ found_description = true; |
+ } else { |
+ return description; |
+ } |
+ } else if (description_sources) { |
+ description_sources->back().invalid = true; |
+ } |
+ } |
+ |
+ // aria-describedby overrides any other accessible description, from: |
+ // http://rawgit.com/w3c/aria/master/html-aam/html-aam.html |
const AtomicString& aria_describedby = GetAttribute(aria_describedbyAttr); |
if (!aria_describedby.IsNull()) { |
if (description_sources) |