6d13aad06178f11d6823ab23e7bce0175b8a6038
[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 "RenderPart.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 PassRefPtr<AccessibilityScrollView> AccessibilityScrollView::create(ScrollView* view)
47 {
48     return adoptRef(new AccessibilityScrollView(view));
49 }
50     
51 AccessibilityObject* AccessibilityScrollView::scrollBar(AccessibilityOrientation orientation)
52 {
53     updateScrollbars();
54     
55     switch (orientation) {
56     case AccessibilityOrientationVertical:
57         return m_verticalScrollbar ? m_verticalScrollbar.get() : 0;
58     case AccessibilityOrientationHorizontal:
59         return m_horizontalScrollbar ? m_horizontalScrollbar.get() : 0;
60     }
61     
62     return 0;
63 }
64
65 // If this is WebKit1 then the native scroll view needs to return the
66 // AX information (because there are no scroll bar children in the ScrollView object in WK1).
67 // In WebKit2, the ScrollView object will return the AX information (because there are no platform widgets).
68 bool AccessibilityScrollView::isAttachment() const
69 {
70     return m_scrollView->platformWidget();
71 }
72
73 Widget* AccessibilityScrollView::widgetForAttachmentView() const
74 {
75     return m_scrollView.get();
76 }
77     
78 void AccessibilityScrollView::updateChildrenIfNecessary()
79 {
80     if (m_childrenDirty)
81         clearChildren();
82
83     if (!m_haveChildren)
84         addChildren();
85     
86     updateScrollbars();
87 }
88
89 void AccessibilityScrollView::updateScrollbars()
90 {
91     if (m_scrollView->horizontalScrollbar() && !m_horizontalScrollbar)
92         m_horizontalScrollbar = addChildScrollbar(m_scrollView->horizontalScrollbar());
93     else if (!m_scrollView->horizontalScrollbar() && m_horizontalScrollbar) {
94         removeChildScrollbar(m_horizontalScrollbar.get());
95         m_horizontalScrollbar = 0;
96     }
97
98     if (m_scrollView->verticalScrollbar() && !m_verticalScrollbar)
99         m_verticalScrollbar = addChildScrollbar(m_scrollView->verticalScrollbar());
100     else if (!m_scrollView->verticalScrollbar() && m_verticalScrollbar) {
101         removeChildScrollbar(m_verticalScrollbar.get());
102         m_verticalScrollbar = 0;
103     }
104 }
105     
106 void AccessibilityScrollView::removeChildScrollbar(AccessibilityObject* scrollbar)
107 {
108     size_t pos = m_children.find(scrollbar);
109     if (pos != WTF::notFound) {
110         m_children[pos]->detachFromParent();
111         m_children.remove(pos);
112     }
113 }
114     
115 AccessibilityScrollbar* AccessibilityScrollView::addChildScrollbar(Scrollbar* scrollbar)
116 {
117     if (!scrollbar)
118         return 0;
119     
120     AccessibilityScrollbar* scrollBarObject = static_cast<AccessibilityScrollbar*>(axObjectCache()->getOrCreate(scrollbar));
121     scrollBarObject->setParent(this);
122     m_children.append(scrollBarObject);
123     return scrollBarObject;
124 }
125         
126 void AccessibilityScrollView::clearChildren()
127 {
128     AccessibilityObject::clearChildren();
129     m_verticalScrollbar = 0;
130     m_horizontalScrollbar = 0;
131 }
132
133 bool AccessibilityScrollView::accessibilityIsIgnored() const
134 {
135     AccessibilityObject* webArea = webAreaObject();
136     if (!webArea)
137         return true;
138     
139     return webArea->accessibilityIsIgnored();
140 }
141
142 void AccessibilityScrollView::addChildren()
143 {
144     ASSERT(!m_haveChildren);
145     m_haveChildren = true;
146     
147     AccessibilityObject* webArea = webAreaObject();
148     if (webArea && !webArea->accessibilityIsIgnored())
149         m_children.append(webArea);
150     
151     updateScrollbars();
152 }
153
154 AccessibilityObject* AccessibilityScrollView::webAreaObject() const
155 {
156     if (!m_scrollView->isFrameView())
157         return 0;
158     
159     Document* doc = static_cast<FrameView*>(m_scrollView.get())->frame()->document();
160     if (!doc || !doc->renderer())
161         return 0;
162
163     return axObjectCache()->getOrCreate(doc);
164 }
165
166 AccessibilityObject* AccessibilityScrollView::accessibilityHitTest(const IntPoint& point) const
167 {
168     AccessibilityObject* webArea = webAreaObject();
169     if (!webArea)
170         return 0;
171     
172     if (m_horizontalScrollbar && m_horizontalScrollbar->elementRect().contains(point))
173         return m_horizontalScrollbar.get();
174     if (m_verticalScrollbar && m_verticalScrollbar->elementRect().contains(point))
175         return m_verticalScrollbar.get();
176     
177     return webArea->accessibilityHitTest(point);
178 }
179
180 LayoutRect AccessibilityScrollView::elementRect() const
181 {
182     return m_scrollView->frameRect();
183 }
184
185 FrameView* AccessibilityScrollView::documentFrameView() const
186 {
187     if (!m_scrollView->isFrameView())
188         return 0;
189     
190     return static_cast<FrameView*>(m_scrollView.get());
191 }    
192
193 AccessibilityObject* AccessibilityScrollView::parentObject() const
194 {
195     if (!m_scrollView->isFrameView())
196         return 0;
197     
198     HTMLFrameOwnerElement* owner = static_cast<FrameView*>(m_scrollView.get())->frame()->ownerElement();
199     if (owner && owner->renderer())
200         return axObjectCache()->getOrCreate(owner);
201
202     return 0;
203 }
204     
205 AccessibilityObject* AccessibilityScrollView::parentObjectIfExists() const
206 {
207     if (!m_scrollView->isFrameView())
208         return 0;
209     
210     HTMLFrameOwnerElement* owner = static_cast<FrameView*>(m_scrollView.get())->frame()->ownerElement();
211     if (owner && owner->renderer())
212         return axObjectCache()->get(owner);
213     
214     return 0;
215 }
216
217 ScrollableArea* AccessibilityScrollView::getScrollableAreaIfScrollable() const
218 {
219     return m_scrollView.get();
220 }
221
222 void AccessibilityScrollView::scrollTo(const IntPoint& point) const
223 {
224     m_scrollView->setScrollPosition(point);
225 }
226
227 } // namespace WebCore