Title: [270390] trunk/Source
Revision
270390
Author
[email protected]
Date
2020-12-03 01:50:39 -0800 (Thu, 03 Dec 2020)

Log Message

Move code from AxisScrollSnapOffsets to ScrollSnapOffsetsInfo
https://bugs.webkit.org/show_bug.cgi?id=219345

Patch by Martin Robinson <[email protected]> on 2020-12-03
Reviewed by Daniel Bates.

Source/WebCore:

No new tests. This should not modify behavior.

* Headers.cmake: Remove AxisScrollSnapOffsets.h from header list.
* Sources.txt: Update source list.
* WebCore.xcodeproj/project.pbxproj: Ditto.
* page/FrameView.cpp: Update includes.
* page/scrolling/AxisScrollSnapOffsets.h: Removed.
* page/scrolling/ScrollSnapOffsetsInfo.cpp: Renamed from Source/WebCore/page/scrolling/AxisScrollSnapOffsets.cpp.
(WebCore::indicesOfNearestSnapOffsetRanges): Added from AxisScrollSnapOffsets.
(WebCore::indicesOfNearestSnapOffsets): Ditto.
(WebCore::closestSnapOffset): Ditto.
(WebCore::computeScrollSnapPortOrAreaRect): Ditto.
(WebCore::computeScrollSnapAlignOffset): Ditto.
(WebCore::operator<<): Ditto.
(WebCore::computeAxisProximitySnapOffsetRanges): Ditto.
(WebCore::updateSnapOffsetsForScrollableArea): Ditto.
* page/scrolling/ScrollSnapOffsetsInfo.h: Added functions from AxisScrollSnapOffsets.h and surrounded
this header in conditional compilation so it can be included unconditionally.
* page/scrolling/ScrollingCoordinator.h: Updated includes.
* page/scrolling/ScrollingMomentumCalculator.h: Ditto.
* platform/cocoa/ScrollSnapAnimatorState.h: Ditto.
* rendering/RenderLayer.cpp: Ditto.

Source/WebKit:

* UIProcess/RemoteLayerTree/ios/RemoteScrollingCoordinatorProxyIOS.mm: Remove AxisScrollSnapOffsets.h include.
* UIProcess/RemoteLayerTree/ios/ScrollingTreeScrollingNodeDelegateIOS.mm: Ditto.

Modified Paths

Added Paths

Removed Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (270389 => 270390)


--- trunk/Source/WebCore/ChangeLog	2020-12-03 07:58:44 UTC (rev 270389)
+++ trunk/Source/WebCore/ChangeLog	2020-12-03 09:50:39 UTC (rev 270390)
@@ -1,3 +1,33 @@
+2020-12-03  Martin Robinson  <[email protected]>
+
+        Move code from AxisScrollSnapOffsets to ScrollSnapOffsetsInfo
+        https://bugs.webkit.org/show_bug.cgi?id=219345
+
+        Reviewed by Daniel Bates.
+
+        No new tests. This should not modify behavior.
+
+        * Headers.cmake: Remove AxisScrollSnapOffsets.h from header list.
+        * Sources.txt: Update source list.
+        * WebCore.xcodeproj/project.pbxproj: Ditto.
+        * page/FrameView.cpp: Update includes.
+        * page/scrolling/AxisScrollSnapOffsets.h: Removed.
+        * page/scrolling/ScrollSnapOffsetsInfo.cpp: Renamed from Source/WebCore/page/scrolling/AxisScrollSnapOffsets.cpp.
+        (WebCore::indicesOfNearestSnapOffsetRanges): Added from AxisScrollSnapOffsets.
+        (WebCore::indicesOfNearestSnapOffsets): Ditto.
+        (WebCore::closestSnapOffset): Ditto.
+        (WebCore::computeScrollSnapPortOrAreaRect): Ditto.
+        (WebCore::computeScrollSnapAlignOffset): Ditto.
+        (WebCore::operator<<): Ditto.
+        (WebCore::computeAxisProximitySnapOffsetRanges): Ditto.
+        (WebCore::updateSnapOffsetsForScrollableArea): Ditto.
+        * page/scrolling/ScrollSnapOffsetsInfo.h: Added functions from AxisScrollSnapOffsets.h and surrounded
+        this header in conditional compilation so it can be included unconditionally.
+        * page/scrolling/ScrollingCoordinator.h: Updated includes.
+        * page/scrolling/ScrollingMomentumCalculator.h: Ditto.
+        * platform/cocoa/ScrollSnapAnimatorState.h: Ditto.
+        * rendering/RenderLayer.cpp: Ditto.
+
 2020-12-02  Simon Fraser  <[email protected]>
 
         Determine the WheelScrollGestureState on the main thread before passing it to ScrollingCoordinator

Modified: trunk/Source/WebCore/Headers.cmake (270389 => 270390)


--- trunk/Source/WebCore/Headers.cmake	2020-12-03 07:58:44 UTC (rev 270389)
+++ trunk/Source/WebCore/Headers.cmake	2020-12-03 09:50:39 UTC (rev 270390)
@@ -943,7 +943,6 @@
     page/csp/ContentSecurityPolicyResponseHeaders.h
 
     page/scrolling/AsyncScrollingCoordinator.h
-    page/scrolling/AxisScrollSnapOffsets.h
     page/scrolling/ScrollSnapOffsetsInfo.h
     page/scrolling/ScrollingConstraints.h
     page/scrolling/ScrollingCoordinator.h

Modified: trunk/Source/WebCore/Sources.txt (270389 => 270390)


--- trunk/Source/WebCore/Sources.txt	2020-12-03 07:58:44 UTC (rev 270389)
+++ trunk/Source/WebCore/Sources.txt	2020-12-03 09:50:39 UTC (rev 270390)
@@ -1757,7 +1757,7 @@
 page/csp/ContentSecurityPolicySourceList.cpp
 page/csp/ContentSecurityPolicySourceListDirective.cpp
 page/scrolling/AsyncScrollingCoordinator.cpp
-page/scrolling/AxisScrollSnapOffsets.cpp
+page/scrolling/ScrollSnapOffsetsInfo.cpp
 page/scrolling/ScrollLatchingController.cpp
 page/scrolling/ScrollingConstraints.cpp
 page/scrolling/ScrollingCoordinator.cpp

Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (270389 => 270390)


