Generalize ScrollingTreeScrollingNodeDelegate for use in macOS too, add a macOS subcl...
authorsimon.fraser@apple.com <simon.fraser@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 31 Jan 2019 23:26:38 +0000 (23:26 +0000)
committersimon.fraser@apple.com <simon.fraser@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 31 Jan 2019 23:26:38 +0000 (23:26 +0000)
https://bugs.webkit.org/show_bug.cgi?id=194080

Reviewed by Antti Koivisto.

To share code between ScrollingTreeFrameScrollingNodeMac and ScrollingTreeOverflowScrollingNodeMac, build ScrollingTreeScrollingNodeDelegate
for macOS too, and add some helper functions to ScrollingTreeScrollingNodeDelegate.

Add a macOS subclass, ScrollingTreeScrollingNodeDelegateMac, which takes over the basic scrolling, rubber-banding
and scroll snapping functionality from ScrollingTreeFrameScrollingNodeMac. The delegate owns the ScrollController and
implements ScrollControllerClient.

ScrollingTreeFrameScrollingNodeMac now owns a ScrollingTreeScrollingNodeDelegateMac. A future patch
will add one to ScrollingTreeOverflowScrollingNodeMac.

No behavior change.

* SourcesCocoa.txt:
* WebCore.xcodeproj/project.pbxproj:
* page/scrolling/ScrollingTreeFrameScrollingNode.cpp:
(WebCore::ScrollingTreeFrameScrollingNode::scrollBy): Deleted.
(WebCore::ScrollingTreeFrameScrollingNode::scrollByWithoutContentEdgeConstraints): Deleted.
* page/scrolling/ScrollingTreeFrameScrollingNode.h:
(WebCore::ScrollingTreeFrameScrollingNode::frameScaleFactor const):
* page/scrolling/ScrollingTreeNode.cpp:
(WebCore::ScrollingTreeNode::isRootNode const):
* page/scrolling/ScrollingTreeNode.h:
* page/scrolling/ScrollingTreeScrollingNode.cpp:
(WebCore::ScrollingTreeScrollingNode::commitStateBeforeChildren):
(WebCore::ScrollingTreeScrollingNode::scrollBy):
(WebCore::ScrollingTreeScrollingNode::scrollByWithoutContentEdgeConstraints):
* page/scrolling/ScrollingTreeScrollingNode.h:
(WebCore::ScrollingTreeScrollingNode::expectsWheelEventTestTrigger const):
* page/scrolling/ScrollingTreeScrollingNodeDelegate.cpp:
* page/scrolling/ScrollingTreeScrollingNodeDelegate.h:
(WebCore::ScrollingTreeScrollingNodeDelegate::scrollPosition const):
(WebCore::ScrollingTreeScrollingNodeDelegate::minimumScrollPosition const):
(WebCore::ScrollingTreeScrollingNodeDelegate::maximumScrollPosition const):
(WebCore::ScrollingTreeScrollingNodeDelegate::scrollableAreaSize const):
(WebCore::ScrollingTreeScrollingNodeDelegate::totalContentsSize const):
(WebCore::ScrollingTreeScrollingNodeDelegate::hasEnabledHorizontalScrollbar const):
(WebCore::ScrollingTreeScrollingNodeDelegate::hasEnabledVerticalScrollbar const):
(WebCore::ScrollingTreeScrollingNodeDelegate::horizontalScrollElasticity const):
(WebCore::ScrollingTreeScrollingNodeDelegate::verticalScrollElasticity const):
* page/scrolling/mac/ScrollingTreeFrameScrollingNodeMac.h:
* page/scrolling/mac/ScrollingTreeFrameScrollingNodeMac.mm:
(WebCore::ScrollingTreeFrameScrollingNodeMac::ScrollingTreeFrameScrollingNodeMac):
(WebCore::ScrollingTreeFrameScrollingNodeMac::commitStateBeforeChildren):
(WebCore::ScrollingTreeFrameScrollingNodeMac::handleWheelEvent):
(WebCore::ScrollingTreeFrameScrollingNodeMac::minimumScrollPosition const):
(WebCore::ScrollingTreeFrameScrollingNodeMac::maximumScrollPosition const):
(WebCore::newGestureIsStarting): Deleted.
(WebCore::ScrollingTreeFrameScrollingNodeMac::isAlreadyPinnedInDirectionOfGesture): Deleted.
(WebCore::ScrollingTreeFrameScrollingNodeMac::allowsHorizontalStretching): Deleted.
(WebCore::ScrollingTreeFrameScrollingNodeMac::allowsVerticalStretching): Deleted.
(WebCore::ScrollingTreeFrameScrollingNodeMac::stretchAmount): Deleted.
(WebCore::ScrollingTreeFrameScrollingNodeMac::pinnedInDirection): Deleted.
(WebCore::ScrollingTreeFrameScrollingNodeMac::canScrollHorizontally): Deleted.
(WebCore::ScrollingTreeFrameScrollingNodeMac::canScrollVertically): Deleted.
(WebCore::ScrollingTreeFrameScrollingNodeMac::shouldRubberBandInDirection): Deleted.
(WebCore::ScrollingTreeFrameScrollingNodeMac::immediateScrollBy): Deleted.
(WebCore::ScrollingTreeFrameScrollingNodeMac::immediateScrollByWithoutContentEdgeConstraints): Deleted.
(WebCore::ScrollingTreeFrameScrollingNodeMac::stopSnapRubberbandTimer): Deleted.
(WebCore::ScrollingTreeFrameScrollingNodeMac::adjustScrollPositionToBoundsIfNecessary): Deleted.
(WebCore::ScrollingTreeFrameScrollingNodeMac::scrollOffset const): Deleted.
(WebCore::ScrollingTreeFrameScrollingNodeMac::immediateScrollOnAxis): Deleted.
(WebCore::ScrollingTreeFrameScrollingNodeMac::pageScaleFactor const): Deleted.
(WebCore::ScrollingTreeFrameScrollingNodeMac::startScrollSnapTimer): Deleted.
(WebCore::ScrollingTreeFrameScrollingNodeMac::stopScrollSnapTimer): Deleted.
(WebCore::ScrollingTreeFrameScrollingNodeMac::scrollExtent const): Deleted.
(WebCore::ScrollingTreeFrameScrollingNodeMac::viewportSize const): Deleted.
(WebCore::ScrollingTreeFrameScrollingNodeMac::deferTestsForReason const): Deleted.
(WebCore::ScrollingTreeFrameScrollingNodeMac::removeTestDeferralForReason const): Deleted.
* page/scrolling/mac/ScrollingTreeScrollingNodeDelegateMac.h: Copied from Source/WebCore/page/scrolling/mac/ScrollingTreeFrameScrollingNodeMac.h.
* page/scrolling/mac/ScrollingTreeScrollingNodeDelegateMac.mm: Added.
(WebCore::ScrollingTreeScrollingNodeDelegateMac::ScrollingTreeScrollingNodeDelegateMac):
(WebCore::ScrollingTreeScrollingNodeDelegateMac::updateScrollSnapPoints):
(WebCore::ScrollingTreeScrollingNodeDelegateMac::setActiveScrollSnapIndexForAxis):
(WebCore::ScrollingTreeScrollingNodeDelegateMac::activeScrollSnapIndexForAxis const):
(WebCore::ScrollingTreeScrollingNodeDelegateMac::activeScrollSnapIndexDidChange const):
(WebCore::ScrollingTreeScrollingNodeDelegateMac::handleWheelEvent):
(WebCore::ScrollingTreeScrollingNodeDelegateMac::isScrollSnapInProgress const):
(WebCore::newGestureIsStarting):
(WebCore::ScrollingTreeScrollingNodeDelegateMac::isAlreadyPinnedInDirectionOfGesture):
(WebCore::ScrollingTreeScrollingNodeDelegateMac::allowsHorizontalStretching):
(WebCore::ScrollingTreeScrollingNodeDelegateMac::allowsVerticalStretching):
(WebCore::ScrollingTreeScrollingNodeDelegateMac::stretchAmount):
(WebCore::ScrollingTreeScrollingNodeDelegateMac::pinnedInDirection):
(WebCore::ScrollingTreeScrollingNodeDelegateMac::canScrollHorizontally):
(WebCore::ScrollingTreeScrollingNodeDelegateMac::canScrollVertically):
(WebCore::ScrollingTreeScrollingNodeDelegateMac::shouldRubberBandInDirection):
(WebCore::ScrollingTreeScrollingNodeDelegateMac::immediateScrollBy):
(WebCore::ScrollingTreeScrollingNodeDelegateMac::immediateScrollByWithoutContentEdgeConstraints):
(WebCore::ScrollingTreeScrollingNodeDelegateMac::stopSnapRubberbandTimer):
(WebCore::ScrollingTreeScrollingNodeDelegateMac::adjustScrollPositionToBoundsIfNecessary):
(WebCore::ScrollingTreeScrollingNodeDelegateMac::scrollOffset const):
(WebCore::ScrollingTreeScrollingNodeDelegateMac::immediateScrollOnAxis):
(WebCore::ScrollingTreeScrollingNodeDelegateMac::pageScaleFactor const):
(WebCore::ScrollingTreeScrollingNodeDelegateMac::startScrollSnapTimer):
(WebCore::ScrollingTreeScrollingNodeDelegateMac::stopScrollSnapTimer):
(WebCore::ScrollingTreeScrollingNodeDelegateMac::scrollExtent const):
(WebCore::ScrollingTreeScrollingNodeDelegateMac::viewportSize const):
(WebCore::ScrollingTreeScrollingNodeDelegateMac::deferTestsForReason const):
(WebCore::ScrollingTreeScrollingNodeDelegateMac::removeTestDeferralForReason const):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@240825 268f45cc-cd09-0410-ab3c-d52691b4dbfc

