Changeset 254807 in webkit


Ignore:
Timestamp:
Jan 19, 2020 8:43:43 AM (4 years ago)
Author:
cathiechen
Message:

Add support for scroll behavior relies on ScrollAnimation of the Web process
https://bugs.webkit.org/show_bug.cgi?id=204882

Reviewed by Frédéric Wang

Based on the patch by Frédéric Wang.

LayoutTests/imported/w3c:

Enable CSSOMViewSmoothScrollingEnabled on scroll behavior tests and update expectations.

  • web-platform-tests/css/cssom-view/scroll-behavior-default-css-expected.txt:
  • web-platform-tests/css/cssom-view/scroll-behavior-default-css.html:
  • web-platform-tests/css/cssom-view/scroll-behavior-element-expected.txt:
  • web-platform-tests/css/cssom-view/scroll-behavior-element.html:
  • web-platform-tests/css/cssom-view/scroll-behavior-main-frame-root-expected.txt:
  • web-platform-tests/css/cssom-view/scroll-behavior-main-frame-root.html:
  • web-platform-tests/css/cssom-view/scroll-behavior-main-frame-window-expected.txt:
  • web-platform-tests/css/cssom-view/scroll-behavior-main-frame-window.html:
  • web-platform-tests/css/cssom-view/scroll-behavior-scrollintoview-nested-expected.txt:
  • web-platform-tests/css/cssom-view/scroll-behavior-scrollintoview-nested.html:
  • web-platform-tests/css/cssom-view/scroll-behavior-smooth-positions.html:
  • web-platform-tests/css/cssom-view/scroll-behavior-subframe-root-expected.txt:
  • web-platform-tests/css/cssom-view/scroll-behavior-subframe-root.html:
  • web-platform-tests/css/cssom-view/scroll-behavior-subframe-window-expected.txt:
  • web-platform-tests/css/cssom-view/scroll-behavior-subframe-window.html:

Source/WebCore:

This patch introduces a programmatic smooth scrolling in WebKit from the CSSOM View
specification [1]. To use this effect, web developers can pass a behavior parameter (auto,
smooth, or instant) to Element.scroll, Element.scrollTo, Element.scrollBy,
Element.scrollIntoView, Window.scroll, Window.scrollTo or Window.scrollBy [2]. When behavior
is auto, the instant/smooth characteristic is actually taken from the value of a new CSS
scroll-behavior property [3]. Both the new CSS and DOM behavior are protected by a runtime
flag.

[1] https://drafts.csswg.org/cssom-view
[2] https://drafts.csswg.org/cssom-view/#dictdef-scrolloptions
[3] https://drafts.csswg.org/cssom-view/#propdef-scroll-behavior

Tests: imported/w3c/web-platform-tests/css/cssom-view/scroll-behavior-default-css.html

imported/w3c/web-platform-tests/css/cssom-view/scroll-behavior-element.html
imported/w3c/web-platform-tests/css/cssom-view/scroll-behavior-main-frame-root.html
imported/w3c/web-platform-tests/css/cssom-view/scroll-behavior-main-frame-window.html
imported/w3c/web-platform-tests/css/cssom-view/scroll-behavior-scrollintoview-nested.html
imported/w3c/web-platform-tests/css/cssom-view/scroll-behavior-smooth-positions.html
imported/w3c/web-platform-tests/css/cssom-view/scroll-behavior-subframe-root.html
imported/w3c/web-platform-tests/css/cssom-view/scroll-behavior-subframe-window.html

  • Sources.txt: Build ScrollAnimationSmooth.cpp on all platforms.
  • SourcesGTK.txt: Remove ScrollAnimationSmooth.cpp since it is built on all platforms now.
  • dom/Element.cpp:

(WebCore::Element::scrollIntoView): Pass scroll behavior, if any.
(WebCore::Element::scrollBy):
(WebCore::Element::scrollTo): Handle the case when scroll behavior is smooth.
(WebCore::Element::setScrollLeft): Handle the case when scroll behavior is smooth.
(WebCore::Element::setScrollTop): Handle the case when scroll behavior is smooth.

  • page/DOMWindow.cpp:

(WebCore::DOMWindow::scrollBy const):
(WebCore::DOMWindow::scrollTo const): Handle the case when scroll behavior is smooth.
The optimization of cancel (0, 0) scrolling is skipped if an animated scroll is in progress.
Otherwise, the previous scroll won't be stopped by a follow-up scroll.

  • page/FrameView.cpp:

(WebCore::FrameView::setScrollPosition):
(WebCore::FrameView::scrollToOffsetWithAnimation): Start an animated scroll.

  • page/FrameView.h:
  • page/scrolling/AsyncScrollingCoordinator.cpp:

(WebCore::AsyncScrollingCoordinator::requestScrollPositionUpdate):

  • platform/ScrollAnimation.h:

(WebCore::ScrollAnimation::scroll): Function to animate scrolling to a specified position.

  • platform/ScrollAnimationSmooth.cpp: Build this file on all platforms. Add a

smoothFactorForProgrammaticScroll parameter to slow down the smooth scrolling.
(WebCore::ScrollAnimationSmooth::scroll):
(WebCore::ScrollAnimationSmooth::updatePerAxisData): Scale the time parameters of the
animation so that it looks smoother.

  • platform/ScrollAnimationSmooth.h: Declare the class on all platforms.
  • platform/ScrollAnimator.cpp:

(WebCore::ScrollAnimator::ScrollAnimator): Initialize animation member for programmatic scrolling.
(WebCore::ScrollAnimator::scrollToOffset): Animate scrolling to the specified position.
(WebCore::ScrollAnimator::cancelAnimations): Copy logic from ScrollAnimationSmooth.cpp.
(WebCore::ScrollAnimator::serviceScrollAnimations): Ditto.
(WebCore::ScrollAnimator::willEndLiveResize): Ditto.
(WebCore::ScrollAnimator::didAddVerticalScrollbar): Ditto.
(WebCore::ScrollAnimator::didAddHorizontalScrollbar): Ditto.

  • platform/ScrollAnimator.h: New animation member for smooth programmatic scrolling.

(WebCore::ScrollAnimator::ScrollAnimator::cancelAnimations): Deleted.
(WebCore::ScrollAnimator::ScrollAnimator::serviceScrollAnimations): Deleted.
(WebCore::ScrollAnimator::ScrollAnimator::willEndLiveResize): Deleted.
(WebCore::ScrollAnimator::ScrollAnimator::didAddVerticalScrollbar): Deleted.
(WebCore::ScrollAnimator::ScrollAnimator::didAddHorizontalScrollbar): Deleted.

  • platform/ScrollTypes.h: Add ScrollBehaviorStatus to indicate the status of scrolling.
  • platform/ScrollView.cpp:

(WebCore::ScrollView::setScrollPosition): Follow the CSSOM View spec: If a scroll is in
progress, we interrupt it and continue the scroll call (even when we are at the final position).

  • platform/ScrollView.h:
  • platform/ScrollableArea.cpp:

(WebCore::ScrollableArea::scrollToOffsetWithAnimation):
(WebCore::ScrollableArea::setScrollOffsetFromInternals):
(WebCore::ScrollableArea::setScrollOffsetFromAnimation): To avoid iterate calling,
move the requestScrollPositionUpdate(position) checking out of setScrollOffsetFromAnimation().

  • platform/ScrollableArea.h:

(WebCore::ScrollableArea::currentScrollBehaviorStatus const): Maintain currentScrollBehaviorStatus.
(WebCore::ScrollableArea::setScrollBehaviorStatus):

  • platform/generic/ScrollAnimatorGeneric.cpp:

(WebCore::ScrollAnimatorGeneric::updatePosition):

  • platform/mac/ScrollAnimatorMac.mm:

(WebCore::ScrollAnimatorMac::cancelAnimations): Call parent member to handle programmatic scrolling.

  • rendering/RenderBox.cpp:

(WebCore::RenderBox::setScrollLeft): Add flag to indicate animated or not.
(WebCore::RenderBox::setScrollTop): Ditto.
(WebCore::RenderBox::setScrollPosition):

  • rendering/RenderBox.h:
  • rendering/RenderLayer.cpp:

(WebCore::RenderLayer::scrollToXPosition): Ditto.
(WebCore::RenderLayer::scrollToYPosition): Ditto.
(WebCore::RenderLayer::scrollToPosition):
(WebCore::RenderLayer::scrollToOffset): Follow the CSSOM View spec: If a scroll is in
progress, we interrupt it and continue the scroll call (even when we are at the final
position). It's ScrollBehaviorType::Instant scroll.
(WebCore::RenderLayer::requestScrollPositionUpdate):
(WebCore::RenderLayer::scrollToOffsetWithAnimation): Ditto. This is similar to scrollToOffset
but animates the scroll. It's ScrollBehaviorType::Smooth scroll.
(WebCore::RenderLayer::scrollTo):
(WebCore::RenderLayer::scrollRectToVisible): Again don't do an early return if scroll is in
progress. We call scrollToOffsetWithAnimation instead of scrollToOffset when appropriate.
Note that this function may not work well for several nested scroll boxes with at least one
element with smooth behavior. It will handled in bug Follow.

  • rendering/RenderLayer.h: Add scroll behavior to ScrollTectToVisibleOptions.
  • rendering/RenderListBox.cpp:

(WebCore::RenderListBox::setScrollLeft): Add animated flag.
(WebCore::RenderListBox::setScrollTop): Ditto.

  • rendering/RenderListBox.h:
  • rendering/RenderTextControlSingleLine.cpp:

(WebCore::RenderTextControlSingleLine::setScrollLeft):
(WebCore::RenderTextControlSingleLine::setScrollTop):

  • rendering/RenderTextControlSingleLine.h:
  • testing/Internals.cpp:

(WebCore::Internals::unconstrainedScrollTo):

LayoutTests:

  • platform/mac-wk1/TestExpectations: Skip these tests on WK1 as they don't work for now.
