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 ignoredReasons->push_back(IgnoredReason(AXLabelFor, controlObject)); | 295 ignoredReasons->push_back(IgnoredReason(AXLabelFor, controlObject)); |
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 (ignoredReasons) | 304 if (ignoredReasons) |
305 ignoredReasons->push_back(IgnoredReason(AXNotRendered)); | 305 ignoredReasons->push_back(IgnoredReason(AXNotRendered)); |
306 return true; | 306 return true; |
307 } | 307 } |
308 | 308 |
309 if (m_role == UnknownRole) { | 309 if (m_role == UnknownRole) { |
310 if (ignoredReasons) | 310 if (ignoredReasons) |
311 ignoredReasons->push_back(IgnoredReason(AXUninteresting)); | 311 ignoredReasons->push_back(IgnoredReason(AXUninteresting)); |
312 return true; | 312 return true; |
313 } | 313 } |
(...skipping 721 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1035 | 1035 |
1036 bool AXNodeObject::isMenuButton() const { | 1036 bool AXNodeObject::isMenuButton() const { |
1037 return roleValue() == MenuButtonRole; | 1037 return roleValue() == MenuButtonRole; |
1038 } | 1038 } |
1039 | 1039 |
1040 bool AXNodeObject::isMeter() const { | 1040 bool AXNodeObject::isMeter() const { |
1041 return roleValue() == MeterRole; | 1041 return roleValue() == MeterRole; |
1042 } | 1042 } |
1043 | 1043 |
1044 bool AXNodeObject::isMultiSelectable() const { | 1044 bool AXNodeObject::isMultiSelectable() const { |
1045 const AtomicString& ariaMultiSelectable = | 1045 bool multiselectable = false; |
1046 getAttribute(aria_multiselectableAttr); | 1046 if (getAOMPropertyOrARIAAttribute(AOMBooleanProperty::kMultiselectable, |
1047 if (equalIgnoringASCIICase(ariaMultiSelectable, "true")) | 1047 multiselectable)) { |
1048 return true; | 1048 return multiselectable; |
1049 if (equalIgnoringASCIICase(ariaMultiSelectable, "false")) | 1049 } |
1050 return false; | |
1051 | 1050 |
1052 return isHTMLSelectElement(getNode()) && | 1051 return isHTMLSelectElement(getNode()) && |
1053 toHTMLSelectElement(*getNode()).isMultiple(); | 1052 toHTMLSelectElement(*getNode()).isMultiple(); |
1054 } | 1053 } |
1055 | 1054 |
1056 bool AXNodeObject::isNativeCheckboxOrRadio() const { | 1055 bool AXNodeObject::isNativeCheckboxOrRadio() const { |
1057 Node* node = this->getNode(); | 1056 Node* node = this->getNode(); |
1058 if (!isHTMLInputElement(node)) | 1057 if (!isHTMLInputElement(node)) |
1059 return false; | 1058 return false; |
1060 | 1059 |
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1203 | 1202 |
1204 AccessibilityExpanded AXNodeObject::isExpanded() const { | 1203 AccessibilityExpanded AXNodeObject::isExpanded() const { |
1205 if (getNode() && isHTMLSummaryElement(*getNode())) { | 1204 if (getNode() && isHTMLSummaryElement(*getNode())) { |
1206 if (getNode()->parentNode() && | 1205 if (getNode()->parentNode() && |
1207 isHTMLDetailsElement(getNode()->parentNode())) | 1206 isHTMLDetailsElement(getNode()->parentNode())) |
1208 return toElement(getNode()->parentNode())->hasAttribute(openAttr) | 1207 return toElement(getNode()->parentNode())->hasAttribute(openAttr) |
1209 ? ExpandedExpanded | 1208 ? ExpandedExpanded |
1210 : ExpandedCollapsed; | 1209 : ExpandedCollapsed; |
1211 } | 1210 } |
1212 | 1211 |
1213 const AtomicString& expanded = getAttribute(aria_expandedAttr); | 1212 bool expanded = false; |
1214 if (equalIgnoringASCIICase(expanded, "true")) | 1213 if (getAOMPropertyOrARIAAttribute(AOMBooleanProperty::kExpanded, expanded)) { |
1215 return ExpandedExpanded; | 1214 return expanded ? ExpandedExpanded : ExpandedCollapsed; |
1216 if (equalIgnoringASCIICase(expanded, "false")) | 1215 } |
1217 return ExpandedCollapsed; | |
1218 | 1216 |
1219 return ExpandedUndefined; | 1217 return ExpandedUndefined; |
1220 } | 1218 } |
1221 | 1219 |
1222 bool AXNodeObject::isModal() const { | 1220 bool AXNodeObject::isModal() const { |
1223 if (roleValue() != DialogRole && roleValue() != AlertDialogRole) | 1221 if (roleValue() != DialogRole && roleValue() != AlertDialogRole) |
1224 return false; | 1222 return false; |
1225 | 1223 |
1226 if (hasAttribute(aria_modalAttr)) { | 1224 bool modal = false; |
1227 const AtomicString& modal = getAttribute(aria_modalAttr); | 1225 if (getAOMPropertyOrARIAAttribute(AOMBooleanProperty::kModal, modal)) |
1228 if (equalIgnoringASCIICase(modal, "true")) | 1226 return modal; |
1229 return true; | |
1230 if (equalIgnoringASCIICase(modal, "false")) | |
1231 return false; | |
1232 } | |
1233 | 1227 |
1234 if (getNode() && isHTMLDialogElement(*getNode())) | 1228 if (getNode() && isHTMLDialogElement(*getNode())) |
1235 return toElement(getNode())->isInTopLayer(); | 1229 return toElement(getNode())->isInTopLayer(); |
1236 | 1230 |
1237 return false; | 1231 return false; |
1238 } | 1232 } |
1239 | 1233 |
1240 bool AXNodeObject::isPressed() const { | 1234 bool AXNodeObject::isPressed() const { |
1241 if (!isButton()) | 1235 if (!isButton()) |
1242 return false; | 1236 return false; |
(...skipping 30 matching lines...) Expand all Loading... |
1273 | 1267 |
1274 return !hasEditableStyle(*node); | 1268 return !hasEditableStyle(*node); |
1275 } | 1269 } |
1276 | 1270 |
1277 bool AXNodeObject::isRequired() const { | 1271 bool AXNodeObject::isRequired() const { |
1278 Node* n = this->getNode(); | 1272 Node* n = this->getNode(); |
1279 if (n && (n->isElementNode() && toElement(n)->isFormControlElement()) && | 1273 if (n && (n->isElementNode() && toElement(n)->isFormControlElement()) && |
1280 hasAttribute(requiredAttr)) | 1274 hasAttribute(requiredAttr)) |
1281 return toHTMLFormControlElement(n)->isRequired(); | 1275 return toHTMLFormControlElement(n)->isRequired(); |
1282 | 1276 |
1283 if (equalIgnoringASCIICase(getAttribute(aria_requiredAttr), "true")) | 1277 if (AOMPropertyOrARIAAttributeIsTrue(AOMBooleanProperty::kRequired)) |
1284 return true; | 1278 return true; |
1285 | 1279 |
1286 return false; | 1280 return false; |
1287 } | 1281 } |
1288 | 1282 |
1289 bool AXNodeObject::canSetFocusAttribute() const { | 1283 bool AXNodeObject::canSetFocusAttribute() const { |
1290 Node* node = getNode(); | 1284 Node* node = getNode(); |
1291 if (!node) | 1285 if (!node) |
1292 return false; | 1286 return false; |
1293 | 1287 |
1294 if (isWebArea()) | 1288 if (isWebArea()) |
1295 return true; | 1289 return true; |
1296 | 1290 |
1297 // Children of elements with an aria-activedescendant attribute should be | 1291 // Children of elements with an aria-activedescendant attribute should be |
1298 // focusable if they have a (non-presentational) ARIA role. | 1292 // focusable if they have a (non-presentational) ARIA role. |
1299 if (!isPresentational() && ariaRoleAttribute() != UnknownRole && | 1293 if (!isPresentational() && ariaRoleAttribute() != UnknownRole && |
1300 ancestorExposesActiveDescendant()) | 1294 ancestorExposesActiveDescendant()) |
1301 return true; | 1295 return true; |
1302 | 1296 |
1303 // NOTE: It would be more accurate to ask the document whether | 1297 // NOTE: It would be more accurate to ask the document whether |
1304 // setFocusedNode() would do anything. For example, setFocusedNode() will do | 1298 // setFocusedNode() would do anything. For example, setFocusedNode() will do |
1305 // nothing if the current focused node will not relinquish the focus. | 1299 // nothing if the current focused node will not relinquish the focus. |
1306 if (isDisabledFormControl(node)) | 1300 if (isDisabledFormControl(node)) |
1307 return false; | 1301 return false; |
1308 | 1302 |
1309 return node->isElementNode() && toElement(node)->supportsFocus(); | 1303 return node->isElementNode() && toElement(node)->supportsFocus(); |
1310 } | 1304 } |
1311 | 1305 |
1312 bool AXNodeObject::canSetValueAttribute() const { | 1306 bool AXNodeObject::canSetValueAttribute() const { |
1313 if (equalIgnoringASCIICase(getAttribute(aria_readonlyAttr), "true")) | 1307 if (AOMPropertyOrARIAAttributeIsTrue(AOMBooleanProperty::kReadOnly)) |
1314 return false; | 1308 return false; |
1315 | 1309 |
1316 if (isProgressIndicator() || isSlider()) | 1310 if (isProgressIndicator() || isSlider()) |
1317 return true; | 1311 return true; |
1318 | 1312 |
1319 if (isTextControl() && !isNativeTextControl()) | 1313 if (isTextControl() && !isNativeTextControl()) |
1320 return true; | 1314 return true; |
1321 | 1315 |
1322 // Any node could be contenteditable, so isReadOnly should be relied upon | 1316 // Any node could be contenteditable, so isReadOnly should be relied upon |
1323 // for this information for all elements. | 1317 // for this information for all elements. |
(...skipping 666 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1990 } | 1984 } |
1991 for (const auto& ownedChild : ownedChildren) | 1985 for (const auto& ownedChild : ownedChildren) |
1992 children.push_back(ownedChild); | 1986 children.push_back(ownedChild); |
1993 | 1987 |
1994 for (AXObject* child : children) { | 1988 for (AXObject* child : children) { |
1995 // Don't recurse into children that are explicitly marked as aria-hidden. | 1989 // Don't recurse into children that are explicitly marked as aria-hidden. |
1996 // Note that we don't call isInertOrAriaHidden because that would return | 1990 // Note that we don't call isInertOrAriaHidden because that would return |
1997 // true if any ancestor is hidden, but we need to be able to compute the | 1991 // true if any ancestor is hidden, but we need to be able to compute the |
1998 // accessible name of object inside hidden subtrees (for example, if | 1992 // accessible name of object inside hidden subtrees (for example, if |
1999 // aria-labelledby points to an object that's hidden). | 1993 // aria-labelledby points to an object that's hidden). |
2000 if (equalIgnoringASCIICase(child->getAttribute(aria_hiddenAttr), "true")) | 1994 if (child->AOMPropertyOrARIAAttributeIsTrue(AOMBooleanProperty::kHidden)) |
2001 continue; | 1995 continue; |
2002 | 1996 |
2003 // If we're going between two layoutObjects that are in separate | 1997 // If we're going between two layoutObjects that are in separate |
2004 // LayoutBoxes, add whitespace if it wasn't there already. Intuitively if | 1998 // LayoutBoxes, add whitespace if it wasn't there already. Intuitively if |
2005 // you have <span>Hello</span><span>World</span>, those are part of the same | 1999 // you have <span>Hello</span><span>World</span>, those are part of the same |
2006 // LayoutBox so we should return "HelloWorld", but given | 2000 // LayoutBox so we should return "HelloWorld", but given |
2007 // <div>Hello</div><div>World</div> the strings are in separate boxes so we | 2001 // <div>Hello</div><div>World</div> the strings are in separate boxes so we |
2008 // should return "Hello World". | 2002 // should return "Hello World". |
2009 if (previous && accumulatedText.length() && | 2003 if (previous && accumulatedText.length() && |
2010 !isHTMLSpace(accumulatedText[accumulatedText.length() - 1])) { | 2004 !isHTMLSpace(accumulatedText[accumulatedText.length() - 1])) { |
(...skipping 1250 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3261 return String(); | 3255 return String(); |
3262 return toTextControlElement(node)->strippedPlaceholder(); | 3256 return toTextControlElement(node)->strippedPlaceholder(); |
3263 } | 3257 } |
3264 | 3258 |
3265 DEFINE_TRACE(AXNodeObject) { | 3259 DEFINE_TRACE(AXNodeObject) { |
3266 visitor->trace(m_node); | 3260 visitor->trace(m_node); |
3267 AXObject::trace(visitor); | 3261 AXObject::trace(visitor); |
3268 } | 3262 } |
3269 | 3263 |
3270 } // namespace blink | 3264 } // namespace blink |
OLD | NEW |