Changeset 279714 in webkit


Ignore:
Timestamp:
Jul 8, 2021 12:23:32 AM (13 months ago)
Author:
commit-queue@webkit.org
Message:

[css-scroll-snap] scroll-snap-align should use the box's writing-mode when the box is larger than the snapport
https://bugs.webkit.org/show_bug.cgi?id=227743

Patch by Martin Robinson <mrobinson@igalia.com> on 2021-07-08
Reviewed by Simon Fraser.

Source/WebCore:

No new tests. This fixes an existing WPT test:

  • imported/w3c/web-platform-tests/css/css-scroll-snap/snap-after-initial-layout/scroll-snap-writing-mode-000.html
  • page/scrolling/ScrollSnapOffsetsInfo.cpp:

(WebCore::axesFlippedForWritingModeAndDirection): Added this helper which abstracts the process of
determining if the x-axis and y-axis are flipped given the style's writing mode and text direction.
(WebCore::updateSnapOffsetsForScrollableArea): When the inline axis of the box defining the snap area
is larger than the snapport, we use the box's writing mode and text-direction to determine if the
x-axis and y-axis are flipped.

LayoutTests:

Location:
trunk
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r279706 r279714  
     12021-07-08  Martin Robinson  <mrobinson@igalia.com>
     2
     3        [css-scroll-snap] scroll-snap-align should use the box's writing-mode when the box is larger than the snapport
     4        https://bugs.webkit.org/show_bug.cgi?id=227743
     5
     6        Reviewed by Simon Fraser.
     7
     8        * TestExpectations: Unskip a test which is now passing.
     9
    1102021-07-07  Chris Dumez  <cdumez@apple.com>
    211
  • trunk/LayoutTests/TestExpectations

    r279698 r279714  
    47264726imported/w3c/web-platform-tests/css/css-scroll-snap/scroll-target-snap-001.html [ ImageOnlyFailure ]
    47274727imported/w3c/web-platform-tests/css/css-scroll-snap/scroll-target-snap-002.html [ ImageOnlyFailure ]
    4728 imported/w3c/web-platform-tests/css/css-scroll-snap/snap-after-initial-layout/scroll-snap-writing-mode-000.html [ ImageOnlyFailure ]
    47294728webkit.org/b/218325 imported/w3c/web-platform-tests/css/css-scroll-snap/scroll-target-margin-001.html [ Pass ImageOnlyFailure ]
    47304729webkit.org/b/218325 imported/w3c/web-platform-tests/css/css-scroll-snap/scroll-target-margin-003.html [ Pass ImageOnlyFailure ]
  • trunk/Source/WebCore/ChangeLog

    r279713 r279714  
     12021-07-08  Martin Robinson  <mrobinson@igalia.com>
     2
     3        [css-scroll-snap] scroll-snap-align should use the box's writing-mode when the box is larger than the snapport
     4        https://bugs.webkit.org/show_bug.cgi?id=227743
     5
     6        Reviewed by Simon Fraser.
     7
     8        No new tests. This fixes an existing WPT test:
     9           - imported/w3c/web-platform-tests/css/css-scroll-snap/snap-after-initial-layout/scroll-snap-writing-mode-000.html
     10
     11        * page/scrolling/ScrollSnapOffsetsInfo.cpp:
     12        (WebCore::axesFlippedForWritingModeAndDirection): Added this helper which abstracts the process of
     13        determining if the x-axis and y-axis are flipped given the style's writing mode and text direction.
     14        (WebCore::updateSnapOffsetsForScrollableArea): When the inline axis of the box defining the snap area
     15        is larger than the snapport, we use the box's writing mode and text-direction to determine if the
     16        x-axis and y-axis are flipped.
     17
    1182021-07-08  Fujii Hironori  <Hironori.Fujii@sony.com>
    219
  • trunk/Source/WebCore/page/scrolling/ScrollSnapOffsetsInfo.cpp

    r279364 r279714  
    200200}
    201201
     202static std::pair<bool, bool> axesFlippedForWritingModeAndDirection(WritingMode writingMode, TextDirection textDirection)
     203{
     204    // text-direction flips the inline axis and writing-mode can flip the block axis. Whether or
     205    // not the writing-mode is vertical determines the physical orientation of the block and inline axes.
     206    bool hasVerticalWritingMode = isVerticalWritingMode(writingMode);
     207    bool blockAxisFlipped = isFlippedWritingMode(writingMode);
     208    bool inlineAxisFlipped = textDirection == TextDirection::RTL;
     209    return std::make_pair(hasVerticalWritingMode ? blockAxisFlipped : inlineAxisFlipped, hasVerticalWritingMode ? inlineAxisFlipped : blockAxisFlipped);
     210}
     211
    202212void updateSnapOffsetsForScrollableArea(ScrollableArea& scrollableArea, const RenderBox& scrollingElementBox, const RenderStyle& scrollingElementStyle, LayoutRect viewportRectInBorderBoxCoordinates, WritingMode writingMode, TextDirection textDirection)
    203213{
     
    224234    auto scrollPosition = LayoutPoint { scrollableArea.scrollPosition() };
    225235
    226     // text-direction flips the inline axis and writing-mode can flip the block axis. Whether or
    227     // not the writing-mode is vertical determines the physical orientation of the block and inline axes.
     236    auto [scrollerXAxisFlipped, scrollerYAxisFlipped] = axesFlippedForWritingModeAndDirection(writingMode, textDirection);
    228237    bool scrollerHasVerticalWritingMode = isVerticalWritingMode(writingMode);
    229     bool blockAxisFlipped = isFlippedWritingMode(writingMode);
    230     bool inlineAxisFlipped = textDirection == TextDirection::RTL;
    231     bool xAxisFlipped = scrollerHasVerticalWritingMode ? blockAxisFlipped : inlineAxisFlipped;
    232     bool yAxisFlipped = scrollerHasVerticalWritingMode ? inlineAxisFlipped : blockAxisFlipped;
    233 
    234238    bool hasHorizontalSnapOffsets = scrollSnapType.axis == ScrollSnapAxis::Both || scrollSnapType.axis == ScrollSnapAxis::XAxis;
    235239    bool hasVerticalSnapOffsets = scrollSnapType.axis == ScrollSnapAxis::Both || scrollSnapType.axis == ScrollSnapAxis::YAxis;
     
    264268        auto stop = child->style().scrollSnapStop();
    265269
     270        // From https://drafts.csswg.org/css-scroll-snap-1/#scroll-snap-align:
     271        // "Start and end alignments are resolved with respect to the writing mode of the snap container unless the
     272        // scroll snap area is larger than the snapport, in which case they are resolved with respect to the writing
     273        // mode of the box itself."
     274        bool areaXAxisFlipped = scrollerXAxisFlipped;
     275        bool areaYAxisFlipped = scrollerYAxisFlipped;
     276        bool areaHasVerticalWritingMode = isVerticalWritingMode(child->style().writingMode());
     277        if ((areaHasVerticalWritingMode && scrollSnapArea.height() > scrollSnapPort.height()) || (!areaHasVerticalWritingMode && scrollSnapArea.width() > scrollSnapPort.width()))
     278            std::tie(areaXAxisFlipped, areaYAxisFlipped) = axesFlippedForWritingModeAndDirection(child->style().writingMode(), child->style().direction());
     279
    266280        ScrollSnapAxisAlignType xAlign = scrollerHasVerticalWritingMode ? alignment.blockAlign : alignment.inlineAlign;
    267281        ScrollSnapAxisAlignType yAlign = scrollerHasVerticalWritingMode ? alignment.inlineAlign : alignment.blockAlign;
     
    271285        if (!snapsHorizontally && !snapsVertically)
    272286            continue;
    273 
    274287        // The scroll snap area is defined via its scroll position, so convert the snap area rectangle to be relative to scroll offsets.
    275288        auto snapAreaOriginRelativeToBorderEdge = scrollSnapArea.location() - scrollSnapPort.location();
     
    278291
    279292        if (snapsHorizontally) {
    280             auto absoluteScrollXPosition = computeScrollSnapAlignOffset(scrollSnapArea.x(), scrollSnapArea.maxX(), xAlign, xAxisFlipped) - computeScrollSnapAlignOffset(scrollSnapPort.x(), scrollSnapPort.maxX(), xAlign, xAxisFlipped);
     293            auto absoluteScrollXPosition = computeScrollSnapAlignOffset(scrollSnapArea.x(), scrollSnapArea.maxX(), xAlign, areaXAxisFlipped) - computeScrollSnapAlignOffset(scrollSnapPort.x(), scrollSnapPort.maxX(), xAlign, areaXAxisFlipped);
    281294            auto absoluteScrollOffset = clampTo<int>(scrollableArea.scrollOffsetFromPosition({ roundToInt(absoluteScrollXPosition), 0 }).x(), 0, maxScrollOffset.x());
    282295            addOrUpdateStopForSnapOffset(horizontalSnapOffsetsMap, { absoluteScrollOffset, stop, snapAreas.size() - 1 });
    283296        }
    284297        if (snapsVertically) {
    285             auto absoluteScrollYPosition = computeScrollSnapAlignOffset(scrollSnapArea.y(), scrollSnapArea.maxY(), yAlign, yAxisFlipped) - computeScrollSnapAlignOffset(scrollSnapPort.y(), scrollSnapPort.maxY(), yAlign, yAxisFlipped);
     298            auto absoluteScrollYPosition = computeScrollSnapAlignOffset(scrollSnapArea.y(), scrollSnapArea.maxY(), yAlign, areaYAxisFlipped) - computeScrollSnapAlignOffset(scrollSnapPort.y(), scrollSnapPort.maxY(), yAlign, areaYAxisFlipped);
    286299            auto absoluteScrollOffset = clampTo<int>(scrollableArea.scrollOffsetFromPosition({ 0, roundToInt(absoluteScrollYPosition) }).y(), 0, maxScrollOffset.y());
    287300            addOrUpdateStopForSnapOffset(verticalSnapOffsetsMap, { absoluteScrollOffset, stop, snapAreas.size() - 1 });
Note: See TracChangeset for help on using the changeset viewer.