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