ScrollSnapInfo.cpp (3643B)
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #include "ScrollSnapInfo.h" 8 9 #include "mozilla/WritingModes.h" 10 #include "nsPoint.h" 11 #include "nsRect.h" 12 #include "nsStyleStruct.h" 13 14 namespace mozilla { 15 16 ScrollSnapInfo::ScrollSnapInfo() 17 : mScrollSnapStrictnessX(StyleScrollSnapStrictness::None), 18 mScrollSnapStrictnessY(StyleScrollSnapStrictness::None) {} 19 20 bool ScrollSnapInfo::HasScrollSnapping() const { 21 return mScrollSnapStrictnessY != StyleScrollSnapStrictness::None || 22 mScrollSnapStrictnessX != StyleScrollSnapStrictness::None; 23 } 24 25 bool ScrollSnapInfo::HasSnapPositions() const { 26 if (!HasScrollSnapping()) { 27 return false; 28 } 29 30 for (const auto& target : mSnapTargets) { 31 if ((target.mSnapPoint.mX && 32 mScrollSnapStrictnessX != StyleScrollSnapStrictness::None) || 33 (target.mSnapPoint.mY && 34 mScrollSnapStrictnessY != StyleScrollSnapStrictness::None)) { 35 return true; 36 } 37 } 38 return false; 39 } 40 41 void ScrollSnapInfo::InitializeScrollSnapStrictness( 42 WritingMode aWritingMode, const nsStyleDisplay* aDisplay) { 43 if (aDisplay->mScrollSnapType.strictness == StyleScrollSnapStrictness::None) { 44 return; 45 } 46 47 mScrollSnapStrictnessX = StyleScrollSnapStrictness::None; 48 mScrollSnapStrictnessY = StyleScrollSnapStrictness::None; 49 50 switch (aDisplay->mScrollSnapType.axis) { 51 case StyleScrollSnapAxis::X: 52 mScrollSnapStrictnessX = aDisplay->mScrollSnapType.strictness; 53 break; 54 case StyleScrollSnapAxis::Y: 55 mScrollSnapStrictnessY = aDisplay->mScrollSnapType.strictness; 56 break; 57 case StyleScrollSnapAxis::Block: 58 if (aWritingMode.IsVertical()) { 59 mScrollSnapStrictnessX = aDisplay->mScrollSnapType.strictness; 60 } else { 61 mScrollSnapStrictnessY = aDisplay->mScrollSnapType.strictness; 62 } 63 break; 64 case StyleScrollSnapAxis::Inline: 65 if (aWritingMode.IsVertical()) { 66 mScrollSnapStrictnessY = aDisplay->mScrollSnapType.strictness; 67 } else { 68 mScrollSnapStrictnessX = aDisplay->mScrollSnapType.strictness; 69 } 70 break; 71 case StyleScrollSnapAxis::Both: 72 mScrollSnapStrictnessX = aDisplay->mScrollSnapType.strictness; 73 mScrollSnapStrictnessY = aDisplay->mScrollSnapType.strictness; 74 break; 75 } 76 } 77 78 void ScrollSnapInfo::ForEachValidTargetFor( 79 const nsPoint& aDestination, 80 const std::function<bool(const SnapTarget&)>& aFunc) const { 81 for (const auto& target : mSnapTargets) { 82 nsPoint snapPoint( 83 mScrollSnapStrictnessX != StyleScrollSnapStrictness::None && 84 target.mSnapPoint.mX 85 ? *target.mSnapPoint.mX 86 : aDestination.x, 87 mScrollSnapStrictnessY != StyleScrollSnapStrictness::None && 88 target.mSnapPoint.mY 89 ? *target.mSnapPoint.mY 90 : aDestination.y); 91 nsRect snappedPort = nsRect(snapPoint, mSnapportSize); 92 // Ignore snap points if snapping to the point would leave the snap area 93 // outside of the snapport. 94 // https://drafts.csswg.org/css-scroll-snap-1/#snap-scope 95 // 96 // NOTE: We don't use BaseRect::Intersects() here since the function returns 97 // false in cases where the given rectangle is empty. 98 if (!snappedPort.EdgeInclusiveIntersection(target.mSnapArea)) { 99 continue; 100 } 101 102 if (!aFunc(target)) { 103 break; 104 } 105 } 106 } 107 108 } // namespace mozilla