Changeset 205505 in webkit


Ignore:
Timestamp:
Sep 6, 2016 2:18:06 PM (8 years ago)
Author:
Simon Fraser
Message:

Align element.scroll() / scrollTo() / scrollBy() with the CSSOM specification
https://bugs.webkit.org/show_bug.cgi?id=161610

Reviewed by Darin Adler, Chris Dumez.

Source/WebCore:

Implement Element.scroll(), scrollBy() and scrollTo() with x,y and ScrollToOptions
on Element, according to <https://drafts.csswg.org/cssom-view/#element-scrolling-members>

WebKit's behavior of treating scrolls on the body element in both quirks and strict mode
is preserved.

Tests: fast/dom/Element/scrolling-funtions-on-body-quirks.html

fast/dom/Element/scrolling-funtions-on-body.html
fast/dom/Element/scrolling-funtions-on-element.html

  • dom/Element.cpp:

(WebCore::Element::scrollBy):
(WebCore::normalizeNonFiniteValue):
(WebCore::Element::scrollTo):

  • dom/Element.h:
  • dom/Element.idl:
  • html/HTMLBodyElement.cpp:

(WebCore::HTMLBodyElement::scrollTo):

  • html/HTMLBodyElement.h:

LayoutTests:

  • fast/dom/Element/scrolling-funtions-on-body-expected.txt: Added.
  • fast/dom/Element/scrolling-funtions-on-body-quirks-expected.txt: Added.
  • fast/dom/Element/scrolling-funtions-on-body-quirks.html: Added.
  • fast/dom/Element/scrolling-funtions-on-body.html: Added.
  • fast/dom/Element/scrolling-funtions-on-element-expected.txt: Added.
  • fast/dom/Element/scrolling-funtions-on-element.html: Added.
