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

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

Issue 2805493002: Boolean properties for Accessibility Object Model Phase 1 (Closed)
Patch Set: Back to previous patchset, ready to land Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2012, Google Inc. All rights reserved. 2 * Copyright (C) 2012, Google Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions 5 * modification, are permitted provided that the following conditions
6 * are met: 6 * are met:
7 * 7 *
8 * 1. Redistributions of source code must retain the above copyright 8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer. 9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright 10 * 2. Redistributions in binary form must reproduce the above copyright
(...skipping 282 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698