AX: CrashTracer: [USER] 296 crashes in WebProcess at com.apple.WebCore: WebCore:...
[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[pos]->detachFromParent();
104         m_children.remove(pos);
105     }
106 }
107     
108 AccessibilityScrollbar* AccessibilityScrollView::addChildScrollbar(Scrollbar* scrollbar)
109 {
110     if (!scrollbar)
111         return 0;
112     
113     AccessibilityScrollbar* scrollBarObject = static_cast<AccessibilityScrollbar*>(axObjectCache()->getOrCreate(scrollbar));
114     scrollBarObject->setParent(this);
115     m_children.append(scrollBarObject);
116     return scrollBarObject;
117 }
118         
119 void AccessibilityScrollView::addChildren()
120 {
121     ASSERT(!m_haveChildren);
122     m_haveChildren = true;
123     
124     AccessibilityObject* webArea = webAreaObject();
125     if (webArea)
126         m_children.append(webArea);
127     
128     updateChildrenIfNecessary();
129 }
130
131 AccessibilityObject* AccessibilityScrollView::webAreaObject() const
132 {
133     if (!m_scrollView->isFrameView())
134         return 0;
135     
136     Document* doc = static_cast<FrameView*>(m_scrollView.get())->frame()->document();
137     if (!doc || !doc->renderer())
138         return 0;
139
140     return axObjectCache()->getOrCreate(doc->renderer());
141 }
142
143 AccessibilityObject* AccessibilityScrollView::accessibilityHitTest(const LayoutPoint& point) const
144 {
145     AccessibilityObject* webArea = webAreaObject();
146     if (!webArea)
147         return 0;
148     
149     if (m_horizontalScrollbar && m_horizontalScrollbar->elementRect().contains(point))
150         return m_horizontalScrollbar.get();
151     if (m_verticalScrollbar && m_verticalScrollbar->elementRect().contains(point))
152         return m_verticalScrollbar.get();
153     
154     return webArea->accessibilityHitTest(point);
155 }
156
157 LayoutRect AccessibilityScrollView::elementRect() const
158 {
159     return m_scrollView->frameRect();
160 }
161
162 FrameView* AccessibilityScrollView::documentFrameView() const
163 {
164     if (!m_scrollView->isFrameView())
165         return 0;
166     
167     return static_cast<FrameView*>(m_scrollView.get());
168 }    
169
170 AccessibilityObject* AccessibilityScrollView::parentObject() const
171 {
172     if (!m_scrollView->isFrameView())
173         return 0;
174     
175     HTMLFrameOwnerElement* owner = static_cast<FrameView*>(m_scrollView.get())->frame()->ownerElement();
176     if (owner && owner->renderPart())
177         return axObjectCache()->getOrCreate(owner->renderPart()->parent());
178     
179     return 0;
180 }
181     
182 } // namespace WebCore