| 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 |