[iOS WK2] REGRESSION (r242687): Programmatic scroll of overflow scroll results in...
[WebKit-https.git] / Source / WebCore / page / scrolling / ScrollingTreeScrollingNode.h
index 0be37b1..bbf166a 100644 (file)
  * THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-#ifndef ScrollingTreeScrollingNode_h
-#define ScrollingTreeScrollingNode_h
+#pragma once
 
-#if ENABLE(THREADED_SCROLLING)
+#if ENABLE(ASYNC_SCROLLING)
 
 #include "IntRect.h"
+#include "ScrollSnapOffsetsInfo.h"
 #include "ScrollTypes.h"
 #include "ScrollingCoordinator.h"
 #include "ScrollingTreeNode.h"
-#include <wtf/PassOwnPtr.h>
 
 namespace WebCore {
 
-class PlatformWheelEvent;
 class ScrollingTree;
 class ScrollingStateScrollingNode;
 
-class ScrollingTreeScrollingNode : public ScrollingTreeNode {
+class WEBCORE_EXPORT ScrollingTreeScrollingNode : public ScrollingTreeNode {
+    friend class ScrollingTreeScrollingNodeDelegate;
+#if PLATFORM(MAC)
+    friend class ScrollingTreeScrollingNodeDelegateMac;
+#endif
+    friend class ScrollingTree;
+
 public:
-    static PassOwnPtr<ScrollingTreeScrollingNode> create(ScrollingTree*, ScrollingNodeID);
     virtual ~ScrollingTreeScrollingNode();
 
-    virtual void updateBeforeChildren(ScrollingStateNode*) OVERRIDE;
+    void commitStateBeforeChildren(const ScrollingStateNode&) override;
+    void commitStateAfterChildren(const ScrollingStateNode&) override;
+
+    virtual ScrollingEventResult handleWheelEvent(const PlatformWheelEvent&);
+
+    FloatPoint currentScrollPosition() const { return m_currentScrollPosition; }
+    FloatPoint lastCommittedScrollPosition() const { return m_lastCommittedScrollPosition; }
+
+    // These are imperative; they adjust the scrolling layers.
+    void scrollTo(const FloatPoint&, ScrollType = ScrollType::User, ScrollPositionClamp = ScrollPositionClamp::ToContentEdges);
+    void scrollBy(const FloatSize&, ScrollPositionClamp = ScrollPositionClamp::ToContentEdges);
+
+    void wasScrolledByDelegatedScrolling(const FloatPoint& position, Optional<FloatRect> overrideLayoutViewport = { });
+    
+    const FloatSize& scrollableAreaSize() const { return m_scrollableAreaSize; }
+    const FloatSize& totalContentsSize() const { return m_totalContentsSize; }
+
+    bool horizontalScrollbarHiddenByStyle() const { return m_scrollableAreaParameters.horizontalScrollbarHiddenByStyle; }
+    bool verticalScrollbarHiddenByStyle() const { return m_scrollableAreaParameters.verticalScrollbarHiddenByStyle; }
+
+#if ENABLE(CSS_SCROLL_SNAP)
+    const Vector<float>& horizontalSnapOffsets() const { return m_snapOffsetsInfo.horizontalSnapOffsets; }
+    const Vector<float>& verticalSnapOffsets() const { return m_snapOffsetsInfo.verticalSnapOffsets; }
+    const Vector<ScrollOffsetRange<float>>& horizontalSnapOffsetRanges() const { return m_snapOffsetsInfo.horizontalSnapOffsetRanges; }
+    const Vector<ScrollOffsetRange<float>>& verticalSnapOffsetRanges() const { return m_snapOffsetsInfo.verticalSnapOffsetRanges; }
+    unsigned currentHorizontalSnapPointIndex() const { return m_currentHorizontalSnapPointIndex; }
+    unsigned currentVerticalSnapPointIndex() const { return m_currentVerticalSnapPointIndex; }
+    void setCurrentHorizontalSnapPointIndex(unsigned index) { m_currentHorizontalSnapPointIndex = index; }
+    void setCurrentVerticalSnapPointIndex(unsigned index) { m_currentVerticalSnapPointIndex = index; }
+#endif
 
-    // FIXME: We should implement this when we support ScrollingTreeScrollingNodes as children.
-    virtual void parentScrollPositionDidChange(const IntRect& /*viewportRect*/, const FloatSize& /*cumulativeDelta*/) OVERRIDE { }
+    bool useDarkAppearanceForScrollbars() const { return m_scrollableAreaParameters.useDarkAppearanceForScrollbars; }
 
-    virtual void handleWheelEvent(const PlatformWheelEvent&) = 0;
-    virtual void setScrollPosition(const IntPoint&) = 0;
+    bool scrollLimitReached(const PlatformWheelEvent&) const;
+    ScrollingTreeScrollingNode* scrollingNodeForPoint(LayoutPoint) const override;
 
-    MainThreadScrollingReasons shouldUpdateScrollLayerPositionOnMainThread() const { return m_shouldUpdateScrollLayerPositionOnMainThread; }
+#if PLATFORM(COCOA)
+    CALayer *scrollContainerLayer() const { return m_scrollContainerLayer.get(); }
+    CALayer *scrolledContentsLayer() const { return m_scrolledContentsLayer.get(); }
+#endif
 
 protected:
-    explicit ScrollingTreeScrollingNode(ScrollingTree*, ScrollingNodeID);
+    ScrollingTreeScrollingNode(ScrollingTree&, ScrollingNodeType, ScrollingNodeID);
 
-    const IntRect& viewportRect() const { return m_viewportRect; }
-    const IntSize& totalContentsSize() const { return m_totalContentsSize; }
+    virtual FloatPoint minimumScrollPosition() const;
+    virtual FloatPoint maximumScrollPosition() const;
 
-    float frameScaleFactor() const { return m_frameScaleFactor; }
+    FloatPoint clampScrollPosition(const FloatPoint&) const;
+    
+    virtual FloatPoint adjustedScrollPosition(const FloatPoint&, ScrollPositionClamp = ScrollPositionClamp::ToContentEdges) const;
 
-    ScrollElasticity horizontalScrollElasticity() const { return m_horizontalScrollElasticity; }
-    ScrollElasticity verticalScrollElasticity() const { return m_verticalScrollElasticity; }
+    virtual void currentScrollPositionChanged();
+    WEBCORE_EXPORT virtual void updateViewportForCurrentScrollPosition(Optional<FloatRect> = { }) { }
+    virtual bool scrollPositionAndLayoutViewportMatch(const FloatPoint& position, Optional<FloatRect> overrideLayoutViewport);
 
-    bool hasEnabledHorizontalScrollbar() const { return m_hasEnabledHorizontalScrollbar; }
-    bool hasEnabledVerticalScrollbar() const { return m_hasEnabledVerticalScrollbar; }
+    WEBCORE_EXPORT virtual void repositionScrollingLayers() { }
+    WEBCORE_EXPORT virtual void repositionRelatedLayers() { }
 
-    bool canHaveScrollbars() const { return m_horizontalScrollbarMode != ScrollbarAlwaysOff || m_verticalScrollbarMode != ScrollbarAlwaysOff; }
+    void applyLayerPositions(const FloatRect& layoutViewport, FloatSize& cumulativeDelta) override;
 
+    const FloatSize& reachableContentsSize() const { return m_reachableContentsSize; }
+    const LayoutRect& parentRelativeScrollableRect() const { return m_parentRelativeScrollableRect; }
     const IntPoint& scrollOrigin() const { return m_scrollOrigin; }
 
-private:
-    IntRect m_viewportRect;
-    IntSize m_totalContentsSize;
-    IntPoint m_scrollOrigin;
-    
-    float m_frameScaleFactor;
+    // If the totalContentsSize changes in the middle of a rubber-band, we still want to use the old totalContentsSize for the sake of
+    // computing the stretchAmount(). Using the old value will keep the animation smooth. When there is no rubber-band in progress at
+    // all, m_totalContentsSizeForRubberBand should be equivalent to m_totalContentsSize.
+    const FloatSize& totalContentsSizeForRubberBand() const { return m_totalContentsSizeForRubberBand; }
+    void setTotalContentsSizeForRubberBand(const FloatSize& totalContentsSizeForRubberBand) { m_totalContentsSizeForRubberBand = totalContentsSizeForRubberBand; }
 
-    MainThreadScrollingReasons m_shouldUpdateScrollLayerPositionOnMainThread;
+    ScrollElasticity horizontalScrollElasticity() const { return m_scrollableAreaParameters.horizontalScrollElasticity; }
+    ScrollElasticity verticalScrollElasticity() const { return m_scrollableAreaParameters.verticalScrollElasticity; }
 
-    ScrollElasticity m_horizontalScrollElasticity;
-    ScrollElasticity m_verticalScrollElasticity;
-    
-    bool m_hasEnabledHorizontalScrollbar;
-    bool m_hasEnabledVerticalScrollbar;
+    bool hasEnabledHorizontalScrollbar() const { return m_scrollableAreaParameters.hasEnabledHorizontalScrollbar; }
+    bool hasEnabledVerticalScrollbar() const { return m_scrollableAreaParameters.hasEnabledVerticalScrollbar; }
+
+    bool canHaveScrollbars() const { return m_scrollableAreaParameters.horizontalScrollbarMode != ScrollbarAlwaysOff || m_scrollableAreaParameters.verticalScrollbarMode != ScrollbarAlwaysOff; }
+
+    bool expectsWheelEventTestTrigger() const { return m_expectsWheelEventTestTrigger; }
 
-    ScrollbarMode m_horizontalScrollbarMode;
-    ScrollbarMode m_verticalScrollbarMode;
+    LayoutPoint parentToLocalPoint(LayoutPoint) const override;
+    LayoutPoint localToContentsPoint(LayoutPoint) const override;
+
+    void dumpProperties(WTF::TextStream&, ScrollingStateTreeAsTextBehavior) const override;
+
+private:
+    FloatSize m_scrollableAreaSize;
+    FloatSize m_totalContentsSize;
+    FloatSize m_totalContentsSizeForRubberBand;
+    FloatSize m_reachableContentsSize;
+    FloatPoint m_lastCommittedScrollPosition;
+    LayoutRect m_parentRelativeScrollableRect;
+    FloatPoint m_currentScrollPosition;
+    IntPoint m_scrollOrigin;
+#if ENABLE(CSS_SCROLL_SNAP)
+    ScrollSnapOffsetsInfo<float> m_snapOffsetsInfo;
+    unsigned m_currentHorizontalSnapPointIndex { 0 };
+    unsigned m_currentVerticalSnapPointIndex { 0 };
+#endif
+    ScrollableAreaParameters m_scrollableAreaParameters;
+    bool m_expectsWheelEventTestTrigger { false };
+
+#if PLATFORM(COCOA)
+    RetainPtr<CALayer> m_scrollContainerLayer;
+    RetainPtr<CALayer> m_scrolledContentsLayer;
+#endif
 };
 
 } // namespace WebCore
 
-#endif // ENABLE(THREADED_SCROLLING)
+SPECIALIZE_TYPE_TRAITS_SCROLLING_NODE(ScrollingTreeScrollingNode, isScrollingNode())
 
-#endif // ScrollingTreeScrollingNode_h
+#endif // ENABLE(ASYNC_SCROLLING)