Skip to content
Permalink
Browse files
Scroll snapping on Mac should use AppKit animations
https://bugs.webkit.org/show_bug.cgi?id=147261
<rdar://problem/29395293>

Reviewed by Brent Fulgham.

Source/WebCore:

Refactors the scroll snapping animation logic to support arbitrary scrolling momentum calculators and
introduces ScrollingMomentumCalculatorMac, which wraps AppKit's _NSScrollingMomentumCalculator. On macOS El
Capitan and later, we use the platform scrolling momentum calculator and for all other cases, we fall back to
the preexissting platform-invariant momentum calculator.

Previously, the scroll snapping animation logic was shared between the ScrollSnapAnimatorState and
ScrollController -- namely, the ScrollController would update various parameters of the ScrollSnapAnimatorState
and then tell it to compute animation-specific constants and coefficients. After this patch, ScrollController
will no longer directly set the ScrollSnapAnimatorState's member variables. Instead, it will tell the animator
state to transition to a new ScrollSnapState with the necessary parameters, and the ScrollSnapAnimatorState is
responsible for modifying itself accordingly. Furthermore, logic pertaining to computing animated scroll offsets
is now split out into a new ScrollingMomentumCalculator, which may have different platform-dependent
implementations. The correct calculator is initialized via ScrollingMomentumCalculator::create, which currently
returns a ScrollingMomentumCalculatorMac on El Capitan and later, and a BasicScrollingMomentumCalculator
otherwise.

The new abstracted ScrollingMomentumCalculator is initialized with various parameters describing the scrolled
content and viewport, as well as the initial and target scrolling offsets. The momentum calculator is then able
to compute the animated scroll offset at any given elapsed time, as well as the total duration of the snapping
animation. The ScrollController's scroll snap timer uses this information (via the ScrollSnapAnimatorState) to
animate its client's scroll offset during a snap or glide.

Also reenables 8 failing and/or flaky scroll snapping tests and adds a new layout test. This patch addresses
two causes for failures and flakiness in these scroll snapping tests:

1.  When starting or stopping the scroll snap animation timer, we call deferTestsForReason and
    removeTestDeferralForReason, respectively. These were actually noops for the first simulated scroll gesture
    on each of the failing mainframe scrolling tests due to m_expectsWheelEventTestTrigger being false. This
    member variable is updated when AsyncScrollingCoordinator::frameViewLayoutUpdated is invoked, wherein we
    call ScrollingStateFrameScrollingNode::setExpectsWheelEventTestTrigger(true) when the test has started
    monitoring wheel events. However, if this does not happen before scrolling begins in the test (which is the
    case here), then the mainframe scrolling node will not expect a wheel event test trigger even though
    eventSender.monitorWheelEvents() has been called. To fix this, we simply make the Page trigger a layout of
    the main FrameView when first ensuring the wheel event test trigger on the Page.

2.  The second reason for flakiness affects both overflow and mainframe scrolling. Previously, due to the way
    we would wait for multiple momentum scroll events before starting to glide, we would end up starting the
    scroll snap timer for a snapping animation, stopping it, and then starting it again for the glide animation.
    Thus, if the wheel event test trigger's timer fires right after the scroll snap timer stops and before it
    starts again due to a glide animation, it will erroneously think that scroll snapping is complete, even
    though it's only just about to begin! Now that we know scrolling velocity when we receive the initial
    "momentum begin", we now directly transition the scroll snap state from a snapping state to a gliding state
    and no longer stop and start the timer during this transition, which means that the test trigger will be
    deferred for at least the entire duration of the scroll snapping animation (starting right after the first
    "drag end" wheel event).

Test: tiled-drawing/scrolling/scroll-snap/scroll-snap-mandatory-vertical-then-horizontal.html

* WebCore.xcodeproj/project.pbxproj:
* page/EventHandler.cpp:
(WebCore::handleWheelEventInAppropriateEnclosingBox):
(WebCore::EventHandler::defaultWheelEventHandler):
* page/Page.cpp:
(WebCore::Page::ensureTestTrigger):

Addresses test failures by forcing the mainframe scrolling node to expect wheel event test triggers.