15 files changed:
Source/WebCore/ChangeLog
Source/WebCore/SourcesCocoa.txt
Source/WebCore/WebCore.xcodeproj/project.pbxproj
Source/WebCore/page/scrolling/ScrollingTreeFrameScrollingNode.cpp
Source/WebCore/page/scrolling/ScrollingTreeFrameScrollingNode.h
Source/WebCore/page/scrolling/ScrollingTreeNode.cpp
Source/WebCore/page/scrolling/ScrollingTreeNode.h
Source/WebCore/page/scrolling/ScrollingTreeScrollingNode.cpp
Source/WebCore/page/scrolling/ScrollingTreeScrollingNode.h
Source/WebCore/page/scrolling/ScrollingTreeScrollingNodeDelegate.cpp
Source/WebCore/page/scrolling/ScrollingTreeScrollingNodeDelegate.h
Source/WebCore/page/scrolling/mac/ScrollingTreeFrameScrollingNodeMac.h
Source/WebCore/page/scrolling/mac/ScrollingTreeFrameScrollingNodeMac.mm
Source/WebCore/page/scrolling/mac/ScrollingTreeScrollingNodeDelegateMac.h [new file with mode: 0644]
Source/WebCore/page/scrolling/mac/ScrollingTreeScrollingNodeDelegateMac.mm [new file with mode: 0644]

index fa1ebfb..3cdfef7 100644 (file)
@@ -1,3 +1,110 @@
+2019-01-31  Simon Fraser  <simon.fraser@apple.com>
+
+        Generalize ScrollingTreeScrollingNodeDelegate for use in macOS too, add a macOS subclass for frame/overflow scrolling
+        https://bugs.webkit.org/show_bug.cgi?id=194080
+
+        Reviewed by Antti Koivisto.
+
+        To share code between ScrollingTreeFrameScrollingNodeMac and ScrollingTreeOverflowScrollingNodeMac, build ScrollingTreeScrollingNodeDelegate
+        for macOS too, and add some helper functions to ScrollingTreeScrollingNodeDelegate.
+
+        Add a macOS subclass, ScrollingTreeScrollingNodeDelegateMac, which takes over the basic scrolling, rubber-banding
+        and scroll snapping functionality from ScrollingTreeFrameScrollingNodeMac. The delegate owns the ScrollController and
+        implements ScrollControllerClient.
+
+        ScrollingTreeFrameScrollingNodeMac now owns a ScrollingTreeScrollingNodeDelegateMac. A future patch
+        will add one to ScrollingTreeOverflowScrollingNodeMac.
+
+        No behavior change.
+
+        * SourcesCocoa.txt:
+        * WebCore.xcodeproj/project.pbxproj:
+        * page/scrolling/ScrollingTreeFrameScrollingNode.cpp:
+        (WebCore::ScrollingTreeFrameScrollingNode::scrollBy): Deleted.
+        (WebCore::ScrollingTreeFrameScrollingNode::scrollByWithoutContentEdgeConstraints): Deleted.
+        * page/scrolling/ScrollingTreeFrameScrollingNode.h:
+        (WebCore::ScrollingTreeFrameScrollingNode::frameScaleFactor const):
+        * page/scrolling/ScrollingTreeNode.cpp:
+        (WebCore::ScrollingTreeNode::isRootNode const):
+        * page/scrolling/ScrollingTreeNode.h:
+        * page/scrolling/ScrollingTreeScrollingNode.cpp:
+        (WebCore::ScrollingTreeScrollingNode::commitStateBeforeChildren):
+        (WebCore::ScrollingTreeScrollingNode::scrollBy):
+        (WebCore::ScrollingTreeScrollingNode::scrollByWithoutContentEdgeConstraints):
+        * page/scrolling/ScrollingTreeScrollingNode.h:
+        (WebCore::ScrollingTreeScrollingNode::expectsWheelEventTestTrigger const):
+        * page/scrolling/ScrollingTreeScrollingNodeDelegate.cpp:
+        * page/scrolling/ScrollingTreeScrollingNodeDelegate.h:
+        (WebCore::ScrollingTreeScrollingNodeDelegate::scrollPosition const):
+        (WebCore::ScrollingTreeScrollingNodeDelegate::minimumScrollPosition const):
+        (WebCore::ScrollingTreeScrollingNodeDelegate::maximumScrollPosition const):
+        (WebCore::ScrollingTreeScrollingNodeDelegate::scrollableAreaSize const):
+        (WebCore::ScrollingTreeScrollingNodeDelegate::totalContentsSize const):
+        (WebCore::ScrollingTreeScrollingNodeDelegate::hasEnabledHorizontalScrollbar const):
+        (WebCore::ScrollingTreeScrollingNodeDelegate::hasEnabledVerticalScrollbar const):
+        (WebCore::ScrollingTreeScrollingNodeDelegate::horizontalScrollElasticity const):
+        (WebCore::ScrollingTreeScrollingNodeDelegate::verticalScrollElasticity const):
+        * page/scrolling/mac/ScrollingTreeFrameScrollingNodeMac.h:
+        * page/scrolling/mac/ScrollingTreeFrameScrollingNodeMac.mm:
+        (WebCore::ScrollingTreeFrameScrollingNodeMac::ScrollingTreeFrameScrollingNodeMac):
+        (WebCore::ScrollingTreeFrameScrollingNodeMac::commitStateBeforeChildren):
+        (WebCore::ScrollingTreeFrameScrollingNodeMac::handleWheelEvent):
+        (WebCore::ScrollingTreeFrameScrollingNodeMac::minimumScrollPosition const):
+        (WebCore::ScrollingTreeFrameScrollingNodeMac::maximumScrollPosition const):
+        (WebCore::newGestureIsStarting): Deleted.
+        (WebCore::ScrollingTreeFrameScrollingNodeMac::isAlreadyPinnedInDirectionOfGesture): Deleted.
+        (WebCore::ScrollingTreeFrameScrollingNodeMac::allowsHorizontalStretching): Deleted.
+        (WebCore::ScrollingTreeFrameScrollingNodeMac::allowsVerticalStretching): Deleted.
+        (WebCore::ScrollingTreeFrameScrollingNodeMac::stretchAmount): Deleted.
+        (WebCore::ScrollingTreeFrameScrollingNodeMac::pinnedInDirection): Deleted.
+        (WebCore::ScrollingTreeFrameScrollingNodeMac::canScrollHorizontally): Deleted.
+        (WebCore::ScrollingTreeFrameScrollingNodeMac::canScrollVertically): Deleted.
+        (WebCore::ScrollingTreeFrameScrollingNodeMac::shouldRubberBandInDirection): Deleted.
+        (WebCore::ScrollingTreeFrameScrollingNodeMac::immediateScrollBy): Deleted.
+        (WebCore::ScrollingTreeFrameScrollingNodeMac::immediateScrollByWithoutContentEdgeConstraints): Deleted.
+        (WebCore::ScrollingTreeFrameScrollingNodeMac::stopSnapRubberbandTimer): Deleted.
+        (WebCore::ScrollingTreeFrameScrollingNodeMac::adjustScrollPositionToBoundsIfNecessary): Deleted.
+        (WebCore::ScrollingTreeFrameScrollingNodeMac::scrollOffset const): Deleted.
+        (WebCore::ScrollingTreeFrameScrollingNodeMac::immediateScrollOnAxis): Deleted.
+        (WebCore::ScrollingTreeFrameScrollingNodeMac::pageScaleFactor const): Deleted.
+        (WebCore::ScrollingTreeFrameScrollingNodeMac::startScrollSnapTimer): Deleted.
+        (WebCore::ScrollingTreeFrameScrollingNodeMac::stopScrollSnapTimer): Deleted.
+        (WebCore::ScrollingTreeFrameScrollingNodeMac::scrollExtent const): Deleted.
+        (WebCore::ScrollingTreeFrameScrollingNodeMac::viewportSize const): Deleted.
+        (WebCore::ScrollingTreeFrameScrollingNodeMac::deferTestsForReason const): Deleted.
+        (WebCore::ScrollingTreeFrameScrollingNodeMac::removeTestDeferralForReason const): Deleted.
+        * page/scrolling/mac/ScrollingTreeScrollingNodeDelegateMac.h: Copied from Source/WebCore/page/scrolling/mac/ScrollingTreeFrameScrollingNodeMac.h.
+        * page/scrolling/mac/ScrollingTreeScrollingNodeDelegateMac.mm: Added.
+        (WebCore::ScrollingTreeScrollingNodeDelegateMac::ScrollingTreeScrollingNodeDelegateMac):
+        (WebCore::ScrollingTreeScrollingNodeDelegateMac::updateScrollSnapPoints):
+        (WebCore::ScrollingTreeScrollingNodeDelegateMac::setActiveScrollSnapIndexForAxis):
+        (WebCore::ScrollingTreeScrollingNodeDelegateMac::activeScrollSnapIndexForAxis const):
+        (WebCore::ScrollingTreeScrollingNodeDelegateMac::activeScrollSnapIndexDidChange const):
+        (WebCore::ScrollingTreeScrollingNodeDelegateMac::handleWheelEvent):
+        (WebCore::ScrollingTreeScrollingNodeDelegateMac::isScrollSnapInProgress const):
+        (WebCore::newGestureIsStarting):
+        (WebCore::ScrollingTreeScrollingNodeDelegateMac::isAlreadyPinnedInDirectionOfGesture):
+        (WebCore::ScrollingTreeScrollingNodeDelegateMac::allowsHorizontalStretching):
+        (WebCore::ScrollingTreeScrollingNodeDelegateMac::allowsVerticalStretching):
+        (WebCore::ScrollingTreeScrollingNodeDelegateMac::stretchAmount):
+        (WebCore::ScrollingTreeScrollingNodeDelegateMac::pinnedInDirection):
+        (WebCore::ScrollingTreeScrollingNodeDelegateMac::canScrollHorizontally):
+        (WebCore::ScrollingTreeScrollingNodeDelegateMac::canScrollVertically):
+        (WebCore::ScrollingTreeScrollingNodeDelegateMac::shouldRubberBandInDirection):
+        (WebCore::ScrollingTreeScrollingNodeDelegateMac::immediateScrollBy):
+        (WebCore::ScrollingTreeScrollingNodeDelegateMac::immediateScrollByWithoutContentEdgeConstraints):
+        (WebCore::ScrollingTreeScrollingNodeDelegateMac::stopSnapRubberbandTimer):
+        (WebCore::ScrollingTreeScrollingNodeDelegateMac::adjustScrollPositionToBoundsIfNecessary):
+        (WebCore::ScrollingTreeScrollingNodeDelegateMac::scrollOffset const):
+        (WebCore::ScrollingTreeScrollingNodeDelegateMac::immediateScrollOnAxis):
+        (WebCore::ScrollingTreeScrollingNodeDelegateMac::pageScaleFactor const):
+        (WebCore::ScrollingTreeScrollingNodeDelegateMac::startScrollSnapTimer):
+        (WebCore::ScrollingTreeScrollingNodeDelegateMac::stopScrollSnapTimer):
+        (WebCore::ScrollingTreeScrollingNodeDelegateMac::scrollExtent const):
+        (WebCore::ScrollingTreeScrollingNodeDelegateMac::viewportSize const):
+        (WebCore::ScrollingTreeScrollingNodeDelegateMac::deferTestsForReason const):
+        (WebCore::ScrollingTreeScrollingNodeDelegateMac::removeTestDeferralForReason const):
+
 2019-01-31  Jer Noble  <jer.noble@apple.com>
 
         [Mac] Requesting PiP from two different WebViews gets PiP window "stuck"
