Changeset 255957 in webkit


Ignore:
Timestamp:
Feb 6, 2020 8:49:04 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:
  • 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::ScrollableArea):
(WebCore::ScrollableArea::scrollToOffsetWithAnimation):

  • platform/ScrollableArea.h:

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

  • 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::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

    r255956 r255957  
     12020-02-06  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-02-06  Jason Lawrence  <lawrence.j@apple.com>
    213
  • trunk/LayoutTests/imported/w3c/ChangeLog

    r255821 r255957  
     12020-02-06  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-02-05  Antoine Quint  <graouts@apple.com>
    229
  • trunk/LayoutTests/imported/w3c/web-platform-tests/css/cssom-view/scroll-behavior-default-css-expected.txt

    r254890 r255957  
    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

    r254890 r255957  
    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

    r254890 r255957  
    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

    r254890 r255957  
    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

    r254890 r255957  
    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

    r254890 r255957  
    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

    r254890 r255957  
    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

    r254890 r255957  
    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

    r254890 r255957  
    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

    r254890 r255957  
    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

    r254890 r255957  
    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

    r254890 r255957  
    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

    r254890 r255957  
    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

    r254890 r255957  
    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

    r254890 r255957  
    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

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

    r255953 r255957  
     12020-02-06  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        * platform/ScrollAnimation.h:
     48        (WebCore::ScrollAnimation::scroll): Function to animate scrolling to a specified position.
     49        * platform/ScrollAnimationSmooth.cpp: Build this file on all platforms. Add a
     50        smoothFactorForProgrammaticScroll parameter to slow down the smooth scrolling.
     51        (WebCore::ScrollAnimationSmooth::scroll):
     52        (WebCore::ScrollAnimationSmooth::updatePerAxisData): Scale the time parameters of the
     53        animation so that it looks smoother.
     54        * platform/ScrollAnimationSmooth.h: Declare the class on all platforms.
     55        * platform/ScrollAnimator.cpp:
     56        (WebCore::ScrollAnimator::ScrollAnimator): Initialize animation member for programmatic scrolling.
     57        (WebCore::ScrollAnimator::scrollToOffset): Animate scrolling to the specified position.
     58        (WebCore::ScrollAnimator::cancelAnimations): Copy logic from ScrollAnimationSmooth.cpp.
     59        (WebCore::ScrollAnimator::serviceScrollAnimations): Ditto.
     60        (WebCore::ScrollAnimator::willEndLiveResize): Ditto.
     61        (WebCore::ScrollAnimator::didAddVerticalScrollbar): Ditto.
     62        (WebCore::ScrollAnimator::didAddHorizontalScrollbar): Ditto.
     63        * platform/ScrollAnimator.h: New animation member for smooth programmatic scrolling.
     64        (WebCore::ScrollAnimator::ScrollAnimator::cancelAnimations): Deleted.
     65        (WebCore::ScrollAnimator::ScrollAnimator::serviceScrollAnimations): Deleted.
     66        (WebCore::ScrollAnimator::ScrollAnimator::willEndLiveResize): Deleted.
     67        (WebCore::ScrollAnimator::ScrollAnimator::didAddVerticalScrollbar): Deleted.
     68        (WebCore::ScrollAnimator::ScrollAnimator::didAddHorizontalScrollbar): Deleted.
     69        * platform/ScrollTypes.h: Add ScrollBehaviorStatus to indicate the status of scrolling.
     70        * platform/ScrollView.cpp:
     71        (WebCore::ScrollView::setScrollPosition): Follow the CSSOM View spec: If a scroll is in
     72        progress, we interrupt it and continue the scroll call (even when we are at the final position).
     73        * platform/ScrollView.h:
     74        * platform/ScrollableArea.cpp:
     75        (WebCore::ScrollableArea::ScrollableArea):
     76        (WebCore::ScrollableArea::scrollToOffsetWithAnimation):
     77        * platform/ScrollableArea.h:
     78        (WebCore::ScrollableArea::currentScrollBehaviorStatus const): Maintain currentScrollBehaviorStatus.
     79        (WebCore::ScrollableArea::setScrollBehaviorStatus):
     80        * platform/mac/ScrollAnimatorMac.mm:
     81        (WebCore::ScrollAnimatorMac::cancelAnimations): Call parent member to handle programmatic scrolling.
     82        * rendering/RenderBox.cpp:
     83        (WebCore::RenderBox::setScrollLeft): Add flag to indicate animated or not.
     84        (WebCore::RenderBox::setScrollTop): Ditto.
     85        (WebCore::RenderBox::setScrollPosition):
     86        * rendering/RenderBox.h:
     87        * rendering/RenderLayer.cpp:
     88        (WebCore::RenderLayer::scrollToXPosition): Ditto.
     89        (WebCore::RenderLayer::scrollToYPosition): Ditto.
     90        (WebCore::RenderLayer::scrollToPosition):
     91        (WebCore::RenderLayer::scrollToOffset): Follow the CSSOM View spec: If a scroll is in
     92        progress, we interrupt it and continue the scroll call (even when we are at the final
     93        position). It's ScrollBehaviorType::Instant scroll.
     94        (WebCore::RenderLayer::scrollToOffsetWithAnimation): Ditto. This is similar to scrollToOffset
     95        but animates the scroll. It's ScrollBehaviorType::Smooth scroll.
     96        (WebCore::RenderLayer::scrollTo):
     97        (WebCore::RenderLayer::scrollRectToVisible): Again don't do an early return if scroll is in
     98        progress. We call scrollToOffsetWithAnimation instead of scrollToOffset when appropriate.
     99        Note that this function may not work well for several nested scroll boxes with at least one
     100        element with smooth behavior. It will handled in bug Follow.
     101        * rendering/RenderLayer.h: Add scroll behavior to ScrollTectToVisibleOptions.
     102        * rendering/RenderListBox.cpp:
     103        (WebCore::RenderListBox::setScrollLeft): Add animated flag.
     104        (WebCore::RenderListBox::setScrollTop): Ditto.
     105        * rendering/RenderListBox.h:
     106        * rendering/RenderTextControlSingleLine.cpp:
     107        (WebCore::RenderTextControlSingleLine::setScrollLeft):
     108        (WebCore::RenderTextControlSingleLine::setScrollTop):
     109        * rendering/RenderTextControlSingleLine.h:
     110        * testing/Internals.cpp:
     111        (WebCore::Internals::unconstrainedScrollTo):
     112
    11132020-02-06  Antoine Quint  <graouts@apple.com>
    2114
  • trunk/Source/WebCore/Sources.txt

    r255785 r255957  
    17541754platform/SSLKeyGenerator.cpp
    17551755platform/ScrollAnimator.cpp
     1756platform/ScrollAnimationSmooth.cpp
    17561757platform/ScrollTypes.cpp
    17571758platform/ScrollView.cpp
  • trunk/Source/WebCore/SourcesGTK.txt

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

    r255383 r255957  
    842842    LayoutRect absoluteBounds = renderer()->absoluteAnchorRect(&insideFixed);
    843843
    844     // FIXME(webkit.org/b/188043): Support ScrollBehavior.
    845844    ScrollIntoViewOptions options;
    846845    if (arg) {
     
    861860        isHorizontal ? alignX : alignY,
    862861        isHorizontal ? alignY : alignX,
    863         ShouldAllowCrossOriginScrolling::No
     862        ShouldAllowCrossOriginScrolling::No,
     863        options.behavior.valueOr(ScrollBehavior::Auto)
    864864    };
    865865    renderer()->scrollRectToVisible(absoluteBounds, insideFixed, visibleOptions);
     
    922922void Element::scrollBy(double x, double y)
    923923{
    924     scrollBy({ x, y });
     924    scrollBy(ScrollToOptions(x, y));
    925925}
    926926
     
    958958        adjustForAbsoluteZoom(renderer->scrollTop(), *renderer)
    959959    );
    960     renderer->setScrollLeft(clampToInteger(scrollToOptions.left.value() * renderer->style().effectiveZoom()), ScrollType::Programmatic, clamping);
    961     renderer->setScrollTop(clampToInteger(scrollToOptions.top.value() * renderer->style().effectiveZoom()), ScrollType::Programmatic, clamping);
     960    IntPoint scrollPosition(
     961        clampToInteger(scrollToOptions.left.value() * renderer->style().effectiveZoom()),
     962        clampToInteger(scrollToOptions.top.value() * renderer->style().effectiveZoom())
     963    );
     964    bool animated = useSmoothScrolling(scrollToOptions.behavior.valueOr(ScrollBehavior::Auto), this);
     965    renderer->setScrollPosition(scrollPosition, ScrollType::Programmatic, clamping, animated);
    962966}
    963967
    964968void Element::scrollTo(double x, double y)
    965969{
    966     scrollTo({ x, y });
     970    scrollTo(ScrollToOptions(x, y));
    967971}
    968972
     
    12981302
    12991303    if (document().scrollingElement() == this) {
    1300         if (auto* frame = documentFrameWithNonNullView())
    1301             frame->view()->setScrollPosition(IntPoint(static_cast<int>(newLeft * frame->pageZoomFactor() * frame->frameScaleFactor()), frame->view()->scrollY()));
     1304        if (auto* frame = documentFrameWithNonNullView()) {
     1305            // FIXME: Should we use document()->scrollingElement()?
     1306            // See https://bugs.webkit.org/show_bug.cgi?id=205059
     1307            bool animated = useSmoothScrolling(ScrollBehavior::Auto, document().documentElement());
     1308            IntPoint position(static_cast<int>(newLeft * frame->pageZoomFactor() * frame->frameScaleFactor()), frame->view()->scrollY());
     1309            frame->view()->setScrollPosition(position, ScrollClamping::Clamped, animated);
     1310        }
    13021311        return;
    13031312    }
    13041313
    13051314    if (auto* renderer = renderBox()) {
    1306         renderer->setScrollLeft(static_cast<int>(newLeft * renderer->style().effectiveZoom()), ScrollType::Programmatic);
     1315        int clampedLeft = clampToInteger(newLeft * renderer->style().effectiveZoom());
     1316        bool animated = useSmoothScrolling(ScrollBehavior::Auto, this);
     1317        renderer->setScrollLeft(clampedLeft, ScrollType::Programmatic, ScrollClamping::Clamped, animated);
    13071318        if (auto* scrollableArea = renderer->layer())
    13081319            scrollableArea->setScrollShouldClearLatchedState(true);
     
    13151326
    13161327    if (document().scrollingElement() == this) {
    1317         if (auto* frame = documentFrameWithNonNullView())
    1318             frame->view()->setScrollPosition(IntPoint(frame->view()->scrollX(), static_cast<int>(newTop * frame->pageZoomFactor() * frame->frameScaleFactor())));
     1328        if (auto* frame = documentFrameWithNonNullView()) {
     1329            // FIXME: Should we use document()->scrollingElement()?
     1330            // See https://bugs.webkit.org/show_bug.cgi?id=205059
     1331            bool animated = useSmoothScrolling(ScrollBehavior::Auto, document().documentElement());
     1332            IntPoint position(frame->view()->scrollX(), static_cast<int>(newTop * frame->pageZoomFactor() * frame->frameScaleFactor()));
     1333            frame->view()->setScrollPosition(position, ScrollClamping::Clamped, animated);
     1334        }
    13191335        return;
    13201336    }
    13211337
    13221338    if (auto* renderer = renderBox()) {
    1323         renderer->setScrollTop(static_cast<int>(newTop * renderer->style().effectiveZoom()), ScrollType::Programmatic);
     1339        int clampedTop = clampToInteger(newTop * renderer->style().effectiveZoom());
     1340        bool animated = useSmoothScrolling(ScrollBehavior::Auto, this);
     1341        renderer->setScrollTop(clampedTop, ScrollType::Programmatic, ScrollClamping::Clamped, animated);
    13241342        if (auto* scrollableArea = renderer->layer())
    13251343            scrollableArea->setScrollShouldClearLatchedState(true);
  • trunk/Source/WebCore/page/DOMWindow.cpp

    r255668 r255957  
    16741674void DOMWindow::scrollBy(double x, double y) const
    16751675{
    1676     scrollBy({ x, y });
     1676    scrollBy(ScrollToOptions(x, y));
    16771677}
    16781678
     
    17001700void DOMWindow::scrollTo(double x, double y, ScrollClamping clamping) const
    17011701{
    1702     scrollTo({ x, y }, clamping);
     1702    scrollTo(ScrollToOptions(x, y), clamping);
    17031703}
    17041704
     
    17161716    );
    17171717
    1718     if (!scrollToOptions.left.value() && !scrollToOptions.top.value() && view->contentsScrollPosition() == IntPoint(0, 0))
     1718    // This is an optimization for the common case of scrolling to (0, 0) when the scroller is already at the origin.
     1719    // If an animated scroll is in progress, this optimization is skipped to ensure that the animated scroll is really stopped.
     1720    if (view->currentScrollBehaviorStatus() == ScrollBehaviorStatus::NotInAnimation && !scrollToOptions.left.value() && !scrollToOptions.top.value() && view->contentsScrollPosition() == IntPoint(0, 0))
    17191721        return;
    17201722
     
    17221724
    17231725    IntPoint layoutPos(view->mapFromCSSToLayoutUnits(scrollToOptions.left.value()), view->mapFromCSSToLayoutUnits(scrollToOptions.top.value()));
     1726
     1727    // FIXME: Should we use document()->scrollingElement()?
     1728    // See https://bugs.webkit.org/show_bug.cgi?id=205059
     1729    if (useSmoothScrolling(scrollToOptions.behavior.valueOr(ScrollBehavior::Auto), document()->documentElement())) {
     1730        view->scrollToOffsetWithAnimation(layoutPos, ScrollType::Programmatic, clamping);
     1731        return;
     1732    }
     1733
    17241734    view->setContentsScrollPosition(layoutPos, clamping);
    17251735}
  • trunk/Source/WebCore/page/FrameView.cpp

    r255342 r255957  
    22802280}
    22812281
    2282 void FrameView::setScrollPosition(const ScrollPosition& scrollPosition, ScrollClamping clamping)
     2282void FrameView::setScrollPosition(const ScrollPosition& scrollPosition, ScrollClamping clamping, 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, clamping);
     2295    if (animated)
     2296        scrollToOffsetWithAnimation(scrollOffsetFromPosition(scrollPosition), currentScrollType(), clamping);
     2297    else
     2298        ScrollView::setScrollPosition(scrollPosition, clamping);
    22962299
    22972300    setCurrentScrollType(oldScrollType);
     
    36523655
    36533656    didChangeScrollOffset();
     3657}
     3658
     3659void FrameView::scrollToOffsetWithAnimation(const ScrollOffset& offset, ScrollType scrollType, ScrollClamping)
     3660{
     3661    auto previousScrollType = currentScrollType();
     3662    setCurrentScrollType(scrollType);
     3663
     3664    if (currentScrollBehaviorStatus() == ScrollBehaviorStatus::InNonNativeAnimation)
     3665        scrollAnimator().cancelAnimations();
     3666    if (offset != this->scrollOffset())
     3667        ScrollableArea::scrollToOffsetWithAnimation(offset);
     3668
     3669    setCurrentScrollType(previousScrollType);
    36543670}
    36553671
  • trunk/Source/WebCore/page/FrameView.h

    r255037 r255957  
    224224    WEBCORE_EXPORT void setFixedVisibleContentRect(const IntRect&) final;
    225225#endif
    226     WEBCORE_EXPORT void setScrollPosition(const ScrollPosition&, ScrollClamping = ScrollClamping::Clamped) final;
     226    WEBCORE_EXPORT void setScrollPosition(const ScrollPosition&, ScrollClamping = ScrollClamping::Clamped, 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/page/ScrollBehavior.cpp

    r254790 r255957  
    3434namespace WebCore {
    3535
    36 bool useSmoothScrolling(ScrollBehavior behavior, Element& associatedElement)
     36bool useSmoothScrolling(ScrollBehavior behavior, Element* associatedElement)
    3737{
    38     if (!associatedElement.document().settings().CSSOMViewSmoothScrollingEnabled() || !associatedElement.renderer())
     38    if (!associatedElement
     39        || !associatedElement->renderer()
     40        || !associatedElement->document().settings().CSSOMViewSmoothScrollingEnabled())
    3941        return false;
    4042
     
    4244    switch (behavior) {
    4345    case ScrollBehavior::Auto:
    44         return associatedElement.renderer()->style().useSmoothScrolling();
     46        return associatedElement->renderer()->style().useSmoothScrolling();
    4547    case ScrollBehavior::Instant:
    4648        return false;
  • trunk/Source/WebCore/page/ScrollBehavior.h

    r254790 r255957  
    3636};
    3737
    38 bool useSmoothScrolling(ScrollBehavior, Element& associatedElement);
     38bool useSmoothScrolling(ScrollBehavior, Element* associatedElement);
    3939
    4040} // namespace WebCore
  • trunk/Source/WebCore/platform/ScrollAnimation.h

    r254890 r255957  
    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

    r254890 r255957  
    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

    r254890 r255957  
    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

    r254890 r255957  
    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        FloatSize delta = position - m_currentPosition;
     58        m_currentPosition = WTFMove(position);
     59        notifyPositionChanged(delta);
     60    }))
    5561{
    5662}
     
    7480    notifyPositionChanged(newPosition - currentPosition);
    7581    return true;
     82}
     83
     84void ScrollAnimator::scrollToOffset(const FloatPoint& offset)
     85{
     86    m_animationProgrammaticScroll->setCurrentPosition(m_currentPosition);
     87    auto newPosition = ScrollableArea::scrollPositionFromOffset(offset, toFloatSize(m_scrollableArea.scrollOrigin()));
     88    m_animationProgrammaticScroll->scroll(newPosition);
     89    m_scrollableArea.setScrollBehaviorStatus(ScrollBehaviorStatus::InNonNativeAnimation);
    7690}
    7791
     
    246260#endif
    247261
     262void ScrollAnimator::cancelAnimations()
     263{
     264#if !USE(REQUEST_ANIMATION_FRAME_TIMER)
     265    m_animationProgrammaticScroll->stop();
     266#endif
     267}
     268
     269void ScrollAnimator::serviceScrollAnimations()
     270{
     271#if !USE(REQUEST_ANIMATION_FRAME_TIMER)
     272    m_animationProgrammaticScroll->serviceAnimation();
     273#endif
     274}
     275
     276void ScrollAnimator::willEndLiveResize()
     277{
     278    m_animationProgrammaticScroll->updateVisibleLengths();
     279}
     280
     281void ScrollAnimator::didAddVerticalScrollbar(Scrollbar*)
     282{
     283    m_animationProgrammaticScroll->updateVisibleLengths();
     284}
     285
     286void ScrollAnimator::didAddHorizontalScrollbar(Scrollbar*)
     287{
     288    m_animationProgrammaticScroll->updateVisibleLengths();
     289}
     290
    248291} // namespace WebCore
  • trunk/Source/WebCore/platform/ScrollAnimator.h

    r254890 r255957  
    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

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

    r255226 r255957  
    514514}
    515515
    516 void ScrollView::setScrollPosition(const ScrollPosition& scrollPosition, ScrollClamping clamping)
     516void ScrollView::setScrollPosition(const ScrollPosition& scrollPosition, ScrollClamping clamping, bool/* animated*/)
    517517{
    518518    LOG_WITH_STREAM(Scrolling, stream << "ScrollView::setScrollPosition " << scrollPosition);
     
    528528    ScrollPosition newScrollPosition = (!delegatesScrolling() && clamping == ScrollClamping::Clamped) ? adjustScrollPositionWithinRange(scrollPosition) : scrollPosition;
    529529
    530     if ((!delegatesScrolling() || currentScrollType() == ScrollType::User) && newScrollPosition == this->scrollPosition())
    531         return;
    532 
    533     if (requestScrollPositionUpdate(newScrollPosition, currentScrollType(), clamping))
    534         return;
    535 
    536     updateScrollbars(newScrollPosition);
     530    if ((!delegatesScrolling() || currentScrollType() == ScrollType::User) && currentScrollBehaviorStatus() == ScrollBehaviorStatus::NotInAnimation && newScrollPosition == this->scrollPosition())
     531        return;
     532
     533    if (currentScrollBehaviorStatus() == ScrollBehaviorStatus::InNonNativeAnimation)
     534        scrollAnimator().cancelAnimations();
     535
     536    if (!requestScrollPositionUpdate(newScrollPosition, currentScrollType(), clamping))
     537        updateScrollbars(newScrollPosition);
     538
     539    setScrollBehaviorStatus(ScrollBehaviorStatus::NotInAnimation);
    537540}
    538541
  • trunk/Source/WebCore/platform/ScrollView.h

    r255226 r255957  
    262262
    263263    // Functions for scrolling the view.
    264     virtual void setScrollPosition(const ScrollPosition&, ScrollClamping = ScrollClamping::Clamped);
     264    virtual void setScrollPosition(const ScrollPosition&, ScrollClamping = ScrollClamping::Clamped, bool animated = false);
     265
    265266    void scrollBy(const IntSize& s) { return setScrollPosition(scrollPosition() + s); }
    266267
  • trunk/Source/WebCore/platform/ScrollableArea.cpp

    r255037 r255957  
    7272    , m_currentScrollType(static_cast<unsigned>(ScrollType::User))
    7373    , m_scrollShouldClearLatchedState(false)
     74    , m_currentScrollBehaviorStatus(static_cast<unsigned>(ScrollBehaviorStatus::NotInAnimation))
    7475{
    7576}
     
    143144}
    144145
     146void ScrollableArea::scrollToOffsetWithAnimation(const FloatPoint& offset, ScrollClamping)
     147{
     148    LOG_WITH_STREAM(Scrolling, stream << "ScrollableArea " << this << " scrollToOffsetWithAnimation " << offset);
     149    scrollAnimator().scrollToOffset(offset);
     150}
     151
    145152void ScrollableArea::scrollToOffsetWithoutAnimation(const FloatPoint& offset, ScrollClamping clamping)
    146153{
  • trunk/Source/WebCore/platform/ScrollableArea.h

    r255037 r255957  
    6363class ScrollableArea : public CanMakeWeakPtr<ScrollableArea> {
    6464public:
     65    ScrollBehaviorStatus currentScrollBehaviorStatus() { return static_cast<ScrollBehaviorStatus>(m_currentScrollBehaviorStatus); }
     66    void setScrollBehaviorStatus(ScrollBehaviorStatus status) { m_currentScrollBehaviorStatus = static_cast<unsigned>(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);
     
    405409    unsigned m_currentScrollType : 1; // ScrollType
    406410    unsigned m_scrollShouldClearLatchedState : 1;
     411    unsigned m_currentScrollBehaviorStatus : 1;
    407412};
    408413
  • trunk/Source/WebCore/platform/mac/ScrollAnimatorMac.mm

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

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

    r255413 r255957  
    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, ScrollClamping = ScrollClamping::Clamped, bool animated = false);
     251    virtual void setScrollTop(int, ScrollType, ScrollClamping = ScrollClamping::Clamped, bool animated = false);
     252    void setScrollPosition(const ScrollPosition&, ScrollType, ScrollClamping = ScrollClamping::Clamped, bool animated = false);
    252253
    253254    LayoutUnit marginTop() const override { return m_marginBox.top(); }
  • trunk/Source/WebCore/rendering/RenderLayer.cpp

    r255501 r255957  
    25802580}
    25812581
    2582 void RenderLayer::scrollToXPosition(int x, ScrollType scrollType, ScrollClamping clamping)
     2582void RenderLayer::scrollToXPosition(int x, ScrollType scrollType, ScrollClamping clamping, bool animated)
    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, clamping, animated);
     2586}
     2587
     2588void RenderLayer::scrollToYPosition(int y, ScrollType scrollType, ScrollClamping clamping, bool animated)
    25892589{
    25902590    ScrollPosition position(m_scrollPosition.x(), y);
    2591     scrollToOffset(scrollOffsetFromPosition(position), scrollType, clamping);
     2591    scrollToPosition(position, scrollType, clamping, animated);
     2592}
     2593
     2594void RenderLayer::scrollToPosition(const ScrollPosition& position, ScrollType scrollType, ScrollClamping clamping, bool animated)
     2595{
     2596    if (animated)
     2597        scrollToOffsetWithAnimation(scrollOffsetFromPosition(position), scrollType, clamping);
     2598    else
     2599        scrollToOffset(scrollOffsetFromPosition(position), scrollType, clamping);
    25922600}
    25932601
     
    26082616void RenderLayer::scrollToOffset(const ScrollOffset& scrollOffset, ScrollType scrollType, ScrollClamping clamping)
    26092617{
     2618    if (currentScrollBehaviorStatus() == ScrollBehaviorStatus::InNonNativeAnimation)
     2619        scrollAnimator().cancelAnimations();
     2620
    26102621    ScrollOffset clampedScrollOffset = clamping == ScrollClamping::Clamped ? clampScrollOffset(scrollOffset) : scrollOffset;
    26112622    if (clampedScrollOffset == this->scrollOffset())
     
    26172628    if (!requestScrollPositionUpdate(scrollPositionFromOffset(clampedScrollOffset), scrollType, clamping))
    26182629        scrollToOffsetWithoutAnimation(clampedScrollOffset, clamping);
     2630    setScrollBehaviorStatus(ScrollBehaviorStatus::NotInAnimation);
     2631
     2632    setCurrentScrollType(previousScrollType);
     2633}
     2634
     2635void RenderLayer::scrollToOffsetWithAnimation(const ScrollOffset& offset, ScrollType scrollType, ScrollClamping clamping)
     2636{
     2637    auto previousScrollType = currentScrollType();
     2638    setCurrentScrollType(scrollType);
     2639
     2640    ScrollOffset newScrollOffset = clamping == ScrollClamping::Clamped ? clampScrollOffset(offset) : offset;
     2641    if (currentScrollBehaviorStatus() == ScrollBehaviorStatus::InNonNativeAnimation)
     2642        scrollAnimator().cancelAnimations();
     2643    if (newScrollOffset != this->scrollOffset())
     2644        ScrollableArea::scrollToOffsetWithAnimation(newScrollOffset);
    26192645
    26202646    setCurrentScrollType(previousScrollType);
     
    26532679    }
    26542680   
    2655     if (m_scrollPosition == newPosition) {
     2681    if (m_scrollPosition == newPosition && currentScrollBehaviorStatus() == ScrollBehaviorStatus::NotInAnimation) {
    26562682        // FIXME: Nothing guarantees we get a scrollTo() with an unchanged position at the end of a user gesture.
    26572683        // The ScrollingCoordinator probably needs to message the main thread when a gesture ends.
     
    27982824
    27992825        ScrollOffset clampedScrollOffset = clampScrollOffset(scrollOffset() + toIntSize(roundedIntRect(revealRect).location()));
    2800         if (clampedScrollOffset != scrollOffset()) {
     2826        if (clampedScrollOffset != scrollOffset() || currentScrollBehaviorStatus() != ScrollBehaviorStatus::NotInAnimation) {
    28012827            ScrollOffset oldScrollOffset = scrollOffset();
    2802             scrollToOffset(clampedScrollOffset);
    2803             IntSize scrollOffsetDifference = scrollOffset() - oldScrollOffset;
     2828            bool animated = useSmoothScrolling(options.behavior, box->element());
     2829            scrollToPosition(scrollPositionFromOffset(clampedScrollOffset), ScrollType::Programmatic, ScrollClamping::Clamped, animated);
     2830            IntSize scrollOffsetDifference = clampedScrollOffset - oldScrollOffset;
    28042831            localExposeRect.move(-scrollOffsetDifference);
    28052832            newRect = LayoutRect(box->localToAbsoluteQuad(FloatQuad(FloatRect(localExposeRect)), UseTransforms).boundingBox());
     
    28212848                LayoutRect exposeRect = getRectToExpose(viewRect, absoluteRect, insideFixed, options.alignX, options.alignY);
    28222849
    2823                 IntPoint scrollOffset(roundedIntPoint(exposeRect.location()));
     2850                IntPoint scrollPosition(roundedIntPoint(exposeRect.location()));
    28242851                // Adjust offsets if they're outside of the allowable range.
    2825                 scrollOffset = scrollOffset.constrainedBetween(IntPoint(), IntPoint(frameView.contentsSize()));
    2826                 frameView.setScrollPosition(scrollOffset);
     2852                scrollPosition = scrollPosition.constrainedBetween(IntPoint(), IntPoint(frameView.contentsSize()));
     2853                // FIXME: Should we use contentDocument()->scrollingElement()?
     2854                // See https://bugs.webkit.org/show_bug.cgi?id=205059
     2855                bool animated = ownerElement->contentDocument() && useSmoothScrolling(options.behavior, ownerElement->contentDocument()->documentElement());
     2856                frameView.setScrollPosition(scrollPosition, ScrollClamping::Clamped, animated);
    28272857
    28282858                if (options.shouldAllowCrossOriginScrolling == ShouldAllowCrossOriginScrolling::Yes || frameView.safeToPropagateScrollToParent()) {
     
    28632893            if (revealRect != viewRect) {
    28642894                ScrollOffset clampedScrollPosition = roundedIntPoint(revealRect.location()).constrainedBetween(minScrollPosition, maxScrollPosition);
    2865                 frameView.setScrollPosition(clampedScrollPosition);
     2895                // FIXME: Should we use document()->scrollingElement()?
     2896                // See https://bugs.webkit.org/show_bug.cgi?id=205059
     2897                bool animated = useSmoothScrolling(options.behavior, renderer().document().documentElement());
     2898                frameView.setScrollPosition(clampedScrollPosition, ScrollClamping::Clamped, animated);
    28662899            }
    28672900
  • trunk/Source/WebCore/rendering/RenderLayer.h

    r255501 r255957  
    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
     
    443445
    444446    WEBCORE_EXPORT void scrollToOffset(const ScrollOffset&, ScrollType = ScrollType::Programmatic, ScrollClamping = ScrollClamping::Clamped);
    445 
    446     void scrollToXPosition(int x, ScrollType, ScrollClamping = ScrollClamping::Clamped);
    447     void scrollToYPosition(int y, ScrollType, ScrollClamping = ScrollClamping::Clamped);
     447    WEBCORE_EXPORT void scrollToOffsetWithAnimation(const ScrollOffset&, ScrollType = ScrollType::Programmatic, ScrollClamping = ScrollClamping::Clamped);
     448
     449    void scrollToXPosition(int x, ScrollType, ScrollClamping = ScrollClamping::Clamped, bool animated = false);
     450    void scrollToYPosition(int y, ScrollType, ScrollClamping = ScrollClamping::Clamped, bool animated = false);
     451    void scrollToPosition(const ScrollPosition&, ScrollType, ScrollClamping = ScrollClamping::Clamped, bool animated = false);
    448452
    449453    // These are only used by marquee.
  • trunk/Source/WebCore/rendering/RenderListBox.cpp

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

    r254890 r255957  
    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, ScrollClamping, bool) override;
     110    void setScrollTop(int, ScrollType, ScrollClamping, bool) override;
    111111
    112112    bool nodeAtPoint(const HitTestRequest&, HitTestResult&, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestAction) override;
  • trunk/Source/WebCore/rendering/RenderTextControlSingleLine.cpp

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

    r254890 r255957  
    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, ScrollClamping, bool) override;
     61    void setScrollTop(int, ScrollType, ScrollClamping, bool) 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

    r255875 r255957  
    17761776        return Exception { InvalidAccessError };
    17771777
    1778     element.scrollTo({ x, y }, ScrollClamping::Unclamped);
     1778    element.scrollTo(ScrollToOptions(x, y), ScrollClamping::Unclamped);
    17791779
    17801780    auto& frameView = *document->view();
Note: See TracChangeset for help on using the changeset viewer.