Migrate accessibility/ to using nullptr instead of 0
[WebKit-https.git] / Source / WebCore / accessibility / AccessibilityScrollView.cpp
1 /*
2  * Copyright (C) 2011 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  *
8  * 1.  Redistributions of source code must retain the above copyright
9  *     notice, this list of conditions and the following disclaimer.
10  * 2.  Redistributions in binary form must reproduce the above copyright
11  *     notice, this list of conditions and the following disclaimer in the
12  *     documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
15  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
16  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
17  * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
18  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
19  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
20  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
21  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #include "config.h"
27 #include "AccessibilityScrollView.h"
28
29 #include "AXObjectCache.h"
30 #include "AccessibilityScrollbar.h"
31 #include "Frame.h"
32 #include "FrameView.h"
33 #include "HTMLFrameOwnerElement.h"
34 #include "RenderElement.h"
35 #include "ScrollView.h"
36 #include "Widget.h"
37
38 namespace WebCore {
39     
40 AccessibilityScrollView::AccessibilityScrollView(ScrollView* view)
41     : m_scrollView(view)
42     , m_childrenDirty(false)
43 {
44 }
45
46 AccessibilityScrollView::~AccessibilityScrollView()
47 {
48     ASSERT(isDetached());
49 }
50
51 void AccessibilityScrollView::detach(AccessibilityDetachmentType detachmentType, AXObjectCache* cache)
52 {
53     AccessibilityObject::detach(detachmentType, cache);
54     m_scrollView = nullptr;
55 }
56
57 PassRefPtr<AccessibilityScrollView> AccessibilityScrollView::create(ScrollView* view)
58 {
59     return adoptRef(new AccessibilityScrollView(view));
60 }
61     
62 AccessibilityObject* AccessibilityScrollView::scrollBar(AccessibilityOrientation orientation)
63 {
64     updateScrollbars();
65     
66     switch (orientation) {
67     case AccessibilityOrientationVertical:
68         return m_verticalScrollbar ? m_verticalScrollbar.get() : 0;
69     case AccessibilityOrientationHorizontal:
70         return m_horizontalScrollbar ? m_horizontalScrollbar.get() : 0;
71     }
72     
73     return nullptr;
74 }
75
76 // If this is WebKit1 then the native scroll view needs to return the
77 // AX information (because there are no scroll bar children in the ScrollView object in WK1).
78 // In WebKit2, the ScrollView object will return the AX information (because there are no platform widgets).
79 bool AccessibilityScrollView::isAttachment() const
80 {
81     return m_scrollView && m_scrollView->platformWidget();
82 }
83
84 Widget* AccessibilityScrollView::widgetForAttachmentView() const
85 {
86     return m_scrollView;
87 }
88     
89 bool AccessibilityScrollView::canSetFocusAttribute() const
90 {
91     AccessibilityObject* webArea = webAreaObject();
92     return webArea && webArea->canSetFocusAttribute();
93 }
94     
95 bool AccessibilityScrollView::isFocused() const
96 {
97     AccessibilityObject* webArea = webAreaObject();
98     return webArea && webArea->isFocused();
99 }
100     
101 void AccessibilityScrollView::setFocused(bool focused)
102 {
103     if (AccessibilityObject* webArea = webAreaObject())
104         webArea->setFocused(focused);
105 }
106
107 void AccessibilityScrollView::updateChildrenIfNecessary()
108 {
109     if (m_childrenDirty)
110         clearChildren();
111
112     if (!m_haveChildren)
113         addChildren();
114     
115     updateScrollbars();
116 }
117
118 void AccessibilityScrollView::updateScrollbars()
119 {
120     if (!m_scrollView)
121         return;
122
123     if (m_scrollView->horizontalScrollbar() && !m_horizontalScrollbar)
124         m_horizontalScrollbar = addChildScrollbar(m_scrollView->horizontalScrollbar());
125     else if (!m_scrollView->horizontalScrollbar() && m_horizontalScrollbar) {
126         removeChildScrollbar(m_horizontalScrollbar.get());
127         m_horizontalScrollbar = nullptr;
128     }
129
130     if (m_scrollView->verticalScrollbar() && !m_verticalScrollbar)
131         m_verticalScrollbar = addChildScrollbar(m_scrollView->verticalScrollbar());
132     else if (!m_scrollView->verticalScrollbar() && m_verticalScrollbar) {
133         removeChildScrollbar(m_verticalScrollbar.get());
134         m_verticalScrollbar = nullptr;
135     }
136 }
137     
138 void AccessibilityScrollView::removeChildScrollbar(AccessibilityObject* scrollbar)
139 {
140     size_t pos = m_children.find(scrollbar);
141     if (pos != WTF::notFound) {
142         m_children[pos]->detachFromParent();
143         m_children.remove(pos);
144     }
145 }
146     
147 AccessibilityScrollbar* AccessibilityScrollView::addChildScrollbar(Scrollbar* scrollbar)
148 {
149     if (!scrollbar)
150         return nullptr;
151     
152     AXObjectCache* cache = axObjectCache();
153     if (!cache)
154         return nullptr;
155
156     AccessibilityScrollbar* scrollBarObject = toAccessibilityScrollbar(cache->getOrCreate(scrollbar));
157     scrollBarObject->setParent(this);
158     m_children.append(scrollBarObject);
159     return scrollBarObject;
160 }
161         
162 void AccessibilityScrollView::clearChildren()
163 {
164     AccessibilityObject::clearChildren();
165     m_verticalScrollbar = nullptr;
166     m_horizontalScrollbar = nullptr;
167 }
168
169 bool AccessibilityScrollView::computeAccessibilityIsIgnored() const
170 {
171     AccessibilityObject* webArea = webAreaObject();
172     if (!webArea)
173         return true;
174     
175     return webArea->accessibilityIsIgnored();
176 }
177
178 void AccessibilityScrollView::addChildren()
179 {
180     ASSERT(!m_haveChildren);
181     m_haveChildren = true;
182     
183     AccessibilityObject* webArea = webAreaObject();
184     if (webArea && !webArea->accessibilityIsIgnored())
185         m_children.append(webArea);
186     
187     updateScrollbars();
188 }
189
190 AccessibilityObject* AccessibilityScrollView::webAreaObject() const
191 {
192     if (!m_scrollView || !m_scrollView->isFrameView())
193         return nullptr;
194     
195     Document* doc = toFrameView(m_scrollView)->frame().document();
196     if (!doc || !doc->hasLivingRenderTree())
197         return nullptr;
198
199     if (AXObjectCache* cache = axObjectCache())
200         return cache->getOrCreate(doc);
201     
202     return nullptr;
203 }
204
205 AccessibilityObject* AccessibilityScrollView::accessibilityHitTest(const IntPoint& point) const
206 {
207     AccessibilityObject* webArea = webAreaObject();
208     if (!webArea)
209         return nullptr;
210     
211     if (m_horizontalScrollbar && m_horizontalScrollbar->elementRect().contains(point))
212         return m_horizontalScrollbar.get();
213     if (m_verticalScrollbar && m_verticalScrollbar->elementRect().contains(point))
214         return m_verticalScrollbar.get();
215     
216     return webArea->accessibilityHitTest(point);
217 }
218
219 LayoutRect AccessibilityScrollView::elementRect() const
220 {
221     if (!m_scrollView)
222         return LayoutRect();
223
224     LayoutRect rect = m_scrollView->frameRect();
225     rect.setY(rect.y() + m_scrollView->topContentInset());
226     return rect;
227 }
228
229 FrameView* AccessibilityScrollView::documentFrameView() const
230 {
231     if (!m_scrollView || !m_scrollView->isFrameView())
232         return nullptr;
233     
234     return toFrameView(m_scrollView);
235 }    
236
237 AccessibilityObject* AccessibilityScrollView::parentObject() const
238 {
239     if (!m_scrollView || !m_scrollView->isFrameView())
240         return nullptr;
241
242     AXObjectCache* cache = axObjectCache();
243     if (!cache)
244         return nullptr;
245
246     HTMLFrameOwnerElement* owner = toFrameView(m_scrollView)->frame().ownerElement();
247     if (owner && owner->renderer())
248         return cache->getOrCreate(owner);
249
250     return nullptr;
251 }
252     
253 AccessibilityObject* AccessibilityScrollView::parentObjectIfExists() const
254 {
255     if (!m_scrollView || !m_scrollView->isFrameView())
256         return nullptr;
257     
258     AXObjectCache* cache = axObjectCache();
259     if (!cache)
260         return nullptr;
261
262     HTMLFrameOwnerElement* owner = toFrameView(m_scrollView)->frame().ownerElement();
263     if (owner && owner->renderer())
264         return cache->get(owner);
265     
266     return nullptr;
267 }
268
269 ScrollableArea* AccessibilityScrollView::getScrollableAreaIfScrollable() const
270 {
271     return m_scrollView;
272 }
273
274 void AccessibilityScrollView::scrollTo(const IntPoint& point) const
275 {
276     if (m_scrollView)
277         m_scrollView->setScrollPosition(point);
278 }
279
280 } // namespace WebCore