Add a way to get the UI-side scrolling tree as text via UIScriptController
[WebKit-https.git] / Source / WebCore / page / scrolling / ScrollingTreeScrollingNode.cpp
1 /*
2  * Copyright (C) 2012 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 "ScrollingTreeScrollingNode.h"
28
29 #if ENABLE(ASYNC_SCROLLING)
30
31 #include "ScrollingStateTree.h"
32 #include "ScrollingTree.h"
33 #include "TextStream.h"
34
35 namespace WebCore {
36
37 ScrollingTreeScrollingNode::ScrollingTreeScrollingNode(ScrollingTree& scrollingTree, ScrollingNodeType nodeType, ScrollingNodeID nodeID)
38     : ScrollingTreeNode(scrollingTree, nodeType, nodeID)
39 {
40 }
41
42 ScrollingTreeScrollingNode::~ScrollingTreeScrollingNode()
43 {
44 }
45
46 void ScrollingTreeScrollingNode::commitStateBeforeChildren(const ScrollingStateNode& stateNode)
47 {
48     const ScrollingStateScrollingNode& state = downcast<ScrollingStateScrollingNode>(stateNode);
49
50     if (state.hasChangedProperty(ScrollingStateScrollingNode::ScrollableAreaSize))
51         m_scrollableAreaSize = state.scrollableAreaSize();
52
53     if (state.hasChangedProperty(ScrollingStateScrollingNode::TotalContentsSize)) {
54         if (scrollingTree().isRubberBandInProgress())
55             m_totalContentsSizeForRubberBand = m_totalContentsSize;
56         else
57             m_totalContentsSizeForRubberBand = state.totalContentsSize();
58
59         m_totalContentsSize = state.totalContentsSize();
60     }
61
62     if (state.hasChangedProperty(ScrollingStateScrollingNode::ReachableContentsSize))
63         m_reachableContentsSize = state.reachableContentsSize();
64
65     if (state.hasChangedProperty(ScrollingStateScrollingNode::ScrollPosition))
66         m_lastCommittedScrollPosition = state.scrollPosition();
67
68     if (state.hasChangedProperty(ScrollingStateScrollingNode::ScrollOrigin))
69         m_scrollOrigin = state.scrollOrigin();
70
71 #if ENABLE(CSS_SCROLL_SNAP)
72     if (state.hasChangedProperty(ScrollingStateScrollingNode::HorizontalSnapOffsets))
73         m_horizontalSnapOffsets = state.horizontalSnapOffsets();
74
75     if (state.hasChangedProperty(ScrollingStateScrollingNode::VerticalSnapOffsets))
76         m_verticalSnapOffsets = state.verticalSnapOffsets();
77
78     if (state.hasChangedProperty(ScrollingStateScrollingNode::CurrentHorizontalSnapOffsetIndex))
79         m_currentHorizontalSnapPointIndex = state.currentHorizontalSnapPointIndex();
80
81     if (state.hasChangedProperty(ScrollingStateScrollingNode::CurrentVerticalSnapOffsetIndex))
82         m_currentVerticalSnapPointIndex = state.currentVerticalSnapPointIndex();
83 #endif
84
85     if (state.hasChangedProperty(ScrollingStateScrollingNode::ScrollableAreaParams))
86         m_scrollableAreaParameters = state.scrollableAreaParameters();
87 }
88
89 void ScrollingTreeScrollingNode::commitStateAfterChildren(const ScrollingStateNode& stateNode)
90 {
91     const ScrollingStateScrollingNode& scrollingStateNode = downcast<ScrollingStateScrollingNode>(stateNode);
92     if (scrollingStateNode.hasChangedProperty(ScrollingStateScrollingNode::RequestedScrollPosition))
93         scrollingTree().scrollingTreeNodeRequestsScroll(scrollingNodeID(), scrollingStateNode.requestedScrollPosition(), scrollingStateNode.requestedScrollPositionRepresentsProgrammaticScroll());
94 }
95
96 void ScrollingTreeScrollingNode::updateLayersAfterAncestorChange(const ScrollingTreeNode& changedNode, const FloatRect& fixedPositionRect, const FloatSize& cumulativeDelta)
97 {
98     if (!m_children)
99         return;
100
101     for (auto& child : *m_children)
102         child->updateLayersAfterAncestorChange(changedNode, fixedPositionRect, cumulativeDelta);
103 }
104
105 void ScrollingTreeScrollingNode::setScrollPosition(const FloatPoint& scrollPosition)
106 {
107     FloatPoint newScrollPosition = scrollPosition.constrainedBetween(minimumScrollPosition(), maximumScrollPosition());
108     setScrollPositionWithoutContentEdgeConstraints(newScrollPosition);
109 }
110
111 void ScrollingTreeScrollingNode::setScrollPositionWithoutContentEdgeConstraints(const FloatPoint& scrollPosition)
112 {
113     setScrollLayerPosition(scrollPosition, { });
114     scrollingTree().scrollingTreeNodeDidScroll(scrollingNodeID(), scrollPosition, Nullopt);
115 }
116
117 FloatPoint ScrollingTreeScrollingNode::minimumScrollPosition() const
118 {
119     return FloatPoint();
120 }
121
122 FloatPoint ScrollingTreeScrollingNode::maximumScrollPosition() const
123 {
124     FloatPoint contentSizePoint(totalContentsSize());
125     return FloatPoint(contentSizePoint - scrollableAreaSize()).expandedTo(FloatPoint());
126 }
127
128 void ScrollingTreeScrollingNode::dumpProperties(TextStream& ts, ScrollingStateTreeAsTextBehavior behavior) const
129 {
130     ScrollingTreeNode::dumpProperties(ts, behavior);
131     ts.dumpProperty("scrollable area size", m_scrollableAreaSize);
132     ts.dumpProperty("total content size", m_totalContentsSize);
133     if (m_totalContentsSizeForRubberBand != m_totalContentsSize)
134         ts.dumpProperty("total content size for rubber band", m_totalContentsSizeForRubberBand);
135     if (m_reachableContentsSize != m_totalContentsSize)
136         ts.dumpProperty("reachable content size", m_reachableContentsSize);
137     ts.dumpProperty("scrollable area size", m_lastCommittedScrollPosition);
138     if (m_scrollOrigin != IntPoint())
139         ts.dumpProperty("scrollable area size", m_scrollOrigin);
140
141 #if ENABLE(CSS_SCROLL_SNAP)
142     if (m_horizontalSnapOffsets.size())
143         ts.dumpProperty("horizontal snap offsets", m_horizontalSnapOffsets);
144
145     if (m_verticalSnapOffsets.size())
146         ts.dumpProperty("horizontal snap offsets", m_verticalSnapOffsets);
147
148     if (m_currentHorizontalSnapPointIndex)
149         ts.dumpProperty("current horizontal snap point index", m_verticalSnapOffsets);
150
151     if (m_currentVerticalSnapPointIndex)
152         ts.dumpProperty("current vertical snap point index", m_currentVerticalSnapPointIndex);
153     
154 #endif
155 }
156
157 } // namespace WebCore
158
159 #endif // ENABLE(ASYNC_SCROLLING)