* page/WheelEventDeltaFilter.cpp:
(WebCore::WheelEventDeltaFilter::create):
(WebCore::WheelEventDeltaFilter::filteredVelocity):
* page/WheelEventDeltaFilter.h:
* page/mac/WheelEventDeltaFilterMac.mm:
(WebCore::WheelEventDeltaFilterMac::updateFromDelta):

Add support for plumbing filtered scrolling velocity over to the ScrollController.

* page/scrolling/ScrollingMomentumCalculator.cpp: Copied from Source/WebCore/platform/cocoa/ScrollSnapAnimatorState.mm.
(WebCore::ScrollingMomentumCalculator::ScrollingMomentumCalculator):
(WebCore::ScrollingMomentumCalculator::create):

Creates a platform-independent BasicScrollingMomentumCalculator.

(WebCore::BasicScrollingMomentumCalculator::BasicScrollingMomentumCalculator):
(WebCore::BasicScrollingMomentumCalculator::linearlyInterpolatedOffsetAtProgress):
(WebCore::BasicScrollingMomentumCalculator::cubicallyInterpolatedOffsetAtProgress):
(WebCore::BasicScrollingMomentumCalculator::scrollOffsetAfterElapsedTime):
(WebCore::BasicScrollingMomentumCalculator::animationDuration):
(WebCore::BasicScrollingMomentumCalculator::initializeInterpolationCoefficientsIfNecessary):
(WebCore::BasicScrollingMomentumCalculator::initializeSnapProgressCurve):
(WebCore::BasicScrollingMomentumCalculator::animationProgressAfterElapsedTime):

Interpolation logic ported over from ScrollSnapAnimatorState.

* page/scrolling/ScrollingMomentumCalculator.h: Added.
(WebCore::ScrollingMomentumCalculator::~ScrollingMomentumCalculator):
* page/scrolling/mac/ScrollingMomentumCalculatorMac.h: Copied from Source/WebCore/page/WheelEventDeltaFilter.h.
* page/scrolling/mac/ScrollingMomentumCalculatorMac.mm: Added.
(WebCore::ScrollingMomentumCalculator::create):

Creates a ScrollingMomentumCalculatorMac.

(WebCore::ScrollingMomentumCalculatorMac::ScrollingMomentumCalculatorMac):
(WebCore::ScrollingMomentumCalculatorMac::scrollOffsetAfterElapsedTime):
(WebCore::ScrollingMomentumCalculatorMac::animationDuration):
(WebCore::ScrollingMomentumCalculatorMac::ensurePlatformMomentumCalculator):
* page/scrolling/mac/ScrollingTreeFrameScrollingNodeMac.h:
* page/scrolling/mac/ScrollingTreeFrameScrollingNodeMac.mm:
(WebCore::ScrollingTreeFrameScrollingNodeMac::scrollOffset):
(WebCore::ScrollingTreeFrameScrollingNodeMac::viewportSize):
(WebCore::ScrollingTreeFrameScrollingNodeMac::scrollOffsetOnAxis): Deleted.
* platform/PlatformWheelEvent.h:
(WebCore::PlatformWheelEvent::copyWithDeltasAndVelocity):
(WebCore::PlatformWheelEvent::scrollingVelocity):
(WebCore::PlatformWheelEvent::copyWithDeltas): Deleted.
* platform/ScrollAnimator.cpp:
(WebCore::ScrollAnimator::scrollOffset):
(WebCore::ScrollAnimator::viewportSize):
(WebCore::ScrollAnimator::scrollOffsetOnAxis): Deleted.
* platform/ScrollAnimator.h:
* platform/cocoa/ScrollController.h:
* platform/cocoa/ScrollController.mm:
(WebCore::otherScrollEventAxis):
(WebCore::ScrollController::ScrollController):
(WebCore::ScrollController::shouldOverrideInertialScrolling):
(WebCore::ScrollController::scheduleStatelessScrollSnap):
(WebCore::ScrollController::statelessSnapTransitionTimerFired):
(WebCore::ScrollController::startDeferringTestsDueToScrollSnapping):
(WebCore::ScrollController::stopDeferringTestsDueToScrollSnapping):
(WebCore::ScrollController::processWheelEventForScrollSnap):
(WebCore::ScrollController::updateScrollSnapState):
(WebCore::ScrollController::updateScrollSnapPoints):