--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj	2020-12-03 07:58:44 UTC (rev 270389)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj	2020-12-03 09:50:39 UTC (rev 270390)
@@ -5227,7 +5227,6 @@
 		F44A5F591FED38F2007F5944 /* LegacyNSPasteboardTypes.h in Headers */ = {isa = PBXBuildFile; fileRef = F44A5F571FED3830007F5944 /* LegacyNSPasteboardTypes.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		F44EBBD91DB5D21400277334 /* StaticRange.h in Headers */ = {isa = PBXBuildFile; fileRef = F44EBBD81DB5D21400277334 /* StaticRange.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		F45775CE241437D5002DF1A0 /* InlinePathData.h in Headers */ = {isa = PBXBuildFile; fileRef = F45775CD241437D5002DF1A0 /* InlinePathData.h */; settings = {ATTRIBUTES = (Private, ); }; };
-		F45C231E1995B73B00A6E2E3 /* AxisScrollSnapOffsets.h in Headers */ = {isa = PBXBuildFile; fileRef = F45C231C1995B73B00A6E2E3 /* AxisScrollSnapOffsets.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		F46729281E0DE68500ACC3D8 /* ScrollSnapOffsetsInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = F46729251E0DE5AB00ACC3D8 /* ScrollSnapOffsetsInfo.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		F46C447E234654540039A79D /* ClipboardItemBindingsDataSource.h in Headers */ = {isa = PBXBuildFile; fileRef = F46C447C234654540039A79D /* ClipboardItemBindingsDataSource.h */; };
 		F478755419983AFF0024A287 /* ScrollSnapAnimatorState.h in Headers */ = {isa = PBXBuildFile; fileRef = F478755219983AFF0024A287 /* ScrollSnapAnimatorState.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -9407,6 +9406,7 @@
 		5B30695A18B3D3450099D5E8 /* WebGLDrawBuffers.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WebGLDrawBuffers.cpp; sourceTree = "<group>"; };
 		5B30695B18B3D3450099D5E8 /* WebGLDrawBuffers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebGLDrawBuffers.h; sourceTree = "<group>"; };
 		5B30695C18B3D3450099D5E8 /* WebGLDrawBuffers.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = WebGLDrawBuffers.idl; sourceTree = "<group>"; };
+		5B7AB9F62567DB7E006592D0 /* ScrollSnapOffsetsInfo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ScrollSnapOffsetsInfo.cpp; sourceTree = "<group>"; };
 		5C001521250011000094AA93 /* TextCodecSingleByte.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TextCodecSingleByte.cpp; sourceTree = "<group>"; };
 		5C001523250011010094AA93 /* TextCodecSingleByte.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TextCodecSingleByte.h; sourceTree = "<group>"; };
 		5C39305D1AA0F6A90029C816 /* DFABytecode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DFABytecode.h; sourceTree = "<group>"; };
@@ -16491,8 +16491,6 @@
 		F44EBBD81DB5D21400277334 /* StaticRange.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StaticRange.h; sourceTree = "<group>"; };
 		F44EBBDA1DB5DD9D00277334 /* StaticRange.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StaticRange.cpp; sourceTree = "<group>"; };
 		F45775CD241437D5002DF1A0 /* InlinePathData.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = InlinePathData.h; sourceTree = "<group>"; };
-		F45C231B1995B73B00A6E2E3 /* AxisScrollSnapOffsets.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AxisScrollSnapOffsets.cpp; sourceTree = "<group>"; };
-		F45C231C1995B73B00A6E2E3 /* AxisScrollSnapOffsets.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AxisScrollSnapOffsets.h; sourceTree = "<group>"; };
 		F4628A9E234D3BBF00BC884C /* PlatformPasteboardCocoa.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = PlatformPasteboardCocoa.mm; sourceTree = "<group>"; };
 		F462E79F242ADA3C00204DDD /* DragDataCocoa.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = DragDataCocoa.mm; sourceTree = "<group>"; };
 		F462E7A0242ADA3D00204DDD /* DragImageCocoa.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = DragImageCocoa.mm; sourceTree = "<group>"; };
@@ -18469,8 +18467,6 @@
 				1AF62EE214DA22A70041556C /* mac */,
 				0FFD4D5E18651FA300512F6E /* AsyncScrollingCoordinator.cpp */,
 				0FFD4D5F18651FA300512F6E /* AsyncScrollingCoordinator.h */,
-				F45C231B1995B73B00A6E2E3 /* AxisScrollSnapOffsets.cpp */,
-				F45C231C1995B73B00A6E2E3 /* AxisScrollSnapOffsets.h */,
 				0F605AEA15F94848004DF0C0 /* ScrollingConstraints.cpp */,
 				0F605AEB15F94848004DF0C0 /* ScrollingConstraints.h */,
 				1AF62EE414DA22A70041556C /* ScrollingCoordinator.cpp */,
@@ -18520,6 +18516,7 @@
 				A6D5A99B1629D70000297330 /* ScrollingTreeScrollingNodeDelegate.h */,
 				0F9510F224F4769C001F52DC /* ScrollLatchingController.cpp */,
 				0F9510F024F4769C001F52DC /* ScrollLatchingController.h */,
+				5B7AB9F62567DB7E006592D0 /* ScrollSnapOffsetsInfo.cpp */,
 				F46729251E0DE5AB00ACC3D8 /* ScrollSnapOffsetsInfo.h */,
 				0F6383DB18615B29003E5DB5 /* ThreadedScrollingTree.cpp */,
 				0F6383DC18615B29003E5DB5 /* ThreadedScrollingTree.h */,
@@ -31118,7 +31115,6 @@
 				070363E6181A1CDC00C074A5 /* AVVideoCaptureSource.h in Headers */,
 				29AE213521ABA48A00869283 /* AXIsolatedObject.h in Headers */,
 				29AE212D21AB9EEB00869283 /* AXIsolatedTree.h in Headers */,
-				F45C231E1995B73B00A6E2E3 /* AxisScrollSnapOffsets.h in Headers */,
 				29A812380FBB9C1D00510293 /* AXObjectCache.h in Headers */,
 				91C9F2F91AE3BEB00095B61C /* AXTextStateChangeIntent.h in Headers */,
 				1477E7770BF4134A00152872 /* BackForwardCache.h in Headers */,

Modified: trunk/Source/WebCore/page/FrameView.cpp (270389 => 270390)


--- trunk/Source/WebCore/page/FrameView.cpp	2020-12-03 07:58:44 UTC (rev 270389)
+++ trunk/Source/WebCore/page/FrameView.cpp	2020-12-03 09:50:39 UTC (rev 270390)
@@ -96,6 +96,7 @@
 #include "ScriptRunner.h"
 #include "ScriptedAnimationController.h"
 #include "ScrollAnimator.h"
+#include "ScrollSnapOffsetsInfo.h"
 #include "ScrollingCoordinator.h"
 #include "Settings.h"
 #include "StyleResolver.h"
@@ -117,10 +118,6 @@
 #include "TiledBackingStore.h"
 #endif
 
-#if ENABLE(CSS_SCROLL_SNAP)
-#include "AxisScrollSnapOffsets.h"
-#endif
-
 #if PLATFORM(IOS_FAMILY)
 #include "DocumentLoader.h"
 #include "LegacyTileCache.h"

Deleted: trunk/Source/WebCore/page/scrolling/AxisScrollSnapOffsets.cpp (270389 => 270390)


--- trunk/Source/WebCore/page/scrolling/AxisScrollSnapOffsets.cpp	2020-12-03 07:58:44 UTC (rev 270389)
+++ trunk/Source/WebCore/page/scrolling/AxisScrollSnapOffsets.cpp	2020-12-03 09:50:39 UTC (rev 270390)
@@ -1,313 +0,0 @@
-/*
- * Copyright (C) 2014-2015 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "AxisScrollSnapOffsets.h"
-
-#include "ElementChildIterator.h"
-#include "HTMLElement.h"
-#include "Length.h"
-#include "Logging.h"
-#include "RenderBox.h"
-#include "RenderView.h"
-#include "ScrollableArea.h"
-#include "StyleScrollSnapPoints.h"
-#include <wtf/text/StringConcatenateNumbers.h>
-
-#if ENABLE(CSS_SCROLL_SNAP)
-
-namespace WebCore {
-
-enum class InsetOrOutset {
-    Inset,
-    Outset
-};
-
-static LayoutRect computeScrollSnapPortOrAreaRect(const LayoutRect& rect, const LengthBox& insetOrOutsetBox, InsetOrOutset insetOrOutset)
-{
-    LayoutBoxExtent extents(valueForLength(insetOrOutsetBox.top(), rect.height()), valueForLength(insetOrOutsetBox.right(), rect.width()), valueForLength(insetOrOutsetBox.bottom(), rect.height()), valueForLength(insetOrOutsetBox.left(), rect.width()));
-    auto snapPortOrArea(rect);
-    if (insetOrOutset == InsetOrOutset::Inset)
-        snapPortOrArea.contract(extents);
-    else
-        snapPortOrArea.expand(extents);
-    return snapPortOrArea;
-}
-
-static LayoutUnit computeScrollSnapAlignOffset(LayoutUnit minLocation, LayoutUnit maxLocation, ScrollSnapAxisAlignType alignment, bool axisIsFlipped)
-{
-    switch (alignment) {
-    case ScrollSnapAxisAlignType::Start:
-        return axisIsFlipped ? maxLocation : minLocation;
-    case ScrollSnapAxisAlignType::Center:
-        return (minLocation + maxLocation) / 2;
-    case ScrollSnapAxisAlignType::End:
-        return axisIsFlipped ? minLocation : maxLocation;
-    default:
-        ASSERT_NOT_REACHED();
-        return 0;
-    }
-}
-
-template<typename T>
-TextStream& operator<<(TextStream& ts, const ScrollOffsetRange<T>& range)
-{
-    ts << "start: " << range.start << " end: " << range.end;
-    return ts;
-}
-
-template <typename LayoutType>
-static void indicesOfNearestSnapOffsetRanges(LayoutType offset, const Vector<ScrollOffsetRange<LayoutType>>& snapOffsetRanges, unsigned& lowerIndex, unsigned& upperIndex)
-{
-    if (snapOffsetRanges.isEmpty()) {
-        lowerIndex = invalidSnapOffsetIndex;
-        upperIndex = invalidSnapOffsetIndex;
-        return;
-    }
-
-    int lowerIndexAsInt = -1;
-    int upperIndexAsInt = snapOffsetRanges.size();
-    do {
-        int middleIndex = (lowerIndexAsInt + upperIndexAsInt) / 2;
-        auto& range = snapOffsetRanges[middleIndex];
-        if (range.start < offset && offset < range.end) {
-            lowerIndexAsInt = middleIndex;
-            upperIndexAsInt = middleIndex;
-            break;
-        }
-
-        if (offset > range.end)
-            lowerIndexAsInt = middleIndex;
-        else
-            upperIndexAsInt = middleIndex;
-    } while (lowerIndexAsInt < upperIndexAsInt - 1);
-
-    if (offset <= snapOffsetRanges.first().start)
-        lowerIndex = invalidSnapOffsetIndex;
-    else
-        lowerIndex = lowerIndexAsInt;
-
-    if (offset >= snapOffsetRanges.last().end)
-        upperIndex = invalidSnapOffsetIndex;
-    else
-        upperIndex = upperIndexAsInt;
-}
-
-template <typename LayoutType>
-static void indicesOfNearestSnapOffsets(LayoutType offset, const Vector<LayoutType>& snapOffsets, unsigned& lowerIndex, unsigned& upperIndex)
-{
-    lowerIndex = 0;
-    upperIndex = snapOffsets.size() - 1;
-    while (lowerIndex < upperIndex - 1) {
-        int middleIndex = (lowerIndex + upperIndex) / 2;
-        auto middleOffset = snapOffsets[middleIndex];
-        if (offset == middleOffset) {
-            upperIndex = middleIndex;
-            lowerIndex = middleIndex;
-            break;
-        }
-
-        if (offset > middleOffset)
-            lowerIndex = middleIndex;
-        else
-            upperIndex = middleIndex;
-    }
-}
-
-static void computeAxisProximitySnapOffsetRanges(const Vector<LayoutUnit>& snapOffsets, Vector<ScrollOffsetRange<LayoutUnit>>& offsetRanges, LayoutUnit scrollPortAxisLength)
-{
-    // This is an arbitrary choice for what it means to be "in proximity" of a snap offset. We should play around with
-    // this and see what feels best.
-    static const float ratioOfScrollPortAxisLengthToBeConsideredForProximity = 0.3;
-    if (snapOffsets.size() < 2)
-        return;
-
-    // The extra rule accounting for scroll offset ranges in between the scroll destination and a potential snap offset
-    // handles the corner case where the user scrolls with momentum very lightly away from a snap offset, such that the
-    // predicted scroll destination is still within proximity of the snap offset. In this case, the regular (mandatory
-    // scroll snapping) behavior would be to snap to the next offset in the direction of momentum scrolling, but
-    // instead, it is more intuitive to either return to the original snap position (which we arbitrarily choose here)
-    // or scroll just outside of the snap offset range. This is another minor behavior tweak that we should play around
-    // with to see what feels best.
-    LayoutUnit proximityDistance { ratioOfScrollPortAxisLengthToBeConsideredForProximity * scrollPortAxisLength };
-    for (size_t index = 1; index < snapOffsets.size(); ++index) {
-        auto startOffset = snapOffsets[index - 1] + proximityDistance;
-        auto endOffset = snapOffsets[index] - proximityDistance;
-        if (startOffset < endOffset)
-            offsetRanges.append({ startOffset, endOffset });
-    }
-}
-
-void updateSnapOffsetsForScrollableArea(ScrollableArea& scrollableArea, const RenderBox& scrollingElementBox, const RenderStyle& scrollingElementStyle, LayoutRect viewportRectInBorderBoxCoordinates)
-{
-    auto scrollSnapType = scrollingElementStyle.scrollSnapType();
-    const auto& boxesWithScrollSnapPositions = scrollingElementBox.view().boxesWithScrollSnapPositions();
-    if (scrollSnapType.strictness == ScrollSnapStrictness::None || boxesWithScrollSnapPositions.isEmpty()) {
-        scrollableArea.clearSnapOffsets();
-        return;
-    }
-
-    Vector<LayoutUnit> verticalSnapOffsets;
-    Vector<LayoutUnit> horizontalSnapOffsets;
-    Vector<ScrollOffsetRange<LayoutUnit>> verticalSnapOffsetRanges;
-    Vector<ScrollOffsetRange<LayoutUnit>> horizontalSnapOffsetRanges;
-    HashSet<float> seenVerticalSnapOffsets;
-    HashSet<float> seenHorizontalSnapOffsets;
-    bool hasHorizontalSnapOffsets = scrollSnapType.axis == ScrollSnapAxis::Both || scrollSnapType.axis == ScrollSnapAxis::XAxis || scrollSnapType.axis == ScrollSnapAxis::Inline;
-    bool hasVerticalSnapOffsets = scrollSnapType.axis == ScrollSnapAxis::Both || scrollSnapType.axis == ScrollSnapAxis::YAxis || scrollSnapType.axis == ScrollSnapAxis::Block;
-
-    auto maxScrollOffset = scrollableArea.maximumScrollOffset();
-    auto scrollPosition = LayoutPoint { scrollableArea.scrollPosition() };
-    bool scrollerIsRTL = !scrollingElementBox.style().isLeftToRightDirection();
-
-    // The bounds of the scrolling container's snap port, where the top left of the scrolling container's border box is the origin.
-    auto scrollSnapPort = computeScrollSnapPortOrAreaRect(viewportRectInBorderBoxCoordinates, scrollingElementStyle.scrollPadding(), InsetOrOutset::Inset);
-    LOG_WITH_STREAM(ScrollSnap, stream << "Computing scroll snap offsets for " << scrollableArea << " in snap port " << scrollSnapPort);
-    for (auto* child : boxesWithScrollSnapPositions) {
-        if (child->enclosingScrollableContainerForSnapping() != &scrollingElementBox)
-            continue;
-
-        // The bounds of the child element's snap area, where the top left of the scrolling container's border box is the origin.
-        // The snap area is the bounding box of the child element's border box, after applying transformations.
-        // FIXME: For now, just consider whether the scroller is RTL. The behavior of LTR boxes inside a RTL scroller is poorly defined: https://github.com/w3c/csswg-drafts/issues/5361.
-        auto scrollSnapArea = LayoutRect(child->localToContainerQuad(FloatQuad(child->borderBoundingBox()), &scrollingElementBox).boundingBox());
-
-        // localToContainerQuad will transform the scroll snap area by the scroll position, except in the case that this position is
-        // coming from a ScrollView. We want the transformed area, but without scroll position taken into account.
-        if (!scrollableArea.isScrollView())
-            scrollSnapArea.moveBy(scrollPosition);
-
-        scrollSnapArea = computeScrollSnapPortOrAreaRect(scrollSnapArea, child->style().scrollMargin(), InsetOrOutset::Outset);
-        LOG_WITH_STREAM(ScrollSnap, stream << "    Considering scroll snap target area " << scrollSnapArea);
-        auto alignment = child->style().scrollSnapAlign();
-        if (hasHorizontalSnapOffsets && alignment.x != ScrollSnapAxisAlignType::None) {
-            auto absoluteScrollXPosition = computeScrollSnapAlignOffset(scrollSnapArea.x(), scrollSnapArea.maxX(), alignment.x, scrollerIsRTL) - computeScrollSnapAlignOffset(scrollSnapPort.x(), scrollSnapPort.maxX(), alignment.x, scrollerIsRTL);
-            auto absoluteScrollOffset = clampTo<int>(scrollableArea.scrollOffsetFromPosition({ roundToInt(absoluteScrollXPosition), 0 }).x(), 0, maxScrollOffset.x());
-            if (!seenHorizontalSnapOffsets.contains(absoluteScrollOffset)) {
-                seenHorizontalSnapOffsets.add(absoluteScrollOffset);
-                horizontalSnapOffsets.append(absoluteScrollOffset);
-            }
-        }
-        if (hasVerticalSnapOffsets && alignment.y != ScrollSnapAxisAlignType::None) {
-            auto absoluteScrollYPosition = computeScrollSnapAlignOffset(scrollSnapArea.y(), scrollSnapArea.maxY(), alignment.y, false) - computeScrollSnapAlignOffset(scrollSnapPort.y(), scrollSnapPort.maxY(), alignment.y, false);
-            auto absoluteScrollOffset = clampTo<int>(scrollableArea.scrollOffsetFromPosition({ 0, roundToInt(absoluteScrollYPosition) }).y(), 0, maxScrollOffset.y());
-            if (!seenVerticalSnapOffsets.contains(absoluteScrollOffset)) {
-                seenVerticalSnapOffsets.add(absoluteScrollOffset);
-                verticalSnapOffsets.append(absoluteScrollOffset);
-            }
-        }
-    }
-
-    if (!horizontalSnapOffsets.isEmpty()) {
-        std::sort(horizontalSnapOffsets.begin(), horizontalSnapOffsets.end());
-        if (scrollSnapType.strictness == ScrollSnapStrictness::Proximity)
-            computeAxisProximitySnapOffsetRanges(horizontalSnapOffsets, horizontalSnapOffsetRanges, scrollSnapPort.width());
-
-        LOG_WITH_STREAM(ScrollSnap, stream << " => Computed horizontal scroll snap offsets: " << horizontalSnapOffsets);
-        LOG_WITH_STREAM(ScrollSnap, stream << " => Computed horizontal scroll snap offset ranges: " << horizontalSnapOffsetRanges);
-
-        scrollableArea.setHorizontalSnapOffsets(horizontalSnapOffsets);
-        scrollableArea.setHorizontalSnapOffsetRanges(horizontalSnapOffsetRanges);
-    } else
-        scrollableArea.clearHorizontalSnapOffsets();
-
-    if (!verticalSnapOffsets.isEmpty()) {
-        std::sort(verticalSnapOffsets.begin(), verticalSnapOffsets.end());
-        if (scrollSnapType.strictness == ScrollSnapStrictness::Proximity)
-            computeAxisProximitySnapOffsetRanges(verticalSnapOffsets, verticalSnapOffsetRanges, scrollSnapPort.height());
-
-        LOG_WITH_STREAM(ScrollSnap, stream << " => Computed vertical scroll snap offsets: " << verticalSnapOffsets);
-        LOG_WITH_STREAM(ScrollSnap, stream << " => Computed vertical scroll snap offset ranges: " << verticalSnapOffsetRanges);
-
-        scrollableArea.setVerticalSnapOffsets(verticalSnapOffsets);
-        scrollableArea.setVerticalSnapOffsetRanges(verticalSnapOffsetRanges);
-    } else
-        scrollableArea.clearVerticalSnapOffsets();
-}
-
-template <typename LayoutType>
-LayoutType closestSnapOffset(const Vector<LayoutType>& snapOffsets, const Vector<ScrollOffsetRange<LayoutType>>& snapOffsetRanges, LayoutType scrollDestination, float velocity, unsigned& activeSnapIndex)
-{
-    ASSERT(snapOffsets.size());
-    activeSnapIndex = 0;
-
-    unsigned lowerSnapOffsetRangeIndex;
-    unsigned upperSnapOffsetRangeIndex;
-    indicesOfNearestSnapOffsetRanges<LayoutType>(scrollDestination, snapOffsetRanges, lowerSnapOffsetRangeIndex, upperSnapOffsetRangeIndex);
-    if (lowerSnapOffsetRangeIndex == upperSnapOffsetRangeIndex && upperSnapOffsetRangeIndex != invalidSnapOffsetIndex) {
-        activeSnapIndex = invalidSnapOffsetIndex;
-        return scrollDestination;
-    }
-
-    if (scrollDestination <= snapOffsets.first())
-        return snapOffsets.first();
-
-    activeSnapIndex = snapOffsets.size() - 1;
-    if (scrollDestination >= snapOffsets.last())
-        return snapOffsets.last();
-
-    unsigned lowerIndex;
-    unsigned upperIndex;
-    indicesOfNearestSnapOffsets<LayoutType>(scrollDestination, snapOffsets, lowerIndex, upperIndex);
-    LayoutType lowerSnapPosition = snapOffsets[lowerIndex];
-    LayoutType upperSnapPosition = snapOffsets[upperIndex];
-    if (!std::abs(velocity)) {
-        bool isCloserToLowerSnapPosition = scrollDestination - lowerSnapPosition <= upperSnapPosition - scrollDestination;
-        activeSnapIndex = isCloserToLowerSnapPosition ? lowerIndex : upperIndex;
-        return isCloserToLowerSnapPosition ? lowerSnapPosition : upperSnapPosition;
-    }
-
-    // Non-zero velocity indicates a flick gesture. Even if another snap point is closer, we should choose the one in the direction of the flick gesture
-    // as long as a scroll snap offset range does not lie between the scroll destination and the targeted snap offset.
-    if (velocity < 0) {
-        if (lowerSnapOffsetRangeIndex != invalidSnapOffsetIndex && lowerSnapPosition < snapOffsetRanges[lowerSnapOffsetRangeIndex].end) {
-            activeSnapIndex = upperIndex;
-            return upperSnapPosition;
-        }
-        activeSnapIndex = lowerIndex;
-        return lowerSnapPosition;
-    }
-
-    if (upperSnapOffsetRangeIndex != invalidSnapOffsetIndex && snapOffsetRanges[upperSnapOffsetRangeIndex].start < upperSnapPosition) {
-        activeSnapIndex = lowerIndex;
-        return lowerSnapPosition;
-    }
-    activeSnapIndex = upperIndex;
-    return upperSnapPosition;
-}
-
-LayoutUnit closestSnapOffset(const Vector<LayoutUnit>& snapOffsets, const Vector<ScrollOffsetRange<LayoutUnit>>& snapOffsetRanges, LayoutUnit scrollDestination, float velocity, unsigned& activeSnapIndex)
-{
-    return closestSnapOffset<LayoutUnit>(snapOffsets, snapOffsetRanges, scrollDestination, velocity, activeSnapIndex);
-}
-
-float closestSnapOffset(const Vector<float>& snapOffsets, const Vector<ScrollOffsetRange<float>>& snapOffsetRanges, float scrollDestination, float velocity, unsigned& activeSnapIndex)
-{
-    return closestSnapOffset<float>(snapOffsets, snapOffsetRanges, scrollDestination, velocity, activeSnapIndex);
-}
-
-} // namespace WebCore
-
-#endif // CSS_SCROLL_SNAP

Deleted: trunk/Source/WebCore/page/scrolling/AxisScrollSnapOffsets.h (270389 => 270390)


--- trunk/Source/WebCore/page/scrolling/AxisScrollSnapOffsets.h	2020-12-03 07:58:44 UTC (rev 270389)
+++ trunk/Source/WebCore/page/scrolling/AxisScrollSnapOffsets.h	2020-12-03 09:50:39 UTC (rev 270390)
@@ -1,54 +0,0 @@
-/*
- * Copyright (C) 2014-2015 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#pragma once
-
-#if ENABLE(CSS_SCROLL_SNAP)
-
-#include "LayoutRect.h"
-#include "LayoutUnit.h"
-#include "ScrollSnapOffsetsInfo.h"
-#include "ScrollTypes.h"
-#include <wtf/Forward.h>
-
-namespace WebCore {
-
-class HTMLElement;
-class RenderBox;
-class RenderStyle;
-class ScrollableArea;
-
-// Update the snap offsets for this scrollable area, given the RenderBox of the scroll container, the RenderStyle
-// which defines the scroll-snap properties, and the viewport rectangle with the origin at the top left of
-// the scrolling container's border box.
-void updateSnapOffsetsForScrollableArea(ScrollableArea&, const RenderBox& scrollingElementBox, const RenderStyle& scrollingElementStyle, LayoutRect viewportRectInBorderBoxCoordinates);
-
-const unsigned invalidSnapOffsetIndex = UINT_MAX;
-WEBCORE_EXPORT LayoutUnit closestSnapOffset(const Vector<LayoutUnit>& snapOffsets, const Vector<ScrollOffsetRange<LayoutUnit>>& snapOffsetRanges, LayoutUnit scrollDestination, float velocity, unsigned& activeSnapIndex);
-WEBCORE_EXPORT float closestSnapOffset(const Vector<float>& snapOffsets, const Vector<ScrollOffsetRange<float>>& snapOffsetRanges, float scrollDestination, float velocity, unsigned& activeSnapIndex);
-
-} // namespace WebCore
-
-#endif // ENABLE(CSS_SCROLL_SNAP)

Copied: trunk/Source/WebCore/page/scrolling/ScrollSnapOffsetsInfo.cpp (from rev 270389, trunk/Source/WebCore/page/scrolling/AxisScrollSnapOffsets.cpp) (0 => 270390)


--- trunk/Source/WebCore/page/scrolling/ScrollSnapOffsetsInfo.cpp	                        (rev 0)
+++ trunk/Source/WebCore/page/scrolling/ScrollSnapOffsetsInfo.cpp	2020-12-03 09:50:39 UTC (rev 270390)
@@ -0,0 +1,314 @@
+/*
+ * Copyright (C) 2014-2015 Apple Inc. All rights reserved.
+ * Copyright (C) 2020 Igalia S.L.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "ScrollSnapOffsetsInfo.h"
+
+#if ENABLE(CSS_SCROLL_SNAP)
+
+#include "ElementChildIterator.h"
+#include "LayoutRect.h"
+#include "Length.h"
+#include "RenderBox.h"
+#include "RenderStyle.h"
+#include "RenderView.h"
+#include "ScrollableArea.h"
+#include "StyleScrollSnapPoints.h"
+#include <wtf/text/StringConcatenateNumbers.h>
+
+namespace WebCore {
+
+template <typename LayoutType>
+static void indicesOfNearestSnapOffsetRanges(LayoutType offset, const Vector<ScrollOffsetRange<LayoutType>>& snapOffsetRanges, unsigned& lowerIndex, unsigned& upperIndex)
+{
+    if (snapOffsetRanges.isEmpty()) {
+        lowerIndex = invalidSnapOffsetIndex;
+        upperIndex = invalidSnapOffsetIndex;
+        return;
+    }
+
+    int lowerIndexAsInt = -1;
+    int upperIndexAsInt = snapOffsetRanges.size();
+    do {
+        int middleIndex = (lowerIndexAsInt + upperIndexAsInt) / 2;
+        auto& range = snapOffsetRanges[middleIndex];
+        if (range.start < offset && offset < range.end) {
+            lowerIndexAsInt = middleIndex;
+            upperIndexAsInt = middleIndex;
+            break;
+        }
+
+        if (offset > range.end)
+            lowerIndexAsInt = middleIndex;
+        else
+            upperIndexAsInt = middleIndex;
+    } while (lowerIndexAsInt < upperIndexAsInt - 1);
+
+    if (offset <= snapOffsetRanges.first().start)
+        lowerIndex = invalidSnapOffsetIndex;
+    else
+        lowerIndex = lowerIndexAsInt;
+
+    if (offset >= snapOffsetRanges.last().end)
+        upperIndex = invalidSnapOffsetIndex;
+    else
+        upperIndex = upperIndexAsInt;
+}
+
+template <typename LayoutType>
+static void indicesOfNearestSnapOffsets(LayoutType offset, const Vector<LayoutType>& snapOffsets, unsigned& lowerIndex, unsigned& upperIndex)
+{
+    lowerIndex = 0;
+    upperIndex = snapOffsets.size() - 1;
+    while (lowerIndex < upperIndex - 1) {
+        int middleIndex = (lowerIndex + upperIndex) / 2;
+        auto middleOffset = snapOffsets[middleIndex];
+        if (offset == middleOffset) {
+            upperIndex = middleIndex;
+            lowerIndex = middleIndex;
+            break;
+        }
+
+        if (offset > middleOffset)
+            lowerIndex = middleIndex;
+        else
+            upperIndex = middleIndex;
+    }
+}
+
+template <typename LayoutType>
+LayoutType closestSnapOffset(const Vector<LayoutType>& snapOffsets, const Vector<ScrollOffsetRange<LayoutType>>& snapOffsetRanges, LayoutType scrollDestination, float velocity, unsigned& activeSnapIndex)
+{
+    ASSERT(snapOffsets.size());
+    activeSnapIndex = 0;
+
+    unsigned lowerSnapOffsetRangeIndex;
+    unsigned upperSnapOffsetRangeIndex;
+    indicesOfNearestSnapOffsetRanges<LayoutType>(scrollDestination, snapOffsetRanges, lowerSnapOffsetRangeIndex, upperSnapOffsetRangeIndex);
+    if (lowerSnapOffsetRangeIndex == upperSnapOffsetRangeIndex && upperSnapOffsetRangeIndex != invalidSnapOffsetIndex) {
+        activeSnapIndex = invalidSnapOffsetIndex;
+        return scrollDestination;
+    }
+
+    if (scrollDestination <= snapOffsets.first())
+        return snapOffsets.first();
+
+    activeSnapIndex = snapOffsets.size() - 1;
+    if (scrollDestination >= snapOffsets.last())
+        return snapOffsets.last();
+
+    unsigned lowerIndex;
+    unsigned upperIndex;
+    indicesOfNearestSnapOffsets<LayoutType>(scrollDestination, snapOffsets, lowerIndex, upperIndex);
+    LayoutType lowerSnapPosition = snapOffsets[lowerIndex];
+    LayoutType upperSnapPosition = snapOffsets[upperIndex];
+    if (!std::abs(velocity)) {
+        bool isCloserToLowerSnapPosition = scrollDestination - lowerSnapPosition <= upperSnapPosition - scrollDestination;
+        activeSnapIndex = isCloserToLowerSnapPosition ? lowerIndex : upperIndex;
+        return isCloserToLowerSnapPosition ? lowerSnapPosition : upperSnapPosition;
+    }
+
+    // Non-zero velocity indicates a flick gesture. Even if another snap point is closer, we should choose the one in the direction of the flick gesture
+    // as long as a scroll snap offset range does not lie between the scroll destination and the targeted snap offset.
+    if (velocity < 0) {
+        if (lowerSnapOffsetRangeIndex != invalidSnapOffsetIndex && lowerSnapPosition < snapOffsetRanges[lowerSnapOffsetRangeIndex].end) {
+            activeSnapIndex = upperIndex;
+            return upperSnapPosition;
+        }
+        activeSnapIndex = lowerIndex;
+        return lowerSnapPosition;
+    }
+
+    if (upperSnapOffsetRangeIndex != invalidSnapOffsetIndex && snapOffsetRanges[upperSnapOffsetRangeIndex].start < upperSnapPosition) {
+        activeSnapIndex = lowerIndex;
+        return lowerSnapPosition;
+    }
+    activeSnapIndex = upperIndex;
+    return upperSnapPosition;
+}
+
+LayoutUnit closestSnapOffset(const Vector<LayoutUnit>& snapOffsets, const Vector<ScrollOffsetRange<LayoutUnit>>& snapOffsetRanges, LayoutUnit scrollDestination, float velocity, unsigned& activeSnapIndex)
+{
+    return closestSnapOffset<LayoutUnit>(snapOffsets, snapOffsetRanges, scrollDestination, velocity, activeSnapIndex);
+}
+
+float closestSnapOffset(const Vector<float>& snapOffsets, const Vector<ScrollOffsetRange<float>>& snapOffsetRanges, float scrollDestination, float velocity, unsigned& activeSnapIndex)
+{
+    return closestSnapOffset<float>(snapOffsets, snapOffsetRanges, scrollDestination, velocity, activeSnapIndex);
+}
+
+enum class InsetOrOutset {
+    Inset,
+    Outset
+};
+
+static LayoutRect computeScrollSnapPortOrAreaRect(const LayoutRect& rect, const LengthBox& insetOrOutsetBox, InsetOrOutset insetOrOutset)
+{
+    LayoutBoxExtent extents(valueForLength(insetOrOutsetBox.top(), rect.height()), valueForLength(insetOrOutsetBox.right(), rect.width()), valueForLength(insetOrOutsetBox.bottom(), rect.height()), valueForLength(insetOrOutsetBox.left(), rect.width()));
+    auto snapPortOrArea(rect);
+    if (insetOrOutset == InsetOrOutset::Inset)
+        snapPortOrArea.contract(extents);
+    else
+        snapPortOrArea.expand(extents);
+    return snapPortOrArea;
+}
+
+static LayoutUnit computeScrollSnapAlignOffset(LayoutUnit minLocation, LayoutUnit maxLocation, ScrollSnapAxisAlignType alignment, bool axisIsFlipped)
+{
+    switch (alignment) {
+    case ScrollSnapAxisAlignType::Start:
+        return axisIsFlipped ? maxLocation : minLocation;
+    case ScrollSnapAxisAlignType::Center:
+        return (minLocation + maxLocation) / 2;
+    case ScrollSnapAxisAlignType::End:
+        return axisIsFlipped ? minLocation : maxLocation;
+    default:
+        ASSERT_NOT_REACHED();
+        return 0;
+    }
+}
+
+template<typename T>
+TextStream& operator<<(TextStream& ts, const ScrollOffsetRange<T>& range)
+{
+    ts << "start: " << range.start << " end: " << range.end;
+    return ts;
+}
+
+static void computeAxisProximitySnapOffsetRanges(const Vector<LayoutUnit>& snapOffsets, Vector<ScrollOffsetRange<LayoutUnit>>& offsetRanges, LayoutUnit scrollPortAxisLength)
+{
+    // This is an arbitrary choice for what it means to be "in proximity" of a snap offset. We should play around with
+    // this and see what feels best.
+    static const float ratioOfScrollPortAxisLengthToBeConsideredForProximity = 0.3;
+    if (snapOffsets.size() < 2)
+        return;
+
+    // The extra rule accounting for scroll offset ranges in between the scroll destination and a potential snap offset
+    // handles the corner case where the user scrolls with momentum very lightly away from a snap offset, such that the
+    // predicted scroll destination is still within proximity of the snap offset. In this case, the regular (mandatory
+    // scroll snapping) behavior would be to snap to the next offset in the direction of momentum scrolling, but
+    // instead, it is more intuitive to either return to the original snap position (which we arbitrarily choose here)
+    // or scroll just outside of the snap offset range. This is another minor behavior tweak that we should play around
+    // with to see what feels best.
+    LayoutUnit proximityDistance { ratioOfScrollPortAxisLengthToBeConsideredForProximity * scrollPortAxisLength };
+    for (size_t index = 1; index < snapOffsets.size(); ++index) {
+        auto startOffset = snapOffsets[index - 1] + proximityDistance;
+        auto endOffset = snapOffsets[index] - proximityDistance;
+        if (startOffset < endOffset)
+            offsetRanges.append({ startOffset, endOffset });
+    }
+}
+
+void updateSnapOffsetsForScrollableArea(ScrollableArea& scrollableArea, const RenderBox& scrollingElementBox, const RenderStyle& scrollingElementStyle, LayoutRect viewportRectInBorderBoxCoordinates)
+{
+    auto scrollSnapType = scrollingElementStyle.scrollSnapType();
+    const auto& boxesWithScrollSnapPositions = scrollingElementBox.view().boxesWithScrollSnapPositions();
+    if (scrollSnapType.strictness == ScrollSnapStrictness::None || boxesWithScrollSnapPositions.isEmpty()) {
+        scrollableArea.clearSnapOffsets();
+        return;
+    }
+
+    Vector<LayoutUnit> verticalSnapOffsets;
+    Vector<LayoutUnit> horizontalSnapOffsets;
+    Vector<ScrollOffsetRange<LayoutUnit>> verticalSnapOffsetRanges;
+    Vector<ScrollOffsetRange<LayoutUnit>> horizontalSnapOffsetRanges;
+    HashSet<float> seenVerticalSnapOffsets;
+    HashSet<float> seenHorizontalSnapOffsets;
+    bool hasHorizontalSnapOffsets = scrollSnapType.axis == ScrollSnapAxis::Both || scrollSnapType.axis == ScrollSnapAxis::XAxis || scrollSnapType.axis == ScrollSnapAxis::Inline;
+    bool hasVerticalSnapOffsets = scrollSnapType.axis == ScrollSnapAxis::Both || scrollSnapType.axis == ScrollSnapAxis::YAxis || scrollSnapType.axis == ScrollSnapAxis::Block;
+
+    auto maxScrollOffset = scrollableArea.maximumScrollOffset();
+    auto scrollPosition = LayoutPoint { scrollableArea.scrollPosition() };
+    bool scrollerIsRTL = !scrollingElementBox.style().isLeftToRightDirection();
+
+    // The bounds of the scrolling container's snap port, where the top left of the scrolling container's border box is the origin.
+    auto scrollSnapPort = computeScrollSnapPortOrAreaRect(viewportRectInBorderBoxCoordinates, scrollingElementStyle.scrollPadding(), InsetOrOutset::Inset);
+    LOG_WITH_STREAM(ScrollSnap, stream << "Computing scroll snap offsets for " << scrollableArea << " in snap port " << scrollSnapPort);
+    for (auto* child : boxesWithScrollSnapPositions) {
+        if (child->enclosingScrollableContainerForSnapping() != &scrollingElementBox)
+            continue;
+
+        // The bounds of the child element's snap area, where the top left of the scrolling container's border box is the origin.
+        // The snap area is the bounding box of the child element's border box, after applying transformations.
+        // FIXME: For now, just consider whether the scroller is RTL. The behavior of LTR boxes inside a RTL scroller is poorly defined: https://github.com/w3c/csswg-drafts/issues/5361.
+        auto scrollSnapArea = LayoutRect(child->localToContainerQuad(FloatQuad(child->borderBoundingBox()), &scrollingElementBox).boundingBox());
+
+        // localToContainerQuad will transform the scroll snap area by the scroll position, except in the case that this position is
+        // coming from a ScrollView. We want the transformed area, but without scroll position taken into account.
+        if (!scrollableArea.isScrollView())
+            scrollSnapArea.moveBy(scrollPosition);
+
+        scrollSnapArea = computeScrollSnapPortOrAreaRect(scrollSnapArea, child->style().scrollMargin(), InsetOrOutset::Outset);
+        LOG_WITH_STREAM(ScrollSnap, stream << "    Considering scroll snap target area " << scrollSnapArea);
+        auto alignment = child->style().scrollSnapAlign();
+        if (hasHorizontalSnapOffsets && alignment.x != ScrollSnapAxisAlignType::None) {
+            auto absoluteScrollXPosition = computeScrollSnapAlignOffset(scrollSnapArea.x(), scrollSnapArea.maxX(), alignment.x, scrollerIsRTL) - computeScrollSnapAlignOffset(scrollSnapPort.x(), scrollSnapPort.maxX(), alignment.x, scrollerIsRTL);
+            auto absoluteScrollOffset = clampTo<int>(scrollableArea.scrollOffsetFromPosition({ roundToInt(absoluteScrollXPosition), 0 }).x(), 0, maxScrollOffset.x());
+            if (!seenHorizontalSnapOffsets.contains(absoluteScrollOffset)) {
+                seenHorizontalSnapOffsets.add(absoluteScrollOffset);
+                horizontalSnapOffsets.append(absoluteScrollOffset);
+            }
+        }
+        if (hasVerticalSnapOffsets && alignment.y != ScrollSnapAxisAlignType::None) {
+            auto absoluteScrollYPosition = computeScrollSnapAlignOffset(scrollSnapArea.y(), scrollSnapArea.maxY(), alignment.y, false) - computeScrollSnapAlignOffset(scrollSnapPort.y(), scrollSnapPort.maxY(), alignment.y, false);
+            auto absoluteScrollOffset = clampTo<int>(scrollableArea.scrollOffsetFromPosition({ 0, roundToInt(absoluteScrollYPosition) }).y(), 0, maxScrollOffset.y());
+            if (!seenVerticalSnapOffsets.contains(absoluteScrollOffset)) {
+                seenVerticalSnapOffsets.add(absoluteScrollOffset);
+                verticalSnapOffsets.append(absoluteScrollOffset);
+            }
+        }
+    }
+
+    if (!horizontalSnapOffsets.isEmpty()) {
+        std::sort(horizontalSnapOffsets.begin(), horizontalSnapOffsets.end());
+        if (scrollSnapType.strictness == ScrollSnapStrictness::Proximity)
+            computeAxisProximitySnapOffsetRanges(horizontalSnapOffsets, horizontalSnapOffsetRanges, scrollSnapPort.width());
+
+        LOG_WITH_STREAM(ScrollSnap, stream << " => Computed horizontal scroll snap offsets: " << horizontalSnapOffsets);
+        LOG_WITH_STREAM(ScrollSnap, stream << " => Computed horizontal scroll snap offset ranges: " << horizontalSnapOffsetRanges);
+
+        scrollableArea.setHorizontalSnapOffsets(horizontalSnapOffsets);
+        scrollableArea.setHorizontalSnapOffsetRanges(horizontalSnapOffsetRanges);
+    } else
+        scrollableArea.clearHorizontalSnapOffsets();
+
+    if (!verticalSnapOffsets.isEmpty()) {
+        std::sort(verticalSnapOffsets.begin(), verticalSnapOffsets.end());
+        if (scrollSnapType.strictness == ScrollSnapStrictness::Proximity)
+            computeAxisProximitySnapOffsetRanges(verticalSnapOffsets, verticalSnapOffsetRanges, scrollSnapPort.height());
+
+        LOG_WITH_STREAM(ScrollSnap, stream << " => Computed vertical scroll snap offsets: " << verticalSnapOffsets);
+        LOG_WITH_STREAM(ScrollSnap, stream << " => Computed vertical scroll snap offset ranges: " << verticalSnapOffsetRanges);
+
+        scrollableArea.setVerticalSnapOffsets(verticalSnapOffsets);
+        scrollableArea.setVerticalSnapOffsetRanges(verticalSnapOffsetRanges);
+    } else
+        scrollableArea.clearVerticalSnapOffsets();
+}
+
+}
+
+#endif // ENABLE(CSS_SCROLL_SNAP)

Modified: trunk/Source/WebCore/page/scrolling/ScrollSnapOffsetsInfo.h (270389 => 270390)


--- trunk/Source/WebCore/page/scrolling/ScrollSnapOffsetsInfo.h	2020-12-03 07:58:44 UTC (rev 270389)
+++ trunk/Source/WebCore/page/scrolling/ScrollSnapOffsetsInfo.h	2020-12-03 09:50:39 UTC (rev 270390)
@@ -25,10 +25,19 @@
 
 #pragma once
 
+#if ENABLE(CSS_SCROLL_SNAP)
+
+#include "LayoutUnit.h"
+#include "StyleScrollSnapPoints.h"
 #include <wtf/Vector.h>
 
 namespace WebCore {
 
+class LayoutRect;
+class ScrollableArea;
+class RenderBox;
+class RenderStyle;
+
 template <typename T>
 struct ScrollOffsetRange {
     T start;
@@ -49,4 +58,16 @@
     Vector<ScrollOffsetRange<T>> verticalSnapOffsetRanges;
 };
 
+const unsigned invalidSnapOffsetIndex = UINT_MAX;
+
+// Update the snap offsets for this scrollable area, given the RenderBox of the scroll container, the RenderStyle
+// which defines the scroll-snap properties, and the viewport rectangle with the origin at the top left of
+// the scrolling container's border box.
+void updateSnapOffsetsForScrollableArea(ScrollableArea&, const RenderBox& scrollingElementBox, const RenderStyle& scrollingElementStyle, LayoutRect viewportRectInBorderBoxCoordinates);
+
+WEBCORE_EXPORT LayoutUnit closestSnapOffset(const Vector<LayoutUnit>& snapOffsets, const Vector<ScrollOffsetRange<LayoutUnit>>& snapOffsetRanges, LayoutUnit scrollDestination, float velocity, unsigned& activeSnapIndex);
+WEBCORE_EXPORT float closestSnapOffset(const Vector<float>& snapOffsets, const Vector<ScrollOffsetRange<float>>& snapOffsetRanges, float scrollDestination, float velocity, unsigned& activeSnapIndex);
+
 }; // namespace WebCore
+
+#endif // ENABLE(CSS_SCROLL_SNAP)

Modified: trunk/Source/WebCore/page/scrolling/ScrollingCoordinator.h (270389 => 270390)


--- trunk/Source/WebCore/page/scrolling/ScrollingCoordinator.h	2020-12-03 07:58:44 UTC (rev 270389)
+++ trunk/Source/WebCore/page/scrolling/ScrollingCoordinator.h	2020-12-03 09:50:39 UTC (rev 270390)
@@ -42,10 +42,6 @@
 #include <wtf/Threading.h>
 #endif
 
-#if ENABLE(CSS_SCROLL_SNAP)
-#include "AxisScrollSnapOffsets.h"
-#endif
-
 namespace WTF {
 class TextStream;
 }

Modified: trunk/Source/WebCore/page/scrolling/ScrollingMomentumCalculator.h (270389 => 270390)


--- trunk/Source/WebCore/page/scrolling/ScrollingMomentumCalculator.h	2020-12-03 07:58:44 UTC (rev 270389)
+++ trunk/Source/WebCore/page/scrolling/ScrollingMomentumCalculator.h	2020-12-03 09:50:39 UTC (rev 270390)
@@ -27,7 +27,6 @@
 
 #if ENABLE(CSS_SCROLL_SNAP)
 
-#include "AxisScrollSnapOffsets.h"
 #include "PlatformWheelEvent.h"
 #include "ScrollTypes.h"
 #include <wtf/Optional.h>

Modified: trunk/Source/WebCore/platform/ScrollableArea.h (270389 => 270390)


--- trunk/Source/WebCore/platform/ScrollableArea.h	2020-12-03 07:58:44 UTC (rev 270389)
+++ trunk/Source/WebCore/platform/ScrollableArea.h	2020-12-03 09:50:39 UTC (rev 270390)
@@ -385,11 +385,11 @@
     // This function should be overridden by subclasses to perform the actual
     // scroll of the content.
     virtual void setScrollOffset(const ScrollOffset&) = 0;
-    ScrollSnapOffsetsInfo<LayoutUnit>& ensureSnapOffsetsInfo();
 
     mutable std::unique_ptr<ScrollAnimator> m_scrollAnimator;
 
 #if ENABLE(CSS_SCROLL_SNAP)
+    ScrollSnapOffsetsInfo<LayoutUnit>& ensureSnapOffsetsInfo();
     std::unique_ptr<ScrollSnapOffsetsInfo<LayoutUnit>> m_snapOffsetsInfo;
     unsigned m_currentHorizontalSnapPointIndex { 0 };
     unsigned m_currentVerticalSnapPointIndex { 0 };

Modified: trunk/Source/WebCore/platform/cocoa/ScrollSnapAnimatorState.h (270389 => 270390)


--- trunk/Source/WebCore/platform/cocoa/ScrollSnapAnimatorState.h	2020-12-03 07:58:44 UTC (rev 270389)
+++ trunk/Source/WebCore/platform/cocoa/ScrollSnapAnimatorState.h	2020-12-03 09:50:39 UTC (rev 270390)
@@ -27,7 +27,6 @@
 
 #if ENABLE(CSS_SCROLL_SNAP)
 
-#include "AxisScrollSnapOffsets.h"
 #include "FloatPoint.h"
 #include "FloatSize.h"
 #include "LayoutPoint.h"

Modified: trunk/Source/WebCore/rendering/RenderLayer.cpp (270389 => 270390)


--- trunk/Source/WebCore/rendering/RenderLayer.cpp	2020-12-03 07:58:44 UTC (rev 270389)
+++ trunk/Source/WebCore/rendering/RenderLayer.cpp	2020-12-03 09:50:39 UTC (rev 270390)
@@ -117,6 +117,7 @@
 #include "ScaleTransformOperation.h"
 #include "ScriptDisallowedScope.h"
 #include "ScrollAnimator.h"
+#include "ScrollSnapOffsetsInfo.h"
 #include "Scrollbar.h"
 #include "ScrollbarTheme.h"
 #include "ScrollingCoordinator.h"
@@ -135,10 +136,6 @@
 #include <wtf/text/CString.h>
 #include <wtf/text/TextStream.h>
 
-#if ENABLE(CSS_SCROLL_SNAP)
-#include "AxisScrollSnapOffsets.h"
-#endif
-
 #define MIN_INTERSECT_FOR_REVEAL 32
 
 namespace WebCore {

Modified: trunk/Source/WebKit/ChangeLog (270389 => 270390)


--- trunk/Source/WebKit/ChangeLog	2020-12-03 07:58:44 UTC (rev 270389)
+++ trunk/Source/WebKit/ChangeLog	2020-12-03 09:50:39 UTC (rev 270390)
@@ -1,3 +1,13 @@
+2020-12-03  Martin Robinson  <[email protected]>
+
+        Move code from AxisScrollSnapOffsets to ScrollSnapOffsetsInfo
+        https://bugs.webkit.org/show_bug.cgi?id=219345
+
+        Reviewed by Daniel Bates.
+
+        * UIProcess/RemoteLayerTree/ios/RemoteScrollingCoordinatorProxyIOS.mm: Remove AxisScrollSnapOffsets.h include.
+        * UIProcess/RemoteLayerTree/ios/ScrollingTreeScrollingNodeDelegateIOS.mm: Ditto.
+
 2020-12-02  Tim Horton  <[email protected]>
 
         Many different assertion failures on the GPU process bot after r270366

Modified: trunk/Source/WebKit/UIProcess/RemoteLayerTree/ios/RemoteScrollingCoordinatorProxyIOS.mm (270389 => 270390)


--- trunk/Source/WebKit/UIProcess/RemoteLayerTree/ios/RemoteScrollingCoordinatorProxyIOS.mm	2020-12-03 07:58:44 UTC (rev 270389)
+++ trunk/Source/WebKit/UIProcess/RemoteLayerTree/ios/RemoteScrollingCoordinatorProxyIOS.mm	2020-12-03 09:50:39 UTC (rev 270390)
@@ -41,7 +41,6 @@
 #import <WebCore/ScrollingStateTree.h>
 
 #if ENABLE(CSS_SCROLL_SNAP)
-#import <WebCore/AxisScrollSnapOffsets.h>
 #import <WebCore/ScrollSnapOffsetsInfo.h>
 #import <WebCore/ScrollTypes.h>
 #import <WebCore/ScrollingTreeFrameScrollingNode.h>

Modified: trunk/Source/WebKit/UIProcess/RemoteLayerTree/ios/ScrollingTreeScrollingNodeDelegateIOS.mm (270389 => 270390)


--- trunk/Source/WebKit/UIProcess/RemoteLayerTree/ios/ScrollingTreeScrollingNodeDelegateIOS.mm	2020-12-03 07:58:44 UTC (rev 270389)
+++ trunk/Source/WebKit/UIProcess/RemoteLayerTree/ios/ScrollingTreeScrollingNodeDelegateIOS.mm	2020-12-03 09:50:39 UTC (rev 270390)
@@ -45,7 +45,6 @@
 #import <wtf/SetForScope.h>
 
 #if ENABLE(CSS_SCROLL_SNAP)
-#import <WebCore/AxisScrollSnapOffsets.h>
 #import <WebCore/ScrollSnapOffsetsInfo.h>
 #endif
 
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to