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 |