| 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 1025 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1036 ariaLabeledByElements(elements); | 1036 ariaLabeledByElements(elements); |
| 1037 | 1037 |
| 1038 return accessibilityDescriptionForElements(elements); | 1038 return accessibilityDescriptionForElements(elements); |
| 1039 } | 1039 } |
| 1040 | 1040 |
| 1041 AccessibilityRole AXNodeObject::ariaRoleAttribute() const | 1041 AccessibilityRole AXNodeObject::ariaRoleAttribute() const |
| 1042 { | 1042 { |
| 1043 return m_ariaRole; | 1043 return m_ariaRole; |
| 1044 } | 1044 } |
| 1045 | 1045 |
| 1046 void AXNodeObject::accessibilityText(Vector<AccessibilityText>& textOrder) | |
| 1047 { | |
| 1048 titleElementText(textOrder); | |
| 1049 alternativeText(textOrder); | |
| 1050 visibleText(textOrder); | |
| 1051 helpText(textOrder); | |
| 1052 | |
| 1053 String placeholder = placeholderValue(); | |
| 1054 if (!placeholder.isEmpty()) | |
| 1055 textOrder.append(AccessibilityText(placeholder, PlaceholderText)); | |
| 1056 } | |
| 1057 | |
| 1058 // When building the textUnderElement for an object, determine whether or not | 1046 // When building the textUnderElement for an object, determine whether or not |
| 1059 // we should include the inner text of this given descendant object or skip it. | 1047 // we should include the inner text of this given descendant object or skip it. |
| 1060 static bool shouldUseAccessiblityObjectInnerText(AXObject* obj) | 1048 static bool shouldUseAccessiblityObjectInnerText(AXObject* obj) |
| 1061 { | 1049 { |
| 1062 // Consider this hypothetical example: | 1050 // Consider this hypothetical example: |
| 1063 // <div tabindex=0> | 1051 // <div tabindex=0> |
| 1064 // <h2> | 1052 // <h2> |
| 1065 // Table of contents | 1053 // Table of contents |
| 1066 // </h2> | 1054 // </h2> |
| 1067 // <a href="#start">Jump to start of book</a> | 1055 // <a href="#start">Jump to start of book</a> |
| (...skipping 616 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1684 { | 1672 { |
| 1685 float range = maxValueForRange() - minValueForRange(); | 1673 float range = maxValueForRange() - minValueForRange(); |
| 1686 float value = valueForRange(); | 1674 float value = valueForRange(); |
| 1687 | 1675 |
| 1688 value += range * (percentChange / 100); | 1676 value += range * (percentChange / 100); |
| 1689 setValue(String::number(value)); | 1677 setValue(String::number(value)); |
| 1690 | 1678 |
| 1691 axObjectCache()->postNotification(node(), AXObjectCache::AXValueChanged, tru
e); | 1679 axObjectCache()->postNotification(node(), AXObjectCache::AXValueChanged, tru
e); |
| 1692 } | 1680 } |
| 1693 | 1681 |
| 1694 void AXNodeObject::helpText(Vector<AccessibilityText>& textOrder) const | |
| 1695 { | |
| 1696 const AtomicString& ariaHelp = getAttribute(aria_helpAttr); | |
| 1697 if (!ariaHelp.isEmpty()) | |
| 1698 textOrder.append(AccessibilityText(ariaHelp, HelpText)); | |
| 1699 | |
| 1700 String describedBy = ariaDescribedByAttribute(); | |
| 1701 if (!describedBy.isEmpty()) | |
| 1702 textOrder.append(AccessibilityText(describedBy, SummaryText)); | |
| 1703 | |
| 1704 // Add help type text that is derived from ancestors. | |
| 1705 for (Node* curr = node(); curr; curr = curr->parentNode()) { | |
| 1706 const AtomicString& summary = getAttribute(summaryAttr); | |
| 1707 if (!summary.isEmpty()) | |
| 1708 textOrder.append(AccessibilityText(summary, SummaryText)); | |
| 1709 | |
| 1710 // The title attribute should be used as help text unless it is already
being used as descriptive text. | |
| 1711 const AtomicString& title = getAttribute(titleAttr); | |
| 1712 if (!title.isEmpty()) | |
| 1713 textOrder.append(AccessibilityText(title, TitleTagText)); | |
| 1714 | |
| 1715 // Only take help text from an ancestor element if its a group or an unk
nown role. If help was | |
| 1716 // added to those kinds of elements, it is likely it was meant for a chi
ld element. | |
| 1717 AXObject* axObj = axObjectCache()->getOrCreate(curr); | |
| 1718 if (!axObj) | |
| 1719 return; | |
| 1720 | |
| 1721 AccessibilityRole role = axObj->roleValue(); | |
| 1722 if (role != GroupRole && role != UnknownRole) | |
| 1723 break; | |
| 1724 } | |
| 1725 } | |
| 1726 | |
| 1727 void AXNodeObject::titleElementText(Vector<AccessibilityText>& textOrder) | |
| 1728 { | |
| 1729 Node* node = this->node(); | |
| 1730 if (!node) | |
| 1731 return; | |
| 1732 | |
| 1733 if (isHTMLInputElement(*node) || AXObject::isARIAInput(ariaRoleAttribute())
|| isControl()) { | |
| 1734 HTMLLabelElement* label = labelForElement(toElement(node)); | |
| 1735 if (label) { | |
| 1736 AXObject* labelObject = axObjectCache()->getOrCreate(label); | |
| 1737 textOrder.append(AccessibilityText(label->innerText(), LabelByElemen
tText, labelObject)); | |
| 1738 return; | |
| 1739 } | |
| 1740 } | |
| 1741 | |
| 1742 AXObject* titleUIElement = this->titleUIElement(); | |
| 1743 if (titleUIElement) | |
| 1744 textOrder.append(AccessibilityText(String(), LabelByElementText, titleUI
Element)); | |
| 1745 } | |
| 1746 | |
| 1747 void AXNodeObject::visibleText(Vector<AccessibilityText>& textOrder) const | |
| 1748 { | |
| 1749 Node* node = this->node(); | |
| 1750 if (!node) | |
| 1751 return; | |
| 1752 | |
| 1753 if (isHTMLInputElement(*node)) { | |
| 1754 HTMLInputElement& input = toHTMLInputElement(*node); | |
| 1755 if (input.isTextButton()) { | |
| 1756 textOrder.append(AccessibilityText(input.valueWithDefault(), Visible
Text)); | |
| 1757 return; | |
| 1758 } | |
| 1759 } | |
| 1760 | |
| 1761 // If this node isn't rendered, there's no inner text we can extract from a
select element. | |
| 1762 if (!isAXRenderObject() && isHTMLSelectElement(*node)) | |
| 1763 return; | |
| 1764 | |
| 1765 bool useTextUnderElement = false; | |
| 1766 | |
| 1767 switch (roleValue()) { | |
| 1768 case PopUpButtonRole: | |
| 1769 // Native popup buttons should not use their button children's text as a
title. That value is retrieved through stringValue(). | |
| 1770 if (isHTMLSelectElement(*node)) | |
| 1771 break; | |
| 1772 case ButtonRole: | |
| 1773 case ToggleButtonRole: | |
| 1774 case CheckBoxRole: | |
| 1775 case ListBoxOptionRole: | |
| 1776 case MenuButtonRole: | |
| 1777 case MenuItemRole: | |
| 1778 case RadioButtonRole: | |
| 1779 case TabRole: | |
| 1780 useTextUnderElement = true; | |
| 1781 break; | |
| 1782 default: | |
| 1783 break; | |
| 1784 } | |
| 1785 | |
| 1786 // If it's focusable but it's not content editable or a known control type,
then it will appear to | |
| 1787 // the user as a single atomic object, so we should use its text as the defa
ult title. | |
| 1788 if (isHeading() || isLink() || isGenericFocusableElement()) | |
| 1789 useTextUnderElement = true; | |
| 1790 | |
| 1791 if (useTextUnderElement) { | |
| 1792 String text = textUnderElement(); | |
| 1793 if (!text.isEmpty()) | |
| 1794 textOrder.append(AccessibilityText(text, ChildrenText)); | |
| 1795 } | |
| 1796 } | |
| 1797 | |
| 1798 } // namespace WebCore | 1682 } // namespace WebCore |
| OLD | NEW |