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/. */
7 #ifndef mozilla_layout_ScrollSnapInfo_h_
8 #define mozilla_layout_ScrollSnapInfo_h_
11 #include "mozilla/ScrollTypes.h"
12 #include "mozilla/ScrollSnapTargetId.h"
13 #include "mozilla/ServoStyleConsts.h"
14 #include "mozilla/Maybe.h"
15 #include "mozilla/layers/LayersTypes.h"
22 struct nsStyleDisplay
;
26 enum class StyleScrollSnapStrictness
: uint8_t;
30 SnapPoint() = default;
31 explicit SnapPoint(const nsPoint
& aPoint
)
32 : mX(Some(aPoint
.x
)), mY(Some(aPoint
.y
)) {}
33 SnapPoint(Maybe
<nscoord
>&& aX
, Maybe
<nscoord
>&& aY
)
34 : mX(std::move(aX
)), mY(std::move(aY
)) {}
36 bool operator==(const SnapPoint
& aOther
) const {
37 return mX
== aOther
.mX
&& mY
== aOther
.mY
;
44 struct ScrollSnapInfo
{
45 using ScrollDirection
= layers::ScrollDirection
;
48 bool operator==(const ScrollSnapInfo
& aOther
) const {
49 return mScrollSnapStrictnessX
== aOther
.mScrollSnapStrictnessX
&&
50 mScrollSnapStrictnessY
== aOther
.mScrollSnapStrictnessY
&&
51 mSnapTargets
== aOther
.mSnapTargets
&&
52 mXRangeWiderThanSnapport
== aOther
.mXRangeWiderThanSnapport
&&
53 mYRangeWiderThanSnapport
== aOther
.mYRangeWiderThanSnapport
&&
54 mSnapportSize
== aOther
.mSnapportSize
;
57 bool HasScrollSnapping() const;
58 bool HasSnapPositions() const;
60 void InitializeScrollSnapStrictness(WritingMode aWritingMode
,
61 const nsStyleDisplay
* aDisplay
);
63 // The scroll frame's scroll-snap-type.
64 StyleScrollSnapStrictness mScrollSnapStrictnessX
;
65 StyleScrollSnapStrictness mScrollSnapStrictnessY
;
68 // The scroll positions corresponding to scroll-snap-align values.
71 // https://drafts.csswg.org/css-scroll-snap/#scroll-snap-area
74 // https://drafts.csswg.org/css-scroll-snap/#propdef-scroll-snap-stop
75 StyleScrollSnapStop mScrollSnapStop
= StyleScrollSnapStop::Normal
;
77 // Use for tracking the last snapped target.
78 ScrollSnapTargetId mTargetId
= ScrollSnapTargetId::None
;
80 SnapTarget() = default;
82 SnapTarget(Maybe
<nscoord
>&& aSnapPositionX
, Maybe
<nscoord
>&& aSnapPositionY
,
83 const nsRect
& aSnapArea
, StyleScrollSnapStop aScrollSnapStop
,
84 ScrollSnapTargetId aTargetId
)
85 : mSnapPoint(std::move(aSnapPositionX
), std::move(aSnapPositionY
)),
87 mScrollSnapStop(aScrollSnapStop
),
88 mTargetId(aTargetId
) {}
90 bool operator==(const SnapTarget
& aOther
) const {
91 return mSnapPoint
== aOther
.mSnapPoint
&& mSnapArea
== aOther
.mSnapArea
&&
92 mScrollSnapStop
== aOther
.mScrollSnapStop
&&
93 mTargetId
== aOther
.mTargetId
;
97 CopyableTArray
<SnapTarget
> mSnapTargets
;
99 // A utility function to iterate over the valid snap targets for the given
100 // |aDestination| until |aFunc| returns false.
101 void ForEachValidTargetFor(
102 const nsPoint
& aDestination
,
103 const std::function
<bool(const SnapTarget
&)>& aFunc
) const;
105 struct ScrollSnapRange
{
106 ScrollSnapRange() = default;
108 ScrollSnapRange(const nsRect
& aSnapArea
, ScrollDirection aDirection
,
109 ScrollSnapTargetId aTargetId
)
110 : mSnapArea(aSnapArea
), mDirection(aDirection
), mTargetId(aTargetId
) {}
113 ScrollDirection mDirection
;
114 ScrollSnapTargetId mTargetId
;
116 bool operator==(const ScrollSnapRange
& aOther
) const {
117 return mDirection
== aOther
.mDirection
&& mSnapArea
== aOther
.mSnapArea
&&
118 mTargetId
== aOther
.mTargetId
;
121 nscoord
Start() const {
122 return mDirection
== ScrollDirection::eHorizontal
? mSnapArea
.X()
126 nscoord
End() const {
127 return mDirection
== ScrollDirection::eHorizontal
? mSnapArea
.XMost()
131 // Returns true if |aPoint| is a valid snap position in this range.
132 bool IsValid(nscoord aPoint
, nscoord aSnapportSize
) const {
133 MOZ_ASSERT(End() - Start() > aSnapportSize
);
134 return Start() <= aPoint
&& aPoint
<= End() - aSnapportSize
;
137 // An array of the range that the target element is larger than the snapport
139 // Snap positions in this range will be valid snap positions in the case where
140 // the distance between the closest snap position and the second closest snap
141 // position is still larger than the snapport size.
142 // See https://drafts.csswg.org/css-scroll-snap-1/#snap-overflow
144 // Note: This range contains scroll-margin values.
145 CopyableTArray
<ScrollSnapRange
> mXRangeWiderThanSnapport
;
146 CopyableTArray
<ScrollSnapRange
> mYRangeWiderThanSnapport
;
148 // Note: This snapport size has been already deflated by scroll-padding.
149 nsSize mSnapportSize
;
152 } // namespace mozilla
154 #endif // mozilla_layout_ScrollSnapInfo_h_