717bfc2a55cc18cb38cdb44edb0ef543587f2ae0
[WebKit-https.git] / Source / WebCore / page / scrolling / ScrollingStateScrollingNode.cpp
1 /*
2  * Copyright (C) 2012, 2015 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 #if ENABLE(ASYNC_SCROLLING)
30
31 #include "ScrollingStateTree.h"
32 #include <wtf/text/TextStream.h>
33
34 namespace WebCore {
35
36 ScrollingStateScrollingNode::ScrollingStateScrollingNode(ScrollingStateTree& stateTree, ScrollingNodeType nodeType, ScrollingNodeID nodeID)
37     : ScrollingStateNode(nodeType, stateTree, nodeID)
38 {
39 }
40
41 ScrollingStateScrollingNode::ScrollingStateScrollingNode(const ScrollingStateScrollingNode& stateNode, ScrollingStateTree& adoptiveTree)
42     : ScrollingStateNode(stateNode, adoptiveTree)
43     , m_scrollableAreaSize(stateNode.scrollableAreaSize())
44     , m_totalContentsSize(stateNode.totalContentsSize())
45     , m_reachableContentsSize(stateNode.reachableContentsSize())
46     , m_parentRelativeScrollableRect(stateNode.parentRelativeScrollableRect())
47     , m_scrollPosition(stateNode.scrollPosition())
48     , m_requestedScrollPosition(stateNode.requestedScrollPosition())
49     , m_scrollOrigin(stateNode.scrollOrigin())
50 #if ENABLE(CSS_SCROLL_SNAP)
51     , m_snapOffsetsInfo(stateNode.m_snapOffsetsInfo)
52 #endif
53 #if PLATFORM(MAC)
54     , m_verticalScrollerImp(stateNode.verticalScrollerImp())
55     , m_horizontalScrollerImp(stateNode.horizontalScrollerImp())
56 #endif
57     , m_scrollableAreaParameters(stateNode.scrollableAreaParameters())
58     , m_requestedScrollPositionRepresentsProgrammaticScroll(stateNode.requestedScrollPositionRepresentsProgrammaticScroll())
59     , m_isMonitoringWheelEvents(stateNode.isMonitoringWheelEvents())
60 {
61     if (hasChangedProperty(ScrollContainerLayer))
62         setScrollContainerLayer(stateNode.scrollContainerLayer().toRepresentation(adoptiveTree.preferredLayerRepresentation()));
63
64     if (hasChangedProperty(ScrolledContentsLayer))
65         setScrolledContentsLayer(stateNode.scrolledContentsLayer().toRepresentation(adoptiveTree.preferredLayerRepresentation()));
66
67     if (hasChangedProperty(VerticalScrollbarLayer))
68         setVerticalScrollbarLayer(stateNode.verticalScrollbarLayer().toRepresentation(adoptiveTree.preferredLayerRepresentation()));
69
70     if (hasChangedProperty(HorizontalScrollbarLayer))
71         setHorizontalScrollbarLayer(stateNode.horizontalScrollbarLayer().toRepresentation(adoptiveTree.preferredLayerRepresentation()));
72 }
73
74 ScrollingStateScrollingNode::~ScrollingStateScrollingNode() = default;
75
76 void ScrollingStateScrollingNode::setPropertyChangedBitsAfterReattach()
77 {
78     setPropertyChangedBit(ScrollableAreaSize);
79     setPropertyChangedBit(TotalContentsSize);
80     setPropertyChangedBit(ReachableContentsSize);
81     setPropertyChangedBit(ParentRelativeScrollableRect);
82     setPropertyChangedBit(ScrollPosition);
83     setPropertyChangedBit(ScrollOrigin);
84     setPropertyChangedBit(ScrollableAreaParams);
85 #if ENABLE(CSS_SCROLL_SNAP)
86     setPropertyChangedBit(HorizontalSnapOffsets);
87     setPropertyChangedBit(VerticalSnapOffsets);
88     setPropertyChangedBit(HorizontalSnapOffsetRanges);
89     setPropertyChangedBit(VerticalSnapOffsetRanges);
90     setPropertyChangedBit(CurrentHorizontalSnapOffsetIndex);
91     setPropertyChangedBit(CurrentVerticalSnapOffsetIndex);
92 #endif
93     setPropertyChangedBit(IsMonitoringWheelEvents);
94     setPropertyChangedBit(ScrollContainerLayer);
95     setPropertyChangedBit(ScrolledContentsLayer);
96     setPropertyChangedBit(HorizontalScrollbarLayer);
97     setPropertyChangedBit(VerticalScrollbarLayer);
98     setPropertyChangedBit(PainterForScrollbar);
99
100     ScrollingStateNode::setPropertyChangedBitsAfterReattach();
101 }
102
103 void ScrollingStateScrollingNode::setScrollableAreaSize(const FloatSize& size)
104 {
105     if (m_scrollableAreaSize == size)
106         return;
107
108     m_scrollableAreaSize = size;
109     setPropertyChanged(ScrollableAreaSize);
110 }
111
112 void ScrollingStateScrollingNode::setTotalContentsSize(const FloatSize& totalContentsSize)
113 {
114     if (m_totalContentsSize == totalContentsSize)
115         return;
116
117     m_totalContentsSize = totalContentsSize;
118     setPropertyChanged(TotalContentsSize);
119 }
120
121 void ScrollingStateScrollingNode::setReachableContentsSize(const FloatSize& reachableContentsSize)
122 {
123     if (m_reachableContentsSize == reachableContentsSize)
124         return;
125
126     m_reachableContentsSize = reachableContentsSize;
127     setPropertyChanged(ReachableContentsSize);
128 }
129
130 void ScrollingStateScrollingNode::setParentRelativeScrollableRect(const LayoutRect& parentRelativeScrollableRect)
131 {
132     if (m_parentRelativeScrollableRect == parentRelativeScrollableRect)
133         return;
134
135     m_parentRelativeScrollableRect = parentRelativeScrollableRect;
136     setPropertyChanged(ParentRelativeScrollableRect);
137 }
138
139 void ScrollingStateScrollingNode::setScrollPosition(const FloatPoint& scrollPosition)
140 {
141     if (m_scrollPosition == scrollPosition)
142         return;
143
144     m_scrollPosition = scrollPosition;
145     setPropertyChanged(ScrollPosition);
146 }
147
148 void ScrollingStateScrollingNode::setScrollOrigin(const IntPoint& scrollOrigin)
149 {
150     if (m_scrollOrigin == scrollOrigin)
151         return;
152
153     m_scrollOrigin = scrollOrigin;
154     setPropertyChanged(ScrollOrigin);
155 }
156
157 #if ENABLE(CSS_SCROLL_SNAP)
158 void ScrollingStateScrollingNode::setHorizontalSnapOffsets(const Vector<float>& snapOffsets)
159 {
160     if (m_snapOffsetsInfo.horizontalSnapOffsets == snapOffsets)
161         return;
162
163     m_snapOffsetsInfo.horizontalSnapOffsets = snapOffsets;
164     setPropertyChanged(HorizontalSnapOffsets);
165 }
166
167 void ScrollingStateScrollingNode::setVerticalSnapOffsets(const Vector<float>& snapOffsets)
168 {
169     if (m_snapOffsetsInfo.verticalSnapOffsets == snapOffsets)
170         return;
171
172     m_snapOffsetsInfo.verticalSnapOffsets = snapOffsets;
173     setPropertyChanged(VerticalSnapOffsets);
174 }
175
176 void ScrollingStateScrollingNode::setHorizontalSnapOffsetRanges(const Vector<ScrollOffsetRange<float>>& scrollOffsetRanges)
177 {
178     if (m_snapOffsetsInfo.horizontalSnapOffsetRanges == scrollOffsetRanges)
179         return;
180
181     m_snapOffsetsInfo.horizontalSnapOffsetRanges = scrollOffsetRanges;
182     setPropertyChanged(HorizontalSnapOffsetRanges);
183 }
184
185 void ScrollingStateScrollingNode::setVerticalSnapOffsetRanges(const Vector<ScrollOffsetRange<float>>& scrollOffsetRanges)
186 {
187     if (m_snapOffsetsInfo.verticalSnapOffsetRanges == scrollOffsetRanges)
188         return;
189
190     m_snapOffsetsInfo.verticalSnapOffsetRanges = scrollOffsetRanges;
191     setPropertyChanged(VerticalSnapOffsetRanges);
192 }
193
194 void ScrollingStateScrollingNode::setCurrentHorizontalSnapPointIndex(unsigned index)
195 {
196     if (m_currentHorizontalSnapPointIndex == index)
197         return;
198     
199     m_currentHorizontalSnapPointIndex = index;
200     setPropertyChanged(CurrentHorizontalSnapOffsetIndex);
201 }
202
203 void ScrollingStateScrollingNode::setCurrentVerticalSnapPointIndex(unsigned index)
204 {
205     if (m_currentVerticalSnapPointIndex == index)
206         return;
207     
208     m_currentVerticalSnapPointIndex = index;
209     setPropertyChanged(CurrentVerticalSnapOffsetIndex);
210 }
211 #endif
212
213 void ScrollingStateScrollingNode::setScrollableAreaParameters(const ScrollableAreaParameters& parameters)
214 {
215     if (m_scrollableAreaParameters == parameters)
216         return;
217
218     m_scrollableAreaParameters = parameters;
219     setPropertyChanged(ScrollableAreaParams);
220 }
221
222 void ScrollingStateScrollingNode::setRequestedScrollPosition(const FloatPoint& requestedScrollPosition, bool representsProgrammaticScroll)
223 {
224     m_requestedScrollPosition = requestedScrollPosition;
225     m_requestedScrollPositionRepresentsProgrammaticScroll = representsProgrammaticScroll;
226     setPropertyChanged(RequestedScrollPosition);
227 }
228
229 void ScrollingStateScrollingNode::setIsMonitoringWheelEvents(bool isMonitoringWheelEvents)
230 {
231     if (isMonitoringWheelEvents == m_isMonitoringWheelEvents)
232         return;
233
234     m_isMonitoringWheelEvents = isMonitoringWheelEvents;
235     setPropertyChanged(IsMonitoringWheelEvents);
236 }
237
238 void ScrollingStateScrollingNode::setScrollContainerLayer(const LayerRepresentation& layerRepresentation)
239 {
240     if (layerRepresentation == m_scrollContainerLayer)
241         return;
242
243     m_scrollContainerLayer = layerRepresentation;
244     setPropertyChanged(ScrollContainerLayer);
245 }
246
247 void ScrollingStateScrollingNode::setScrolledContentsLayer(const LayerRepresentation& layerRepresentation)
248 {
249     if (layerRepresentation == m_scrolledContentsLayer)
250         return;
251
252     m_scrolledContentsLayer = layerRepresentation;
253     setPropertyChanged(ScrolledContentsLayer);
254 }
255
256 void ScrollingStateScrollingNode::setHorizontalScrollbarLayer(const LayerRepresentation& layer)
257 {
258     if (layer == m_horizontalScrollbarLayer)
259         return;
260
261     m_horizontalScrollbarLayer = layer;
262     setPropertyChanged(HorizontalScrollbarLayer);
263 }
264
265 void ScrollingStateScrollingNode::setVerticalScrollbarLayer(const LayerRepresentation& layer)
266 {
267     if (layer == m_verticalScrollbarLayer)
268         return;
269
270     m_verticalScrollbarLayer = layer;
271     setPropertyChanged(VerticalScrollbarLayer);
272 }
273
274 #if !PLATFORM(MAC)
275 void ScrollingStateScrollingNode::setScrollerImpsFromScrollbars(Scrollbar*, Scrollbar*)
276 {
277 }
278 #endif
279
280 void ScrollingStateScrollingNode::dumpProperties(TextStream& ts, ScrollingStateTreeAsTextBehavior behavior) const
281 {
282     ScrollingStateNode::dumpProperties(ts, behavior);
283     
284     if (m_scrollPosition != FloatPoint()) {
285         TextStream::GroupScope scope(ts);
286         ts << "scroll position "
287             << TextStream::FormatNumberRespectingIntegers(m_scrollPosition.x()) << " "
288             << TextStream::FormatNumberRespectingIntegers(m_scrollPosition.y());
289     }
290
291     if (!m_scrollableAreaSize.isEmpty()) {
292         TextStream::GroupScope scope(ts);
293         ts << "scrollable area size "
294             << TextStream::FormatNumberRespectingIntegers(m_scrollableAreaSize.width()) << " "
295             << TextStream::FormatNumberRespectingIntegers(m_scrollableAreaSize.height());
296     }
297
298     if (!m_totalContentsSize.isEmpty()) {
299         TextStream::GroupScope scope(ts);
300         ts << "contents size "
301             << TextStream::FormatNumberRespectingIntegers(m_totalContentsSize.width()) << " "
302             << TextStream::FormatNumberRespectingIntegers(m_totalContentsSize.height());
303     }
304
305     if (m_reachableContentsSize != m_totalContentsSize)
306         ts.dumpProperty("reachable contents size", m_reachableContentsSize);
307
308     if (m_requestedScrollPosition != IntPoint()) {
309         TextStream::GroupScope scope(ts);
310         ts << "requested scroll position "
311             << TextStream::FormatNumberRespectingIntegers(m_requestedScrollPosition.x()) << " "
312             << TextStream::FormatNumberRespectingIntegers(m_requestedScrollPosition.y());
313     }
314     if (m_requestedScrollPositionRepresentsProgrammaticScroll)
315         ts.dumpProperty("requested scroll position represents programmatic scroll", m_requestedScrollPositionRepresentsProgrammaticScroll);
316
317     if (!m_parentRelativeScrollableRect.isEmpty())
318         ts.dumpProperty("parent relative scrollable rect", m_parentRelativeScrollableRect);
319
320     if (m_scrollOrigin != IntPoint())
321         ts.dumpProperty("scroll origin", m_scrollOrigin);
322
323 #if ENABLE(CSS_SCROLL_SNAP)
324     if (m_snapOffsetsInfo.horizontalSnapOffsets.size())
325         ts.dumpProperty("horizontal snap offsets", m_snapOffsetsInfo.horizontalSnapOffsets);
326
327     if (m_snapOffsetsInfo.verticalSnapOffsets.size())
328         ts.dumpProperty("vertical snap offsets", m_snapOffsetsInfo.verticalSnapOffsets);
329
330     if (m_currentHorizontalSnapPointIndex)
331         ts.dumpProperty("current horizontal snap point index", m_currentHorizontalSnapPointIndex);
332
333     if (m_currentVerticalSnapPointIndex)
334         ts.dumpProperty("current vertical snap point index", m_currentVerticalSnapPointIndex);
335 #endif
336
337     ts.dumpProperty("scrollable area parameters", m_scrollableAreaParameters);
338
339     if (m_isMonitoringWheelEvents)
340         ts.dumpProperty("expects wheel event test trigger", m_isMonitoringWheelEvents);
341
342     if (behavior & ScrollingStateTreeAsTextBehaviorIncludeLayerIDs) {
343         if (m_scrollContainerLayer.layerID())
344             ts.dumpProperty("scroll container layer", m_scrollContainerLayer.layerID());
345         if (m_scrolledContentsLayer.layerID())
346             ts.dumpProperty("scrolled contents layer", m_scrolledContentsLayer.layerID());
347     }
348 }
349
350 } // namespace WebCore
351
352 #endif // ENABLE(ASYNC_SCROLLING)