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

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

Issue 2788523002: Finish all string attributes for Accessibility Object Model Phase 1. (Closed)
Patch Set: notifyAttributeChanged Created 3 years, 8 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 805 matching lines...) Expand 10 before | Expand all | Expand 10 after
816 return 0; 816 return 0;
817 } 817 }
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 = sibling->getAttribute(roleAttr); 826 const AtomicString& siblingAriaRole =
827 AccessibleNode::getProperty(sibling, AOMStringProperty::kRole);
827 if (equalIgnoringCase(siblingAriaRole, role)) 828 if (equalIgnoringCase(siblingAriaRole, role))
828 return sibling; 829 return sibling;
829 } 830 }
830 831
831 return 0; 832 return 0;
832 } 833 }
833 834
834 Element* AXNodeObject::menuItemElementForMenu() const { 835 Element* AXNodeObject::menuItemElementForMenu() const {
835 if (ariaRoleAttribute() != MenuRole) 836 if (ariaRoleAttribute() != MenuRole)
836 return 0; 837 return 0;
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
921 return; 922 return;
922 923
923 AXSparseAttributeSetterMap& axSparseAttributeSetterMap = 924 AXSparseAttributeSetterMap& axSparseAttributeSetterMap =
924 getSparseAttributeSetterMap(); 925 getSparseAttributeSetterMap();
925 AttributeCollection attributes = toElement(node)->attributesWithoutUpdate(); 926 AttributeCollection attributes = toElement(node)->attributesWithoutUpdate();
926 for (const Attribute& attr : attributes) { 927 for (const Attribute& attr : attributes) {
927 SparseAttributeSetter* setter = axSparseAttributeSetterMap.at(attr.name()); 928 SparseAttributeSetter* setter = axSparseAttributeSetterMap.at(attr.name());
928 if (setter) 929 if (setter)
929 setter->run(*this, sparseAttributeClient, attr.value()); 930 setter->run(*this, sparseAttributeClient, attr.value());
930 } 931 }
932
933 // TODO(dmazzoni): Efficiently iterate over AccessibleNode properties that are
934 // set and merge the two loops somehow.
935 if (toElement(node)->existingAccessibleNode()) {
936 AtomicString keyShortcuts =
937 getAOMPropertyOrARIAAttribute(AOMStringProperty::kKeyShortcuts);
938 if (!keyShortcuts.isNull()) {
939 axSparseAttributeSetterMap.at(aria_keyshortcutsAttr)
940 ->run(*this, sparseAttributeClient, keyShortcuts);
941 }
942 AtomicString roleDescription =
943 getAOMPropertyOrARIAAttribute(AOMStringProperty::kRoleDescription);
944 if (!roleDescription.isNull()) {
945 axSparseAttributeSetterMap.at(aria_roledescriptionAttr)
946 ->run(*this, sparseAttributeClient, roleDescription);
947 }
948 }
931 } 949 }
932 950
933 bool AXNodeObject::isAnchor() const { 951 bool AXNodeObject::isAnchor() const {
934 return !isNativeImage() && isLink(); 952 return !isNativeImage() && isLink();
935 } 953 }
936 954
937 bool AXNodeObject::isControl() const { 955 bool AXNodeObject::isControl() const {
938 Node* node = this->getNode(); 956 Node* node = this->getNode();
939 if (!node) 957 if (!node)
940 return false; 958 return false;
(...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after
1134 return toHTMLInputElement(*node).shouldAppearChecked(); 1152 return toHTMLInputElement(*node).shouldAppearChecked();
1135 1153
1136 // 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
1137 // or menuitemradio or switch, respect the aria-checked attribute 1155 // or menuitemradio or switch, respect the aria-checked attribute
1138 switch (ariaRoleAttribute()) { 1156 switch (ariaRoleAttribute()) {
1139 case CheckBoxRole: 1157 case CheckBoxRole:
1140 case MenuItemCheckBoxRole: 1158 case MenuItemCheckBoxRole:
1141 case MenuItemRadioRole: 1159 case MenuItemRadioRole:
1142 case RadioButtonRole: 1160 case RadioButtonRole:
1143 case SwitchRole: 1161 case SwitchRole:
1144 if (equalIgnoringCase(getAttribute(aria_checkedAttr), "true")) 1162 if (equalIgnoringCase(
1163 getAOMPropertyOrARIAAttribute(AOMStringProperty::kChecked),
1164 "true"))
1145 return true; 1165 return true;
1146 return false; 1166 return false;
1147 default: 1167 default:
1148 break; 1168 break;
1149 } 1169 }
1150 1170
1151 // Otherwise it's not checked 1171 // Otherwise it's not checked
1152 return false; 1172 return false;
1153 } 1173 }
1154 1174
(...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after
1396 } 1416 }
1397 1417
1398 return level; 1418 return level;
1399 } 1419 }
1400 1420
1401 String AXNodeObject::ariaAutoComplete() const { 1421 String AXNodeObject::ariaAutoComplete() const {
1402 if (roleValue() != ComboBoxRole) 1422 if (roleValue() != ComboBoxRole)
1403 return String(); 1423 return String();
1404 1424
1405 const AtomicString& ariaAutoComplete = 1425 const AtomicString& ariaAutoComplete =
1406 getAttribute(aria_autocompleteAttr).lower(); 1426 getAOMPropertyOrARIAAttribute(AOMStringProperty::kAutocomplete).lower();
1407 1427
1408 if (ariaAutoComplete == "inline" || ariaAutoComplete == "list" || 1428 if (ariaAutoComplete == "inline" || ariaAutoComplete == "list" ||
1409 ariaAutoComplete == "both") 1429 ariaAutoComplete == "both")
1410 return ariaAutoComplete; 1430 return ariaAutoComplete;
1411 1431
1412 return String(); 1432 return String();
1413 } 1433 }
1414 1434
1415 void AXNodeObject::markers(Vector<DocumentMarker::MarkerType>& markerTypes, 1435 void AXNodeObject::markers(Vector<DocumentMarker::MarkerType>& markerTypes,
1416 Vector<AXRange>& markerRanges) const { 1436 Vector<AXRange>& markerRanges) const {
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
1458 TreeScope& treeScope = anchor->treeScope(); 1478 TreeScope& treeScope = anchor->treeScope();
1459 Element* target = treeScope.findAnchor(fragment); 1479 Element* target = treeScope.findAnchor(fragment);
1460 if (!target) 1480 if (!target)
1461 return AXObject::inPageLinkTarget(); 1481 return AXObject::inPageLinkTarget();
1462 // 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
1463 // sibling. 1483 // sibling.
1464 return axObjectCache().firstAccessibleObjectFromNode(target); 1484 return axObjectCache().firstAccessibleObjectFromNode(target);
1465 } 1485 }
1466 1486
1467 AccessibilityOrientation AXNodeObject::orientation() const { 1487 AccessibilityOrientation AXNodeObject::orientation() const {
1468 const AtomicString& ariaOrientation = getAttribute(aria_orientationAttr); 1488 const AtomicString& ariaOrientation =
1489 getAOMPropertyOrARIAAttribute(AOMStringProperty::kOrientation);
1469 AccessibilityOrientation orientation = AccessibilityOrientationUndefined; 1490 AccessibilityOrientation orientation = AccessibilityOrientationUndefined;
1470 if (equalIgnoringCase(ariaOrientation, "horizontal")) 1491 if (equalIgnoringCase(ariaOrientation, "horizontal"))
1471 orientation = AccessibilityOrientationHorizontal; 1492 orientation = AccessibilityOrientationHorizontal;
1472 else if (equalIgnoringCase(ariaOrientation, "vertical")) 1493 else if (equalIgnoringCase(ariaOrientation, "vertical"))
1473 orientation = AccessibilityOrientationVertical; 1494 orientation = AccessibilityOrientationVertical;
1474 1495
1475 switch (roleValue()) { 1496 switch (roleValue()) {
1476 case ComboBoxRole: 1497 case ComboBoxRole:
1477 case ListBoxRole: 1498 case ListBoxRole:
1478 case MenuRole: 1499 case MenuRole:
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
1604 return AXObject::colorValue(); 1625 return AXObject::colorValue();
1605 1626
1606 // HTMLInputElement::value always returns a string parseable by Color. 1627 // HTMLInputElement::value always returns a string parseable by Color.
1607 Color color; 1628 Color color;
1608 bool success = color.setFromString(input->value()); 1629 bool success = color.setFromString(input->value());
1609 DCHECK(success); 1630 DCHECK(success);
1610 return color.rgb(); 1631 return color.rgb();
1611 } 1632 }
1612 1633
1613 AriaCurrentState AXNodeObject::ariaCurrentState() const { 1634 AriaCurrentState AXNodeObject::ariaCurrentState() const {
1614 if (!hasAttribute(aria_currentAttr)) 1635 const AtomicString& attributeValue =
1615 return AXObject::ariaCurrentState(); 1636 getAOMPropertyOrARIAAttribute(AOMStringProperty::kCurrent);
1616 1637 if (attributeValue.isNull())
1617 const AtomicString& attributeValue = getAttribute(aria_currentAttr); 1638 return AriaCurrentStateUndefined;
1618 if (attributeValue.isEmpty() || equalIgnoringCase(attributeValue, "false")) 1639 if (attributeValue.isEmpty() || equalIgnoringCase(attributeValue, "false"))
1619 return AriaCurrentStateFalse; 1640 return AriaCurrentStateFalse;
1620 if (equalIgnoringCase(attributeValue, "true")) 1641 if (equalIgnoringCase(attributeValue, "true"))
1621 return AriaCurrentStateTrue; 1642 return AriaCurrentStateTrue;
1622 if (equalIgnoringCase(attributeValue, "page")) 1643 if (equalIgnoringCase(attributeValue, "page"))
1623 return AriaCurrentStatePage; 1644 return AriaCurrentStatePage;
1624 if (equalIgnoringCase(attributeValue, "step")) 1645 if (equalIgnoringCase(attributeValue, "step"))
1625 return AriaCurrentStateStep; 1646 return AriaCurrentStateStep;
1626 if (equalIgnoringCase(attributeValue, "location")) 1647 if (equalIgnoringCase(attributeValue, "location"))
1627 return AriaCurrentStateLocation; 1648 return AriaCurrentStateLocation;
1628 if (equalIgnoringCase(attributeValue, "date")) 1649 if (equalIgnoringCase(attributeValue, "date"))
1629 return AriaCurrentStateDate; 1650 return AriaCurrentStateDate;
1630 if (equalIgnoringCase(attributeValue, "time")) 1651 if (equalIgnoringCase(attributeValue, "time"))
1631 return AriaCurrentStateTime; 1652 return AriaCurrentStateTime;
1632 // An unknown value should return true. 1653 // An unknown value should return true.
1633 if (!attributeValue.isEmpty()) 1654 if (!attributeValue.isEmpty())
1634 return AriaCurrentStateTrue; 1655 return AriaCurrentStateTrue;
1635 1656
1636 return AXObject::ariaCurrentState(); 1657 return AXObject::ariaCurrentState();
1637 } 1658 }
1638 1659
1639 InvalidState AXNodeObject::getInvalidState() const { 1660 InvalidState AXNodeObject::getInvalidState() const {
1640 if (hasAttribute(aria_invalidAttr)) { 1661 const AtomicString& attributeValue =
1641 const AtomicString& attributeValue = getAttribute(aria_invalidAttr); 1662 getAOMPropertyOrARIAAttribute(AOMStringProperty::kInvalid);
1642 if (equalIgnoringCase(attributeValue, "false")) 1663 if (equalIgnoringCase(attributeValue, "false"))
1643 return InvalidStateFalse; 1664 return InvalidStateFalse;
1644 if (equalIgnoringCase(attributeValue, "true")) 1665 if (equalIgnoringCase(attributeValue, "true"))
1645 return InvalidStateTrue; 1666 return InvalidStateTrue;
1646 if (equalIgnoringCase(attributeValue, "spelling")) 1667 if (equalIgnoringCase(attributeValue, "spelling"))
1647 return InvalidStateSpelling; 1668 return InvalidStateSpelling;
1648 if (equalIgnoringCase(attributeValue, "grammar")) 1669 if (equalIgnoringCase(attributeValue, "grammar"))
1649 return InvalidStateGrammar; 1670 return InvalidStateGrammar;
1650 // A yet unknown value. 1671 // A yet unknown value.
1651 if (!attributeValue.isEmpty()) 1672 if (!attributeValue.isEmpty())
1652 return InvalidStateOther; 1673 return InvalidStateOther;
1653 }
1654 1674
1655 if (getNode() && getNode()->isElementNode() && 1675 if (getNode() && getNode()->isElementNode() &&
1656 toElement(getNode())->isFormControlElement()) { 1676 toElement(getNode())->isFormControlElement()) {
1657 HTMLFormControlElement* element = toHTMLFormControlElement(getNode()); 1677 HTMLFormControlElement* element = toHTMLFormControlElement(getNode());
1658 HeapVector<Member<HTMLFormControlElement>> invalidControls; 1678 HeapVector<Member<HTMLFormControlElement>> invalidControls;
1659 bool isInvalid = 1679 bool isInvalid =
1660 !element->checkValidity(&invalidControls, CheckValidityDispatchNoEvent); 1680 !element->checkValidity(&invalidControls, CheckValidityDispatchNoEvent);
1661 return isInvalid ? InvalidStateTrue : InvalidStateFalse; 1681 return isInvalid ? InvalidStateTrue : InvalidStateFalse;
1662 } 1682 }
1663 1683
(...skipping 30 matching lines...) Expand all
1694 const auto& siblings = parentObject()->children(); 1714 const auto& siblings = parentObject()->children();
1695 return siblings.size(); 1715 return siblings.size();
1696 } 1716 }
1697 } 1717 }
1698 1718
1699 return 0; 1719 return 0;
1700 } 1720 }
1701 1721
1702 String AXNodeObject::ariaInvalidValue() const { 1722 String AXNodeObject::ariaInvalidValue() const {
1703 if (getInvalidState() == InvalidStateOther) 1723 if (getInvalidState() == InvalidStateOther)
1704 return getAttribute(aria_invalidAttr); 1724 return getAOMPropertyOrARIAAttribute(AOMStringProperty::kInvalid);
1705 1725
1706 return String(); 1726 return String();
1707 } 1727 }
1708 1728
1709 String AXNodeObject::valueDescription() const { 1729 String AXNodeObject::valueDescription() const {
1710 if (!supportsRangeValue()) 1730 if (!supportsRangeValue())
1711 return String(); 1731 return String();
1712 1732
1713 return getAttribute(aria_valuetextAttr).getString(); 1733 return getAOMPropertyOrARIAAttribute(AOMStringProperty::kValueText)
1734 .getString();
1714 } 1735 }
1715 1736
1716 float AXNodeObject::valueForRange() const { 1737 float AXNodeObject::valueForRange() const {
1717 if (hasAttribute(aria_valuenowAttr)) 1738 if (hasAttribute(aria_valuenowAttr))
1718 return getAttribute(aria_valuenowAttr).toFloat(); 1739 return getAttribute(aria_valuenowAttr).toFloat();
1719 1740
1720 if (isNativeSlider()) 1741 if (isNativeSlider())
1721 return toHTMLInputElement(*getNode()).valueAsNumber(); 1742 return toHTMLInputElement(*getNode()).valueAsNumber();
1722 1743
1723 if (isHTMLMeterElement(getNode())) 1744 if (isHTMLMeterElement(getNode()))
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after
1867 if (foundTextAlternative && !nameSources) 1888 if (foundTextAlternative && !nameSources)
1868 return textAlternative; 1889 return textAlternative;
1869 1890
1870 // Step 2E from: http://www.w3.org/TR/accname-aam-1.1 1891 // Step 2E from: http://www.w3.org/TR/accname-aam-1.1
1871 if (recursive && !inAriaLabelledByTraversal && isControl() && !isButton()) { 1892 if (recursive && !inAriaLabelledByTraversal && isControl() && !isButton()) {
1872 // No need to set any name source info in a recursive call. 1893 // No need to set any name source info in a recursive call.
1873 if (isTextControl()) 1894 if (isTextControl())
1874 return text(); 1895 return text();
1875 1896
1876 if (isRange()) { 1897 if (isRange()) {
1877 const AtomicString& ariaValuetext = getAttribute(aria_valuetextAttr); 1898 const AtomicString& ariaValuetext =
1899 getAOMPropertyOrARIAAttribute(AOMStringProperty::kValueText);
1878 if (!ariaValuetext.isNull()) 1900 if (!ariaValuetext.isNull())
1879 return ariaValuetext.getString(); 1901 return ariaValuetext.getString();
1880 return String::number(valueForRange()); 1902 return String::number(valueForRange());
1881 } 1903 }
1882 1904
1883 return stringValue(); 1905 return stringValue();
1884 } 1906 }
1885 1907
1886 // Step 2D from: http://www.w3.org/TR/accname-aam-1.1 1908 // Step 2D from: http://www.w3.org/TR/accname-aam-1.1
1887 textAlternative = nativeTextAlternative(visited, nameFrom, relatedObjects, 1909 textAlternative = nativeTextAlternative(visited, nameFrom, relatedObjects,
(...skipping 842 matching lines...) Expand 10 before | Expand all | Expand 10 after
2730 2752
2731 // Also check for aria-placeholder. 2753 // Also check for aria-placeholder.
2732 nameFrom = AXNameFromPlaceholder; 2754 nameFrom = AXNameFromPlaceholder;
2733 if (nameSources) { 2755 if (nameSources) {
2734 nameSources->push_back( 2756 nameSources->push_back(
2735 NameSource(*foundTextAlternative, aria_placeholderAttr)); 2757 NameSource(*foundTextAlternative, aria_placeholderAttr));
2736 NameSource& source = nameSources->back(); 2758 NameSource& source = nameSources->back();
2737 source.type = nameFrom; 2759 source.type = nameFrom;
2738 } 2760 }
2739 const AtomicString& ariaPlaceholder = 2761 const AtomicString& ariaPlaceholder =
2740 htmlElement->fastGetAttribute(aria_placeholderAttr); 2762 getAOMPropertyOrARIAAttribute(AOMStringProperty::kPlaceholder);
2741 if (!ariaPlaceholder.isEmpty()) { 2763 if (!ariaPlaceholder.isEmpty()) {
2742 textAlternative = ariaPlaceholder; 2764 textAlternative = ariaPlaceholder;
2743 if (nameSources) { 2765 if (nameSources) {
2744 NameSource& source = nameSources->back(); 2766 NameSource& source = nameSources->back();
2745 source.text = textAlternative; 2767 source.text = textAlternative;
2746 source.attributeValue = ariaPlaceholder; 2768 source.attributeValue = ariaPlaceholder;
2747 *foundTextAlternative = true; 2769 *foundTextAlternative = true;
2748 } else { 2770 } else {
2749 return textAlternative; 2771 return textAlternative;
2750 } 2772 }
(...skipping 487 matching lines...) Expand 10 before | Expand all | Expand 10 after
3238 return String(); 3260 return String();
3239 return toTextControlElement(node)->strippedPlaceholder(); 3261 return toTextControlElement(node)->strippedPlaceholder();
3240 } 3262 }
3241 3263
3242 DEFINE_TRACE(AXNodeObject) { 3264 DEFINE_TRACE(AXNodeObject) {
3243 visitor->trace(m_node); 3265 visitor->trace(m_node);
3244 AXObject::trace(visitor); 3266 AXObject::trace(visitor);
3245 } 3267 }
3246 3268
3247 } // namespace blink 3269 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698