Title: [277083] trunk/Source
Revision
277083
Author
[email protected]
Date
2021-05-06 05:11:15 -0700 (Thu, 06 May 2021)

Log Message

[css-scroll-snap] Compute proximity information while snapping
https://bugs.webkit.org/show_bug.cgi?id=224326

Reviewed by Simon Fraser.

Source/WebCore:

Have ScrollSnapOffsetsInfo carry snap area rectangles instead of scroll offset
ranges. This allows proximity information to be handled during snap point selection.
The geometry will be used in a future patch to follow spec behavior for snap
areas that overflow the snapport and when handling masonry layouts.

No new tests. This is just a refactor. It should not change behavior at all.

* page/scrolling/AsyncScrollingCoordinator.cpp:
(WebCore::setStateScrollingNodeSnapOffsetsAsFloat): Pass in the new template argument.
* page/scrolling/ScrollSnapOffsetsInfo.cpp:
(WebCore::isNearEnoughToOffsetForProximity): Added.
(WebCore::closestSnapOffsetWithInfoAndAxis): Modified to take in the ScrollSnapOffsetsInfo data
structure and axis along with the viewport size. This function now explicitly determines if a
snap point is too far away to affect scrolling due to scroll-snap proximity.
(WebCore::updateSnapOffsetsForScrollableArea): Add snap areas and snap area indices to SnapOffset.
(WebCore::convertOffsetInfo): Instead of converting scroll offset ranges, convert the snap
area rectangles.
(WebCore::FloatScrollSnapOffsetsInfo::convertUnits const): Ditto.
(WebCore::LayoutScrollSnapOffsetsInfo::convertUnits const): Ditto.
(WebCore::LayoutScrollSnapOffsetsInfo::closestSnapOffset const): Updated to reflect new
internal function.
(WebCore::FloatScrollSnapOffsetsInfo::closestSnapOffset const): Ditto.
* page/scrolling/ScrollSnapOffsetsInfo.h:
(WebCore::ScrollSnapOffsetsInfo::isEqual const): Update to reflect new mem ers.
(WebCore::ScrollSnapOffsetsInfo::offsetsForAxis const): Changed template parameter name.
* page/scrolling/mac/ScrollingTreeScrollingNodeDelegateMac.mm:
(WebCore::ScrollingTreeScrollingNodeDelegateMac::updateFromStateNode): ::convertUnits
takes a new template parameter.
* page/scrolling/nicosia/ScrollingTreeScrollingNodeDelegateNicosia.cpp:
(WebCore::ScrollingTreeScrollingNodeDelegateNicosia::handleWheelEvent): Pass in viewport size.
* platform/ScrollController.cpp:
(WebCore::ScrollController::setNearestScrollSnapIndexForAxisAndOffset): Ditto.
(WebCore::ScrollController::adjustScrollDestination): Ditto.
* platform/ScrollSnapAnimatorState.cpp:
(WebCore::ScrollSnapAnimatorState::setupAnimationForState): Ditto.
(WebCore::ScrollSnapAnimatorState::targetOffsetForStartOffset const): Ditto.
(WebCore::operator<<): No longer print snap offset ranges.
* platform/ScrollSnapAnimatorState.h: Remove references to snap offset ranges.

Source/WebKit:

* Shared/RemoteLayerTree/RemoteScrollingCoordinatorTransaction.cpp:
(ArgumentCoder<SnapOffset<float>>::encode): Add the snap area index to the encoded arguments.
(ArgumentCoder<SnapOffset<float>>::decode): Add the snap area index to the decoded arguments.
(ArgumentCoder<FloatScrollSnapOffsetsInfo>::encode): No longer encode ranges, but encode snap areas.
(ArgumentCoder<FloatScrollSnapOffsetsInfo>::decode): Ditto for decode.
* Shared/WebCoreArgumentCoders.cpp: Remove code dealing with scroll offset ranges.
* Shared/WebCoreArgumentCoders.h: Ditto.
* UIProcess/RemoteLayerTree/ios/RemoteScrollingCoordinatorProxyIOS.mm:
(WebKit::RemoteScrollingCoordinatorProxy::closestSnapOffsetForMainFrameScrolling const): Pass
in viewport size to closestSnapOffset which is necessary for calculating proximity.
* UIProcess/RemoteLayerTree/ios/ScrollingTreeScrollingNodeDelegateIOS.mm:
(-[WKScrollingNodeScrollViewDelegate scrollViewWillEndDragging:withVelocity:targetContentOffset:]): Ditto.

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (277082 => 277083)


--- trunk/Source/WebCore/ChangeLog	2021-05-06 12:07:56 UTC (rev 277082)
+++ trunk/Source/WebCore/ChangeLog	2021-05-06 12:11:15 UTC (rev 277083)
@@ -1,3 +1,49 @@
+2021-05-06  Martin Robinson  <[email protected]>
+
+        [css-scroll-snap] Compute proximity information while snapping
+        https://bugs.webkit.org/show_bug.cgi?id=224326
+
+        Reviewed by Simon Fraser.
+
+        Have ScrollSnapOffsetsInfo carry snap area rectangles instead of scroll offset
+        ranges. This allows proximity information to be handled during snap point selection.
+        The geometry will be used in a future patch to follow spec behavior for snap
+        areas that overflow the snapport and when handling masonry layouts.
+
+        No new tests. This is just a refactor. It should not change behavior at all.
+
+        * page/scrolling/AsyncScrollingCoordinator.cpp:
+        (WebCore::setStateScrollingNodeSnapOffsetsAsFloat): Pass in the new template argument.
+        * page/scrolling/ScrollSnapOffsetsInfo.cpp:
+        (WebCore::isNearEnoughToOffsetForProximity): Added.
+        (WebCore::closestSnapOffsetWithInfoAndAxis): Modified to take in the ScrollSnapOffsetsInfo data
+        structure and axis along with the viewport size. This function now explicitly determines if a
+        snap point is too far away to affect scrolling due to scroll-snap proximity.
+        (WebCore::updateSnapOffsetsForScrollableArea): Add snap areas and snap area indices to SnapOffset.
+        (WebCore::convertOffsetInfo): Instead of converting scroll offset ranges, convert the snap
+        area rectangles.
+        (WebCore::FloatScrollSnapOffsetsInfo::convertUnits const): Ditto.
+        (WebCore::LayoutScrollSnapOffsetsInfo::convertUnits const): Ditto.
+        (WebCore::LayoutScrollSnapOffsetsInfo::closestSnapOffset const): Updated to reflect new
+        internal function.
+        (WebCore::FloatScrollSnapOffsetsInfo::closestSnapOffset const): Ditto.
+        * page/scrolling/ScrollSnapOffsetsInfo.h:
+        (WebCore::ScrollSnapOffsetsInfo::isEqual const): Update to reflect new mem ers.
+        (WebCore::ScrollSnapOffsetsInfo::offsetsForAxis const): Changed template parameter name.
+        * page/scrolling/mac/ScrollingTreeScrollingNodeDelegateMac.mm:
+        (WebCore::ScrollingTreeScrollingNodeDelegateMac::updateFromStateNode): ::convertUnits
+        takes a new template parameter.
+        * page/scrolling/nicosia/ScrollingTreeScrollingNodeDelegateNicosia.cpp:
+        (WebCore::ScrollingTreeScrollingNodeDelegateNicosia::handleWheelEvent): Pass in viewport size.
+        * platform/ScrollController.cpp:
+        (WebCore::ScrollController::setNearestScrollSnapIndexForAxisAndOffset): Ditto.
+        (WebCore::ScrollController::adjustScrollDestination): Ditto.
+        * platform/ScrollSnapAnimatorState.cpp:
+        (WebCore::ScrollSnapAnimatorState::setupAnimationForState): Ditto.
+        (WebCore::ScrollSnapAnimatorState::targetOffsetForStartOffset const): Ditto.
+        (WebCore::operator<<): No longer print snap offset ranges.
+        * platform/ScrollSnapAnimatorState.h: Remove references to snap offset ranges.
+
 2021-05-06  Philippe Normand  <[email protected]>
 
         REGRESSION(r271341): media/media-fullscreen-inline.html times out on GTK

