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