Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(9)

Side by Side Diff: third_party/WebKit/Source/modules/accessibility/AXNodeObject.cpp

Issue 2883203002: Revert of Rename AXObject to AXObjectImpl in modules/ and web/ (Closed)
Patch Set: Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
73 #include "platform/wtf/text/StringBuilder.h" 73 #include "platform/wtf/text/StringBuilder.h"
74 74
75 namespace blink { 75 namespace blink {
76 76
77 using namespace HTMLNames; 77 using namespace HTMLNames;
78 78
79 class SparseAttributeSetter { 79 class SparseAttributeSetter {
80 USING_FAST_MALLOC(SparseAttributeSetter); 80 USING_FAST_MALLOC(SparseAttributeSetter);
81 81
82 public: 82 public:
83 virtual void Run(const AXObjectImpl&, 83 virtual void Run(const AXObject&,
84 AXSparseAttributeClient&, 84 AXSparseAttributeClient&,
85 const AtomicString& value) = 0; 85 const AtomicString& value) = 0;
86 }; 86 };
87 87
88 class BoolAttributeSetter : public SparseAttributeSetter { 88 class BoolAttributeSetter : public SparseAttributeSetter {
89 public: 89 public:
90 BoolAttributeSetter(AXBoolAttribute attribute) : attribute_(attribute) {} 90 BoolAttributeSetter(AXBoolAttribute attribute) : attribute_(attribute) {}
91 91
92 private: 92 private:
93 AXBoolAttribute attribute_; 93 AXBoolAttribute attribute_;
94 94
95 void Run(const AXObjectImpl& obj, 95 void Run(const AXObject& obj,
96 AXSparseAttributeClient& attribute_map, 96 AXSparseAttributeClient& attribute_map,
97 const AtomicString& value) override { 97 const AtomicString& value) override {
98 attribute_map.AddBoolAttribute(attribute_, 98 attribute_map.AddBoolAttribute(attribute_,
99 EqualIgnoringASCIICase(value, "true")); 99 EqualIgnoringASCIICase(value, "true"));
100 } 100 }
101 }; 101 };
102 102
103 class StringAttributeSetter : public SparseAttributeSetter { 103 class StringAttributeSetter : public SparseAttributeSetter {
104 public: 104 public:
105 StringAttributeSetter(AXStringAttribute attribute) : attribute_(attribute) {} 105 StringAttributeSetter(AXStringAttribute attribute) : attribute_(attribute) {}
106 106
107 private: 107 private:
108 AXStringAttribute attribute_; 108 AXStringAttribute attribute_;
109 109
110 void Run(const AXObjectImpl& obj, 110 void Run(const AXObject& obj,
111 AXSparseAttributeClient& attribute_map, 111 AXSparseAttributeClient& attribute_map,
112 const AtomicString& value) override { 112 const AtomicString& value) override {
113 attribute_map.AddStringAttribute(attribute_, value); 113 attribute_map.AddStringAttribute(attribute_, value);
114 } 114 }
115 }; 115 };
116 116
117 class ObjectAttributeSetter : public SparseAttributeSetter { 117 class ObjectAttributeSetter : public SparseAttributeSetter {
118 public: 118 public:
119 ObjectAttributeSetter(AXObjectAttribute attribute) : attribute_(attribute) {} 119 ObjectAttributeSetter(AXObjectAttribute attribute) : attribute_(attribute) {}
120 120
121 private: 121 private:
122 AXObjectAttribute attribute_; 122 AXObjectAttribute attribute_;
123 123
124 void Run(const AXObjectImpl& obj, 124 void Run(const AXObject& obj,
125 AXSparseAttributeClient& attribute_map, 125 AXSparseAttributeClient& attribute_map,
126 const AtomicString& value) override { 126 const AtomicString& value) override {
127 if (value.IsNull() || value.IsEmpty()) 127 if (value.IsNull() || value.IsEmpty())
128 return; 128 return;
129 129
130 Node* node = obj.GetNode(); 130 Node* node = obj.GetNode();
131 if (!node || !node->IsElementNode()) 131 if (!node || !node->IsElementNode())
132 return; 132 return;
133 Element* target = ToElement(node)->GetTreeScope().getElementById(value); 133 Element* target = ToElement(node)->GetTreeScope().getElementById(value);
134 if (!target) 134 if (!target)
135 return; 135 return;
136 AXObjectImpl* ax_target = obj.AxObjectCache().GetOrCreate(target); 136 AXObject* ax_target = obj.AxObjectCache().GetOrCreate(target);
137 if (ax_target) 137 if (ax_target)
138 attribute_map.AddObjectAttribute(attribute_, *ax_target); 138 attribute_map.AddObjectAttribute(attribute_, *ax_target);
139 } 139 }
140 }; 140 };
141 141
142 class ObjectVectorAttributeSetter : public SparseAttributeSetter { 142 class ObjectVectorAttributeSetter : public SparseAttributeSetter {
143 public: 143 public:
144 ObjectVectorAttributeSetter(AXObjectVectorAttribute attribute) 144 ObjectVectorAttributeSetter(AXObjectVectorAttribute attribute)
145 : attribute_(attribute) {} 145 : attribute_(attribute) {}
146 146
147 private: 147 private:
148 AXObjectVectorAttribute attribute_; 148 AXObjectVectorAttribute attribute_;
149 149
150 void Run(const AXObjectImpl& obj, 150 void Run(const AXObject& obj,
151 AXSparseAttributeClient& attribute_map, 151 AXSparseAttributeClient& attribute_map,
152 const AtomicString& value) override { 152 const AtomicString& value) override {
153 Node* node = obj.GetNode(); 153 Node* node = obj.GetNode();
154 if (!node || !node->IsElementNode()) 154 if (!node || !node->IsElementNode())
155 return; 155 return;
156 156
157 String attribute_value = value.GetString(); 157 String attribute_value = value.GetString();
158 if (attribute_value.IsEmpty()) 158 if (attribute_value.IsEmpty())
159 return; 159 return;
160 160
161 attribute_value.SimplifyWhiteSpace(); 161 attribute_value.SimplifyWhiteSpace();
162 Vector<String> ids; 162 Vector<String> ids;
163 attribute_value.Split(' ', ids); 163 attribute_value.Split(' ', ids);
164 if (ids.IsEmpty()) 164 if (ids.IsEmpty())
165 return; 165 return;
166 166
167 HeapVector<Member<AXObjectImpl>> objects; 167 HeapVector<Member<AXObject>> objects;
168 TreeScope& scope = node->GetTreeScope(); 168 TreeScope& scope = node->GetTreeScope();
169 for (const auto& id : ids) { 169 for (const auto& id : ids) {
170 if (Element* id_element = scope.getElementById(AtomicString(id))) { 170 if (Element* id_element = scope.getElementById(AtomicString(id))) {
171 AXObjectImpl* ax_id_element = 171 AXObject* ax_id_element = obj.AxObjectCache().GetOrCreate(id_element);
172 obj.AxObjectCache().GetOrCreate(id_element);
173 if (ax_id_element && !ax_id_element->AccessibilityIsIgnored()) 172 if (ax_id_element && !ax_id_element->AccessibilityIsIgnored())
174 objects.push_back(ax_id_element); 173 objects.push_back(ax_id_element);
175 } 174 }
176 } 175 }
177 176
178 attribute_map.AddObjectVectorAttribute(attribute_, objects); 177 attribute_map.AddObjectVectorAttribute(attribute_, objects);
179 } 178 }
180 }; 179 };
181 180
182 using AXSparseAttributeSetterMap = 181 using AXSparseAttributeSetterMap =
(...skipping 26 matching lines...) Expand all
209 aria_keyshortcutsAttr, 208 aria_keyshortcutsAttr,
210 new StringAttributeSetter(AXStringAttribute::kAriaKeyShortcuts)); 209 new StringAttributeSetter(AXStringAttribute::kAriaKeyShortcuts));
211 ax_sparse_attribute_setter_map.Set( 210 ax_sparse_attribute_setter_map.Set(
212 aria_roledescriptionAttr, 211 aria_roledescriptionAttr,
213 new StringAttributeSetter(AXStringAttribute::kAriaRoleDescription)); 212 new StringAttributeSetter(AXStringAttribute::kAriaRoleDescription));
214 } 213 }
215 return ax_sparse_attribute_setter_map; 214 return ax_sparse_attribute_setter_map;
216 } 215 }
217 216
218 AXNodeObject::AXNodeObject(Node* node, AXObjectCacheImpl& ax_object_cache) 217 AXNodeObject::AXNodeObject(Node* node, AXObjectCacheImpl& ax_object_cache)
219 : AXObjectImpl(ax_object_cache), 218 : AXObject(ax_object_cache),
220 aria_role_(kUnknownRole), 219 aria_role_(kUnknownRole),
221 children_dirty_(false), 220 children_dirty_(false),
222 node_(node) {} 221 node_(node) {}
223 222
224 AXNodeObject* AXNodeObject::Create(Node* node, 223 AXNodeObject* AXNodeObject::Create(Node* node,
225 AXObjectCacheImpl& ax_object_cache) { 224 AXObjectCacheImpl& ax_object_cache) {
226 return new AXNodeObject(node, ax_object_cache); 225 return new AXNodeObject(node, ax_object_cache);
227 } 226 }
228 227
229 AXNodeObject::~AXNodeObject() { 228 AXNodeObject::~AXNodeObject() {
230 DCHECK(!node_); 229 DCHECK(!node_);
231 } 230 }
232 231
233 void AXNodeObject::AlterSliderValue(bool increase) { 232 void AXNodeObject::AlterSliderValue(bool increase) {
234 if (RoleValue() != kSliderRole) 233 if (RoleValue() != kSliderRole)
235 return; 234 return;
236 235
237 float value = ValueForRange(); 236 float value = ValueForRange();
238 float step = StepValueForRange(); 237 float step = StepValueForRange();
239 238
240 value += increase ? step : -step; 239 value += increase ? step : -step;
241 240
242 SetValue(String::Number(value)); 241 SetValue(String::Number(value));
243 AxObjectCache().PostNotification(GetNode(), 242 AxObjectCache().PostNotification(GetNode(),
244 AXObjectCacheImpl::kAXValueChanged); 243 AXObjectCacheImpl::kAXValueChanged);
245 } 244 }
246 245
247 AXObjectImpl* AXNodeObject::ActiveDescendant() { 246 AXObject* AXNodeObject::ActiveDescendant() {
248 if (!node_ || !node_->IsElementNode()) 247 if (!node_ || !node_->IsElementNode())
249 return nullptr; 248 return nullptr;
250 249
251 const AtomicString& active_descendant_attr = 250 const AtomicString& active_descendant_attr =
252 GetAttribute(aria_activedescendantAttr); 251 GetAttribute(aria_activedescendantAttr);
253 if (active_descendant_attr.IsNull() || active_descendant_attr.IsEmpty()) 252 if (active_descendant_attr.IsNull() || active_descendant_attr.IsEmpty())
254 return nullptr; 253 return nullptr;
255 254
256 Element* element = ToElement(GetNode()); 255 Element* element = ToElement(GetNode());
257 Element* descendant = 256 Element* descendant =
258 element->GetTreeScope().getElementById(active_descendant_attr); 257 element->GetTreeScope().getElementById(active_descendant_attr);
259 if (!descendant) 258 if (!descendant)
260 return nullptr; 259 return nullptr;
261 260
262 AXObjectImpl* ax_descendant = AxObjectCache().GetOrCreate(descendant); 261 AXObject* ax_descendant = AxObjectCache().GetOrCreate(descendant);
263 return ax_descendant; 262 return ax_descendant;
264 } 263 }
265 264
266 bool AXNodeObject::ComputeAccessibilityIsIgnored( 265 bool AXNodeObject::ComputeAccessibilityIsIgnored(
267 IgnoredReasons* ignored_reasons) const { 266 IgnoredReasons* ignored_reasons) const {
268 #if DCHECK_IS_ON() 267 #if DCHECK_IS_ON()
269 // Double-check that an AXObjectImpl is never accessed before 268 // Double-check that an AXObject is never accessed before
270 // it's been initialized. 269 // it's been initialized.
271 DCHECK(initialized_); 270 DCHECK(initialized_);
272 #endif 271 #endif
273 272
274 // If this element is within a parent that cannot have children, it should not 273 // If this element is within a parent that cannot have children, it should not
275 // be exposed. 274 // be exposed.
276 if (IsDescendantOfLeafNode()) { 275 if (IsDescendantOfLeafNode()) {
277 if (ignored_reasons) 276 if (ignored_reasons)
278 ignored_reasons->push_back( 277 ignored_reasons->push_back(
279 IgnoredReason(kAXAncestorIsLeafNode, LeafNodeAncestor())); 278 IgnoredReason(kAXAncestorIsLeafNode, LeafNodeAncestor()));
280 return true; 279 return true;
281 } 280 }
282 281
283 // Ignore labels that are already referenced by a control. 282 // Ignore labels that are already referenced by a control.
284 AXObjectImpl* control_object = CorrespondingControlForLabelElement(); 283 AXObject* control_object = CorrespondingControlForLabelElement();
285 if (control_object && control_object->IsCheckboxOrRadio() && 284 if (control_object && control_object->IsCheckboxOrRadio() &&
286 control_object->NameFromLabelElement()) { 285 control_object->NameFromLabelElement()) {
287 if (ignored_reasons) { 286 if (ignored_reasons) {
288 HTMLLabelElement* label = LabelElementContainer(); 287 HTMLLabelElement* label = LabelElementContainer();
289 if (label && label != GetNode()) { 288 if (label && label != GetNode()) {
290 AXObjectImpl* label_ax_object = AxObjectCache().GetOrCreate(label); 289 AXObject* label_ax_object = AxObjectCache().GetOrCreate(label);
291 ignored_reasons->push_back( 290 ignored_reasons->push_back(
292 IgnoredReason(kAXLabelContainer, label_ax_object)); 291 IgnoredReason(kAXLabelContainer, label_ax_object));
293 } 292 }
294 293
295 ignored_reasons->push_back(IgnoredReason(kAXLabelFor, control_object)); 294 ignored_reasons->push_back(IgnoredReason(kAXLabelFor, control_object));
296 } 295 }
297 return true; 296 return true;
298 } 297 }
299 298
300 Element* element = GetNode()->IsElementNode() ? ToElement(GetNode()) 299 Element* element = GetNode()->IsElementNode() ? ToElement(GetNode())
(...skipping 11 matching lines...) Expand all
312 return true; 311 return true;
313 } 312 }
314 return false; 313 return false;
315 } 314 }
316 315
317 static bool IsListElement(Node* node) { 316 static bool IsListElement(Node* node) {
318 return isHTMLUListElement(*node) || isHTMLOListElement(*node) || 317 return isHTMLUListElement(*node) || isHTMLOListElement(*node) ||
319 isHTMLDListElement(*node); 318 isHTMLDListElement(*node);
320 } 319 }
321 320
322 static bool IsPresentationalInTable(AXObjectImpl* parent, 321 static bool IsPresentationalInTable(AXObject* parent,
323 HTMLElement* current_element) { 322 HTMLElement* current_element) {
324 if (!current_element) 323 if (!current_element)
325 return false; 324 return false;
326 325
327 Node* parent_node = parent->GetNode(); 326 Node* parent_node = parent->GetNode();
328 if (!parent_node || !parent_node->IsHTMLElement()) 327 if (!parent_node || !parent_node->IsHTMLElement())
329 return false; 328 return false;
330 329
331 // AXTable determines the role as checking isTableXXX. 330 // AXTable determines the role as checking isTableXXX.
332 // If Table has explicit role including presentation, AXTable doesn't assign 331 // If Table has explicit role including presentation, AXTable doesn't assign
333 // implicit Role to a whole Table. That's why we should check it based on 332 // implicit Role to a whole Table. That's why we should check it based on
334 // node. 333 // node.
335 // Normal Table Tree is that 334 // Normal Table Tree is that
336 // cell(its role)-> tr(tr role)-> tfoot, tbody, thead(ignored role) -> 335 // cell(its role)-> tr(tr role)-> tfoot, tbody, thead(ignored role) ->
337 // table(table role). 336 // table(table role).
338 // If table has presentation role, it will be like 337 // If table has presentation role, it will be like
339 // cell(group)-> tr(unknown) -> tfoot, tbody, thead(ignored) -> 338 // cell(group)-> tr(unknown) -> tfoot, tbody, thead(ignored) ->
340 // table(presentation). 339 // table(presentation).
341 if (IsHTMLTableCellElement(*current_element) && 340 if (IsHTMLTableCellElement(*current_element) &&
342 isHTMLTableRowElement(*parent_node)) 341 isHTMLTableRowElement(*parent_node))
343 return parent->HasInheritedPresentationalRole(); 342 return parent->HasInheritedPresentationalRole();
344 343
345 if (isHTMLTableRowElement(*current_element) && 344 if (isHTMLTableRowElement(*current_element) &&
346 IsHTMLTableSectionElement(ToHTMLElement(*parent_node))) { 345 IsHTMLTableSectionElement(ToHTMLElement(*parent_node))) {
347 // Because TableSections have ignored role, presentation should be checked 346 // Because TableSections have ignored role, presentation should be checked
348 // with its parent node. 347 // with its parent node.
349 AXObjectImpl* table_object = parent->ParentObject(); 348 AXObject* table_object = parent->ParentObject();
350 Node* table_node = table_object ? table_object->GetNode() : 0; 349 Node* table_node = table_object ? table_object->GetNode() : 0;
351 return isHTMLTableElement(table_node) && 350 return isHTMLTableElement(table_node) &&
352 table_object->HasInheritedPresentationalRole(); 351 table_object->HasInheritedPresentationalRole();
353 } 352 }
354 return false; 353 return false;
355 } 354 }
356 355
357 static bool IsRequiredOwnedElement(AXObjectImpl* parent, 356 static bool IsRequiredOwnedElement(AXObject* parent,
358 AccessibilityRole current_role, 357 AccessibilityRole current_role,
359 HTMLElement* current_element) { 358 HTMLElement* current_element) {
360 Node* parent_node = parent->GetNode(); 359 Node* parent_node = parent->GetNode();
361 if (!parent_node || !parent_node->IsHTMLElement()) 360 if (!parent_node || !parent_node->IsHTMLElement())
362 return false; 361 return false;
363 362
364 if (current_role == kListItemRole) 363 if (current_role == kListItemRole)
365 return IsListElement(parent_node); 364 return IsListElement(parent_node);
366 if (current_role == kListMarkerRole) 365 if (current_role == kListMarkerRole)
367 return isHTMLLIElement(*parent_node); 366 return isHTMLLIElement(*parent_node);
368 if (current_role == kMenuItemCheckBoxRole || current_role == kMenuItemRole || 367 if (current_role == kMenuItemCheckBoxRole || current_role == kMenuItemRole ||
369 current_role == kMenuItemRadioRole) 368 current_role == kMenuItemRadioRole)
370 return isHTMLMenuElement(*parent_node); 369 return isHTMLMenuElement(*parent_node);
371 370
372 if (!current_element) 371 if (!current_element)
373 return false; 372 return false;
374 if (IsHTMLTableCellElement(*current_element)) 373 if (IsHTMLTableCellElement(*current_element))
375 return isHTMLTableRowElement(*parent_node); 374 return isHTMLTableRowElement(*parent_node);
376 if (isHTMLTableRowElement(*current_element)) 375 if (isHTMLTableRowElement(*current_element))
377 return IsHTMLTableSectionElement(ToHTMLElement(*parent_node)); 376 return IsHTMLTableSectionElement(ToHTMLElement(*parent_node));
378 377
379 // In case of ListboxRole and its child, ListBoxOptionRole, inheritance of 378 // In case of ListboxRole and its child, ListBoxOptionRole, inheritance of
380 // presentation role is handled in AXListBoxOption because ListBoxOption Role 379 // presentation role is handled in AXListBoxOption because ListBoxOption Role
381 // doesn't have any child. 380 // doesn't have any child.
382 // If it's just ignored because of presentation, we can't see any AX tree 381 // If it's just ignored because of presentation, we can't see any AX tree
383 // related to ListBoxOption. 382 // related to ListBoxOption.
384 return false; 383 return false;
385 } 384 }
386 385
387 const AXObjectImpl* AXNodeObject::InheritsPresentationalRoleFrom() const { 386 const AXObject* AXNodeObject::InheritsPresentationalRoleFrom() const {
388 // ARIA states if an item can get focus, it should not be presentational. 387 // ARIA states if an item can get focus, it should not be presentational.
389 if (CanSetFocusAttribute()) 388 if (CanSetFocusAttribute())
390 return 0; 389 return 0;
391 390
392 if (IsPresentational()) 391 if (IsPresentational())
393 return this; 392 return this;
394 393
395 // http://www.w3.org/TR/wai-aria/complete#presentation 394 // http://www.w3.org/TR/wai-aria/complete#presentation
396 // ARIA spec says that the user agent MUST apply an inherited role of 395 // ARIA spec says that the user agent MUST apply an inherited role of
397 // presentation 396 // presentation
398 // to any owned elements that do not have an explicit role defined. 397 // to any owned elements that do not have an explicit role defined.
399 if (AriaRoleAttribute() != kUnknownRole) 398 if (AriaRoleAttribute() != kUnknownRole)
400 return 0; 399 return 0;
401 400
402 AXObjectImpl* parent = ParentObject(); 401 AXObject* parent = ParentObject();
403 if (!parent) 402 if (!parent)
404 return 0; 403 return 0;
405 404
406 HTMLElement* element = nullptr; 405 HTMLElement* element = nullptr;
407 if (GetNode() && GetNode()->IsHTMLElement()) 406 if (GetNode() && GetNode()->IsHTMLElement())
408 element = ToHTMLElement(GetNode()); 407 element = ToHTMLElement(GetNode());
409 if (!parent->HasInheritedPresentationalRole()) { 408 if (!parent->HasInheritedPresentationalRole()) {
410 if (!GetLayoutObject() || !GetLayoutObject()->IsBoxModelObject()) 409 if (!GetLayoutObject() || !GetLayoutObject()->IsBoxModelObject())
411 return 0; 410 return 0;
412 411
(...skipping 304 matching lines...) Expand 10 before | Expand all | Expand 10 after
717 role = RemapAriaRoleDueToParent(role); 716 role = RemapAriaRoleDueToParent(role);
718 717
719 if (role) 718 if (role)
720 return role; 719 return role;
721 720
722 return kUnknownRole; 721 return kUnknownRole;
723 } 722 }
724 723
725 void AXNodeObject::AccessibilityChildrenFromAttribute( 724 void AXNodeObject::AccessibilityChildrenFromAttribute(
726 QualifiedName attr, 725 QualifiedName attr,
727 AXObjectImpl::AXObjectVector& children) const { 726 AXObject::AXObjectVector& children) const {
728 HeapVector<Member<Element>> elements; 727 HeapVector<Member<Element>> elements;
729 ElementsFromAttribute(elements, attr); 728 ElementsFromAttribute(elements, attr);
730 729
731 AXObjectCacheImpl& cache = AxObjectCache(); 730 AXObjectCacheImpl& cache = AxObjectCache();
732 for (const auto& element : elements) { 731 for (const auto& element : elements) {
733 if (AXObjectImpl* child = cache.GetOrCreate(element)) { 732 if (AXObject* child = cache.GetOrCreate(element)) {
734 // Only aria-labelledby and aria-describedby can target hidden elements. 733 // Only aria-labelledby and aria-describedby can target hidden elements.
735 if (child->AccessibilityIsIgnored() && attr != aria_labelledbyAttr && 734 if (child->AccessibilityIsIgnored() && attr != aria_labelledbyAttr &&
736 attr != aria_labeledbyAttr && attr != aria_describedbyAttr) { 735 attr != aria_labeledbyAttr && attr != aria_describedbyAttr) {
737 continue; 736 continue;
738 } 737 }
739 children.push_back(child); 738 children.push_back(child);
740 } 739 }
741 } 740 }
742 } 741 }
743 742
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
797 796
798 // An SVG root is focusable by default, but it's probably not interactive, so 797 // An SVG root is focusable by default, but it's probably not interactive, so
799 // don't include it. It can still be made accessible by giving it an ARIA 798 // don't include it. It can still be made accessible by giving it an ARIA
800 // role. 799 // role.
801 if (RoleValue() == kSVGRootRole) 800 if (RoleValue() == kSVGRootRole)
802 return false; 801 return false;
803 802
804 return true; 803 return true;
805 } 804 }
806 805
807 AXObjectImpl* AXNodeObject::MenuButtonForMenu() const { 806 AXObject* AXNodeObject::MenuButtonForMenu() const {
808 Element* menu_item = MenuItemElementForMenu(); 807 Element* menu_item = MenuItemElementForMenu();
809 808
810 if (menu_item) { 809 if (menu_item) {
811 // ARIA just has generic menu items. AppKit needs to know if this is a top 810 // ARIA just has generic menu items. AppKit needs to know if this is a top
812 // level items like MenuBarButton or MenuBarItem 811 // level items like MenuBarButton or MenuBarItem
813 AXObjectImpl* menu_item_ax = AxObjectCache().GetOrCreate(menu_item); 812 AXObject* menu_item_ax = AxObjectCache().GetOrCreate(menu_item);
814 if (menu_item_ax && menu_item_ax->IsMenuButton()) 813 if (menu_item_ax && menu_item_ax->IsMenuButton())
815 return menu_item_ax; 814 return menu_item_ax;
816 } 815 }
817 return 0; 816 return 0;
818 } 817 }
819 818
820 static Element* SiblingWithAriaRole(String role, Node* node) { 819 static Element* SiblingWithAriaRole(String role, Node* node) {
821 Node* parent = node->parentNode(); 820 Node* parent = node->parentNode();
822 if (!parent) 821 if (!parent)
823 return 0; 822 return 0;
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
873 AccessibilityRole role) const { 872 AccessibilityRole role) const {
874 // Some objects change their role based on their parent. 873 // Some objects change their role based on their parent.
875 // However, asking for the unignoredParent calls accessibilityIsIgnored(), 874 // However, asking for the unignoredParent calls accessibilityIsIgnored(),
876 // which can trigger a loop. While inside the call stack of creating an 875 // which can trigger a loop. While inside the call stack of creating an
877 // element, we need to avoid accessibilityIsIgnored(). 876 // element, we need to avoid accessibilityIsIgnored().
878 // https://bugs.webkit.org/show_bug.cgi?id=65174 877 // https://bugs.webkit.org/show_bug.cgi?id=65174
879 878
880 if (role != kListBoxOptionRole && role != kMenuItemRole) 879 if (role != kListBoxOptionRole && role != kMenuItemRole)
881 return role; 880 return role;
882 881
883 for (AXObjectImpl* parent = ParentObject(); 882 for (AXObject* parent = ParentObject();
884 parent && !parent->AccessibilityIsIgnored(); 883 parent && !parent->AccessibilityIsIgnored();
885 parent = parent->ParentObject()) { 884 parent = parent->ParentObject()) {
886 AccessibilityRole parent_aria_role = parent->AriaRoleAttribute(); 885 AccessibilityRole parent_aria_role = parent->AriaRoleAttribute();
887 886
888 // Selects and listboxes both have options as child roles, but they map to 887 // Selects and listboxes both have options as child roles, but they map to
889 // different roles within WebCore. 888 // different roles within WebCore.
890 if (role == kListBoxOptionRole && parent_aria_role == kMenuRole) 889 if (role == kListBoxOptionRole && parent_aria_role == kMenuRole)
891 return kMenuItemRole; 890 return kMenuItemRole;
892 // An aria "menuitem" may map to MenuButton or MenuItem depending on its 891 // An aria "menuitem" may map to MenuButton or MenuItem depending on its
893 // parent. 892 // parent.
(...skipping 11 matching lines...) Expand all
905 904
906 void AXNodeObject::Init() { 905 void AXNodeObject::Init() {
907 #if DCHECK_IS_ON() 906 #if DCHECK_IS_ON()
908 DCHECK(!initialized_); 907 DCHECK(!initialized_);
909 initialized_ = true; 908 initialized_ = true;
910 #endif 909 #endif
911 role_ = DetermineAccessibilityRole(); 910 role_ = DetermineAccessibilityRole();
912 } 911 }
913 912
914 void AXNodeObject::Detach() { 913 void AXNodeObject::Detach() {
915 AXObjectImpl::Detach(); 914 AXObject::Detach();
916 node_ = nullptr; 915 node_ = nullptr;
917 } 916 }
918 917
919 void AXNodeObject::GetSparseAXAttributes( 918 void AXNodeObject::GetSparseAXAttributes(
920 AXSparseAttributeClient& sparse_attribute_client) const { 919 AXSparseAttributeClient& sparse_attribute_client) const {
921 Node* node = this->GetNode(); 920 Node* node = this->GetNode();
922 if (!node || !node->IsElementNode()) 921 if (!node || !node->IsElementNode())
923 return; 922 return;
924 923
925 AXSparseAttributeSetterMap& ax_sparse_attribute_setter_map = 924 AXSparseAttributeSetterMap& ax_sparse_attribute_setter_map =
(...skipping 27 matching lines...) Expand all
953 bool AXNodeObject::IsAnchor() const { 952 bool AXNodeObject::IsAnchor() const {
954 return !IsNativeImage() && IsLink(); 953 return !IsNativeImage() && IsLink();
955 } 954 }
956 955
957 bool AXNodeObject::IsControl() const { 956 bool AXNodeObject::IsControl() const {
958 Node* node = this->GetNode(); 957 Node* node = this->GetNode();
959 if (!node) 958 if (!node)
960 return false; 959 return false;
961 960
962 return ((node->IsElementNode() && ToElement(node)->IsFormControlElement()) || 961 return ((node->IsElementNode() && ToElement(node)->IsFormControlElement()) ||
963 AXObjectImpl::IsARIAControl(AriaRoleAttribute())); 962 AXObject::IsARIAControl(AriaRoleAttribute()));
964 } 963 }
965 964
966 bool AXNodeObject::IsControllingVideoElement() const { 965 bool AXNodeObject::IsControllingVideoElement() const {
967 Node* node = this->GetNode(); 966 Node* node = this->GetNode();
968 if (!node) 967 if (!node)
969 return true; 968 return true;
970 969
971 return isHTMLVideoElement(ToParentMediaElement(node)); 970 return isHTMLVideoElement(ToParentMediaElement(node));
972 } 971 }
973 972
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after
1154 1153
1155 // Note: we can't call getNode()->willRespondToMouseClickEvents() because 1154 // Note: we can't call getNode()->willRespondToMouseClickEvents() because
1156 // that triggers a style recalc and can delete this. 1155 // that triggers a style recalc and can delete this.
1157 if (GetNode()->HasEventListeners(EventTypeNames::mouseup) || 1156 if (GetNode()->HasEventListeners(EventTypeNames::mouseup) ||
1158 GetNode()->HasEventListeners(EventTypeNames::mousedown) || 1157 GetNode()->HasEventListeners(EventTypeNames::mousedown) ||
1159 GetNode()->HasEventListeners(EventTypeNames::click) || 1158 GetNode()->HasEventListeners(EventTypeNames::click) ||
1160 GetNode()->HasEventListeners(EventTypeNames::DOMActivate)) 1159 GetNode()->HasEventListeners(EventTypeNames::DOMActivate))
1161 return true; 1160 return true;
1162 } 1161 }
1163 1162
1164 return AXObjectImpl::IsClickable(); 1163 return AXObject::IsClickable();
1165 } 1164 }
1166 1165
1167 bool AXNodeObject::IsEnabled() const { 1166 bool AXNodeObject::IsEnabled() const {
1168 if (IsDescendantOfDisabledNode()) 1167 if (IsDescendantOfDisabledNode())
1169 return false; 1168 return false;
1170 1169
1171 Node* node = this->GetNode(); 1170 Node* node = this->GetNode();
1172 if (!node || !node->IsElementNode()) 1171 if (!node || !node->IsElementNode())
1173 return true; 1172 return true;
1174 1173
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
1297 // for this information for all elements. 1296 // for this information for all elements.
1298 return !IsReadOnly(); 1297 return !IsReadOnly();
1299 } 1298 }
1300 1299
1301 bool AXNodeObject::CanSetSelectedAttribute() const { 1300 bool AXNodeObject::CanSetSelectedAttribute() const {
1302 // ARIA list box options can be selected if they are children of an element 1301 // ARIA list box options can be selected if they are children of an element
1303 // with an aria-activedescendant attribute. 1302 // with an aria-activedescendant attribute.
1304 if (AriaRoleAttribute() == kListBoxOptionRole && 1303 if (AriaRoleAttribute() == kListBoxOptionRole &&
1305 AncestorExposesActiveDescendant()) 1304 AncestorExposesActiveDescendant())
1306 return true; 1305 return true;
1307 return AXObjectImpl::CanSetSelectedAttribute(); 1306 return AXObject::CanSetSelectedAttribute();
1308 } 1307 }
1309 1308
1310 bool AXNodeObject::CanvasHasFallbackContent() const { 1309 bool AXNodeObject::CanvasHasFallbackContent() const {
1311 Node* node = this->GetNode(); 1310 Node* node = this->GetNode();
1312 if (!isHTMLCanvasElement(node)) 1311 if (!isHTMLCanvasElement(node))
1313 return false; 1312 return false;
1314 1313
1315 // If it has any children that are elements, we'll assume it might be fallback 1314 // If it has any children that are elements, we'll assume it might be fallback
1316 // content. If it has no children or its only children are not elements 1315 // content. If it has no children or its only children are not elements
1317 // (e.g. just text nodes), it doesn't have fallback content. 1316 // (e.g. just text nodes), it doesn't have fallback content.
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
1373 return 1; 1372 return 1;
1374 } 1373 }
1375 1374
1376 // Only tree item will calculate its level through the DOM currently. 1375 // Only tree item will calculate its level through the DOM currently.
1377 if (RoleValue() != kTreeItemRole) 1376 if (RoleValue() != kTreeItemRole)
1378 return 0; 1377 return 0;
1379 1378
1380 // Hierarchy leveling starts at 1, to match the aria-level spec. 1379 // Hierarchy leveling starts at 1, to match the aria-level spec.
1381 // We measure tree hierarchy by the number of groups that the item is within. 1380 // We measure tree hierarchy by the number of groups that the item is within.
1382 unsigned level = 1; 1381 unsigned level = 1;
1383 for (AXObjectImpl* parent = ParentObject(); parent; 1382 for (AXObject* parent = ParentObject(); parent;
1384 parent = parent->ParentObject()) { 1383 parent = parent->ParentObject()) {
1385 AccessibilityRole parent_role = parent->RoleValue(); 1384 AccessibilityRole parent_role = parent->RoleValue();
1386 if (parent_role == kGroupRole) 1385 if (parent_role == kGroupRole)
1387 level++; 1386 level++;
1388 else if (parent_role == kTreeRole) 1387 else if (parent_role == kTreeRole)
1389 break; 1388 break;
1390 } 1389 }
1391 1390
1392 return level; 1391 return level;
1393 } 1392 }
(...skipping 30 matching lines...) Expand all
1424 marker_ranges.push_back( 1423 marker_ranges.push_back(
1425 AXRange(marker->StartOffset(), marker->EndOffset())); 1424 AXRange(marker->StartOffset(), marker->EndOffset()));
1426 break; 1425 break;
1427 case DocumentMarker::kComposition: 1426 case DocumentMarker::kComposition:
1428 // No need for accessibility to know about these marker types. 1427 // No need for accessibility to know about these marker types.
1429 break; 1428 break;
1430 } 1429 }
1431 } 1430 }
1432 } 1431 }
1433 1432
1434 AXObjectImpl* AXNodeObject::InPageLinkTarget() const { 1433 AXObject* AXNodeObject::InPageLinkTarget() const {
1435 if (!node_ || !isHTMLAnchorElement(node_) || !GetDocument()) 1434 if (!node_ || !isHTMLAnchorElement(node_) || !GetDocument())
1436 return AXObjectImpl::InPageLinkTarget(); 1435 return AXObject::InPageLinkTarget();
1437 1436
1438 HTMLAnchorElement* anchor = toHTMLAnchorElement(node_); 1437 HTMLAnchorElement* anchor = toHTMLAnchorElement(node_);
1439 DCHECK(anchor); 1438 DCHECK(anchor);
1440 KURL link_url = anchor->Href(); 1439 KURL link_url = anchor->Href();
1441 if (!link_url.IsValid()) 1440 if (!link_url.IsValid())
1442 return AXObjectImpl::InPageLinkTarget(); 1441 return AXObject::InPageLinkTarget();
1443 String fragment = link_url.FragmentIdentifier(); 1442 String fragment = link_url.FragmentIdentifier();
1444 if (fragment.IsEmpty()) 1443 if (fragment.IsEmpty())
1445 return AXObjectImpl::InPageLinkTarget(); 1444 return AXObject::InPageLinkTarget();
1446 1445
1447 KURL document_url = GetDocument()->Url(); 1446 KURL document_url = GetDocument()->Url();
1448 if (!document_url.IsValid() || 1447 if (!document_url.IsValid() ||
1449 !EqualIgnoringFragmentIdentifier(document_url, link_url)) { 1448 !EqualIgnoringFragmentIdentifier(document_url, link_url)) {
1450 return AXObjectImpl::InPageLinkTarget(); 1449 return AXObject::InPageLinkTarget();
1451 } 1450 }
1452 1451
1453 TreeScope& tree_scope = anchor->GetTreeScope(); 1452 TreeScope& tree_scope = anchor->GetTreeScope();
1454 Element* target = tree_scope.FindAnchor(fragment); 1453 Element* target = tree_scope.FindAnchor(fragment);
1455 if (!target) 1454 if (!target)
1456 return AXObjectImpl::InPageLinkTarget(); 1455 return AXObject::InPageLinkTarget();
1457 // If the target is not in the accessibility tree, get the first unignored 1456 // If the target is not in the accessibility tree, get the first unignored
1458 // sibling. 1457 // sibling.
1459 return AxObjectCache().FirstAccessibleObjectFromNode(target); 1458 return AxObjectCache().FirstAccessibleObjectFromNode(target);
1460 } 1459 }
1461 1460
1462 AccessibilityOrientation AXNodeObject::Orientation() const { 1461 AccessibilityOrientation AXNodeObject::Orientation() const {
1463 const AtomicString& aria_orientation = 1462 const AtomicString& aria_orientation =
1464 GetAOMPropertyOrARIAAttribute(AOMStringProperty::kOrientation); 1463 GetAOMPropertyOrARIAAttribute(AOMStringProperty::kOrientation);
1465 AccessibilityOrientation orientation = kAccessibilityOrientationUndefined; 1464 AccessibilityOrientation orientation = kAccessibilityOrientationUndefined;
1466 if (EqualIgnoringASCIICase(aria_orientation, "horizontal")) 1465 if (EqualIgnoringASCIICase(aria_orientation, "horizontal"))
(...skipping 17 matching lines...) Expand all
1484 case kTabListRole: 1483 case kTabListRole:
1485 case kToolbarRole: 1484 case kToolbarRole:
1486 if (orientation == kAccessibilityOrientationUndefined) 1485 if (orientation == kAccessibilityOrientationUndefined)
1487 orientation = kAccessibilityOrientationHorizontal; 1486 orientation = kAccessibilityOrientationHorizontal;
1488 1487
1489 return orientation; 1488 return orientation;
1490 case kRadioGroupRole: 1489 case kRadioGroupRole:
1491 case kTreeGridRole: 1490 case kTreeGridRole:
1492 return orientation; 1491 return orientation;
1493 default: 1492 default:
1494 return AXObjectImpl::Orientation(); 1493 return AXObject::Orientation();
1495 } 1494 }
1496 } 1495 }
1497 1496
1498 AXObjectImpl::AXObjectVector AXNodeObject::RadioButtonsInGroup() const { 1497 AXObject::AXObjectVector AXNodeObject::RadioButtonsInGroup() const {
1499 AXObjectVector radio_buttons; 1498 AXObjectVector radio_buttons;
1500 if (!node_ || RoleValue() != kRadioButtonRole) 1499 if (!node_ || RoleValue() != kRadioButtonRole)
1501 return radio_buttons; 1500 return radio_buttons;
1502 1501
1503 if (isHTMLInputElement(node_)) { 1502 if (isHTMLInputElement(node_)) {
1504 HTMLInputElement* radio_button = toHTMLInputElement(node_); 1503 HTMLInputElement* radio_button = toHTMLInputElement(node_);
1505 HeapVector<Member<HTMLInputElement>> html_radio_buttons = 1504 HeapVector<Member<HTMLInputElement>> html_radio_buttons =
1506 FindAllRadioButtonsWithSameName(radio_button); 1505 FindAllRadioButtonsWithSameName(radio_button);
1507 for (size_t i = 0; i < html_radio_buttons.size(); ++i) { 1506 for (size_t i = 0; i < html_radio_buttons.size(); ++i) {
1508 AXObjectImpl* ax_radio_button = 1507 AXObject* ax_radio_button =
1509 AxObjectCache().GetOrCreate(html_radio_buttons[i]); 1508 AxObjectCache().GetOrCreate(html_radio_buttons[i]);
1510 if (ax_radio_button) 1509 if (ax_radio_button)
1511 radio_buttons.push_back(ax_radio_button); 1510 radio_buttons.push_back(ax_radio_button);
1512 } 1511 }
1513 return radio_buttons; 1512 return radio_buttons;
1514 } 1513 }
1515 1514
1516 // If the immediate parent is a radio group, return all its children that are 1515 // If the immediate parent is a radio group, return all its children that are
1517 // radio buttons. 1516 // radio buttons.
1518 AXObjectImpl* parent = ParentObject(); 1517 AXObject* parent = ParentObject();
1519 if (parent && parent->RoleValue() == kRadioGroupRole) { 1518 if (parent && parent->RoleValue() == kRadioGroupRole) {
1520 for (size_t i = 0; i < parent->Children().size(); ++i) { 1519 for (size_t i = 0; i < parent->Children().size(); ++i) {
1521 AXObjectImpl* child = parent->Children()[i]; 1520 AXObject* child = parent->Children()[i];
1522 DCHECK(child); 1521 DCHECK(child);
1523 if (child->RoleValue() == kRadioButtonRole && 1522 if (child->RoleValue() == kRadioButtonRole &&
1524 !child->AccessibilityIsIgnored()) { 1523 !child->AccessibilityIsIgnored()) {
1525 radio_buttons.push_back(child); 1524 radio_buttons.push_back(child);
1526 } 1525 }
1527 } 1526 }
1528 } 1527 }
1529 1528
1530 return radio_buttons; 1529 return radio_buttons;
1531 } 1530 }
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
1573 return ToTextControlElement(*node).value(); 1572 return ToTextControlElement(*node).value();
1574 1573
1575 if (!node->IsElementNode()) 1574 if (!node->IsElementNode())
1576 return String(); 1575 return String();
1577 1576
1578 return ToElement(node)->innerText(); 1577 return ToElement(node)->innerText();
1579 } 1578 }
1580 1579
1581 RGBA32 AXNodeObject::ColorValue() const { 1580 RGBA32 AXNodeObject::ColorValue() const {
1582 if (!isHTMLInputElement(GetNode()) || !IsColorWell()) 1581 if (!isHTMLInputElement(GetNode()) || !IsColorWell())
1583 return AXObjectImpl::ColorValue(); 1582 return AXObject::ColorValue();
1584 1583
1585 HTMLInputElement* input = toHTMLInputElement(GetNode()); 1584 HTMLInputElement* input = toHTMLInputElement(GetNode());
1586 const AtomicString& type = input->getAttribute(typeAttr); 1585 const AtomicString& type = input->getAttribute(typeAttr);
1587 if (!EqualIgnoringASCIICase(type, "color")) 1586 if (!EqualIgnoringASCIICase(type, "color"))
1588 return AXObjectImpl::ColorValue(); 1587 return AXObject::ColorValue();
1589 1588
1590 // HTMLInputElement::value always returns a string parseable by Color. 1589 // HTMLInputElement::value always returns a string parseable by Color.
1591 Color color; 1590 Color color;
1592 bool success = color.SetFromString(input->value()); 1591 bool success = color.SetFromString(input->value());
1593 DCHECK(success); 1592 DCHECK(success);
1594 return color.Rgb(); 1593 return color.Rgb();
1595 } 1594 }
1596 1595
1597 AriaCurrentState AXNodeObject::GetAriaCurrentState() const { 1596 AriaCurrentState AXNodeObject::GetAriaCurrentState() const {
1598 const AtomicString& attribute_value = 1597 const AtomicString& attribute_value =
(...skipping 12 matching lines...) Expand all
1611 if (EqualIgnoringASCIICase(attribute_value, "location")) 1610 if (EqualIgnoringASCIICase(attribute_value, "location"))
1612 return kAriaCurrentStateLocation; 1611 return kAriaCurrentStateLocation;
1613 if (EqualIgnoringASCIICase(attribute_value, "date")) 1612 if (EqualIgnoringASCIICase(attribute_value, "date"))
1614 return kAriaCurrentStateDate; 1613 return kAriaCurrentStateDate;
1615 if (EqualIgnoringASCIICase(attribute_value, "time")) 1614 if (EqualIgnoringASCIICase(attribute_value, "time"))
1616 return kAriaCurrentStateTime; 1615 return kAriaCurrentStateTime;
1617 // An unknown value should return true. 1616 // An unknown value should return true.
1618 if (!attribute_value.IsEmpty()) 1617 if (!attribute_value.IsEmpty())
1619 return kAriaCurrentStateTrue; 1618 return kAriaCurrentStateTrue;
1620 1619
1621 return AXObjectImpl::GetAriaCurrentState(); 1620 return AXObject::GetAriaCurrentState();
1622 } 1621 }
1623 1622
1624 InvalidState AXNodeObject::GetInvalidState() const { 1623 InvalidState AXNodeObject::GetInvalidState() const {
1625 const AtomicString& attribute_value = 1624 const AtomicString& attribute_value =
1626 GetAOMPropertyOrARIAAttribute(AOMStringProperty::kInvalid); 1625 GetAOMPropertyOrARIAAttribute(AOMStringProperty::kInvalid);
1627 if (EqualIgnoringASCIICase(attribute_value, "false")) 1626 if (EqualIgnoringASCIICase(attribute_value, "false"))
1628 return kInvalidStateFalse; 1627 return kInvalidStateFalse;
1629 if (EqualIgnoringASCIICase(attribute_value, "true")) 1628 if (EqualIgnoringASCIICase(attribute_value, "true"))
1630 return kInvalidStateTrue; 1629 return kInvalidStateTrue;
1631 if (EqualIgnoringASCIICase(attribute_value, "spelling")) 1630 if (EqualIgnoringASCIICase(attribute_value, "spelling"))
1632 return kInvalidStateSpelling; 1631 return kInvalidStateSpelling;
1633 if (EqualIgnoringASCIICase(attribute_value, "grammar")) 1632 if (EqualIgnoringASCIICase(attribute_value, "grammar"))
1634 return kInvalidStateGrammar; 1633 return kInvalidStateGrammar;
1635 // A yet unknown value. 1634 // A yet unknown value.
1636 if (!attribute_value.IsEmpty()) 1635 if (!attribute_value.IsEmpty())
1637 return kInvalidStateOther; 1636 return kInvalidStateOther;
1638 1637
1639 if (GetNode() && GetNode()->IsElementNode() && 1638 if (GetNode() && GetNode()->IsElementNode() &&
1640 ToElement(GetNode())->IsFormControlElement()) { 1639 ToElement(GetNode())->IsFormControlElement()) {
1641 HTMLFormControlElement* element = ToHTMLFormControlElement(GetNode()); 1640 HTMLFormControlElement* element = ToHTMLFormControlElement(GetNode());
1642 HeapVector<Member<HTMLFormControlElement>> invalid_controls; 1641 HeapVector<Member<HTMLFormControlElement>> invalid_controls;
1643 bool is_invalid = !element->checkValidity(&invalid_controls, 1642 bool is_invalid = !element->checkValidity(&invalid_controls,
1644 kCheckValidityDispatchNoEvent); 1643 kCheckValidityDispatchNoEvent);
1645 return is_invalid ? kInvalidStateTrue : kInvalidStateFalse; 1644 return is_invalid ? kInvalidStateTrue : kInvalidStateFalse;
1646 } 1645 }
1647 1646
1648 return AXObjectImpl::GetInvalidState(); 1647 return AXObject::GetInvalidState();
1649 } 1648 }
1650 1649
1651 int AXNodeObject::PosInSet() const { 1650 int AXNodeObject::PosInSet() const {
1652 if (SupportsSetSizeAndPosInSet()) { 1651 if (SupportsSetSizeAndPosInSet()) {
1653 String pos_in_set_str = GetAttribute(aria_posinsetAttr); 1652 String pos_in_set_str = GetAttribute(aria_posinsetAttr);
1654 if (!pos_in_set_str.IsEmpty()) { 1653 if (!pos_in_set_str.IsEmpty()) {
1655 int pos_in_set = pos_in_set_str.ToInt(); 1654 int pos_in_set = pos_in_set_str.ToInt();
1656 if (pos_in_set > 0) 1655 if (pos_in_set > 0)
1657 return pos_in_set; 1656 return pos_in_set;
1658 return 1; 1657 return 1;
1659 } 1658 }
1660 1659
1661 return AXObjectImpl::IndexInParent() + 1; 1660 return AXObject::IndexInParent() + 1;
1662 } 1661 }
1663 1662
1664 return 0; 1663 return 0;
1665 } 1664 }
1666 1665
1667 int AXNodeObject::SetSize() const { 1666 int AXNodeObject::SetSize() const {
1668 if (SupportsSetSizeAndPosInSet()) { 1667 if (SupportsSetSizeAndPosInSet()) {
1669 String set_size_str = GetAttribute(aria_setsizeAttr); 1668 String set_size_str = GetAttribute(aria_setsizeAttr);
1670 if (!set_size_str.IsEmpty()) { 1669 if (!set_size_str.IsEmpty()) {
1671 int set_size = set_size_str.ToInt(); 1670 int set_size = set_size_str.ToInt();
(...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after
1930 1929
1931 return String(); 1930 return String();
1932 } 1931 }
1933 1932
1934 String AXNodeObject::TextFromDescendants(AXObjectSet& visited, 1933 String AXNodeObject::TextFromDescendants(AXObjectSet& visited,
1935 bool recursive) const { 1934 bool recursive) const {
1936 if (!CanHaveChildren() && recursive) 1935 if (!CanHaveChildren() && recursive)
1937 return String(); 1936 return String();
1938 1937
1939 StringBuilder accumulated_text; 1938 StringBuilder accumulated_text;
1940 AXObjectImpl* previous = nullptr; 1939 AXObject* previous = nullptr;
1941 1940
1942 AXObjectVector children; 1941 AXObjectVector children;
1943 1942
1944 HeapVector<Member<AXObjectImpl>> owned_children; 1943 HeapVector<Member<AXObject>> owned_children;
1945 ComputeAriaOwnsChildren(owned_children); 1944 ComputeAriaOwnsChildren(owned_children);
1946 for (AXObjectImpl* obj = RawFirstChild(); obj; obj = obj->RawNextSibling()) { 1945 for (AXObject* obj = RawFirstChild(); obj; obj = obj->RawNextSibling()) {
1947 if (!AxObjectCache().IsAriaOwned(obj)) 1946 if (!AxObjectCache().IsAriaOwned(obj))
1948 children.push_back(obj); 1947 children.push_back(obj);
1949 } 1948 }
1950 for (const auto& owned_child : owned_children) 1949 for (const auto& owned_child : owned_children)
1951 children.push_back(owned_child); 1950 children.push_back(owned_child);
1952 1951
1953 for (AXObjectImpl* child : children) { 1952 for (AXObject* child : children) {
1954 // Don't recurse into children that are explicitly marked as aria-hidden. 1953 // Don't recurse into children that are explicitly marked as aria-hidden.
1955 // Note that we don't call isInertOrAriaHidden because that would return 1954 // Note that we don't call isInertOrAriaHidden because that would return
1956 // true if any ancestor is hidden, but we need to be able to compute the 1955 // true if any ancestor is hidden, but we need to be able to compute the
1957 // accessible name of object inside hidden subtrees (for example, if 1956 // accessible name of object inside hidden subtrees (for example, if
1958 // aria-labelledby points to an object that's hidden). 1957 // aria-labelledby points to an object that's hidden).
1959 if (EqualIgnoringASCIICase(child->GetAttribute(aria_hiddenAttr), "true")) 1958 if (EqualIgnoringASCIICase(child->GetAttribute(aria_hiddenAttr), "true"))
1960 continue; 1959 continue;
1961 1960
1962 // If we're going between two layoutObjects that are in separate 1961 // If we're going between two layoutObjects that are in separate
1963 // LayoutBoxes, add whitespace if it wasn't there already. Intuitively if 1962 // LayoutBoxes, add whitespace if it wasn't there already. Intuitively if
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
2020 ToLabelableElement(html_element)->labels()->length() > 0) 2019 ToLabelableElement(html_element)->labels()->length() > 0)
2021 return true; 2020 return true;
2022 } 2021 }
2023 2022
2024 return false; 2023 return false;
2025 } 2024 }
2026 2025
2027 bool AXNodeObject::NameFromContents() const { 2026 bool AXNodeObject::NameFromContents() const {
2028 Node* node = GetNode(); 2027 Node* node = GetNode();
2029 if (!node || !node->IsElementNode()) 2028 if (!node || !node->IsElementNode())
2030 return AXObjectImpl::NameFromContents(); 2029 return AXObject::NameFromContents();
2031 // AXObjectImpl::nameFromContents determines whether an element should take 2030 // AXObject::nameFromContents determines whether an element should take its
2032 // its name from its descendant contents based on role. However, <select> is a 2031 // name from its descendant contents based on role. However, <select> is a
2033 // special case, as unlike a typical pop-up button it contains its own pop-up 2032 // special case, as unlike a typical pop-up button it contains its own pop-up
2034 // menu's contents, which should not be used as the name. 2033 // menu's contents, which should not be used as the name.
2035 if (isHTMLSelectElement(node)) 2034 if (isHTMLSelectElement(node))
2036 return false; 2035 return false;
2037 return AXObjectImpl::NameFromContents(); 2036 return AXObject::NameFromContents();
2038 } 2037 }
2039 2038
2040 void AXNodeObject::GetRelativeBounds( 2039 void AXNodeObject::GetRelativeBounds(
2041 AXObjectImpl** out_container, 2040 AXObject** out_container,
2042 FloatRect& out_bounds_in_container, 2041 FloatRect& out_bounds_in_container,
2043 SkMatrix44& out_container_transform) const { 2042 SkMatrix44& out_container_transform) const {
2044 if (LayoutObjectForRelativeBounds()) { 2043 if (LayoutObjectForRelativeBounds()) {
2045 AXObjectImpl::GetRelativeBounds(out_container, out_bounds_in_container, 2044 AXObject::GetRelativeBounds(out_container, out_bounds_in_container,
2046 out_container_transform); 2045 out_container_transform);
2047 return; 2046 return;
2048 } 2047 }
2049 2048
2050 *out_container = nullptr; 2049 *out_container = nullptr;
2051 out_bounds_in_container = FloatRect(); 2050 out_bounds_in_container = FloatRect();
2052 out_container_transform.setIdentity(); 2051 out_container_transform.setIdentity();
2053 2052
2054 // First check if it has explicit bounds, for example if this element is tied 2053 // First check if it has explicit bounds, for example if this element is tied
2055 // to a canvas path. When explicit coordinates are provided, the ID of the 2054 // to a canvas path. When explicit coordinates are provided, the ID of the
2056 // explicit container element that the coordinates are relative to must be 2055 // explicit container element that the coordinates are relative to must be
2057 // provided too. 2056 // provided too.
2058 if (!explicit_element_rect_.IsEmpty()) { 2057 if (!explicit_element_rect_.IsEmpty()) {
2059 *out_container = AxObjectCache().ObjectFromAXID(explicit_container_id_); 2058 *out_container = AxObjectCache().ObjectFromAXID(explicit_container_id_);
2060 if (*out_container) { 2059 if (*out_container) {
2061 out_bounds_in_container = FloatRect(explicit_element_rect_); 2060 out_bounds_in_container = FloatRect(explicit_element_rect_);
2062 return; 2061 return;
2063 } 2062 }
2064 } 2063 }
2065 2064
2066 // If it's in a canvas but doesn't have an explicit rect, get the bounding 2065 // If it's in a canvas but doesn't have an explicit rect, get the bounding
2067 // rect of its children. 2066 // rect of its children.
2068 if (GetNode()->parentElement()->IsInCanvasSubtree()) { 2067 if (GetNode()->parentElement()->IsInCanvasSubtree()) {
2069 Vector<FloatRect> rects; 2068 Vector<FloatRect> rects;
2070 for (Node& child : NodeTraversal::ChildrenOf(*GetNode())) { 2069 for (Node& child : NodeTraversal::ChildrenOf(*GetNode())) {
2071 if (child.IsHTMLElement()) { 2070 if (child.IsHTMLElement()) {
2072 if (AXObjectImpl* obj = AxObjectCache().Get(&child)) { 2071 if (AXObject* obj = AxObjectCache().Get(&child)) {
2073 AXObjectImpl* container; 2072 AXObject* container;
2074 FloatRect bounds; 2073 FloatRect bounds;
2075 obj->GetRelativeBounds(&container, bounds, out_container_transform); 2074 obj->GetRelativeBounds(&container, bounds, out_container_transform);
2076 if (container) { 2075 if (container) {
2077 *out_container = container; 2076 *out_container = container;
2078 rects.push_back(bounds); 2077 rects.push_back(bounds);
2079 } 2078 }
2080 } 2079 }
2081 } 2080 }
2082 } 2081 }
2083 2082
2084 if (*out_container) { 2083 if (*out_container) {
2085 out_bounds_in_container = UnionRect(rects); 2084 out_bounds_in_container = UnionRect(rects);
2086 return; 2085 return;
2087 } 2086 }
2088 } 2087 }
2089 2088
2090 // If this object doesn't have an explicit element rect or computable from its 2089 // If this object doesn't have an explicit element rect or computable from its
2091 // children, for now, let's return the position of the ancestor that does have 2090 // children, for now, let's return the position of the ancestor that does have
2092 // a position, and make it the width of that parent, and about the height of a 2091 // a position, and make it the width of that parent, and about the height of a
2093 // line of text, so that it's clear the object is a child of the parent. 2092 // line of text, so that it's clear the object is a child of the parent.
2094 for (AXObjectImpl* position_provider = ParentObject(); position_provider; 2093 for (AXObject* position_provider = ParentObject(); position_provider;
2095 position_provider = position_provider->ParentObject()) { 2094 position_provider = position_provider->ParentObject()) {
2096 if (position_provider->IsAXLayoutObject()) { 2095 if (position_provider->IsAXLayoutObject()) {
2097 position_provider->GetRelativeBounds( 2096 position_provider->GetRelativeBounds(
2098 out_container, out_bounds_in_container, out_container_transform); 2097 out_container, out_bounds_in_container, out_container_transform);
2099 if (*out_container) 2098 if (*out_container)
2100 out_bounds_in_container.SetSize( 2099 out_bounds_in_container.SetSize(
2101 FloatSize(out_bounds_in_container.Width(), 2100 FloatSize(out_bounds_in_container.Width(),
2102 std::min(10.0f, out_bounds_in_container.Height()))); 2101 std::min(10.0f, out_bounds_in_container.Height())));
2103 break; 2102 break;
2104 } 2103 }
(...skipping 10 matching lines...) Expand all
2115 // <option>. 2114 // <option>.
2116 if (isHTMLOptionElement(node)) 2115 if (isHTMLOptionElement(node))
2117 parent_node = toHTMLOptionElement(node)->OwnerSelectElement(); 2116 parent_node = toHTMLOptionElement(node)->OwnerSelectElement();
2118 2117
2119 if (!parent_node) 2118 if (!parent_node)
2120 parent_node = node->parentNode(); 2119 parent_node = node->parentNode();
2121 2120
2122 return parent_node; 2121 return parent_node;
2123 } 2122 }
2124 2123
2125 AXObjectImpl* AXNodeObject::ComputeParent() const { 2124 AXObject* AXNodeObject::ComputeParent() const {
2126 DCHECK(!IsDetached()); 2125 DCHECK(!IsDetached());
2127 if (Node* parent_node = GetParentNodeForComputeParent(GetNode())) 2126 if (Node* parent_node = GetParentNodeForComputeParent(GetNode()))
2128 return AxObjectCache().GetOrCreate(parent_node); 2127 return AxObjectCache().GetOrCreate(parent_node);
2129 2128
2130 return nullptr; 2129 return nullptr;
2131 } 2130 }
2132 2131
2133 AXObjectImpl* AXNodeObject::ComputeParentIfExists() const { 2132 AXObject* AXNodeObject::ComputeParentIfExists() const {
2134 if (Node* parent_node = GetParentNodeForComputeParent(GetNode())) 2133 if (Node* parent_node = GetParentNodeForComputeParent(GetNode()))
2135 return AxObjectCache().Get(parent_node); 2134 return AxObjectCache().Get(parent_node);
2136 2135
2137 return nullptr; 2136 return nullptr;
2138 } 2137 }
2139 2138
2140 AXObjectImpl* AXNodeObject::RawFirstChild() const { 2139 AXObject* AXNodeObject::RawFirstChild() const {
2141 if (!GetNode()) 2140 if (!GetNode())
2142 return 0; 2141 return 0;
2143 2142
2144 Node* first_child = GetNode()->firstChild(); 2143 Node* first_child = GetNode()->firstChild();
2145 2144
2146 if (!first_child) 2145 if (!first_child)
2147 return 0; 2146 return 0;
2148 2147
2149 return AxObjectCache().GetOrCreate(first_child); 2148 return AxObjectCache().GetOrCreate(first_child);
2150 } 2149 }
2151 2150
2152 AXObjectImpl* AXNodeObject::RawNextSibling() const { 2151 AXObject* AXNodeObject::RawNextSibling() const {
2153 if (!GetNode()) 2152 if (!GetNode())
2154 return 0; 2153 return 0;
2155 2154
2156 Node* next_sibling = GetNode()->nextSibling(); 2155 Node* next_sibling = GetNode()->nextSibling();
2157 if (!next_sibling) 2156 if (!next_sibling)
2158 return 0; 2157 return 0;
2159 2158
2160 return AxObjectCache().GetOrCreate(next_sibling); 2159 return AxObjectCache().GetOrCreate(next_sibling);
2161 } 2160 }
2162 2161
2163 void AXNodeObject::AddChildren() { 2162 void AXNodeObject::AddChildren() {
2164 DCHECK(!IsDetached()); 2163 DCHECK(!IsDetached());
2165 // If the need to add more children in addition to existing children arises, 2164 // If the need to add more children in addition to existing children arises,
2166 // childrenChanged should have been called, leaving the object with no 2165 // childrenChanged should have been called, leaving the object with no
2167 // children. 2166 // children.
2168 DCHECK(!have_children_); 2167 DCHECK(!have_children_);
2169 2168
2170 if (!node_) 2169 if (!node_)
2171 return; 2170 return;
2172 2171
2173 have_children_ = true; 2172 have_children_ = true;
2174 2173
2175 // The only time we add children from the DOM tree to a node with a 2174 // The only time we add children from the DOM tree to a node with a
2176 // layoutObject is when it's a canvas. 2175 // layoutObject is when it's a canvas.
2177 if (GetLayoutObject() && !isHTMLCanvasElement(*node_)) 2176 if (GetLayoutObject() && !isHTMLCanvasElement(*node_))
2178 return; 2177 return;
2179 2178
2180 HeapVector<Member<AXObjectImpl>> owned_children; 2179 HeapVector<Member<AXObject>> owned_children;
2181 ComputeAriaOwnsChildren(owned_children); 2180 ComputeAriaOwnsChildren(owned_children);
2182 2181
2183 for (Node& child : NodeTraversal::ChildrenOf(*node_)) { 2182 for (Node& child : NodeTraversal::ChildrenOf(*node_)) {
2184 AXObjectImpl* child_obj = AxObjectCache().GetOrCreate(&child); 2183 AXObject* child_obj = AxObjectCache().GetOrCreate(&child);
2185 if (child_obj && !AxObjectCache().IsAriaOwned(child_obj)) 2184 if (child_obj && !AxObjectCache().IsAriaOwned(child_obj))
2186 AddChild(child_obj); 2185 AddChild(child_obj);
2187 } 2186 }
2188 2187
2189 for (const auto& owned_child : owned_children) 2188 for (const auto& owned_child : owned_children)
2190 AddChild(owned_child); 2189 AddChild(owned_child);
2191 2190
2192 for (const auto& child : children_) 2191 for (const auto& child : children_)
2193 child->SetParent(this); 2192 child->SetParent(this);
2194 } 2193 }
2195 2194
2196 void AXNodeObject::AddChild(AXObjectImpl* child) { 2195 void AXNodeObject::AddChild(AXObject* child) {
2197 InsertChild(child, children_.size()); 2196 InsertChild(child, children_.size());
2198 } 2197 }
2199 2198
2200 void AXNodeObject::InsertChild(AXObjectImpl* child, unsigned index) { 2199 void AXNodeObject::InsertChild(AXObject* child, unsigned index) {
2201 if (!child) 2200 if (!child)
2202 return; 2201 return;
2203 2202
2204 // If the parent is asking for this child's children, then either it's the 2203 // If the parent is asking for this child's children, then either it's the
2205 // first time (and clearing is a no-op), or its visibility has changed. In the 2204 // first time (and clearing is a no-op), or its visibility has changed. In the
2206 // latter case, this child may have a stale child cached. This can prevent 2205 // latter case, this child may have a stale child cached. This can prevent
2207 // aria-hidden changes from working correctly. Hence, whenever a parent is 2206 // aria-hidden changes from working correctly. Hence, whenever a parent is
2208 // getting children, ensure data is not stale. 2207 // getting children, ensure data is not stale.
2209 child->ClearChildren(); 2208 child->ClearChildren();
2210 2209
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
2266 if (isHTMLInputElement(*node)) { 2265 if (isHTMLInputElement(*node)) {
2267 HTMLInputElement& input = toHTMLInputElement(*node); 2266 HTMLInputElement& input = toHTMLInputElement(*node);
2268 if (!input.IsDisabledFormControl() && 2267 if (!input.IsDisabledFormControl() &&
2269 (IsCheckboxOrRadio() || input.IsTextButton() || 2268 (IsCheckboxOrRadio() || input.IsTextButton() ||
2270 input.type() == InputTypeNames::file)) 2269 input.type() == InputTypeNames::file))
2271 return &input; 2270 return &input;
2272 } else if (isHTMLButtonElement(*node)) { 2271 } else if (isHTMLButtonElement(*node)) {
2273 return ToElement(node); 2272 return ToElement(node);
2274 } 2273 }
2275 2274
2276 if (AXObjectImpl::IsARIAInput(AriaRoleAttribute())) 2275 if (AXObject::IsARIAInput(AriaRoleAttribute()))
2277 return ToElement(node); 2276 return ToElement(node);
2278 2277
2279 if (IsImageButton()) 2278 if (IsImageButton())
2280 return ToElement(node); 2279 return ToElement(node);
2281 2280
2282 if (isHTMLSelectElement(*node)) 2281 if (isHTMLSelectElement(*node))
2283 return ToElement(node); 2282 return ToElement(node);
2284 2283
2285 switch (RoleValue()) { 2284 switch (RoleValue()) {
2286 case kButtonRole: 2285 case kButtonRole:
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
2325 Document* AXNodeObject::GetDocument() const { 2324 Document* AXNodeObject::GetDocument() const {
2326 if (!GetNode()) 2325 if (!GetNode())
2327 return 0; 2326 return 0;
2328 return &GetNode()->GetDocument(); 2327 return &GetNode()->GetDocument();
2329 } 2328 }
2330 2329
2331 void AXNodeObject::SetNode(Node* node) { 2330 void AXNodeObject::SetNode(Node* node) {
2332 node_ = node; 2331 node_ = node;
2333 } 2332 }
2334 2333
2335 AXObjectImpl* AXNodeObject::CorrespondingControlForLabelElement() const { 2334 AXObject* AXNodeObject::CorrespondingControlForLabelElement() const {
2336 HTMLLabelElement* label_element = LabelElementContainer(); 2335 HTMLLabelElement* label_element = LabelElementContainer();
2337 if (!label_element) 2336 if (!label_element)
2338 return 0; 2337 return 0;
2339 2338
2340 HTMLElement* corresponding_control = label_element->control(); 2339 HTMLElement* corresponding_control = label_element->control();
2341 if (!corresponding_control) 2340 if (!corresponding_control)
2342 return 0; 2341 return 0;
2343 2342
2344 // Make sure the corresponding control isn't a descendant of this label 2343 // Make sure the corresponding control isn't a descendant of this label
2345 // that's in the middle of being destroyed. 2344 // that's in the middle of being destroyed.
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
2424 return; 2423 return;
2425 } 2424 }
2426 2425
2427 AxObjectCache().PostNotification(this, AXObjectCacheImpl::kAXChildrenChanged); 2426 AxObjectCache().PostNotification(this, AXObjectCacheImpl::kAXChildrenChanged);
2428 2427
2429 // Go up the accessibility parent chain, but only if the element already 2428 // Go up the accessibility parent chain, but only if the element already
2430 // exists. This method is called during layout, minimal work should be done. 2429 // exists. This method is called during layout, minimal work should be done.
2431 // If AX elements are created now, they could interrogate the layout tree 2430 // If AX elements are created now, they could interrogate the layout tree
2432 // while it's in a funky state. At the same time, process ARIA live region 2431 // while it's in a funky state. At the same time, process ARIA live region
2433 // changes. 2432 // changes.
2434 for (AXObjectImpl* parent = this; parent; 2433 for (AXObject* parent = this; parent;
2435 parent = parent->ParentObjectIfExists()) { 2434 parent = parent->ParentObjectIfExists()) {
2436 parent->SetNeedsToUpdateChildren(); 2435 parent->SetNeedsToUpdateChildren();
2437 2436
2438 // These notifications always need to be sent because screenreaders are 2437 // These notifications always need to be sent because screenreaders are
2439 // reliant on them to perform. In other words, they need to be sent even 2438 // reliant on them to perform. In other words, they need to be sent even
2440 // when the screen reader has not accessed this live region since the last 2439 // when the screen reader has not accessed this live region since the last
2441 // update. 2440 // update.
2442 2441
2443 // If this element supports ARIA live regions, then notify the AT of 2442 // If this element supports ARIA live regions, then notify the AT of
2444 // changes. 2443 // changes.
(...skipping 11 matching lines...) Expand all
2456 } 2455 }
2457 2456
2458 void AXNodeObject::SelectionChanged() { 2457 void AXNodeObject::SelectionChanged() {
2459 // Post the selected text changed event on the first ancestor that's 2458 // Post the selected text changed event on the first ancestor that's
2460 // focused (to handle form controls, ARIA text boxes and contentEditable), 2459 // focused (to handle form controls, ARIA text boxes and contentEditable),
2461 // or the web area if the selection is just in the document somewhere. 2460 // or the web area if the selection is just in the document somewhere.
2462 if (IsFocused() || IsWebArea()) { 2461 if (IsFocused() || IsWebArea()) {
2463 AxObjectCache().PostNotification(this, 2462 AxObjectCache().PostNotification(this,
2464 AXObjectCacheImpl::kAXSelectedTextChanged); 2463 AXObjectCacheImpl::kAXSelectedTextChanged);
2465 if (GetDocument()) { 2464 if (GetDocument()) {
2466 AXObjectImpl* document_object = 2465 AXObject* document_object = AxObjectCache().GetOrCreate(GetDocument());
2467 AxObjectCache().GetOrCreate(GetDocument());
2468 AxObjectCache().PostNotification( 2466 AxObjectCache().PostNotification(
2469 document_object, AXObjectCacheImpl::kAXDocumentSelectionChanged); 2467 document_object, AXObjectCacheImpl::kAXDocumentSelectionChanged);
2470 } 2468 }
2471 } else { 2469 } else {
2472 AXObjectImpl::SelectionChanged(); // Calls selectionChanged on parent. 2470 AXObject::SelectionChanged(); // Calls selectionChanged on parent.
2473 } 2471 }
2474 } 2472 }
2475 2473
2476 void AXNodeObject::TextChanged() { 2474 void AXNodeObject::TextChanged() {
2477 // If this element supports ARIA live regions, or is part of a region with an 2475 // If this element supports ARIA live regions, or is part of a region with an
2478 // ARIA editable role, then notify the AT of changes. 2476 // ARIA editable role, then notify the AT of changes.
2479 AXObjectCacheImpl& cache = AxObjectCache(); 2477 AXObjectCacheImpl& cache = AxObjectCache();
2480 for (Node* parent_node = GetNode(); parent_node; 2478 for (Node* parent_node = GetNode(); parent_node;
2481 parent_node = parent_node->parentNode()) { 2479 parent_node = parent_node->parentNode()) {
2482 AXObjectImpl* parent = cache.Get(parent_node); 2480 AXObject* parent = cache.Get(parent_node);
2483 if (!parent) 2481 if (!parent)
2484 continue; 2482 continue;
2485 2483
2486 if (parent->IsLiveRegion()) 2484 if (parent->IsLiveRegion())
2487 cache.PostNotification(parent_node, 2485 cache.PostNotification(parent_node,
2488 AXObjectCacheImpl::kAXLiveRegionChanged); 2486 AXObjectCacheImpl::kAXLiveRegionChanged);
2489 2487
2490 // If this element is an ARIA text box or content editable, post a "value 2488 // If this element is an ARIA text box or content editable, post a "value
2491 // changed" notification on it so that it behaves just like a native input 2489 // changed" notification on it so that it behaves just like a native input
2492 // element or textarea. 2490 // element or textarea.
2493 if (parent->IsNonNativeTextControl()) 2491 if (parent->IsNonNativeTextControl())
2494 cache.PostNotification(parent_node, AXObjectCacheImpl::kAXValueChanged); 2492 cache.PostNotification(parent_node, AXObjectCacheImpl::kAXValueChanged);
2495 } 2493 }
2496 } 2494 }
2497 2495
2498 void AXNodeObject::UpdateAccessibilityRole() { 2496 void AXNodeObject::UpdateAccessibilityRole() {
2499 role_ = DetermineAccessibilityRole(); 2497 role_ = DetermineAccessibilityRole();
2500 bool ignored_status = AccessibilityIsIgnored(); 2498 bool ignored_status = AccessibilityIsIgnored();
2501 2499
2502 // The AX hierarchy only needs to be updated if the ignored status of an 2500 // The AX hierarchy only needs to be updated if the ignored status of an
2503 // element has changed. 2501 // element has changed.
2504 if (ignored_status != AccessibilityIsIgnored()) 2502 if (ignored_status != AccessibilityIsIgnored())
2505 ChildrenChanged(); 2503 ChildrenChanged();
2506 } 2504 }
2507 2505
2508 void AXNodeObject::ComputeAriaOwnsChildren( 2506 void AXNodeObject::ComputeAriaOwnsChildren(
2509 HeapVector<Member<AXObjectImpl>>& owned_children) const { 2507 HeapVector<Member<AXObject>>& owned_children) const {
2510 if (!HasAttribute(aria_ownsAttr)) 2508 if (!HasAttribute(aria_ownsAttr))
2511 return; 2509 return;
2512 2510
2513 Vector<String> id_vector; 2511 Vector<String> id_vector;
2514 if (CanHaveChildren() && !IsNativeTextControl() && 2512 if (CanHaveChildren() && !IsNativeTextControl() &&
2515 !HasContentEditableAttributeSet()) 2513 !HasContentEditableAttributeSet())
2516 TokenVectorFromAttribute(id_vector, aria_ownsAttr); 2514 TokenVectorFromAttribute(id_vector, aria_ownsAttr);
2517 2515
2518 AxObjectCache().UpdateAriaOwns(this, id_vector, owned_children); 2516 AxObjectCache().UpdateAriaOwns(this, id_vector, owned_children);
2519 } 2517 }
(...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after
2751 name_sources->back().native_source = kAXTextFromNativeHTMLFigcaption; 2749 name_sources->back().native_source = kAXTextFromNativeHTMLFigcaption;
2752 } 2750 }
2753 Element* figcaption = nullptr; 2751 Element* figcaption = nullptr;
2754 for (Element& element : ElementTraversal::DescendantsOf(*(GetNode()))) { 2752 for (Element& element : ElementTraversal::DescendantsOf(*(GetNode()))) {
2755 if (element.HasTagName(figcaptionTag)) { 2753 if (element.HasTagName(figcaptionTag)) {
2756 figcaption = &element; 2754 figcaption = &element;
2757 break; 2755 break;
2758 } 2756 }
2759 } 2757 }
2760 if (figcaption) { 2758 if (figcaption) {
2761 AXObjectImpl* figcaption_ax_object = 2759 AXObject* figcaption_ax_object = AxObjectCache().GetOrCreate(figcaption);
2762 AxObjectCache().GetOrCreate(figcaption);
2763 if (figcaption_ax_object) { 2760 if (figcaption_ax_object) {
2764 text_alternative = 2761 text_alternative =
2765 RecursiveTextAlternative(*figcaption_ax_object, false, visited); 2762 RecursiveTextAlternative(*figcaption_ax_object, false, visited);
2766 2763
2767 if (related_objects) { 2764 if (related_objects) {
2768 local_related_objects.push_back(new NameSourceRelatedObject( 2765 local_related_objects.push_back(new NameSourceRelatedObject(
2769 figcaption_ax_object, text_alternative)); 2766 figcaption_ax_object, text_alternative));
2770 *related_objects = local_related_objects; 2767 *related_objects = local_related_objects;
2771 local_related_objects.clear(); 2768 local_related_objects.clear();
2772 } 2769 }
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
2816 2813
2817 // caption 2814 // caption
2818 name_from = kAXNameFromCaption; 2815 name_from = kAXNameFromCaption;
2819 if (name_sources) { 2816 if (name_sources) {
2820 name_sources->push_back(NameSource(*found_text_alternative)); 2817 name_sources->push_back(NameSource(*found_text_alternative));
2821 name_sources->back().type = name_from; 2818 name_sources->back().type = name_from;
2822 name_sources->back().native_source = kAXTextFromNativeHTMLTableCaption; 2819 name_sources->back().native_source = kAXTextFromNativeHTMLTableCaption;
2823 } 2820 }
2824 HTMLTableCaptionElement* caption = table_element->caption(); 2821 HTMLTableCaptionElement* caption = table_element->caption();
2825 if (caption) { 2822 if (caption) {
2826 AXObjectImpl* caption_ax_object = AxObjectCache().GetOrCreate(caption); 2823 AXObject* caption_ax_object = AxObjectCache().GetOrCreate(caption);
2827 if (caption_ax_object) { 2824 if (caption_ax_object) {
2828 text_alternative = 2825 text_alternative =
2829 RecursiveTextAlternative(*caption_ax_object, false, visited); 2826 RecursiveTextAlternative(*caption_ax_object, false, visited);
2830 if (related_objects) { 2827 if (related_objects) {
2831 local_related_objects.push_back( 2828 local_related_objects.push_back(
2832 new NameSourceRelatedObject(caption_ax_object, text_alternative)); 2829 new NameSourceRelatedObject(caption_ax_object, text_alternative));
2833 *related_objects = local_related_objects; 2830 *related_objects = local_related_objects;
2834 local_related_objects.clear(); 2831 local_related_objects.clear();
2835 } 2832 }
2836 2833
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
2873 if (name_sources) { 2870 if (name_sources) {
2874 name_sources->push_back(NameSource(*found_text_alternative)); 2871 name_sources->push_back(NameSource(*found_text_alternative));
2875 name_sources->back().type = name_from; 2872 name_sources->back().type = name_from;
2876 name_sources->back().native_source = kAXTextFromNativeHTMLTitleElement; 2873 name_sources->back().native_source = kAXTextFromNativeHTMLTitleElement;
2877 } 2874 }
2878 DCHECK(GetNode()->IsContainerNode()); 2875 DCHECK(GetNode()->IsContainerNode());
2879 Element* title = ElementTraversal::FirstChild( 2876 Element* title = ElementTraversal::FirstChild(
2880 ToContainerNode(*(GetNode())), HasTagName(SVGNames::titleTag)); 2877 ToContainerNode(*(GetNode())), HasTagName(SVGNames::titleTag));
2881 2878
2882 if (title) { 2879 if (title) {
2883 AXObjectImpl* title_ax_object = AxObjectCache().GetOrCreate(title); 2880 AXObject* title_ax_object = AxObjectCache().GetOrCreate(title);
2884 if (title_ax_object && !visited.Contains(title_ax_object)) { 2881 if (title_ax_object && !visited.Contains(title_ax_object)) {
2885 text_alternative = 2882 text_alternative =
2886 RecursiveTextAlternative(*title_ax_object, false, visited); 2883 RecursiveTextAlternative(*title_ax_object, false, visited);
2887 if (related_objects) { 2884 if (related_objects) {
2888 local_related_objects.push_back( 2885 local_related_objects.push_back(
2889 new NameSourceRelatedObject(title_ax_object, text_alternative)); 2886 new NameSourceRelatedObject(title_ax_object, text_alternative));
2890 *related_objects = local_related_objects; 2887 *related_objects = local_related_objects;
2891 local_related_objects.clear(); 2888 local_related_objects.clear();
2892 } 2889 }
2893 } 2890 }
(...skipping 11 matching lines...) Expand all
2905 // Fieldset / legend. 2902 // Fieldset / legend.
2906 if (isHTMLFieldSetElement(GetNode())) { 2903 if (isHTMLFieldSetElement(GetNode())) {
2907 name_from = kAXNameFromRelatedElement; 2904 name_from = kAXNameFromRelatedElement;
2908 if (name_sources) { 2905 if (name_sources) {
2909 name_sources->push_back(NameSource(*found_text_alternative)); 2906 name_sources->push_back(NameSource(*found_text_alternative));
2910 name_sources->back().type = name_from; 2907 name_sources->back().type = name_from;
2911 name_sources->back().native_source = kAXTextFromNativeHTMLLegend; 2908 name_sources->back().native_source = kAXTextFromNativeHTMLLegend;
2912 } 2909 }
2913 HTMLElement* legend = toHTMLFieldSetElement(GetNode())->Legend(); 2910 HTMLElement* legend = toHTMLFieldSetElement(GetNode())->Legend();
2914 if (legend) { 2911 if (legend) {
2915 AXObjectImpl* legend_ax_object = AxObjectCache().GetOrCreate(legend); 2912 AXObject* legend_ax_object = AxObjectCache().GetOrCreate(legend);
2916 // Avoid an infinite loop 2913 // Avoid an infinite loop
2917 if (legend_ax_object && !visited.Contains(legend_ax_object)) { 2914 if (legend_ax_object && !visited.Contains(legend_ax_object)) {
2918 text_alternative = 2915 text_alternative =
2919 RecursiveTextAlternative(*legend_ax_object, false, visited); 2916 RecursiveTextAlternative(*legend_ax_object, false, visited);
2920 2917
2921 if (related_objects) { 2918 if (related_objects) {
2922 local_related_objects.push_back( 2919 local_related_objects.push_back(
2923 new NameSourceRelatedObject(legend_ax_object, text_alternative)); 2920 new NameSourceRelatedObject(legend_ax_object, text_alternative));
2924 *related_objects = local_related_objects; 2921 *related_objects = local_related_objects;
2925 local_related_objects.clear(); 2922 local_related_objects.clear();
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
2967 name_from = kAXNameFromRelatedElement; 2964 name_from = kAXNameFromRelatedElement;
2968 if (name_sources) { 2965 if (name_sources) {
2969 name_sources->push_back(NameSource(*found_text_alternative)); 2966 name_sources->push_back(NameSource(*found_text_alternative));
2970 name_sources->back().type = name_from; 2967 name_sources->back().type = name_from;
2971 name_sources->back().native_source = kAXTextFromNativeHTMLTitleElement; 2968 name_sources->back().native_source = kAXTextFromNativeHTMLTitleElement;
2972 } 2969 }
2973 2970
2974 text_alternative = document->title(); 2971 text_alternative = document->title();
2975 2972
2976 Element* title_element = document->TitleElement(); 2973 Element* title_element = document->TitleElement();
2977 AXObjectImpl* title_ax_object = 2974 AXObject* title_ax_object = AxObjectCache().GetOrCreate(title_element);
2978 AxObjectCache().GetOrCreate(title_element);
2979 if (title_ax_object) { 2975 if (title_ax_object) {
2980 if (related_objects) { 2976 if (related_objects) {
2981 local_related_objects.push_back( 2977 local_related_objects.push_back(
2982 new NameSourceRelatedObject(title_ax_object, text_alternative)); 2978 new NameSourceRelatedObject(title_ax_object, text_alternative));
2983 *related_objects = local_related_objects; 2979 *related_objects = local_related_objects;
2984 local_related_objects.clear(); 2980 local_related_objects.clear();
2985 } 2981 }
2986 2982
2987 if (name_sources) { 2983 if (name_sources) {
2988 NameSource& source = name_sources->back(); 2984 NameSource& source = name_sources->back();
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
3095 3091
3096 description_from = kAXDescriptionFromRelatedElement; 3092 description_from = kAXDescriptionFromRelatedElement;
3097 if (description_sources) { 3093 if (description_sources) {
3098 description_sources->push_back(DescriptionSource(found_description)); 3094 description_sources->push_back(DescriptionSource(found_description));
3099 description_sources->back().type = description_from; 3095 description_sources->back().type = description_from;
3100 description_sources->back().native_source = 3096 description_sources->back().native_source =
3101 kAXTextFromNativeHTMLTableCaption; 3097 kAXTextFromNativeHTMLTableCaption;
3102 } 3098 }
3103 HTMLTableCaptionElement* caption = table_element->caption(); 3099 HTMLTableCaptionElement* caption = table_element->caption();
3104 if (caption) { 3100 if (caption) {
3105 AXObjectImpl* caption_ax_object = AxObjectCache().GetOrCreate(caption); 3101 AXObject* caption_ax_object = AxObjectCache().GetOrCreate(caption);
3106 if (caption_ax_object) { 3102 if (caption_ax_object) {
3107 AXObjectSet visited; 3103 AXObjectSet visited;
3108 description = 3104 description =
3109 RecursiveTextAlternative(*caption_ax_object, false, visited); 3105 RecursiveTextAlternative(*caption_ax_object, false, visited);
3110 if (related_objects) 3106 if (related_objects)
3111 related_objects->push_back( 3107 related_objects->push_back(
3112 new NameSourceRelatedObject(caption_ax_object, description)); 3108 new NameSourceRelatedObject(caption_ax_object, description));
3113 3109
3114 if (description_sources) { 3110 if (description_sources) {
3115 DescriptionSource& source = description_sources->back(); 3111 DescriptionSource& source = description_sources->back();
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
3226 3222
3227 String AXNodeObject::PlaceholderFromNativeAttribute() const { 3223 String AXNodeObject::PlaceholderFromNativeAttribute() const {
3228 Node* node = GetNode(); 3224 Node* node = GetNode();
3229 if (!node || !IsTextControlElement(node)) 3225 if (!node || !IsTextControlElement(node))
3230 return String(); 3226 return String();
3231 return ToTextControlElement(node)->StrippedPlaceholder(); 3227 return ToTextControlElement(node)->StrippedPlaceholder();
3232 } 3228 }
3233 3229
3234 DEFINE_TRACE(AXNodeObject) { 3230 DEFINE_TRACE(AXNodeObject) {
3235 visitor->Trace(node_); 3231 visitor->Trace(node_);
3236 AXObjectImpl::Trace(visitor); 3232 AXObject::Trace(visitor);
3237 } 3233 }
3238 3234
3239 } // namespace blink 3235 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698