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