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