Update the ScrollController's ScrollSnapAnimationState for both vertical and horizontal axes. If both axes lack
any snap points, the pointer to the animation state will be nulled out; otherwise, the animation state will
exist.

(WebCore::ScrollController::startScrollSnapTimer):
(WebCore::ScrollController::stopScrollSnapTimer):
(WebCore::ScrollController::scrollSnapTimerFired):
(WebCore::ScrollController::activeScrollSnapIndexForAxis):
(WebCore::ScrollController::setActiveScrollSnapIndexForAxis):
(WebCore::ScrollController::setNearestScrollSnapIndexForAxisAndOffset):
(WebCore::ScrollController::setActiveScrollSnapIndicesForOffset):
(WebCore::ScrollController::scrollSnapPointState): Deleted.
(WebCore::ScrollController::processWheelEventForScrollSnapOnAxis): Deleted.
(WebCore::ScrollController::shouldOverrideWheelEvent): Deleted.
(WebCore::projectedInertialScrollDistance): Deleted.
(WebCore::ScrollController::beginScrollSnapAnimation): Deleted.
(WebCore::ScrollController::endScrollSnapAnimation): Deleted.
(WebCore::ScrollController::initializeScrollSnapAnimationParameters): Deleted.
(WebCore::ScrollController::isSnappingOnAxis): Deleted.
* platform/cocoa/ScrollSnapAnimatorState.h:
(WebCore::ScrollSnapAnimatorState::snapOffsetsForAxis):
(WebCore::ScrollSnapAnimatorState::setSnapOffsetsForAxis):
(WebCore::ScrollSnapAnimatorState::currentState):
(WebCore::ScrollSnapAnimatorState::activeSnapIndexForAxis):
(WebCore::ScrollSnapAnimatorState::setActiveSnapIndexForAxis):
* platform/cocoa/ScrollSnapAnimatorState.mm:
(WebCore::projectedInertialScrollDistance):
(WebCore::ScrollSnapAnimatorState::transitionToSnapAnimationState):
(WebCore::ScrollSnapAnimatorState::transitionToGlideAnimationState):
(WebCore::ScrollSnapAnimatorState::transitionToUserInteractionState):
(WebCore::ScrollSnapAnimatorState::transitionToDestinationReachedState):

These methods are used to update the ScrollSnapAnimationState. These state transitions should (and do)
encapsulate all changes that need to be made to the animation state; in other words, the ScrollController should
no longer be reaching directly into the ScrollSnapAnimatorState to change member variables.

(WebCore::ScrollSnapAnimatorState::setupAnimationForState):
(WebCore::ScrollSnapAnimatorState::teardownAnimationForState):
(WebCore::ScrollSnapAnimatorState::currentAnimatedScrollOffset):
(WebCore::ScrollSnapAnimatorState::targetOffsetForStartOffset):
(WebCore::ScrollSnapAnimatorState::ScrollSnapAnimatorState): Deleted.
(WebCore::ScrollSnapAnimatorState::pushInitialWheelDelta): Deleted.
(WebCore::ScrollSnapAnimatorState::averageInitialWheelDelta): Deleted.
(WebCore::ScrollSnapAnimatorState::clearInitialWheelDeltaWindow): Deleted.
(WebCore::ScrollSnapAnimatorState::isSnapping): Deleted.
(WebCore::ScrollSnapAnimatorState::canReachTargetWithCurrentInitialScrollDelta): Deleted.
(WebCore::ScrollSnapAnimatorState::wheelDeltaTrackingIsInProgress): Deleted.
(WebCore::ScrollSnapAnimatorState::hasFinishedTrackingWheelDeltas): Deleted.
(WebCore::ScrollSnapAnimatorState::interpolatedOffsetAtProgress): Deleted.
(WebCore::ScrollSnapAnimationCurveState::initializeSnapProgressCurve): Deleted.
(WebCore::ScrollSnapAnimationCurveState::initializeInterpolationCoefficientsIfNecessary): Deleted.
(WebCore::ScrollSnapAnimationCurveState::interpolatedPositionAtProgress): Deleted.
(WebCore::ScrollSnapAnimationCurveState::shouldCompleteSnapAnimationImmediatelyAtTime): Deleted.
(WebCore::ScrollSnapAnimationCurveState::animationProgressAtTime): Deleted.

