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 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
89 public: | 89 public: |
90 BoolAttributeSetter(AXBoolAttribute attribute) : m_attribute(attribute) {} | 90 BoolAttributeSetter(AXBoolAttribute attribute) : m_attribute(attribute) {} |
91 | 91 |
92 private: | 92 private: |
93 AXBoolAttribute m_attribute; | 93 AXBoolAttribute m_attribute; |
94 | 94 |
95 void run(const AXObject& obj, | 95 void run(const AXObject& obj, |
96 AXSparseAttributeClient& attributeMap, | 96 AXSparseAttributeClient& attributeMap, |
97 const AtomicString& value) override { | 97 const AtomicString& value) override { |
98 attributeMap.addBoolAttribute(m_attribute, | 98 attributeMap.addBoolAttribute(m_attribute, |
99 equalIgnoringCase(value, "true")); | 99 equalIgnoringASCIICase(value, "true")); |
100 } | 100 } |
101 }; | 101 }; |
102 | 102 |
103 class StringAttributeSetter : public SparseAttributeSetter { | 103 class StringAttributeSetter : public SparseAttributeSetter { |
104 public: | 104 public: |
105 StringAttributeSetter(AXStringAttribute attribute) : m_attribute(attribute) {} | 105 StringAttributeSetter(AXStringAttribute attribute) : m_attribute(attribute) {} |
106 | 106 |
107 private: | 107 private: |
108 AXStringAttribute m_attribute; | 108 AXStringAttribute m_attribute; |
109 | 109 |
(...skipping 183 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 !equalIgnoringCase(getAttribute(aria_hiddenAttr), "false")) { | 303 !equalIgnoringASCIICase(getAttribute(aria_hiddenAttr), "false")) { |
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 429 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
743 | 743 |
744 // This only returns true if this is the element that actually has the | 744 // This only returns true if this is the element that actually has the |
745 // contentEditable attribute set, unlike node->hasEditableStyle() which will | 745 // contentEditable attribute set, unlike node->hasEditableStyle() which will |
746 // also return true if an ancestor is editable. | 746 // also return true if an ancestor is editable. |
747 bool AXNodeObject::hasContentEditableAttributeSet() const { | 747 bool AXNodeObject::hasContentEditableAttributeSet() const { |
748 const AtomicString& contentEditableValue = getAttribute(contenteditableAttr); | 748 const AtomicString& contentEditableValue = getAttribute(contenteditableAttr); |
749 if (contentEditableValue.isNull()) | 749 if (contentEditableValue.isNull()) |
750 return false; | 750 return false; |
751 // Both "true" (case-insensitive) and the empty string count as true. | 751 // Both "true" (case-insensitive) and the empty string count as true. |
752 return contentEditableValue.isEmpty() || | 752 return contentEditableValue.isEmpty() || |
753 equalIgnoringCase(contentEditableValue, "true"); | 753 equalIgnoringASCIICase(contentEditableValue, "true"); |
754 } | 754 } |
755 | 755 |
756 bool AXNodeObject::isTextControl() const { | 756 bool AXNodeObject::isTextControl() const { |
757 if (hasContentEditableAttributeSet()) | 757 if (hasContentEditableAttributeSet()) |
758 return true; | 758 return true; |
759 | 759 |
760 switch (roleValue()) { | 760 switch (roleValue()) { |
761 case TextFieldRole: | 761 case TextFieldRole: |
762 case ComboBoxRole: | 762 case ComboBoxRole: |
763 case SearchBoxRole: | 763 case SearchBoxRole: |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
818 | 818 |
819 static Element* siblingWithAriaRole(String role, Node* node) { | 819 static Element* siblingWithAriaRole(String role, Node* node) { |
820 Node* parent = node->parentNode(); | 820 Node* parent = node->parentNode(); |
821 if (!parent) | 821 if (!parent) |
822 return 0; | 822 return 0; |
823 | 823 |
824 for (Element* sibling = ElementTraversal::firstChild(*parent); sibling; | 824 for (Element* sibling = ElementTraversal::firstChild(*parent); sibling; |
825 sibling = ElementTraversal::nextSibling(*sibling)) { | 825 sibling = ElementTraversal::nextSibling(*sibling)) { |
826 const AtomicString& siblingAriaRole = | 826 const AtomicString& siblingAriaRole = |
827 AccessibleNode::getProperty(sibling, AOMStringProperty::kRole); | 827 AccessibleNode::getProperty(sibling, AOMStringProperty::kRole); |
828 if (equalIgnoringCase(siblingAriaRole, role)) | 828 if (equalIgnoringASCIICase(siblingAriaRole, role)) |
829 return sibling; | 829 return sibling; |
830 } | 830 } |
831 | 831 |
832 return 0; | 832 return 0; |
833 } | 833 } |
834 | 834 |
835 Element* AXNodeObject::menuItemElementForMenu() const { | 835 Element* AXNodeObject::menuItemElementForMenu() const { |
836 if (ariaRoleAttribute() != MenuRole) | 836 if (ariaRoleAttribute() != MenuRole) |
837 return 0; | 837 return 0; |
838 | 838 |
(...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
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 const AtomicString& ariaMultiSelectable = |
1046 getAttribute(aria_multiselectableAttr); | 1046 getAttribute(aria_multiselectableAttr); |
1047 if (equalIgnoringCase(ariaMultiSelectable, "true")) | 1047 if (equalIgnoringASCIICase(ariaMultiSelectable, "true")) |
1048 return true; | 1048 return true; |
1049 if (equalIgnoringCase(ariaMultiSelectable, "false")) | 1049 if (equalIgnoringASCIICase(ariaMultiSelectable, "false")) |
1050 return false; | 1050 return false; |
1051 | 1051 |
1052 return isHTMLSelectElement(getNode()) && | 1052 return isHTMLSelectElement(getNode()) && |
1053 toHTMLSelectElement(*getNode()).isMultiple(); | 1053 toHTMLSelectElement(*getNode()).isMultiple(); |
1054 } | 1054 } |
1055 | 1055 |
1056 bool AXNodeObject::isNativeCheckboxOrRadio() const { | 1056 bool AXNodeObject::isNativeCheckboxOrRadio() const { |
1057 Node* node = this->getNode(); | 1057 Node* node = this->getNode(); |
1058 if (!isHTMLInputElement(node)) | 1058 if (!isHTMLInputElement(node)) |
1059 return false; | 1059 return false; |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1152 return toHTMLInputElement(*node).shouldAppearChecked(); | 1152 return toHTMLInputElement(*node).shouldAppearChecked(); |
1153 | 1153 |
1154 // Else, if this is an ARIA role checkbox or radio or menuitemcheckbox | 1154 // Else, if this is an ARIA role checkbox or radio or menuitemcheckbox |
1155 // or menuitemradio or switch, respect the aria-checked attribute | 1155 // or menuitemradio or switch, respect the aria-checked attribute |
1156 switch (ariaRoleAttribute()) { | 1156 switch (ariaRoleAttribute()) { |
1157 case CheckBoxRole: | 1157 case CheckBoxRole: |
1158 case MenuItemCheckBoxRole: | 1158 case MenuItemCheckBoxRole: |
1159 case MenuItemRadioRole: | 1159 case MenuItemRadioRole: |
1160 case RadioButtonRole: | 1160 case RadioButtonRole: |
1161 case SwitchRole: | 1161 case SwitchRole: |
1162 if (equalIgnoringCase( | 1162 if (equalIgnoringASCIICase( |
1163 getAOMPropertyOrARIAAttribute(AOMStringProperty::kChecked), | 1163 getAOMPropertyOrARIAAttribute(AOMStringProperty::kChecked), |
1164 "true")) | 1164 "true")) |
1165 return true; | 1165 return true; |
1166 return false; | 1166 return false; |
1167 default: | 1167 default: |
1168 break; | 1168 break; |
1169 } | 1169 } |
1170 | 1170 |
1171 // Otherwise it's not checked | 1171 // Otherwise it's not checked |
1172 return false; | 1172 return false; |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1204 AccessibilityExpanded AXNodeObject::isExpanded() const { | 1204 AccessibilityExpanded AXNodeObject::isExpanded() const { |
1205 if (getNode() && isHTMLSummaryElement(*getNode())) { | 1205 if (getNode() && isHTMLSummaryElement(*getNode())) { |
1206 if (getNode()->parentNode() && | 1206 if (getNode()->parentNode() && |
1207 isHTMLDetailsElement(getNode()->parentNode())) | 1207 isHTMLDetailsElement(getNode()->parentNode())) |
1208 return toElement(getNode()->parentNode())->hasAttribute(openAttr) | 1208 return toElement(getNode()->parentNode())->hasAttribute(openAttr) |
1209 ? ExpandedExpanded | 1209 ? ExpandedExpanded |
1210 : ExpandedCollapsed; | 1210 : ExpandedCollapsed; |
1211 } | 1211 } |
1212 | 1212 |
1213 const AtomicString& expanded = getAttribute(aria_expandedAttr); | 1213 const AtomicString& expanded = getAttribute(aria_expandedAttr); |
1214 if (equalIgnoringCase(expanded, "true")) | 1214 if (equalIgnoringASCIICase(expanded, "true")) |
1215 return ExpandedExpanded; | 1215 return ExpandedExpanded; |
1216 if (equalIgnoringCase(expanded, "false")) | 1216 if (equalIgnoringASCIICase(expanded, "false")) |
1217 return ExpandedCollapsed; | 1217 return ExpandedCollapsed; |
1218 | 1218 |
1219 return ExpandedUndefined; | 1219 return ExpandedUndefined; |
1220 } | 1220 } |
1221 | 1221 |
1222 bool AXNodeObject::isModal() const { | 1222 bool AXNodeObject::isModal() const { |
1223 if (roleValue() != DialogRole && roleValue() != AlertDialogRole) | 1223 if (roleValue() != DialogRole && roleValue() != AlertDialogRole) |
1224 return false; | 1224 return false; |
1225 | 1225 |
1226 if (hasAttribute(aria_modalAttr)) { | 1226 if (hasAttribute(aria_modalAttr)) { |
1227 const AtomicString& modal = getAttribute(aria_modalAttr); | 1227 const AtomicString& modal = getAttribute(aria_modalAttr); |
1228 if (equalIgnoringCase(modal, "true")) | 1228 if (equalIgnoringASCIICase(modal, "true")) |
1229 return true; | 1229 return true; |
1230 if (equalIgnoringCase(modal, "false")) | 1230 if (equalIgnoringASCIICase(modal, "false")) |
1231 return false; | 1231 return false; |
1232 } | 1232 } |
1233 | 1233 |
1234 if (getNode() && isHTMLDialogElement(*getNode())) | 1234 if (getNode() && isHTMLDialogElement(*getNode())) |
1235 return toElement(getNode())->isInTopLayer(); | 1235 return toElement(getNode())->isInTopLayer(); |
1236 | 1236 |
1237 return false; | 1237 return false; |
1238 } | 1238 } |
1239 | 1239 |
1240 bool AXNodeObject::isPressed() const { | 1240 bool AXNodeObject::isPressed() const { |
1241 if (!isButton()) | 1241 if (!isButton()) |
1242 return false; | 1242 return false; |
1243 | 1243 |
1244 Node* node = this->getNode(); | 1244 Node* node = this->getNode(); |
1245 if (!node) | 1245 if (!node) |
1246 return false; | 1246 return false; |
1247 | 1247 |
1248 // ARIA button with aria-pressed not undefined, then check for aria-pressed | 1248 // ARIA button with aria-pressed not undefined, then check for aria-pressed |
1249 // attribute rather than getNode()->active() | 1249 // attribute rather than getNode()->active() |
1250 if (ariaRoleAttribute() == ToggleButtonRole) { | 1250 if (ariaRoleAttribute() == ToggleButtonRole) { |
1251 if (equalIgnoringCase(getAttribute(aria_pressedAttr), "true") || | 1251 if (equalIgnoringASCIICase(getAttribute(aria_pressedAttr), "true") || |
1252 equalIgnoringCase(getAttribute(aria_pressedAttr), "mixed")) | 1252 equalIgnoringASCIICase(getAttribute(aria_pressedAttr), "mixed")) |
1253 return true; | 1253 return true; |
1254 return false; | 1254 return false; |
1255 } | 1255 } |
1256 | 1256 |
1257 return node->isActive(); | 1257 return node->isActive(); |
1258 } | 1258 } |
1259 | 1259 |
1260 bool AXNodeObject::isReadOnly() const { | 1260 bool AXNodeObject::isReadOnly() const { |
1261 Node* node = this->getNode(); | 1261 Node* node = this->getNode(); |
1262 if (!node) | 1262 if (!node) |
(...skipping 10 matching lines...) Expand all Loading... |
1273 | 1273 |
1274 return !hasEditableStyle(*node); | 1274 return !hasEditableStyle(*node); |
1275 } | 1275 } |
1276 | 1276 |
1277 bool AXNodeObject::isRequired() const { | 1277 bool AXNodeObject::isRequired() const { |
1278 Node* n = this->getNode(); | 1278 Node* n = this->getNode(); |
1279 if (n && (n->isElementNode() && toElement(n)->isFormControlElement()) && | 1279 if (n && (n->isElementNode() && toElement(n)->isFormControlElement()) && |
1280 hasAttribute(requiredAttr)) | 1280 hasAttribute(requiredAttr)) |
1281 return toHTMLFormControlElement(n)->isRequired(); | 1281 return toHTMLFormControlElement(n)->isRequired(); |
1282 | 1282 |
1283 if (equalIgnoringCase(getAttribute(aria_requiredAttr), "true")) | 1283 if (equalIgnoringASCIICase(getAttribute(aria_requiredAttr), "true")) |
1284 return true; | 1284 return true; |
1285 | 1285 |
1286 return false; | 1286 return false; |
1287 } | 1287 } |
1288 | 1288 |
1289 bool AXNodeObject::canSetFocusAttribute() const { | 1289 bool AXNodeObject::canSetFocusAttribute() const { |
1290 Node* node = getNode(); | 1290 Node* node = getNode(); |
1291 if (!node) | 1291 if (!node) |
1292 return false; | 1292 return false; |
1293 | 1293 |
1294 if (isWebArea()) | 1294 if (isWebArea()) |
1295 return true; | 1295 return true; |
1296 | 1296 |
1297 // Children of elements with an aria-activedescendant attribute should be | 1297 // Children of elements with an aria-activedescendant attribute should be |
1298 // focusable if they have a (non-presentational) ARIA role. | 1298 // focusable if they have a (non-presentational) ARIA role. |
1299 if (!isPresentational() && ariaRoleAttribute() != UnknownRole && | 1299 if (!isPresentational() && ariaRoleAttribute() != UnknownRole && |
1300 ancestorExposesActiveDescendant()) | 1300 ancestorExposesActiveDescendant()) |
1301 return true; | 1301 return true; |
1302 | 1302 |
1303 // NOTE: It would be more accurate to ask the document whether | 1303 // NOTE: It would be more accurate to ask the document whether |
1304 // setFocusedNode() would do anything. For example, setFocusedNode() will do | 1304 // setFocusedNode() would do anything. For example, setFocusedNode() will do |
1305 // nothing if the current focused node will not relinquish the focus. | 1305 // nothing if the current focused node will not relinquish the focus. |
1306 if (isDisabledFormControl(node)) | 1306 if (isDisabledFormControl(node)) |
1307 return false; | 1307 return false; |
1308 | 1308 |
1309 return node->isElementNode() && toElement(node)->supportsFocus(); | 1309 return node->isElementNode() && toElement(node)->supportsFocus(); |
1310 } | 1310 } |
1311 | 1311 |
1312 bool AXNodeObject::canSetValueAttribute() const { | 1312 bool AXNodeObject::canSetValueAttribute() const { |
1313 if (equalIgnoringCase(getAttribute(aria_readonlyAttr), "true")) | 1313 if (equalIgnoringASCIICase(getAttribute(aria_readonlyAttr), "true")) |
1314 return false; | 1314 return false; |
1315 | 1315 |
1316 if (isProgressIndicator() || isSlider()) | 1316 if (isProgressIndicator() || isSlider()) |
1317 return true; | 1317 return true; |
1318 | 1318 |
1319 if (isTextControl() && !isNativeTextControl()) | 1319 if (isTextControl() && !isNativeTextControl()) |
1320 return true; | 1320 return true; |
1321 | 1321 |
1322 // Any node could be contenteditable, so isReadOnly should be relied upon | 1322 // Any node could be contenteditable, so isReadOnly should be relied upon |
1323 // for this information for all elements. | 1323 // for this information for all elements. |
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1481 return AXObject::inPageLinkTarget(); | 1481 return AXObject::inPageLinkTarget(); |
1482 // If the target is not in the accessibility tree, get the first unignored | 1482 // If the target is not in the accessibility tree, get the first unignored |
1483 // sibling. | 1483 // sibling. |
1484 return axObjectCache().firstAccessibleObjectFromNode(target); | 1484 return axObjectCache().firstAccessibleObjectFromNode(target); |
1485 } | 1485 } |
1486 | 1486 |
1487 AccessibilityOrientation AXNodeObject::orientation() const { | 1487 AccessibilityOrientation AXNodeObject::orientation() const { |
1488 const AtomicString& ariaOrientation = | 1488 const AtomicString& ariaOrientation = |
1489 getAOMPropertyOrARIAAttribute(AOMStringProperty::kOrientation); | 1489 getAOMPropertyOrARIAAttribute(AOMStringProperty::kOrientation); |
1490 AccessibilityOrientation orientation = AccessibilityOrientationUndefined; | 1490 AccessibilityOrientation orientation = AccessibilityOrientationUndefined; |
1491 if (equalIgnoringCase(ariaOrientation, "horizontal")) | 1491 if (equalIgnoringASCIICase(ariaOrientation, "horizontal")) |
1492 orientation = AccessibilityOrientationHorizontal; | 1492 orientation = AccessibilityOrientationHorizontal; |
1493 else if (equalIgnoringCase(ariaOrientation, "vertical")) | 1493 else if (equalIgnoringASCIICase(ariaOrientation, "vertical")) |
1494 orientation = AccessibilityOrientationVertical; | 1494 orientation = AccessibilityOrientationVertical; |
1495 | 1495 |
1496 switch (roleValue()) { | 1496 switch (roleValue()) { |
1497 case ComboBoxRole: | 1497 case ComboBoxRole: |
1498 case ListBoxRole: | 1498 case ListBoxRole: |
1499 case MenuRole: | 1499 case MenuRole: |
1500 case ScrollBarRole: | 1500 case ScrollBarRole: |
1501 case TreeRole: | 1501 case TreeRole: |
1502 if (orientation == AccessibilityOrientationUndefined) | 1502 if (orientation == AccessibilityOrientationUndefined) |
1503 orientation = AccessibilityOrientationVertical; | 1503 orientation = AccessibilityOrientationVertical; |
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1614 | 1614 |
1615 return AXObject::checkboxOrRadioValue(); | 1615 return AXObject::checkboxOrRadioValue(); |
1616 } | 1616 } |
1617 | 1617 |
1618 RGBA32 AXNodeObject::colorValue() const { | 1618 RGBA32 AXNodeObject::colorValue() const { |
1619 if (!isHTMLInputElement(getNode()) || !isColorWell()) | 1619 if (!isHTMLInputElement(getNode()) || !isColorWell()) |
1620 return AXObject::colorValue(); | 1620 return AXObject::colorValue(); |
1621 | 1621 |
1622 HTMLInputElement* input = toHTMLInputElement(getNode()); | 1622 HTMLInputElement* input = toHTMLInputElement(getNode()); |
1623 const AtomicString& type = input->getAttribute(typeAttr); | 1623 const AtomicString& type = input->getAttribute(typeAttr); |
1624 if (!equalIgnoringCase(type, "color")) | 1624 if (!equalIgnoringASCIICase(type, "color")) |
1625 return AXObject::colorValue(); | 1625 return AXObject::colorValue(); |
1626 | 1626 |
1627 // HTMLInputElement::value always returns a string parseable by Color. | 1627 // HTMLInputElement::value always returns a string parseable by Color. |
1628 Color color; | 1628 Color color; |
1629 bool success = color.setFromString(input->value()); | 1629 bool success = color.setFromString(input->value()); |
1630 DCHECK(success); | 1630 DCHECK(success); |
1631 return color.rgb(); | 1631 return color.rgb(); |
1632 } | 1632 } |
1633 | 1633 |
1634 AriaCurrentState AXNodeObject::ariaCurrentState() const { | 1634 AriaCurrentState AXNodeObject::ariaCurrentState() const { |
1635 const AtomicString& attributeValue = | 1635 const AtomicString& attributeValue = |
1636 getAOMPropertyOrARIAAttribute(AOMStringProperty::kCurrent); | 1636 getAOMPropertyOrARIAAttribute(AOMStringProperty::kCurrent); |
1637 if (attributeValue.isNull()) | 1637 if (attributeValue.isNull()) |
1638 return AriaCurrentStateUndefined; | 1638 return AriaCurrentStateUndefined; |
1639 if (attributeValue.isEmpty() || equalIgnoringCase(attributeValue, "false")) | 1639 if (attributeValue.isEmpty() || |
| 1640 equalIgnoringASCIICase(attributeValue, "false")) |
1640 return AriaCurrentStateFalse; | 1641 return AriaCurrentStateFalse; |
1641 if (equalIgnoringCase(attributeValue, "true")) | 1642 if (equalIgnoringASCIICase(attributeValue, "true")) |
1642 return AriaCurrentStateTrue; | 1643 return AriaCurrentStateTrue; |
1643 if (equalIgnoringCase(attributeValue, "page")) | 1644 if (equalIgnoringASCIICase(attributeValue, "page")) |
1644 return AriaCurrentStatePage; | 1645 return AriaCurrentStatePage; |
1645 if (equalIgnoringCase(attributeValue, "step")) | 1646 if (equalIgnoringASCIICase(attributeValue, "step")) |
1646 return AriaCurrentStateStep; | 1647 return AriaCurrentStateStep; |
1647 if (equalIgnoringCase(attributeValue, "location")) | 1648 if (equalIgnoringASCIICase(attributeValue, "location")) |
1648 return AriaCurrentStateLocation; | 1649 return AriaCurrentStateLocation; |
1649 if (equalIgnoringCase(attributeValue, "date")) | 1650 if (equalIgnoringASCIICase(attributeValue, "date")) |
1650 return AriaCurrentStateDate; | 1651 return AriaCurrentStateDate; |
1651 if (equalIgnoringCase(attributeValue, "time")) | 1652 if (equalIgnoringASCIICase(attributeValue, "time")) |
1652 return AriaCurrentStateTime; | 1653 return AriaCurrentStateTime; |
1653 // An unknown value should return true. | 1654 // An unknown value should return true. |
1654 if (!attributeValue.isEmpty()) | 1655 if (!attributeValue.isEmpty()) |
1655 return AriaCurrentStateTrue; | 1656 return AriaCurrentStateTrue; |
1656 | 1657 |
1657 return AXObject::ariaCurrentState(); | 1658 return AXObject::ariaCurrentState(); |
1658 } | 1659 } |
1659 | 1660 |
1660 InvalidState AXNodeObject::getInvalidState() const { | 1661 InvalidState AXNodeObject::getInvalidState() const { |
1661 const AtomicString& attributeValue = | 1662 const AtomicString& attributeValue = |
1662 getAOMPropertyOrARIAAttribute(AOMStringProperty::kInvalid); | 1663 getAOMPropertyOrARIAAttribute(AOMStringProperty::kInvalid); |
1663 if (equalIgnoringCase(attributeValue, "false")) | 1664 if (equalIgnoringASCIICase(attributeValue, "false")) |
1664 return InvalidStateFalse; | 1665 return InvalidStateFalse; |
1665 if (equalIgnoringCase(attributeValue, "true")) | 1666 if (equalIgnoringASCIICase(attributeValue, "true")) |
1666 return InvalidStateTrue; | 1667 return InvalidStateTrue; |
1667 if (equalIgnoringCase(attributeValue, "spelling")) | 1668 if (equalIgnoringASCIICase(attributeValue, "spelling")) |
1668 return InvalidStateSpelling; | 1669 return InvalidStateSpelling; |
1669 if (equalIgnoringCase(attributeValue, "grammar")) | 1670 if (equalIgnoringASCIICase(attributeValue, "grammar")) |
1670 return InvalidStateGrammar; | 1671 return InvalidStateGrammar; |
1671 // A yet unknown value. | 1672 // A yet unknown value. |
1672 if (!attributeValue.isEmpty()) | 1673 if (!attributeValue.isEmpty()) |
1673 return InvalidStateOther; | 1674 return InvalidStateOther; |
1674 | 1675 |
1675 if (getNode() && getNode()->isElementNode() && | 1676 if (getNode() && getNode()->isElementNode() && |
1676 toElement(getNode())->isFormControlElement()) { | 1677 toElement(getNode())->isFormControlElement()) { |
1677 HTMLFormControlElement* element = toHTMLFormControlElement(getNode()); | 1678 HTMLFormControlElement* element = toHTMLFormControlElement(getNode()); |
1678 HeapVector<Member<HTMLFormControlElement>> invalidControls; | 1679 HeapVector<Member<HTMLFormControlElement>> invalidControls; |
1679 bool isInvalid = | 1680 bool isInvalid = |
(...skipping 309 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1989 } | 1990 } |
1990 for (const auto& ownedChild : ownedChildren) | 1991 for (const auto& ownedChild : ownedChildren) |
1991 children.push_back(ownedChild); | 1992 children.push_back(ownedChild); |
1992 | 1993 |
1993 for (AXObject* child : children) { | 1994 for (AXObject* child : children) { |
1994 // Don't recurse into children that are explicitly marked as aria-hidden. | 1995 // Don't recurse into children that are explicitly marked as aria-hidden. |
1995 // Note that we don't call isInertOrAriaHidden because that would return | 1996 // Note that we don't call isInertOrAriaHidden because that would return |
1996 // true if any ancestor is hidden, but we need to be able to compute the | 1997 // true if any ancestor is hidden, but we need to be able to compute the |
1997 // accessible name of object inside hidden subtrees (for example, if | 1998 // accessible name of object inside hidden subtrees (for example, if |
1998 // aria-labelledby points to an object that's hidden). | 1999 // aria-labelledby points to an object that's hidden). |
1999 if (equalIgnoringCase(child->getAttribute(aria_hiddenAttr), "true")) | 2000 if (equalIgnoringASCIICase(child->getAttribute(aria_hiddenAttr), "true")) |
2000 continue; | 2001 continue; |
2001 | 2002 |
2002 // If we're going between two layoutObjects that are in separate | 2003 // If we're going between two layoutObjects that are in separate |
2003 // LayoutBoxes, add whitespace if it wasn't there already. Intuitively if | 2004 // LayoutBoxes, add whitespace if it wasn't there already. Intuitively if |
2004 // you have <span>Hello</span><span>World</span>, those are part of the same | 2005 // you have <span>Hello</span><span>World</span>, those are part of the same |
2005 // LayoutBox so we should return "HelloWorld", but given | 2006 // LayoutBox so we should return "HelloWorld", but given |
2006 // <div>Hello</div><div>World</div> the strings are in separate boxes so we | 2007 // <div>Hello</div><div>World</div> the strings are in separate boxes so we |
2007 // should return "Hello World". | 2008 // should return "Hello World". |
2008 if (previous && accumulatedText.length() && | 2009 if (previous && accumulatedText.length() && |
2009 !isHTMLSpace(accumulatedText[accumulatedText.length() - 1])) { | 2010 !isHTMLSpace(accumulatedText[accumulatedText.length() - 1])) { |
(...skipping 1250 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3260 return String(); | 3261 return String(); |
3261 return toTextControlElement(node)->strippedPlaceholder(); | 3262 return toTextControlElement(node)->strippedPlaceholder(); |
3262 } | 3263 } |
3263 | 3264 |
3264 DEFINE_TRACE(AXNodeObject) { | 3265 DEFINE_TRACE(AXNodeObject) { |
3265 visitor->trace(m_node); | 3266 visitor->trace(m_node); |
3266 AXObject::trace(visitor); | 3267 AXObject::trace(visitor); |
3267 } | 3268 } |
3268 | 3269 |
3269 } // namespace blink | 3270 } // namespace blink |
OLD | NEW |