Viewport constrained elements should work properly with headers and footers
[WebKit-https.git] / Source / WebCore / page / scrolling / ScrollingStateScrollingNode.cpp
1 /*
2  * Copyright (C) 2012 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  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23  * THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #include "config.h"
27 #include "ScrollingStateScrollingNode.h"
28
29 #include "ScrollingStateTree.h"
30 #include "TextStream.h"
31 #include <wtf/OwnPtr.h>
32
33 #if ENABLE(THREADED_SCROLLING)
34
35 namespace WebCore {
36
37 PassOwnPtr<ScrollingStateScrollingNode> ScrollingStateScrollingNode::create(ScrollingStateTree* stateTree, ScrollingNodeID nodeID)
38 {
39     return adoptPtr(new ScrollingStateScrollingNode(stateTree, nodeID));
40 }
41
42 ScrollingStateScrollingNode::ScrollingStateScrollingNode(ScrollingStateTree* stateTree, ScrollingNodeID nodeID)
43     : ScrollingStateNode(stateTree, nodeID)
44     , m_counterScrollingLayer(0)
45     , m_frameScaleFactor(1)
46     , m_wheelEventHandlerCount(0)
47     , m_shouldUpdateScrollLayerPositionOnMainThread(0)
48     , m_horizontalScrollElasticity(ScrollElasticityNone)
49     , m_verticalScrollElasticity(ScrollElasticityNone)
50     , m_hasEnabledHorizontalScrollbar(false)
51     , m_hasEnabledVerticalScrollbar(false)
52     , m_requestedScrollPositionRepresentsProgrammaticScroll(false)
53     , m_horizontalScrollbarMode(ScrollbarAuto)
54     , m_verticalScrollbarMode(ScrollbarAuto)
55     , m_headerHeight(0)
56     , m_footerHeight(0)
57 {
58 }
59
60 ScrollingStateScrollingNode::ScrollingStateScrollingNode(const ScrollingStateScrollingNode& stateNode)
61     : ScrollingStateNode(stateNode)
62     , m_viewportRect(stateNode.viewportRect())
63     , m_totalContentsSize(stateNode.totalContentsSize())
64     , m_frameScaleFactor(stateNode.frameScaleFactor())
65     , m_nonFastScrollableRegion(stateNode.nonFastScrollableRegion())
66     , m_wheelEventHandlerCount(stateNode.wheelEventHandlerCount())
67     , m_shouldUpdateScrollLayerPositionOnMainThread(stateNode.shouldUpdateScrollLayerPositionOnMainThread())
68     , m_horizontalScrollElasticity(stateNode.horizontalScrollElasticity())
69     , m_verticalScrollElasticity(stateNode.verticalScrollElasticity())
70     , m_hasEnabledHorizontalScrollbar(stateNode.hasEnabledHorizontalScrollbar())
71     , m_hasEnabledVerticalScrollbar(stateNode.hasEnabledVerticalScrollbar())
72     , m_requestedScrollPositionRepresentsProgrammaticScroll(stateNode.requestedScrollPositionRepresentsProgrammaticScroll())
73     , m_horizontalScrollbarMode(stateNode.horizontalScrollbarMode())
74     , m_verticalScrollbarMode(stateNode.verticalScrollbarMode())
75     , m_requestedScrollPosition(stateNode.requestedScrollPosition())
76     , m_scrollOrigin(stateNode.scrollOrigin())
77     , m_headerHeight(stateNode.headerHeight())
78     , m_footerHeight(stateNode.footerHeight())
79 {
80     setCounterScrollingLayer(stateNode.counterScrollingLayer());
81 }
82
83 ScrollingStateScrollingNode::~ScrollingStateScrollingNode()
84 {
85 }
86
87 PassOwnPtr<ScrollingStateNode> ScrollingStateScrollingNode::clone()
88 {
89     return adoptPtr(new ScrollingStateScrollingNode(*this));
90 }
91
92 void ScrollingStateScrollingNode::setViewportRect(const IntRect& viewportRect)
93 {
94     if (m_viewportRect == viewportRect)
95         return;
96
97     m_viewportRect = viewportRect;
98     setPropertyChanged(ViewportRect);
99     m_scrollingStateTree->setHasChangedProperties(true);
100 }
101
102 void ScrollingStateScrollingNode::setTotalContentsSize(const IntSize& totalContentsSize)
103 {
104     if (m_totalContentsSize == totalContentsSize)
105         return;
106
107     m_totalContentsSize = totalContentsSize;
108     setPropertyChanged(TotalContentsSize);
109     m_scrollingStateTree->setHasChangedProperties(true);
110 }
111
112 void ScrollingStateScrollingNode::setFrameScaleFactor(float scaleFactor)
113 {
114     if (m_frameScaleFactor == scaleFactor)
115         return;
116
117     m_frameScaleFactor = scaleFactor;
118
119     setPropertyChanged(FrameScaleFactor);
120     m_scrollingStateTree->setHasChangedProperties(true);
121 }
122
123 void ScrollingStateScrollingNode::setNonFastScrollableRegion(const Region& nonFastScrollableRegion)
124 {
125     if (m_nonFastScrollableRegion == nonFastScrollableRegion)
126         return;
127
128     m_nonFastScrollableRegion = nonFastScrollableRegion;
129     setPropertyChanged(NonFastScrollableRegion);
130     m_scrollingStateTree->setHasChangedProperties(true);
131 }
132
133 void ScrollingStateScrollingNode::setWheelEventHandlerCount(unsigned wheelEventHandlerCount)
134 {
135     if (m_wheelEventHandlerCount == wheelEventHandlerCount)
136         return;
137
138     m_wheelEventHandlerCount = wheelEventHandlerCount;
139     setPropertyChanged(WheelEventHandlerCount);
140     m_scrollingStateTree->setHasChangedProperties(true);
141 }
142
143 void ScrollingStateScrollingNode::setShouldUpdateScrollLayerPositionOnMainThread(MainThreadScrollingReasons reasons)
144 {
145     if (m_shouldUpdateScrollLayerPositionOnMainThread == reasons)
146         return;
147
148     m_shouldUpdateScrollLayerPositionOnMainThread = reasons;
149     setPropertyChanged(ShouldUpdateScrollLayerPositionOnMainThread);
150     m_scrollingStateTree->setHasChangedProperties(true);
151 }
152
153 void ScrollingStateScrollingNode::setHorizontalScrollElasticity(ScrollElasticity horizontalScrollElasticity)
154 {
155     if (m_horizontalScrollElasticity == horizontalScrollElasticity)
156         return;
157
158     m_horizontalScrollElasticity = horizontalScrollElasticity;
159     setPropertyChanged(HorizontalScrollElasticity);
160     m_scrollingStateTree->setHasChangedProperties(true);
161 }
162
163 void ScrollingStateScrollingNode::setVerticalScrollElasticity(ScrollElasticity verticalScrollElasticity)
164 {
165     if (m_verticalScrollElasticity == verticalScrollElasticity)
166         return;
167
168     m_verticalScrollElasticity = verticalScrollElasticity;
169     setPropertyChanged(VerticalScrollElasticity);
170     m_scrollingStateTree->setHasChangedProperties(true);
171 }
172
173 void ScrollingStateScrollingNode::setHasEnabledHorizontalScrollbar(bool hasEnabledHorizontalScrollbar)
174 {
175     if (m_hasEnabledHorizontalScrollbar == hasEnabledHorizontalScrollbar)
176         return;
177
178     m_hasEnabledHorizontalScrollbar = hasEnabledHorizontalScrollbar;
179     setPropertyChanged(HasEnabledHorizontalScrollbar);
180     m_scrollingStateTree->setHasChangedProperties(true);
181 }
182
183 void ScrollingStateScrollingNode::setHasEnabledVerticalScrollbar(bool hasEnabledVerticalScrollbar)
184 {
185     if (m_hasEnabledVerticalScrollbar == hasEnabledVerticalScrollbar)
186         return;
187
188     m_hasEnabledVerticalScrollbar = hasEnabledVerticalScrollbar;
189     setPropertyChanged(HasEnabledVerticalScrollbar);
190     m_scrollingStateTree->setHasChangedProperties(true);
191 }
192
193 void ScrollingStateScrollingNode::setHorizontalScrollbarMode(ScrollbarMode horizontalScrollbarMode)
194 {
195     if (m_horizontalScrollbarMode == horizontalScrollbarMode)
196         return;
197
198     m_horizontalScrollbarMode = horizontalScrollbarMode;
199     setPropertyChanged(HorizontalScrollbarMode);
200     m_scrollingStateTree->setHasChangedProperties(true);
201 }
202
203 void ScrollingStateScrollingNode::setVerticalScrollbarMode(ScrollbarMode verticalScrollbarMode)
204 {
205     if (m_verticalScrollbarMode == verticalScrollbarMode)
206         return;
207
208     m_verticalScrollbarMode = verticalScrollbarMode;
209     setPropertyChanged(VerticalScrollbarMode);
210     m_scrollingStateTree->setHasChangedProperties(true);
211 }
212
213 void ScrollingStateScrollingNode::setRequestedScrollPosition(const IntPoint& requestedScrollPosition, bool representsProgrammaticScroll)
214 {
215     m_requestedScrollPosition = requestedScrollPosition;
216     m_requestedScrollPositionRepresentsProgrammaticScroll = representsProgrammaticScroll;
217     setPropertyChanged(RequestedScrollPosition);
218     m_scrollingStateTree->setHasChangedProperties(true);
219 }
220
221 void ScrollingStateScrollingNode::setScrollOrigin(const IntPoint& scrollOrigin)
222 {
223     if (m_scrollOrigin == scrollOrigin)
224         return;
225
226     m_scrollOrigin = scrollOrigin;
227     setPropertyChanged(ScrollOrigin);
228     m_scrollingStateTree->setHasChangedProperties(true);
229 }
230
231 void ScrollingStateScrollingNode::setHeaderHeight(int headerHeight)
232 {
233     if (m_headerHeight == headerHeight)
234         return;
235
236     m_headerHeight = headerHeight;
237     setPropertyChanged(HeaderHeight);
238     m_scrollingStateTree->setHasChangedProperties(true);
239 }
240
241 void ScrollingStateScrollingNode::setFooterHeight(int footerHeight)
242 {
243     if (m_footerHeight == footerHeight)
244         return;
245
246     m_footerHeight = footerHeight;
247     setPropertyChanged(FooterHeight);
248     m_scrollingStateTree->setHasChangedProperties(true);
249 }
250
251 void ScrollingStateScrollingNode::dumpProperties(TextStream& ts, int indent) const
252 {
253     ts << "(" << "Scrolling node" << "\n";
254
255     if (!m_viewportRect.isEmpty()) {
256         writeIndent(ts, indent + 1);
257         ts << "(viewport rect " << m_viewportRect.x() << " " << m_viewportRect.y() << " " << m_viewportRect.width() << " " << m_viewportRect.height() << ")\n";
258     }
259
260     if (!m_totalContentsSize.isEmpty()) {
261         writeIndent(ts, indent + 1);
262         ts << "(contents size " << m_totalContentsSize.width() << " " << m_totalContentsSize.height() << ")\n";
263     }
264
265     if (m_frameScaleFactor != 1) {
266         writeIndent(ts, indent + 1);
267         ts << "(frame scale factor " << m_frameScaleFactor << ")\n";
268     }
269
270     if (m_shouldUpdateScrollLayerPositionOnMainThread) {
271         writeIndent(ts, indent + 1);
272         ts << "(Scrolling on main thread because: " << ScrollingCoordinator::mainThreadScrollingReasonsAsText(m_shouldUpdateScrollLayerPositionOnMainThread) << ")\n";
273     }
274
275     if (m_requestedScrollPosition != IntPoint()) {
276         writeIndent(ts, indent + 1);
277         ts << "(requested scroll position " << m_requestedScrollPosition.x() << " " << m_requestedScrollPosition.y() << ")\n";
278     }
279
280     if (m_scrollOrigin != IntPoint()) {
281         writeIndent(ts, indent + 1);
282         ts << "(scroll origin " << m_scrollOrigin.x() << " " << m_scrollOrigin.y() << ")\n";
283     }
284 }
285
286 } // namespace WebCore
287
288 #endif // ENABLE(THREADED_SCROLLING)