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