Modified: trunk/Source/WebCore/page/scrolling/AsyncScrollingCoordinator.cpp (277082 => 277083)


--- trunk/Source/WebCore/page/scrolling/AsyncScrollingCoordinator.cpp	2021-05-06 12:07:56 UTC (rev 277082)
+++ trunk/Source/WebCore/page/scrolling/AsyncScrollingCoordinator.cpp	2021-05-06 12:11:15 UTC (rev 277083)
@@ -105,7 +105,7 @@
     }
 
     // FIXME: Incorporate current page scale factor in snapping to device pixel. Perhaps we should just convert to float here and let UI process do the pixel snapping?
-    node.setSnapOffsetsInfo(offsetInfo->convertUnits<float>(deviceScaleFactor));
+    node.setSnapOffsetsInfo(offsetInfo->convertUnits<FloatScrollSnapOffsetsInfo>(deviceScaleFactor));
 }
 #endif
 

Modified: trunk/Source/WebCore/page/scrolling/ScrollSnapOffsetsInfo.cpp (277082 => 277083)


--- trunk/Source/WebCore/page/scrolling/ScrollSnapOffsetsInfo.cpp	2021-05-06 12:07:56 UTC (rev 277082)
+++ trunk/Source/WebCore/page/scrolling/ScrollSnapOffsetsInfo.cpp	2021-05-06 12:11:15 UTC (rev 277083)
@@ -42,41 +42,16 @@
 
 namespace WebCore {
 
-template <typename LayoutType>
-static void indicesOfNearestSnapOffsetRanges(LayoutType offset, const Vector<ScrollOffsetRange<LayoutType>>& snapOffsetRanges, unsigned& lowerIndex, unsigned& upperIndex)
+template <typename UnitType>
+static bool isNearEnoughToOffsetForProximity(ScrollSnapStrictness strictness, UnitType scrollDestination, UnitType candidateSnapOffset, UnitType viewportLength)
 {
-    if (snapOffsetRanges.isEmpty()) {
-        lowerIndex = invalidSnapOffsetIndex;
-        upperIndex = invalidSnapOffsetIndex;
-        return;
-    }
+    if (strictness != ScrollSnapStrictness::Proximity)
+        return true;
 
-    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;
+    // 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;
+    return std::abs(float {candidateSnapOffset - scrollDestination}) <= (viewportLength * ratioOfScrollPortAxisLengthToBeConsideredForProximity);
 }
 
 template <typename LayoutType>
@@ -131,9 +106,10 @@
     return WTF::nullopt;
 }
 
-template <typename LayoutType>
-static std::pair<LayoutType, unsigned> closestSnapOffsetWithOffsetsAndRanges(const Vector<SnapOffset<LayoutType>>& snapOffsets, const Vector<ScrollOffsetRange<LayoutType>>& snapOffsetRanges, LayoutType scrollDestinationOffset, float velocity, Optional<LayoutType> originalOffsetForDirectionalSnapping)
+template <typename InfoType, typename SizeType, typename LayoutType>
+static std::pair<LayoutType, unsigned> closestSnapOffsetWithInfoAndAxis(const InfoType& info, ScrollEventAxis axis, const SizeType& viewportSize, LayoutType scrollDestinationOffset, float velocity, Optional<LayoutType> originalOffsetForDirectionalSnapping)
 {
+    const auto& snapOffsets = info.offsetsForAxis(axis);
     if (snapOffsets.isEmpty())
         return std::make_pair(scrollDestinationOffset, invalidSnapOffsetIndex);
 
@@ -143,12 +119,6 @@
             return std::make_pair(snapOffsets[*firstSnapStopOffsetIndex].offset, *firstSnapStopOffsetIndex);
     }
 
-    unsigned lowerSnapOffsetRangeIndex;
-    unsigned upperSnapOffsetRangeIndex;
-    indicesOfNearestSnapOffsetRanges<LayoutType>(scrollDestinationOffset, snapOffsetRanges, lowerSnapOffsetRangeIndex, upperSnapOffsetRangeIndex);
-    if (lowerSnapOffsetRangeIndex == upperSnapOffsetRangeIndex && upperSnapOffsetRangeIndex != invalidSnapOffsetIndex)
-        return std::make_pair(scrollDestinationOffset, invalidSnapOffsetIndex);
-
     if (scrollDestinationOffset <= snapOffsets.first().offset)
         return std::make_pair(snapOffsets.first().offset, 0u);
 
@@ -160,28 +130,36 @@
     indicesOfNearestSnapOffsets<LayoutType>(scrollDestinationOffset, snapOffsets, lowerIndex, upperIndex);
     LayoutType lowerSnapPosition = snapOffsets[lowerIndex].offset;
     LayoutType upperSnapPosition = snapOffsets[upperIndex].offset;
+
+    auto viewportLength = axis == ScrollEventAxis::Horizontal ? viewportSize.width() : viewportSize.height();
+    if (!isNearEnoughToOffsetForProximity<LayoutType>(info.strictness, scrollDestinationOffset, lowerSnapPosition, viewportLength)) {
+        lowerSnapPosition = scrollDestinationOffset;
+        lowerIndex = invalidSnapOffsetIndex;
+    }
+
+    if (!isNearEnoughToOffsetForProximity<LayoutType>(info.strictness, scrollDestinationOffset, upperSnapPosition, viewportLength)) {
+        upperSnapPosition = scrollDestinationOffset;
+        upperIndex = invalidSnapOffsetIndex;
+    }
     if (!std::abs(velocity)) {
-        bool isCloserToLowerSnapPosition = scrollDestinationOffset - lowerSnapPosition <= upperSnapPosition - scrollDestinationOffset;
+        bool isCloserToLowerSnapPosition = (upperIndex == invalidSnapOffsetIndex)
+            || (lowerIndex != invalidSnapOffsetIndex && scrollDestinationOffset - lowerSnapPosition <= upperSnapPosition - scrollDestinationOffset);
         return isCloserToLowerSnapPosition ? std::make_pair(lowerSnapPosition, lowerIndex) : std::make_pair(upperSnapPosition, upperIndex);
     }
 
     // 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 we are doing directional
