Changeset 280527 in webkit
- Timestamp:
- Aug 2, 2021 1:54:16 AM (12 months ago)
- Location:
- trunk
- Files:
-
- 8 edited
-
LayoutTests/imported/w3c/ChangeLog (modified) (1 diff)
-
LayoutTests/imported/w3c/web-platform-tests/css/css-scroll-snap/overflowing-snap-areas-expected.txt (modified) (1 diff)
-
LayoutTests/imported/w3c/web-platform-tests/css/css-scroll-snap/overflowing-snap-areas.html (modified) (4 diffs)
-
Source/WebCore/ChangeLog (modified) (1 diff)
-
Source/WebCore/page/scrolling/ScrollSnapOffsetsInfo.cpp (modified) (5 diffs)
-
Source/WebCore/page/scrolling/ScrollSnapOffsetsInfo.h (modified) (2 diffs)
-
Source/WebKit/ChangeLog (modified) (1 diff)
-
Source/WebKit/Shared/RemoteLayerTree/RemoteScrollingCoordinatorTransaction.cpp (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/imported/w3c/ChangeLog
r280511 r280527 1 2021-08-02 Martin Robinson <mrobinson@webkit.org> 2 3 [css-scroll-snap] Consider all snap areas at a given snap offset when snapping 4 https://bugs.webkit.org/show_bug.cgi?id=228141 5 6 Reviewed by Frédéric Wang. 7 8 * web-platform-tests/css/css-scroll-snap/overflowing-snap-areas-expected.txt: 9 * web-platform-tests/css/css-scroll-snap/overflowing-snap-areas.html: 10 1 11 2021-07-31 Commit Queue <commit-queue@webkit.org> 2 12 -
trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-scroll-snap/overflowing-snap-areas-expected.txt
r279364 r280527 11 11 PASS Don't snap back even if scrollTo tries to scroll to positions which are outside of the scroll range and if a snap target element covers the snaport 12 12 PASS Snap to current scroll position on x as the area is covering x axis.However, we snap to the specified snap position on y as the area is not covering y axis. 13 PASS snap to current scroll position on y as the area is covering y axis, even though that area is not the only scroll area at the same position. 14 PASS snap to current scroll position on x as the area is covering x axis, even though that area is not the only scroll area at the same position. 13 15 -
trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-scroll-snap/overflowing-snap-areas.html
r268250 r280527 25 25 .target { 26 26 scroll-snap-align: start; 27 height: 400px; 28 width: 400px; 27 29 } 28 30 .large-x { 29 31 width: 3000px; 30 height: 400px;31 32 background-color: yellow; 32 33 } 33 34 .large-y { 34 width: 400px;35 35 height: 2000px; 36 background-color: green;36 background-color: yellow; 37 37 } 38 38 .small { … … 73 73 </div> 74 74 75 <div class="scroller-x" id="overlapping-overflow" style="scroll-snap-type: both mandatory"> 76 <div class="space"></div> 77 <div style="left: 200px; top: 200px;"> 78 <div class="target small"></div> 79 <div class="target small"></div> 80 <div class="target small"></div> 81 <div class="target large-y large-x"></div> 82 <div class="target small"></div> 83 <div class="target small"></div> 84 <div class="target small"></div> 85 </div> 86 </div> 87 75 88 <script> 76 89 var one_target_scroller = document.getElementById("one-target"); … … 78 91 var scroller_y = document.getElementById("y"); 79 92 var two_axes_scroller = document.getElementById("two-axes"); 93 var overlapping_scroller = document.getElementById("overlapping-overflow"); 80 94 81 95 test(() => { … … 166 180 "However, we snap to the specified snap position on y as the area is not " + 167 181 "covering y axis."); 182 183 test(() => { 184 overlapping_scroller.scrollTo(200, 800); 185 assert_equals(overlapping_scroller.scrollLeft, 200); 186 assert_equals(overlapping_scroller.scrollTop, 800); 187 }, "snap to current scroll position on y as the area is covering y axis, " + 188 "even though that area is not the only scroll area at the same position."); 189 190 test(() => { 191 overlapping_scroller.scrollTo(800, 200); 192 assert_equals(overlapping_scroller.scrollLeft, 800); 193 assert_equals(overlapping_scroller.scrollTop, 200); 194 }, "snap to current scroll position on x as the area is covering x axis, " + 195 "even though that area is not the only scroll area at the same position."); 168 196 </script> 197 </script> -
trunk/Source/WebCore/ChangeLog
r280525 r280527 1 2021-08-02 Martin Robinson <mrobinson@webkit.org> 2 3 [css-scroll-snap] Consider all snap areas at a given snap offset when snapping 4 https://bugs.webkit.org/show_bug.cgi?id=228141 5 6 Reviewed by Frédéric Wang. 7 8 When deciding whether to snap to snap areas that overflow the snap port, don't 9 just consider the first snap area at a given snap offset. Instead, keep information 10 about all snap areas in the ScrolSnapOffsetInfo. In order to avoid iterating over 11 arrays of hundreds of rectangles, also record whether any of them are larger than 12 the viewport. This will avoid extra work on the most common usecase of large sets 13 of snap areas (gridded table layouts). 14 15 This change is tested by extending an existing WPT test. 16 17 * page/scrolling/ScrollSnapOffsetsInfo.cpp: 18 (WebCore::rangeForAxis): Added this helper. 19 (WebCore::searchForPotentialSnapPoints): When deciding if a particular snap area 20 overflows the snap port, look at all available snap areas instead of just the 21 first one. 22 (WebCore::updateSnapOffsetsForScrollableArea): Instead of only recording the first 23 snap area, record all of them in the list of snap area rectangles. 24 (WebCore::convertOffsetInfo): Convert the list of snap ares. 25 * page/scrolling/ScrollSnapOffsetsInfo.h: 26 (WebCore::operator==): Added this operator which is necessary now that snapAreaIndices 27 is a vector. 28 1 29 2021-08-01 Rob Buis <rbuis@igalia.com> 2 30 -
trunk/Source/WebCore/page/scrolling/ScrollSnapOffsetsInfo.cpp
r280171 r280527 41 41 namespace WebCore { 42 42 43 template <typename UnitType, typename RectType> 44 static std::pair<UnitType, UnitType> rangeForAxis(RectType rect, ScrollEventAxis axis) 45 { 46 return axis == ScrollEventAxis::Horizontal ? std::make_pair(rect.x(), rect.maxX()) : std::make_pair(rect.y(), rect.maxY()); 47 } 48 43 49 template <typename UnitType> 44 50 struct PotentialSnapPointSearchResult { … … 68 74 69 75 for (unsigned i = 0; i < snapOffsets.size(); i++) { 76 if (!landedInsideSnapAreaThatConsumesViewport && snapOffsets[i].hasSnapAreaLargerThanViewport) { 77 for (auto snapAreaIndices : snapOffsets[i].snapAreaIndices) { 78 auto [snapAreaMin, snapAreaMax] = rangeForAxis<UnitType>(info.snapAreas[snapAreaIndices], axis); 79 if (snapAreaMin <= destinationOffset && snapAreaMax >= (destinationOffset + viewportLength)) { 80 landedInsideSnapAreaThatConsumesViewport = true; 81 break; 82 } 83 } 84 } 85 70 86 UnitType potentialSnapOffset = snapOffsets[i].offset; 71 72 const auto& snapArea = info.snapAreas[snapOffsets[i].snapAreaIndex];73 auto snapAreaMin = axis == ScrollEventAxis::Horizontal ? snapArea.x() : snapArea.y();74 auto snapAreaMax = axis == ScrollEventAxis::Horizontal ? snapArea.maxX() : snapArea.maxY();75 landedInsideSnapAreaThatConsumesViewport |= snapAreaMin <= destinationOffset && snapAreaMax >= (destinationOffset + viewportLength);76 77 87 if (potentialSnapOffset == destinationOffset) 78 88 exact = std::make_pair(potentialSnapOffset, i); … … 220 230 } 221 231 222 auto addOrUpdateStopForSnapOffset = [](HashMap<float, SnapOffset<LayoutUnit>>& offsets, SnapOffset<LayoutUnit> newOffset)232 auto addOrUpdateStopForSnapOffset = [](HashMap<float, SnapOffset<LayoutUnit>>& offsets, LayoutUnit newOffset, ScrollSnapStop stop, bool hasSnapAreaLargerThanViewport, size_t snapAreaIndices) 223 233 { 234 auto offset = offsets.ensure(newOffset, [&] { 235 return SnapOffset<LayoutUnit> { newOffset, stop, hasSnapAreaLargerThanViewport, { } }; 236 }); 237 224 238 // If the offset already exists, we ensure that it has ScrollSnapStop::Always, when appropriate. 225 auto addResult = offsets.add(newOffset.offset, newOffset); 226 if (newOffset.stop == ScrollSnapStop::Always) 227 addResult.iterator->value.stop = ScrollSnapStop::Always; 239 if (stop == ScrollSnapStop::Always) 240 offset.iterator->value.stop = ScrollSnapStop::Always; 241 242 offset.iterator->value.hasSnapAreaLargerThanViewport |= hasSnapAreaLargerThanViewport; 243 offset.iterator->value.snapAreaIndices.append(snapAreaIndices); 228 244 }; 229 245 … … 294 310 auto absoluteScrollXPosition = computeScrollSnapAlignOffset(scrollSnapArea.x(), scrollSnapArea.maxX(), xAlign, areaXAxisFlipped) - computeScrollSnapAlignOffset(scrollSnapPort.x(), scrollSnapPort.maxX(), xAlign, areaXAxisFlipped); 295 311 auto absoluteScrollOffset = clampTo<int>(scrollableArea.scrollOffsetFromPosition({ roundToInt(absoluteScrollXPosition), 0 }).x(), 0, maxScrollOffset.x()); 296 addOrUpdateStopForSnapOffset(horizontalSnapOffsetsMap, { absoluteScrollOffset, stop, snapAreas.size() - 1 });312 addOrUpdateStopForSnapOffset(horizontalSnapOffsetsMap, absoluteScrollOffset, stop, scrollSnapAreaAsOffsets.width() > scrollSnapPort.width(), snapAreas.size() - 1); 297 313 } 298 314 if (snapsVertically) { 299 315 auto absoluteScrollYPosition = computeScrollSnapAlignOffset(scrollSnapArea.y(), scrollSnapArea.maxY(), yAlign, areaYAxisFlipped) - computeScrollSnapAlignOffset(scrollSnapPort.y(), scrollSnapPort.maxY(), yAlign, areaYAxisFlipped); 300 316 auto absoluteScrollOffset = clampTo<int>(scrollableArea.scrollOffsetFromPosition({ 0, roundToInt(absoluteScrollYPosition) }).y(), 0, maxScrollOffset.y()); 301 addOrUpdateStopForSnapOffset(verticalSnapOffsetsMap, { absoluteScrollOffset, stop, snapAreas.size() - 1 });317 addOrUpdateStopForSnapOffset(verticalSnapOffsetsMap, absoluteScrollOffset, stop, scrollSnapAreaAsOffsets.height() > scrollSnapPort.height(), snapAreas.size() - 1); 302 318 } 303 319 … … 349 365 output.reserveInitialCapacity(input.size()); 350 366 for (auto& offset : input) 351 output.uncheckedAppend({ convertOffsetUnit(offset.offset, scaleFactor), offset.stop, offset. snapAreaIndex});367 output.uncheckedAppend({ convertOffsetUnit(offset.offset, scaleFactor), offset.stop, offset.hasSnapAreaLargerThanViewport, offset.snapAreaIndices }); 352 368 return output; 353 369 }; -
trunk/Source/WebCore/page/scrolling/ScrollSnapOffsetsInfo.h
r280171 r280527 44 44 T offset; 45 45 ScrollSnapStop stop; 46 size_t snapAreaIndex; 46 bool hasSnapAreaLargerThanViewport; 47 Vector<size_t> snapAreaIndices; 47 48 }; 48 49 … … 75 76 }; 76 77 78 template<typename UnitType> inline bool operator==(const SnapOffset<UnitType>& a, const SnapOffset<UnitType>& b) 79 { 80 return a.offset == b.offset && a.stop == b.stop && a.snapAreaIndices == b.snapAreaIndices; 81 } 82 77 83 using LayoutScrollSnapOffsetsInfo = ScrollSnapOffsetsInfo<LayoutUnit, LayoutRect>; 78 84 using FloatScrollSnapOffsetsInfo = ScrollSnapOffsetsInfo<float, FloatRect>; -
trunk/Source/WebKit/ChangeLog
r280523 r280527 1 2021-08-02 Martin Robinson <mrobinson@igalia.com> 2 3 [css-scroll-snap] Consider all snap areas at a given snap offset when snapping 4 https://bugs.webkit.org/show_bug.cgi?id=228141 5 6 Reviewed by Frédéric Wang. 7 8 * Shared/RemoteLayerTree/RemoteScrollingCoordinatorTransaction.cpp: 9 (ArgumentCoder<SnapOffset<float>>::encode): Serialize new members. 10 (ArgumentCoder<SnapOffset<float>>::decode): Deserialize new members. 11 1 12 2021-08-01 Youenn Fablet <youenn@apple.com> 2 13 -
trunk/Source/WebKit/Shared/RemoteLayerTree/RemoteScrollingCoordinatorTransaction.cpp
r279218 r280527 528 528 encoder << offset.offset; 529 529 encoder << offset.stop; 530 encoder << offset.snapAreaIndex; 530 encoder << offset.hasSnapAreaLargerThanViewport; 531 encoder << offset.snapAreaIndices; 531 532 } 532 533 … … 537 538 if (!decoder.decode(offset.stop)) 538 539 return false; 539 if (!decoder.decode(offset.snapAreaIndex)) 540 if (!decoder.decode(offset.hasSnapAreaLargerThanViewport)) 541 return false; 542 if (!decoder.decode(offset.snapAreaIndices)) 540 543 return false; 541 544 return true;
Note: See TracChangeset
for help on using the changeset viewer.