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 "FrameView.h"
32 #include "HTMLFrameOwnerElement.h"
33 #include "RenderPart.h"
34 #include "ScrollView.h"
35 #include "Widget.h"
36
37 namespace WebCore {
38
AccessibilityScrollView(ScrollView * view)39 AccessibilityScrollView::AccessibilityScrollView(ScrollView* view)
40 : m_scrollView(view)
41 {
42 }
43
create(ScrollView * view)44 PassRefPtr<AccessibilityScrollView> AccessibilityScrollView::create(ScrollView* view)
45 {
46 return adoptRef(new AccessibilityScrollView(view));
47 }
48
scrollBar(AccessibilityOrientation orientation) const49 AccessibilityObject* AccessibilityScrollView::scrollBar(AccessibilityOrientation orientation) const
50 {
51 switch (orientation) {
52 case AccessibilityOrientationVertical:
53 return m_verticalScrollbar ? m_verticalScrollbar.get() : 0;
54 case AccessibilityOrientationHorizontal:
55 return m_horizontalScrollbar ? m_horizontalScrollbar.get() : 0;
56 }
57
58 return 0;
59 }
60
children()61 const AccessibilityObject::AccessibilityChildrenVector& AccessibilityScrollView::children()
62 {
63 if (!m_haveChildren)
64 addChildren();
65 return m_children;
66 }
67
68 // If this is WebKit1 then the native scroll view needs to return the
69 // AX information (because there are no scroll bar children in the ScrollView object in WK1).
70 // In WebKit2, the ScrollView object will return the AX information (because there are no platform widgets).
isAttachment() const71 bool AccessibilityScrollView::isAttachment() const
72 {
73 return m_scrollView->platformWidget();
74 }
75
widgetForAttachmentView() const76 Widget* AccessibilityScrollView::widgetForAttachmentView() const
77 {
78 return m_scrollView.get();
79 }
80
updateChildrenIfNecessary()81 void AccessibilityScrollView::updateChildrenIfNecessary()
82 {
83 if (m_scrollView->horizontalScrollbar() && !m_horizontalScrollbar)
84 m_horizontalScrollbar = addChildScrollbar(m_scrollView->horizontalScrollbar());
85 else if (!m_scrollView->horizontalScrollbar() && m_horizontalScrollbar) {
86 removeChildScrollbar(m_horizontalScrollbar.get());
87 m_horizontalScrollbar = 0;
88 }
89
90 if (m_scrollView->verticalScrollbar() && !m_verticalScrollbar)
91 m_verticalScrollbar = addChildScrollbar(m_scrollView->verticalScrollbar());
92 else if (!m_scrollView->verticalScrollbar() && m_verticalScrollbar) {
93 removeChildScrollbar(m_verticalScrollbar.get());
94 m_verticalScrollbar = 0;
95 }
96 }
97
removeChildScrollbar(AccessibilityObject * scrollbar)98 void AccessibilityScrollView::removeChildScrollbar(AccessibilityObject* scrollbar)
99 {
100 size_t pos = m_children.find(scrollbar);
101 if (pos != WTF::notFound)
102 m_children.remove(pos);
103 }
104
addChildScrollbar(Scrollbar * scrollbar)105 AccessibilityScrollbar* AccessibilityScrollView::addChildScrollbar(Scrollbar* scrollbar)
106 {
107 if (!scrollbar)
108 return 0;
109
110 AccessibilityScrollbar* scrollBarObject = static_cast<AccessibilityScrollbar*>(axObjectCache()->getOrCreate(scrollbar));
111 scrollBarObject->setParent(this);
112 m_children.append(scrollBarObject);
113 return scrollBarObject;
114 }
115
addChildren()116 void AccessibilityScrollView::addChildren()
117 {
118 ASSERT(!m_haveChildren);
119 m_haveChildren = true;
120
121 AccessibilityObject* webArea = webAreaObject();
122 if (webArea)
123 m_children.append(webArea);
124
125 updateChildrenIfNecessary();
126 }
127
webAreaObject() const128 AccessibilityObject* AccessibilityScrollView::webAreaObject() const
129 {
130 if (!m_scrollView->isFrameView())
131 return 0;
132
133 Document* doc = static_cast<FrameView*>(m_scrollView.get())->frame()->document();
134 if (!doc || !doc->renderer())
135 return 0;
136
137 return axObjectCache()->getOrCreate(doc->renderer());
138 }
139
accessibilityHitTest(const IntPoint & point) const140 AccessibilityObject* AccessibilityScrollView::accessibilityHitTest(const IntPoint& point) const
141 {
142 AccessibilityObject* webArea = webAreaObject();
143 if (!webArea)
144 return 0;
145
146 if (m_horizontalScrollbar && m_horizontalScrollbar->elementRect().contains(point))
147 return m_horizontalScrollbar.get();
148 if (m_verticalScrollbar && m_verticalScrollbar->elementRect().contains(point))
149 return m_verticalScrollbar.get();
150
151 return webArea->accessibilityHitTest(point);
152 }
153
elementRect() const154 IntRect AccessibilityScrollView::elementRect() const
155 {
156 return m_scrollView->frameRect();
157 }
158
documentFrameView() const159 FrameView* AccessibilityScrollView::documentFrameView() const
160 {
161 if (!m_scrollView->isFrameView())
162 return 0;
163
164 return static_cast<FrameView*>(m_scrollView.get());
165 }
166
parentObject() const167 AccessibilityObject* AccessibilityScrollView::parentObject() const
168 {
169 if (!m_scrollView->isFrameView())
170 return 0;
171
172 HTMLFrameOwnerElement* owner = static_cast<FrameView*>(m_scrollView.get())->frame()->ownerElement();
173 if (owner && owner->renderPart())
174 return axObjectCache()->getOrCreate(owner->renderPart()->parent());
175
176 return 0;
177 }
178
179 } // namespace WebCore
180