Support boundingBoxRect and elementRect in AXIsolatedObject.
[WebKit-https.git] / Source / WebCore / accessibility / isolatedtree / AXIsolatedTreeNode.cpp
1 /*
2  * Copyright (C) 2019 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23  * THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #include "config.h"
27
28 #if ENABLE(ACCESSIBILITY_ISOLATED_TREE)
29 #include "AXIsolatedTreeNode.h"
30
31 #include "AccessibilityObject.h"
32
33 extern "C" bool _AXUIElementRequestServicedBySecondaryAXThread(void);
34
35 namespace WebCore {
36
37 AXIsolatedObject::AXIsolatedObject(AXCoreObject& object)
38     : m_id(object.objectID())
39 {
40     ASSERT(isMainThread());
41     initializeAttributeData(object);
42 #if !ASSERT_DISABLED
43     m_initialized = true;
44 #endif
45 }
46
47 Ref<AXIsolatedObject> AXIsolatedObject::create(AXCoreObject& object)
48 {
49     return adoptRef(*new AXIsolatedObject(object));
50 }
51
52 AXIsolatedObject::~AXIsolatedObject() = default;
53
54 void AXIsolatedObject::initializeAttributeData(AXCoreObject& object)
55 {
56     setProperty(AXPropertyName::BoundingBoxRect, object.boundingBoxRect());
57     setProperty(AXPropertyName::ElementRect, object.elementRect());
58     setProperty(AXPropertyName::RoleValue, static_cast<int>(object.roleValue()));
59     setProperty(AXPropertyName::RolePlatformString, object.rolePlatformString().isolatedCopy());
60     setProperty(AXPropertyName::ARIALandmarkRoleDescription, object.ariaLandmarkRoleDescription().isolatedCopy());
61     setProperty(AXPropertyName::RoleDescription, object.roleDescription().isolatedCopy());
62     setProperty(AXPropertyName::IsAttachment, object.isAttachment());
63     setProperty(AXPropertyName::IsMediaControlLabel, object.isMediaControlLabel());
64     setProperty(AXPropertyName::IsLink, object.isLink());
65     setProperty(AXPropertyName::IsImageMapLink, object.isImageMapLink());
66     setProperty(AXPropertyName::IsImage, object.isImage());
67     setProperty(AXPropertyName::IsFileUploadButton, object.isFileUploadButton());
68     setProperty(AXPropertyName::IsAccessibilityIgnored, object.accessibilityIsIgnored());
69     setProperty(AXPropertyName::IsTree, object.isTree());
70     setProperty(AXPropertyName::IsScrollbar, object.isScrollbar());
71     setProperty(AXPropertyName::RelativeFrame, object.relativeFrame());
72     setProperty(AXPropertyName::SpeechHint, object.speechHintAttributeValue().isolatedCopy());
73     setProperty(AXPropertyName::Title, object.titleAttributeValue().isolatedCopy());
74     setProperty(AXPropertyName::Description, object.descriptionAttributeValue().isolatedCopy());
75     setProperty(AXPropertyName::HelpText, object.helpTextAttributeValue().isolatedCopy());
76
77     if (bool isMathElement = object.isMathElement()) {
78         setProperty(AXPropertyName::IsMathElement, isMathElement);
79         setProperty(AXPropertyName::IsAnonymousMathOperator, object.isAnonymousMathOperator());
80         setProperty(AXPropertyName::IsMathFraction, object.isMathFraction());
81         setProperty(AXPropertyName::IsMathFenced, object.isMathFenced());
82         setProperty(AXPropertyName::IsMathSubscriptSuperscript, object.isMathSubscriptSuperscript());
83         setProperty(AXPropertyName::IsMathRow, object.isMathRow());
84         setProperty(AXPropertyName::IsMathUnderOver, object.isMathUnderOver());
85         setProperty(AXPropertyName::IsMathRoot, object.isMathRoot());
86         setProperty(AXPropertyName::IsMathSquareRoot, object.isMathSquareRoot());
87         setProperty(AXPropertyName::IsMathText, object.isMathText());
88         setProperty(AXPropertyName::IsMathNumber, object.isMathNumber());
89         setProperty(AXPropertyName::IsMathOperator, object.isMathOperator());
90         setProperty(AXPropertyName::IsMathFenceOperator, object.isMathFenceOperator());
91         setProperty(AXPropertyName::IsMathSeparatorOperator, object.isMathSeparatorOperator());
92         setProperty(AXPropertyName::IsMathIdentifier, object.isMathIdentifier());
93         setProperty(AXPropertyName::IsMathTable, object.isMathTable());
94         setProperty(AXPropertyName::IsMathTableRow, object.isMathTableRow());
95         setProperty(AXPropertyName::IsMathTableCell, object.isMathTableCell());
96         setProperty(AXPropertyName::IsMathMultiscript, object.isMathMultiscript());
97         setProperty(AXPropertyName::IsMathToken, object.isMathToken());
98         setProperty(AXPropertyName::MathFencedOpenString, object.mathFencedOpenString());
99         setProperty(AXPropertyName::MathFencedCloseString, object.mathFencedCloseString());
100         setProperty(AXPropertyName::MathLineThickness, object.mathLineThickness());
101         setObjectProperty(AXPropertyName::MathRadicandObject, object.mathRadicandObject());
102         setObjectProperty(AXPropertyName::MathRootIndexObject, object.mathRootIndexObject());
103         setObjectProperty(AXPropertyName::MathUnderObject, object.mathUnderObject());
104         setObjectProperty(AXPropertyName::MathOverObject, object.mathOverObject());
105         setObjectProperty(AXPropertyName::MathNumeratorObject, object.mathNumeratorObject());
106         setObjectProperty(AXPropertyName::MathDenominatorObject, object.mathDenominatorObject());
107         setObjectProperty(AXPropertyName::MathBaseObject, object.mathBaseObject());
108         setObjectProperty(AXPropertyName::MathSubscriptObject, object.mathSubscriptObject());
109         setObjectProperty(AXPropertyName::MathSuperscriptObject, object.mathSuperscriptObject());
110     }
111 }
112
113 void AXIsolatedObject::setObjectProperty(AXPropertyName propertyName, AXCoreObject* object)
114 {
115     if (object)
116         setProperty(propertyName, object->objectID());
117     else
118         setProperty(propertyName, nullptr, true);
119 }
120
121 void AXIsolatedObject::setProperty(AXPropertyName propertyName, AttributeValueVariant&& value, bool shouldRemove)
122 {
123     ASSERT(!m_initialized);
124     ASSERT(isMainThread());
125
126     if (shouldRemove)
127         m_attributeMap.remove(propertyName);
128     else
129         m_attributeMap.set(propertyName, value);
130 }
131
132 void AXIsolatedObject::appendChild(AXID axID)
133 {
134     ASSERT(isMainThread());
135     m_childrenIDs.append(axID);
136 }
137
138 void AXIsolatedObject::setParent(AXID parent)
139 {
140     ASSERT(isMainThread());
141     m_parent = parent;
142 }
143
144 void AXIsolatedObject::setTreeIdentifier(AXIsolatedTreeID treeIdentifier)
145 {
146     m_treeIdentifier = treeIdentifier;
147     if (auto tree = AXIsolatedTree::treeForID(m_treeIdentifier))
148         m_cachedTree = tree;
149 }
150
151 const AXCoreObject::AccessibilityChildrenVector& AXIsolatedObject::children(bool)
152 {
153     if (_AXUIElementRequestServicedBySecondaryAXThread()) {
154         m_children.clear();
155         m_children.reserveInitialCapacity(m_childrenIDs.size());
156         auto tree = this->tree();
157         for (auto childID : m_childrenIDs)
158             m_children.uncheckedAppend(tree->nodeForID(childID));
159     }
160     return m_children;
161 }
162
163 AXCoreObject* AXIsolatedObject::focusedUIElement() const
164 {
165     if (auto focusedElement = tree()->focusedUIElement())
166         return focusedElement.get();
167     return nullptr;
168 }
169     
170 AXCoreObject* AXIsolatedObject::parentObjectUnignored() const
171 {
172     return tree()->nodeForID(parent()).get();
173 }
174
175 AXCoreObject* AXIsolatedObject::accessibilityHitTest(const IntPoint& point) const
176 {
177     if (!relativeFrame().contains(point))
178         return nullptr;
179     for (const auto& childID : m_childrenIDs) {
180         auto child = tree()->nodeForID(childID);
181         ASSERT(child);
182         if (child && child->relativeFrame().contains(point))
183             return child->accessibilityHitTest(point);
184     }
185     return const_cast<AXIsolatedObject*>(this);
186 }
187
188 AXIsolatedTree* AXIsolatedObject::tree() const
189 {
190     return m_cachedTree.get();
191 }
192
193 AXCoreObject* AXIsolatedObject::objectAttributeValue(AXPropertyName propertyName) const
194 {
195     auto value = m_attributeMap.get(propertyName);
196     AXID nodeID = WTF::switchOn(value,
197         [] (AXID& typedValue) { return typedValue; },
198         [] (auto&) { return InvalidAXID; }
199     );
200     
201     return tree()->nodeForID(nodeID).get();
202 }
203
204 template<typename T>
205 T AXIsolatedObject::rectAttributeValue(AXPropertyName propertyName) const
206 {
207     auto value = m_attributeMap.get(propertyName);
208     return WTF::switchOn(value,
209         [] (T& typedValue) { return typedValue; },
210         [] (auto&) { return T { }; }
211     );
212 }
213
214 double AXIsolatedObject::doubleAttributeValue(AXPropertyName propertyName) const
215 {
216     auto value = m_attributeMap.get(propertyName);
217     return WTF::switchOn(value,
218         [] (double& typedValue) { return typedValue; },
219         [] (auto&) { return 0; }
220     );
221 }
222
223 unsigned AXIsolatedObject::unsignedAttributeValue(AXPropertyName propertyName) const
224 {
225     auto value = m_attributeMap.get(propertyName);
226     return WTF::switchOn(value,
227         [] (unsigned& typedValue) { return typedValue; },
228         [] (auto&) { return 0; }
229     );
230 }
231
232 bool AXIsolatedObject::boolAttributeValue(AXPropertyName propertyName) const
233 {
234     auto value = m_attributeMap.get(propertyName);
235     return WTF::switchOn(value,
236         [] (bool& typedValue) { return typedValue; },
237         [] (auto&) { return false; }
238     );
239 }
240
241 const String AXIsolatedObject::stringAttributeValue(AXPropertyName propertyName) const
242 {
243     auto value = m_attributeMap.get(propertyName);
244     return WTF::switchOn(value,
245         [] (String& typedValue) { return typedValue; },
246         [] (auto&) { return emptyString(); }
247     );
248 }
249
250 int AXIsolatedObject::intAttributeValue(AXPropertyName propertyName) const
251 {
252     auto value = m_attributeMap.get(propertyName);
253     return WTF::switchOn(value,
254         [] (int& typedValue) { return typedValue; },
255         [] (auto&) { return 0; }
256     );
257 }
258
259 void AXIsolatedObject::updateBackingStore()
260 {
261     if (_AXUIElementRequestServicedBySecondaryAXThread()) {
262         RELEASE_ASSERT(!isMainThread());
263         if (auto tree = this->tree())
264             tree->applyPendingChanges();
265     }
266 }
267
268 } // namespace WebCore
269
270 #endif // ENABLE((ACCESSIBILITY_ISOLATED_TREE)