OLD | NEW |
| (Empty) |
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/AXObjectCacheImpl.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 | |
37 AXScrollView::AXScrollView(FrameView* view) | |
38 : m_scrollView(view) | |
39 , m_childrenDirty(false) | |
40 { | |
41 } | |
42 | |
43 AXScrollView::~AXScrollView() | |
44 { | |
45 ASSERT(isDetached()); | |
46 } | |
47 | |
48 void AXScrollView::detach() | |
49 { | |
50 AXObject::detach(); | |
51 m_scrollView = 0; | |
52 } | |
53 | |
54 PassRefPtr<AXScrollView> AXScrollView::create(FrameView* view) | |
55 { | |
56 return adoptRef(new AXScrollView(view)); | |
57 } | |
58 | |
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 FrameView obj
ect in WK1). | |
75 // In WebKit2, the FrameView object will return the AX information (because ther
e are no platform widgets). | |
76 bool AXScrollView::isAttachment() const | |
77 { | |
78 return false; | |
79 } | |
80 | |
81 Widget* AXScrollView::widgetForAttachmentView() const | |
82 { | |
83 return m_scrollView; | |
84 } | |
85 | |
86 void AXScrollView::updateChildrenIfNecessary() | |
87 { | |
88 if (m_childrenDirty) | |
89 clearChildren(); | |
90 | |
91 if (!m_haveChildren) | |
92 addChildren(); | |
93 | |
94 updateScrollbars(); | |
95 } | |
96 | |
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->horizontalScroll
bar()); | |
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 | |
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 | |
126 AXScrollbar* AXScrollView::addChildScrollbar(Scrollbar* scrollbar) | |
127 { | |
128 if (!scrollbar) | |
129 return 0; | |
130 | |
131 AXScrollbar* scrollBarObject = toAXScrollbar(axObjectCache()->getOrCreate(sc
rollbar)); | |
132 scrollBarObject->setParent(this); | |
133 m_children.append(scrollBarObject); | |
134 return scrollBarObject; | |
135 } | |
136 | |
137 void AXScrollView::clearChildren() | |
138 { | |
139 AXObject::clearChildren(); | |
140 m_verticalScrollbar = nullptr; | |
141 m_horizontalScrollbar = nullptr; | |
142 } | |
143 | |
144 bool AXScrollView::computeAccessibilityIsIgnored() const | |
145 { | |
146 // We just want to match whatever's returned by our web area, which is a chi
ld of this | |
147 // object. Normally cached attribute values may only search up the tree. We
can't just | |
148 // call accessibilityIsIgnored on the web area, because the web area may sea
rch up its | |
149 // ancestors and call this function recursively, and we'd loop until a stack
overflow. | |
150 | |
151 // Instead, we first update the cached accessibilityIsIgnored value for this
node to | |
152 // false, call accessibilityIsIgnored on the web area, then return the mathc
ing value. | |
153 m_cachedIsIgnored = false; | |
154 m_lastModificationCount = axObjectCache()->modificationCount(); | |
155 | |
156 AXObject* webArea = webAreaObject(); | |
157 if (webArea) | |
158 return webArea->accessibilityIsIgnored(); | |
159 | |
160 return true; | |
161 } | |
162 | |
163 void AXScrollView::addChildren() | |
164 { | |
165 ASSERT(!m_haveChildren); | |
166 m_haveChildren = true; | |
167 | |
168 AXObject* webArea = webAreaObject(); | |
169 if (webArea && !webArea->accessibilityIsIgnored()) | |
170 m_children.append(webArea); | |
171 | |
172 updateScrollbars(); | |
173 } | |
174 | |
175 AXObject* AXScrollView::webAreaObject() const | |
176 { | |
177 if (!m_scrollView || !m_scrollView->isFrameView()) | |
178 return 0; | |
179 | |
180 Document* doc = m_scrollView->frame().document(); | |
181 if (!doc || !doc->renderView()) | |
182 return 0; | |
183 | |
184 return axObjectCache()->getOrCreate(doc); | |
185 } | |
186 | |
187 AXObject* AXScrollView::accessibilityHitTest(const IntPoint& point) const | |
188 { | |
189 AXObject* webArea = webAreaObject(); | |
190 if (!webArea) | |
191 return 0; | |
192 | |
193 if (m_horizontalScrollbar && m_horizontalScrollbar->elementRect().contains(p
oint)) | |
194 return m_horizontalScrollbar.get(); | |
195 if (m_verticalScrollbar && m_verticalScrollbar->elementRect().contains(point
)) | |
196 return m_verticalScrollbar.get(); | |
197 | |
198 return webArea->accessibilityHitTest(point); | |
199 } | |
200 | |
201 LayoutRect AXScrollView::elementRect() const | |
202 { | |
203 if (!m_scrollView) | |
204 return LayoutRect(); | |
205 | |
206 return m_scrollView->frameRect(); | |
207 } | |
208 | |
209 FrameView* AXScrollView::documentFrameView() const | |
210 { | |
211 if (!m_scrollView || !m_scrollView->isFrameView()) | |
212 return 0; | |
213 | |
214 return m_scrollView; | |
215 } | |
216 | |
217 AXObject* AXScrollView::computeParent() const | |
218 { | |
219 if (!m_scrollView || !m_scrollView->isFrameView()) | |
220 return 0; | |
221 | |
222 // FIXME: Broken for OOPI. | |
223 HTMLFrameOwnerElement* owner = m_scrollView->frame().deprecatedLocalOwner(); | |
224 if (owner && owner->renderer()) | |
225 return axObjectCache()->getOrCreate(owner); | |
226 | |
227 return axObjectCache()->getOrCreate(m_scrollView->frame().pagePopupOwner()); | |
228 } | |
229 | |
230 AXObject* AXScrollView::computeParentIfExists() const | |
231 { | |
232 if (!m_scrollView || !m_scrollView->isFrameView()) | |
233 return 0; | |
234 | |
235 HTMLFrameOwnerElement* owner = m_scrollView->frame().deprecatedLocalOwner(); | |
236 if (owner && owner->renderer()) | |
237 return axObjectCache()->get(owner); | |
238 | |
239 return axObjectCache()->get(m_scrollView->frame().pagePopupOwner()); | |
240 } | |
241 | |
242 ScrollableArea* AXScrollView::getScrollableAreaIfScrollable() const | |
243 { | |
244 return m_scrollView; | |
245 } | |
246 | |
247 void AXScrollView::scrollTo(const IntPoint& point) const | |
248 { | |
249 if (m_scrollView) | |
250 m_scrollView->setScrollPosition(point); | |
251 } | |
252 | |
253 } // namespace blink | |
OLD | NEW |