1/*
2 * Copyright (C) 2014 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) || USE(COORDINATED_GRAPHICS)
30
31#include "ScrollingStateTree.h"
32#include "TextStream.h"
33#include <wtf/OwnPtr.h>
34
35namespace WebCore {
36
37PassRefPtr<ScrollingStateFrameScrollingNode> ScrollingStateFrameScrollingNode::create(ScrollingStateTree& stateTree, ScrollingNodeID nodeID)
38{
39    return adoptRef(new ScrollingStateFrameScrollingNode(stateTree, nodeID));
40}
41
42ScrollingStateFrameScrollingNode::ScrollingStateFrameScrollingNode(ScrollingStateTree& stateTree, ScrollingNodeID nodeID)
43    : ScrollingStateScrollingNode(stateTree, FrameScrollingNode, nodeID)
44#if PLATFORM(MAC)
45    , m_verticalScrollbarPainter(0)
46    , m_horizontalScrollbarPainter(0)
47#endif
48    , m_frameScaleFactor(1)
49    , m_wheelEventHandlerCount(0)
50    , m_synchronousScrollingReasons(0)
51    , m_behaviorForFixed(StickToDocumentBounds)
52    , m_headerHeight(0)
53    , m_footerHeight(0)
54    , m_requestedScrollPositionRepresentsProgrammaticScroll(false)
55    , m_topContentInset(0)
56{
57}
58
59ScrollingStateFrameScrollingNode::ScrollingStateFrameScrollingNode(const ScrollingStateFrameScrollingNode& stateNode, ScrollingStateTree& adoptiveTree)
60    : ScrollingStateScrollingNode(stateNode, adoptiveTree)
61#if PLATFORM(MAC)
62    , m_verticalScrollbarPainter(stateNode.verticalScrollbarPainter())
63    , m_horizontalScrollbarPainter(stateNode.horizontalScrollbarPainter())
64#endif
65    , m_nonFastScrollableRegion(stateNode.nonFastScrollableRegion())
66    , m_frameScaleFactor(stateNode.frameScaleFactor())
67    , m_wheelEventHandlerCount(stateNode.wheelEventHandlerCount())
68    , m_synchronousScrollingReasons(stateNode.synchronousScrollingReasons())
69    , m_behaviorForFixed(stateNode.scrollBehaviorForFixedElements())
70    , m_headerHeight(stateNode.headerHeight())
71    , m_footerHeight(stateNode.footerHeight())
72    , m_requestedScrollPosition(stateNode.requestedScrollPosition())
73    , m_requestedScrollPositionRepresentsProgrammaticScroll(stateNode.requestedScrollPositionRepresentsProgrammaticScroll())
74    , m_topContentInset(stateNode.topContentInset())
75{
76    if (hasChangedProperty(ScrolledContentsLayer))
77        setScrolledContentsLayer(stateNode.scrolledContentsLayer().toRepresentation(adoptiveTree.preferredLayerRepresentation()));
78
79    if (hasChangedProperty(CounterScrollingLayer))
80        setCounterScrollingLayer(stateNode.counterScrollingLayer().toRepresentation(adoptiveTree.preferredLayerRepresentation()));
81
82    if (hasChangedProperty(InsetClipLayer))
83        setInsetClipLayer(stateNode.insetClipLayer().toRepresentation(adoptiveTree.preferredLayerRepresentation()));
84
85    if (hasChangedProperty(ContentShadowLayer))
86        setContentShadowLayer(stateNode.contentShadowLayer().toRepresentation(adoptiveTree.preferredLayerRepresentation()));
87
88    if (hasChangedProperty(HeaderLayer))
89        setHeaderLayer(stateNode.headerLayer().toRepresentation(adoptiveTree.preferredLayerRepresentation()));
90
91    if (hasChangedProperty(FooterLayer))
92        setFooterLayer(stateNode.footerLayer().toRepresentation(adoptiveTree.preferredLayerRepresentation()));
93}
94
95ScrollingStateFrameScrollingNode::~ScrollingStateFrameScrollingNode()
96{
97}
98
99PassRefPtr<ScrollingStateNode> ScrollingStateFrameScrollingNode::clone(ScrollingStateTree& adoptiveTree)
100{
101    return adoptRef(new ScrollingStateFrameScrollingNode(*this, adoptiveTree));
102}
103
104void ScrollingStateFrameScrollingNode::setFrameScaleFactor(float scaleFactor)
105{
106    if (m_frameScaleFactor == scaleFactor)
107        return;
108
109    m_frameScaleFactor = scaleFactor;
110
111    setPropertyChanged(FrameScaleFactor);
112}
113
114void ScrollingStateFrameScrollingNode::setNonFastScrollableRegion(const Region& nonFastScrollableRegion)
115{
116    if (m_nonFastScrollableRegion == nonFastScrollableRegion)
117        return;
118
119    m_nonFastScrollableRegion = nonFastScrollableRegion;
120    setPropertyChanged(NonFastScrollableRegion);
121}
122
123void ScrollingStateFrameScrollingNode::setWheelEventHandlerCount(unsigned wheelEventHandlerCount)
124{
125    if (m_wheelEventHandlerCount == wheelEventHandlerCount)
126        return;
127
128    m_wheelEventHandlerCount = wheelEventHandlerCount;
129    setPropertyChanged(WheelEventHandlerCount);
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::setHeaderHeight(int headerHeight)
151{
152    if (m_headerHeight == headerHeight)
153        return;
154
155    m_headerHeight = headerHeight;
156    setPropertyChanged(HeaderHeight);
157}
158
159void ScrollingStateFrameScrollingNode::setFooterHeight(int footerHeight)
160{
161    if (m_footerHeight == footerHeight)
162        return;
163
164    m_footerHeight = footerHeight;
165    setPropertyChanged(FooterHeight);
166}
167
168void ScrollingStateFrameScrollingNode::setTopContentInset(float topContentInset)
169{
170    if (m_topContentInset == topContentInset)
171        return;
172
173    m_topContentInset = topContentInset;
174    setPropertyChanged(TopContentInset);
175}
176
177void ScrollingStateFrameScrollingNode::setScrolledContentsLayer(const LayerRepresentation& layerRepresentation)
178{
179    if (layerRepresentation == m_scrolledContentsLayer)
180        return;
181
182    m_scrolledContentsLayer = layerRepresentation;
183    setPropertyChanged(ScrolledContentsLayer);
184}
185
186void ScrollingStateFrameScrollingNode::setCounterScrollingLayer(const LayerRepresentation& layerRepresentation)
187{
188    if (layerRepresentation == m_counterScrollingLayer)
189        return;
190
191    m_counterScrollingLayer = layerRepresentation;
192    setPropertyChanged(CounterScrollingLayer);
193}
194
195void ScrollingStateFrameScrollingNode::setInsetClipLayer(const LayerRepresentation& layerRepresentation)
196{
197    if (layerRepresentation == m_insetClipLayer)
198        return;
199
200    m_insetClipLayer = layerRepresentation;
201    setPropertyChanged(InsetClipLayer);
202}
203
204void ScrollingStateFrameScrollingNode::setContentShadowLayer(const LayerRepresentation& layerRepresentation)
205{
206    if (layerRepresentation == m_contentShadowLayer)
207        return;
208
209    m_contentShadowLayer = layerRepresentation;
210    setPropertyChanged(ContentShadowLayer);
211}
212
213void ScrollingStateFrameScrollingNode::setHeaderLayer(const LayerRepresentation& layerRepresentation)
214{
215    if (layerRepresentation == m_headerLayer)
216        return;
217
218    m_headerLayer = layerRepresentation;
219    setPropertyChanged(HeaderLayer);
220}
221
222void ScrollingStateFrameScrollingNode::setFooterLayer(const LayerRepresentation& layerRepresentation)
223{
224    if (layerRepresentation == m_footerLayer)
225        return;
226
227    m_footerLayer = layerRepresentation;
228    setPropertyChanged(FooterLayer);
229}
230
231#if !PLATFORM(MAC)
232void ScrollingStateFrameScrollingNode::setScrollbarPaintersFromScrollbars(Scrollbar*, Scrollbar*)
233{
234}
235#endif
236
237void ScrollingStateFrameScrollingNode::dumpProperties(TextStream& ts, int indent) const
238{
239    ts << "(Frame scrolling node" << "\n";
240
241    ScrollingStateScrollingNode::dumpProperties(ts, indent);
242
243    if (m_frameScaleFactor != 1) {
244        writeIndent(ts, indent + 1);
245        ts << "(frame scale factor " << m_frameScaleFactor << ")\n";
246    }
247
248    if (!m_nonFastScrollableRegion.isEmpty()) {
249        ++indent;
250        writeIndent(ts, indent);
251        ts << "(non-fast-scrollable region";
252        ++indent;
253        for (auto rect : m_nonFastScrollableRegion.rects()) {
254            ts << "\n";
255            writeIndent(ts, indent);
256            ts << rect;
257        }
258        ts << ")\n";
259        indent -= 2;
260    }
261
262    if (m_synchronousScrollingReasons) {
263        writeIndent(ts, indent + 1);
264        ts << "(Scrolling on main thread because: " << ScrollingCoordinator::synchronousScrollingReasonsAsText(m_synchronousScrollingReasons) << ")\n";
265    }
266
267    // FIXME: dump more properties.
268}
269
270} // namespace WebCore
271
272#endif // ENABLE(ASYNC_SCROLLING) || USE(COORDINATED_GRAPHICS)
273