| 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 282 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 293 } | 293 } |
| 294 | 294 |
| 295 ignored_reasons->push_back(IgnoredReason(kAXLabelFor, control_object)); | 295 ignored_reasons->push_back(IgnoredReason(kAXLabelFor, control_object)); |
| 296 } | 296 } |
| 297 return true; | 297 return true; |
| 298 } | 298 } |
| 299 | 299 |
| 300 Element* element = GetNode()->IsElementNode() ? ToElement(GetNode()) | 300 Element* element = GetNode()->IsElementNode() ? ToElement(GetNode()) |
| 301 : GetNode()->parentElement(); | 301 : GetNode()->parentElement(); |
| 302 if (!GetLayoutObject() && (!element || !element->IsInCanvasSubtree()) && | 302 if (!GetLayoutObject() && (!element || !element->IsInCanvasSubtree()) && |
| 303 !EqualIgnoringASCIICase(GetAttribute(aria_hiddenAttr), "false")) { | 303 !AOMPropertyOrARIAAttributeIsFalse(AOMBooleanProperty::kHidden)) { |
| 304 if (ignored_reasons) | 304 if (ignored_reasons) |
| 305 ignored_reasons->push_back(IgnoredReason(kAXNotRendered)); | 305 ignored_reasons->push_back(IgnoredReason(kAXNotRendered)); |
| 306 return true; | 306 return true; |
| 307 } | 307 } |
| 308 | 308 |
| 309 if (role_ == kUnknownRole) { | 309 if (role_ == kUnknownRole) { |
| 310 if (ignored_reasons) | 310 if (ignored_reasons) |
| 311 ignored_reasons->push_back(IgnoredReason(kAXUninteresting)); | 311 ignored_reasons->push_back(IgnoredReason(kAXUninteresting)); |
| 312 return true; | 312 return true; |
| 313 } | 313 } |
| (...skipping 504 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 818 } | 818 } |
| 819 | 819 |
| 820 static Element* SiblingWithAriaRole(String role, Node* node) { | 820 static Element* SiblingWithAriaRole(String role, Node* node) { |
| 821 Node* parent = node->parentNode(); | 821 Node* parent = node->parentNode(); |
| 822 if (!parent) | 822 if (!parent) |
| 823 return 0; | 823 return 0; |
| 824 | 824 |
| 825 for (Element* sibling = ElementTraversal::FirstChild(*parent); sibling; | 825 for (Element* sibling = ElementTraversal::FirstChild(*parent); sibling; |
| 826 sibling = ElementTraversal::NextSibling(*sibling)) { | 826 sibling = ElementTraversal::NextSibling(*sibling)) { |
| 827 const AtomicString& sibling_aria_role = | 827 const AtomicString& sibling_aria_role = |
| 828 AccessibleNode::GetProperty(sibling, AOMStringProperty::kRole); | 828 AccessibleNode::GetPropertyOrARIAAttribute(sibling, |
| 829 AOMStringProperty::kRole); |
| 829 if (EqualIgnoringASCIICase(sibling_aria_role, role)) | 830 if (EqualIgnoringASCIICase(sibling_aria_role, role)) |
| 830 return sibling; | 831 return sibling; |
| 831 } | 832 } |
| 832 | 833 |
| 833 return 0; | 834 return 0; |
| 834 } | 835 } |
| 835 | 836 |
| 836 Element* AXNodeObject::MenuItemElementForMenu() const { | 837 Element* AXNodeObject::MenuItemElementForMenu() const { |
| 837 if (AriaRoleAttribute() != kMenuRole) | 838 if (AriaRoleAttribute() != kMenuRole) |
| 838 return 0; | 839 return 0; |
| (...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1039 | 1040 |
| 1040 bool AXNodeObject::IsMenuButton() const { | 1041 bool AXNodeObject::IsMenuButton() const { |
| 1041 return RoleValue() == kMenuButtonRole; | 1042 return RoleValue() == kMenuButtonRole; |
| 1042 } | 1043 } |
| 1043 | 1044 |
| 1044 bool AXNodeObject::IsMeter() const { | 1045 bool AXNodeObject::IsMeter() const { |
| 1045 return RoleValue() == kMeterRole; | 1046 return RoleValue() == kMeterRole; |
| 1046 } | 1047 } |
| 1047 | 1048 |
| 1048 bool AXNodeObject::IsMultiSelectable() const { | 1049 bool AXNodeObject::IsMultiSelectable() const { |
| 1049 const AtomicString& aria_multi_selectable = | 1050 bool multiselectable = false; |
| 1050 GetAttribute(aria_multiselectableAttr); | 1051 if (HasAOMPropertyOrARIAAttribute(AOMBooleanProperty::kMultiselectable, |
| 1051 if (EqualIgnoringASCIICase(aria_multi_selectable, "true")) | 1052 multiselectable)) { |
| 1052 return true; | 1053 return multiselectable; |
| 1053 if (EqualIgnoringASCIICase(aria_multi_selectable, "false")) | 1054 } |
| 1054 return false; | |
| 1055 | 1055 |
| 1056 return isHTMLSelectElement(GetNode()) && | 1056 return isHTMLSelectElement(GetNode()) && |
| 1057 toHTMLSelectElement(*GetNode()).IsMultiple(); | 1057 toHTMLSelectElement(*GetNode()).IsMultiple(); |
| 1058 } | 1058 } |
| 1059 | 1059 |
| 1060 bool AXNodeObject::IsNativeCheckboxOrRadio() const { | 1060 bool AXNodeObject::IsNativeCheckboxOrRadio() const { |
| 1061 Node* node = this->GetNode(); | 1061 Node* node = this->GetNode(); |
| 1062 if (!isHTMLInputElement(node)) | 1062 if (!isHTMLInputElement(node)) |
| 1063 return false; | 1063 return false; |
| 1064 | 1064 |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1177 | 1177 |
| 1178 AccessibilityExpanded AXNodeObject::IsExpanded() const { | 1178 AccessibilityExpanded AXNodeObject::IsExpanded() const { |
| 1179 if (GetNode() && isHTMLSummaryElement(*GetNode())) { | 1179 if (GetNode() && isHTMLSummaryElement(*GetNode())) { |
| 1180 if (GetNode()->parentNode() && | 1180 if (GetNode()->parentNode() && |
| 1181 isHTMLDetailsElement(GetNode()->parentNode())) | 1181 isHTMLDetailsElement(GetNode()->parentNode())) |
| 1182 return ToElement(GetNode()->parentNode())->hasAttribute(openAttr) | 1182 return ToElement(GetNode()->parentNode())->hasAttribute(openAttr) |
| 1183 ? kExpandedExpanded | 1183 ? kExpandedExpanded |
| 1184 : kExpandedCollapsed; | 1184 : kExpandedCollapsed; |
| 1185 } | 1185 } |
| 1186 | 1186 |
| 1187 const AtomicString& expanded = GetAttribute(aria_expandedAttr); | 1187 bool expanded = false; |
| 1188 if (EqualIgnoringASCIICase(expanded, "true")) | 1188 if (HasAOMPropertyOrARIAAttribute(AOMBooleanProperty::kExpanded, expanded)) { |
| 1189 return kExpandedExpanded; | 1189 return expanded ? kExpandedExpanded : kExpandedCollapsed; |
| 1190 if (EqualIgnoringASCIICase(expanded, "false")) | 1190 } |
| 1191 return kExpandedCollapsed; | |
| 1192 | 1191 |
| 1193 return kExpandedUndefined; | 1192 return kExpandedUndefined; |
| 1194 } | 1193 } |
| 1195 | 1194 |
| 1196 bool AXNodeObject::IsModal() const { | 1195 bool AXNodeObject::IsModal() const { |
| 1197 if (RoleValue() != kDialogRole && RoleValue() != kAlertDialogRole) | 1196 if (RoleValue() != kDialogRole && RoleValue() != kAlertDialogRole) |
| 1198 return false; | 1197 return false; |
| 1199 | 1198 |
| 1200 if (HasAttribute(aria_modalAttr)) { | 1199 bool modal = false; |
| 1201 const AtomicString& modal = GetAttribute(aria_modalAttr); | 1200 if (HasAOMPropertyOrARIAAttribute(AOMBooleanProperty::kModal, modal)) |
| 1202 if (EqualIgnoringASCIICase(modal, "true")) | 1201 return modal; |
| 1203 return true; | |
| 1204 if (EqualIgnoringASCIICase(modal, "false")) | |
| 1205 return false; | |
| 1206 } | |
| 1207 | 1202 |
| 1208 if (GetNode() && isHTMLDialogElement(*GetNode())) | 1203 if (GetNode() && isHTMLDialogElement(*GetNode())) |
| 1209 return ToElement(GetNode())->IsInTopLayer(); | 1204 return ToElement(GetNode())->IsInTopLayer(); |
| 1210 | 1205 |
| 1211 return false; | 1206 return false; |
| 1212 } | 1207 } |
| 1213 | 1208 |
| 1214 bool AXNodeObject::IsPressed() const { | 1209 bool AXNodeObject::IsPressed() const { |
| 1215 if (!IsButton()) | 1210 if (!IsButton()) |
| 1216 return false; | 1211 return false; |
| (...skipping 30 matching lines...) Expand all Loading... |
| 1247 | 1242 |
| 1248 return !HasEditableStyle(*node); | 1243 return !HasEditableStyle(*node); |
| 1249 } | 1244 } |
| 1250 | 1245 |
| 1251 bool AXNodeObject::IsRequired() const { | 1246 bool AXNodeObject::IsRequired() const { |
| 1252 Node* n = this->GetNode(); | 1247 Node* n = this->GetNode(); |
| 1253 if (n && (n->IsElementNode() && ToElement(n)->IsFormControlElement()) && | 1248 if (n && (n->IsElementNode() && ToElement(n)->IsFormControlElement()) && |
| 1254 HasAttribute(requiredAttr)) | 1249 HasAttribute(requiredAttr)) |
| 1255 return ToHTMLFormControlElement(n)->IsRequired(); | 1250 return ToHTMLFormControlElement(n)->IsRequired(); |
| 1256 | 1251 |
| 1257 if (EqualIgnoringASCIICase(GetAttribute(aria_requiredAttr), "true")) | 1252 if (AOMPropertyOrARIAAttributeIsTrue(AOMBooleanProperty::kRequired)) |
| 1258 return true; | 1253 return true; |
| 1259 | 1254 |
| 1260 return false; | 1255 return false; |
| 1261 } | 1256 } |
| 1262 | 1257 |
| 1263 bool AXNodeObject::CanSetFocusAttribute() const { | 1258 bool AXNodeObject::CanSetFocusAttribute() const { |
| 1264 Node* node = GetNode(); | 1259 Node* node = GetNode(); |
| 1265 if (!node) | 1260 if (!node) |
| 1266 return false; | 1261 return false; |
| 1267 | 1262 |
| 1268 if (IsWebArea()) | 1263 if (IsWebArea()) |
| 1269 return true; | 1264 return true; |
| 1270 | 1265 |
| 1271 // Children of elements with an aria-activedescendant attribute should be | 1266 // Children of elements with an aria-activedescendant attribute should be |
| 1272 // focusable if they have a (non-presentational) ARIA role. | 1267 // focusable if they have a (non-presentational) ARIA role. |
| 1273 if (!IsPresentational() && AriaRoleAttribute() != kUnknownRole && | 1268 if (!IsPresentational() && AriaRoleAttribute() != kUnknownRole && |
| 1274 AncestorExposesActiveDescendant()) | 1269 AncestorExposesActiveDescendant()) |
| 1275 return true; | 1270 return true; |
| 1276 | 1271 |
| 1277 // NOTE: It would be more accurate to ask the document whether | 1272 // NOTE: It would be more accurate to ask the document whether |
| 1278 // setFocusedNode() would do anything. For example, setFocusedNode() will do | 1273 // setFocusedNode() would do anything. For example, setFocusedNode() will do |
| 1279 // nothing if the current focused node will not relinquish the focus. | 1274 // nothing if the current focused node will not relinquish the focus. |
| 1280 if (IsDisabledFormControl(node)) | 1275 if (IsDisabledFormControl(node)) |
| 1281 return false; | 1276 return false; |
| 1282 | 1277 |
| 1283 return node->IsElementNode() && ToElement(node)->SupportsFocus(); | 1278 return node->IsElementNode() && ToElement(node)->SupportsFocus(); |
| 1284 } | 1279 } |
| 1285 | 1280 |
| 1286 bool AXNodeObject::CanSetValueAttribute() const { | 1281 bool AXNodeObject::CanSetValueAttribute() const { |
| 1287 if (EqualIgnoringASCIICase(GetAttribute(aria_readonlyAttr), "true")) | 1282 if (AOMPropertyOrARIAAttributeIsTrue(AOMBooleanProperty::kReadOnly)) |
| 1288 return false; | 1283 return false; |
| 1289 | 1284 |
| 1290 if (IsProgressIndicator() || IsSlider()) | 1285 if (IsProgressIndicator() || IsSlider()) |
| 1291 return true; | 1286 return true; |
| 1292 | 1287 |
| 1293 if (IsTextControl() && !IsNativeTextControl()) | 1288 if (IsTextControl() && !IsNativeTextControl()) |
| 1294 return true; | 1289 return true; |
| 1295 | 1290 |
| 1296 // Any node could be contenteditable, so isReadOnly should be relied upon | 1291 // Any node could be contenteditable, so isReadOnly should be relied upon |
| 1297 // for this information for all elements. | 1292 // for this information for all elements. |
| (...skipping 651 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1949 } | 1944 } |
| 1950 for (const auto& owned_child : owned_children) | 1945 for (const auto& owned_child : owned_children) |
| 1951 children.push_back(owned_child); | 1946 children.push_back(owned_child); |
| 1952 | 1947 |
| 1953 for (AXObjectImpl* child : children) { | 1948 for (AXObjectImpl* child : children) { |
| 1954 // Don't recurse into children that are explicitly marked as aria-hidden. | 1949 // Don't recurse into children that are explicitly marked as aria-hidden. |
| 1955 // Note that we don't call isInertOrAriaHidden because that would return | 1950 // Note that we don't call isInertOrAriaHidden because that would return |
| 1956 // true if any ancestor is hidden, but we need to be able to compute the | 1951 // true if any ancestor is hidden, but we need to be able to compute the |
| 1957 // accessible name of object inside hidden subtrees (for example, if | 1952 // accessible name of object inside hidden subtrees (for example, if |
| 1958 // aria-labelledby points to an object that's hidden). | 1953 // aria-labelledby points to an object that's hidden). |
| 1959 if (EqualIgnoringASCIICase(child->GetAttribute(aria_hiddenAttr), "true")) | 1954 if (child->AOMPropertyOrARIAAttributeIsTrue(AOMBooleanProperty::kHidden)) |
| 1960 continue; | 1955 continue; |
| 1961 | 1956 |
| 1962 // If we're going between two layoutObjects that are in separate | 1957 // If we're going between two layoutObjects that are in separate |
| 1963 // LayoutBoxes, add whitespace if it wasn't there already. Intuitively if | 1958 // LayoutBoxes, add whitespace if it wasn't there already. Intuitively if |
| 1964 // you have <span>Hello</span><span>World</span>, those are part of the same | 1959 // you have <span>Hello</span><span>World</span>, those are part of the same |
| 1965 // LayoutBox so we should return "HelloWorld", but given | 1960 // LayoutBox so we should return "HelloWorld", but given |
| 1966 // <div>Hello</div><div>World</div> the strings are in separate boxes so we | 1961 // <div>Hello</div><div>World</div> the strings are in separate boxes so we |
| 1967 // should return "Hello World". | 1962 // should return "Hello World". |
| 1968 if (previous && accumulated_text.length() && | 1963 if (previous && accumulated_text.length() && |
| 1969 !IsHTMLSpace(accumulated_text[accumulated_text.length() - 1])) { | 1964 !IsHTMLSpace(accumulated_text[accumulated_text.length() - 1])) { |
| (...skipping 971 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2941 if (IsWebArea()) { | 2936 if (IsWebArea()) { |
| 2942 Document* document = this->GetDocument(); | 2937 Document* document = this->GetDocument(); |
| 2943 if (document) { | 2938 if (document) { |
| 2944 name_from = kAXNameFromAttribute; | 2939 name_from = kAXNameFromAttribute; |
| 2945 if (name_sources) { | 2940 if (name_sources) { |
| 2946 name_sources->push_back( | 2941 name_sources->push_back( |
| 2947 NameSource(found_text_alternative, aria_labelAttr)); | 2942 NameSource(found_text_alternative, aria_labelAttr)); |
| 2948 name_sources->back().type = name_from; | 2943 name_sources->back().type = name_from; |
| 2949 } | 2944 } |
| 2950 if (Element* document_element = document->documentElement()) { | 2945 if (Element* document_element = document->documentElement()) { |
| 2951 const AtomicString& aria_label = AccessibleNode::GetProperty( | 2946 const AtomicString& aria_label = |
| 2952 document_element, AOMStringProperty::kLabel); | 2947 AccessibleNode::GetPropertyOrARIAAttribute( |
| 2948 document_element, AOMStringProperty::kLabel); |
| 2953 if (!aria_label.IsEmpty()) { | 2949 if (!aria_label.IsEmpty()) { |
| 2954 text_alternative = aria_label; | 2950 text_alternative = aria_label; |
| 2955 | 2951 |
| 2956 if (name_sources) { | 2952 if (name_sources) { |
| 2957 NameSource& source = name_sources->back(); | 2953 NameSource& source = name_sources->back(); |
| 2958 source.text = text_alternative; | 2954 source.text = text_alternative; |
| 2959 source.attribute_value = aria_label; | 2955 source.attribute_value = aria_label; |
| 2960 *found_text_alternative = true; | 2956 *found_text_alternative = true; |
| 2961 } else { | 2957 } else { |
| 2962 return text_alternative; | 2958 return text_alternative; |
| (...skipping 267 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3230 return String(); | 3226 return String(); |
| 3231 return ToTextControlElement(node)->StrippedPlaceholder(); | 3227 return ToTextControlElement(node)->StrippedPlaceholder(); |
| 3232 } | 3228 } |
| 3233 | 3229 |
| 3234 DEFINE_TRACE(AXNodeObject) { | 3230 DEFINE_TRACE(AXNodeObject) { |
| 3235 visitor->Trace(node_); | 3231 visitor->Trace(node_); |
| 3236 AXObjectImpl::Trace(visitor); | 3232 AXObjectImpl::Trace(visitor); |
| 3237 } | 3233 } |
| 3238 | 3234 |
| 3239 } // namespace blink | 3235 } // namespace blink |
| OLD | NEW |