+    // as long as a scroll snap offset is close enough for proximity (or we aren't using proximity). If we are doing directional
     // snapping, we should never snap to a point that was on the other side of the original position in the opposite direction of this scroll.
     // This allows directional scrolling to escape snap points.
-    if (velocity < 0) {
-        if (lowerSnapOffsetRangeIndex == invalidSnapOffsetIndex || lowerSnapPosition >= snapOffsetRanges[lowerSnapOffsetRangeIndex].end)
-            return std::make_pair(lowerSnapPosition, lowerIndex);
-        if (!originalOffsetForDirectionalSnapping.hasValue() || *originalOffsetForDirectionalSnapping > upperSnapPosition)
+    if (velocity < 0)  {
+        if (upperIndex != invalidSnapOffsetIndex && (!originalOffsetForDirectionalSnapping || *originalOffsetForDirectionalSnapping > upperSnapPosition))
             return std::make_pair(upperSnapPosition, upperIndex);
-    } else {
-        if (upperSnapOffsetRangeIndex == invalidSnapOffsetIndex || snapOffsetRanges[upperSnapOffsetRangeIndex].start >= upperSnapPosition)
-            return std::make_pair(upperSnapPosition, upperIndex);
-        if (!originalOffsetForDirectionalSnapping.hasValue() || *originalOffsetForDirectionalSnapping < lowerSnapPosition)
-            return std::make_pair(lowerSnapPosition, lowerIndex);
+        return std::make_pair(lowerSnapPosition, lowerIndex);
     }
 
-    return std::make_pair(scrollDestinationOffset, invalidSnapOffsetIndex);
+    if (lowerIndex != invalidSnapOffsetIndex && (!originalOffsetForDirectionalSnapping || *originalOffsetForDirectionalSnapping < lowerSnapPosition))
+        return std::make_pair(lowerSnapPosition, lowerIndex);
+    return std::make_pair(upperSnapPosition, upperIndex);
 }
 
 enum class InsetOrOutset {
@@ -220,30 +198,6 @@
     }
 }
 
-static void computeAxisProximitySnapOffsetRanges(const Vector<SnapOffset<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].offset + proximityDistance;
-        auto endOffset = snapOffsets[index].offset - proximityDistance;
-        if (startOffset < endOffset)
-            offsetRanges.append({ startOffset, endOffset });
-    }
-}
-
 void updateSnapOffsetsForScrollableArea(ScrollableArea& scrollableArea, const RenderBox& scrollingElementBox, const RenderStyle& scrollingElementStyle, LayoutRect viewportRectInBorderBoxCoordinates)
 {
     auto scrollSnapType = scrollingElementStyle.scrollSnapType();
@@ -263,6 +217,7 @@
 
     HashMap<float, SnapOffset<LayoutUnit>> verticalSnapOffsetsMap;
     HashMap<float, SnapOffset<LayoutUnit>> horizontalSnapOffsetsMap;
+    Vector<LayoutRect> snapAreas;
     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;
 
@@ -291,16 +246,30 @@
         LOG_WITH_STREAM(ScrollSnap, stream << "    Considering scroll snap target area " << scrollSnapArea);
         auto alignment = child->style().scrollSnapAlign();
         auto stop = child->style().scrollSnapStop();
-        if (hasHorizontalSnapOffsets && alignment.x != ScrollSnapAxisAlignType::None) {
+
+        bool snapsHorizontally = hasHorizontalSnapOffsets && alignment.x != ScrollSnapAxisAlignType::None;
+        bool snapsVertically = hasVerticalSnapOffsets && alignment.y != ScrollSnapAxisAlignType::None;
+        if (!snapsHorizontally && !snapsVertically)
+            continue;
+
+        // The scroll snap area is defined via its scroll position, so convert the snap area rectangle to be relative to scroll offsets.
+        auto snapAreaOriginRelativeToBorderEdge = scrollSnapArea.location() - scrollSnapPort.location();
+        LayoutRect scrollSnapAreaAsOffsets(scrollableArea.scrollOffsetFromPosition(roundedIntPoint(snapAreaOriginRelativeToBorderEdge)), scrollSnapArea.size());
+        snapAreas.append(scrollSnapAreaAsOffsets);
+
+        if (snapsHorizontally) {
             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());
-            addOrUpdateStopForSnapOffset(horizontalSnapOffsetsMap, { absoluteScrollOffset, stop });
+            addOrUpdateStopForSnapOffset(horizontalSnapOffsetsMap, { absoluteScrollOffset, stop, snapAreas.size() - 1 });
         }
-        if (hasVerticalSnapOffsets && alignment.y != ScrollSnapAxisAlignType::None) {
+        if (snapsVertically) {
             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());
-            addOrUpdateStopForSnapOffset(verticalSnapOffsetsMap, { absoluteScrollOffset, stop });
+            addOrUpdateStopForSnapOffset(verticalSnapOffsetsMap, { absoluteScrollOffset, stop, snapAreas.size() - 1 });
         }
+
+        if (!snapAreas.isEmpty())
+            LOG_WITH_STREAM(ScrollSnap, stream << " => Computed snap areas: " << snapAreas);
     }
 
     auto compareSnapOffsets = [](const SnapOffset<LayoutUnit>& a, const SnapOffset<LayoutUnit>& b)
@@ -309,32 +278,22 @@
     };
 
     Vector<SnapOffset<LayoutUnit>> horizontalSnapOffsets = copyToVector(horizontalSnapOffsetsMap.values());
-    Vector<ScrollOffsetRange<LayoutUnit>> horizontalSnapOffsetRanges;
     if (!horizontalSnapOffsets.isEmpty()) {
         std::sort(horizontalSnapOffsets.begin(), horizontalSnapOffsets.end(), compareSnapOffsets);
-        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);
     }
 
     Vector<SnapOffset<LayoutUnit>> verticalSnapOffsets = copyToVector(verticalSnapOffsetsMap.values());
-    Vector<ScrollOffsetRange<LayoutUnit>> verticalSnapOffsetRanges;
     if (!verticalSnapOffsets.isEmpty()) {
         std::sort(verticalSnapOffsets.begin(), verticalSnapOffsets.end(), compareSnapOffsets);
-        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.setScrollSnapOffsetInfo({
+        scrollSnapType.strictness,
         horizontalSnapOffsets,
         verticalSnapOffsets,
-        horizontalSnapOffsetRanges,
-        verticalSnapOffsetRanges
+        snapAreas
     });
 }
 
@@ -348,8 +307,8 @@
     return LayoutUnit(input);
 }
 