The ScrollSnapAnimatorState now tracks state across both axes. This simplifies coordinating scroll snapping in
both horizontal and vertical axes and fixes the issue of the scroll offset not snapping when performing a scroll
in one direction without momentum, then scrolling with momentum in the other direction in a single gesture.

* platform/spi/mac/NSScrollingMomentumCalculatorSPI.h: Added.

Source/WebKit2:

Add some logic to plumb filtered wheel velocity over to WebCore in the case of mainframe scrolling. See
WebCore/ChangeLog for more details.

* WebProcess/WebPage/EventDispatcher.cpp:
(WebKit::EventDispatcher::wheelEvent):

Source/WTF:

Introduce HAVE(NSSCROLLING_FILTERS), which is on for macOS El Capitan and later.

* wtf/Platform.h:

LayoutTests:

Fixes 8 previously failing scroll snapping tests in the tiled-drawing/scrolling/scroll-snap directory and
removes them from TestExpectations. Also adds a new layout test. See WebCore/ChangeLog for more details.

* platform/mac-wk2/TestExpectations:
* tiled-drawing/scrolling/scroll-snap/scroll-snap-mandatory-2d-overflow-expected.txt:
* tiled-drawing/scrolling/scroll-snap/scroll-snap-mandatory-borders-expected.txt:
* tiled-drawing/scrolling/scroll-snap/scroll-snap-mandatory-mainframe-slow-horizontal.html:
* tiled-drawing/scrolling/scroll-snap/scroll-snap-mandatory-mainframe-slow-vertical.html:
* tiled-drawing/scrolling/scroll-snap/scroll-snap-mandatory-mainframe-vertical-then-horizontal-expected.txt: Added.
* tiled-drawing/scrolling/scroll-snap/scroll-snap-mandatory-mainframe-vertical-then-horizontal.html: Added.
* tiled-drawing/scrolling/scroll-snap/scroll-snap-mandatory-mainframe-vertical.html:


Canonical link: https://commits.webkit.org/182760@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@209070 268f45cc-cd09-0410-ab3c-d52691b4dbfc
  • Loading branch information
whsieh committed Nov 29, 2016
1 parent 4f9eaff commit b7d7a4c54c8707d4a91b816c823a0715cdeb3ddb
Showing with 1,107 additions and 554 deletions.
  1. +20 −0 LayoutTests/ChangeLog
  2. +0 −10 LayoutTests/platform/mac-wk2/TestExpectations
  3. +1 −1 LayoutTests/tiled-drawing/scrolling/scroll-snap/scroll-snap-mandatory-2d-overflow-expected.txt
  4. +2 −2 LayoutTests/tiled-drawing/scrolling/scroll-snap/scroll-snap-mandatory-borders-expected.txt
  5. +2 −2 LayoutTests/tiled-drawing/scrolling/scroll-snap/scroll-snap-mandatory-mainframe-slow-horizontal.html
  6. +2 −3 LayoutTests/tiled-drawing/scrolling/scroll-snap/scroll-snap-mandatory-mainframe-slow-vertical.html
  7. +5 −0 ...awing/scrolling/scroll-snap/scroll-snap-mandatory-mainframe-vertical-then-horizontal-expected.txt
  8. +75 −0 ...tiled-drawing/scrolling/scroll-snap/scroll-snap-mandatory-mainframe-vertical-then-horizontal.html
  9. +2 −2 LayoutTests/tiled-drawing/scrolling/scroll-snap/scroll-snap-mandatory-mainframe-vertical.html
  10. +12 −0 Source/WTF/ChangeLog
  11. +6 −0 Source/WTF/wtf/Platform.h
  12. +191 −0 Source/WebCore/ChangeLog
  13. +18 −0 Source/WebCore/WebCore.xcodeproj/project.pbxproj
  14. +10 −6 Source/WebCore/page/EventHandler.cpp
  15. +4 −1 Source/WebCore/page/Page.cpp
  16. +7 −2 Source/WebCore/page/WheelEventDeltaFilter.cpp
  17. +3 −0 Source/WebCore/page/WheelEventDeltaFilter.h
  18. +3 −2 Source/WebCore/page/mac/WheelEventDeltaFilterMac.mm
  19. +208 −0 Source/WebCore/page/scrolling/ScrollingMomentumCalculator.cpp
  20. +79 −0 Source/WebCore/page/scrolling/ScrollingMomentumCalculator.h
  21. +51 −0 Source/WebCore/page/scrolling/mac/ScrollingMomentumCalculatorMac.h
  22. +70 −0 Source/WebCore/page/scrolling/mac/ScrollingMomentumCalculatorMac.mm
  23. +2 −1 Source/WebCore/page/scrolling/mac/ScrollingTreeFrameScrollingNodeMac.h
  24. +8 −3 Source/WebCore/page/scrolling/mac/ScrollingTreeFrameScrollingNodeMac.mm
  25. +6 −1 Source/WebCore/platform/PlatformWheelEvent.h
  26. +8 −2 Source/WebCore/platform/ScrollAnimator.cpp
  27. +2 −1 Source/WebCore/platform/ScrollAnimator.h
  28. +27 −19 Source/WebCore/platform/cocoa/ScrollController.h
  29. +121 −300 Source/WebCore/platform/cocoa/ScrollController.mm
  30. +52 −48 Source/WebCore/platform/cocoa/ScrollSnapAnimatorState.h
  31. +49 −147 Source/WebCore/platform/cocoa/ScrollSnapAnimatorState.mm
  32. +46 −0 Source/WebCore/platform/spi/mac/NSScrollingMomentumCalculatorSPI.h
  33. +14 −0 Source/WebKit2/ChangeLog
  34. +1 −1 Source/WebKit2/WebProcess/WebPage/EventDispatcher.cpp
