• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "core/accessibility/AXScrollView.h"
28 
29 #include "core/accessibility/AXObjectCache.h"
30 #include "core/accessibility/AXScrollbar.h"
31 #include "core/frame/FrameView.h"
32 #include "core/frame/LocalFrame.h"
33 #include "core/html/HTMLFrameOwnerElement.h"
34 
35 namespace blink {
36 
AXScrollView(ScrollView * view)37 AXScrollView::AXScrollView(ScrollView* view)
38     : m_scrollView(view)
39     , m_childrenDirty(false)
40 {
41 }
42 
~AXScrollView()43 AXScrollView::~AXScrollView()
44 {
45     ASSERT(isDetached());
46 }
47 
detach()48 void AXScrollView::detach()
49 {
50     AXObject::detach();
51     m_scrollView = 0;
52 }
53 
create(ScrollView * view)54 PassRefPtr<AXScrollView> AXScrollView::create(ScrollView* view)
55 {
56     return adoptRef(new AXScrollView(view));
57 }
58 
scrollBar(AccessibilityOrientation orientation)59 AXObject* AXScrollView::scrollBar(AccessibilityOrientation orientation)
60 {
61     updateScrollbars();
62 
63     switch (orientation) {
64     case AccessibilityOrientationVertical:
65         return m_verticalScrollbar ? m_verticalScrollbar.get() : 0;
66     case AccessibilityOrientationHorizontal:
67         return m_horizontalScrollbar ? m_horizontalScrollbar.get() : 0;
68     }
69 
70     return 0;
71 }
72 
73 // If this is WebKit1 then the native scroll view needs to return the
74 // AX information (because there are no scroll bar children in the ScrollView object in WK1).
75 // In WebKit2, the ScrollView object will return the AX information (because there are no platform widgets).
isAttachment() const76 bool AXScrollView::isAttachment() const
77 {
78     return false;
79 }
80 
widgetForAttachmentView() const81 Widget* AXScrollView::widgetForAttachmentView() const
82 {
83     return m_scrollView;
84 }
85 
updateChildrenIfNecessary()86 void AXScrollView::updateChildrenIfNecessary()
87 {
88     if (m_childrenDirty)
89         clearChildren();
90 
91     if (!m_haveChildren)
92         addChildren();
93 
94     updateScrollbars();
95 }
96 
updateScrollbars()97 void AXScrollView::updateScrollbars()
98 {
99     if (!m_scrollView)
100         return;
101 
102     if (m_scrollView->horizontalScrollbar() && !m_horizontalScrollbar) {
103         m_horizontalScrollbar = addChildScrollbar(m_scrollView->horizontalScrollbar());
104     } else if (!m_scrollView->horizontalScrollbar() && m_horizontalScrollbar) {
105         removeChildScrollbar(m_horizontalScrollbar.get());
106         m_horizontalScrollbar = nullptr;
107     }
108 
109     if (m_scrollView->verticalScrollbar() && !m_verticalScrollbar) {
110         m_verticalScrollbar = addChildScrollbar(m_scrollView->verticalScrollbar());
111     } else if (!m_scrollView->verticalScrollbar() && m_verticalScrollbar) {
112         removeChildScrollbar(m_verticalScrollbar.get());
113         m_verticalScrollbar = nullptr;
114     }
115 }
116 
removeChildScrollbar(AXObject * scrollbar)117 void AXScrollView::removeChildScrollbar(AXObject* scrollbar)
118 {
119     size_t pos = m_children.find(scrollbar);
120     if (pos != kNotFound) {
121         m_children[pos]->detachFromParent();
122         m_children.remove(pos);
123     }
124 }
125 
addChildScrollbar(Scrollbar * scrollbar)126 AXScrollbar* AXScrollView::addChildScrollbar(Scrollbar* scrollbar)
127 {
128     if (!scrollbar)
129         return 0;
130 
131     AXScrollbar* scrollBarObject = toAXScrollbar(axObjectCache()->getOrCreate(scrollbar));
132     scrollBarObject->setParent(this);
133     m_children.append(scrollBarObject);
134     return scrollBarObject;
135 }
136 
clearChildren()137 void AXScrollView::clearChildren()
138 {
139     AXObject::clearChildren();
140     m_verticalScrollbar = nullptr;
141     m_horizontalScrollbar = nullptr;
142 }
143 
computeAccessibilityIsIgnored() const144 bool AXScrollView::computeAccessibilityIsIgnored() const
145 {
146     AXObject* webArea = webAreaObject();
147     if (!webArea)
148         return true;
149 
150     return webArea->accessibilityIsIgnored();
151 }
152 
addChildren()153 void AXScrollView::addChildren()
154 {
155     ASSERT(!m_haveChildren);
156     m_haveChildren = true;
157 
158     AXObject* webArea = webAreaObject();
159     if (webArea && !webArea->accessibilityIsIgnored())
160         m_children.append(webArea);
161 
162     updateScrollbars();
163 }
164 
webAreaObject() const165 AXObject* AXScrollView::webAreaObject() const
166 {
167     if (!m_scrollView || !m_scrollView->isFrameView())
168         return 0;
169 
170     Document* doc = toFrameView(m_scrollView)->frame().document();
171     if (!doc || !doc->renderView())
172         return 0;
173 
174     return axObjectCache()->getOrCreate(doc);
175 }
176 
accessibilityHitTest(const IntPoint & point) const177 AXObject* AXScrollView::accessibilityHitTest(const IntPoint& point) const
178 {
179     AXObject* webArea = webAreaObject();
180     if (!webArea)
181         return 0;
182 
183     if (m_horizontalScrollbar && m_horizontalScrollbar->elementRect().contains(point))
184         return m_horizontalScrollbar.get();
185     if (m_verticalScrollbar && m_verticalScrollbar->elementRect().contains(point))
186         return m_verticalScrollbar.get();
187 
188     return webArea->accessibilityHitTest(point);
189 }
190 
elementRect() const191 LayoutRect AXScrollView::elementRect() const
192 {
193     if (!m_scrollView)
194         return LayoutRect();
195 
196     return m_scrollView->frameRect();
197 }
198 
documentFrameView() const199 FrameView* AXScrollView::documentFrameView() const
200 {
201     if (!m_scrollView || !m_scrollView->isFrameView())
202         return 0;
203 
204     return toFrameView(m_scrollView);
205 }
206 
parentObject() const207 AXObject* AXScrollView::parentObject() const
208 {
209     if (!m_scrollView || !m_scrollView->isFrameView())
210         return 0;
211 
212     // FIXME: Broken for OOPI.
213     HTMLFrameOwnerElement* owner = toFrameView(m_scrollView)->frame().deprecatedLocalOwner();
214     if (owner && owner->renderer())
215         return axObjectCache()->getOrCreate(owner);
216 
217     return axObjectCache()->getOrCreate(toFrameView(m_scrollView)->frame().pagePopupOwner());
218 }
219 
parentObjectIfExists() const220 AXObject* AXScrollView::parentObjectIfExists() const
221 {
222     if (!m_scrollView || !m_scrollView->isFrameView())
223         return 0;
224 
225     HTMLFrameOwnerElement* owner = toFrameView(m_scrollView)->frame().deprecatedLocalOwner();
226     if (owner && owner->renderer())
227         return axObjectCache()->get(owner);
228 
229     return axObjectCache()->get(toFrameView(m_scrollView)->frame().pagePopupOwner());
230 }
231 
getScrollableAreaIfScrollable() const232 ScrollableArea* AXScrollView::getScrollableAreaIfScrollable() const
233 {
234     return m_scrollView;
235 }
236 
scrollTo(const IntPoint & point) const237 void AXScrollView::scrollTo(const IntPoint& point) const
238 {
239     if (m_scrollView)
240         m_scrollView->setScrollPosition(point);
241 }
242 
243 } // namespace blink
244