-template <typename InputType, typename OutputType>
-static ScrollSnapOffsetsInfo<OutputType> convertOffsetInfo(const ScrollSnapOffsetsInfo<InputType>& input, float scaleFactor = 0.0)
+template <typename InputType, typename InputRectType, typename OutputType, typename OutputRectType>
+static ScrollSnapOffsetsInfo<OutputType, OutputRectType> convertOffsetInfo(const ScrollSnapOffsetsInfo<InputType, InputRectType>& input, float scaleFactor = 0.0)
 {
     auto convertOffsets = [scaleFactor](const Vector<SnapOffset<InputType>>& input)
     {
@@ -356,24 +315,29 @@
         Vector<SnapOffset<OutputType>> output;
         output.reserveInitialCapacity(input.size());
         for (auto& offset : input)
-            output.uncheckedAppend({ convertOffsetUnit(offset.offset, scaleFactor), offset.stop });
+            output.uncheckedAppend({ convertOffsetUnit(offset.offset, scaleFactor), offset.stop, offset.snapAreaIndex });
         return output;
     };
 
-    auto convertOffsetRanges = [scaleFactor](const Vector<ScrollOffsetRange<InputType>>& input)
+    auto convertRects = [scaleFactor](const Vector<InputRectType>& input)
     {
-        Vector<ScrollOffsetRange<OutputType>> output;
+        Vector<OutputRectType> output;
         output.reserveInitialCapacity(input.size());
-        for (auto& range : input)
-            output.uncheckedAppend({ convertOffsetUnit(range.start, scaleFactor), convertOffsetUnit(range.end, scaleFactor) });
+        for (auto& rect : input) {
+            OutputRectType outputRect(
+                convertOffsetUnit(rect.x(), scaleFactor), convertOffsetUnit(rect.y(), scaleFactor),
+                convertOffsetUnit(rect.width(), scaleFactor), convertOffsetUnit(rect.height(), scaleFactor));
+            output.uncheckedAppend(outputRect);
+        }
+
         return output;
     };
 
     return {
+        input.strictness,
         convertOffsets(input.horizontalSnapOffsets),
         convertOffsets(input.verticalSnapOffsets),
-        convertOffsetRanges(input.horizontalSnapOffsetRanges),
-        convertOffsetRanges(input.verticalSnapOffsetRanges)
+        convertRects(input.snapAreas),
     };
 }
 
@@ -380,25 +344,27 @@
 template <> template <>
 LayoutScrollSnapOffsetsInfo FloatScrollSnapOffsetsInfo::convertUnits(float /* unusedScaleFactor */) const
 {
-    return convertOffsetInfo<float, LayoutUnit>(*this);
+    return convertOffsetInfo<float, FloatRect, LayoutUnit, LayoutRect>(*this);
+
 }
 
 template <> template <>
 FloatScrollSnapOffsetsInfo LayoutScrollSnapOffsetsInfo::convertUnits(float deviceScaleFactor) const
 {
-    return convertOffsetInfo<LayoutUnit, float>(*this, deviceScaleFactor);
+    return convertOffsetInfo<LayoutUnit, LayoutRect, float, FloatRect>(*this, deviceScaleFactor);
+
 }
 
-template <>
-std::pair<LayoutUnit, unsigned> LayoutScrollSnapOffsetsInfo::closestSnapOffset(ScrollEventAxis axis, LayoutUnit scrollDestinationOffset, float velocity, Optional<LayoutUnit> originalPositionForDirectionalSnapping) const
+template <> template <>
+std::pair<LayoutUnit, unsigned> LayoutScrollSnapOffsetsInfo::closestSnapOffset(ScrollEventAxis axis, const LayoutSize& viewportSize, LayoutUnit scrollDestinationOffset, float velocity, Optional<LayoutUnit> originalPositionForDirectionalSnapping) const
 {
-    return closestSnapOffsetWithOffsetsAndRanges(offsetsForAxis(axis), offsetRangesForAxis(axis), scrollDestinationOffset, velocity, originalPositionForDirectionalSnapping);
+    return closestSnapOffsetWithInfoAndAxis(*this, axis, viewportSize, scrollDestinationOffset, velocity, originalPositionForDirectionalSnapping);
 }
 
-template <>
-std::pair<float, unsigned> FloatScrollSnapOffsetsInfo::closestSnapOffset(ScrollEventAxis axis, float scrollDestinationOffset, float velocity, Optional<float> originalPositionForDirectionalSnapping) const
+template <> template<>
+std::pair<float, unsigned> FloatScrollSnapOffsetsInfo::closestSnapOffset(ScrollEventAxis axis, const FloatSize& viewportSize, float scrollDestinationOffset, float velocity, Optional<float> originalPositionForDirectionalSnapping) const
 {
-    return closestSnapOffsetWithOffsetsAndRanges(offsetsForAxis(axis), offsetRangesForAxis(axis), scrollDestinationOffset, velocity, originalPositionForDirectionalSnapping);
+    return closestSnapOffsetWithInfoAndAxis(*this, axis, viewportSize, scrollDestinationOffset, velocity, originalPositionForDirectionalSnapping);
 }
 
 }

Modified: trunk/Source/WebCore/page/scrolling/ScrollSnapOffsetsInfo.h (277082 => 277083)


--- trunk/Source/WebCore/page/scrolling/ScrollSnapOffsetsInfo.h	2021-05-06 12:07:56 UTC (rev 277082)
+++ trunk/Source/WebCore/page/scrolling/ScrollSnapOffsetsInfo.h	2021-05-06 12:11:15 UTC (rev 277083)
@@ -27,6 +27,8 @@
 
 #if ENABLE(CSS_SCROLL_SNAP)
 
+#include "FloatRect.h"
+#include "LayoutRect.h"
 #include "LayoutUnit.h"
 #include "ScrollTypes.h"
 #include "StyleScrollSnapPoints.h"