@@ -1,3 +1,23 @@
2016-11-29 Wenson Hsieh <wenson_hsieh@apple.com>

Scroll snapping on Mac should use AppKit animations
https://bugs.webkit.org/show_bug.cgi?id=147261
<rdar://problem/29395293>

Reviewed by Brent Fulgham.

Fixes 8 previously failing scroll snapping tests in the tiled-drawing/scrolling/scroll-snap directory and
removes them from TestExpectations. Also adds a new layout test. See WebCore/ChangeLog for more details.

* platform/mac-wk2/TestExpectations:
* tiled-drawing/scrolling/scroll-snap/scroll-snap-mandatory-2d-overflow-expected.txt:
* tiled-drawing/scrolling/scroll-snap/scroll-snap-mandatory-borders-expected.txt:
* tiled-drawing/scrolling/scroll-snap/scroll-snap-mandatory-mainframe-slow-horizontal.html:
* tiled-drawing/scrolling/scroll-snap/scroll-snap-mandatory-mainframe-slow-vertical.html:
* tiled-drawing/scrolling/scroll-snap/scroll-snap-mandatory-mainframe-vertical-then-horizontal-expected.txt: Added.
* tiled-drawing/scrolling/scroll-snap/scroll-snap-mandatory-mainframe-vertical-then-horizontal.html: Added.
* tiled-drawing/scrolling/scroll-snap/scroll-snap-mandatory-mainframe-vertical.html:

2016-11-29 Brady Eidson <beidson@apple.com>

IndexedDB 2.0: Queue up completed requests in the client, handle them one by one.
@@ -264,19 +264,9 @@ webkit.org/b/136554 tiled-drawing/scrolling/frames/frameset-nested-frame-scrolla
webkit.org/b/139901 tiled-drawing/scrolling/frames/frameset-frame-scrollability.html [ Pass Failure ]

webkit.org/b/162505 tiled-drawing/scrolling/latched-div-with-scroll-snap.html [ Pass Failure ]

webkit.org/b/148405 tiled-drawing/scrolling/scroll-snap/scroll-snap-mandatory-2d-overflow.html [ Pass Failure ]

webkit.org/b/148407 tiled-drawing/scrolling/scroll-snap/scroll-snap-mandatory-mainframe-horizontal.html [ Pass Failure ]
webkit.org/b/148407 tiled-drawing/scrolling/scroll-snap/scroll-snap-mandatory-mainframe-slow-horizontal.html [ Pass Failure ]
webkit.org/b/148407 tiled-drawing/scrolling/scroll-snap/scroll-snap-mandatory-mainframe-slow-vertical.html [ Pass Failure ]
webkit.org/b/148407 tiled-drawing/scrolling/scroll-snap/scroll-snap-mandatory-mainframe-vertical.html [ Pass Failure ]