index c24185f..5a00d12 100644 (file)
@@ -158,6 +158,7 @@ page/scrolling/mac/ScrollingThreadMac.mm
 page/scrolling/mac/ScrollingTreeFixedNode.mm
 page/scrolling/mac/ScrollingTreeFrameScrollingNodeMac.mm
 page/scrolling/mac/ScrollingTreeOverflowScrollingNodeMac.mm
+page/scrolling/mac/ScrollingTreeScrollingNodeDelegateMac.mm
 page/scrolling/mac/ScrollingTreeMac.cpp
 page/scrolling/mac/ScrollingTreeStickyNode.mm
 
index 88cf902..dd9174d 100644 (file)
                0F15DA8A0F3AAEE70000CE47 /* CSSAnimationControllerPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F15DA890F3AAEE70000CE47 /* CSSAnimationControllerPrivate.h */; };
                0F15ED5C1B7EC7C500EDDFEB /* WillChangeData.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F15ED5A1B7EC7C500EDDFEB /* WillChangeData.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0F1774801378B772009DA76A /* ScrollAnimatorIOS.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F17747E1378B771009DA76A /* ScrollAnimatorIOS.h */; };
+               0F37F0852202BF9800A89C0B /* ScrollingTreeScrollingNodeDelegateMac.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F37F0842202ACB700A89C0B /* ScrollingTreeScrollingNodeDelegateMac.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0F3DD45012F5EA1B000D9190 /* ShadowBlur.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F3DD44E12F5EA1B000D9190 /* ShadowBlur.h */; };
                0F3F0E5A157030C3006DA57F /* RenderGeometryMap.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F3F0E58157030C3006DA57F /* RenderGeometryMap.h */; };
                0F4710AF1DB56AFC002DCEC3 /* DOMRect.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F4710A91DB56AFC002DCEC3 /* DOMRect.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0F26A7AD205626100090A141 /* SVGUnknownElement.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SVGUnknownElement.cpp; sourceTree = "<group>"; };
                0F36E7361BD1837A002DB891 /* LayoutPoint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LayoutPoint.cpp; sourceTree = "<group>"; };
                0F36E7381BD184B9002DB891 /* LayoutSize.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LayoutSize.cpp; sourceTree = "<group>"; };
+               0F37F0832202AC8F00A89C0B /* ScrollingTreeScrollingNodeDelegateMac.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = ScrollingTreeScrollingNodeDelegateMac.mm; sourceTree = "<group>"; };
+               0F37F0842202ACB700A89C0B /* ScrollingTreeScrollingNodeDelegateMac.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ScrollingTreeScrollingNodeDelegateMac.h; sourceTree = "<group>"; };
                0F3DD44D12F5EA1B000D9190 /* ShadowBlur.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ShadowBlur.cpp; sourceTree = "<group>"; };
                0F3DD44E12F5EA1B000D9190 /* ShadowBlur.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ShadowBlur.h; sourceTree = "<group>"; };
                0F3F0E57157030C3006DA57F /* RenderGeometryMap.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RenderGeometryMap.cpp; sourceTree = "<group>"; };
                                0FE5806219327A6200DE32EB /* ScrollingTreeMac.h */,
                                0FC0516A219B5EBE0031C39E /* ScrollingTreeOverflowScrollingNodeMac.h */,
                                0FC05168219B5EBE0031C39E /* ScrollingTreeOverflowScrollingNodeMac.mm */,
+                               0F37F0842202ACB700A89C0B /* ScrollingTreeScrollingNodeDelegateMac.h */,
+                               0F37F0832202AC8F00A89C0B /* ScrollingTreeScrollingNodeDelegateMac.mm */,
                                0FB88908167D2FA10010CDA5 /* ScrollingTreeStickyNode.h */,
                                0FB88909167D2FA10010CDA5 /* ScrollingTreeStickyNode.mm */,
                        );
                                0FEA3E80191B3169000F1B55 /* ScrollingTreeOverflowScrollingNode.h in Headers */,
                                9391A99D1629D70000297330 /* ScrollingTreeScrollingNode.h in Headers */,
                                A6D5A99D1629D70000297330 /* ScrollingTreeScrollingNodeDelegate.h in Headers */,
+                               0F37F0852202BF9800A89C0B /* ScrollingTreeScrollingNodeDelegateMac.h in Headers */,
                                0FB8890A167D2FA10010CDA5 /* ScrollingTreeStickyNode.h in Headers */,
                                83C5795D1DA5C301006F9C97 /* ScrollIntoViewOptions.h in Headers */,
                                7AAFE8D019CB8672000F56D8 /* ScrollLatchingState.h in Headers */,
index d0a9fb5..258bb93 100644 (file)
@@ -82,16 +82,6 @@ void ScrollingTreeFrameScrollingNode::commitStateBeforeChildren(const ScrollingS
         m_maxLayoutViewportOrigin = state.maxLayoutViewportOrigin();
 }
 
-void ScrollingTreeFrameScrollingNode::scrollBy(const FloatSize& delta)
-{
-    setScrollPosition(scrollPosition() + delta);
-}
-
-void ScrollingTreeFrameScrollingNode::scrollByWithoutContentEdgeConstraints(const FloatSize& offset)
-{
-    setScrollPositionWithoutContentEdgeConstraints(scrollPosition() + offset);
-}
-
 void ScrollingTreeFrameScrollingNode::setScrollPosition(const FloatPoint& scrollPosition)
 {
     FloatPoint newScrollPosition = scrollPosition.constrainedBetween(minimumScrollPosition(), maximumScrollPosition());
index 18c913f..d09f048 100644 (file)
@@ -60,13 +60,11 @@ public:
 
     FloatRect fixedPositionRect() { return FloatRect(lastCommittedScrollPosition(), scrollableAreaSize()); };
 
+    float frameScaleFactor() const { return m_frameScaleFactor; }
+
 protected:
     ScrollingTreeFrameScrollingNode(ScrollingTree&, ScrollingNodeType, ScrollingNodeID);
 
-    void scrollBy(const FloatSize&);
-    void scrollByWithoutContentEdgeConstraints(const FloatSize&);
-
-    float frameScaleFactor() const { return m_frameScaleFactor; }
     int headerHeight() const { return m_headerHeight; }
     int footerHeight() const { return m_footerHeight; }
     float topContentInset() const { return m_topContentInset; }
index 5855d5e..d857513 100644 (file)
@@ -29,6 +29,7 @@
 #if ENABLE(ASYNC_SCROLLING)
 
 #include "ScrollingStateTree.h"
+#include "ScrollingTree.h"
 #include "ScrollingTreeFrameScrollingNode.h"
 #include <wtf/text/TextStream.h>
 
@@ -71,6 +72,11 @@ void ScrollingTreeNode::removeChild(ScrollingTreeNode& node)
         child->removeChild(node);
 }
 