Location:
trunk
Files:
6 added
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r205503 r205505  
     12016-09-06  Simon Fraser  <simon.fraser@apple.com>
     2
     3        Align element.scroll() / scrollTo() / scrollBy() with the CSSOM specification
     4        https://bugs.webkit.org/show_bug.cgi?id=161610
     5
     6        Reviewed by Darin Adler, Chris Dumez.
     7
     8        * fast/dom/Element/scrolling-funtions-on-body-expected.txt: Added.
     9        * fast/dom/Element/scrolling-funtions-on-body-quirks-expected.txt: Added.
     10        * fast/dom/Element/scrolling-funtions-on-body-quirks.html: Added.
     11        * fast/dom/Element/scrolling-funtions-on-body.html: Added.
     12        * fast/dom/Element/scrolling-funtions-on-element-expected.txt: Added.
     13        * fast/dom/Element/scrolling-funtions-on-element.html: Added.
     14
    1152016-09-06  Ryan Haddad  <ryanhaddad@apple.com>
    216
  • trunk/Source/WebCore/ChangeLog

    r205504 r205505  
     12016-09-06  Simon Fraser  <simon.fraser@apple.com>
     2
     3        Align element.scroll() / scrollTo() / scrollBy() with the CSSOM specification
     4        https://bugs.webkit.org/show_bug.cgi?id=161610
     5
     6        Reviewed by Darin Adler, Chris Dumez.
     7
     8        Implement Element.scroll(), scrollBy() and scrollTo() with x,y and ScrollToOptions
     9        on Element, according to <https://drafts.csswg.org/cssom-view/#element-scrolling-members>
     10
     11        WebKit's behavior of treating scrolls on the body element in both quirks and strict mode
     12        is preserved.
     13
     14        Tests: fast/dom/Element/scrolling-funtions-on-body-quirks.html
     15               fast/dom/Element/scrolling-funtions-on-body.html
     16               fast/dom/Element/scrolling-funtions-on-element.html
     17
     18        * dom/Element.cpp:
     19        (WebCore::Element::scrollBy):
     20        (WebCore::normalizeNonFiniteValue):
     21        (WebCore::Element::scrollTo):
     22        * dom/Element.h:
     23        * dom/Element.idl:
     24        * html/HTMLBodyElement.cpp:
     25        (WebCore::HTMLBodyElement::scrollTo):
     26        * html/HTMLBodyElement.h:
     27
    1282016-09-06  Saam Barati  <sbarati@apple.com>
    229
  • trunk/Source/WebCore/dom/Element.cpp

    r205468 r205505  
    685685        renderer()->scrollRectToVisible(SelectionRevealMode::Reveal, bounds, ScrollAlignment::alignToEdgeIfNotVisible, ScrollAlignment::alignToEdgeIfNotVisible);
    686686}
    687    
     687
     688void Element::scrollBy(const ScrollToOptions& options)
     689{
     690    return scrollBy(options.left.valueOr(0), options.top.valueOr(0));
     691}
     692
     693static inline double normalizeNonFiniteValue(double f)
     694{
     695    return std::isfinite(f) ? f : 0;
     696}
     697
     698void Element::scrollBy(double x, double y)
     699{
     700    scrollTo(scrollLeft() + normalizeNonFiniteValue(x), scrollTop() + normalizeNonFiniteValue(y));
     701}
     702
     703void Element::scrollTo(const ScrollToOptions& options)
     704{
     705    // If the element is the root element and document is in quirks mode, terminate these steps.
     706    // Note that WebKit always uses quirks mode document scrolling behavior. See Document::scrollingElement().
     707    if (this == document().documentElement())
     708        return;
     709
     710    document().updateLayoutIgnorePendingStylesheets();
     711
     712    // If the element does not have any associated CSS layout box, the element has no associated scrolling box,
     713    // or the element has no overflow, terminate these steps.
     714    RenderBox* renderer = renderBox();
     715    if (!renderer || !renderer->hasOverflowClip())
     716        return;
     717
     718    // Normalize non-finite values for left and top dictionary members of options, if present.
     719    double x = options.left ? normalizeNonFiniteValue(options.left.value()) : adjustForAbsoluteZoom(renderer->scrollLeft(), *renderer);
     720    double y = options.top ? normalizeNonFiniteValue(options.top.value()) : adjustForAbsoluteZoom(renderer->scrollTop(), *renderer);
     721
     722    renderer->setScrollLeft(clampToInteger(x * renderer->style().effectiveZoom()));
     723    renderer->setScrollTop(clampToInteger(y * renderer->style().effectiveZoom()));
     724}
     725
     726void Element::scrollTo(double x, double y)
     727{
     728    scrollTo({ x, y });
     729}
     730
    688731void Element::scrollByUnits(int units, ScrollGranularity granularity)
    689732{
     
    827870    document().updateLayoutIgnorePendingStylesheets();
    828871
    829     if (RenderBox* renderer = renderBox()) {
     872    if (auto* renderer = renderBox()) {
    830873        LayoutUnit clientLeft = subpixelMetricsEnabled(renderer->document()) ? renderer->clientLeft() : LayoutUnit(roundToInt(renderer->clientLeft()));
    831874        return convertToNonSubpixelValueIfNeeded(adjustLayoutUnitForAbsoluteZoom(clientLeft, *renderer).toDouble(), renderer->document());
     
    838881    document().updateLayoutIgnorePendingStylesheets();
    839882
    840     if (RenderBox* renderer = renderBox()) {
     883    if (auto* renderer = renderBox()) {
    841884        LayoutUnit clientTop = subpixelMetricsEnabled(renderer->document()) ? renderer->clientTop() : LayoutUnit(roundToInt(renderer->clientTop()));
    842885        return convertToNonSubpixelValueIfNeeded(adjustLayoutUnitForAbsoluteZoom(clientTop, *renderer).toDouble(), renderer->document());
     
    851894    if (!document().hasLivingRenderTree())
    852895        return 0;
     896
    853897    RenderView& renderView = *document().renderView();
    854898
     
    871915    if (!document().hasLivingRenderTree())
    872916        return 0;
     917
    873918    RenderView& renderView = *document().renderView();
    874919
     
    890935    document().updateLayoutIgnorePendingStylesheets();
    891936
    892     if (RenderBox* rend = renderBox())
    893         return adjustForAbsoluteZoom(rend->scrollLeft(), *rend);
     937    if (auto* renderer = renderBox())
     938        return adjustForAbsoluteZoom(renderer->scrollLeft(), *renderer);
    894939    return 0;
    895940}
     
    899944    document().updateLayoutIgnorePendingStylesheets();
    900945
    901     if (RenderBox* rend = renderBox())
    902         return adjustForAbsoluteZoom(rend->scrollTop(), *rend);
     946    if (RenderBox* renderer = renderBox())
     947        return adjustForAbsoluteZoom(renderer->scrollTop(), *renderer);
    903948    return 0;
    904949}
     
    908953    document().updateLayoutIgnorePendingStylesheets();
    909954
    910     if (RenderBox* renderer = renderBox()) {
     955    if (auto* renderer = renderBox()) {
    911956        renderer->setScrollLeft(static_cast<int>(newLeft * renderer->style().effectiveZoom()));
    912957        if (auto* scrollableArea = renderer->layer())
     
    919964    document().updateLayoutIgnorePendingStylesheets();
    920965
    921     if (RenderBox* renderer = renderBox()) {
     966    if (auto* renderer = renderBox()) {
    922967        renderer->setScrollTop(static_cast<int>(newTop * renderer->style().effectiveZoom()));
    923968        if (auto* scrollableArea = renderer->layer())
     
    929974{
    930975    document().updateLayoutIfDimensionsOutOfDate(*this, WidthDimensionsCheck);
    931     if (RenderBox* rend = renderBox())
    932         return adjustForAbsoluteZoom(rend->scrollWidth(), *rend);
     976    if (auto* renderer = renderBox())
     977        return adjustForAbsoluteZoom(renderer->scrollWidth(), *renderer);
    933978    return 0;
    934979}
     
    937982{
    938983    document().updateLayoutIfDimensionsOutOfDate(*this, HeightDimensionsCheck);
    939     if (RenderBox* rend = renderBox())
    940         return adjustForAbsoluteZoom(rend->scrollHeight(), *rend);
     984    if (auto* renderer = renderBox())
     985        return adjustForAbsoluteZoom(renderer->scrollHeight(), *renderer);
    941986    return 0;
    942987}
  • trunk/Source/WebCore/dom/Element.h

    r205468 r205505  
    137137    WEBCORE_EXPORT void scrollIntoViewIfNotVisible(bool centerIfNotVisible = true);
    138138
     139    struct ScrollToOptions {
     140        Optional<double> left;
     141        Optional<double> top;
     142    };
     143
     144    void scrollBy(const ScrollToOptions&);
     145    void scrollBy(double x, double y);
     146    virtual void scrollTo(const ScrollToOptions&);
     147    void scrollTo(double x, double y);
     148
    139149    WEBCORE_EXPORT void scrollByLines(int lines);
    140150    WEBCORE_EXPORT void scrollByPages(int pages);
     
    158168    WEBCORE_EXPORT double clientWidth();
    159169    WEBCORE_EXPORT double clientHeight();
     170
    160171    virtual int scrollLeft();
    161172    virtual int scrollTop();
  • trunk/Source/WebCore/dom/Element.idl

    r205280 r205505  
    7272    readonly attribute double clientHeight;
    7373
    74     attribute long scrollLeft;
    75     attribute long scrollTop;
     74    attribute long scrollLeft; // FIXME: should be unrestricted double
     75    attribute long scrollTop; // FIXME: should be unrestricted double
    7676    readonly attribute long scrollWidth;
    7777    readonly attribute long scrollHeight;
     
    8181    void scrollIntoView(optional boolean alignWithTop = true);
    8282
    83     sequence<DOMString> getAttributeNames();
    84 
    8583    void scrollIntoViewIfNeeded(optional boolean centerIfNeeded = true);
     84
     85    [ImplementedAs=scrollTo] void scroll(optional ScrollToOptions options);
     86    [ImplementedAs=scrollTo] void scroll(unrestricted double x, unrestricted double y);
     87
     88    void scrollTo(optional ScrollToOptions options);
     89    void scrollTo(unrestricted double x, unrestricted double y);
     90
     91    void scrollBy(optional ScrollToOptions option);
     92    void scrollBy(unrestricted double x, unrestricted double y);
     93
    8694    void scrollByLines(optional long lines = 0);
    8795    void scrollByPages(optional long pages = 0);
     96
     97    sequence<DOMString> getAttributeNames();
    8898
    8999    HTMLCollection getElementsByClassName(DOMString name);
     
    179189};
    180190
     191// FIXME: Support ScrollBehavior.
     192dictionary ScrollToOptions {
     193    unrestricted double left;
     194    unrestricted double top;
     195};
     196
    181197Element implements Animatable;
    182198Element implements ChildNode;
  • trunk/Source/WebCore/html/HTMLBodyElement.cpp

    r203324 r205505  
    2828#include "CSSParser.h"
    2929#include "CSSValueKeywords.h"
     30#include "DOMWindow.h"
    3031#include "EventNames.h"
    3132#include "Frame.h"
     
    295296}
    296297
     298void HTMLBodyElement::scrollTo(const ScrollToOptions& options)
     299{
     300    if (isFirstBodyElementOfDocument()) {
     301        // If the element is the HTML body element, document is in quirks mode, and the element is not potentially scrollable,
     302        // invoke scroll() on window with options as the only argument, and terminate these steps.
     303        // Note that WebKit always uses quirks mode document scrolling behavior. See Document::scrollingElement().
     304        // FIXME: Scrolling an independently scrollable body is broken: webkit.org/b/161612.
     305        auto* window = document().domWindow();
     306        if (!window)
     307            return;
     308
     309        window->scrollTo({ options.left, options.top });
     310        return;
     311    }
     312    return HTMLElement::scrollTo(options);
     313}
     314
    297315int HTMLBodyElement::scrollHeight()
    298316{
  • trunk/Source/WebCore/html/HTMLBodyElement.h

    r203264 r205505  
    5757    int scrollTop() final;
    5858    void setScrollTop(int) final;
     59
     60    void scrollTo(const ScrollToOptions&) final;
    5961   
    6062    int scrollHeight() final;
Note: See TracChangeset for help on using the changeset viewer.