webkit.org/b/148408 tiled-drawing/scrolling/scroll-snap/scroll-snap-mandatory-borders.html [ Pass Failure ]
webkit.org/b/148408 tiled-drawing/scrolling/scroll-snap/scroll-snap-mandatory-overflow.html [ Pass Failure ]
webkit.org/b/148408 tiled-drawing/scrolling/scroll-snap/scroll-snap-mandatory-rotated.html [ Pass Failure ]
webkit.org/b/148408 tiled-drawing/scrolling/scroll-snap/scroll-snap-mandatory-padding.html [ Pass Failure ]
webkit.org/b/148408 tiled-drawing/scrolling/scroll-snap/scroll-snap-iframe.html [ Pass Failure ]
webkit.org/b/148408 tiled-drawing/scrolling/root-overflow-with-mousewheel.html [ Pass Failure Timeout ]

webkit.org/b/139820 fast/frames/lots-of-objects.html [ Timeout ]
@@ -1,6 +1,6 @@
PASS div successfully scrolled diagonally.
PASS div successfully snapped diagonally.
FAIL div did not honor 2D snap points. (single axis scroll followed by flick on other axis)
PASS div successfully snapped after dragging along one axis and then scrolling in the other.
PASS successfullyParsed is true

TEST COMPLETE
@@ -4,9 +4,9 @@ PASS div scrolled to next window.
Testing scroll-snap snap for horizontalTarget:
PASS div honored snap points.
Testing scroll-snap glide for verticalTarget:
FAIL div did not honor snap points. Expected 300, but got 50
PASS div scrolled to next window.
Testing scroll-snap snap for verticalTarget:
FAIL div did not snap back to proper location for verticalTarget. Expected 50, but got 0
PASS div honored snap points.
PASS successfullyParsed is true

TEST COMPLETE
@@ -33,7 +33,7 @@
function checkForScrollSnap() {
// The div should have snapped back to the previous position
if (divTarget.scrollLeft != divScrollPositionBeforeSnap)
testFailed("div did not snap back to proper location.");
testFailed(`div did not snap back to proper location. ${divTarget.scrollLeft} vs. ${divScrollPositionBeforeSnap}`);
else
testPassed("div honored snap points.");

@@ -63,7 +63,7 @@
if (divTarget.scrollLeft == window.innerWidth)
testPassed("div scrolled to next window.");
else
testFailed("div did not honor snap points.");
testFailed(`div did not honor snap points. ${divTarget.scrollLeft} vs. ${window.innerWidth}`);

setTimeout(scrollSnapTest, 0);
}
@@ -33,7 +33,7 @@
function checkForScrollSnap() {
// The div should have snapped back to the previous position
if (divTarget.scrollTop != divScrollPositionBeforeSnap)
testFailed("div did not snap back to proper location.");
testFailed(`div did not snap back to proper location. (${divTarget.scrollTop} vs. ${divScrollPositionBeforeSnap})`);
else
testPassed("div honored snap points.");

@@ -63,7 +63,7 @@
if (divTarget.scrollTop == window.innerHeight)
testPassed("div scrolled to next window.");
else
testFailed("div did not honor snap points.");
testFailed(`div did not honor snap points. (${divTarget.scrollTop} vs. ${window.innerHeight})`);

setTimeout(scrollSnapTest, 0);
}
@@ -88,7 +88,6 @@
}