@@ -35,7 +37,6 @@
 
 namespace WebCore {
 
-class LayoutRect;
 class ScrollableArea;
 class RenderBox;
 class RenderStyle;
@@ -44,30 +45,20 @@
 struct SnapOffset {
     T offset;
     ScrollSnapStop stop;
+    size_t snapAreaIndex;
 };
 
-template <typename T>
-struct ScrollOffsetRange {
-    T start;
-    T end;
-};
-
-template <typename T>
+template <typename UnitType, typename RectType>
 struct ScrollSnapOffsetsInfo {
     WTF_MAKE_STRUCT_FAST_ALLOCATED;
-    Vector<SnapOffset<T>> horizontalSnapOffsets;
-    Vector<SnapOffset<T>> verticalSnapOffsets;
+    ScrollSnapStrictness strictness;
+    Vector<SnapOffset<UnitType>> horizontalSnapOffsets;
+    Vector<SnapOffset<UnitType>> verticalSnapOffsets;
+    Vector<RectType> snapAreas;
 
-    // Snap offset ranges represent non-empty ranges of scroll offsets in which scrolling may rest after scroll snapping.
-    // These are used in two cases: (1) for proximity scroll snapping, where portions of areas between adjacent snap offsets
-    // may emit snap offset ranges, and (2) in the case where the snap area is larger than the snap port, in which case areas
-    // where the snap port fits within the snap area are considered to be valid snap positions.
-    Vector<ScrollOffsetRange<T>> horizontalSnapOffsetRanges;
-    Vector<ScrollOffsetRange<T>> verticalSnapOffsetRanges;
-
-    bool isEqual(const ScrollSnapOffsetsInfo<T>& other) const
+    bool isEqual(const ScrollSnapOffsetsInfo<UnitType, RectType>& other) const
     {
-        return horizontalSnapOffsets == other.horizontalSnapOffsets && verticalSnapOffsets == other.verticalSnapOffsets && horizontalSnapOffsetRanges == other.horizontalSnapOffsetRanges && verticalSnapOffsetRanges == other.verticalSnapOffsetRanges;
+        return strictness == other.strictness && horizontalSnapOffsets == other.horizontalSnapOffsets && verticalSnapOffsets == other.verticalSnapOffsets && snapAreas == other.snapAreas;
     }
 
     bool isEmpty() const
@@ -75,33 +66,31 @@
         return horizontalSnapOffsets.isEmpty() && verticalSnapOffsets.isEmpty();
     }
 
-    Vector<SnapOffset<T>> offsetsForAxis(ScrollEventAxis axis) const
+    Vector<SnapOffset<UnitType>> offsetsForAxis(ScrollEventAxis axis) const
     {
         return axis == ScrollEventAxis::Vertical ? verticalSnapOffsets : horizontalSnapOffsets;
     }
 
-    Vector<ScrollOffsetRange<T>> offsetRangesForAxis(ScrollEventAxis axis) const
-    {
-        return axis == ScrollEventAxis::Vertical ? verticalSnapOffsetRanges : horizontalSnapOffsetRanges;
-    }
-
-    template<typename OutputType> ScrollSnapOffsetsInfo<OutputType> convertUnits(float deviceScaleFactor = 0.0) const;
-    WEBCORE_EXPORT std::pair<T, unsigned> closestSnapOffset(ScrollEventAxis, T scrollDestinationOffset, float velocity, Optional<T> originalPositionForDirectionalSnapping = WTF::nullopt) const;
+    template<typename OutputType> OutputType convertUnits(float deviceScaleFactor = 0.0) const;
+    template<typename SizeType>
+    WEBCORE_EXPORT std::pair<UnitType, unsigned> closestSnapOffset(ScrollEventAxis, const SizeType& viewportSize, UnitType scrollDestinationOffset, float velocity, Optional<UnitType> originalPositionForDirectionalSnapping = WTF::nullopt) const;
 };
 
-using LayoutScrollSnapOffsetsInfo = ScrollSnapOffsetsInfo<LayoutUnit>;
-using FloatScrollSnapOffsetsInfo = ScrollSnapOffsetsInfo<float>;
+using LayoutScrollSnapOffsetsInfo = ScrollSnapOffsetsInfo<LayoutUnit, LayoutRect>;
+using FloatScrollSnapOffsetsInfo = ScrollSnapOffsetsInfo<float, FloatRect>;
 
 template <> template <>
 LayoutScrollSnapOffsetsInfo FloatScrollSnapOffsetsInfo::convertUnits(float /* unusedScaleFactor */) const;
-template <>
-WEBCORE_EXPORT std::pair<float, unsigned> FloatScrollSnapOffsetsInfo::closestSnapOffset(ScrollEventAxis, float scrollDestinationOffset, float velocity, Optional<float> originalPositionForDirectionalSnapping) const;
+template <> template <>
+WEBCORE_EXPORT std::pair<float, unsigned> FloatScrollSnapOffsetsInfo::closestSnapOffset(ScrollEventAxis, const FloatSize& viewportSize, float scrollDestinationOffset, float velocity, Optional<float> originalPositionForDirectionalSnapping) const;
 
+
 template <> template <>
 FloatScrollSnapOffsetsInfo LayoutScrollSnapOffsetsInfo::convertUnits(float deviceScaleFactor) const;
-template <>
-WEBCORE_EXPORT std::pair<LayoutUnit, unsigned> LayoutScrollSnapOffsetsInfo::closestSnapOffset(ScrollEventAxis, LayoutUnit scrollDestinationOffset, float velocity, Optional<LayoutUnit> originalPositionForDirectionalSnapping) const;
+template <> template <>
+WEBCORE_EXPORT std::pair<LayoutUnit, unsigned> LayoutScrollSnapOffsetsInfo::closestSnapOffset(ScrollEventAxis, const LayoutSize& viewportSize, LayoutUnit scrollDestinationOffset, float velocity, Optional<LayoutUnit> originalPositionForDirectionalSnapping) const;
 
+
 const unsigned invalidSnapOffsetIndex = UINT_MAX;
 
 // Update the snap offsets for this scrollable area, given the RenderBox of the scroll container, the RenderStyle
@@ -117,13 +106,6 @@
     return ts;
 }
 
-template<typename T>
-TextStream& operator<<(TextStream& ts, const ScrollOffsetRange<T>& range)
-{
-    ts << "start: " << range.start << " end: " << range.end;
-    return ts;
-}
-
 }; // namespace WebCore
 
 #endif // ENABLE(CSS_SCROLL_SNAP)

Modified: trunk/Source/WebCore/page/scrolling/mac/ScrollingTreeScrollingNodeDelegateMac.mm (277082 => 277083)


--- trunk/Source/WebCore/page/scrolling/mac/ScrollingTreeScrollingNodeDelegateMac.mm	2021-05-06 12:07:56 UTC (rev 277082)
+++ trunk/Source/WebCore/page/scrolling/mac/ScrollingTreeScrollingNodeDelegateMac.mm	2021-05-06 12:11:15 UTC (rev 277083)
@@ -65,7 +65,7 @@
 
 #if ENABLE(CSS_SCROLL_SNAP)
     if (scrollingStateNode.hasChangedProperty(ScrollingStateNode::Property::SnapOffsetsInfo))
-        m_scrollController.updateScrollSnapPoints(scrollingStateNode.snapOffsetsInfo().convertUnits<LayoutUnit>());
+        m_scrollController.updateScrollSnapPoints(scrollingStateNode.snapOffsetsInfo().convertUnits<LayoutScrollSnapOffsetsInfo>());
 
     if (scrollingStateNode.hasChangedProperty(ScrollingStateNode::Property::CurrentHorizontalSnapOffsetIndex))
         m_scrollController.setActiveScrollSnapIndexForAxis(ScrollEventAxis::Horizontal, scrollingStateNode.currentHorizontalSnapPointIndex());

Modified: trunk/Source/WebCore/page/scrolling/nicosia/ScrollingTreeScrollingNodeDelegateNicosia.cpp (277082 => 277083)