+bool ScrollingTreeNode::isRootNode() const
+{
+    return m_scrollingTree.rootNode() == this;
+}
+
 void ScrollingTreeNode::dumpProperties(TextStream& ts, ScrollingStateTreeAsTextBehavior behavior) const
 {
     if (behavior & ScrollingStateTreeAsTextBehaviorIncludeNodeIDs)
index b5096ab..6754a27 100644 (file)
@@ -38,7 +38,6 @@
 namespace WebCore {
 
 class ScrollingStateFixedNode;
-class ScrollingStateScrollingNode;
 class ScrollingTreeFrameScrollingNode;
 class ScrollingTreeScrollingNode;
 
@@ -63,6 +62,8 @@ public:
 
     ScrollingTreeNode* parent() const { return m_parent; }
     void setParent(ScrollingTreeNode* parent) { m_parent = parent; }
+    
+    bool isRootNode() const;
 
     Vector<RefPtr<ScrollingTreeNode>>* children() { return m_children.get(); }
     const Vector<RefPtr<ScrollingTreeNode>>* children() const { return m_children.get(); }
index dcc96f1..642f110 100644 (file)
@@ -93,6 +93,9 @@ void ScrollingTreeScrollingNode::commitStateBeforeChildren(const ScrollingStateN
 
     if (state.hasChangedProperty(ScrollingStateScrollingNode::ScrollableAreaParams))
         m_scrollableAreaParameters = state.scrollableAreaParameters();
+
+    if (state.hasChangedProperty(ScrollingStateScrollingNode::ExpectsWheelEventTestTrigger))
+        m_expectsWheelEventTestTrigger = state.expectsWheelEventTestTrigger();
 }
 
 void ScrollingTreeScrollingNode::commitStateAfterChildren(const ScrollingStateNode& stateNode)
@@ -142,6 +145,16 @@ bool ScrollingTreeScrollingNode::scrollLimitReached(const PlatformWheelEvent& wh
     return newScrollPosition == oldScrollPosition;
 }
 
+void ScrollingTreeScrollingNode::scrollBy(const FloatSize& delta)
+{
+    setScrollPosition(scrollPosition() + delta);
+}
+
+void ScrollingTreeScrollingNode::scrollByWithoutContentEdgeConstraints(const FloatSize& offset)
+{
+    setScrollPositionWithoutContentEdgeConstraints(scrollPosition() + offset);
+}
+
 LayoutPoint ScrollingTreeScrollingNode::parentToLocalPoint(LayoutPoint point) const
 {
     return point - toLayoutSize(parentRelativeScrollableRect().location());
index f652b2d..b8f6568 100644 (file)
 #include "ScrollingCoordinator.h"
 #include "ScrollingTreeNode.h"
 
-#if PLATFORM(IOS_FAMILY)
-class ScrollingTreeScrollingNodeDelegate;
-#endif
-
 namespace WebCore {
 
 class ScrollingTree;
 class ScrollingStateScrollingNode;
 
 class ScrollingTreeScrollingNode : public ScrollingTreeNode {
-#if PLATFORM(IOS_FAMILY)
     friend class ScrollingTreeScrollingNodeDelegate;
+#if PLATFORM(MAC)
+    friend class ScrollingTreeScrollingNodeDelegateMac;
 #endif
 
 public:
@@ -59,6 +56,9 @@ public:
     WEBCORE_EXPORT virtual void setScrollPosition(const FloatPoint&);
     WEBCORE_EXPORT virtual void setScrollPositionWithoutContentEdgeConstraints(const FloatPoint&);
 
+    void scrollBy(const FloatSize&);
+    void scrollByWithoutContentEdgeConstraints(const FloatSize&);
+
     virtual void updateLayersAfterViewportChange(const FloatRect& fixedPositionRect, double scale) = 0;
     virtual void updateLayersAfterDelegatedScroll(const FloatPoint&) { }
 
@@ -109,6 +109,8 @@ protected:
 
     bool canHaveScrollbars() const { return m_scrollableAreaParameters.horizontalScrollbarMode != ScrollbarAlwaysOff || m_scrollableAreaParameters.verticalScrollbarMode != ScrollbarAlwaysOff; }
 
+    bool expectsWheelEventTestTrigger() const { return m_expectsWheelEventTestTrigger; }
+
     WEBCORE_EXPORT LayoutPoint parentToLocalPoint(LayoutPoint) const override;
     WEBCORE_EXPORT LayoutPoint localToContentsPoint(LayoutPoint) const override;
 
@@ -128,6 +130,7 @@ private:
     unsigned m_currentVerticalSnapPointIndex { 0 };
 #endif
     ScrollableAreaParameters m_scrollableAreaParameters;
+    bool m_expectsWheelEventTestTrigger { false };
 };
 
 } // namespace WebCore
index b3e4788..97332cc 100644 (file)
@@ -26,7 +26,7 @@
 #import "config.h"
 #import "ScrollingTreeScrollingNodeDelegate.h"
 
-#if PLATFORM(IOS_FAMILY) && ENABLE(ASYNC_SCROLLING)
+#if ENABLE(ASYNC_SCROLLING)
 
 #import "ScrollingTreeScrollingNode.h"
 
@@ -66,4 +66,4 @@ const IntPoint& ScrollingTreeScrollingNodeDelegate::scrollOrigin() const
 
 } // namespace WebCore
 
-#endif // PLATFORM(IOS_FAMILY) && ENABLE(ASYNC_SCROLLING)
+#endif // ENABLE(ASYNC_SCROLLING)
index 78ccc01..4a15a2e 100644 (file)
 
 #pragma once
 
-#if PLATFORM(IOS_FAMILY) && ENABLE(ASYNC_SCROLLING)
+#if ENABLE(ASYNC_SCROLLING)
 
-namespace WebCore {
+#include "ScrollingTreeScrollingNode.h"
 
-class FloatPoint;
-class FloatSize;
-class IntPoint;
-class ScrollingTreeScrollingNode;
-class ScrollingTree;
+namespace WebCore {
 
 class ScrollingTreeScrollingNodeDelegate {
 public:
     WEBCORE_EXPORT explicit ScrollingTreeScrollingNodeDelegate(ScrollingTreeScrollingNode&);
     WEBCORE_EXPORT virtual ~ScrollingTreeScrollingNodeDelegate();
+
     ScrollingTreeScrollingNode& scrollingNode() { return m_scrollingNode; }
     const ScrollingTreeScrollingNode& scrollingNode() const { return m_scrollingNode; }
 
@@ -49,10 +46,23 @@ protected:
     WEBCORE_EXPORT const FloatSize& reachableContentsSize();
     WEBCORE_EXPORT const IntPoint& scrollOrigin() const;
 
+    FloatPoint scrollPosition() const { return m_scrollingNode.scrollPosition(); }
+    FloatPoint minimumScrollPosition() const { return m_scrollingNode.minimumScrollPosition(); }
+    FloatPoint maximumScrollPosition() const { return m_scrollingNode.maximumScrollPosition(); }
+
+    FloatSize scrollableAreaSize() const { return m_scrollingNode.scrollableAreaSize(); }
+    FloatSize totalContentsSize() const { return m_scrollingNode.totalContentsSize(); }
+
+    bool hasEnabledHorizontalScrollbar() const { return m_scrollingNode.hasEnabledHorizontalScrollbar(); }
+    bool hasEnabledVerticalScrollbar() const { return m_scrollingNode.hasEnabledVerticalScrollbar(); }
+
+    ScrollElasticity horizontalScrollElasticity() const { return m_scrollingNode.horizontalScrollElasticity(); }
+    ScrollElasticity verticalScrollElasticity() const { return m_scrollingNode.verticalScrollElasticity(); }
+
 private:
     ScrollingTreeScrollingNode& m_scrollingNode;
 };
 
 } // namespace WebCore
 
-#endif // PLATFORM(IOS_FAMILY) && ENABLE(ASYNC_SCROLLING)
+#endif // ENABLE(ASYNC_SCROLLING)
index 73d0be7..01194fb 100644 (file)
 
 #if ENABLE(ASYNC_SCROLLING) && PLATFORM(MAC)
 
-#include "ScrollController.h"
 #include "ScrollbarThemeMac.h"
 #include "ScrollingStateFrameScrollingNode.h"
 #include "ScrollingTreeFrameScrollingNode.h"
+#include "ScrollingTreeScrollingNodeDelegateMac.h"
 #include <wtf/RetainPtr.h>
 
 OBJC_CLASS CALayer;
 
 namespace WebCore {
 
-class WEBCORE_EXPORT ScrollingTreeFrameScrollingNodeMac : public ScrollingTreeFrameScrollingNode, private ScrollControllerClient {
+class WEBCORE_EXPORT ScrollingTreeFrameScrollingNodeMac : public ScrollingTreeFrameScrollingNode {
 public:
     static Ref<ScrollingTreeFrameScrollingNode> create(ScrollingTree&, ScrollingNodeType, ScrollingNodeID);
     virtual ~ScrollingTreeFrameScrollingNodeMac();
@@ -53,19 +53,6 @@ protected:
 
     ScrollingEventResult handleWheelEvent(const PlatformWheelEvent&) override;
 
-    // ScrollController member functions.
-    bool allowsHorizontalStretching(const PlatformWheelEvent&) override;
-    bool allowsVerticalStretching(const PlatformWheelEvent&) override;
-    IntSize stretchAmount() override;
-    bool pinnedInDirection(const FloatSize&) override;
-    bool canScrollHorizontally() override;
-    bool canScrollVertically() override;
-    bool shouldRubberBandInDirection(ScrollDirection) override;
-    void immediateScrollBy(const FloatSize&) override;
-    void immediateScrollByWithoutContentEdgeConstraints(const FloatSize&) override;
-    void stopSnapRubberbandTimer() override;
-    void adjustScrollPositionToBoundsIfNecessary() override;
-
     FloatPoint scrollPosition() const override;
     void setScrollPosition(const FloatPoint&) override;
     void setScrollPositionWithoutContentEdgeConstraints(const FloatPoint&) override;
@@ -79,26 +66,9 @@ protected:
 
     void updateMainFramePinState(const FloatPoint& scrollPosition);
 
-    bool isAlreadyPinnedInDirectionOfGesture(const PlatformWheelEvent&, ScrollEventAxis);
-
-    void deferTestsForReason(WheelEventTestTrigger::ScrollableAreaIdentifier, WheelEventTestTrigger::DeferTestTriggerReason) const override;
-    void removeTestDeferralForReason(WheelEventTestTrigger::ScrollableAreaIdentifier, WheelEventTestTrigger::DeferTestTriggerReason) const override;
-
-#if ENABLE(CSS_SCROLL_SNAP) && PLATFORM(MAC)
-    FloatPoint scrollOffset() const override;
-    void immediateScrollOnAxis(ScrollEventAxis, float delta) override;
-    float pageScaleFactor() const override;
-    void startScrollSnapTimer() override;
-    void stopScrollSnapTimer() override;
-    LayoutSize scrollExtent() const override;
-    FloatSize viewportSize() const override;
-#endif
-
     unsigned exposedUnfilledArea() const;
 
 private:
-    ScrollController m_scrollController;
-
     RetainPtr<CALayer> m_scrollLayer;
     RetainPtr<CALayer> m_rootContentsLayer;
     RetainPtr<CALayer> m_counterScrollingLayer;
@@ -109,9 +79,11 @@ private:
     RetainPtr<NSScrollerImp> m_verticalScrollerImp;
     RetainPtr<NSScrollerImp> m_horizontalScrollerImp;
     FloatPoint m_probableMainThreadScrollPosition;
+    
+    ScrollingTreeScrollingNodeDelegateMac m_delegate;
+    
     bool m_lastScrollHadUnfilledPixels { false };
     bool m_hadFirstUpdate { false };
-    bool m_expectsWheelEventTestTrigger { false };
 };
 
 } // namespace WebCore
index 6b2efb0..916fe72 100644 (file)
@@ -54,9 +54,7 @@ Ref<ScrollingTreeFrameScrollingNode> ScrollingTreeFrameScrollingNodeMac::create(
 
 ScrollingTreeFrameScrollingNodeMac::ScrollingTreeFrameScrollingNodeMac(ScrollingTree& scrollingTree, ScrollingNodeType nodeType, ScrollingNodeID nodeID)
     : ScrollingTreeFrameScrollingNode(scrollingTree, nodeType, nodeID)
-    , m_scrollController(*this)
-    , m_verticalScrollerImp(nullptr)
-    , m_horizontalScrollerImp(nullptr)
+    , m_delegate(*this)
 {
 }
 
@@ -150,21 +148,18 @@ void ScrollingTreeFrameScrollingNodeMac::commitStateBeforeChildren(const Scrolli
 
 #if ENABLE(CSS_SCROLL_SNAP)
     if (scrollingStateNode.hasChangedProperty(ScrollingStateFrameScrollingNode::HorizontalSnapOffsets) || scrollingStateNode.hasChangedProperty(ScrollingStateFrameScrollingNode::HorizontalSnapOffsetRanges))
-        m_scrollController.updateScrollSnapPoints(ScrollEventAxis::Horizontal, convertToLayoutUnits(scrollingStateNode.horizontalSnapOffsets()), convertToLayoutUnits(scrollingStateNode.horizontalSnapOffsetRanges()));
+        m_delegate.updateScrollSnapPoints(ScrollEventAxis::Horizontal, convertToLayoutUnits(scrollingStateNode.horizontalSnapOffsets()), convertToLayoutUnits(scrollingStateNode.horizontalSnapOffsetRanges()));
 
     if (scrollingStateNode.hasChangedProperty(ScrollingStateFrameScrollingNode::VerticalSnapOffsets) || scrollingStateNode.hasChangedProperty(ScrollingStateFrameScrollingNode::VerticalSnapOffsetRanges))
-        m_scrollController.updateScrollSnapPoints(ScrollEventAxis::Vertical, convertToLayoutUnits(scrollingStateNode.verticalSnapOffsets()), convertToLayoutUnits(scrollingStateNode.verticalSnapOffsetRanges()));
+        m_delegate.updateScrollSnapPoints(ScrollEventAxis::Vertical, convertToLayoutUnits(scrollingStateNode.verticalSnapOffsets()), convertToLayoutUnits(scrollingStateNode.verticalSnapOffsetRanges()));
 
     if (scrollingStateNode.hasChangedProperty(ScrollingStateScrollingNode::CurrentHorizontalSnapOffsetIndex))
-        m_scrollController.setActiveScrollSnapIndexForAxis(ScrollEventAxis::Horizontal, scrollingStateNode.currentHorizontalSnapPointIndex());
+        m_delegate.setActiveScrollSnapIndexForAxis(ScrollEventAxis::Horizontal, scrollingStateNode.currentHorizontalSnapPointIndex());
     
     if (scrollingStateNode.hasChangedProperty(ScrollingStateScrollingNode::CurrentVerticalSnapOffsetIndex))
-        m_scrollController.setActiveScrollSnapIndexForAxis(ScrollEventAxis::Vertical, scrollingStateNode.currentVerticalSnapPointIndex());
+        m_delegate.setActiveScrollSnapIndexForAxis(ScrollEventAxis::Vertical, scrollingStateNode.currentVerticalSnapPointIndex());
 #endif
 
-    if (scrollingStateNode.hasChangedProperty(ScrollingStateScrollingNode::ExpectsWheelEventTestTrigger))
-        m_expectsWheelEventTestTrigger = scrollingStateNode.expectsWheelEventTestTrigger();
-
     m_hadFirstUpdate = true;
 }
 
@@ -199,19 +194,20 @@ ScrollingEventResult ScrollingTreeFrameScrollingNodeMac::handleWheelEvent(const
     }
 
 #if ENABLE(CSS_SCROLL_SNAP) || ENABLE(RUBBER_BANDING)
-    if (m_expectsWheelEventTestTrigger) {
+    if (expectsWheelEventTestTrigger()) {
         if (scrollingTree().shouldHandleWheelEventSynchronously(wheelEvent))
-            removeTestDeferralForReason(reinterpret_cast<WheelEventTestTrigger::ScrollableAreaIdentifier>(scrollingNodeID()), WheelEventTestTrigger::ScrollingThreadSyncNeeded);
+            m_delegate.removeTestDeferralForReason(reinterpret_cast<WheelEventTestTrigger::ScrollableAreaIdentifier>(scrollingNodeID()), WheelEventTestTrigger::ScrollingThreadSyncNeeded);
         else
-            deferTestsForReason(reinterpret_cast<WheelEventTestTrigger::ScrollableAreaIdentifier>(scrollingNodeID()), WheelEventTestTrigger::ScrollingThreadSyncNeeded);
+            m_delegate.deferTestsForReason(reinterpret_cast<WheelEventTestTrigger::ScrollableAreaIdentifier>(scrollingNodeID()), WheelEventTestTrigger::ScrollingThreadSyncNeeded);
     }
 #endif
 
-    m_scrollController.handleWheelEvent(wheelEvent);
+    m_delegate.handleWheelEvent(wheelEvent);
+
 #if ENABLE(CSS_SCROLL_SNAP)
-    scrollingTree().setMainFrameIsScrollSnapping(m_scrollController.isScrollSnapInProgress());
-    if (m_scrollController.activeScrollSnapIndexDidChange())
-        scrollingTree().setActiveScrollSnapIndices(scrollingNodeID(), m_scrollController.activeScrollSnapIndexForAxis(ScrollEventAxis::Horizontal), m_scrollController.activeScrollSnapIndexForAxis(ScrollEventAxis::Vertical));
+    scrollingTree().setMainFrameIsScrollSnapping(m_delegate.isScrollSnapInProgress());
+    if (m_delegate.activeScrollSnapIndexDidChange())
+        scrollingTree().setActiveScrollSnapIndices(scrollingNodeID(), m_delegate.activeScrollSnapIndexForAxis(ScrollEventAxis::Horizontal), m_delegate.activeScrollSnapIndexForAxis(ScrollEventAxis::Vertical));
 #endif
     scrollingTree().setOrClearLatchedNode(wheelEvent, scrollingNodeID());
     scrollingTree().handleWheelEventPhase(wheelEvent.phase());
@@ -220,154 +216,6 @@ ScrollingEventResult ScrollingTreeFrameScrollingNodeMac::handleWheelEvent(const
     return ScrollingEventResult::DidHandleEvent;
 }
 
-// FIXME: We should find a way to share some of the code from newGestureIsStarting(), isAlreadyPinnedInDirectionOfGesture(),
-// allowsVerticalStretching(), and allowsHorizontalStretching() with the implementation in ScrollAnimatorMac.
-static bool newGestureIsStarting(const PlatformWheelEvent& wheelEvent)
-{
-    return wheelEvent.phase() == PlatformWheelEventPhaseMayBegin || wheelEvent.phase() == PlatformWheelEventPhaseBegan;
-}
-
-bool ScrollingTreeFrameScrollingNodeMac::isAlreadyPinnedInDirectionOfGesture(const PlatformWheelEvent& wheelEvent, ScrollEventAxis axis)
-{
-    switch (axis) {
-    case ScrollEventAxis::Vertical:
-        return (wheelEvent.deltaY() > 0 && scrollPosition().y() <= minimumScrollPosition().y()) || (wheelEvent.deltaY() < 0 && scrollPosition().y() >= maximumScrollPosition().y());
-    case ScrollEventAxis::Horizontal:
-        return (wheelEvent.deltaX() > 0 && scrollPosition().x() <= minimumScrollPosition().x()) || (wheelEvent.deltaX() < 0 && scrollPosition().x() >= maximumScrollPosition().x());
-    }
-
-    ASSERT_NOT_REACHED();
-    return false;
-}
-
-bool ScrollingTreeFrameScrollingNodeMac::allowsHorizontalStretching(const PlatformWheelEvent& wheelEvent)
-{
-    switch (horizontalScrollElasticity()) {
-    case ScrollElasticityAutomatic: {
-        bool scrollbarsAllowStretching = hasEnabledHorizontalScrollbar() || !hasEnabledVerticalScrollbar();
-        bool eventPreventsStretching = newGestureIsStarting(wheelEvent) && isAlreadyPinnedInDirectionOfGesture(wheelEvent, ScrollEventAxis::Horizontal);
-        return scrollbarsAllowStretching && !eventPreventsStretching;
-    }
-    case ScrollElasticityNone:
-        return false;
-    case ScrollElasticityAllowed:
-        return true;
-    }
-
-    ASSERT_NOT_REACHED();
-    return false;
-}
-
-bool ScrollingTreeFrameScrollingNodeMac::allowsVerticalStretching(const PlatformWheelEvent& wheelEvent)
-{
-    switch (verticalScrollElasticity()) {
-    case ScrollElasticityAutomatic: {
-        bool scrollbarsAllowStretching = hasEnabledVerticalScrollbar() || !hasEnabledHorizontalScrollbar();
-        bool eventPreventsStretching = newGestureIsStarting(wheelEvent) && isAlreadyPinnedInDirectionOfGesture(wheelEvent, ScrollEventAxis::Vertical);
-        return scrollbarsAllowStretching && !eventPreventsStretching;
-    }
-    case ScrollElasticityNone:
-        return false;
-    case ScrollElasticityAllowed:
-        return true;
-    }
-
-    ASSERT_NOT_REACHED();
-    return false;
-}
-
-IntSize ScrollingTreeFrameScrollingNodeMac::stretchAmount()
-{
-    IntSize stretch;
-
-    if (scrollPosition().y() < minimumScrollPosition().y())
-        stretch.setHeight(scrollPosition().y() - minimumScrollPosition().y());
-    else if (scrollPosition().y() > maximumScrollPosition().y())
-        stretch.setHeight(scrollPosition().y() - maximumScrollPosition().y());
-
-    if (scrollPosition().x() < minimumScrollPosition().x())
-        stretch.setWidth(scrollPosition().x() - minimumScrollPosition().x());
-    else if (scrollPosition().x() > maximumScrollPosition().x())
-        stretch.setWidth(scrollPosition().x() - maximumScrollPosition().x());
-
-    if (scrollingTree().rootNode() == this) {
-        if (stretch.isZero())
-            scrollingTree().setMainFrameIsRubberBanding(false);
-        else
-            scrollingTree().setMainFrameIsRubberBanding(true);
-    }
-
-    return stretch;
-}
-
-bool ScrollingTreeFrameScrollingNodeMac::pinnedInDirection(const FloatSize& delta)
-{
-    FloatSize limitDelta;
-
-    if (fabsf(delta.height()) >= fabsf(delta.width())) {
-        if (delta.height() < 0) {
-            // We are trying to scroll up. Make sure we are not pinned to the top.
-            limitDelta.setHeight(scrollPosition().y() - minimumScrollPosition().y());
-        } else {
-            // We are trying to scroll down. Make sure we are not pinned to the bottom.
-            limitDelta.setHeight(maximumScrollPosition().y() - scrollPosition().y());
-        }
-    } else if (delta.width()) {
-        if (delta.width() < 0) {
-            // We are trying to scroll left. Make sure we are not pinned to the left.
-            limitDelta.setWidth(scrollPosition().x() - minimumScrollPosition().x());
-        } else {
-            // We are trying to scroll right. Make sure we are not pinned to the right.
-            limitDelta.setWidth(maximumScrollPosition().x() - scrollPosition().x());
-        }
-    }
-
-    if ((delta.width() || delta.height()) && (limitDelta.width() < 1 && limitDelta.height() < 1))
-        return true;
-
-    return false;
-}
-
-bool ScrollingTreeFrameScrollingNodeMac::canScrollHorizontally()
-{
-    return hasEnabledHorizontalScrollbar();
-}
-
-bool ScrollingTreeFrameScrollingNodeMac::canScrollVertically()
-{
-    return hasEnabledVerticalScrollbar();
-}
-
-bool ScrollingTreeFrameScrollingNodeMac::shouldRubberBandInDirection(ScrollDirection)
-{
-    return true;
-}
-
-void ScrollingTreeFrameScrollingNodeMac::immediateScrollBy(const FloatSize& delta)
-{
-    scrollBy(delta);
-}
-
-void ScrollingTreeFrameScrollingNodeMac::immediateScrollByWithoutContentEdgeConstraints(const FloatSize& offset)
-{
-    scrollByWithoutContentEdgeConstraints(offset);
-}
-
-void ScrollingTreeFrameScrollingNodeMac::stopSnapRubberbandTimer()
-{
-    scrollingTree().setMainFrameIsRubberBanding(false);
-
-    // Since the rubberband timer has stopped, totalContentsSizeForRubberBand can be synchronized with totalContentsSize.
-    setTotalContentsSizeForRubberBand(totalContentsSize());
-}
-
-void ScrollingTreeFrameScrollingNodeMac::adjustScrollPositionToBoundsIfNecessary()
-{
-    FloatPoint currentScrollPosition = scrollPosition();
-    FloatPoint constrainedPosition = currentScrollPosition.constrainedBetween(minimumScrollPosition(), maximumScrollPosition());
-    immediateScrollBy(constrainedPosition - currentScrollPosition);
-}
-
 FloatPoint ScrollingTreeFrameScrollingNodeMac::scrollPosition() const
 {
     if (shouldUpdateScrollLayerPositionSynchronously())
@@ -504,7 +352,7 @@ FloatPoint ScrollingTreeFrameScrollingNodeMac::minimumScrollPosition() const
 {
     FloatPoint position = ScrollableArea::scrollPositionFromOffset(FloatPoint(), toFloatSize(scrollOrigin()));
     
-    if (scrollingTree().rootNode() == this && scrollingTree().scrollPinningBehavior() == PinToBottom)
+    if (isRootNode() && scrollingTree().scrollPinningBehavior() == PinToBottom)
         position.setY(maximumScrollPosition().y());
 
     return position;
@@ -515,7 +363,7 @@ FloatPoint ScrollingTreeFrameScrollingNodeMac::maximumScrollPosition() const
     FloatPoint position = ScrollableArea::scrollPositionFromOffset(FloatPoint(totalContentsSizeForRubberBand() - scrollableAreaSize()), toFloatSize(scrollOrigin()));
     position = position.expandedTo(FloatPoint());
 
-    if (scrollingTree().rootNode() == this && scrollingTree().scrollPinningBehavior() == PinToTop)
+    if (isRootNode() && scrollingTree().scrollPinningBehavior() == PinToTop)
         position.setY(minimumScrollPosition().y());
 
     return position;
@@ -560,69 +408,6 @@ unsigned ScrollingTreeFrameScrollingNodeMac::exposedUnfilledArea() const
     return TileController::blankPixelCountForTiles(tiles, viewPortRect, IntPoint(-scrollPosition.x(), -scrollPosition.y()));
 }
 
-#if ENABLE(CSS_SCROLL_SNAP)
-FloatPoint ScrollingTreeFrameScrollingNodeMac::scrollOffset() const
-{
-    return scrollPosition();
-}
-
-void ScrollingTreeFrameScrollingNodeMac::immediateScrollOnAxis(ScrollEventAxis axis, float delta)
-{
-    const FloatPoint& currentPosition = scrollPosition();
-    FloatPoint change;
-    if (axis == ScrollEventAxis::Horizontal)
-        change = FloatPoint(currentPosition.x() + delta, currentPosition.y());
-    else
-        change = FloatPoint(currentPosition.x(), currentPosition.y() + delta);
-
-    immediateScrollBy(change - currentPosition);
-}
-
-float ScrollingTreeFrameScrollingNodeMac::pageScaleFactor() const
-{
-    return frameScaleFactor();
-}
-
-void ScrollingTreeFrameScrollingNodeMac::startScrollSnapTimer()
-{
-    scrollingTree().setMainFrameIsScrollSnapping(true);
-}
-
-void ScrollingTreeFrameScrollingNodeMac::stopScrollSnapTimer()
-{
-    scrollingTree().setMainFrameIsScrollSnapping(false);
-}
-    
-LayoutSize ScrollingTreeFrameScrollingNodeMac::scrollExtent() const
-{
-    return LayoutSize(totalContentsSize());
-}
-
-FloatSize ScrollingTreeFrameScrollingNodeMac::viewportSize() const
-{
-    return scrollableAreaSize();
-}
-
-#endif
-
-void ScrollingTreeFrameScrollingNodeMac::deferTestsForReason(WheelEventTestTrigger::ScrollableAreaIdentifier identifier, WheelEventTestTrigger::DeferTestTriggerReason reason) const
-{
-    if (!m_expectsWheelEventTestTrigger)
-        return;
-
-    LOG(WheelEventTestTriggers, "  ScrollingTreeFrameScrollingNodeMac::deferTestsForReason: STARTING deferral for %p because of %d", identifier, reason);
-    scrollingTree().deferTestsForReason(identifier, reason);
-}
-    
-void ScrollingTreeFrameScrollingNodeMac::removeTestDeferralForReason(WheelEventTestTrigger::ScrollableAreaIdentifier identifier, WheelEventTestTrigger::DeferTestTriggerReason reason) const
-{
-    if (!m_expectsWheelEventTestTrigger)
-        return;
-    
-    LOG(WheelEventTestTriggers, "   ScrollingTreeFrameScrollingNodeMac::deferTestsForReason: ENDING deferral for %p because of %d", identifier, reason);
-    scrollingTree().removeTestDeferralForReason(identifier, reason);
-}
-
 } // namespace WebCore
 
 #endif // ENABLE(ASYNC_SCROLLING) && PLATFORM(MAC)
diff --git a/Source/WebCore/page/scrolling/mac/ScrollingTreeScrollingNodeDelegateMac.h b/Source/WebCore/page/scrolling/mac/ScrollingTreeScrollingNodeDelegateMac.h
new file mode 100644 (file)
index 0000000..d1442cd
--- /dev/null
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2019 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "ScrollingTreeScrollingNodeDelegate.h"
+
+#if PLATFORM(MAC) && ENABLE(ASYNC_SCROLLING)
+
+#include "ScrollController.h"
+
+namespace WebCore {
+
+class FloatPoint;
+class FloatSize;
+class IntPoint;
+class ScrollingTreeScrollingNode;
+class ScrollingTree;
+
+class ScrollingTreeScrollingNodeDelegateMac : public ScrollingTreeScrollingNodeDelegate, private ScrollControllerClient {
+public:
+    explicit ScrollingTreeScrollingNodeDelegateMac(ScrollingTreeScrollingNode&);
+    virtual ~ScrollingTreeScrollingNodeDelegateMac();
+
+    bool handleWheelEvent(const PlatformWheelEvent&);
+
+#if ENABLE(CSS_SCROLL_SNAP)
+    void updateScrollSnapPoints(ScrollEventAxis, const Vector<LayoutUnit>&, const Vector<ScrollOffsetRange<LayoutUnit>>&);
+    void setActiveScrollSnapIndexForAxis(ScrollEventAxis, unsigned);
+    bool activeScrollSnapIndexDidChange() const;
+    unsigned activeScrollSnapIndexForAxis(ScrollEventAxis) const;
+    bool isScrollSnapInProgress() const;
+#endif
+
+    void deferTestsForReason(WheelEventTestTrigger::ScrollableAreaIdentifier, WheelEventTestTrigger::DeferTestTriggerReason) const override;
+    void removeTestDeferralForReason(WheelEventTestTrigger::ScrollableAreaIdentifier, WheelEventTestTrigger::DeferTestTriggerReason) const override;
+
+private:
+    bool isAlreadyPinnedInDirectionOfGesture(const PlatformWheelEvent&, ScrollEventAxis);
+
+    // ScrollControllerClient.
+    bool allowsHorizontalStretching(const PlatformWheelEvent&) override;
+    bool allowsVerticalStretching(const PlatformWheelEvent&) override;
+    IntSize stretchAmount() override;
+    bool pinnedInDirection(const FloatSize&) override;
+    bool canScrollHorizontally() override;
+    bool canScrollVertically() override;
+    bool shouldRubberBandInDirection(ScrollDirection) override;
+    void immediateScrollBy(const FloatSize&) override;
+    void immediateScrollByWithoutContentEdgeConstraints(const FloatSize&) override;
+    void stopSnapRubberbandTimer() override;
+    void adjustScrollPositionToBoundsIfNecessary() override;
+
+#if ENABLE(CSS_SCROLL_SNAP)
+    FloatPoint scrollOffset() const override;
+    void immediateScrollOnAxis(ScrollEventAxis, float delta) override;
+    float pageScaleFactor() const override;
+    void startScrollSnapTimer() override;
+    void stopScrollSnapTimer() override;
+    LayoutSize scrollExtent() const override;
+    FloatSize viewportSize() const override;
+#endif
+
+    ScrollController m_scrollController;
+};
+
+} // namespace WebCore
+
+#endif // PLATFORM(MAC) && ENABLE(ASYNC_SCROLLING)
diff --git a/Source/WebCore/page/scrolling/mac/ScrollingTreeScrollingNodeDelegateMac.mm b/Source/WebCore/page/scrolling/mac/ScrollingTreeScrollingNodeDelegateMac.mm
new file mode 100644 (file)
index 0000000..6823131
--- /dev/null
@@ -0,0 +1,293 @@
+/*
+ * Copyright (C) 2019 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#import "config.h"
+#import "ScrollingTreeScrollingNodeDelegateMac.h"
+
+#if PLATFORM(MAC) && ENABLE(ASYNC_SCROLLING)
+
+#import "Logging.h"
+#import "ScrollingTree.h"
+#import "ScrollingTreeFrameScrollingNode.h"
+#import "ScrollingTreeScrollingNode.h"
+
+namespace WebCore {
+
+ScrollingTreeScrollingNodeDelegateMac::ScrollingTreeScrollingNodeDelegateMac(ScrollingTreeScrollingNode& scrollingNode)
+    : ScrollingTreeScrollingNodeDelegate(scrollingNode)
+    , m_scrollController(*this)
+{
+}
+
+ScrollingTreeScrollingNodeDelegateMac::~ScrollingTreeScrollingNodeDelegateMac() = default;
+
+void ScrollingTreeScrollingNodeDelegateMac::updateScrollSnapPoints(ScrollEventAxis axis, const Vector<LayoutUnit>& snapOffsets, const Vector<ScrollOffsetRange<LayoutUnit>>& snapRanges)
+{
+    m_scrollController.updateScrollSnapPoints(axis, snapOffsets, snapRanges);
+}
+
+void ScrollingTreeScrollingNodeDelegateMac::setActiveScrollSnapIndexForAxis(ScrollEventAxis axis, unsigned index)
+{
+    m_scrollController.setActiveScrollSnapIndexForAxis(axis, index);
+}
+
+unsigned ScrollingTreeScrollingNodeDelegateMac::activeScrollSnapIndexForAxis(ScrollEventAxis axis) const
+{
+    return m_scrollController.activeScrollSnapIndexForAxis(axis);
+}
+
+bool ScrollingTreeScrollingNodeDelegateMac::activeScrollSnapIndexDidChange() const
+{
+    return m_scrollController.activeScrollSnapIndexDidChange();
+}
+
+bool ScrollingTreeScrollingNodeDelegateMac::handleWheelEvent(const PlatformWheelEvent& wheelEvent)
+{
+    return m_scrollController.handleWheelEvent(wheelEvent);
+}
+
+bool ScrollingTreeScrollingNodeDelegateMac::isScrollSnapInProgress() const
+{
+    return m_scrollController.isScrollSnapInProgress();
+}
+
+// FIXME: We should find a way to share some of the code from newGestureIsStarting(), isAlreadyPinnedInDirectionOfGesture(),
+// allowsVerticalStretching(), and allowsHorizontalStretching() with the implementation in ScrollAnimatorMac.
+static bool newGestureIsStarting(const PlatformWheelEvent& wheelEvent)
+{
+    return wheelEvent.phase() == PlatformWheelEventPhaseMayBegin || wheelEvent.phase() == PlatformWheelEventPhaseBegan;
+}
+
+bool ScrollingTreeScrollingNodeDelegateMac::isAlreadyPinnedInDirectionOfGesture(const PlatformWheelEvent& wheelEvent, ScrollEventAxis axis)
+{
+    switch (axis) {
+    case ScrollEventAxis::Vertical:
+        return (wheelEvent.deltaY() > 0 && scrollPosition().y() <= minimumScrollPosition().y()) || (wheelEvent.deltaY() < 0 && scrollPosition().y() >= maximumScrollPosition().y());
+    case ScrollEventAxis::Horizontal:
+        return (wheelEvent.deltaX() > 0 && scrollPosition().x() <= minimumScrollPosition().x()) || (wheelEvent.deltaX() < 0 && scrollPosition().x() >= maximumScrollPosition().x());
+    }
+
+    ASSERT_NOT_REACHED();
+    return false;
+}
+
+bool ScrollingTreeScrollingNodeDelegateMac::allowsHorizontalStretching(const PlatformWheelEvent& wheelEvent)
+{
+    switch (horizontalScrollElasticity()) {
+    case ScrollElasticityAutomatic: {
+        bool scrollbarsAllowStretching = hasEnabledHorizontalScrollbar() || !hasEnabledVerticalScrollbar();
+        bool eventPreventsStretching = newGestureIsStarting(wheelEvent) && isAlreadyPinnedInDirectionOfGesture(wheelEvent, ScrollEventAxis::Horizontal);
+        return scrollbarsAllowStretching && !eventPreventsStretching;
+    }
+    case ScrollElasticityNone:
+        return false;
+    case ScrollElasticityAllowed:
+        return true;
+    }
+
+    ASSERT_NOT_REACHED();
+    return false;
+}
+
+bool ScrollingTreeScrollingNodeDelegateMac::allowsVerticalStretching(const PlatformWheelEvent& wheelEvent)
+{
+    switch (verticalScrollElasticity()) {
+    case ScrollElasticityAutomatic: {
+        bool scrollbarsAllowStretching = hasEnabledVerticalScrollbar() || !hasEnabledHorizontalScrollbar();
+        bool eventPreventsStretching = newGestureIsStarting(wheelEvent) && isAlreadyPinnedInDirectionOfGesture(wheelEvent, ScrollEventAxis::Vertical);
+        return scrollbarsAllowStretching && !eventPreventsStretching;
+    }
+    case ScrollElasticityNone:
+        return false;
+    case ScrollElasticityAllowed:
+        return true;
+    }
+
+    ASSERT_NOT_REACHED();
+    return false;
+}
+
+IntSize ScrollingTreeScrollingNodeDelegateMac::stretchAmount()
+{
+    IntSize stretch;
+
+    if (scrollPosition().y() < minimumScrollPosition().y())
+        stretch.setHeight(scrollPosition().y() - minimumScrollPosition().y());
+    else if (scrollPosition().y() > maximumScrollPosition().y())
+        stretch.setHeight(scrollPosition().y() - maximumScrollPosition().y());
+
+    if (scrollPosition().x() < minimumScrollPosition().x())
+        stretch.setWidth(scrollPosition().x() - minimumScrollPosition().x());
+    else if (scrollPosition().x() > maximumScrollPosition().x())
+        stretch.setWidth(scrollPosition().x() - maximumScrollPosition().x());
+
+    if (scrollingNode().isRootNode()) {
+        if (stretch.isZero())
+            scrollingTree().setMainFrameIsRubberBanding(false);
+        else
+            scrollingTree().setMainFrameIsRubberBanding(true);
+    }
+
+    return stretch;
+}
+
+bool ScrollingTreeScrollingNodeDelegateMac::pinnedInDirection(const FloatSize& delta)
+{
+    FloatSize limitDelta;
+
+    if (fabsf(delta.height()) >= fabsf(delta.width())) {
+        if (delta.height() < 0) {
+            // We are trying to scroll up. Make sure we are not pinned to the top.
+            limitDelta.setHeight(scrollPosition().y() - minimumScrollPosition().y());
+        } else {
+            // We are trying to scroll down. Make sure we are not pinned to the bottom.
+            limitDelta.setHeight(maximumScrollPosition().y() - scrollPosition().y());
+        }
+    } else if (delta.width()) {
+        if (delta.width() < 0) {
+            // We are trying to scroll left. Make sure we are not pinned to the left.
+            limitDelta.setWidth(scrollPosition().x() - minimumScrollPosition().x());
+        } else {
+            // We are trying to scroll right. Make sure we are not pinned to the right.
+            limitDelta.setWidth(maximumScrollPosition().x() - scrollPosition().x());
+        }
+    }
+
+    if ((delta.width() || delta.height()) && (limitDelta.width() < 1 && limitDelta.height() < 1))
+        return true;
+
+    return false;
+}
+
+bool ScrollingTreeScrollingNodeDelegateMac::canScrollHorizontally()
+{
+    return hasEnabledHorizontalScrollbar();
+}
+
+bool ScrollingTreeScrollingNodeDelegateMac::canScrollVertically()
+{
+    return hasEnabledVerticalScrollbar();
+}
+
+bool ScrollingTreeScrollingNodeDelegateMac::shouldRubberBandInDirection(ScrollDirection)
+{
+    return true;
+}
+
+void ScrollingTreeScrollingNodeDelegateMac::immediateScrollBy(const FloatSize& delta)
+{
+    scrollingNode().scrollBy(delta);
+}
+
+void ScrollingTreeScrollingNodeDelegateMac::immediateScrollByWithoutContentEdgeConstraints(const FloatSize& offset)
+{
+    scrollingNode().scrollByWithoutContentEdgeConstraints(offset);
+}
+
+void ScrollingTreeScrollingNodeDelegateMac::stopSnapRubberbandTimer()
+{
+    scrollingTree().setMainFrameIsRubberBanding(false);
+
+    // Since the rubberband timer has stopped, totalContentsSizeForRubberBand can be synchronized with totalContentsSize.
+    scrollingNode().setTotalContentsSizeForRubberBand(totalContentsSize());
+}
+
+void ScrollingTreeScrollingNodeDelegateMac::adjustScrollPositionToBoundsIfNecessary()
+{
+    FloatPoint currentScrollPosition = scrollPosition();
+    FloatPoint constrainedPosition = currentScrollPosition.constrainedBetween(minimumScrollPosition(), maximumScrollPosition());
+    immediateScrollBy(constrainedPosition - currentScrollPosition);
+}
+
+#if ENABLE(CSS_SCROLL_SNAP)
+FloatPoint ScrollingTreeScrollingNodeDelegateMac::scrollOffset() const
+{
+    return scrollPosition();
+}
+
+void ScrollingTreeScrollingNodeDelegateMac::immediateScrollOnAxis(ScrollEventAxis axis, float delta)
+{
+    const FloatPoint& currentPosition = scrollPosition();
+    FloatPoint change;
+    if (axis == ScrollEventAxis::Horizontal)
+        change = FloatPoint(currentPosition.x() + delta, currentPosition.y());
+    else
+        change = FloatPoint(currentPosition.x(), currentPosition.y() + delta);
+
+    immediateScrollBy(change - currentPosition);
+}
+
+float ScrollingTreeScrollingNodeDelegateMac::pageScaleFactor() const
+{
+    // FIXME: What should this return for non-root frames, and overflow?
+    // Also, this should not have to access ScrollingTreeFrameScrollingNode.
+    if (is<ScrollingTreeFrameScrollingNode>(scrollingNode()))
+        return downcast<ScrollingTreeFrameScrollingNode>(scrollingNode()).frameScaleFactor();
+
+    return 1;
+}
+
+void ScrollingTreeScrollingNodeDelegateMac::startScrollSnapTimer()
+{
+    scrollingTree().setMainFrameIsScrollSnapping(true);
+}
+
+void ScrollingTreeScrollingNodeDelegateMac::stopScrollSnapTimer()
+{
+    scrollingTree().setMainFrameIsScrollSnapping(false);
+}
+    
+LayoutSize ScrollingTreeScrollingNodeDelegateMac::scrollExtent() const
+{
+    return LayoutSize(totalContentsSize());
+}
+
+FloatSize ScrollingTreeScrollingNodeDelegateMac::viewportSize() const
+{
+    return scrollableAreaSize();
+}
+#endif
+
+void ScrollingTreeScrollingNodeDelegateMac::deferTestsForReason(WheelEventTestTrigger::ScrollableAreaIdentifier identifier, WheelEventTestTrigger::DeferTestTriggerReason reason) const
+{
+    if (!scrollingNode().expectsWheelEventTestTrigger())
+        return;
+
+    LOG(WheelEventTestTriggers, "  ScrollingTreeScrollingNodeDelegateMac::deferTestsForReason: STARTING deferral for %p because of %d", identifier, reason);
+    scrollingTree().deferTestsForReason(identifier, reason);
+}
+    
+void ScrollingTreeScrollingNodeDelegateMac::removeTestDeferralForReason(WheelEventTestTrigger::ScrollableAreaIdentifier identifier, WheelEventTestTrigger::DeferTestTriggerReason reason) const
+{
+    if (!scrollingNode().expectsWheelEventTestTrigger())
+        return;
+    
+    LOG(WheelEventTestTriggers, "   ScrollingTreeScrollingNodeDelegateMac::deferTestsForReason: ENDING deferral for %p because of %d", identifier, reason);
+    scrollingTree().removeTestDeferralForReason(identifier, reason);
+}
+
+} // namespace WebCore
+
+#endif // PLATFORM(MAC) && ENABLE(ASYNC_SCROLLING)