e2ef412122963dc5e5f72d49c72f1d9fee9b75b8
[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 namespace WebCore {
34
35 AXIsolatedTreeNode::AXIsolatedTreeNode(const AccessibilityObject& object)
36     : m_identifier(object.axObjectID())
37 {
38     ASSERT(isMainThread());
39     initializeAttributeData(object);
40 #if !ASSERT_DISABLED
41     m_initialized = true;
42 #endif
43 }
44
45 Ref<AXIsolatedTreeNode> AXIsolatedTreeNode::create(const AccessibilityObject& object)
46 {
47     return adoptRef(*new AXIsolatedTreeNode(object));
48 }
49
50 AXIsolatedTreeNode::~AXIsolatedTreeNode() = default;
51
52 void AXIsolatedTreeNode::initializeAttributeData(const AccessibilityObject& object)
53 {
54     setProperty(AXPropertyName::RoleValue, static_cast<int>(object.roleValue()));
55     setProperty(AXPropertyName::IsAttachment, object.isAttachment());
56     setProperty(AXPropertyName::IsMediaControlLabel, object.isMediaControlLabel());
57     setProperty(AXPropertyName::IsLink, object.isLink());
58     setProperty(AXPropertyName::IsImageMapLink, object.isImageMapLink());
59     setProperty(AXPropertyName::IsImage, object.isImage());
60     setProperty(AXPropertyName::IsFileUploadButton, object.isFileUploadButton());
61     setProperty(AXPropertyName::IsAccessibilityIgnored, object.accessibilityIsIgnored());
62     setProperty(AXPropertyName::IsTree, object.isTree());
63     setProperty(AXPropertyName::IsScrollbar, object.isScrollbar());
64     setProperty(AXPropertyName::RelativeFrame, object.relativeFrame());
65     setProperty(AXPropertyName::SpeechHint, object.speechHintAttributeValue().isolatedCopy());
66     setProperty(AXPropertyName::Title, object.titleAttributeValue().isolatedCopy());
67     setProperty(AXPropertyName::Description, object.descriptionAttributeValue().isolatedCopy());
68     setProperty(AXPropertyName::HelpText, object.helpTextAttributeValue().isolatedCopy());
69 }
70
71 void AXIsolatedTreeNode::setProperty(AXPropertyName propertyName, AttributeValueVariant&& value, bool shouldRemove)
72 {
73     ASSERT(!m_initialized);
74     ASSERT(isMainThread());
75
76     if (shouldRemove)
77         m_attributeMap.remove(propertyName);
78     else
79         m_attributeMap.set(propertyName, value);
80 }
81
82 void AXIsolatedTreeNode::appendChild(AXID axID)
83 {
84     ASSERT(isMainThread());
85     m_children.append(axID);
86 }
87
88 void AXIsolatedTreeNode::setParent(AXID parent)
89 {
90     ASSERT(isMainThread());
91     m_parent = parent;
92 }
93
94 void AXIsolatedTreeNode::setTreeIdentifier(AXIsolatedTreeID treeIdentifier)
95 {
96     m_treeIdentifier = treeIdentifier;
97     if (auto tree = AXIsolatedTree::treeForID(m_treeIdentifier))
98         m_cachedTree = makeWeakPtr(tree.get());
99 }
100
101 AccessibilityObjectInterface* AXIsolatedTreeNode::focusedUIElement() const
102 {
103     if (auto focusedElement = tree()->focusedUIElement())
104         return focusedElement.get();
105     return nullptr;
106 }
107     
108 AccessibilityObjectInterface* AXIsolatedTreeNode::parentObjectInterfaceUnignored() const
109 {
110     return tree()->nodeForID(parent()).get();
111 }
112
113 AccessibilityObjectInterface* AXIsolatedTreeNode::accessibilityHitTest(const IntPoint& point) const
114 {
115     if (!relativeFrame().contains(point))
116         return nullptr;
117     for (auto childID : children()) {
118         auto child = tree()->nodeForID(childID);
119         ASSERT(child);
120         if (child && child->relativeFrame().contains(point))
121             return child->accessibilityHitTest(point);
122     }
123     return const_cast<AXIsolatedTreeNode*>(this);
124 }
125
126 AXIsolatedTree* AXIsolatedTreeNode::tree() const
127 {
128     return m_cachedTree.get();
129 }
130
131 FloatRect AXIsolatedTreeNode::rectAttributeValue(AXPropertyName propertyName) const
132 {
133     auto value = m_attributeMap.get(propertyName);
134     return WTF::switchOn(value,
135         [&zeroRect] (Optional<FloatRect> typedValue) {
136             if (!typedValue)
137                 return FloatRect { };
138             return typedValue.value();
139         },
140         [] (auto&) { return FloatRect { }; }
141     );
142 }
143
144 double AXIsolatedTreeNode::doubleAttributeValue(AXPropertyName propertyName) const
145 {
146     auto value = m_attributeMap.get(propertyName);
147     return WTF::switchOn(value,
148         [&] (double& typedValue) { return typedValue; },
149         [] (auto&) { return 0; }
150     );
151 }
152
153 unsigned AXIsolatedTreeNode::unsignedAttributeValue(AXPropertyName propertyName) const
154 {
155     auto value = m_attributeMap.get(propertyName);
156     return WTF::switchOn(value,
157         [&] (unsigned& typedValue) { return typedValue; },
158         [] (auto&) { return 0; }
159     );
160 }
161
162 bool AXIsolatedTreeNode::boolAttributeValue(AXPropertyName propertyName) const
163 {
164     auto value = m_attributeMap.get(propertyName);
165     return WTF::switchOn(value,
166         [&] (bool& typedValue) { return typedValue; },
167         [] (auto&) { return false; }
168     );
169 }
170
171 const String AXIsolatedTreeNode::stringAttributeValue(AXPropertyName propertyName) const
172 {
173     auto value = m_attributeMap.get(propertyName);
174     return WTF::switchOn(value,
175         [&] (String& typedValue) { return typedValue; },
176         [] (auto&) { return emptyString(); }
177     );
178 }
179
180 int AXIsolatedTreeNode::intAttributeValue(AXPropertyName propertyName) const
181 {
182     auto value = m_attributeMap.get(propertyName);
183     return WTF::switchOn(value,
184         [&] (int& typedValue) { return typedValue; },
185         [] (auto&) { return 0; }
186     );
187 }
188
189 } // namespace WebCore
190
191 #endif // ENABLE((ACCESSIBILITY_ISOLATED_TREE)