--- trunk/Source/WebCore/page/scrolling/nicosia/ScrollingTreeScrollingNodeDelegateNicosia.cpp	2021-05-06 12:07:56 UTC (rev 277082)
+++ trunk/Source/WebCore/page/scrolling/nicosia/ScrollingTreeScrollingNodeDelegateNicosia.cpp	2021-05-06 12:11:15 UTC (rev 277083)
@@ -173,8 +173,8 @@
         FloatPoint newFloatOffset = scrollingNode().currentScrollOffset() + FloatSize(deltaX, deltaY);
         auto newOffset = LayoutPoint(newFloatOffset.x() / scale, newFloatOffset.y() / scale);
 
-        auto offsetX = scrollingNode().snapOffsetsInfo().closestSnapOffset(ScrollEventAxis::Horizontal, newOffset.x(), deltaX, originalOffset.x()).first;
-        auto offsetY = scrollingNode().snapOffsetsInfo().closestSnapOffset(ScrollEventAxis::Vertical, newOffset.y(), deltaY, originalOffset.y()).first;
+        auto offsetX = scrollingNode().snapOffsetsInfo().closestSnapOffset(ScrollEventAxis::Horizontal, scrollableAreaSize(), newOffset.x(), deltaX, originalOffset.x()).first;
+        auto offsetY = scrollingNode().snapOffsetsInfo().closestSnapOffset(ScrollEventAxis::Vertical, scrollableAreaSize(), newOffset.y(), deltaY, originalOffset.y()).first;
 
         deltaX = (offsetX - originalOffset.x()) * scale;
         deltaY = (offsetY - originalOffset.y()) * scale;

Modified: trunk/Source/WebCore/platform/ScrollController.cpp (277082 => 277083)


--- trunk/Source/WebCore/platform/ScrollController.cpp	2021-05-06 12:07:56 UTC (rev 277082)
+++ trunk/Source/WebCore/platform/ScrollController.cpp	2021-05-06 12:11:15 UTC (rev 277083)
@@ -116,7 +116,8 @@
 
     LayoutUnit clampedOffset = std::min(std::max(LayoutUnit(offset / scaleFactor), snapOffsets.first().offset), snapOffsets.last().offset);
 
-    unsigned activeIndex = snapState.snapOffsetInfo().closestSnapOffset(axis, clampedOffset, 0).second;
+    LayoutSize viewportSize(m_client.viewportSize().width(), m_client.viewportSize().height());
+    unsigned activeIndex = snapState.snapOffsetInfo().closestSnapOffset(axis, viewportSize, clampedOffset, 0).second;
     if (activeIndex == activeScrollSnapIndexForAxis(axis))
         return;
 
@@ -137,7 +138,8 @@
     Optional<LayoutUnit> originalOffsetInLayoutUnits;
     if (originalOffset.hasValue())
         originalOffsetInLayoutUnits = LayoutUnit(*originalOffset / m_client.pageScaleFactor());
-    LayoutUnit offset = snapState.snapOffsetInfo().closestSnapOffset(axis, LayoutUnit(destinationOffset / m_client.pageScaleFactor()), velocity, originalOffsetInLayoutUnits).first;
+    LayoutSize viewportSize(m_client.viewportSize().width(), m_client.viewportSize().height());
+    LayoutUnit offset = snapState.snapOffsetInfo().closestSnapOffset(axis, viewportSize, LayoutUnit(destinationOffset / m_client.pageScaleFactor()), velocity, originalOffsetInLayoutUnits).first;
     return offset * m_client.pageScaleFactor();
 }
 

Modified: trunk/Source/WebCore/platform/ScrollSnapAnimatorState.cpp (277082 => 277083)


--- trunk/Source/WebCore/platform/ScrollSnapAnimatorState.cpp	2021-05-06 12:07:56 UTC (rev 277082)
+++ trunk/Source/WebCore/platform/ScrollSnapAnimatorState.cpp	2021-05-06 12:11:15 UTC (rev 277083)
@@ -51,8 +51,8 @@
 
     m_momentumCalculator = ScrollingMomentumCalculator::create(viewportSize, contentSize, initialOffset, initialDelta, initialVelocity);
     auto predictedScrollTarget = m_momentumCalculator->predictedDestinationOffset();
-    float targetOffsetX = targetOffsetForStartOffset(ScrollEventAxis::Horizontal, contentSize.width() - viewportSize.width(), initialOffset.x(), predictedScrollTarget.width(), pageScale, initialDelta.width(), m_activeSnapIndexX);
-    float targetOffsetY = targetOffsetForStartOffset(ScrollEventAxis::Vertical, contentSize.height() - viewportSize.height(), initialOffset.y(), predictedScrollTarget.height(), pageScale, initialDelta.height(), m_activeSnapIndexY);
+    float targetOffsetX = targetOffsetForStartOffset(ScrollEventAxis::Horizontal, viewportSize, contentSize.width() - viewportSize.width(), initialOffset.x(), predictedScrollTarget.width(), pageScale, initialDelta.width(), m_activeSnapIndexX);
+    float targetOffsetY = targetOffsetForStartOffset(ScrollEventAxis::Vertical, viewportSize, contentSize.height() - viewportSize.height(), initialOffset.y(), predictedScrollTarget.height(), pageScale, initialDelta.height(), m_activeSnapIndexY);
     m_momentumCalculator->setRetargetedScrollOffset({ targetOffsetX, targetOffsetY });
     m_startTime = MonotonicTime::now();
     m_currentState = state;
@@ -91,7 +91,7 @@
     return m_momentumCalculator->scrollOffsetAfterElapsedTime(elapsedTime);
 }
 
