| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2012, Google Inc. All rights reserved. | 2 * Copyright (C) 2012, Google Inc. All rights reserved. |
| 3 * | 3 * |
| 4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
| 5 * modification, are permitted provided that the following conditions | 5 * modification, are permitted provided that the following conditions |
| 6 * are met: | 6 * are met: |
| 7 * | 7 * |
| 8 * 1. Redistributions of source code must retain the above copyright | 8 * 1. Redistributions of source code must retain the above copyright |
| 9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
| 10 * 2. Redistributions in binary form must reproduce the above copyright | 10 * 2. Redistributions in binary form must reproduce the above copyright |
| (...skipping 12 matching lines...) Expand all Loading... |
| 23 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | 23 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND |
| 24 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 24 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
| 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 27 */ | 27 */ |
| 28 | 28 |
| 29 #include "modules/accessibility/AXNodeObject.h" | 29 #include "modules/accessibility/AXNodeObject.h" |
| 30 | 30 |
| 31 #include "core/InputTypeNames.h" | 31 #include "core/InputTypeNames.h" |
| 32 #include "core/dom/AccessibleNode.h" | 32 #include "core/dom/AccessibleNode.h" |
| 33 #include "core/dom/AccessibleNodeList.h" |
| 33 #include "core/dom/Element.h" | 34 #include "core/dom/Element.h" |
| 34 #include "core/dom/FlatTreeTraversal.h" | 35 #include "core/dom/FlatTreeTraversal.h" |
| 35 #include "core/dom/NodeTraversal.h" | 36 #include "core/dom/NodeTraversal.h" |
| 36 #include "core/dom/QualifiedName.h" | 37 #include "core/dom/QualifiedName.h" |
| 37 #include "core/dom/Text.h" | 38 #include "core/dom/Text.h" |
| 38 #include "core/dom/UserGestureIndicator.h" | 39 #include "core/dom/UserGestureIndicator.h" |
| 39 #include "core/editing/EditingUtilities.h" | 40 #include "core/editing/EditingUtilities.h" |
| 40 #include "core/editing/markers/DocumentMarkerController.h" | 41 #include "core/editing/markers/DocumentMarkerController.h" |
| 41 #include "core/frame/LocalFrameView.h" | 42 #include "core/frame/LocalFrameView.h" |
| 42 #include "core/html/HTMLAnchorElement.h" | 43 #include "core/html/HTMLAnchorElement.h" |
| (...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 261 default: | 262 default: |
| 262 return; | 263 return; |
| 263 } | 264 } |
| 264 | 265 |
| 265 Element* target_element = value.element(); | 266 Element* target_element = value.element(); |
| 266 AXObject* target_obj = ax_object_cache_->GetOrCreate(target_element); | 267 AXObject* target_obj = ax_object_cache_->GetOrCreate(target_element); |
| 267 if (target_element) | 268 if (target_element) |
| 268 sparse_attribute_client_.AddObjectAttribute(attribute, *target_obj); | 269 sparse_attribute_client_.AddObjectAttribute(attribute, *target_obj); |
| 269 } | 270 } |
| 270 | 271 |
| 272 void AddRelationListProperty(AOMRelationListProperty property, |
| 273 const AccessibleNodeList& relations) override { |
| 274 AXObjectVectorAttribute attribute; |
| 275 switch (property) { |
| 276 case AOMRelationListProperty::kControls: |
| 277 attribute = AXObjectVectorAttribute::kAriaControls; |
| 278 break; |
| 279 case AOMRelationListProperty::kFlowTo: |
| 280 attribute = AXObjectVectorAttribute::kAriaFlowTo; |
| 281 break; |
| 282 default: |
| 283 return; |
| 284 } |
| 285 |
| 286 HeapVector<Member<AXObject>> objects; |
| 287 for (size_t i = 0; i < relations.length(); ++i) { |
| 288 AccessibleNode* accessible_node = relations.item(i); |
| 289 if (accessible_node) { |
| 290 Element* element = accessible_node->element(); |
| 291 AXObject* ax_element = ax_object_cache_->GetOrCreate(element); |
| 292 if (ax_element && !ax_element->AccessibilityIsIgnored()) |
| 293 objects.push_back(ax_element); |
| 294 } |
| 295 } |
| 296 |
| 297 sparse_attribute_client_.AddObjectVectorAttribute(attribute, objects); |
| 298 } |
| 299 |
| 271 private: | 300 private: |
| 272 Persistent<AXObjectCacheImpl> ax_object_cache_; | 301 Persistent<AXObjectCacheImpl> ax_object_cache_; |
| 273 AXSparseAttributeClient& sparse_attribute_client_; | 302 AXSparseAttributeClient& sparse_attribute_client_; |
| 274 }; | 303 }; |
| 275 | 304 |
| 276 AXNodeObject::AXNodeObject(Node* node, AXObjectCacheImpl& ax_object_cache) | 305 AXNodeObject::AXNodeObject(Node* node, AXObjectCacheImpl& ax_object_cache) |
| 277 : AXObject(ax_object_cache), | 306 : AXObject(ax_object_cache), |
| 278 aria_role_(kUnknownRole), | 307 aria_role_(kUnknownRole), |
| 279 children_dirty_(false), | 308 children_dirty_(false), |
| 280 node_(node) {} | 309 node_(node) {} |
| (...skipping 485 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 766 role = ButtonRoleType(); | 795 role = ButtonRoleType(); |
| 767 | 796 |
| 768 role = RemapAriaRoleDueToParent(role); | 797 role = RemapAriaRoleDueToParent(role); |
| 769 | 798 |
| 770 if (role) | 799 if (role) |
| 771 return role; | 800 return role; |
| 772 | 801 |
| 773 return kUnknownRole; | 802 return kUnknownRole; |
| 774 } | 803 } |
| 775 | 804 |
| 776 void AXNodeObject::AccessibilityChildrenFromAttribute( | 805 void AXNodeObject::AccessibilityChildrenFromAOMProperty( |
| 777 QualifiedName attr, | 806 AOMRelationListProperty property, |
| 778 AXObject::AXObjectVector& children) const { | 807 AXObject::AXObjectVector& children) const { |
| 779 HeapVector<Member<Element>> elements; | 808 HeapVector<Member<Element>> elements; |
| 780 ElementsFromAttribute(elements, attr); | 809 if (!HasAOMPropertyOrARIAAttribute(property, elements)) |
| 810 return; |
| 781 | 811 |
| 782 AXObjectCacheImpl& cache = AxObjectCache(); | 812 AXObjectCacheImpl& cache = AxObjectCache(); |
| 783 for (const auto& element : elements) { | 813 for (const auto& element : elements) { |
| 784 if (AXObject* child = cache.GetOrCreate(element)) { | 814 if (AXObject* child = cache.GetOrCreate(element)) { |
| 785 // Only aria-labelledby and aria-describedby can target hidden elements. | 815 // Only aria-labelledby and aria-describedby can target hidden elements. |
| 786 if (child->AccessibilityIsIgnored() && attr != aria_labelledbyAttr && | 816 if (child->AccessibilityIsIgnored() && |
| 787 attr != aria_labeledbyAttr && attr != aria_describedbyAttr) { | 817 property != AOMRelationListProperty::kLabeledBy && |
| 818 property != AOMRelationListProperty::kDescribedBy) { |
| 788 continue; | 819 continue; |
| 789 } | 820 } |
| 790 children.push_back(child); | 821 children.push_back(child); |
| 791 } | 822 } |
| 792 } | 823 } |
| 793 } | 824 } |
| 794 | 825 |
| 795 // This only returns true if this is the element that actually has the | 826 // This only returns true if this is the element that actually has the |
| 796 // contentEditable attribute set, unlike node->hasEditableStyle() which will | 827 // contentEditable attribute set, unlike node->hasEditableStyle() which will |
| 797 // also return true if an ancestor is editable. | 828 // also return true if an ancestor is editable. |
| (...skipping 1731 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2529 bool ignored_status = AccessibilityIsIgnored(); | 2560 bool ignored_status = AccessibilityIsIgnored(); |
| 2530 | 2561 |
| 2531 // The AX hierarchy only needs to be updated if the ignored status of an | 2562 // The AX hierarchy only needs to be updated if the ignored status of an |
| 2532 // element has changed. | 2563 // element has changed. |
| 2533 if (ignored_status != AccessibilityIsIgnored()) | 2564 if (ignored_status != AccessibilityIsIgnored()) |
| 2534 ChildrenChanged(); | 2565 ChildrenChanged(); |
| 2535 } | 2566 } |
| 2536 | 2567 |
| 2537 void AXNodeObject::ComputeAriaOwnsChildren( | 2568 void AXNodeObject::ComputeAriaOwnsChildren( |
| 2538 HeapVector<Member<AXObject>>& owned_children) const { | 2569 HeapVector<Member<AXObject>>& owned_children) const { |
| 2570 Vector<String> id_vector; |
| 2571 if (!CanHaveChildren() || IsNativeTextControl() || |
| 2572 HasContentEditableAttributeSet()) { |
| 2573 AxObjectCache().UpdateAriaOwns(this, id_vector, owned_children); |
| 2574 return; |
| 2575 } |
| 2576 |
| 2577 HeapVector<Member<Element>> elements; |
| 2578 if (HasAOMProperty(AOMRelationListProperty::kOwns, elements)) { |
| 2579 AxObjectCache().UpdateAriaOwns(this, id_vector, owned_children); |
| 2580 |
| 2581 for (const auto& element : elements) { |
| 2582 AXObject* ax_element = ax_object_cache_->GetOrCreate(&*element); |
| 2583 if (ax_element && !ax_element->AccessibilityIsIgnored()) |
| 2584 owned_children.push_back(ax_element); |
| 2585 } |
| 2586 |
| 2587 return; |
| 2588 } |
| 2589 |
| 2539 if (!HasAttribute(aria_ownsAttr)) | 2590 if (!HasAttribute(aria_ownsAttr)) |
| 2540 return; | 2591 return; |
| 2541 | 2592 |
| 2542 Vector<String> id_vector; | 2593 TokenVectorFromAttribute(id_vector, aria_ownsAttr); |
| 2543 if (CanHaveChildren() && !IsNativeTextControl() && | |
| 2544 !HasContentEditableAttributeSet()) | |
| 2545 TokenVectorFromAttribute(id_vector, aria_ownsAttr); | |
| 2546 | |
| 2547 AxObjectCache().UpdateAriaOwns(this, id_vector, owned_children); | 2594 AxObjectCache().UpdateAriaOwns(this, id_vector, owned_children); |
| 2548 } | 2595 } |
| 2549 | 2596 |
| 2550 // Based on | 2597 // Based on |
| 2551 // http://rawgit.com/w3c/aria/master/html-aam/html-aam.html#accessible-name-and-
description-calculation | 2598 // http://rawgit.com/w3c/aria/master/html-aam/html-aam.html#accessible-name-and-
description-calculation |
| 2552 String AXNodeObject::NativeTextAlternative( | 2599 String AXNodeObject::NativeTextAlternative( |
| 2553 AXObjectSet& visited, | 2600 AXObjectSet& visited, |
| 2554 AXNameFrom& name_from, | 2601 AXNameFrom& name_from, |
| 2555 AXRelatedObjectVector* related_objects, | 2602 AXRelatedObjectVector* related_objects, |
| 2556 NameSources* name_sources, | 2603 NameSources* name_sources, |
| (...skipping 504 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3061 | 3108 |
| 3062 description_from = kAXDescriptionFromRelatedElement; | 3109 description_from = kAXDescriptionFromRelatedElement; |
| 3063 if (description_sources) { | 3110 if (description_sources) { |
| 3064 description_sources->push_back( | 3111 description_sources->push_back( |
| 3065 DescriptionSource(found_description, aria_describedbyAttr)); | 3112 DescriptionSource(found_description, aria_describedbyAttr)); |
| 3066 description_sources->back().type = description_from; | 3113 description_sources->back().type = description_from; |
| 3067 } | 3114 } |
| 3068 | 3115 |
| 3069 // aria-describedby overrides any other accessible description, from: | 3116 // aria-describedby overrides any other accessible description, from: |
| 3070 // http://rawgit.com/w3c/aria/master/html-aam/html-aam.html | 3117 // http://rawgit.com/w3c/aria/master/html-aam/html-aam.html |
| 3118 // AOM version. |
| 3119 HeapVector<Member<Element>> elements; |
| 3120 if (HasAOMProperty(AOMRelationListProperty::kDescribedBy, elements)) { |
| 3121 AXObjectSet visited; |
| 3122 description = TextFromElements(true, visited, elements, related_objects); |
| 3123 if (!description.IsNull()) { |
| 3124 if (description_sources) { |
| 3125 DescriptionSource& source = description_sources->back(); |
| 3126 source.type = description_from; |
| 3127 source.related_objects = *related_objects; |
| 3128 source.text = description; |
| 3129 found_description = true; |
| 3130 } else { |
| 3131 return description; |
| 3132 } |
| 3133 } else if (description_sources) { |
| 3134 description_sources->back().invalid = true; |
| 3135 } |
| 3136 } |
| 3137 |
| 3138 // aria-describedby overrides any other accessible description, from: |
| 3139 // http://rawgit.com/w3c/aria/master/html-aam/html-aam.html |
| 3071 const AtomicString& aria_describedby = GetAttribute(aria_describedbyAttr); | 3140 const AtomicString& aria_describedby = GetAttribute(aria_describedbyAttr); |
| 3072 if (!aria_describedby.IsNull()) { | 3141 if (!aria_describedby.IsNull()) { |
| 3073 if (description_sources) | 3142 if (description_sources) |
| 3074 description_sources->back().attribute_value = aria_describedby; | 3143 description_sources->back().attribute_value = aria_describedby; |
| 3075 | 3144 |
| 3076 description = TextFromAriaDescribedby(related_objects); | 3145 description = TextFromAriaDescribedby(related_objects); |
| 3077 | 3146 |
| 3078 if (!description.IsNull()) { | 3147 if (!description.IsNull()) { |
| 3079 if (description_sources) { | 3148 if (description_sources) { |
| 3080 DescriptionSource& source = description_sources->back(); | 3149 DescriptionSource& source = description_sources->back(); |
| (...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3258 return String(); | 3327 return String(); |
| 3259 return ToTextControlElement(node)->StrippedPlaceholder(); | 3328 return ToTextControlElement(node)->StrippedPlaceholder(); |
| 3260 } | 3329 } |
| 3261 | 3330 |
| 3262 DEFINE_TRACE(AXNodeObject) { | 3331 DEFINE_TRACE(AXNodeObject) { |
| 3263 visitor->Trace(node_); | 3332 visitor->Trace(node_); |
| 3264 AXObject::Trace(visitor); | 3333 AXObject::Trace(visitor); |
| 3265 } | 3334 } |
| 3266 | 3335 |
| 3267 } // namespace blink | 3336 } // namespace blink |
| OLD | NEW |