Location:
trunk
Files:
47 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r254803 r254807  
     12020-01-19  Cathie Chen  <cathiechen@igalia.com>
     2
     3        Add support for scroll behavior relies on ScrollAnimation of the Web process
     4        https://bugs.webkit.org/show_bug.cgi?id=204882
     5
     6        Reviewed by Frédéric Wang
     7
     8        Based on the patch by Frédéric Wang.
     9
     10        * platform/mac-wk1/TestExpectations: Skip these tests on WK1 as they don't work for now.
     11
    1122020-01-19  Diego Pino Garcia  <dpino@igalia.com>
    213
  • trunk/LayoutTests/imported/w3c/ChangeLog

    r254790 r254807  
     12020-01-19  Cathie Chen  <cathiechen@igalia.com>
     2
     3        Add support for scroll behavior relies on ScrollAnimation of the Web process
     4        https://bugs.webkit.org/show_bug.cgi?id=204882
     5
     6        Reviewed by Frédéric Wang
     7
     8        Based on the patch by Frédéric Wang.
     9
     10        Enable CSSOMViewSmoothScrollingEnabled on scroll behavior tests and update expectations.
     11
     12        * web-platform-tests/css/cssom-view/scroll-behavior-default-css-expected.txt:
     13        * web-platform-tests/css/cssom-view/scroll-behavior-default-css.html:
     14        * web-platform-tests/css/cssom-view/scroll-behavior-element-expected.txt:
     15        * web-platform-tests/css/cssom-view/scroll-behavior-element.html:
     16        * web-platform-tests/css/cssom-view/scroll-behavior-main-frame-root-expected.txt:
     17        * web-platform-tests/css/cssom-view/scroll-behavior-main-frame-root.html:
     18        * web-platform-tests/css/cssom-view/scroll-behavior-main-frame-window-expected.txt:
     19        * web-platform-tests/css/cssom-view/scroll-behavior-main-frame-window.html:
     20        * web-platform-tests/css/cssom-view/scroll-behavior-scrollintoview-nested-expected.txt:
     21        * web-platform-tests/css/cssom-view/scroll-behavior-scrollintoview-nested.html:
     22        * web-platform-tests/css/cssom-view/scroll-behavior-smooth-positions.html:
     23        * web-platform-tests/css/cssom-view/scroll-behavior-subframe-root-expected.txt:
     24        * web-platform-tests/css/cssom-view/scroll-behavior-subframe-root.html:
     25        * web-platform-tests/css/cssom-view/scroll-behavior-subframe-window-expected.txt:
     26        * web-platform-tests/css/cssom-view/scroll-behavior-subframe-window.html:
     27
    1282020-01-17  Cathie Chen  <cathiechen@igalia.com>
    229
  • trunk/LayoutTests/imported/w3c/web-platform-tests/css/cssom-view/scroll-behavior-default-css-expected.txt

    r236274 r254807  
    11
    22PASS Instant scrolling of an element with default scroll-behavior
    3 FAIL Smooth scrolling of an element with default scroll-behavior assert_less_than: Should not set scrollLeft immediately expected a number less than 500 but got 500
     3PASS Smooth scrolling of an element with default scroll-behavior
    44
  • trunk/LayoutTests/imported/w3c/web-platform-tests/css/cssom-view/scroll-behavior-default-css.html

    r254129 r254807  
    1 <!DOCTYPE html>
     1<!DOCTYPE html><!-- webkit-test-runner [ experimental:CSSOMViewSmoothScrollingEnabled=true ] -->
    22<title>Testing default value of scroll-behavior</title>
    33<meta name="timeout" content="long"/>
  • trunk/LayoutTests/imported/w3c/web-platform-tests/css/cssom-view/scroll-behavior-element-expected.txt

    r254129 r254807  
    33PASS Element with auto scroll-behavior ; scroll() with auto behavior
    44PASS Element with auto scroll-behavior ; scroll() with instant behavior
    5 FAIL Element with auto scroll-behavior ; scroll() with smooth behavior assert_less_than: Should not set scrollLeft immediately expected a number less than 500 but got 500
    6 FAIL Element with smooth scroll-behavior ; scroll() with default behavior assert_less_than: Should not set scrollLeft immediately expected a number less than 500 but got 500
    7 FAIL Element with smooth scroll-behavior ; scroll() with auto behavior assert_less_than: Should not set scrollLeft immediately expected a number less than 500 but got 500
     5PASS Element with auto scroll-behavior ; scroll() with smooth behavior
     6PASS Element with smooth scroll-behavior ; scroll() with default behavior
     7PASS Element with smooth scroll-behavior ; scroll() with auto behavior
    88PASS Element with smooth scroll-behavior ; scroll() with instant behavior
    9 FAIL Element with smooth scroll-behavior ; scroll() with smooth behavior assert_less_than: Should not set scrollLeft immediately expected a number less than 500 but got 500
     9PASS Element with smooth scroll-behavior ; scroll() with smooth behavior
    1010PASS Element with auto scroll-behavior ; scrollTo() with default behavior
    1111PASS Element with auto scroll-behavior ; scrollTo() with auto behavior
    1212PASS Element with auto scroll-behavior ; scrollTo() with instant behavior
    13 FAIL Element with auto scroll-behavior ; scrollTo() with smooth behavior assert_less_than: Should not set scrollLeft immediately expected a number less than 500 but got 500
    14 FAIL Element with smooth scroll-behavior ; scrollTo() with default behavior assert_less_than: Should not set scrollLeft immediately expected a number less than 500 but got 500
    15 FAIL Element with smooth scroll-behavior ; scrollTo() with auto behavior assert_less_than: Should not set scrollLeft immediately expected a number less than 500 but got 500
     13PASS Element with auto scroll-behavior ; scrollTo() with smooth behavior
     14PASS Element with smooth scroll-behavior ; scrollTo() with default behavior
     15PASS Element with smooth scroll-behavior ; scrollTo() with auto behavior
    1616PASS Element with smooth scroll-behavior ; scrollTo() with instant behavior
    17 FAIL Element with smooth scroll-behavior ; scrollTo() with smooth behavior assert_less_than: Should not set scrollLeft immediately expected a number less than 500 but got 500
     17PASS Element with smooth scroll-behavior ; scrollTo() with smooth behavior
    1818PASS Element with auto scroll-behavior ; scrollBy() with default behavior
    1919PASS Element with auto scroll-behavior ; scrollBy() with auto behavior
    2020PASS Element with auto scroll-behavior ; scrollBy() with instant behavior
    21 FAIL Element with auto scroll-behavior ; scrollBy() with smooth behavior assert_less_than: Should not set scrollLeft immediately expected a number less than 500 but got 500
    22 FAIL Element with smooth scroll-behavior ; scrollBy() with default behavior assert_less_than: Should not set scrollLeft immediately expected a number less than 500 but got 500
    23 FAIL Element with smooth scroll-behavior ; scrollBy() with auto behavior assert_less_than: Should not set scrollLeft immediately expected a number less than 500 but got 500
     21PASS Element with auto scroll-behavior ; scrollBy() with smooth behavior
     22PASS Element with smooth scroll-behavior ; scrollBy() with default behavior
     23PASS Element with smooth scroll-behavior ; scrollBy() with auto behavior
    2424PASS Element with smooth scroll-behavior ; scrollBy() with instant behavior
    25 FAIL Element with smooth scroll-behavior ; scrollBy() with smooth behavior assert_less_than: Should not set scrollLeft immediately expected a number less than 500 but got 500
     25PASS Element with smooth scroll-behavior ; scrollBy() with smooth behavior
    2626PASS Element with auto scroll-behavior ; scrollIntoView() with default behavior
    2727PASS Element with auto scroll-behavior ; scrollIntoView() with auto behavior
    2828PASS Element with auto scroll-behavior ; scrollIntoView() with instant behavior
    29 FAIL Element with auto scroll-behavior ; scrollIntoView() with smooth behavior assert_less_than: Should not set scrollLeft immediately expected a number less than 500 but got 500
    30 FAIL Element with smooth scroll-behavior ; scrollIntoView() with default behavior assert_less_than: Should not set scrollLeft immediately expected a number less than 500 but got 500
    31 FAIL Element with smooth scroll-behavior ; scrollIntoView() with auto behavior assert_less_than: Should not set scrollLeft immediately expected a number less than 500 but got 500
     29PASS Element with auto scroll-behavior ; scrollIntoView() with smooth behavior
     30PASS Element with smooth scroll-behavior ; scrollIntoView() with default behavior
     31PASS Element with smooth scroll-behavior ; scrollIntoView() with auto behavior
    3232PASS Element with smooth scroll-behavior ; scrollIntoView() with instant behavior
    33 FAIL Element with smooth scroll-behavior ; scrollIntoView() with smooth behavior assert_less_than: Should not set scrollLeft immediately expected a number less than 500 but got 500
     33PASS Element with smooth scroll-behavior ; scrollIntoView() with smooth behavior
    3434PASS Set scrollLeft to element with auto scroll-behavior
    35 FAIL Set scrollLeft to element with smooth scroll-behavior assert_less_than: Shouldn't set scroll attribute immediately expected a number less than 500 but got 500
     35PASS Set scrollLeft to element with smooth scroll-behavior
    3636PASS Set scrollTop to element with auto scroll-behavior
    37 FAIL Set scrollTop to element with smooth scroll-behavior assert_less_than: Shouldn't set scroll attribute immediately expected a number less than 250 but got 250
     37PASS Set scrollTop to element with smooth scroll-behavior
    3838PASS Aborting an ongoing smooth scrolling on an element with another smooth scrolling
    3939PASS Aborting an ongoing smooth scrolling on an element with an instant scrolling
  • trunk/LayoutTests/imported/w3c/web-platform-tests/css/cssom-view/scroll-behavior-element.html

    r254129 r254807  
    1 <!DOCTYPE html>
     1<!DOCTYPE html><!-- webkit-test-runner [ experimental:CSSOMViewSmoothScrollingEnabled=true ] -->
    22<title>Testing scrollOptions' behavior for Element.scroll* and scroll-behavior on an element</title>
    33<meta name="timeout" content="long"/>
  • trunk/LayoutTests/imported/w3c/web-platform-tests/css/cssom-view/scroll-behavior-main-frame-root-expected.txt

    r254129 r254807  
    44PASS Main frame with auto scroll-behavior ; scroll() with auto behavior
    55PASS Main frame with auto scroll-behavior ; scroll() with instant behavior
    6 FAIL Main frame with auto scroll-behavior ; scroll() with smooth behavior assert_less_than: Should not set scrollLeft immediately expected a number less than 2430 but got 2430
    7 FAIL Main frame with smooth scroll-behavior ; scroll() with default behavior assert_less_than: Should not set scrollLeft immediately expected a number less than 2430 but got 2430
    8 FAIL Main frame with smooth scroll-behavior ; scroll() with auto behavior assert_less_than: Should not set scrollLeft immediately expected a number less than 2430 but got 2430
     6PASS Main frame with auto scroll-behavior ; scroll() with smooth behavior
     7PASS Main frame with smooth scroll-behavior ; scroll() with default behavior
     8PASS Main frame with smooth scroll-behavior ; scroll() with auto behavior
    99PASS Main frame with smooth scroll-behavior ; scroll() with instant behavior
    10 FAIL Main frame with smooth scroll-behavior ; scroll() with smooth behavior assert_less_than: Should not set scrollLeft immediately expected a number less than 2430 but got 2430
     10PASS Main frame with smooth scroll-behavior ; scroll() with smooth behavior
    1111PASS Main frame with auto scroll-behavior ; scrollTo() with default behavior
    1212PASS Main frame with auto scroll-behavior ; scrollTo() with auto behavior
    1313PASS Main frame with auto scroll-behavior ; scrollTo() with instant behavior
    14 FAIL Main frame with auto scroll-behavior ; scrollTo() with smooth behavior assert_less_than: Should not set scrollLeft immediately expected a number less than 2430 but got 2430
    15 FAIL Main frame with smooth scroll-behavior ; scrollTo() with default behavior assert_less_than: Should not set scrollLeft immediately expected a number less than 2430 but got 2430
    16 FAIL Main frame with smooth scroll-behavior ; scrollTo() with auto behavior assert_less_than: Should not set scrollLeft immediately expected a number less than 2430 but got 2430
     14PASS Main frame with auto scroll-behavior ; scrollTo() with smooth behavior
     15PASS Main frame with smooth scroll-behavior ; scrollTo() with default behavior
     16PASS Main frame with smooth scroll-behavior ; scrollTo() with auto behavior
    1717PASS Main frame with smooth scroll-behavior ; scrollTo() with instant behavior
    18 FAIL Main frame with smooth scroll-behavior ; scrollTo() with smooth behavior assert_less_than: Should not set scrollLeft immediately expected a number less than 2430 but got 2430
     18PASS Main frame with smooth scroll-behavior ; scrollTo() with smooth behavior
    1919PASS Main frame with auto scroll-behavior ; scrollBy() with default behavior
    2020PASS Main frame with auto scroll-behavior ; scrollBy() with auto behavior
    2121PASS Main frame with auto scroll-behavior ; scrollBy() with instant behavior
    22 FAIL Main frame with auto scroll-behavior ; scrollBy() with smooth behavior assert_less_than: Should not set scrollLeft immediately expected a number less than 2430 but got 2430
    23 FAIL Main frame with smooth scroll-behavior ; scrollBy() with default behavior assert_less_than: Should not set scrollLeft immediately expected a number less than 2430 but got 2430
    24 FAIL Main frame with smooth scroll-behavior ; scrollBy() with auto behavior assert_less_than: Should not set scrollLeft immediately expected a number less than 2430 but got 2430
     22PASS Main frame with auto scroll-behavior ; scrollBy() with smooth behavior
     23PASS Main frame with smooth scroll-behavior ; scrollBy() with default behavior
     24PASS Main frame with smooth scroll-behavior ; scrollBy() with auto behavior
    2525PASS Main frame with smooth scroll-behavior ; scrollBy() with instant behavior
    26 FAIL Main frame with smooth scroll-behavior ; scrollBy() with smooth behavior assert_less_than: Should not set scrollLeft immediately expected a number less than 2430 but got 2430
     26PASS Main frame with smooth scroll-behavior ; scrollBy() with smooth behavior
    2727PASS Main frame with auto scroll-behavior ; scrollIntoView() with default behavior
    2828PASS Main frame with auto scroll-behavior ; scrollIntoView() with auto behavior
    2929PASS Main frame with auto scroll-behavior ; scrollIntoView() with instant behavior
    30 FAIL Main frame with auto scroll-behavior ; scrollIntoView() with smooth behavior assert_less_than: Should not set scrollLeft immediately expected a number less than 2430 but got 2430
    31 FAIL Main frame with smooth scroll-behavior ; scrollIntoView() with default behavior assert_less_than: Should not set scrollLeft immediately expected a number less than 2430 but got 2430
    32 FAIL Main frame with smooth scroll-behavior ; scrollIntoView() with auto behavior assert_less_than: Should not set scrollLeft immediately expected a number less than 2430 but got 2430
     30PASS Main frame with auto scroll-behavior ; scrollIntoView() with smooth behavior
     31PASS Main frame with smooth scroll-behavior ; scrollIntoView() with default behavior
     32PASS Main frame with smooth scroll-behavior ; scrollIntoView() with auto behavior
    3333PASS Main frame with smooth scroll-behavior ; scrollIntoView() with instant behavior
    34 FAIL Main frame with smooth scroll-behavior ; scrollIntoView() with smooth behavior assert_less_than: Should not set scrollLeft immediately expected a number less than 2430 but got 2430
     34PASS Main frame with smooth scroll-behavior ; scrollIntoView() with smooth behavior
    3535PASS Set scrollLeft to frame with auto scroll-behavior
    36 FAIL Set scrollLeft to frame with smooth scroll-behavior assert_less_than: Shouldn't set scroll attribute immediately expected a number less than 2430 but got 2430
     36PASS Set scrollLeft to frame with smooth scroll-behavior
    3737PASS Set scrollTop to frame with auto scroll-behavior
    38 FAIL Set scrollTop to frame with smooth scroll-behavior assert_less_than: Shouldn't set scroll attribute immediately expected a number less than 2480 but got 2480
     38PASS Set scrollTop to frame with smooth scroll-behavior
    3939PASS Aborting an ongoing smooth scrolling on the main frame with another smooth scrolling
    4040PASS Aborting an ongoing smooth scrolling on the main frame with an instant scrolling
  • trunk/LayoutTests/imported/w3c/web-platform-tests/css/cssom-view/scroll-behavior-main-frame-root.html

    r254129 r254807  
    1 <!DOCTYPE html>
     1<!DOCTYPE html><!-- webkit-test-runner [ experimental:CSSOMViewSmoothScrollingEnabled=true ] -->
    22<title>Testing scrollOptions' behavior for Element.scroll* and scroll-behavior on the root of the main frame</title>
    33<meta name="timeout" content="long"/>
  • trunk/LayoutTests/imported/w3c/web-platform-tests/css/cssom-view/scroll-behavior-main-frame-window-expected.txt

    r236274 r254807  
    44PASS Main frame with auto scroll-behavior ; scroll() with auto behavior
    55PASS Main frame with auto scroll-behavior ; scroll() with instant behavior
    6 FAIL Main frame with auto scroll-behavior ; scroll() with smooth behavior assert_less_than: Should not set scrollLeft immediately expected a number less than 2430 but got 2430
    7 FAIL Main frame with smooth scroll-behavior ; scroll() with default behavior assert_less_than: Should not set scrollLeft immediately expected a number less than 2430 but got 2430
    8 FAIL Main frame with smooth scroll-behavior ; scroll() with auto behavior assert_less_than: Should not set scrollLeft immediately expected a number less than 2430 but got 2430
     6PASS Main frame with auto scroll-behavior ; scroll() with smooth behavior
     7PASS Main frame with smooth scroll-behavior ; scroll() with default behavior
     8PASS Main frame with smooth scroll-behavior ; scroll() with auto behavior
    99PASS Main frame with smooth scroll-behavior ; scroll() with instant behavior
    10 FAIL Main frame with smooth scroll-behavior ; scroll() with smooth behavior assert_less_than: Should not set scrollLeft immediately expected a number less than 2430 but got 2430
     10PASS Main frame with smooth scroll-behavior ; scroll() with smooth behavior
    1111PASS Main frame with auto scroll-behavior ; scrollTo() with default behavior
    1212PASS Main frame with auto scroll-behavior ; scrollTo() with auto behavior
    1313PASS Main frame with auto scroll-behavior ; scrollTo() with instant behavior
    14 FAIL Main frame with auto scroll-behavior ; scrollTo() with smooth behavior assert_less_than: Should not set scrollLeft immediately expected a number less than 2430 but got 2430
    15 FAIL Main frame with smooth scroll-behavior ; scrollTo() with default behavior assert_less_than: Should not set scrollLeft immediately expected a number less than 2430 but got 2430
    16 FAIL Main frame with smooth scroll-behavior ; scrollTo() with auto behavior assert_less_than: Should not set scrollLeft immediately expected a number less than 2430 but got 2430
     14PASS Main frame with auto scroll-behavior ; scrollTo() with smooth behavior
     15PASS Main frame with smooth scroll-behavior ; scrollTo() with default behavior
     16PASS Main frame with smooth scroll-behavior ; scrollTo() with auto behavior
    1717PASS Main frame with smooth scroll-behavior ; scrollTo() with instant behavior
    18 FAIL Main frame with smooth scroll-behavior ; scrollTo() with smooth behavior assert_less_than: Should not set scrollLeft immediately expected a number less than 2430 but got 2430
     18PASS Main frame with smooth scroll-behavior ; scrollTo() with smooth behavior
    1919PASS Main frame with auto scroll-behavior ; scrollBy() with default behavior
    2020PASS Main frame with auto scroll-behavior ; scrollBy() with auto behavior
    2121PASS Main frame with auto scroll-behavior ; scrollBy() with instant behavior
    22 FAIL Main frame with auto scroll-behavior ; scrollBy() with smooth behavior assert_less_than: Should not set scrollLeft immediately expected a number less than 2430 but got 2430
    23 FAIL Main frame with smooth scroll-behavior ; scrollBy() with default behavior assert_less_than: Should not set scrollLeft immediately expected a number less than 2430 but got 2430
    24 FAIL Main frame with smooth scroll-behavior ; scrollBy() with auto behavior assert_less_than: Should not set scrollLeft immediately expected a number less than 2430 but got 2430
     22PASS Main frame with auto scroll-behavior ; scrollBy() with smooth behavior
     23PASS Main frame with smooth scroll-behavior ; scrollBy() with default behavior
     24PASS Main frame with smooth scroll-behavior ; scrollBy() with auto behavior
    2525PASS Main frame with smooth scroll-behavior ; scrollBy() with instant behavior
    26 FAIL Main frame with smooth scroll-behavior ; scrollBy() with smooth behavior assert_less_than: Should not set scrollLeft immediately expected a number less than 2430 but got 2430
     26PASS Main frame with smooth scroll-behavior ; scrollBy() with smooth behavior
    2727PASS Aborting an ongoing smooth scrolling on the main frame with another smooth scrolling
    2828PASS Aborting an ongoing smooth scrolling on the main frame with an instant scrolling
  • trunk/LayoutTests/imported/w3c/web-platform-tests/css/cssom-view/scroll-behavior-main-frame-window.html

    r254129 r254807  
    1 <!DOCTYPE html>
     1<!DOCTYPE html><!-- webkit-test-runner [ experimental:CSSOMViewSmoothScrollingEnabled=true ] -->
    22<title>Testing scrollOptions' behavior for Element.scroll* on the window of the main frame</title>
    33<meta name="timeout" content="long"/>
  • trunk/LayoutTests/imported/w3c/web-platform-tests/css/cssom-view/scroll-behavior-scrollintoview-nested-expected.txt

    r236274 r254807  
    11
    2 FAIL scrollIntoView with nested elements with different scroll-behavior assert_less_than: Element with smooth behavior should not scroll immediately expected a number less than 500 but got 500
     2PASS scrollIntoView with nested elements with different scroll-behavior
    33
  • trunk/LayoutTests/imported/w3c/web-platform-tests/css/cssom-view/scroll-behavior-scrollintoview-nested.html

    r254129 r254807  
    1 <!DOCTYPE html>
     1<!DOCTYPE html><!-- webkit-test-runner [ experimental:CSSOMViewSmoothScrollingEnabled=true ] -->
    22<title>Testing scrollOptions' behavior with scrollIntoView for nested scrolling nodes</title>
    33<meta name="timeout" content="long"/>
  • trunk/LayoutTests/imported/w3c/web-platform-tests/css/cssom-view/scroll-behavior-smooth-positions.html

    r254129 r254807  
    1 <!DOCTYPE html>
     1<!DOCTYPE html><!-- webkit-test-runner [ experimental:CSSOMViewSmoothScrollingEnabled=true ] -->
    22<title>Testing scroll positions when scrolling an element with smooth behavior</title>
    33<meta name="timeout" content="long"/>
  • trunk/LayoutTests/imported/w3c/web-platform-tests/css/cssom-view/scroll-behavior-subframe-root-expected.txt

    r254129 r254807  
    44PASS Subframe with auto scroll-behavior ; scroll() with auto behavior
    55PASS Subframe with auto scroll-behavior ; scroll() with instant behavior
    6 FAIL Subframe with auto scroll-behavior ; scroll() with smooth behavior assert_less_than: Should not set scrollLeft immediately expected a number less than 500 but got 500
    7 FAIL Subframe with smooth scroll-behavior ; scroll() with default behavior assert_less_than: Should not set scrollLeft immediately expected a number less than 500 but got 500
    8 FAIL Subframe with smooth scroll-behavior ; scroll() with auto behavior assert_less_than: Should not set scrollLeft immediately expected a number less than 500 but got 500
     6PASS Subframe with auto scroll-behavior ; scroll() with smooth behavior
     7PASS Subframe with smooth scroll-behavior ; scroll() with default behavior
     8PASS Subframe with smooth scroll-behavior ; scroll() with auto behavior
    99PASS Subframe with smooth scroll-behavior ; scroll() with instant behavior
    10 FAIL Subframe with smooth scroll-behavior ; scroll() with smooth behavior assert_less_than: Should not set scrollLeft immediately expected a number less than 500 but got 500
     10PASS Subframe with smooth scroll-behavior ; scroll() with smooth behavior
    1111PASS Subframe with auto scroll-behavior ; scrollTo() with default behavior
    1212PASS Subframe with auto scroll-behavior ; scrollTo() with auto behavior
    1313PASS Subframe with auto scroll-behavior ; scrollTo() with instant behavior
    14 FAIL Subframe with auto scroll-behavior ; scrollTo() with smooth behavior assert_less_than: Should not set scrollLeft immediately expected a number less than 500 but got 500
    15 FAIL Subframe with smooth scroll-behavior ; scrollTo() with default behavior assert_less_than: Should not set scrollLeft immediately expected a number less than 500 but got 500
    16 FAIL Subframe with smooth scroll-behavior ; scrollTo() with auto behavior assert_less_than: Should not set scrollLeft immediately expected a number less than 500 but got 500
     14PASS Subframe with auto scroll-behavior ; scrollTo() with smooth behavior
     15PASS Subframe with smooth scroll-behavior ; scrollTo() with default behavior
     16PASS Subframe with smooth scroll-behavior ; scrollTo() with auto behavior
    1717PASS Subframe with smooth scroll-behavior ; scrollTo() with instant behavior
    18 FAIL Subframe with smooth scroll-behavior ; scrollTo() with smooth behavior assert_less_than: Should not set scrollLeft immediately expected a number less than 500 but got 500
     18PASS Subframe with smooth scroll-behavior ; scrollTo() with smooth behavior
    1919PASS Subframe with auto scroll-behavior ; scrollBy() with default behavior
    2020PASS Subframe with auto scroll-behavior ; scrollBy() with auto behavior
    2121PASS Subframe with auto scroll-behavior ; scrollBy() with instant behavior
    22 FAIL Subframe with auto scroll-behavior ; scrollBy() with smooth behavior assert_less_than: Should not set scrollLeft immediately expected a number less than 500 but got 500
    23 FAIL Subframe with smooth scroll-behavior ; scrollBy() with default behavior assert_less_than: Should not set scrollLeft immediately expected a number less than 500 but got 500
    24 FAIL Subframe with smooth scroll-behavior ; scrollBy() with auto behavior assert_less_than: Should not set scrollLeft immediately expected a number less than 500 but got 500
     22PASS Subframe with auto scroll-behavior ; scrollBy() with smooth behavior
     23PASS Subframe with smooth scroll-behavior ; scrollBy() with default behavior
     24PASS Subframe with smooth scroll-behavior ; scrollBy() with auto behavior
    2525PASS Subframe with smooth scroll-behavior ; scrollBy() with instant behavior
    26 FAIL Subframe with smooth scroll-behavior ; scrollBy() with smooth behavior assert_less_than: Should not set scrollLeft immediately expected a number less than 500 but got 500
     26PASS Subframe with smooth scroll-behavior ; scrollBy() with smooth behavior
    2727PASS Subframe with auto scroll-behavior ; scrollIntoView() with default behavior
    2828PASS Subframe with auto scroll-behavior ; scrollIntoView() with auto behavior
    2929PASS Subframe with auto scroll-behavior ; scrollIntoView() with instant behavior
    30 FAIL Subframe with auto scroll-behavior ; scrollIntoView() with smooth behavior assert_less_than: Should not set scrollLeft immediately expected a number less than 500 but got 500
    31 FAIL Subframe with smooth scroll-behavior ; scrollIntoView() with default behavior assert_less_than: Should not set scrollLeft immediately expected a number less than 500 but got 500
    32 FAIL Subframe with smooth scroll-behavior ; scrollIntoView() with auto behavior assert_less_than: Should not set scrollLeft immediately expected a number less than 500 but got 500
     30PASS Subframe with auto scroll-behavior ; scrollIntoView() with smooth behavior
     31PASS Subframe with smooth scroll-behavior ; scrollIntoView() with default behavior
     32PASS Subframe with smooth scroll-behavior ; scrollIntoView() with auto behavior
    3333PASS Subframe with smooth scroll-behavior ; scrollIntoView() with instant behavior
    34 FAIL Subframe with smooth scroll-behavior ; scrollIntoView() with smooth behavior assert_less_than: Should not set scrollLeft immediately expected a number less than 500 but got 500
     34PASS Subframe with smooth scroll-behavior ; scrollIntoView() with smooth behavior
    3535PASS Subframe setting scrollLeft with auto scroll-behavior
    36 FAIL Subframe setting scrollLeft with smooth scroll-behavior assert_less_than: Should not set scrollLeft immediately expected a number less than 500 but got 500
     36PASS Subframe setting scrollLeft with smooth scroll-behavior
    3737PASS Subframe setting scrollTop with auto scroll-behavior
    38 FAIL Subframe setting scrollTop with smooth scroll-behavior assert_less_than: Should not set scrollTop immediately expected a number less than 250 but got 250
     38PASS Subframe setting scrollTop with smooth scroll-behavior
    3939PASS Aborting an ongoing smooth scrolling on a subframe with another smooth scrolling
    4040PASS Aborting an ongoing smooth scrolling on a subframe with an instant scrolling
  • trunk/LayoutTests/imported/w3c/web-platform-tests/css/cssom-view/scroll-behavior-subframe-root.html

    r254129 r254807  
    1 <!DOCTYPE html>
     1<!DOCTYPE html><!-- webkit-test-runner [ experimental:CSSOMViewSmoothScrollingEnabled=true ] -->
    22<title>Testing scrollOptions' behavior for Element.scroll* and scroll-behavior on the root of a subframe</title>
    33<meta name="timeout" content="long"/>
  • trunk/LayoutTests/imported/w3c/web-platform-tests/css/cssom-view/scroll-behavior-subframe-window-expected.txt

    r236274 r254807  
    44PASS Main frame with auto scroll-behavior ; scroll() with auto behavior
    55PASS Main frame with auto scroll-behavior ; scroll() with instant behavior
    6 FAIL Main frame with auto scroll-behavior ; scroll() with smooth behavior assert_less_than: Should not set scrollLeft immediately expected a number less than 500 but got 500
    7 FAIL Main frame with smooth scroll-behavior ; scroll() with default behavior assert_less_than: Should not set scrollLeft immediately expected a number less than 500 but got 500
    8 FAIL Main frame with smooth scroll-behavior ; scroll() with auto behavior assert_less_than: Should not set scrollLeft immediately expected a number less than 500 but got 500
     6PASS Main frame with auto scroll-behavior ; scroll() with smooth behavior
     7PASS Main frame with smooth scroll-behavior ; scroll() with default behavior
     8PASS Main frame with smooth scroll-behavior ; scroll() with auto behavior
    99PASS Main frame with smooth scroll-behavior ; scroll() with instant behavior
    10 FAIL Main frame with smooth scroll-behavior ; scroll() with smooth behavior assert_less_than: Should not set scrollLeft immediately expected a number less than 500 but got 500
     10PASS Main frame with smooth scroll-behavior ; scroll() with smooth behavior
    1111PASS Main frame with auto scroll-behavior ; scrollTo() with default behavior
    1212PASS Main frame with auto scroll-behavior ; scrollTo() with auto behavior
    1313PASS Main frame with auto scroll-behavior ; scrollTo() with instant behavior
    14 FAIL Main frame with auto scroll-behavior ; scrollTo() with smooth behavior assert_less_than: Should not set scrollLeft immediately expected a number less than 500 but got 500
    15 FAIL Main frame with smooth scroll-behavior ; scrollTo() with default behavior assert_less_than: Should not set scrollLeft immediately expected a number less than 500 but got 500
    16 FAIL Main frame with smooth scroll-behavior ; scrollTo() with auto behavior assert_less_than: Should not set scrollLeft immediately expected a number less than 500 but got 500
     14PASS Main frame with auto scroll-behavior ; scrollTo() with smooth behavior
     15PASS Main frame with smooth scroll-behavior ; scrollTo() with default behavior
     16PASS Main frame with smooth scroll-behavior ; scrollTo() with auto behavior
    1717PASS Main frame with smooth scroll-behavior ; scrollTo() with instant behavior
    18 FAIL Main frame with smooth scroll-behavior ; scrollTo() with smooth behavior assert_less_than: Should not set scrollLeft immediately expected a number less than 500 but got 500
     18PASS Main frame with smooth scroll-behavior ; scrollTo() with smooth behavior
    1919PASS Main frame with auto scroll-behavior ; scrollBy() with default behavior
    2020PASS Main frame with auto scroll-behavior ; scrollBy() with auto behavior
    2121PASS Main frame with auto scroll-behavior ; scrollBy() with instant behavior
    22 FAIL Main frame with auto scroll-behavior ; scrollBy() with smooth behavior assert_less_than: Should not set scrollLeft immediately expected a number less than 500 but got 500
    23 FAIL Main frame with smooth scroll-behavior ; scrollBy() with default behavior assert_less_than: Should not set scrollLeft immediately expected a number less than 500 but got 500
    24 FAIL Main frame with smooth scroll-behavior ; scrollBy() with auto behavior assert_less_than: Should not set scrollLeft immediately expected a number less than 500 but got 500
     22PASS Main frame with auto scroll-behavior ; scrollBy() with smooth behavior
     23PASS Main frame with smooth scroll-behavior ; scrollBy() with default behavior
     24PASS Main frame with smooth scroll-behavior ; scrollBy() with auto behavior
    2525PASS Main frame with smooth scroll-behavior ; scrollBy() with instant behavior
    26 FAIL Main frame with smooth scroll-behavior ; scrollBy() with smooth behavior assert_less_than: Should not set scrollLeft immediately expected a number less than 500 but got 500
     26PASS Main frame with smooth scroll-behavior ; scrollBy() with smooth behavior
    2727PASS Aborting an ongoing smooth scrolling on the main frame with another smooth scrolling
    2828PASS Aborting an ongoing smooth scrolling on the main frame with an instant scrolling
  • trunk/LayoutTests/imported/w3c/web-platform-tests/css/cssom-view/scroll-behavior-subframe-window.html

    r254129 r254807  
    1 <!DOCTYPE html>
     1<!DOCTYPE html><!-- webkit-test-runner [ experimental:CSSOMViewSmoothScrollingEnabled=true ] -->
    22<title>Testing scrollOptions' behavior for Element.scroll* and scroll-behavior on the root of a subframe</title>
    33<meta name="timeout" content="long"/>
  • trunk/LayoutTests/platform/mac-wk1/TestExpectations

    r254697 r254807  
    750750webkit.org/b/188070 imported/w3c/web-platform-tests/streams/piping/error-propagation-backward.html [ Pass Failure ]
    751751
     752# Tests for smooth scroll behavior do not all work and they are slow, so let's just skip them.
     753webkit.org/b/191357 imported/w3c/web-platform-tests/css/cssom-view/scroll-behavior-main-frame-root.html [ Skip ]
     754webkit.org/b/191357 imported/w3c/web-platform-tests/css/cssom-view/scroll-behavior-main-frame-window.html [ Skip ]
     755webkit.org/b/191357 imported/w3c/web-platform-tests/css/cssom-view/scroll-behavior-subframe-root.html [ Skip ]
     756webkit.org/b/191357 imported/w3c/web-platform-tests/css/cssom-view/scroll-behavior-subframe-window.html [ Skip ]
     757
    752758webkit.org/b/189908 imported/w3c/web-platform-tests/resource-timing/resource_timing.worker.html [ Failure ]
    753759
  • trunk/Source/WebCore/ChangeLog

    r254806 r254807  
     12020-01-19  Cathie Chen  <cathiechen@igalia.com>
     2
     3        Add support for scroll behavior relies on ScrollAnimation of the Web process
     4        https://bugs.webkit.org/show_bug.cgi?id=204882
     5
     6        Reviewed by Frédéric Wang
     7
     8        Based on the patch by Frédéric Wang.
     9
     10        This patch introduces a programmatic smooth scrolling in WebKit from the CSSOM View
     11        specification [1]. To use this effect, web developers can pass a behavior parameter (auto,
     12        smooth, or instant) to Element.scroll, Element.scrollTo, Element.scrollBy,
     13        Element.scrollIntoView, Window.scroll, Window.scrollTo or Window.scrollBy [2]. When behavior
     14        is auto, the instant/smooth characteristic is actually taken from the value of a new CSS
     15        scroll-behavior property [3]. Both the new CSS and DOM behavior are protected by a runtime
     16        flag.
     17
     18        [1] https://drafts.csswg.org/cssom-view
     19        [2] https://drafts.csswg.org/cssom-view/#dictdef-scrolloptions
     20        [3] https://drafts.csswg.org/cssom-view/#propdef-scroll-behavior
     21
     22        Tests: imported/w3c/web-platform-tests/css/cssom-view/scroll-behavior-default-css.html
     23               imported/w3c/web-platform-tests/css/cssom-view/scroll-behavior-element.html
     24               imported/w3c/web-platform-tests/css/cssom-view/scroll-behavior-main-frame-root.html
     25               imported/w3c/web-platform-tests/css/cssom-view/scroll-behavior-main-frame-window.html
     26               imported/w3c/web-platform-tests/css/cssom-view/scroll-behavior-scrollintoview-nested.html
     27               imported/w3c/web-platform-tests/css/cssom-view/scroll-behavior-smooth-positions.html
     28               imported/w3c/web-platform-tests/css/cssom-view/scroll-behavior-subframe-root.html
     29               imported/w3c/web-platform-tests/css/cssom-view/scroll-behavior-subframe-window.html
     30        * Sources.txt: Build ScrollAnimationSmooth.cpp on all platforms.
     31        * SourcesGTK.txt: Remove ScrollAnimationSmooth.cpp since it is built on all platforms now.
     32        * dom/Element.cpp:
     33        (WebCore::Element::scrollIntoView): Pass scroll behavior, if any.
     34        (WebCore::Element::scrollBy):
     35        (WebCore::Element::scrollTo): Handle the case when scroll behavior is smooth.
     36        (WebCore::Element::setScrollLeft): Handle the case when scroll behavior is smooth.
     37        (WebCore::Element::setScrollTop): Handle the case when scroll behavior is smooth.
     38        * page/DOMWindow.cpp:
     39        (WebCore::DOMWindow::scrollBy const):
     40        (WebCore::DOMWindow::scrollTo const): Handle the case when scroll behavior is smooth.
     41        The optimization of cancel (0, 0) scrolling is skipped if an animated scroll is in progress.
     42        Otherwise, the previous scroll won't be stopped by a follow-up scroll.
     43        * page/FrameView.cpp:
     44        (WebCore::FrameView::setScrollPosition):
     45        (WebCore::FrameView::scrollToOffsetWithAnimation): Start an animated scroll.
     46        * page/FrameView.h:
     47        * page/scrolling/AsyncScrollingCoordinator.cpp:
     48        (WebCore::AsyncScrollingCoordinator::requestScrollPositionUpdate):
     49        * platform/ScrollAnimation.h:
     50        (WebCore::ScrollAnimation::scroll): Function to animate scrolling to a specified position.
     51        * platform/ScrollAnimationSmooth.cpp: Build this file on all platforms. Add a
     52        smoothFactorForProgrammaticScroll parameter to slow down the smooth scrolling.
     53        (WebCore::ScrollAnimationSmooth::scroll):
     54        (WebCore::ScrollAnimationSmooth::updatePerAxisData): Scale the time parameters of the
     55        animation so that it looks smoother.
     56        * platform/ScrollAnimationSmooth.h: Declare the class on all platforms.
     57        * platform/ScrollAnimator.cpp:
     58        (WebCore::ScrollAnimator::ScrollAnimator): Initialize animation member for programmatic scrolling.
     59        (WebCore::ScrollAnimator::scrollToOffset): Animate scrolling to the specified position.
     60        (WebCore::ScrollAnimator::cancelAnimations): Copy logic from ScrollAnimationSmooth.cpp.
     61        (WebCore::ScrollAnimator::serviceScrollAnimations): Ditto.
     62        (WebCore::ScrollAnimator::willEndLiveResize): Ditto.
     63        (WebCore::ScrollAnimator::didAddVerticalScrollbar): Ditto.
     64        (WebCore::ScrollAnimator::didAddHorizontalScrollbar): Ditto.
     65        * platform/ScrollAnimator.h: New animation member for smooth programmatic scrolling.
     66        (WebCore::ScrollAnimator::ScrollAnimator::cancelAnimations): Deleted.
     67        (WebCore::ScrollAnimator::ScrollAnimator::serviceScrollAnimations): Deleted.
     68        (WebCore::ScrollAnimator::ScrollAnimator::willEndLiveResize): Deleted.
     69        (WebCore::ScrollAnimator::ScrollAnimator::didAddVerticalScrollbar): Deleted.
     70        (WebCore::ScrollAnimator::ScrollAnimator::didAddHorizontalScrollbar): Deleted.
     71        * platform/ScrollTypes.h: Add ScrollBehaviorStatus to indicate the status of scrolling.
     72        * platform/ScrollView.cpp:
     73        (WebCore::ScrollView::setScrollPosition): Follow the CSSOM View spec: If a scroll is in
     74        progress, we interrupt it and continue the scroll call (even when we are at the final position).
     75        * platform/ScrollView.h:
     76        * platform/ScrollableArea.cpp:
     77        (WebCore::ScrollableArea::scrollToOffsetWithAnimation):
     78        (WebCore::ScrollableArea::setScrollOffsetFromInternals):
     79        (WebCore::ScrollableArea::setScrollOffsetFromAnimation): To avoid iterate calling,
     80        move the requestScrollPositionUpdate(position) checking out of setScrollOffsetFromAnimation().
     81        * platform/ScrollableArea.h:
     82        (WebCore::ScrollableArea::currentScrollBehaviorStatus const): Maintain currentScrollBehaviorStatus.
     83        (WebCore::ScrollableArea::setScrollBehaviorStatus):
     84        * platform/generic/ScrollAnimatorGeneric.cpp:
     85        (WebCore::ScrollAnimatorGeneric::updatePosition):
     86        * platform/mac/ScrollAnimatorMac.mm:
     87        (WebCore::ScrollAnimatorMac::cancelAnimations): Call parent member to handle programmatic scrolling.
     88        * rendering/RenderBox.cpp:
     89        (WebCore::RenderBox::setScrollLeft): Add flag to indicate animated or not.
     90        (WebCore::RenderBox::setScrollTop): Ditto.
     91        (WebCore::RenderBox::setScrollPosition):
     92        * rendering/RenderBox.h:
     93        * rendering/RenderLayer.cpp:
     94        (WebCore::RenderLayer::scrollToXPosition): Ditto.
     95        (WebCore::RenderLayer::scrollToYPosition): Ditto.
     96        (WebCore::RenderLayer::scrollToPosition):
     97        (WebCore::RenderLayer::scrollToOffset): Follow the CSSOM View spec: If a scroll is in
     98        progress, we interrupt it and continue the scroll call (even when we are at the final
     99        position). It's ScrollBehaviorType::Instant scroll.
     100        (WebCore::RenderLayer::requestScrollPositionUpdate):
     101        (WebCore::RenderLayer::scrollToOffsetWithAnimation): Ditto. This is similar to scrollToOffset
     102        but animates the scroll. It's ScrollBehaviorType::Smooth scroll.
     103        (WebCore::RenderLayer::scrollTo):
     104        (WebCore::RenderLayer::scrollRectToVisible): Again don't do an early return if scroll is in
     105        progress. We call scrollToOffsetWithAnimation instead of scrollToOffset when appropriate.
     106        Note that this function may not work well for several nested scroll boxes with at least one
     107        element with smooth behavior. It will handled in bug Follow.
     108        * rendering/RenderLayer.h: Add scroll behavior to ScrollTectToVisibleOptions.
     109        * rendering/RenderListBox.cpp:
     110        (WebCore::RenderListBox::setScrollLeft): Add animated flag.
     111        (WebCore::RenderListBox::setScrollTop): Ditto.
     112        * rendering/RenderListBox.h:
     113        * rendering/RenderTextControlSingleLine.cpp:
     114        (WebCore::RenderTextControlSingleLine::setScrollLeft):
     115        (WebCore::RenderTextControlSingleLine::setScrollTop):
     116        * rendering/RenderTextControlSingleLine.h:
     117        * testing/Internals.cpp:
     118        (WebCore::Internals::unconstrainedScrollTo):
     119
    11202020-01-19  Antti Koivisto  <antti@apple.com>
    2121
  • trunk/Source/WebCore/Sources.txt

    r254806 r254807  
    17641764platform/SSLKeyGenerator.cpp
    17651765platform/ScrollAnimator.cpp
     1766platform/ScrollAnimationSmooth.cpp
    17661767platform/ScrollView.cpp
    17671768platform/ScrollableArea.cpp
  • trunk/Source/WebCore/SourcesGTK.txt

    r254064 r254807  
    6464
    6565platform/ScrollAnimationKinetic.cpp
    66 platform/ScrollAnimationSmooth.cpp
    6766platform/UserAgentQuirks.cpp
    6867
  • trunk/Source/WebCore/dom/Element.cpp

    r254700 r254807  
    841841    LayoutRect absoluteBounds = renderer()->absoluteAnchorRect(&insideFixed);
    842842
    843     // FIXME(webkit.org/b/188043): Support ScrollBehavior.
    844843    ScrollIntoViewOptions options;
    845844    if (arg) {
     
    860859        isHorizontal ? alignX : alignY,
    861860        isHorizontal ? alignY : alignX,
    862         ShouldAllowCrossOriginScrolling::No
     861        ShouldAllowCrossOriginScrolling::No,
     862        options.behavior.valueOr(ScrollBehavior::Auto)
    863863    };
    864864    renderer()->scrollRectToVisible(absoluteBounds, insideFixed, visibleOptions);
     
    921921void Element::scrollBy(double x, double y)
    922922{
    923     scrollBy({ x, y });
     923    scrollBy(ScrollToOptions(x, y));
    924924}
    925925
     
    957957        adjustForAbsoluteZoom(renderer->scrollTop(), *renderer)
    958958    );
    959     renderer->setScrollLeft(clampToInteger(scrollToOptions.left.value() * renderer->style().effectiveZoom()), ScrollType::Programmatic, clamping);
    960     renderer->setScrollTop(clampToInteger(scrollToOptions.top.value() * renderer->style().effectiveZoom()), ScrollType::Programmatic, clamping);
     959    IntPoint scrollPosition(
     960        clampToInteger(scrollToOptions.left.value() * renderer->style().effectiveZoom()),
     961        clampToInteger(scrollToOptions.top.value() * renderer->style().effectiveZoom())
     962    );
     963    bool animated = useSmoothScrolling(scrollToOptions.behavior.valueOr(ScrollBehavior::Auto), *this);
     964    renderer->setScrollPosition(scrollPosition, ScrollType::Programmatic, animated, clamping);
    961965}
    962966
    963967void Element::scrollTo(double x, double y)
    964968{
    965     scrollTo({ x, y });
     969    scrollTo(ScrollToOptions(x, y));
    966970}
    967971
     
    12971301
    12981302    if (document().scrollingElement() == this) {
    1299         if (auto* frame = documentFrameWithNonNullView())
    1300             frame->view()->setScrollPosition(IntPoint(static_cast<int>(newLeft * frame->pageZoomFactor() * frame->frameScaleFactor()), frame->view()->scrollY()));
     1303        if (auto* frame = documentFrameWithNonNullView()) {
     1304            // FIXME: Should we use document()->scrollingElement()?
     1305            // See https://bugs.webkit.org/show_bug.cgi?id=205059
     1306            bool animated = document().documentElement() && useSmoothScrolling(ScrollBehavior::Auto, *document().documentElement());
     1307            frame->view()->setScrollPosition(IntPoint(static_cast<int>(newLeft * frame->pageZoomFactor() * frame->frameScaleFactor()), frame->view()->scrollY()), animated);
     1308        }
    13011309        return;
    13021310    }
    13031311
    13041312    if (auto* renderer = renderBox()) {
    1305         renderer->setScrollLeft(static_cast<int>(newLeft * renderer->style().effectiveZoom()), ScrollType::Programmatic);
     1313        int clampedLeft = clampToInteger(newLeft * renderer->style().effectiveZoom());
     1314        bool animated = useSmoothScrolling(ScrollBehavior::Auto, *this);
     1315        renderer->setScrollLeft(clampedLeft, ScrollType::Programmatic, animated);
    13061316        if (auto* scrollableArea = renderer->layer())
    13071317            scrollableArea->setScrollShouldClearLatchedState(true);
     
    13141324
    13151325    if (document().scrollingElement() == this) {
    1316         if (auto* frame = documentFrameWithNonNullView())
    1317             frame->view()->setScrollPosition(IntPoint(frame->view()->scrollX(), static_cast<int>(newTop * frame->pageZoomFactor() * frame->frameScaleFactor())));
     1326        if (auto* frame = documentFrameWithNonNullView()) {
     1327            // FIXME: Should we use document()->scrollingElement()?
     1328            // See https://bugs.webkit.org/show_bug.cgi?id=205059
     1329            bool animated = document().documentElement() && useSmoothScrolling(ScrollBehavior::Auto, *document().documentElement());
     1330            frame->view()->setScrollPosition(IntPoint(frame->view()->scrollX(), static_cast<int>(newTop * frame->pageZoomFactor() * frame->frameScaleFactor())), animated);
     1331        }
    13181332        return;
    13191333    }
    13201334
    13211335    if (auto* renderer = renderBox()) {
    1322         renderer->setScrollTop(static_cast<int>(newTop * renderer->style().effectiveZoom()), ScrollType::Programmatic);
     1336        int clampedTop = clampToInteger(newTop * renderer->style().effectiveZoom());
     1337        bool animated = useSmoothScrolling(ScrollBehavior::Auto, *this);
     1338        renderer->setScrollTop(clampedTop, ScrollType::Programmatic, animated);
    13231339        if (auto* scrollableArea = renderer->layer())
    13241340            scrollableArea->setScrollShouldClearLatchedState(true);
  • trunk/Source/WebCore/page/DOMWindow.cpp

    r254753 r254807  
    16511651void DOMWindow::scrollBy(double x, double y) const
    16521652{
    1653     scrollBy({ x, y });
     1653    scrollBy(ScrollToOptions(x, y));
    16541654}
    16551655
     
    16731673void DOMWindow::scrollTo(double x, double y, ScrollClamping clamping) const
    16741674{
    1675     scrollTo({ x, y }, clamping);
    1676 }
    1677 
    1678 void DOMWindow::scrollTo(const ScrollToOptions& options, ScrollClamping) const
     1675    scrollTo(ScrollToOptions(x, y), clamping);
     1676}
     1677
     1678void DOMWindow::scrollTo(const ScrollToOptions& options, ScrollClamping clamping) const
    16791679{
    16801680    if (!isCurrentlyDisplayedInFrame())
     
    16891689    );
    16901690
    1691     if (!scrollToOptions.left.value() && !scrollToOptions.top.value() && view->contentsScrollPosition() == IntPoint(0, 0))
     1691    // This is an optimization for the common case of scrolling to (0, 0) when the scroller is already at the origin.
     1692    // If an animated scroll is in progress, this optimization is skipped to ensure that the animated scroll is really stopped.
     1693    if (view->currentScrollBehaviorStatus() == ScrollBehaviorStatus::NotInAnimation && !scrollToOptions.left.value() && !scrollToOptions.top.value() && view->contentsScrollPosition() == IntPoint(0, 0))
    16921694        return;
    16931695
     
    16951697
    16961698    IntPoint layoutPos(view->mapFromCSSToLayoutUnits(scrollToOptions.left.value()), view->mapFromCSSToLayoutUnits(scrollToOptions.top.value()));
     1699
     1700    // FIXME: Should we use document()->scrollingElement()?
     1701    // See https://bugs.webkit.org/show_bug.cgi?id=205059
     1702    if (document()->documentElement() && useSmoothScrolling(scrollToOptions.behavior.valueOr(ScrollBehavior::Auto), *document()->documentElement())) {
     1703        view->scrollToOffsetWithAnimation(layoutPos, ScrollType::Programmatic, clamping);
     1704        return;
     1705    }
     1706
    16971707    view->setContentsScrollPosition(layoutPos);
    16981708}
  • trunk/Source/WebCore/page/FrameView.cpp

    r254267 r254807  
    22802280}
    22812281
    2282 void FrameView::setScrollPosition(const ScrollPosition& scrollPosition)
     2282void FrameView::setScrollPosition(const ScrollPosition& scrollPosition, bool animated)
    22832283{
    22842284    LOG_WITH_STREAM(Scrolling, stream << "FrameView::setScrollPosition " << scrollPosition << " , clearing anchor");
     
    22932293    if (page && page->isMonitoringWheelEvents())
    22942294        scrollAnimator().setWheelEventTestMonitor(page->wheelEventTestMonitor());
    2295     ScrollView::setScrollPosition(scrollPosition);
     2295    if (animated)
     2296        scrollToOffsetWithAnimation(scrollOffsetFromPosition(scrollPosition), currentScrollType());
     2297    else
     2298        ScrollView::setScrollPosition(scrollPosition);
    22962299
    22972300    setCurrentScrollType(oldScrollType);
     
    36573660
    36583661    didChangeScrollOffset();
     3662}
     3663
     3664void FrameView::scrollToOffsetWithAnimation(const ScrollOffset& offset, ScrollType scrollType, ScrollClamping)
     3665{
     3666    auto previousScrollType = currentScrollType();
     3667    setCurrentScrollType(scrollType);
     3668
     3669    if (currentScrollBehaviorStatus() == ScrollBehaviorStatus::InNonNativeAnimation)
     3670        scrollAnimator().cancelAnimations();
     3671    if (offset != this->scrollOffset())
     3672        ScrollableArea::scrollToOffsetWithAnimation(offset);
     3673    setCurrentScrollType(previousScrollType);
    36593674}
    36603675
  • trunk/Source/WebCore/page/FrameView.h

    r253673 r254807  
    224224    WEBCORE_EXPORT void setFixedVisibleContentRect(const IntRect&) final;
    225225#endif
    226     WEBCORE_EXPORT void setScrollPosition(const ScrollPosition&) final;
     226    WEBCORE_EXPORT void setScrollPosition(const ScrollPosition&, bool animated = false) final;
    227227    void restoreScrollbar();
    228228    void scheduleScrollToFocusedElement(SelectionRevealMode);
     
    660660    void renderLayerDidScroll(const RenderLayer&);
    661661
     662    WEBCORE_EXPORT void scrollToOffsetWithAnimation(const ScrollOffset&, ScrollType = ScrollType::Programmatic, ScrollClamping = ScrollClamping::Clamped);
     663
    662664protected:
    663665    bool scrollContentsFastPath(const IntSize& scrollDelta, const IntRect& rectToScroll, const IntRect& clipRect) final;
  • trunk/Source/WebCore/platform/ScrollAnimation.h

    r248762 r254807  
    3333class FloatPoint;
    3434class ScrollableArea;
     35enum class ScrollClamping : uint8_t;
    3536
    3637class ScrollAnimation {
     
    3940    virtual ~ScrollAnimation() { };
    4041    virtual bool scroll(ScrollbarOrientation, ScrollGranularity, float /* step */, float /* multiplier */) { return true; };
     42    virtual void scroll(const FloatPoint&) { };
    4143    virtual void stop() = 0;
    4244    virtual void updateVisibleLengths() { };
  • trunk/Source/WebCore/platform/ScrollAnimationSmooth.cpp

    r229209 r254807  
    2929#include "ScrollAnimationSmooth.h"
    3030
    31 #if ENABLE(SMOOTH_SCROLLING)
    32 
    3331#include "FloatPoint.h"
    3432#include "ScrollableArea.h"
     
    3937static const Seconds tickTime = 1_s / frameRate;
    4038static const Seconds minimumTimerInterval { 1_ms };
     39static const double smoothFactorForProgrammaticScroll = 5;
    4140
    4241ScrollAnimationSmooth::ScrollAnimationSmooth(ScrollableArea& scrollableArea, const FloatPoint& position, WTF::Function<void (FloatPoint&&)>&& notifyPositionChangedFunction)
     
    6867}
    6968
     69void ScrollAnimationSmooth::scroll(const FloatPoint& position)
     70{
     71    ScrollGranularity granularity = ScrollByPage;
     72    bool needToScroll = updatePerAxisData(m_horizontalData, granularity, position.x() - m_horizontalData.currentPosition, m_scrollableArea.minimumScrollPosition().x(), m_scrollableArea.maximumScrollPosition().x(), smoothFactorForProgrammaticScroll);
     73    needToScroll |=
     74        updatePerAxisData(m_verticalData, granularity, position.y() - m_verticalData.currentPosition, m_scrollableArea.minimumScrollPosition().y(), m_scrollableArea.maximumScrollPosition().y(), smoothFactorForProgrammaticScroll);
     75    if (needToScroll && !animationTimerActive()) {
     76        m_startTime = m_horizontalData.startTime;
     77        animationTimerFired();
     78    }
     79};
     80
    7081void ScrollAnimationSmooth::stop()
    7182{
    7283    m_animationTimer.stop();
     84    m_scrollableArea.setScrollBehaviorStatus(ScrollBehaviorStatus::NotInAnimation);
    7385}
    7486
     
    248260}
    249261
    250 bool ScrollAnimationSmooth::updatePerAxisData(PerAxisData& data, ScrollGranularity granularity, float delta, float minScrollPosition, float maxScrollPosition)
     262bool ScrollAnimationSmooth::updatePerAxisData(PerAxisData& data, ScrollGranularity granularity, float delta, float minScrollPosition, float maxScrollPosition, double smoothFactor)
    251263{
    252264    if (!data.startTime || !delta || (delta < 0) != (data.desiredPosition - data.currentPosition < 0)) {
     
    264276    Curve coastTimeCurve;
    265277    getAnimationParametersForGranularity(granularity, animationTime, repeatMinimumSustainTime, attackTime, releaseTime, coastTimeCurve, maximumCoastTime);
     278
     279    animationTime *= smoothFactor;
     280    repeatMinimumSustainTime *= smoothFactor;
     281    attackTime *= smoothFactor;
     282    releaseTime *= smoothFactor;
     283    maximumCoastTime *= smoothFactor;
    266284
    267285    data.desiredPosition = newPosition;
     
    393411    if (continueAnimation)
    394412        startNextTimer(std::max(minimumTimerInterval, deltaToNextFrame));
     413    else
     414        m_scrollableArea.setScrollBehaviorStatus(ScrollBehaviorStatus::NotInAnimation);
    395415
    396416    m_notifyPositionChangedFunction(FloatPoint(m_horizontalData.currentPosition, m_verticalData.currentPosition));
     
    408428
    409429} // namespace WebCore
    410 
    411 #endif // ENABLE(SMOOTH_SCROLLING)
  • trunk/Source/WebCore/platform/ScrollAnimationSmooth.h

    r218615 r254807  
    2828#include "ScrollAnimation.h"
    2929
    30 #if ENABLE(SMOOTH_SCROLLING)
    31 
    3230#include "Timer.h"
    3331
     
    3634class FloatPoint;
    3735class ScrollableArea;
     36enum class ScrollClamping : uint8_t;
    3837
    3938class ScrollAnimationSmooth final: public ScrollAnimation {
     
    5251private:
    5352    bool scroll(ScrollbarOrientation, ScrollGranularity, float step, float multiplier) override;
     53    void scroll(const FloatPoint&) override;
    5454    void stop() override;
    5555    void updateVisibleLengths() override;
     
    9090    };
    9191
    92     bool updatePerAxisData(PerAxisData&, ScrollGranularity, float delta, float minScrollPosition, float maxScrollPosition);
     92    bool updatePerAxisData(PerAxisData&, ScrollGranularity, float delta, float minScrollPosition, float maxScrollPosition, double smoothFactor = 1);
    9393    bool animateScroll(PerAxisData&, MonotonicTime currentTime);
    9494
     
    109109} // namespace WebCore
    110110
    111 #endif // ENABLE(SMOOTH_SCROLLING)
  • trunk/Source/WebCore/platform/ScrollAnimator.cpp

    r250946 r254807  
    3636#include "LayoutSize.h"
    3737#include "PlatformWheelEvent.h"
     38#include "ScrollAnimationSmooth.h"
    3839#include "ScrollableArea.h"
    3940#include <algorithm>
     
    5354    , m_scrollController(*this)
    5455#endif
     56    , m_animationProgrammaticScroll(makeUnique<ScrollAnimationSmooth>(scrollableArea, m_currentPosition, [this](FloatPoint&& position) {
     57        auto previousScrollType = m_scrollableArea.currentScrollType();
     58        m_scrollableArea.setCurrentScrollType(ScrollType::Programmatic);
     59        bool updated = m_scrollableArea.requestScrollPositionUpdate(roundedIntPoint(position));
     60        m_scrollableArea.setCurrentScrollType(previousScrollType);
     61        if (updated)
     62            return;
     63
     64        FloatSize delta = position - m_currentPosition;
     65        m_currentPosition = WTFMove(position);
     66        notifyPositionChanged(delta);
     67    }))
    5568{
    5669}
     
    7487    notifyPositionChanged(newPosition - currentPosition);
    7588    return true;
     89}
     90
     91void ScrollAnimator::scrollToOffset(const FloatPoint& offset)
     92{
     93    m_animationProgrammaticScroll->setCurrentPosition(m_currentPosition);
     94    auto newPosition = ScrollableArea::scrollPositionFromOffset(offset, toFloatSize(m_scrollableArea.scrollOrigin()));
     95    m_animationProgrammaticScroll->scroll(newPosition);
     96    m_scrollableArea.setScrollBehaviorStatus(ScrollBehaviorStatus::InNonNativeAnimation);
    7697}
    7798
     
    246267#endif
    247268
     269void ScrollAnimator::cancelAnimations()
     270{
     271#if !USE(REQUEST_ANIMATION_FRAME_TIMER)
     272    m_animationProgrammaticScroll->stop();
     273#endif
     274}
     275
     276void ScrollAnimator::serviceScrollAnimations()
     277{
     278#if !USE(REQUEST_ANIMATION_FRAME_TIMER)
     279    m_animationProgrammaticScroll->serviceAnimation();
     280#endif
     281}
     282
     283void ScrollAnimator::willEndLiveResize()
     284{
     285    m_animationProgrammaticScroll->updateVisibleLengths();
     286}
     287
     288void ScrollAnimator::didAddVerticalScrollbar(Scrollbar*)
     289{
     290    m_animationProgrammaticScroll->updateVisibleLengths();
     291}
     292
     293void ScrollAnimator::didAddHorizontalScrollbar(Scrollbar*)
     294{
     295    m_animationProgrammaticScroll->updateVisibleLengths();
     296}
     297
    248298} // namespace WebCore
  • trunk/Source/WebCore/platform/ScrollAnimator.h

    r250946 r254807  
    4747class FloatPoint;
    4848class PlatformTouchEvent;
     49class ScrollAnimation;
    4950class ScrollableArea;
    5051class Scrollbar;
     
    6970    virtual bool scroll(ScrollbarOrientation, ScrollGranularity, float step, float multiplier);
    7071
     72    void scrollToOffset(const FloatPoint&);
    7173    virtual void scrollToOffsetWithoutAnimation(const FloatPoint&, ScrollClamping = ScrollClamping::Clamped);
    7274
     
    8688    const FloatPoint& currentPosition() const { return m_currentPosition; }
    8789
    88     virtual void cancelAnimations() { }
    89     virtual void serviceScrollAnimations() { }
     90    virtual void cancelAnimations();
     91    virtual void serviceScrollAnimations();
    9092
    9193    virtual void contentAreaWillPaint() const { }
     
    98100    virtual void willStartLiveResize() { }
    99101    virtual void contentsResized() const { }
    100     virtual void willEndLiveResize() { }
     102    virtual void willEndLiveResize();
    101103    virtual void contentAreaDidShow() { }
    102104    virtual void contentAreaDidHide() { }
     
    105107    virtual bool scrollbarsCanBeActive() const { return true; }
    106108
    107     virtual void didAddVerticalScrollbar(Scrollbar*) { }
     109    virtual void didAddVerticalScrollbar(Scrollbar*);
    108110    virtual void willRemoveVerticalScrollbar(Scrollbar*) { }
    109     virtual void didAddHorizontalScrollbar(Scrollbar*) { }
     111    virtual void didAddHorizontalScrollbar(Scrollbar*);
    110112    virtual void willRemoveHorizontalScrollbar(Scrollbar*) { }
    111113
     
    152154#endif
    153155    FloatPoint m_currentPosition;
     156
     157    std::unique_ptr<ScrollAnimation> m_animationProgrammaticScroll;
    154158};
    155159
  • trunk/Source/WebCore/platform/ScrollTypes.h

    r243701 r254807  
    5555};
    5656
     57// FIXME: Add another status InNativeAnimation to indicate native scrolling is in progress.
     58// See: https://bugs.webkit.org/show_bug.cgi?id=204936
     59enum class ScrollBehaviorStatus : uint8_t {
     60    NotInAnimation,
     61    InNonNativeAnimation,
     62};
     63
    5764inline ScrollDirection logicalToPhysical(ScrollLogicalDirection direction, bool isVertical, bool isFlipped)
    5865{
  • trunk/Source/WebCore/platform/ScrollView.cpp

    r253689 r254807  
    519519}
    520520
    521 void ScrollView::setScrollPosition(const ScrollPosition& scrollPosition)
     521void ScrollView::setScrollPosition(const ScrollPosition& scrollPosition, bool/* animated*/)
    522522{
    523523    LOG_WITH_STREAM(Scrolling, stream << "ScrollView::setScrollPosition " << scrollPosition);
     
    533533    ScrollPosition newScrollPosition = !delegatesScrolling() ? adjustScrollPositionWithinRange(scrollPosition) : scrollPosition;
    534534
    535     if ((!delegatesScrolling() || currentScrollType() == ScrollType::User) && newScrollPosition == this->scrollPosition())
    536         return;
    537 
    538     if (requestScrollPositionUpdate(newScrollPosition))
    539         return;
     535    if ((!delegatesScrolling() || currentScrollType() == ScrollType::User) && currentScrollBehaviorStatus() == ScrollBehaviorStatus::NotInAnimation && newScrollPosition == this->scrollPosition())
     536        return;
     537
     538    if (currentScrollBehaviorStatus() == ScrollBehaviorStatus::InNonNativeAnimation)
     539        scrollAnimator().cancelAnimations();
     540
     541    if (requestScrollPositionUpdate(newScrollPosition)) {
     542        setScrollBehaviorStatus(ScrollBehaviorStatus::NotInAnimation);
     543        return;
     544    }
    540545
    541546    updateScrollbars(newScrollPosition);
     547    setScrollBehaviorStatus(ScrollBehaviorStatus::NotInAnimation);
    542548}
    543549
     
    596602    if (!managesScrollbars()) {
    597603        if (scrollOriginChanged()) {
    598             ScrollableArea::scrollToOffsetWithoutAnimation(scrollOffsetFromPosition(desiredPosition));
     604            if (!requestScrollPositionUpdate(desiredPosition))
     605                ScrollableArea::scrollToOffsetWithoutAnimation(scrollOffsetFromPosition(desiredPosition));
    599606            resetScrollOriginChanged();
    600607        }
  • trunk/Source/WebCore/platform/ScrollView.h

    r254497 r254807  
    265265
    266266    // Functions for scrolling the view.
    267     virtual void setScrollPosition(const ScrollPosition&);
     267    virtual void setScrollPosition(const ScrollPosition&, bool animated = false);
    268268    void scrollBy(const IntSize& s) { return setScrollPosition(scrollPosition() + s); }
    269269
  • trunk/Source/WebCore/platform/ScrollableArea.cpp

    r254087 r254807  
    143143}
    144144
     145void ScrollableArea::scrollToOffsetWithAnimation(const FloatPoint& offset, ScrollClamping)
     146{
     147    LOG_WITH_STREAM(Scrolling, stream << "ScrollableArea " << this << " scrollToOffsetWithAnimation " << offset);
     148    scrollAnimator().scrollToOffset(offset);
     149}
     150
    145151void ScrollableArea::scrollToOffsetWithoutAnimation(const FloatPoint& offset, ScrollClamping clamping)
    146152{
     
    222228void ScrollableArea::setScrollOffsetFromInternals(const ScrollOffset& offset)
    223229{
     230    if (requestScrollPositionUpdate(scrollPositionFromOffset(offset)))
     231        return;
     232
    224233    setScrollOffsetFromAnimation(offset);
    225234}
     
    227236void ScrollableArea::setScrollOffsetFromAnimation(const ScrollOffset& offset)
    228237{
    229     ScrollPosition position = scrollPositionFromOffset(offset);
    230     if (requestScrollPositionUpdate(position))
    231         return;
    232 
    233     scrollPositionChanged(position);
     238    scrollPositionChanged(scrollPositionFromOffset(offset));
    234239}
    235240
  • trunk/Source/WebCore/platform/ScrollableArea.h

    r254497 r254807  
    6363class ScrollableArea : public CanMakeWeakPtr<ScrollableArea> {
    6464public:
     65    ScrollBehaviorStatus currentScrollBehaviorStatus() { return m_currentScrollBehaviorStatus; }
     66    void setScrollBehaviorStatus(ScrollBehaviorStatus status) { m_currentScrollBehaviorStatus = status; }
     67
    6568    WEBCORE_EXPORT bool scroll(ScrollDirection, ScrollGranularity, float multiplier = 1);
     69    WEBCORE_EXPORT void scrollToOffsetWithAnimation(const FloatPoint&, ScrollClamping = ScrollClamping::Clamped);
    6670    WEBCORE_EXPORT void scrollToOffsetWithoutAnimation(const FloatPoint&, ScrollClamping = ScrollClamping::Clamped);
    6771    void scrollToOffsetWithoutAnimation(ScrollbarOrientation, float offset);
     
    380384#endif
    381385
     386    ScrollBehaviorStatus m_currentScrollBehaviorStatus { ScrollBehaviorStatus::NotInAnimation };
     387
    382388    // There are 8 possible combinations of writing mode and direction. Scroll origin will be non-zero in the x or y axis
    383389    // if there is any reversed direction or writing-mode. The combinations are:
  • trunk/Source/WebCore/platform/generic/ScrollAnimatorGeneric.cpp

    r248846 r254807  
    163163void ScrollAnimatorGeneric::updatePosition(FloatPoint&& position)
    164164{
     165    if (m_scrollableArea.requestScrollPositionUpdate(roundedIntPoint(position)))
     166        return;
    165167    FloatSize delta = position - m_currentPosition;
    166168    m_currentPosition = WTFMove(position);
  • trunk/Source/WebCore/platform/graphics/cg/PDFDocumentImage.cpp

    r254778 r254807  
    4949#include <wtf/text/TextStream.h>
    5050
    51 #if !PLATFORM(COCOA)
     51#if PLATFORM(COCOA)
     52#import <pal/spi/cg/CoreGraphicsSPI.h>
     53#else
    5254#include "ImageSourceCG.h"
    5355#endif
  • trunk/Source/WebCore/platform/mac/ScrollAnimatorMac.mm

    r254241 r254807  
    11571157void ScrollAnimatorMac::cancelAnimations()
    11581158{
     1159    ScrollAnimator::cancelAnimations();
    11591160    m_haveScrolledSincePageLoad = false;
    11601161
  • trunk/Source/WebCore/rendering/RenderBox.cpp

    r253521 r254807  
    582582}
    583583
    584 void RenderBox::setScrollLeft(int newLeft, ScrollType scrollType, ScrollClamping clamping)
     584void RenderBox::setScrollLeft(int newLeft, ScrollType scrollType, bool animated, ScrollClamping clamping)
    585585{
    586586    if (!hasOverflowClip() || !layer())
    587587        return;
    588588    setupWheelEventMonitor(*layer());
    589     layer()->scrollToXPosition(newLeft, scrollType, clamping);
    590 }
    591 
    592 void RenderBox::setScrollTop(int newTop, ScrollType scrollType, ScrollClamping clamping)
     589    layer()->scrollToXPosition(newLeft, scrollType, animated, clamping);
     590}
     591
     592void RenderBox::setScrollTop(int newTop, ScrollType scrollType, bool animated, ScrollClamping clamping)
    593593{
    594594    if (!hasOverflowClip() || !layer())
    595595        return;
    596596    setupWheelEventMonitor(*layer());
    597     layer()->scrollToYPosition(newTop, scrollType, clamping);
     597    layer()->scrollToYPosition(newTop, scrollType, animated, clamping);
     598}
     599
     600void RenderBox::setScrollPosition(const ScrollPosition& position, ScrollType scrollType, bool animated, ScrollClamping clamping)
     601{
     602    if (!hasOverflowClip() || !layer())
     603        return;
     604    setupWheelEventMonitor(*layer());
     605    layer()->scrollToPosition(position, scrollType, animated, clamping);
    598606}
    599607
  • trunk/Source/WebCore/rendering/RenderBox.h

    r252965 r254807  
    248248    virtual int scrollWidth() const;
    249249    virtual int scrollHeight() const;
    250     virtual void setScrollLeft(int, ScrollType, ScrollClamping = ScrollClamping::Clamped);
    251     virtual void setScrollTop(int, ScrollType, ScrollClamping = ScrollClamping::Clamped);
     250    virtual void setScrollLeft(int, ScrollType, bool animated = false, ScrollClamping = ScrollClamping::Clamped);
     251    virtual void setScrollTop(int, ScrollType, bool animated = false, ScrollClamping = ScrollClamping::Clamped);
     252    void setScrollPosition(const ScrollPosition&, ScrollType, bool animated = false, ScrollClamping = ScrollClamping::Clamped);
    252253
    253254    LayoutUnit marginTop() const override { return m_marginBox.top(); }
  • trunk/Source/WebCore/rendering/RenderLayer.cpp

    r254087 r254807  
    25802580}
    25812581
    2582 void RenderLayer::scrollToXPosition(int x, ScrollType scrollType, ScrollClamping clamping)
     2582void RenderLayer::scrollToXPosition(int x, ScrollType scrollType, bool animated, ScrollClamping clamping)
    25832583{
    25842584    ScrollPosition position(x, m_scrollPosition.y());
    2585     scrollToOffset(scrollOffsetFromPosition(position), scrollType, clamping);
    2586 }
    2587 
    2588 void RenderLayer::scrollToYPosition(int y, ScrollType scrollType, ScrollClamping clamping)
     2585    scrollToPosition(position, scrollType, animated, clamping);
     2586}
     2587
     2588void RenderLayer::scrollToYPosition(int y, ScrollType scrollType, bool animated, ScrollClamping clamping)
    25892589{
    25902590    ScrollPosition position(m_scrollPosition.x(), y);
    2591     scrollToOffset(scrollOffsetFromPosition(position), scrollType, clamping);
     2591    scrollToPosition(position, scrollType, animated, clamping);
     2592}
     2593
     2594void RenderLayer::scrollToPosition(const ScrollPosition& position, ScrollType scrollType, bool animated, ScrollClamping clamping)
     2595{
     2596    if (animated)
     2597        scrollToOffsetWithAnimation(scrollOffsetFromPosition(position), scrollType, clamping);
     2598    else
     2599        scrollToOffset(scrollOffsetFromPosition(position), scrollType, clamping);
    25922600}
    25932601
     
    25992607void RenderLayer::scrollToOffset(const ScrollOffset& scrollOffset, ScrollType scrollType, ScrollClamping clamping)
    26002608{
     2609    if (currentScrollBehaviorStatus() == ScrollBehaviorStatus::InNonNativeAnimation)
     2610        scrollAnimator().cancelAnimations();
     2611
    26012612    ScrollOffset clampedScrollOffset = clamping == ScrollClamping::Clamped ? clampScrollOffset(scrollOffset) : scrollOffset;
    26022613    if (clampedScrollOffset == this->scrollOffset())
     
    26082619    bool handled = false;
    26092620#if ENABLE(ASYNC_SCROLLING)
    2610     if (ScrollingCoordinator* scrollingCoordinator = page().scrollingCoordinator())
    2611         handled = scrollingCoordinator->requestScrollPositionUpdate(*this, scrollPositionFromOffset(clampedScrollOffset));
     2621    handled = requestScrollPositionUpdate(scrollPositionFromOffset(clampedScrollOffset));
    26122622#endif
    26132623
    26142624    if (!handled)
    26152625        scrollToOffsetWithoutAnimation(clampedScrollOffset, clamping);
    2616 
     2626    setScrollBehaviorStatus(ScrollBehaviorStatus::NotInAnimation);
     2627
     2628    setCurrentScrollType(previousScrollType);
     2629}
     2630
     2631bool RenderLayer::requestScrollPositionUpdate(const ScrollPosition& position)
     2632{
     2633#if ENABLE(ASYNC_SCROLLING)
     2634    if (ScrollingCoordinator* scrollingCoordinator = page().scrollingCoordinator())
     2635        return scrollingCoordinator->requestScrollPositionUpdate(*this, position);
     2636#endif
     2637    return false;
     2638}
     2639
     2640void RenderLayer::scrollToOffsetWithAnimation(const ScrollOffset& offset, ScrollType scrollType, ScrollClamping clamping)
     2641{
     2642    auto previousScrollType = currentScrollType();
     2643    setCurrentScrollType(scrollType);
     2644
     2645    ScrollOffset newScrollOffset = clamping == ScrollClamping::Clamped ? clampScrollOffset(offset) : offset;
     2646    if (currentScrollBehaviorStatus() == ScrollBehaviorStatus::InNonNativeAnimation)
     2647        scrollAnimator().cancelAnimations();
     2648    if (newScrollOffset != this->scrollOffset())
     2649        ScrollableArea::scrollToOffsetWithAnimation(newScrollOffset);
    26172650    setCurrentScrollType(previousScrollType);
    26182651}
     
    26502683    }
    26512684   
    2652     if (m_scrollPosition == newPosition) {
     2685    if (m_scrollPosition == newPosition && currentScrollBehaviorStatus() == ScrollBehaviorStatus::NotInAnimation) {
    26532686        // FIXME: Nothing guarantees we get a scrollTo() with an unchanged position at the end of a user gesture.
    26542687        // The ScrollingCoordinator probably needs to message the main thread when a gesture ends.
     
    27952828
    27962829        ScrollOffset clampedScrollOffset = clampScrollOffset(scrollOffset() + toIntSize(roundedIntRect(revealRect).location()));
    2797         if (clampedScrollOffset != scrollOffset()) {
     2830        if (currentScrollBehaviorStatus() != ScrollBehaviorStatus::NotInAnimation || clampedScrollOffset != scrollOffset()) {
    27982831            ScrollOffset oldScrollOffset = scrollOffset();
    2799             scrollToOffset(clampedScrollOffset);
    2800             IntSize scrollOffsetDifference = scrollOffset() - oldScrollOffset;
     2832            bool animated = (box->element() && useSmoothScrolling(options.behavior, *box->element()));
     2833            scrollToPosition(scrollPositionFromOffset(clampedScrollOffset), ScrollType::Programmatic, animated);
     2834            IntSize scrollOffsetDifference = clampedScrollOffset - oldScrollOffset;
    28012835            localExposeRect.move(-scrollOffsetDifference);
    28022836            newRect = LayoutRect(box->localToAbsoluteQuad(FloatQuad(FloatRect(localExposeRect)), UseTransforms).boundingBox());
     
    28182852                LayoutRect exposeRect = getRectToExpose(viewRect, absoluteRect, insideFixed, options.alignX, options.alignY);
    28192853
    2820                 IntPoint scrollOffset(roundedIntPoint(exposeRect.location()));
     2854                IntPoint scrollPosition(roundedIntPoint(exposeRect.location()));
    28212855                // Adjust offsets if they're outside of the allowable range.
    2822                 scrollOffset = scrollOffset.constrainedBetween(IntPoint(), IntPoint(frameView.contentsSize()));
    2823                 frameView.setScrollPosition(scrollOffset);
     2856                scrollPosition = scrollPosition.constrainedBetween(IntPoint(), IntPoint(frameView.contentsSize()));
     2857                // FIXME: Should we use contentDocument()->scrollingElement()?
     2858                // See https://bugs.webkit.org/show_bug.cgi?id=205059
     2859                bool animated = ownerElement->contentDocument() && ownerElement->contentDocument()->documentElement() && useSmoothScrolling(options.behavior, *ownerElement->contentDocument()->documentElement());
     2860                frameView.setScrollPosition(scrollPosition, animated);
    28242861
    28252862                if (options.shouldAllowCrossOriginScrolling == ShouldAllowCrossOriginScrolling::Yes || frameView.safeToPropagateScrollToParent()) {
     
    28602897            if (revealRect != viewRect) {
    28612898                ScrollOffset clampedScrollPosition = roundedIntPoint(revealRect.location()).constrainedBetween(minScrollPosition, maxScrollPosition);
    2862                 frameView.setScrollPosition(clampedScrollPosition);
     2899                // FIXME: Should we use document()->scrollingElement()?
     2900                // See https://bugs.webkit.org/show_bug.cgi?id=205059
     2901                bool animated = renderer().document().documentElement() && useSmoothScrolling(options.behavior, *renderer().document().documentElement());
     2902                frameView.setScrollPosition(clampedScrollPosition, animated);
    28632903            }
    28642904
  • trunk/Source/WebCore/rendering/RenderLayer.h

    r254087 r254807  
    5151#include "RenderBox.h"
    5252#include "RenderPtr.h"
     53#include "ScrollBehavior.h"
    5354#include "ScrollableArea.h"
    5455#include <memory>
     
    135136    const ScrollAlignment& alignY { ScrollAlignment::alignCenterIfNeeded };
    136137    ShouldAllowCrossOriginScrolling shouldAllowCrossOriginScrolling { ShouldAllowCrossOriginScrolling::No };
     138    ScrollBehavior behavior { ScrollBehavior::Auto };
    137139};
    138140
     
    441443
    442444    WEBCORE_EXPORT void scrollToOffset(const ScrollOffset&, ScrollType = ScrollType::Programmatic, ScrollClamping = ScrollClamping::Clamped);
    443 
    444     void scrollToXPosition(int x, ScrollType, ScrollClamping = ScrollClamping::Clamped);
    445     void scrollToYPosition(int y, ScrollType, ScrollClamping = ScrollClamping::Clamped);
     445    WEBCORE_EXPORT void scrollToOffsetWithAnimation(const ScrollOffset&, ScrollType = ScrollType::Programmatic, ScrollClamping = ScrollClamping::Clamped);
     446
     447    bool requestScrollPositionUpdate(const ScrollPosition&) override;
     448
     449    void scrollToXPosition(int x, ScrollType, bool animated, ScrollClamping = ScrollClamping::Clamped);
     450    void scrollToYPosition(int y, ScrollType, bool animated, ScrollClamping = ScrollClamping::Clamped);
     451    void scrollToPosition(const ScrollPosition&, ScrollType, bool animated, ScrollClamping = ScrollClamping::Clamped);
    446452
    447453    // These are only used by marquee.
  • trunk/Source/WebCore/rendering/RenderListBox.cpp

    r253141 r254807  
    744744}
    745745
    746 void RenderListBox::setScrollLeft(int, ScrollType, ScrollClamping)
     746void RenderListBox::setScrollLeft(int, ScrollType, bool, ScrollClamping)
    747747{
    748748}
     
    761761}
    762762
    763 void RenderListBox::setScrollTop(int newTop, ScrollType, ScrollClamping)
     763void RenderListBox::setScrollTop(int newTop, ScrollType, bool, ScrollClamping)
    764764{
    765765    // Determine an index and scroll to it.   
  • trunk/Source/WebCore/rendering/RenderListBox.h

    r246488 r254807  
    107107    int scrollWidth() const override;
    108108    int scrollHeight() const override;
    109     void setScrollLeft(int, ScrollType, ScrollClamping) override;
    110     void setScrollTop(int, ScrollType, ScrollClamping) override;
     109    void setScrollLeft(int, ScrollType, bool, ScrollClamping) override;
     110    void setScrollTop(int, ScrollType, bool, ScrollClamping) override;
    111111
    112112    bool nodeAtPoint(const HitTestRequest&, HitTestResult&, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestAction) override;
  • trunk/Source/WebCore/rendering/RenderTextControlSingleLine.cpp

    r246490 r254807  
    377377}
    378378
    379 void RenderTextControlSingleLine::setScrollLeft(int newLeft, ScrollType, ScrollClamping)
     379void RenderTextControlSingleLine::setScrollLeft(int newLeft, ScrollType, bool, ScrollClamping)
    380380{
    381381    if (innerTextElement())
     
    383383}
    384384
    385 void RenderTextControlSingleLine::setScrollTop(int newTop, ScrollType, ScrollClamping)
     385void RenderTextControlSingleLine::setScrollTop(int newTop, ScrollType, bool, ScrollClamping)
    386386{
    387387    if (innerTextElement())
  • trunk/Source/WebCore/rendering/RenderTextControlSingleLine.h

    r243701 r254807  
    5858    int scrollWidth() const override;
    5959    int scrollHeight() const override;
    60     void setScrollLeft(int, ScrollType, ScrollClamping) override;
    61     void setScrollTop(int, ScrollType, ScrollClamping) override;
     60    void setScrollLeft(int, ScrollType, bool, ScrollClamping) override;
     61    void setScrollTop(int, ScrollType, bool, ScrollClamping) override;
    6262    bool scroll(ScrollDirection, ScrollGranularity, float multiplier = 1, Element** stopElement = nullptr, RenderBox* startBox = nullptr, const IntPoint& wheelEventAbsolutePoint = IntPoint()) final;
    6363    bool logicalScroll(ScrollLogicalDirection, ScrollGranularity, float multiplier = 1, Element** stopElement = 0) final;
  • trunk/Source/WebCore/testing/Internals.cpp

    r254514 r254807  
    17631763        return Exception { InvalidAccessError };
    17641764
    1765     element.scrollTo({ x, y }, ScrollClamping::Unclamped);
     1765    element.scrollTo(ScrollToOptions(x, y), ScrollClamping::Unclamped);
    17661766    return { };
    17671767}
Note: See TracChangeset for help on using the changeset viewer.