-float ScrollSnapAnimatorState::targetOffsetForStartOffset(ScrollEventAxis axis, float maxScrollOffset, float startOffset, float predictedOffset, float pageScale, float initialDelta, unsigned& outActiveSnapIndex) const
+float ScrollSnapAnimatorState::targetOffsetForStartOffset(ScrollEventAxis axis, const FloatSize& viewportSize, float maxScrollOffset, float startOffset, float predictedOffset, float pageScale, float initialDelta, unsigned& outActiveSnapIndex) const
 {
     const auto& snapOffsets = m_snapOffsetsInfo.offsetsForAxis(axis);
     if (snapOffsets.isEmpty()) {
@@ -99,7 +99,7 @@
         return clampTo<float>(predictedOffset, 0, maxScrollOffset);
     }
 
-    float targetOffset = m_snapOffsetsInfo.closestSnapOffset(axis, LayoutUnit(predictedOffset / pageScale), initialDelta, LayoutUnit(startOffset / pageScale)).first;
+    float targetOffset = m_snapOffsetsInfo.closestSnapOffset(axis, LayoutSize { viewportSize }, LayoutUnit(predictedOffset / pageScale), initialDelta, LayoutUnit(startOffset / pageScale)).first;
     float minimumTargetOffset = std::max<float>(0, snapOffsets.first().offset);
     float maximumTargetOffset = std::min<float>(maxScrollOffset, snapOffsets.last().offset);
     targetOffset = clampTo<float>(targetOffset, minimumTargetOffset, maximumTargetOffset);
@@ -111,10 +111,6 @@
     ts << "ScrollSnapAnimatorState";
     ts.dumpProperty("snap offsets x", state.snapOffsetsForAxis(ScrollEventAxis::Horizontal));
     ts.dumpProperty("snap offsets y", state.snapOffsetsForAxis(ScrollEventAxis::Vertical));
-    if (!state.snapOffsetRangesForAxis(ScrollEventAxis::Horizontal).isEmpty())
-        ts.dumpProperty("snap offsets ranges x", state.snapOffsetRangesForAxis(ScrollEventAxis::Horizontal));
-    if (!state.snapOffsetRangesForAxis(ScrollEventAxis::Vertical).isEmpty())
-        ts.dumpProperty("snap offsets ranges y", state.snapOffsetRangesForAxis(ScrollEventAxis::Vertical));
 
     ts.dumpProperty("active snap index x", state.activeSnapIndexForAxis(ScrollEventAxis::Horizontal));
     ts.dumpProperty("active snap index y", state.activeSnapIndexForAxis(ScrollEventAxis::Vertical));

Modified: trunk/Source/WebCore/platform/ScrollSnapAnimatorState.h (277082 => 277083)


--- trunk/Source/WebCore/platform/ScrollSnapAnimatorState.h	2021-05-06 12:07:56 UTC (rev 277082)
+++ trunk/Source/WebCore/platform/ScrollSnapAnimatorState.h	2021-05-06 12:11:15 UTC (rev 277083)
@@ -57,25 +57,9 @@
         return axis == ScrollEventAxis::Horizontal ? m_snapOffsetsInfo.horizontalSnapOffsets : m_snapOffsetsInfo.verticalSnapOffsets;
     }
 
-    const Vector<ScrollOffsetRange<LayoutUnit>>& snapOffsetRangesForAxis(ScrollEventAxis axis) const
-    {
-        return axis == ScrollEventAxis::Horizontal ? m_snapOffsetsInfo.horizontalSnapOffsetRanges : m_snapOffsetsInfo.verticalSnapOffsetRanges;
-    }
-
     const LayoutScrollSnapOffsetsInfo& snapOffsetInfo() const { return m_snapOffsetsInfo; }
     void setSnapOffsetInfo(const LayoutScrollSnapOffsetsInfo& newInfo) { m_snapOffsetsInfo = newInfo; }
 
-    void setSnapOffsetsAndPositionRangesForAxis(ScrollEventAxis axis, const Vector<SnapOffset<LayoutUnit>>& snapOffsets, const Vector<ScrollOffsetRange<LayoutUnit>>& snapOffsetRanges)
-    {
-        if (axis == ScrollEventAxis::Horizontal) {
-            m_snapOffsetsInfo.horizontalSnapOffsets = snapOffsets;
-            m_snapOffsetsInfo.horizontalSnapOffsetRanges = snapOffsetRanges;
-        } else {
-            m_snapOffsetsInfo.verticalSnapOffsets = snapOffsets;
-            m_snapOffsetsInfo.verticalSnapOffsetRanges = snapOffsetRanges;
-        }
-    }
-
     ScrollSnapState currentState() const { return m_currentState; }
 
     unsigned activeSnapIndexForAxis(ScrollEventAxis axis) const
@@ -100,7 +84,7 @@
     void transitionToDestinationReachedState();
 
 private:
-    float targetOffsetForStartOffset(ScrollEventAxis, float maxScrollOffset, float startOffset, float predictedOffset, float pageScale, float initialDelta, unsigned& outActiveSnapIndex) const;
+    float targetOffsetForStartOffset(ScrollEventAxis, const FloatSize& viewportSize, float maxScrollOffset, float startOffset, float predictedOffset, float pageScale, float initialDelta, unsigned& outActiveSnapIndex) const;
     void teardownAnimationForState(ScrollSnapState);
     void setupAnimationForState(ScrollSnapState, const FloatSize& contentSize, const FloatSize& viewportSize, float pageScale, const FloatPoint& initialOffset, const FloatSize& initialVelocity, const FloatSize& initialDelta);
 

Modified: trunk/Source/WebKit/ChangeLog (277082 => 277083)


--- trunk/Source/WebKit/ChangeLog	2021-05-06 12:07:56 UTC (rev 277082)
+++ trunk/Source/WebKit/ChangeLog	2021-05-06 12:11:15 UTC (rev 277083)
@@ -1,3 +1,23 @@
+2021-05-06  Martin Robinson  <[email protected]>
+
+        [css-scroll-snap] Compute proximity information while snapping
+        https://bugs.webkit.org/show_bug.cgi?id=224326
+
+        Reviewed by Simon Fraser.
+
+        * Shared/RemoteLayerTree/RemoteScrollingCoordinatorTransaction.cpp:
+        (ArgumentCoder<SnapOffset<float>>::encode): Add the snap area index to the encoded arguments.
+        (ArgumentCoder<SnapOffset<float>>::decode): Add the snap area index to the decoded arguments.
+        (ArgumentCoder<FloatScrollSnapOffsetsInfo>::encode): No longer encode ranges, but encode snap areas.
+        (ArgumentCoder<FloatScrollSnapOffsetsInfo>::decode): Ditto for decode.
+        * Shared/WebCoreArgumentCoders.cpp: Remove code dealing with scroll offset ranges.
+        * Shared/WebCoreArgumentCoders.h: Ditto.
+        * UIProcess/RemoteLayerTree/ios/RemoteScrollingCoordinatorProxyIOS.mm:
+        (WebKit::RemoteScrollingCoordinatorProxy::closestSnapOffsetForMainFrameScrolling const): Pass
+        in viewport size to closestSnapOffset which is necessary for calculating proximity.
+        * UIProcess/RemoteLayerTree/ios/ScrollingTreeScrollingNodeDelegateIOS.mm:
+        (-[WKScrollingNodeScrollViewDelegate scrollViewWillEndDragging:withVelocity:targetContentOffset:]): Ditto.
+
 2021-05-05  Kate Cheney  <[email protected]>
 
         Remove network website data when a user clears an individual domain

Modified: trunk/Source/WebKit/Shared/RemoteLayerTree/RemoteScrollingCoordinatorTransaction.cpp (277082 => 277083)


--- trunk/Source/WebKit/Shared/RemoteLayerTree/RemoteScrollingCoordinatorTransaction.cpp	2021-05-06 12:07:56 UTC (rev 277082)
+++ trunk/Source/WebKit/Shared/RemoteLayerTree/RemoteScrollingCoordinatorTransaction.cpp	2021-05-06 12:11:15 UTC (rev 277083)
@@ -532,6 +532,7 @@
 {
     encoder << offset.offset;
     encoder << offset.stop;
+    encoder << offset.snapAreaIndex;
 }
 
 bool ArgumentCoder<SnapOffset<float>>::decode(Decoder& decoder, SnapOffset<float>& offset)
@@ -540,6 +541,8 @@
         return false;
     if (!decoder.decode(offset.stop))
         return false;
+    if (!decoder.decode(offset.snapAreaIndex))
+        return false;
     return true;
 }
 
