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 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
166 | 166 |
167 // If this element is within a parent that cannot have children, it should n
ot be exposed. | 167 // If this element is within a parent that cannot have children, it should n
ot be exposed. |
168 if (isDescendantOfLeafNode()) { | 168 if (isDescendantOfLeafNode()) { |
169 if (ignoredReasons) | 169 if (ignoredReasons) |
170 ignoredReasons->append(IgnoredReason(AXAncestorIsLeafNode, leafNodeA
ncestor())); | 170 ignoredReasons->append(IgnoredReason(AXAncestorIsLeafNode, leafNodeA
ncestor())); |
171 return true; | 171 return true; |
172 } | 172 } |
173 | 173 |
174 // Ignore labels that are already referenced by a control. | 174 // Ignore labels that are already referenced by a control. |
175 AXObject* controlObject = correspondingControlForLabelElement(); | 175 AXObject* controlObject = correspondingControlForLabelElement(); |
176 if (controlObject && controlObject->isCheckboxOrRadio()) { | 176 if (controlObject && controlObject->isCheckboxOrRadio() && controlObject->na
meFromLabelElement()) { |
177 AXNameFrom controlNameFrom; | 177 if (ignoredReasons) { |
178 AXObject::AXObjectVector controlNameObjects; | 178 HTMLLabelElement* label = labelElementContainer(); |
179 controlObject->name(controlNameFrom, &controlNameObjects); | 179 if (label && !label->isSameNode(node())) { |
180 if (controlNameFrom == AXNameFromRelatedElement) { | 180 AXObject* labelAXObject = axObjectCache().getOrCreate(label); |
181 if (ignoredReasons) { | 181 ignoredReasons->append(IgnoredReason(AXLabelContainer, labelAXOb
ject)); |
182 HTMLLabelElement* label = labelElementContainer(); | 182 } |
183 if (label && !label->isSameNode(node())) { | |
184 AXObject* labelAXObject = axObjectCache().getOrCreate(label)
; | |
185 ignoredReasons->append(IgnoredReason(AXLabelContainer, label
AXObject)); | |
186 } | |
187 | 183 |
188 ignoredReasons->append(IgnoredReason(AXLabelFor, controlObject))
; | 184 ignoredReasons->append(IgnoredReason(AXLabelFor, controlObject)); |
189 } | |
190 return true; | |
191 } | 185 } |
| 186 return true; |
192 } | 187 } |
193 | 188 |
194 Element* element = node()->isElementNode() ? toElement(node()) : node()->par
entElement(); | 189 Element* element = node()->isElementNode() ? toElement(node()) : node()->par
entElement(); |
195 if (!layoutObject() | 190 if (!layoutObject() |
196 && (!element || !element->isInCanvasSubtree()) | 191 && (!element || !element->isInCanvasSubtree()) |
197 && !equalIgnoringCase(getAttribute(aria_hiddenAttr), "false")) { | 192 && !equalIgnoringCase(getAttribute(aria_hiddenAttr), "false")) { |
198 if (ignoredReasons) | 193 if (ignoredReasons) |
199 ignoredReasons->append(IgnoredReason(AXNotRendered)); | 194 ignoredReasons->append(IgnoredReason(AXNotRendered)); |
200 return true; | 195 return true; |
201 } | 196 } |
(...skipping 1407 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1609 } | 1604 } |
1610 | 1605 |
1611 String result = recursiveTextAlternative(*child, false, visited); | 1606 String result = recursiveTextAlternative(*child, false, visited); |
1612 accumulatedText.append(result); | 1607 accumulatedText.append(result); |
1613 previous = child; | 1608 previous = child; |
1614 } | 1609 } |
1615 | 1610 |
1616 return accumulatedText.toString(); | 1611 return accumulatedText.toString(); |
1617 } | 1612 } |
1618 | 1613 |
| 1614 bool AXNodeObject::nameFromLabelElement() const |
| 1615 { |
| 1616 // This unfortunately duplicates a bit of logic from textAlternative and nat
iveTextAlternative, |
| 1617 // but it's necessary because nameFromLabelElement needs to be called from |
| 1618 // computeAccessibilityIsIgnored, which isn't allowed to call axObjectCache-
>getOrCreate. |
| 1619 |
| 1620 if (!node() && !layoutObject()) |
| 1621 return false; |
| 1622 |
| 1623 // Step 2A from: http://www.w3.org/TR/accname-aam-1.1 |
| 1624 if (layoutObject() |
| 1625 && layoutObject()->style()->visibility() != VISIBLE |
| 1626 && !equalIgnoringCase(getAttribute(aria_hiddenAttr), "false")) { |
| 1627 return false; |
| 1628 } |
| 1629 |
| 1630 // Step 2B from: http://www.w3.org/TR/accname-aam-1.1 |
| 1631 WillBeHeapVector<RawPtrWillBeMember<Element>> elements; |
| 1632 ariaLabelledbyElementVector(elements); |
| 1633 if (elements.size() > 0) |
| 1634 return false; |
| 1635 |
| 1636 // Step 2C from: http://www.w3.org/TR/accname-aam-1.1 |
| 1637 const AtomicString& ariaLabel = getAttribute(aria_labelAttr); |
| 1638 if (!ariaLabel.isEmpty()) |
| 1639 return false; |
| 1640 |
| 1641 // Based on http://rawgit.com/w3c/aria/master/html-aam/html-aam.html#accessi
ble-name-and-description-calculation |
| 1642 // 5.1/5.5 Text inputs, Other labelable Elements |
| 1643 HTMLElement* htmlElement = nullptr; |
| 1644 if (node()->isHTMLElement()) |
| 1645 htmlElement = toHTMLElement(node()); |
| 1646 if (htmlElement && htmlElement->isLabelable()) { |
| 1647 HTMLLabelElement* label = labelForElement(htmlElement); |
| 1648 if (label) |
| 1649 return true; |
| 1650 } |
| 1651 |
| 1652 return false; |
| 1653 } |
| 1654 |
1619 LayoutRect AXNodeObject::elementRect() const | 1655 LayoutRect AXNodeObject::elementRect() const |
1620 { | 1656 { |
1621 // First check if it has a custom rect, for example if this element is tied
to a canvas path. | 1657 // First check if it has a custom rect, for example if this element is tied
to a canvas path. |
1622 if (!m_explicitElementRect.isEmpty()) | 1658 if (!m_explicitElementRect.isEmpty()) |
1623 return m_explicitElementRect; | 1659 return m_explicitElementRect; |
1624 | 1660 |
1625 // FIXME: If there are a lot of elements in the canvas, it will be inefficie
nt. | 1661 // FIXME: If there are a lot of elements in the canvas, it will be inefficie
nt. |
1626 // We can avoid the inefficient calculations by using AXComputedObjectAttrib
uteCache. | 1662 // We can avoid the inefficient calculations by using AXComputedObjectAttrib
uteCache. |
1627 if (node()->parentElement()->isInCanvasSubtree()) { | 1663 if (node()->parentElement()->isInCanvasSubtree()) { |
1628 LayoutRect rect; | 1664 LayoutRect rect; |
(...skipping 429 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2058 ASSERT(relatedObjects); | 2094 ASSERT(relatedObjects); |
2059 | 2095 |
2060 String textAlternative; | 2096 String textAlternative; |
2061 AXRelatedObjectVector localRelatedObjects; | 2097 AXRelatedObjectVector localRelatedObjects; |
2062 | 2098 |
2063 const HTMLInputElement* inputElement = nullptr; | 2099 const HTMLInputElement* inputElement = nullptr; |
2064 if (isHTMLInputElement(node())) | 2100 if (isHTMLInputElement(node())) |
2065 inputElement = toHTMLInputElement(node()); | 2101 inputElement = toHTMLInputElement(node()); |
2066 | 2102 |
2067 // 5.1/5.5 Text inputs, Other labelable Elements | 2103 // 5.1/5.5 Text inputs, Other labelable Elements |
| 2104 // If you change this logic, update AXNodeObject::nameFromLabelElement, too. |
2068 HTMLElement* htmlElement = nullptr; | 2105 HTMLElement* htmlElement = nullptr; |
2069 if (node()->isHTMLElement()) | 2106 if (node()->isHTMLElement()) |
2070 htmlElement = toHTMLElement(node()); | 2107 htmlElement = toHTMLElement(node()); |
2071 if (htmlElement && htmlElement->isLabelable()) { | 2108 if (htmlElement && htmlElement->isLabelable()) { |
2072 // label | 2109 // label |
2073 nameFrom = AXNameFromRelatedElement; | 2110 nameFrom = AXNameFromRelatedElement; |
2074 if (nameSources) { | 2111 if (nameSources) { |
2075 nameSources->append(NameSource(*foundTextAlternative)); | 2112 nameSources->append(NameSource(*foundTextAlternative)); |
2076 nameSources->last().type = nameFrom; | 2113 nameSources->last().type = nameFrom; |
2077 nameSources->last().nativeSource = AXTextFromNativeHTMLLabel; | 2114 nameSources->last().nativeSource = AXTextFromNativeHTMLLabel; |
(...skipping 569 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2647 return placeholder; | 2684 return placeholder; |
2648 } | 2685 } |
2649 | 2686 |
2650 DEFINE_TRACE(AXNodeObject) | 2687 DEFINE_TRACE(AXNodeObject) |
2651 { | 2688 { |
2652 visitor->trace(m_node); | 2689 visitor->trace(m_node); |
2653 AXObject::trace(visitor); | 2690 AXObject::trace(visitor); |
2654 } | 2691 } |
2655 | 2692 |
2656 } // namespace blin | 2693 } // namespace blin |
OLD | NEW |