OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2008, 2009, 2011 Apple Inc. All rights reserved. | 2 * Copyright (C) 2008, 2009, 2011 Apple 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 370 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
381 | 381 |
382 ax_object_cache_ = nullptr; | 382 ax_object_cache_ = nullptr; |
383 } | 383 } |
384 | 384 |
385 bool AXObjectImpl::IsDetached() const { | 385 bool AXObjectImpl::IsDetached() const { |
386 return !ax_object_cache_; | 386 return !ax_object_cache_; |
387 } | 387 } |
388 | 388 |
389 const AtomicString& AXObjectImpl::GetAOMPropertyOrARIAAttribute( | 389 const AtomicString& AXObjectImpl::GetAOMPropertyOrARIAAttribute( |
390 AOMStringProperty property) const { | 390 AOMStringProperty property) const { |
391 Node* node = this->GetNode(); | 391 if (Element* element = this->GetElement()) |
392 if (!node || !node->IsElementNode()) | 392 return AccessibleNode::GetPropertyOrARIAAttribute(element, property); |
393 return g_null_atom; | 393 return g_null_atom; |
| 394 } |
394 | 395 |
395 return AccessibleNode::GetPropertyOrARIAAttribute(ToElement(node), property); | 396 bool AXObjectImpl::HasAOMPropertyOrARIAAttribute(AOMBooleanProperty property, |
| 397 bool& result) const { |
| 398 Element* element = this->GetElement(); |
| 399 if (!element) |
| 400 return false; |
| 401 |
| 402 bool is_null = true; |
| 403 result = |
| 404 AccessibleNode::GetPropertyOrARIAAttribute(element, property, is_null); |
| 405 return !is_null; |
| 406 } |
| 407 |
| 408 bool AXObjectImpl::AOMPropertyOrARIAAttributeIsTrue( |
| 409 AOMBooleanProperty property) const { |
| 410 bool result; |
| 411 if (HasAOMPropertyOrARIAAttribute(property, result)) |
| 412 return result; |
| 413 return false; |
| 414 } |
| 415 |
| 416 bool AXObjectImpl::AOMPropertyOrARIAAttributeIsFalse( |
| 417 AOMBooleanProperty property) const { |
| 418 bool result; |
| 419 if (HasAOMPropertyOrARIAAttribute(property, result)) |
| 420 return !result; |
| 421 return false; |
396 } | 422 } |
397 | 423 |
398 bool AXObjectImpl::IsARIATextControl() const { | 424 bool AXObjectImpl::IsARIATextControl() const { |
399 return AriaRoleAttribute() == kTextFieldRole || | 425 return AriaRoleAttribute() == kTextFieldRole || |
400 AriaRoleAttribute() == kSearchBoxRole || | 426 AriaRoleAttribute() == kSearchBoxRole || |
401 AriaRoleAttribute() == kComboBoxRole; | 427 AriaRoleAttribute() == kComboBoxRole; |
402 } | 428 } |
403 | 429 |
404 bool AXObjectImpl::IsButton() const { | 430 bool AXObjectImpl::IsButton() const { |
405 AccessibilityRole role = RoleValue(); | 431 AccessibilityRole role = RoleValue(); |
(...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
664 | 690 |
665 return parent->LeafNodeAncestor(); | 691 return parent->LeafNodeAncestor(); |
666 } | 692 } |
667 | 693 |
668 return 0; | 694 return 0; |
669 } | 695 } |
670 | 696 |
671 const AXObjectImpl* AXObjectImpl::AriaHiddenRoot() const { | 697 const AXObjectImpl* AXObjectImpl::AriaHiddenRoot() const { |
672 for (const AXObjectImpl* object = this; object; | 698 for (const AXObjectImpl* object = this; object; |
673 object = object->ParentObject()) { | 699 object = object->ParentObject()) { |
674 if (EqualIgnoringASCIICase(object->GetAttribute(aria_hiddenAttr), "true")) | 700 if (object->AOMPropertyOrARIAAttributeIsTrue(AOMBooleanProperty::kHidden)) |
675 return object; | 701 return object; |
676 } | 702 } |
677 | 703 |
678 return 0; | 704 return 0; |
679 } | 705 } |
680 | 706 |
681 bool AXObjectImpl::IsDescendantOfDisabledNode() const { | 707 bool AXObjectImpl::IsDescendantOfDisabledNode() const { |
682 UpdateCachedAttributeValuesIfNeeded(); | 708 UpdateCachedAttributeValuesIfNeeded(); |
683 return cached_is_descendant_of_disabled_node_; | 709 return cached_is_descendant_of_disabled_node_; |
684 } | 710 } |
685 | 711 |
686 const AXObjectImpl* AXObjectImpl::DisabledAncestor() const { | 712 const AXObjectImpl* AXObjectImpl::DisabledAncestor() const { |
687 const AtomicString& disabled = GetAttribute(aria_disabledAttr); | 713 bool disabled = false; |
688 if (EqualIgnoringASCIICase(disabled, "true")) | 714 if (HasAOMPropertyOrARIAAttribute(AOMBooleanProperty::kDisabled, disabled)) { |
689 return this; | 715 if (disabled) |
690 if (EqualIgnoringASCIICase(disabled, "false")) | 716 return this; |
691 return 0; | 717 return nullptr; |
| 718 } |
692 | 719 |
693 if (AXObjectImpl* parent = ParentObject()) | 720 if (AXObjectImpl* parent = ParentObject()) |
694 return parent->DisabledAncestor(); | 721 return parent->DisabledAncestor(); |
695 | 722 |
696 return 0; | 723 return nullptr; |
697 } | 724 } |
698 | 725 |
699 bool AXObjectImpl::LastKnownIsIgnoredValue() { | 726 bool AXObjectImpl::LastKnownIsIgnoredValue() { |
700 if (last_known_is_ignored_value_ == kDefaultBehavior) { | 727 if (last_known_is_ignored_value_ == kDefaultBehavior) { |
701 last_known_is_ignored_value_ = | 728 last_known_is_ignored_value_ = |
702 AccessibilityIsIgnored() ? kIgnoreObject : kIncludeObject; | 729 AccessibilityIsIgnored() ? kIgnoreObject : kIncludeObject; |
703 } | 730 } |
704 | 731 |
705 return last_known_is_ignored_value_ == kIgnoreObject; | 732 return last_known_is_ignored_value_ == kIgnoreObject; |
706 } | 733 } |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
793 AXObjectSet& visited) { | 820 AXObjectSet& visited) { |
794 if (visited.Contains(&ax_obj) && !in_aria_labelled_by_traversal) | 821 if (visited.Contains(&ax_obj) && !in_aria_labelled_by_traversal) |
795 return String(); | 822 return String(); |
796 | 823 |
797 AXNameFrom tmp_name_from; | 824 AXNameFrom tmp_name_from; |
798 return ax_obj.TextAlternative(true, in_aria_labelled_by_traversal, visited, | 825 return ax_obj.TextAlternative(true, in_aria_labelled_by_traversal, visited, |
799 tmp_name_from, nullptr, nullptr); | 826 tmp_name_from, nullptr, nullptr); |
800 } | 827 } |
801 | 828 |
802 bool AXObjectImpl::IsHiddenForTextAlternativeCalculation() const { | 829 bool AXObjectImpl::IsHiddenForTextAlternativeCalculation() const { |
803 if (EqualIgnoringASCIICase(GetAttribute(aria_hiddenAttr), "false")) | 830 if (AOMPropertyOrARIAAttributeIsFalse(AOMBooleanProperty::kHidden)) |
804 return false; | 831 return false; |
805 | 832 |
806 if (GetLayoutObject()) | 833 if (GetLayoutObject()) |
807 return GetLayoutObject()->Style()->Visibility() != EVisibility::kVisible; | 834 return GetLayoutObject()->Style()->Visibility() != EVisibility::kVisible; |
808 | 835 |
809 // This is an obscure corner case: if a node has no LayoutObject, that means | 836 // This is an obscure corner case: if a node has no LayoutObject, that means |
810 // it's not rendered, but we still may be exploring it as part of a text | 837 // it's not rendered, but we still may be exploring it as part of a text |
811 // alternative calculation, for example if it was explicitly referenced by | 838 // alternative calculation, for example if it was explicitly referenced by |
812 // aria-labelledby. So we need to explicitly call the style resolver to check | 839 // aria-labelledby. So we need to explicitly call the style resolver to check |
813 // whether it's invisible or display:none, rather than relying on the style | 840 // whether it's invisible or display:none, rather than relying on the style |
(...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1040 | 1067 |
1041 if (isHTMLTextAreaElement(*node)) | 1068 if (isHTMLTextAreaElement(*node)) |
1042 return true; | 1069 return true; |
1043 | 1070 |
1044 if (HasEditableStyle(*node)) | 1071 if (HasEditableStyle(*node)) |
1045 return true; | 1072 return true; |
1046 | 1073 |
1047 if (!IsNativeTextControl() && !IsNonNativeTextControl()) | 1074 if (!IsNativeTextControl() && !IsNonNativeTextControl()) |
1048 return false; | 1075 return false; |
1049 | 1076 |
1050 return EqualIgnoringASCIICase(GetAttribute(aria_multilineAttr), "true"); | 1077 return AOMPropertyOrARIAAttributeIsTrue(AOMBooleanProperty::kMultiline); |
1051 } | 1078 } |
1052 | 1079 |
1053 bool AXObjectImpl::AriaPressedIsPresent() const { | 1080 bool AXObjectImpl::AriaPressedIsPresent() const { |
1054 return !GetAttribute(aria_pressedAttr).IsEmpty(); | 1081 return !GetAttribute(aria_pressedAttr).IsEmpty(); |
1055 } | 1082 } |
1056 | 1083 |
1057 bool AXObjectImpl::SupportsActiveDescendant() const { | 1084 bool AXObjectImpl::SupportsActiveDescendant() const { |
1058 // According to the ARIA Spec, all ARIA composite widgets, ARIA text boxes | 1085 // According to the ARIA Spec, all ARIA composite widgets, ARIA text boxes |
1059 // and ARIA groups should be able to expose an active descendant. | 1086 // and ARIA groups should be able to expose an active descendant. |
1060 // Implicitly, <input> and <textarea> elements should also have this ability. | 1087 // Implicitly, <input> and <textarea> elements should also have this ability. |
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1218 | 1245 |
1219 void AXObjectImpl::ClearChildren() { | 1246 void AXObjectImpl::ClearChildren() { |
1220 // Detach all weak pointers from objects to their parents. | 1247 // Detach all weak pointers from objects to their parents. |
1221 for (const auto& child : children_) | 1248 for (const auto& child : children_) |
1222 child->DetachFromParent(); | 1249 child->DetachFromParent(); |
1223 | 1250 |
1224 children_.clear(); | 1251 children_.clear(); |
1225 have_children_ = false; | 1252 have_children_ = false; |
1226 } | 1253 } |
1227 | 1254 |
| 1255 Element* AXObjectImpl::GetElement() const { |
| 1256 Node* node = GetNode(); |
| 1257 return node && node->IsElementNode() ? ToElement(node) : nullptr; |
| 1258 } |
| 1259 |
1228 Document* AXObjectImpl::GetDocument() const { | 1260 Document* AXObjectImpl::GetDocument() const { |
1229 FrameView* frame_view = DocumentFrameView(); | 1261 FrameView* frame_view = DocumentFrameView(); |
1230 if (!frame_view) | 1262 if (!frame_view) |
1231 return 0; | 1263 return 0; |
1232 | 1264 |
1233 return frame_view->GetFrame().GetDocument(); | 1265 return frame_view->GetFrame().GetDocument(); |
1234 } | 1266 } |
1235 | 1267 |
1236 FrameView* AXObjectImpl::DocumentFrameView() const { | 1268 FrameView* AXObjectImpl::DocumentFrameView() const { |
1237 const AXObjectImpl* object = this; | 1269 const AXObjectImpl* object = this; |
(...skipping 19 matching lines...) Expand all Loading... |
1257 Document* doc = GetDocument(); | 1289 Document* doc = GetDocument(); |
1258 if (doc) | 1290 if (doc) |
1259 return doc->ContentLanguage(); | 1291 return doc->ContentLanguage(); |
1260 return g_null_atom; | 1292 return g_null_atom; |
1261 } | 1293 } |
1262 | 1294 |
1263 return parent->Language(); | 1295 return parent->Language(); |
1264 } | 1296 } |
1265 | 1297 |
1266 bool AXObjectImpl::HasAttribute(const QualifiedName& attribute) const { | 1298 bool AXObjectImpl::HasAttribute(const QualifiedName& attribute) const { |
1267 Node* element_node = GetNode(); | 1299 if (Element* element = GetElement()) |
1268 if (!element_node) | 1300 return element->FastHasAttribute(attribute); |
1269 return false; | 1301 return false; |
1270 | |
1271 if (!element_node->IsElementNode()) | |
1272 return false; | |
1273 | |
1274 Element* element = ToElement(element_node); | |
1275 return element->FastHasAttribute(attribute); | |
1276 } | 1302 } |
1277 | 1303 |
1278 const AtomicString& AXObjectImpl::GetAttribute( | 1304 const AtomicString& AXObjectImpl::GetAttribute( |
1279 const QualifiedName& attribute) const { | 1305 const QualifiedName& attribute) const { |
1280 Node* element_node = GetNode(); | 1306 if (Element* element = GetElement()) |
1281 if (!element_node) | 1307 return element->FastGetAttribute(attribute); |
1282 return g_null_atom; | 1308 return g_null_atom; |
1283 | |
1284 if (!element_node->IsElementNode()) | |
1285 return g_null_atom; | |
1286 | |
1287 Element* element = ToElement(element_node); | |
1288 return element->FastGetAttribute(attribute); | |
1289 } | 1309 } |
1290 | 1310 |
1291 // | 1311 // |
1292 // Scrollable containers. | 1312 // Scrollable containers. |
1293 // | 1313 // |
1294 | 1314 |
1295 bool AXObjectImpl::IsScrollableContainer() const { | 1315 bool AXObjectImpl::IsScrollableContainer() const { |
1296 return !!GetScrollableAreaIfScrollable(); | 1316 return !!GetScrollableAreaIfScrollable(); |
1297 } | 1317 } |
1298 | 1318 |
(...skipping 534 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1833 case kTreeItemRole: | 1853 case kTreeItemRole: |
1834 case kUserInterfaceTooltipRole: | 1854 case kUserInterfaceTooltipRole: |
1835 return true; | 1855 return true; |
1836 case kRowRole: { | 1856 case kRowRole: { |
1837 // Spec says we should always expose the name on rows, | 1857 // Spec says we should always expose the name on rows, |
1838 // but for performance reasons we only do it | 1858 // but for performance reasons we only do it |
1839 // if the row might receive focus | 1859 // if the row might receive focus |
1840 if (AncestorExposesActiveDescendant()) { | 1860 if (AncestorExposesActiveDescendant()) { |
1841 return true; | 1861 return true; |
1842 } | 1862 } |
1843 const Node* node = this->GetNode(); | 1863 const Element* element = this->GetElement(); |
1844 return node && node->IsElementNode() && ToElement(node)->IsFocusable(); | 1864 return element && element->IsFocusable(); |
1845 } | 1865 } |
1846 default: | 1866 default: |
1847 return false; | 1867 return false; |
1848 } | 1868 } |
1849 } | 1869 } |
1850 | 1870 |
1851 AccessibilityRole AXObjectImpl::ButtonRoleType() const { | 1871 AccessibilityRole AXObjectImpl::ButtonRoleType() const { |
1852 // If aria-pressed is present, then it should be exposed as a toggle button. | 1872 // If aria-pressed is present, then it should be exposed as a toggle button. |
1853 // http://www.w3.org/TR/wai-aria/states_and_properties#aria-pressed | 1873 // http://www.w3.org/TR/wai-aria/states_and_properties#aria-pressed |
1854 if (AriaPressedIsPresent()) | 1874 if (AriaPressedIsPresent()) |
(...skipping 20 matching lines...) Expand all Loading... |
1875 } | 1895 } |
1876 | 1896 |
1877 DEFINE_TRACE(AXObjectImpl) { | 1897 DEFINE_TRACE(AXObjectImpl) { |
1878 visitor->Trace(children_); | 1898 visitor->Trace(children_); |
1879 visitor->Trace(parent_); | 1899 visitor->Trace(parent_); |
1880 visitor->Trace(cached_live_region_root_); | 1900 visitor->Trace(cached_live_region_root_); |
1881 visitor->Trace(ax_object_cache_); | 1901 visitor->Trace(ax_object_cache_); |
1882 } | 1902 } |
1883 | 1903 |
1884 } // namespace blink | 1904 } // namespace blink |
OLD | NEW |