@@ -548,8 +551,7 @@
 {
     encoder << info.horizontalSnapOffsets;
     encoder << info.verticalSnapOffsets;
-    encoder << info.horizontalSnapOffsetRanges;
-    encoder << info.verticalSnapOffsetRanges;
+    encoder << info.snapAreas;
 }
 
 bool ArgumentCoder<FloatScrollSnapOffsetsInfo>::decode(Decoder& decoder, FloatScrollSnapOffsetsInfo& info)
@@ -558,10 +560,8 @@
         return false;
     if (!decoder.decode(info.verticalSnapOffsets))
         return false;
-    if (!decoder.decode(info.horizontalSnapOffsetRanges))
+    if (!decoder.decode(info.snapAreas))
         return false;
-    if (!decoder.decode(info.verticalSnapOffsetRanges))
-        return false;
     return true;
 }
 

Modified: trunk/Source/WebKit/Shared/WebCoreArgumentCoders.cpp (277082 => 277083)


--- trunk/Source/WebKit/Shared/WebCoreArgumentCoders.cpp	2021-05-06 12:07:56 UTC (rev 277082)
+++ trunk/Source/WebKit/Shared/WebCoreArgumentCoders.cpp	2021-05-06 12:11:15 UTC (rev 277083)
@@ -2840,32 +2840,6 @@
 
 #endif
 
-#if ENABLE(CSS_SCROLL_SNAP)
-
-void ArgumentCoder<ScrollOffsetRange<float>>::encode(Encoder& encoder, const ScrollOffsetRange<float>& range)
-{
-    encoder << range.start;
-    encoder << range.end;
-}
-
-auto ArgumentCoder<ScrollOffsetRange<float>>::decode(Decoder& decoder) -> Optional<WebCore::ScrollOffsetRange<float>>
-{
-    WebCore::ScrollOffsetRange<float> range;
-    float start;
-    if (!decoder.decode(start))
-        return WTF::nullopt;
-
-    float end;
-    if (!decoder.decode(end))
-        return WTF::nullopt;
-
-    range.start = start;
-    range.end = end;
-    return range;
-}
-
-#endif
-
 void ArgumentCoder<MediaSelectionOption>::encode(Encoder& encoder, const MediaSelectionOption& option)
 {
     encoder << option.displayName;

Modified: trunk/Source/WebKit/Shared/WebCoreArgumentCoders.h (277082 => 277083)


--- trunk/Source/WebKit/Shared/WebCoreArgumentCoders.h	2021-05-06 12:07:56 UTC (rev 277082)
+++ trunk/Source/WebKit/Shared/WebCoreArgumentCoders.h	2021-05-06 12:11:15 UTC (rev 277083)
@@ -742,15 +742,6 @@
 
 #endif
 
-#if ENABLE(CSS_SCROLL_SNAP)
-
-template<> struct ArgumentCoder<WebCore::ScrollOffsetRange<float>> {
-    static void encode(Encoder&, const WebCore::ScrollOffsetRange<float>&);
-    static Optional<WebCore::ScrollOffsetRange<float>> decode(Decoder&);
-};
-
-#endif
-
 template<> struct ArgumentCoder<WebCore::MediaSelectionOption> {
     static void encode(Encoder&, const WebCore::MediaSelectionOption&);
     static Optional<WebCore::MediaSelectionOption> decode(Decoder&);

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


--- trunk/Source/WebKit/UIProcess/RemoteLayerTree/ios/RemoteScrollingCoordinatorProxyIOS.mm	2021-05-06 12:07:56 UTC (rev 277082)
+++ trunk/Source/WebKit/UIProcess/RemoteLayerTree/ios/RemoteScrollingCoordinatorProxyIOS.mm	2021-05-06 12:11:15 UTC (rev 277083)
@@ -230,7 +230,7 @@
 
     float scaledScrollDestination = scrollDestination / m_webPageProxy.displayedContentScale();
     float rawClosestSnapOffset;
-    std::tie(rawClosestSnapOffset, currentIndex) = snapOffsetsInfo.closestSnapOffset(axis, scaledScrollDestination, velocity);
+    std::tie(rawClosestSnapOffset, currentIndex) = snapOffsetsInfo.closestSnapOffset(axis, rootScrollingNode->layoutViewport().size(), scaledScrollDestination, velocity);
     return rawClosestSnapOffset * m_webPageProxy.displayedContentScale();
 }
 

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


--- trunk/Source/WebKit/UIProcess/RemoteLayerTree/ios/ScrollingTreeScrollingNodeDelegateIOS.mm	2021-05-06 12:07:56 UTC (rev 277082)
+++ trunk/Source/WebKit/UIProcess/RemoteLayerTree/ios/ScrollingTreeScrollingNodeDelegateIOS.mm	2021-05-06 12:11:15 UTC (rev 277083)
@@ -106,9 +106,10 @@
     unsigned originalHorizontalSnapPosition = _scrollingTreeNodeDelegate->scrollingNode().currentHorizontalSnapPointIndex();
     unsigned originalVerticalSnapPosition = _scrollingTreeNodeDelegate->scrollingNode().currentVerticalSnapPointIndex();
 
+    WebCore::FloatSize viewportSize(static_cast<float>(CGRectGetWidth([scrollView bounds])), static_cast<float>(CGRectGetHeight([scrollView bounds])));
     const auto& snapOffsetsInfo = _scrollingTreeNodeDelegate->scrollingNode().snapOffsetsInfo();
     if (!snapOffsetsInfo.horizontalSnapOffsets.isEmpty()) {
-        auto [potentialSnapPosition, index] = snapOffsetsInfo.closestSnapOffset(WebCore::ScrollEventAxis::Horizontal, horizontalTarget, velocity.x);
+        auto [potentialSnapPosition, index] = snapOffsetsInfo.closestSnapOffset(WebCore::ScrollEventAxis::Horizontal, viewportSize, horizontalTarget, velocity.x);
         _scrollingTreeNodeDelegate->scrollingNode().setCurrentHorizontalSnapPointIndex(index);
         if (horizontalTarget >= 0 && horizontalTarget <= scrollView.contentSize.width)
             targetContentOffset->x = potentialSnapPosition;
@@ -115,7 +116,7 @@
     }
 
     if (!snapOffsetsInfo.verticalSnapOffsets.isEmpty()) {
-        auto [potentialSnapPosition, index] = snapOffsetsInfo.closestSnapOffset(WebCore::ScrollEventAxis::Vertical, verticalTarget, velocity.x);
+        auto [potentialSnapPosition, index] = snapOffsetsInfo.closestSnapOffset(WebCore::ScrollEventAxis::Vertical, viewportSize, verticalTarget, velocity.x);
         _scrollingTreeNodeDelegate->scrollingNode().setCurrentVerticalSnapPointIndex(index);
         if (verticalTarget >= 0 && verticalTarget <= scrollView.contentSize.height)
             targetContentOffset->y = potentialSnapPosition;
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to