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 245 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
256 Element* descendant = | 256 Element* descendant = |
257 element->GetTreeScope().GetElementById(active_descendant_attr); | 257 element->GetTreeScope().GetElementById(active_descendant_attr); |
258 if (!descendant) | 258 if (!descendant) |
259 return nullptr; | 259 return nullptr; |
260 | 260 |
261 AXObject* ax_descendant = AxObjectCache().GetOrCreate(descendant); | 261 AXObject* ax_descendant = AxObjectCache().GetOrCreate(descendant); |
262 return ax_descendant; | 262 return ax_descendant; |
263 } | 263 } |
264 | 264 |
265 bool AXNodeObject::ComputeAccessibilityIsIgnored( | 265 bool AXNodeObject::ComputeAccessibilityIsIgnored( |
266 IgnoredReasons* ignored_reasons) const { | 266 IgnoredReasons* ignoredReasons) const { |
267 #if DCHECK_IS_ON() | 267 #if DCHECK_IS_ON() |
268 // Double-check that an AXObject is never accessed before | 268 // Double-check that an AXObject is never accessed before |
269 // it's been initialized. | 269 // it's been initialized. |
270 DCHECK(initialized_); | 270 DCHECK(m_initialized); |
271 #endif | 271 #endif |
272 | 272 |
273 // 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 |
274 // be exposed. | 274 // be exposed. |
275 if (IsDescendantOfLeafNode()) { | 275 if (IsDescendantOfLeafNode()) { |
276 if (ignored_reasons) | 276 if (ignoredReasons) |
277 ignored_reasons->push_back( | 277 ignoredReasons->push_back( |
278 IgnoredReason(kAXAncestorIsLeafNode, LeafNodeAncestor())); | 278 IgnoredReason(kAXAncestorIsLeafNode, LeafNodeAncestor())); |
279 return true; | 279 return true; |
280 } | 280 } |
281 | 281 |
282 // Ignore labels that are already referenced by a control. | 282 // Ignore labels that are already referenced by a control. |
283 AXObject* control_object = CorrespondingControlForLabelElement(); | 283 AXObject* control_object = CorrespondingControlForLabelElement(); |
284 if (control_object && control_object->IsCheckboxOrRadio() && | 284 if (control_object && control_object->IsCheckboxOrRadio() && |
285 control_object->NameFromLabelElement()) { | 285 control_object->NameFromLabelElement()) { |
286 if (ignored_reasons) { | 286 if (ignoredReasons) { |
287 HTMLLabelElement* label = LabelElementContainer(); | 287 HTMLLabelElement* label = LabelElementContainer(); |
288 if (label && label != GetNode()) { | 288 if (label && label != GetNode()) { |
289 AXObject* label_ax_object = AxObjectCache().GetOrCreate(label); | 289 AXObject* label_ax_object = AxObjectCache().GetOrCreate(label); |
290 ignored_reasons->push_back( | 290 ignoredReasons->push_back( |
291 IgnoredReason(kAXLabelContainer, label_ax_object)); | 291 IgnoredReason(kAXLabelContainer, label_ax_object)); |
292 } | 292 } |
293 | 293 |
294 ignored_reasons->push_back(IgnoredReason(kAXLabelFor, control_object)); | 294 ignoredReasons->push_back(IgnoredReason(kAXLabelFor, control_object)); |
295 } | 295 } |
296 return true; | 296 return true; |
297 } | 297 } |
298 | 298 |
299 Element* element = GetNode()->IsElementNode() ? ToElement(GetNode()) | 299 Element* element = GetNode()->IsElementNode() ? ToElement(GetNode()) |
300 : GetNode()->parentElement(); | 300 : GetNode()->parentElement(); |
301 if (!GetLayoutObject() && (!element || !element->IsInCanvasSubtree()) && | 301 if (!GetLayoutObject() && (!element || !element->IsInCanvasSubtree()) && |
302 !EqualIgnoringASCIICase(GetAttribute(aria_hiddenAttr), "false")) { | 302 !AOMPropertyOrARIAAttributeIsFalse(AOMBooleanProperty::kHidden)) { |
303 if (ignored_reasons) | 303 if (ignoredReasons) |
304 ignored_reasons->push_back(IgnoredReason(kAXNotRendered)); | 304 ignoredReasons->push_back(IgnoredReason(kAXNotRendered)); |
305 return true; | 305 return true; |
306 } | 306 } |
307 | 307 |
308 if (role_ == kUnknownRole) { | 308 if (role_ == kUnknownRole) { |
309 if (ignored_reasons) | 309 if (ignoredReasons) |
310 ignored_reasons->push_back(IgnoredReason(kAXUninteresting)); | 310 ignoredReasons->push_back(IgnoredReason(kAXUninteresting)); |
311 return true; | 311 return true; |
312 } | 312 } |
313 return false; | 313 return false; |
314 } | 314 } |
315 | 315 |
316 static bool IsListElement(Node* node) { | 316 static bool IsListElement(Node* node) { |
317 return isHTMLUListElement(*node) || isHTMLOListElement(*node) || | 317 return isHTMLUListElement(*node) || isHTMLOListElement(*node) || |
318 isHTMLDListElement(*node); | 318 isHTMLDListElement(*node); |
319 } | 319 } |
320 | 320 |
321 static bool IsPresentationalInTable(AXObject* parent, | 321 static bool IsPresentationalInTable(AXObject* parent, |
322 HTMLElement* current_element) { | 322 HTMLElement* currentElement) { |
323 if (!current_element) | 323 if (!currentElement) |
324 return false; | 324 return false; |
325 | 325 |
326 Node* parent_node = parent->GetNode(); | 326 Node* parent_node = parent->GetNode(); |
327 if (!parent_node || !parent_node->IsHTMLElement()) | 327 if (!parent_node || !parent_node->IsHTMLElement()) |
328 return false; | 328 return false; |
329 | 329 |
330 // AXTable determines the role as checking isTableXXX. | 330 // AXTable determines the role as checking isTableXXX. |
331 // If Table has explicit role including presentation, AXTable doesn't assign | 331 // 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 | 332 // implicit Role to a whole Table. That's why we should check it based on |
333 // node. | 333 // node. |
334 // Normal Table Tree is that | 334 // Normal Table Tree is that |
335 // cell(its role)-> tr(tr role)-> tfoot, tbody, thead(ignored role) -> | 335 // cell(its role)-> tr(tr role)-> tfoot, tbody, thead(ignored role) -> |
336 // table(table role). | 336 // table(table role). |
337 // If table has presentation role, it will be like | 337 // If table has presentation role, it will be like |
338 // cell(group)-> tr(unknown) -> tfoot, tbody, thead(ignored) -> | 338 // cell(group)-> tr(unknown) -> tfoot, tbody, thead(ignored) -> |
339 // table(presentation). | 339 // table(presentation). |
340 if (IsHTMLTableCellElement(*current_element) && | 340 if (IsHTMLTableCellElement(*currentElement) && |
341 isHTMLTableRowElement(*parent_node)) | 341 isHTMLTableRowElement(*parent_node)) |
342 return parent->HasInheritedPresentationalRole(); | 342 return parent->HasInheritedPresentationalRole(); |
343 | 343 |
344 if (isHTMLTableRowElement(*current_element) && | 344 if (isHTMLTableRowElement(*currentElement) && |
345 IsHTMLTableSectionElement(ToHTMLElement(*parent_node))) { | 345 IsHTMLTableSectionElement(ToHTMLElement(*parent_node))) { |
346 // Because TableSections have ignored role, presentation should be checked | 346 // Because TableSections have ignored role, presentation should be checked |
347 // with its parent node. | 347 // with its parent node. |
348 AXObject* table_object = parent->ParentObject(); | 348 AXObject* table_object = parent->ParentObject(); |
349 Node* table_node = table_object ? table_object->GetNode() : 0; | 349 Node* table_node = table_object ? table_object->GetNode() : 0; |
350 return isHTMLTableElement(table_node) && | 350 return isHTMLTableElement(table_node) && |
351 table_object->HasInheritedPresentationalRole(); | 351 table_object->HasInheritedPresentationalRole(); |
352 } | 352 } |
353 return false; | 353 return false; |
354 } | 354 } |
355 | 355 |
356 static bool IsRequiredOwnedElement(AXObject* parent, | 356 static bool IsRequiredOwnedElement(AXObject* parent, |
357 AccessibilityRole current_role, | 357 AccessibilityRole currentRole, |
358 HTMLElement* current_element) { | 358 HTMLElement* currentElement) { |
359 Node* parent_node = parent->GetNode(); | 359 Node* parent_node = parent->GetNode(); |
360 if (!parent_node || !parent_node->IsHTMLElement()) | 360 if (!parent_node || !parent_node->IsHTMLElement()) |
361 return false; | 361 return false; |
362 | 362 |
363 if (current_role == kListItemRole) | 363 if (currentRole == kListItemRole) |
364 return IsListElement(parent_node); | 364 return IsListElement(parent_node); |
365 if (current_role == kListMarkerRole) | 365 if (currentRole == kListMarkerRole) |
366 return isHTMLLIElement(*parent_node); | 366 return isHTMLLIElement(*parent_node); |
367 if (current_role == kMenuItemCheckBoxRole || current_role == kMenuItemRole || | 367 if (currentRole == kMenuItemCheckBoxRole || currentRole == kMenuItemRole || |
368 current_role == kMenuItemRadioRole) | 368 currentRole == kMenuItemRadioRole) |
369 return isHTMLMenuElement(*parent_node); | 369 return isHTMLMenuElement(*parent_node); |
370 | 370 |
371 if (!current_element) | 371 if (!currentElement) |
372 return false; | 372 return false; |
373 if (IsHTMLTableCellElement(*current_element)) | 373 if (IsHTMLTableCellElement(*currentElement)) |
374 return isHTMLTableRowElement(*parent_node); | 374 return isHTMLTableRowElement(*parent_node); |
375 if (isHTMLTableRowElement(*current_element)) | 375 if (isHTMLTableRowElement(*currentElement)) |
376 return IsHTMLTableSectionElement(ToHTMLElement(*parent_node)); | 376 return IsHTMLTableSectionElement(ToHTMLElement(*parent_node)); |
377 | 377 |
378 // In case of ListboxRole and its child, ListBoxOptionRole, inheritance of | 378 // In case of ListboxRole and its child, ListBoxOptionRole, inheritance of |
379 // presentation role is handled in AXListBoxOption because ListBoxOption Role | 379 // presentation role is handled in AXListBoxOption because ListBoxOption Role |
380 // doesn't have any child. | 380 // doesn't have any child. |
381 // 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 |
382 // related to ListBoxOption. | 382 // related to ListBoxOption. |
383 return false; | 383 return false; |
384 } | 384 } |
385 | 385 |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
439 landmark_roles_not_allowed.insert(detailsTag); | 439 landmark_roles_not_allowed.insert(detailsTag); |
440 landmark_roles_not_allowed.insert(fieldsetTag); | 440 landmark_roles_not_allowed.insert(fieldsetTag); |
441 landmark_roles_not_allowed.insert(figureTag); | 441 landmark_roles_not_allowed.insert(figureTag); |
442 landmark_roles_not_allowed.insert(tdTag); | 442 landmark_roles_not_allowed.insert(tdTag); |
443 landmark_roles_not_allowed.insert(mainTag); | 443 landmark_roles_not_allowed.insert(mainTag); |
444 } | 444 } |
445 return landmark_roles_not_allowed; | 445 return landmark_roles_not_allowed; |
446 } | 446 } |
447 | 447 |
448 bool AXNodeObject::IsDescendantOfElementType( | 448 bool AXNodeObject::IsDescendantOfElementType( |
449 HashSet<QualifiedName>& tag_names) const { | 449 HashSet<QualifiedName>& tagNames) const { |
450 if (!GetNode()) | 450 if (!GetNode()) |
451 return false; | 451 return false; |
452 | 452 |
453 for (Element* parent = GetNode()->parentElement(); parent; | 453 for (Element* parent = GetNode()->parentElement(); parent; |
454 parent = parent->parentElement()) { | 454 parent = parent->parentElement()) { |
455 if (tag_names.Contains(parent->TagQName())) | 455 if (tagNames.Contains(parent->TagQName())) |
456 return true; | 456 return true; |
457 } | 457 } |
458 return false; | 458 return false; |
459 } | 459 } |
460 | 460 |
461 AccessibilityRole AXNodeObject::NativeAccessibilityRoleIgnoringAria() const { | 461 AccessibilityRole AXNodeObject::NativeAccessibilityRoleIgnoringAria() const { |
462 if (!GetNode()) | 462 if (!GetNode()) |
463 return kUnknownRole; | 463 return kUnknownRole; |
464 | 464 |
465 // |HTMLAnchorElement| sets isLink only when it has hrefAttr. | 465 // |HTMLAnchorElement| sets isLink only when it has hrefAttr. |
(...skipping 431 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
897 // searching up the chain. | 897 // searching up the chain. |
898 if (parent_aria_role) | 898 if (parent_aria_role) |
899 break; | 899 break; |
900 } | 900 } |
901 | 901 |
902 return role; | 902 return role; |
903 } | 903 } |
904 | 904 |
905 void AXNodeObject::Init() { | 905 void AXNodeObject::Init() { |
906 #if DCHECK_IS_ON() | 906 #if DCHECK_IS_ON() |
907 DCHECK(!initialized_); | 907 DCHECK(!m_initialized); |
908 initialized_ = true; | 908 m_initialized = true; |
909 #endif | 909 #endif |
910 role_ = DetermineAccessibilityRole(); | 910 role_ = DetermineAccessibilityRole(); |
911 } | 911 } |
912 | 912 |
913 void AXNodeObject::Detach() { | 913 void AXNodeObject::Detach() { |
914 AXObject::Detach(); | 914 AXObject::Detach(); |
915 node_ = nullptr; | 915 node_ = nullptr; |
916 } | 916 } |
917 | 917 |
918 void AXNodeObject::GetSparseAXAttributes( | 918 void AXNodeObject::GetSparseAXAttributes( |
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1036 | 1036 |
1037 bool AXNodeObject::IsMenuButton() const { | 1037 bool AXNodeObject::IsMenuButton() const { |
1038 return RoleValue() == kMenuButtonRole; | 1038 return RoleValue() == kMenuButtonRole; |
1039 } | 1039 } |
1040 | 1040 |
1041 bool AXNodeObject::IsMeter() const { | 1041 bool AXNodeObject::IsMeter() const { |
1042 return RoleValue() == kMeterRole; | 1042 return RoleValue() == kMeterRole; |
1043 } | 1043 } |
1044 | 1044 |
1045 bool AXNodeObject::IsMultiSelectable() const { | 1045 bool AXNodeObject::IsMultiSelectable() const { |
1046 const AtomicString& aria_multi_selectable = | 1046 bool multiselectable = false; |
1047 GetAttribute(aria_multiselectableAttr); | 1047 if (HasAOMPropertyOrARIAAttribute(AOMBooleanProperty::kMultiselectable, |
1048 if (EqualIgnoringASCIICase(aria_multi_selectable, "true")) | 1048 multiselectable)) { |
1049 return true; | 1049 return multiselectable; |
1050 if (EqualIgnoringASCIICase(aria_multi_selectable, "false")) | 1050 } |
1051 return false; | |
1052 | 1051 |
1053 return isHTMLSelectElement(GetNode()) && | 1052 return isHTMLSelectElement(GetNode()) && |
1054 toHTMLSelectElement(*GetNode()).IsMultiple(); | 1053 toHTMLSelectElement(*GetNode()).IsMultiple(); |
1055 } | 1054 } |
1056 | 1055 |
1057 bool AXNodeObject::IsNativeCheckboxOrRadio() const { | 1056 bool AXNodeObject::IsNativeCheckboxOrRadio() const { |
1058 Node* node = this->GetNode(); | 1057 Node* node = this->GetNode(); |
1059 if (!isHTMLInputElement(node)) | 1058 if (!isHTMLInputElement(node)) |
1060 return false; | 1059 return false; |
1061 | 1060 |
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1174 | 1173 |
1175 AccessibilityExpanded AXNodeObject::IsExpanded() const { | 1174 AccessibilityExpanded AXNodeObject::IsExpanded() const { |
1176 if (GetNode() && isHTMLSummaryElement(*GetNode())) { | 1175 if (GetNode() && isHTMLSummaryElement(*GetNode())) { |
1177 if (GetNode()->parentNode() && | 1176 if (GetNode()->parentNode() && |
1178 isHTMLDetailsElement(GetNode()->parentNode())) | 1177 isHTMLDetailsElement(GetNode()->parentNode())) |
1179 return ToElement(GetNode()->parentNode())->hasAttribute(openAttr) | 1178 return ToElement(GetNode()->parentNode())->hasAttribute(openAttr) |
1180 ? kExpandedExpanded | 1179 ? kExpandedExpanded |
1181 : kExpandedCollapsed; | 1180 : kExpandedCollapsed; |
1182 } | 1181 } |
1183 | 1182 |
1184 const AtomicString& expanded = GetAttribute(aria_expandedAttr); | 1183 bool expanded = false; |
1185 if (EqualIgnoringASCIICase(expanded, "true")) | 1184 if (HasAOMPropertyOrARIAAttribute(AOMBooleanProperty::kExpanded, expanded)) { |
1186 return kExpandedExpanded; | 1185 return expanded ? kExpandedExpanded : kExpandedCollapsed; |
1187 if (EqualIgnoringASCIICase(expanded, "false")) | 1186 } |
1188 return kExpandedCollapsed; | |
1189 | 1187 |
1190 return kExpandedUndefined; | 1188 return kExpandedUndefined; |
1191 } | 1189 } |
1192 | 1190 |
1193 bool AXNodeObject::IsModal() const { | 1191 bool AXNodeObject::IsModal() const { |
1194 if (RoleValue() != kDialogRole && RoleValue() != kAlertDialogRole) | 1192 if (RoleValue() != kDialogRole && RoleValue() != kAlertDialogRole) |
1195 return false; | 1193 return false; |
1196 | 1194 |
1197 if (HasAttribute(aria_modalAttr)) { | 1195 bool modal = false; |
1198 const AtomicString& modal = GetAttribute(aria_modalAttr); | 1196 if (HasAOMPropertyOrARIAAttribute(AOMBooleanProperty::kModal, modal)) |
1199 if (EqualIgnoringASCIICase(modal, "true")) | 1197 return modal; |
1200 return true; | |
1201 if (EqualIgnoringASCIICase(modal, "false")) | |
1202 return false; | |
1203 } | |
1204 | 1198 |
1205 if (GetNode() && isHTMLDialogElement(*GetNode())) | 1199 if (GetNode() && isHTMLDialogElement(*GetNode())) |
1206 return ToElement(GetNode())->IsInTopLayer(); | 1200 return ToElement(GetNode())->IsInTopLayer(); |
1207 | 1201 |
1208 return false; | 1202 return false; |
1209 } | 1203 } |
1210 | 1204 |
1211 bool AXNodeObject::IsPressed() const { | 1205 bool AXNodeObject::IsPressed() const { |
1212 if (!IsButton()) | 1206 if (!IsButton()) |
1213 return false; | 1207 return false; |
(...skipping 30 matching lines...) Expand all Loading... |
1244 | 1238 |
1245 return !HasEditableStyle(*node); | 1239 return !HasEditableStyle(*node); |
1246 } | 1240 } |
1247 | 1241 |
1248 bool AXNodeObject::IsRequired() const { | 1242 bool AXNodeObject::IsRequired() const { |
1249 Node* n = this->GetNode(); | 1243 Node* n = this->GetNode(); |
1250 if (n && (n->IsElementNode() && ToElement(n)->IsFormControlElement()) && | 1244 if (n && (n->IsElementNode() && ToElement(n)->IsFormControlElement()) && |
1251 HasAttribute(requiredAttr)) | 1245 HasAttribute(requiredAttr)) |
1252 return ToHTMLFormControlElement(n)->IsRequired(); | 1246 return ToHTMLFormControlElement(n)->IsRequired(); |
1253 | 1247 |
1254 if (EqualIgnoringASCIICase(GetAttribute(aria_requiredAttr), "true")) | 1248 if (AOMPropertyOrARIAAttributeIsTrue(AOMBooleanProperty::kRequired)) |
1255 return true; | 1249 return true; |
1256 | 1250 |
1257 return false; | 1251 return false; |
1258 } | 1252 } |
1259 | 1253 |
1260 bool AXNodeObject::CanSetFocusAttribute() const { | 1254 bool AXNodeObject::CanSetFocusAttribute() const { |
1261 Node* node = GetNode(); | 1255 Node* node = GetNode(); |
1262 if (!node) | 1256 if (!node) |
1263 return false; | 1257 return false; |
1264 | 1258 |
1265 if (IsWebArea()) | 1259 if (IsWebArea()) |
1266 return true; | 1260 return true; |
1267 | 1261 |
1268 // Children of elements with an aria-activedescendant attribute should be | 1262 // Children of elements with an aria-activedescendant attribute should be |
1269 // focusable if they have a (non-presentational) ARIA role. | 1263 // focusable if they have a (non-presentational) ARIA role. |
1270 if (!IsPresentational() && AriaRoleAttribute() != kUnknownRole && | 1264 if (!IsPresentational() && AriaRoleAttribute() != kUnknownRole && |
1271 AncestorExposesActiveDescendant()) | 1265 AncestorExposesActiveDescendant()) |
1272 return true; | 1266 return true; |
1273 | 1267 |
1274 // NOTE: It would be more accurate to ask the document whether | 1268 // NOTE: It would be more accurate to ask the document whether |
1275 // setFocusedNode() would do anything. For example, setFocusedNode() will do | 1269 // setFocusedNode() would do anything. For example, setFocusedNode() will do |
1276 // nothing if the current focused node will not relinquish the focus. | 1270 // nothing if the current focused node will not relinquish the focus. |
1277 if (IsDisabledFormControl(node)) | 1271 if (IsDisabledFormControl(node)) |
1278 return false; | 1272 return false; |
1279 | 1273 |
1280 return node->IsElementNode() && ToElement(node)->SupportsFocus(); | 1274 return node->IsElementNode() && ToElement(node)->SupportsFocus(); |
1281 } | 1275 } |
1282 | 1276 |
1283 bool AXNodeObject::CanSetValueAttribute() const { | 1277 bool AXNodeObject::CanSetValueAttribute() const { |
1284 if (EqualIgnoringASCIICase(GetAttribute(aria_readonlyAttr), "true")) | 1278 if (AOMPropertyOrARIAAttributeIsTrue(AOMBooleanProperty::kReadOnly)) |
1285 return false; | 1279 return false; |
1286 | 1280 |
1287 if (IsProgressIndicator() || IsSlider()) | 1281 if (IsProgressIndicator() || IsSlider()) |
1288 return true; | 1282 return true; |
1289 | 1283 |
1290 if (IsTextControl() && !IsNativeTextControl()) | 1284 if (IsTextControl() && !IsNativeTextControl()) |
1291 return true; | 1285 return true; |
1292 | 1286 |
1293 // Any node could be contenteditable, so isReadOnly should be relied upon | 1287 // Any node could be contenteditable, so isReadOnly should be relied upon |
1294 // for this information for all elements. | 1288 // for this information for all elements. |
(...skipping 650 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1945 } | 1939 } |
1946 for (const auto& owned_child : owned_children) | 1940 for (const auto& owned_child : owned_children) |
1947 children.push_back(owned_child); | 1941 children.push_back(owned_child); |
1948 | 1942 |
1949 for (AXObject* child : children) { | 1943 for (AXObject* child : children) { |
1950 // Don't recurse into children that are explicitly marked as aria-hidden. | 1944 // Don't recurse into children that are explicitly marked as aria-hidden. |
1951 // Note that we don't call isInertOrAriaHidden because that would return | 1945 // Note that we don't call isInertOrAriaHidden because that would return |
1952 // true if any ancestor is hidden, but we need to be able to compute the | 1946 // true if any ancestor is hidden, but we need to be able to compute the |
1953 // accessible name of object inside hidden subtrees (for example, if | 1947 // accessible name of object inside hidden subtrees (for example, if |
1954 // aria-labelledby points to an object that's hidden). | 1948 // aria-labelledby points to an object that's hidden). |
1955 if (EqualIgnoringASCIICase(child->GetAttribute(aria_hiddenAttr), "true")) | 1949 if (child->AOMPropertyOrARIAAttributeIsTrue(AOMBooleanProperty::kHidden)) |
1956 continue; | 1950 continue; |
1957 | 1951 |
1958 // If we're going between two layoutObjects that are in separate | 1952 // If we're going between two layoutObjects that are in separate |
1959 // LayoutBoxes, add whitespace if it wasn't there already. Intuitively if | 1953 // LayoutBoxes, add whitespace if it wasn't there already. Intuitively if |
1960 // you have <span>Hello</span><span>World</span>, those are part of the same | 1954 // you have <span>Hello</span><span>World</span>, those are part of the same |
1961 // LayoutBox so we should return "HelloWorld", but given | 1955 // LayoutBox so we should return "HelloWorld", but given |
1962 // <div>Hello</div><div>World</div> the strings are in separate boxes so we | 1956 // <div>Hello</div><div>World</div> the strings are in separate boxes so we |
1963 // should return "Hello World". | 1957 // should return "Hello World". |
1964 if (previous && accumulated_text.length() && | 1958 if (previous && accumulated_text.length() && |
1965 !IsHTMLSpace(accumulated_text[accumulated_text.length() - 1])) { | 1959 !IsHTMLSpace(accumulated_text[accumulated_text.length() - 1])) { |
(...skipping 1253 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3219 return String(); | 3213 return String(); |
3220 return ToTextControlElement(node)->StrippedPlaceholder(); | 3214 return ToTextControlElement(node)->StrippedPlaceholder(); |
3221 } | 3215 } |
3222 | 3216 |
3223 DEFINE_TRACE(AXNodeObject) { | 3217 DEFINE_TRACE(AXNodeObject) { |
3224 visitor->Trace(node_); | 3218 visitor->Trace(node_); |
3225 AXObject::Trace(visitor); | 3219 AXObject::Trace(visitor); |
3226 } | 3220 } |
3227 | 3221 |
3228 } // namespace blink | 3222 } // namespace blink |
OLD | NEW |