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