function onLoad() {

if (window.eventSender) {
eventSender.monitorWheelEvents();
setTimeout(scrollGlideTest, 0);
@@ -0,0 +1,5 @@
PASS scroll offset snapped back to top.
PASS successfullyParsed is true

TEST COMPLETE

@@ -0,0 +1,75 @@
<!DOCTYPE HTML>
<html>
<head>
<style>
.verticalGallery {
width: 100vw;
height: 600vh;
margin: 0;
padding: 0;
-webkit-scroll-snap-points-y: repeat(100vh);
-webkit-scroll-snap-type: mandatory;
}
.colorBox {
height: 100vh;
width: 100vw;
float: left;
}
#item0 { background-color: red; }
#item1 { background-color: green; }
#item2 { background-color: blue; }
#item3 { background-color: aqua; }
#item4 { background-color: yellow; }
#item5 { background-color: fuchsia; }
</style>
<script src="../../../resources/js-test.js"></script>
<script>
window.jsTestIsAsync = true;

function scrollSnapTest() {
var startPosX = document.body.offsetLeft + 20;
var startPosY = document.body.offsetTop + 20;
eventSender.mouseMoveTo(startPosX, startPosY);
eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'began', 'none');
eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'changed', 'none');
eventSender.mouseScrollByWithWheelAndMomentumPhases(-1, 0, 'changed', 'none');
eventSender.mouseScrollByWithWheelAndMomentumPhases(-1, 0, 'changed', 'none');
eventSender.mouseScrollByWithWheelAndMomentumPhases(-1, 0, 'changed', 'none');
eventSender.mouseScrollByWithWheelAndMomentumPhases(0, 0, 'ended', 'none');
eventSender.mouseScrollByWithWheelAndMomentumPhases(-1, 0, 'none', 'begin');
eventSender.mouseScrollByWithWheelAndMomentumPhases(-4, 0, 'none', 'continue');
eventSender.mouseScrollByWithWheelAndMomentumPhases(0, 0, 'none', 'end');
eventSender.callAfterScrollingCompletes(() => {
if (document.body.scrollTop == 0)
testPassed("scroll offset snapped back to top.");
else
testFailed(`did not honor snap points (expected 0, observed ${document.body.scrollTop}).`);

finishJSTest();
});
}

function onLoad() {
if (window.eventSender) {
eventSender.monitorWheelEvents();
setTimeout(scrollSnapTest, 0);
} else {
var messageLocation = document.getElementById('item0');
var message = document.createElement('div');
message.innerHTML = `<p>This test is better run under DumpRenderTree. To manually test it, scroll down
slightly, and then directly to the left or right with momentum without lifting your fingers from the
trackpad. The scroll offset should animate to the nearest snap offset.</p>`;
messageLocation.appendChild(message);
}
}
</script>
</head>
<body onload="onLoad();" class="verticalGallery">
<div id="item0" class="colorBox"><div id="console"></div></div>
<div id="item1" class="colorBox"></div>
<div id="item2" class="colorBox"></div>
<div id="item3" class="colorBox"></div>
<div id="item4" class="colorBox"></div>
<div id="item5" class="colorBox"></div>
</body>
</html>
@@ -33,7 +33,7 @@
function checkForScrollSnap() {
// The div should have snapped back to the previous position
if (divTarget.scrollTop != divScrollPositionBeforeSnap)
testFailed("div did not snap back to proper location.");
testFailed(`div did not snap back to proper location. (${divTarget.scrollTop} vs. ${divScrollPositionBeforeSnap})`);
else
testPassed("div honored snap points.");

@@ -63,7 +63,7 @@
if (divTarget.scrollTop == window.innerHeight)
testPassed("div scrolled to next window.");
else
testFailed("div did not honor snap points.");
testFailed(`div did not honor snap points. (${divTarget.scrollTop} vs. ${window.innerHeight})`);

setTimeout(scrollSnapTest, 0);
}
@@ -1,3 +1,15 @@
2016-11-29 Wenson Hsieh <wenson_hsieh@apple.com>

Scroll snapping on Mac should use AppKit animations
https://bugs.webkit.org/show_bug.cgi?id=147261
<rdar://problem/29395293>

Reviewed by Brent Fulgham.

Introduce HAVE(NSSCROLLING_FILTERS), which is on for macOS El Capitan and later.

* wtf/Platform.h:

2016-11-28 Darin Adler <darin@apple.com>

Streamline and speed up tokenizer and segmented string classes
@@ -551,6 +551,12 @@
#define USE_PLUGIN_HOST_PROCESS 1
#endif

#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 101100
#define HAVE_NSSCROLLING_FILTERS 1
#else
#define HAVE_NSSCROLLING_FILTERS 0
#endif

/* OS X defines a series of platform macros for debugging. */
/* Some of them are really annoying because they use common names (e.g. check()). */
/* Disable those macros so that we are not limited in how we name methods and functions. */

0 comments on commit b7d7a4c

Please sign in to comment.