ScrollSnapInfo.h (4674B)
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 #ifndef mozilla_layout_ScrollSnapInfo_h_ 8 #define mozilla_layout_ScrollSnapInfo_h_ 9 10 #include "mozilla/Maybe.h" 11 #include "mozilla/ScrollSnapTargetId.h" 12 #include "mozilla/ScrollTypes.h" 13 #include "mozilla/ServoStyleConsts.h" 14 #include "mozilla/layers/LayersTypes.h" 15 #include "nsPoint.h" 16 17 class nsIContent; 18 class nsIFrame; 19 struct nsRect; 20 struct nsSize; 21 struct nsStyleDisplay; 22 23 namespace mozilla { 24 25 enum class StyleScrollSnapStrictness : uint8_t; 26 class WritingMode; 27 28 struct SnapPoint { 29 SnapPoint() = default; 30 explicit SnapPoint(const nsPoint& aPoint) 31 : mX(Some(aPoint.x)), mY(Some(aPoint.y)) {} 32 SnapPoint(Maybe<nscoord>&& aX, Maybe<nscoord>&& aY) 33 : mX(std::move(aX)), mY(std::move(aY)) {} 34 35 bool operator==(const SnapPoint&) const = default; 36 37 Maybe<nscoord> mX; 38 Maybe<nscoord> mY; 39 }; 40 41 struct ScrollSnapInfo { 42 using ScrollDirection = layers::ScrollDirection; 43 ScrollSnapInfo(); 44 45 bool operator==(const ScrollSnapInfo&) const = default; 46 47 bool HasScrollSnapping() const; 48 bool HasSnapPositions() const; 49 50 void InitializeScrollSnapStrictness(WritingMode aWritingMode, 51 const nsStyleDisplay* aDisplay); 52 53 // The scroll frame's scroll-snap-type. 54 StyleScrollSnapStrictness mScrollSnapStrictnessX; 55 StyleScrollSnapStrictness mScrollSnapStrictnessY; 56 57 struct SnapTarget { 58 // The scroll positions corresponding to scroll-snap-align values. 59 SnapPoint mSnapPoint; 60 61 // https://drafts.csswg.org/css-scroll-snap/#scroll-snap-area 62 nsRect mSnapArea; 63 64 // https://drafts.csswg.org/css-scroll-snap/#propdef-scroll-snap-stop 65 StyleScrollSnapStop mScrollSnapStop = StyleScrollSnapStop::Normal; 66 67 // Use for tracking the last snapped target. 68 ScrollSnapTargetId mTargetId = ScrollSnapTargetId::None; 69 70 SnapTarget() = default; 71 72 SnapTarget(Maybe<nscoord>&& aSnapPositionX, Maybe<nscoord>&& aSnapPositionY, 73 const nsRect& aSnapArea, StyleScrollSnapStop aScrollSnapStop, 74 ScrollSnapTargetId aTargetId) 75 : mSnapPoint(std::move(aSnapPositionX), std::move(aSnapPositionY)), 76 mSnapArea(aSnapArea), 77 mScrollSnapStop(aScrollSnapStop), 78 mTargetId(aTargetId) {} 79 80 bool operator==(const SnapTarget& aOther) const = default; 81 }; 82 83 CopyableTArray<SnapTarget> mSnapTargets; 84 85 // A utility function to iterate over the valid snap targets for the given 86 // |aDestination| until |aFunc| returns false. 87 void ForEachValidTargetFor( 88 const nsPoint& aDestination, 89 const std::function<bool(const SnapTarget&)>& aFunc) const; 90 91 struct ScrollSnapRange { 92 ScrollSnapRange() = default; 93 94 ScrollSnapRange(const nsRect& aSnapArea, ScrollDirection aDirection, 95 ScrollSnapTargetId aTargetId) 96 : mSnapArea(aSnapArea), mDirection(aDirection), mTargetId(aTargetId) {} 97 98 nsRect mSnapArea; 99 ScrollDirection mDirection; 100 ScrollSnapTargetId mTargetId; 101 102 bool operator==(const ScrollSnapRange& aOther) const = default; 103 104 nscoord Start() const { 105 return mDirection == ScrollDirection::eHorizontal ? mSnapArea.X() 106 : mSnapArea.Y(); 107 } 108 109 nscoord End() const { 110 return mDirection == ScrollDirection::eHorizontal ? mSnapArea.XMost() 111 : mSnapArea.YMost(); 112 } 113 114 // Returns true if |aPoint| is a valid snap position in this range. 115 bool IsValid(nscoord aPoint, nscoord aSnapportSize) const { 116 MOZ_ASSERT(End() - Start() > aSnapportSize); 117 return Start() <= aPoint && aPoint <= End() - aSnapportSize; 118 } 119 }; 120 // An array of the range that the target element is larger than the snapport 121 // on the axis. 122 // Snap positions in this range will be valid snap positions in the case where 123 // the distance between the closest snap position and the second closest snap 124 // position is still larger than the snapport size. 125 // See https://drafts.csswg.org/css-scroll-snap-1/#snap-overflow 126 // 127 // Note: This range contains scroll-margin values. 128 CopyableTArray<ScrollSnapRange> mXRangeWiderThanSnapport; 129 CopyableTArray<ScrollSnapRange> mYRangeWiderThanSnapport; 130 131 // Note: This snapport size has been already deflated by scroll-padding. 132 nsSize mSnapportSize; 133 }; 134 135 } // namespace mozilla 136 137 #endif // mozilla_layout_ScrollSnapInfo_h_