1/*
2 * Copyright (C) 2014, 2016 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 "ScrollingStateFrameScrollingNode.h"
28
29#if ENABLE(ASYNC_SCROLLING)
30
31#include "ScrollingStateTree.h"
32#include <wtf/text/TextStream.h>
33
34namespace WebCore {
35
36Ref<ScrollingStateFrameScrollingNode> ScrollingStateFrameScrollingNode::create(ScrollingStateTree& stateTree, ScrollingNodeType nodeType, ScrollingNodeID nodeID)
37{
38 return adoptRef(*new ScrollingStateFrameScrollingNode(stateTree, nodeType, nodeID));
39}
40
41ScrollingStateFrameScrollingNode::ScrollingStateFrameScrollingNode(ScrollingStateTree& stateTree, ScrollingNodeType nodeType, ScrollingNodeID nodeID)
42 : ScrollingStateScrollingNode(stateTree, nodeType, nodeID)
43{
44 ASSERT(isFrameScrollingNode());
45}
46
47ScrollingStateFrameScrollingNode::ScrollingStateFrameScrollingNode(const ScrollingStateFrameScrollingNode& stateNode, ScrollingStateTree& adoptiveTree)
48 : ScrollingStateScrollingNode(stateNode, adoptiveTree)
49 , m_eventTrackingRegions(stateNode.eventTrackingRegions())
50 , m_layoutViewport(stateNode.layoutViewport())
51 , m_minLayoutViewportOrigin(stateNode.minLayoutViewportOrigin())
52 , m_maxLayoutViewportOrigin(stateNode.maxLayoutViewportOrigin())
53 , m_frameScaleFactor(stateNode.frameScaleFactor())
54 , m_topContentInset(stateNode.topContentInset())
55 , m_headerHeight(stateNode.headerHeight())
56 , m_footerHeight(stateNode.footerHeight())
57 , m_synchronousScrollingReasons(stateNode.synchronousScrollingReasons())
58 , m_behaviorForFixed(stateNode.scrollBehaviorForFixedElements())
59 , m_fixedElementsLayoutRelativeToFrame(stateNode.fixedElementsLayoutRelativeToFrame())
60 , m_asyncFrameOrOverflowScrollingEnabled(stateNode.asyncFrameOrOverflowScrollingEnabled())
61{
62 if (hasChangedProperty(RootContentsLayer))
63 setRootContentsLayer(stateNode.rootContentsLayer().toRepresentation(adoptiveTree.preferredLayerRepresentation()));
64
65 if (hasChangedProperty(CounterScrollingLayer))
66 setCounterScrollingLayer(stateNode.counterScrollingLayer().toRepresentation(adoptiveTree.preferredLayerRepresentation()));
67
68 if (hasChangedProperty(InsetClipLayer))
69 setInsetClipLayer(stateNode.insetClipLayer().toRepresentation(adoptiveTree.preferredLayerRepresentation()));
70
71 if (hasChangedProperty(ContentShadowLayer))
72 setContentShadowLayer(stateNode.contentShadowLayer().toRepresentation(adoptiveTree.preferredLayerRepresentation()));
73
74 if (hasChangedProperty(HeaderLayer))
75 setHeaderLayer(stateNode.headerLayer().toRepresentation(adoptiveTree.preferredLayerRepresentation()));
76
77 if (hasChangedProperty(FooterLayer))
78 setFooterLayer(stateNode.footerLayer().toRepresentation(adoptiveTree.preferredLayerRepresentation()));
79}
80
81ScrollingStateFrameScrollingNode::~ScrollingStateFrameScrollingNode() = default;
82
83Ref<ScrollingStateNode> ScrollingStateFrameScrollingNode::clone(ScrollingStateTree& adoptiveTree)
84{
85 return adoptRef(*new ScrollingStateFrameScrollingNode(*this, adoptiveTree));
86}
87
88void ScrollingStateFrameScrollingNode::setAllPropertiesChanged()
89{
90 setPropertyChangedBit(FrameScaleFactor);
91 setPropertyChangedBit(EventTrackingRegion);
92 setPropertyChangedBit(ReasonsForSynchronousScrolling);
93 setPropertyChangedBit(RootContentsLayer);
94 setPropertyChangedBit(ScrolledContentsLayer);
95 setPropertyChangedBit(CounterScrollingLayer);
96 setPropertyChangedBit(InsetClipLayer);
97 setPropertyChangedBit(ContentShadowLayer);
98 setPropertyChangedBit(HeaderHeight);
99 setPropertyChangedBit(FooterHeight);
100 setPropertyChangedBit(HeaderLayer);
101 setPropertyChangedBit(FooterLayer);
102 setPropertyChangedBit(BehaviorForFixedElements);
103 setPropertyChangedBit(TopContentInset);
104 setPropertyChangedBit(FixedElementsLayoutRelativeToFrame);
105 setPropertyChangedBit(AsyncFrameOrOverflowScrollingEnabled);
106 setPropertyChangedBit(LayoutViewport);
107 setPropertyChangedBit(MinLayoutViewportOrigin);
108 setPropertyChangedBit(MaxLayoutViewportOrigin);
109
110 ScrollingStateScrollingNode::setAllPropertiesChanged();
111}
112
113void ScrollingStateFrameScrollingNode::setFrameScaleFactor(float scaleFactor)
114{
115 if (m_frameScaleFactor == scaleFactor)
116 return;
117
118 m_frameScaleFactor = scaleFactor;
119
120 setPropertyChanged(FrameScaleFactor);
121}
122
123void ScrollingStateFrameScrollingNode::setEventTrackingRegions(const EventTrackingRegions& eventTrackingRegions)
124{
125 if (m_eventTrackingRegions == eventTrackingRegions)
126 return;
127
128 m_eventTrackingRegions = eventTrackingRegions;
129 setPropertyChanged(EventTrackingRegion);
130}
131
132void ScrollingStateFrameScrollingNode::setSynchronousScrollingReasons(SynchronousScrollingReasons reasons)
133{
134 if (m_synchronousScrollingReasons == reasons)
135 return;
136
137 m_synchronousScrollingReasons = reasons;
138 setPropertyChanged(ReasonsForSynchronousScrolling);
139}
140
141void ScrollingStateFrameScrollingNode::setScrollBehaviorForFixedElements(ScrollBehaviorForFixedElements behaviorForFixed)
142{
143 if (m_behaviorForFixed == behaviorForFixed)
144 return;
145
146 m_behaviorForFixed = behaviorForFixed;
147 setPropertyChanged(BehaviorForFixedElements);
148}
149
150void ScrollingStateFrameScrollingNode::setLayoutViewport(const FloatRect& r)
151{
152 if (m_layoutViewport == r)
153 return;
154
155 m_layoutViewport = r;
156 setPropertyChanged(LayoutViewport);
157}
158
159void ScrollingStateFrameScrollingNode::setMinLayoutViewportOrigin(const FloatPoint& p)
160{
161 if (m_minLayoutViewportOrigin == p)
162 return;
163
164 m_minLayoutViewportOrigin = p;
165 setPropertyChanged(MinLayoutViewportOrigin);
166}
167
168void ScrollingStateFrameScrollingNode::setMaxLayoutViewportOrigin(const FloatPoint& p)
169{
170 if (m_maxLayoutViewportOrigin == p)
171 return;
172
173 m_maxLayoutViewportOrigin = p;
174 setPropertyChanged(MaxLayoutViewportOrigin);
175}
176
177void ScrollingStateFrameScrollingNode::setHeaderHeight(int headerHeight)
178{
179 if (m_headerHeight == headerHeight)
180 return;
181
182 m_headerHeight = headerHeight;
183 setPropertyChanged(HeaderHeight);
184}
185
186void ScrollingStateFrameScrollingNode::setFooterHeight(int footerHeight)
187{
188 if (m_footerHeight == footerHeight)
189 return;
190
191 m_footerHeight = footerHeight;
192 setPropertyChanged(FooterHeight);
193}
194
195void ScrollingStateFrameScrollingNode::setTopContentInset(float topContentInset)
196{
197 if (m_topContentInset == topContentInset)
198 return;
199
200 m_topContentInset = topContentInset;
201 setPropertyChanged(TopContentInset);
202}
203
204void ScrollingStateFrameScrollingNode::setRootContentsLayer(const LayerRepresentation& layerRepresentation)
205{
206 if (layerRepresentation == m_rootContentsLayer)
207 return;
208
209 m_rootContentsLayer = layerRepresentation;
210 setPropertyChanged(RootContentsLayer);
211}
212
213void ScrollingStateFrameScrollingNode::setCounterScrollingLayer(const LayerRepresentation& layerRepresentation)
214{
215 if (layerRepresentation == m_counterScrollingLayer)
216 return;
217
218 m_counterScrollingLayer = layerRepresentation;
219 setPropertyChanged(CounterScrollingLayer);
220}
221
222void ScrollingStateFrameScrollingNode::setInsetClipLayer(const LayerRepresentation& layerRepresentation)
223{
224 if (layerRepresentation == m_insetClipLayer)
225 return;
226
227 m_insetClipLayer = layerRepresentation;
228 setPropertyChanged(InsetClipLayer);
229}
230
231void ScrollingStateFrameScrollingNode::setContentShadowLayer(const LayerRepresentation& layerRepresentation)
232{
233 if (layerRepresentation == m_contentShadowLayer)
234 return;
235
236 m_contentShadowLayer = layerRepresentation;
237 setPropertyChanged(ContentShadowLayer);
238}
239
240void ScrollingStateFrameScrollingNode::setHeaderLayer(const LayerRepresentation& layerRepresentation)
241{
242 if (layerRepresentation == m_headerLayer)
243 return;
244
245 m_headerLayer = layerRepresentation;
246 setPropertyChanged(HeaderLayer);
247}
248
249void ScrollingStateFrameScrollingNode::setFooterLayer(const LayerRepresentation& layerRepresentation)
250{
251 if (layerRepresentation == m_footerLayer)
252 return;
253
254 m_footerLayer = layerRepresentation;
255 setPropertyChanged(FooterLayer);
256}
257
258void ScrollingStateFrameScrollingNode::setFixedElementsLayoutRelativeToFrame(bool fixedElementsLayoutRelativeToFrame)
259{
260 if (fixedElementsLayoutRelativeToFrame == m_fixedElementsLayoutRelativeToFrame)
261 return;
262
263 m_fixedElementsLayoutRelativeToFrame = fixedElementsLayoutRelativeToFrame;
264 setPropertyChanged(FixedElementsLayoutRelativeToFrame);
265}
266
267void ScrollingStateFrameScrollingNode::setAsyncFrameOrOverflowScrollingEnabled(bool enabled)
268{
269 if (enabled == m_asyncFrameOrOverflowScrollingEnabled)
270 return;
271
272 m_asyncFrameOrOverflowScrollingEnabled = enabled;
273 setPropertyChanged(AsyncFrameOrOverflowScrollingEnabled);
274}
275
276void ScrollingStateFrameScrollingNode::dumpProperties(TextStream& ts, ScrollingStateTreeAsTextBehavior behavior) const
277{
278 ts << "Frame scrolling node";
279
280 ScrollingStateScrollingNode::dumpProperties(ts, behavior);
281
282 if (behavior & ScrollingStateTreeAsTextBehaviorIncludeLayerIDs) {
283 ts.dumpProperty("root contents layer ID", m_rootContentsLayer.layerID());
284 ts.dumpProperty("counter scrolling layer ID", m_counterScrollingLayer.layerID());
285 ts.dumpProperty("inset clip layer ID", m_insetClipLayer.layerID());
286 ts.dumpProperty("content shadow layer ID", m_contentShadowLayer.layerID());
287 ts.dumpProperty("header layer ID", m_headerLayer.layerID());
288 ts.dumpProperty("footer layer ID", m_footerLayer.layerID());
289 }
290
291 if (m_frameScaleFactor != 1)
292 ts.dumpProperty("frame scale factor", m_frameScaleFactor);
293 if (m_topContentInset)
294 ts.dumpProperty("top content inset", m_topContentInset);
295 if (m_headerHeight)
296 ts.dumpProperty("header height", m_headerHeight);
297 if (m_footerHeight)
298 ts.dumpProperty("footer height", m_footerHeight);
299
300 ts.dumpProperty("layout viewport", m_layoutViewport);
301 ts.dumpProperty("min layout viewport origin", m_minLayoutViewportOrigin);
302 ts.dumpProperty("max layout viewport origin", m_maxLayoutViewportOrigin);
303
304 if (m_behaviorForFixed == StickToViewportBounds)
305 ts.dumpProperty("behavior for fixed", m_behaviorForFixed);
306
307 if (!m_eventTrackingRegions.asynchronousDispatchRegion.isEmpty()) {
308 TextStream::GroupScope scope(ts);
309 ts << "asynchronous event dispatch region";
310 for (auto rect : m_eventTrackingRegions.asynchronousDispatchRegion.rects()) {
311 ts << "\n";
312 ts << indent << rect;
313 }
314 }
315
316 if (!m_eventTrackingRegions.eventSpecificSynchronousDispatchRegions.isEmpty()) {
317 for (const auto& synchronousEventRegion : m_eventTrackingRegions.eventSpecificSynchronousDispatchRegions) {
318 TextStream::GroupScope scope(ts);
319 ts << "synchronous event dispatch region for event " << synchronousEventRegion.key;
320 for (auto rect : synchronousEventRegion.value.rects()) {
321 ts << "\n";
322 ts << indent << rect;
323 }
324 }
325 }
326
327 if (m_synchronousScrollingReasons)
328 ts.dumpProperty("Scrolling on main thread because:", ScrollingCoordinator::synchronousScrollingReasonsAsText(m_synchronousScrollingReasons));
329
330 ts.dumpProperty("behavior for fixed", m_behaviorForFixed);
331
332 if (m_fixedElementsLayoutRelativeToFrame)
333 ts.dumpProperty("fixed elements lay out relative to frame", m_fixedElementsLayoutRelativeToFrame);
334}
335
336} // namespace WebCore
337
338#endif // ENABLE(ASYNC_SCROLLING)
339