OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2010 Apple Inc. All Rights Reserved. | 2 * Copyright (C) 2010 Apple 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 * 1. Redistributions of source code must retain the above copyright | 7 * 1. Redistributions of source code must retain the above copyright |
8 * notice, this list of conditions and the following disclaimer. | 8 * notice, this list of conditions and the following disclaimer. |
9 * 2. Redistributions in binary form must reproduce the above copyright | 9 * 2. Redistributions in binary form must reproduce the above copyright |
10 * notice, this list of conditions and the following disclaimer in the | 10 * notice, this list of conditions and the following disclaimer in the |
11 * documentation and/or other materials provided with the distribution. | 11 * documentation and/or other materials provided with the distribution. |
12 * | 12 * |
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY | 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY |
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR | 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR |
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY | 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY |
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
24 */ | 24 */ |
25 | 25 |
26 #include "modules/accessibility/AXMenuListOption.h" | 26 #include "modules/accessibility/AXMenuListOption.h" |
27 | 27 |
28 #include "SkMatrix44.h" | 28 #include "SkMatrix44.h" |
29 #include "core/html/HTMLSelectElement.h" | |
30 #include "modules/accessibility/AXMenuListPopup.h" | 29 #include "modules/accessibility/AXMenuListPopup.h" |
31 #include "modules/accessibility/AXObjectCacheImpl.h" | 30 #include "modules/accessibility/AXObjectCacheImpl.h" |
32 | 31 |
33 namespace blink { | 32 namespace blink { |
34 | 33 |
35 using namespace HTMLNames; | 34 using namespace HTMLNames; |
36 | 35 |
37 AXMenuListOption::AXMenuListOption(HTMLOptionElement* element, | 36 AXMenuListOption::AXMenuListOption(HTMLOptionElement* element, |
38 AXObjectCacheImpl& axObjectCache) | 37 AXObjectCacheImpl& axObjectCache) |
39 : AXMockObject(axObjectCache), m_element(element) {} | 38 : AXMockObject(axObjectCache), m_element(element) {} |
40 | 39 |
41 AXMenuListOption::~AXMenuListOption() { | 40 AXMenuListOption::~AXMenuListOption() { |
42 DCHECK(!m_element); | 41 ASSERT(!m_element); |
43 } | 42 } |
44 | 43 |
45 void AXMenuListOption::detach() { | 44 void AXMenuListOption::detach() { |
46 m_element = nullptr; | 45 m_element = nullptr; |
47 AXMockObject::detach(); | 46 AXMockObject::detach(); |
48 } | 47 } |
49 | 48 |
50 AccessibilityRole AXMenuListOption::roleValue() const { | 49 AccessibilityRole AXMenuListOption::roleValue() const { |
51 const AtomicString& ariaRole = getAttribute(roleAttr); | 50 const AtomicString& ariaRole = getAttribute(roleAttr); |
52 if (ariaRole.isEmpty()) | 51 if (ariaRole.isEmpty()) |
53 return MenuListOptionRole; | 52 return MenuListOptionRole; |
54 | 53 |
55 AccessibilityRole role = ariaRoleToWebCoreRole(ariaRole); | 54 AccessibilityRole role = ariaRoleToWebCoreRole(ariaRole); |
56 if (role) | 55 if (role) |
57 return role; | 56 return role; |
58 return MenuListOptionRole; | 57 return MenuListOptionRole; |
59 } | 58 } |
60 | 59 |
61 AXObject* AXMenuListOption::computeParent() const { | |
62 Node* node = getNode(); | |
63 if (!node) | |
64 return nullptr; | |
65 Node* select = toHTMLOptionElement(node)->ownerSelectElement(); | |
66 if (!select) | |
67 return nullptr; | |
68 AXObject* selectAXObject = axObjectCache().getOrCreate(select); | |
69 if (selectAXObject->hasChildren()) { | |
70 const auto& childObjects = selectAXObject->children(); | |
71 DCHECK(!childObjects.isEmpty()); | |
72 DCHECK_EQ(childObjects.size(), 1UL); | |
73 DCHECK(childObjects[0]->isMenuListPopup()); | |
74 toAXMenuListPopup(childObjects[0].get())->updateChildrenIfNecessary(); | |
75 } else { | |
76 selectAXObject->updateChildrenIfNecessary(); | |
77 } | |
78 return m_parent.get(); | |
79 } | |
80 | |
81 Element* AXMenuListOption::actionElement() const { | 60 Element* AXMenuListOption::actionElement() const { |
82 return m_element; | 61 return m_element; |
83 } | 62 } |
84 | 63 |
85 bool AXMenuListOption::isEnabled() const { | 64 bool AXMenuListOption::isEnabled() const { |
86 // isDisabledFormControl() returns true if the parent <select> element is | 65 // isDisabledFormControl() returns true if the parent <select> element is |
87 // disabled, which we don't want. | 66 // disabled, which we don't want. |
88 return m_element && !m_element->ownElementDisabled(); | 67 return m_element && !m_element->ownElementDisabled(); |
89 } | 68 } |
90 | 69 |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
129 AXObject** outContainer, | 108 AXObject** outContainer, |
130 FloatRect& outBoundsInContainer, | 109 FloatRect& outBoundsInContainer, |
131 SkMatrix44& outContainerTransform) const { | 110 SkMatrix44& outContainerTransform) const { |
132 *outContainer = nullptr; | 111 *outContainer = nullptr; |
133 outBoundsInContainer = FloatRect(); | 112 outBoundsInContainer = FloatRect(); |
134 outContainerTransform.setIdentity(); | 113 outContainerTransform.setIdentity(); |
135 | 114 |
136 AXObject* parent = parentObject(); | 115 AXObject* parent = parentObject(); |
137 if (!parent) | 116 if (!parent) |
138 return; | 117 return; |
139 DCHECK(parent->isMenuListPopup()); | 118 ASSERT(parent->isMenuListPopup()); |
140 | 119 |
141 AXObject* grandparent = parent->parentObject(); | 120 AXObject* grandparent = parent->parentObject(); |
142 if (!grandparent) | 121 if (!grandparent) |
143 return; | 122 return; |
144 DCHECK(grandparent->isMenuList()); | 123 ASSERT(grandparent->isMenuList()); |
145 grandparent->getRelativeBounds(outContainer, outBoundsInContainer, | 124 grandparent->getRelativeBounds(outContainer, outBoundsInContainer, |
146 outContainerTransform); | 125 outContainerTransform); |
147 } | 126 } |
148 | 127 |
149 String AXMenuListOption::textAlternative(bool recursive, | 128 String AXMenuListOption::textAlternative(bool recursive, |
150 bool inAriaLabelledByTraversal, | 129 bool inAriaLabelledByTraversal, |
151 AXObjectSet& visited, | 130 AXObjectSet& visited, |
152 AXNameFrom& nameFrom, | 131 AXNameFrom& nameFrom, |
153 AXRelatedObjectVector* relatedObjects, | 132 AXRelatedObjectVector* relatedObjects, |
154 NameSources* nameSources) const { | 133 NameSources* nameSources) const { |
155 // If nameSources is non-null, relatedObjects is used in filling it in, so it | 134 // If nameSources is non-null, relatedObjects is used in filling it in, so it |
156 // must be non-null as well. | 135 // must be non-null as well. |
157 if (nameSources) | 136 if (nameSources) |
158 DCHECK(relatedObjects); | 137 ASSERT(relatedObjects); |
159 | 138 |
160 if (!getNode()) | 139 if (!getNode()) |
161 return String(); | 140 return String(); |
162 | 141 |
163 bool foundTextAlternative = false; | 142 bool foundTextAlternative = false; |
164 String textAlternative = ariaTextAlternative( | 143 String textAlternative = ariaTextAlternative( |
165 recursive, inAriaLabelledByTraversal, visited, nameFrom, relatedObjects, | 144 recursive, inAriaLabelledByTraversal, visited, nameFrom, relatedObjects, |
166 nameSources, &foundTextAlternative); | 145 nameSources, &foundTextAlternative); |
167 if (foundTextAlternative && !nameSources) | 146 if (foundTextAlternative && !nameSources) |
168 return textAlternative; | 147 return textAlternative; |
169 | 148 |
170 nameFrom = AXNameFromContents; | 149 nameFrom = AXNameFromContents; |
171 textAlternative = m_element->displayLabel(); | 150 textAlternative = m_element->displayLabel(); |
172 if (nameSources) { | 151 if (nameSources) { |
173 nameSources->push_back(NameSource(foundTextAlternative)); | 152 nameSources->push_back(NameSource(foundTextAlternative)); |
174 nameSources->back().type = nameFrom; | 153 nameSources->back().type = nameFrom; |
175 nameSources->back().text = textAlternative; | 154 nameSources->back().text = textAlternative; |
176 foundTextAlternative = true; | 155 foundTextAlternative = true; |
177 } | 156 } |
178 | 157 |
179 return textAlternative; | 158 return textAlternative; |
180 } | 159 } |
181 | 160 |
182 DEFINE_TRACE(AXMenuListOption) { | 161 DEFINE_TRACE(AXMenuListOption) { |
183 visitor->trace(m_element); | 162 visitor->trace(m_element); |
184 AXMockObject::trace(visitor); | 163 AXMockObject::trace(visitor); |
185 } | 164 } |
186 | 165 |
187 } // namespace blink | 166 } // namespace blink |
OLD | NEW |