Backed out changeset 1a951477dca5 (bug 1588743) for xpcshell failures at devtools/shared/tests/unit/test_css-properties-db.js on a CLOSED TREE

This commit is contained in:
Coroiu Cristina 2019-10-15 15:35:50 +03:00
parent 420b46f146
commit 291d475197
21 changed files with 597 additions and 406 deletions

View File

@ -675,13 +675,15 @@ void Element::ScrollIntoView(const ScrollIntoViewOptions& aOptions) {
MOZ_ASSERT_UNREACHABLE("Unexpected ScrollLogicalPosition value");
}
ScrollFlags scrollFlags =
ScrollFlags::ScrollOverflowHidden | ScrollFlags::ScrollSnap;
ScrollFlags scrollFlags = ScrollFlags::ScrollOverflowHidden;
if (aOptions.mBehavior == ScrollBehavior::Smooth) {
scrollFlags |= ScrollFlags::ScrollSmooth;
} else if (aOptions.mBehavior == ScrollBehavior::Auto) {
scrollFlags |= ScrollFlags::ScrollSmoothAuto;
}
if (StaticPrefs::layout_css_scroll_snap_v1_enabled()) {
scrollFlags |= ScrollFlags::ScrollSnap;
}
presShell->ScrollContentIntoView(
this, ScrollAxis(whereToScrollVertically, WhenToScroll::Always),

View File

@ -721,6 +721,10 @@ struct ScrollSnapInfo {
bool operator==(const ScrollSnapInfo& aOther) const {
return mScrollSnapStrictnessX == aOther.mScrollSnapStrictnessX &&
mScrollSnapStrictnessY == aOther.mScrollSnapStrictnessY &&
mScrollSnapIntervalX == aOther.mScrollSnapIntervalX &&
mScrollSnapIntervalY == aOther.mScrollSnapIntervalY &&
mScrollSnapDestination == aOther.mScrollSnapDestination &&
mScrollSnapCoordinates == aOther.mScrollSnapCoordinates &&
mSnapPositionX == aOther.mSnapPositionX &&
mSnapPositionY == aOther.mSnapPositionY &&
mXRangeWiderThanSnapport == aOther.mXRangeWiderThanSnapport &&
@ -750,6 +754,18 @@ struct ScrollSnapInfo {
mozilla::StyleScrollSnapStrictness mScrollSnapStrictnessY =
mozilla::StyleScrollSnapStrictness::None;
// The intervals derived from the scroll frame's scroll-snap-points.
Maybe<nscoord> mScrollSnapIntervalX;
Maybe<nscoord> mScrollSnapIntervalY;
// The scroll frame's scroll-snap-destination, in cooked form (to avoid
// shipping the raw style value over IPC).
nsPoint mScrollSnapDestination;
// The scroll-snap-coordinates of any descendant frames of the scroll frame,
// relative to the origin of the scrolled frame.
nsTArray<nsPoint> mScrollSnapCoordinates;
// The scroll positions corresponding to scroll-snap-align values.
nsTArray<nscoord> mSnapPositionX;
nsTArray<nscoord> mSnapPositionY;

View File

@ -29,8 +29,12 @@ TEST_F(APZCSnappingTester, Bug1265510) {
ScrollSnapInfo snap;
snap.mScrollSnapStrictnessY = StyleScrollSnapStrictness::Mandatory;
snap.mSnapPositionY.AppendElement(0 * AppUnitsPerCSSPixel());
snap.mSnapPositionY.AppendElement(100 * AppUnitsPerCSSPixel());
if (StaticPrefs::layout_css_scroll_snap_v1_enabled()) {
snap.mSnapPositionY.AppendElement(0 * AppUnitsPerCSSPixel());
snap.mSnapPositionY.AppendElement(100 * AppUnitsPerCSSPixel());
} else {
snap.mScrollSnapIntervalY = Some(100 * AppUnitsPerCSSPixel());
}
ScrollMetadata metadata = root->GetScrollMetadata(0);
metadata.SetSnapInfo(ScrollSnapInfo(snap));
@ -101,8 +105,12 @@ TEST_F(APZCSnappingTester, Snap_After_Pinch) {
ScrollSnapInfo snap;
snap.mScrollSnapStrictnessY = StyleScrollSnapStrictness::Mandatory;
snap.mSnapPositionY.AppendElement(0 * AppUnitsPerCSSPixel());
snap.mSnapPositionY.AppendElement(100 * AppUnitsPerCSSPixel());
if (StaticPrefs::layout_css_scroll_snap_v1_enabled()) {
snap.mSnapPositionY.AppendElement(0 * AppUnitsPerCSSPixel());
snap.mSnapPositionY.AppendElement(100 * AppUnitsPerCSSPixel());
} else {
snap.mScrollSnapIntervalY = Some(100 * AppUnitsPerCSSPixel());
}
// Save the scroll snap info on the root APZC.
// Also mark the root APZC as "root content", since APZC only allows

View File

@ -28,8 +28,12 @@ TEST_F(APZCSnappingOnMomentumTester, Snap_On_Momentum) {
ScrollSnapInfo snap;
snap.mScrollSnapStrictnessY = StyleScrollSnapStrictness::Mandatory;
snap.mSnapPositionY.AppendElement(0 * AppUnitsPerCSSPixel());
snap.mSnapPositionY.AppendElement(100 * AppUnitsPerCSSPixel());
if (StaticPrefs::layout_css_scroll_snap_v1_enabled()) {
snap.mSnapPositionY.AppendElement(0 * AppUnitsPerCSSPixel());
snap.mSnapPositionY.AppendElement(100 * AppUnitsPerCSSPixel());
} else {
snap.mScrollSnapIntervalY = Some(100 * AppUnitsPerCSSPixel());
}
ScrollMetadata metadata = root->GetScrollMetadata(0);
metadata.SetSnapInfo(ScrollSnapInfo(snap));

View File

@ -15,6 +15,7 @@ const prefs = [
// the target APZC after each such movement.
["mousewheel.transaction.ignoremovedelay", 0],
["mousewheel.transaction.timeout", 0],
["layout.css.scroll-snap-v1.enabled", true],
];
const subtests = [

View File

@ -322,6 +322,10 @@ struct ParamTraits<mozilla::layers::ScrollSnapInfo> {
static void Write(Message* aMsg, const paramType& aParam) {
WriteParam(aMsg, aParam.mScrollSnapStrictnessX);
WriteParam(aMsg, aParam.mScrollSnapStrictnessY);
WriteParam(aMsg, aParam.mScrollSnapIntervalX);
WriteParam(aMsg, aParam.mScrollSnapIntervalY);
WriteParam(aMsg, aParam.mScrollSnapDestination);
WriteParam(aMsg, aParam.mScrollSnapCoordinates);
WriteParam(aMsg, aParam.mSnapPositionX);
WriteParam(aMsg, aParam.mSnapPositionY);
WriteParam(aMsg, aParam.mXRangeWiderThanSnapport);
@ -333,6 +337,10 @@ struct ParamTraits<mozilla::layers::ScrollSnapInfo> {
paramType* aResult) {
return (ReadParam(aMsg, aIter, &aResult->mScrollSnapStrictnessX) &&
ReadParam(aMsg, aIter, &aResult->mScrollSnapStrictnessY) &&
ReadParam(aMsg, aIter, &aResult->mScrollSnapIntervalX) &&
ReadParam(aMsg, aIter, &aResult->mScrollSnapIntervalY) &&
ReadParam(aMsg, aIter, &aResult->mScrollSnapDestination) &&
ReadParam(aMsg, aIter, &aResult->mScrollSnapCoordinates) &&
ReadParam(aMsg, aIter, &aResult->mSnapPositionX) &&
ReadParam(aMsg, aIter, &aResult->mSnapPositionY) &&
ReadParam(aMsg, aIter, &aResult->mXRangeWiderThanSnapport) &&

View File

@ -10,18 +10,59 @@
namespace mozilla {
void ScrollStyles::InitializeScrollSnapStrictness(
WritingMode aWritingMode, const nsStyleDisplay* aDisplay) {
mScrollSnapStrictnessX = StyleScrollSnapStrictness::None;
mScrollSnapStrictnessY = StyleScrollSnapStrictness::None;
if (aDisplay->mScrollSnapType.strictness == StyleScrollSnapStrictness::None) {
return;
}
switch (aDisplay->mScrollSnapType.axis) {
case StyleScrollSnapAxis::X:
mScrollSnapStrictnessX = aDisplay->mScrollSnapType.strictness;
break;
case StyleScrollSnapAxis::Y:
mScrollSnapStrictnessY = aDisplay->mScrollSnapType.strictness;
break;
case StyleScrollSnapAxis::Block:
if (aWritingMode.IsVertical()) {
mScrollSnapStrictnessX = aDisplay->mScrollSnapType.strictness;
} else {
mScrollSnapStrictnessY = aDisplay->mScrollSnapType.strictness;
}
break;
case StyleScrollSnapAxis::Inline:
if (aWritingMode.IsVertical()) {
mScrollSnapStrictnessY = aDisplay->mScrollSnapType.strictness;
} else {
mScrollSnapStrictnessX = aDisplay->mScrollSnapType.strictness;
}
break;
case StyleScrollSnapAxis::Both:
mScrollSnapStrictnessX = aDisplay->mScrollSnapType.strictness;
mScrollSnapStrictnessY = aDisplay->mScrollSnapType.strictness;
break;
}
}
ScrollStyles::ScrollStyles(WritingMode aWritingMode, StyleOverflow aH,
StyleOverflow aV, const nsStyleDisplay* aDisplay)
: mHorizontal(aH),
mVertical(aV),
mOverscrollBehaviorX(aDisplay->mOverscrollBehaviorX),
mOverscrollBehaviorY(aDisplay->mOverscrollBehaviorY) {}
mOverscrollBehaviorY(aDisplay->mOverscrollBehaviorY) {
InitializeScrollSnapStrictness(aWritingMode, aDisplay);
}
ScrollStyles::ScrollStyles(WritingMode aWritingMode,
const nsStyleDisplay* aDisplay)
: mHorizontal(aDisplay->mOverflowX),
mVertical(aDisplay->mOverflowY),
mOverscrollBehaviorX(aDisplay->mOverscrollBehaviorX),
mOverscrollBehaviorY(aDisplay->mOverscrollBehaviorY) {}
mOverscrollBehaviorY(aDisplay->mOverscrollBehaviorY) {
InitializeScrollSnapStrictness(aWritingMode, aDisplay);
}
} // namespace mozilla

View File

@ -16,31 +16,37 @@ struct nsStyleDisplay;
namespace mozilla {
// NOTE: Only styles that are propagated from the <body> should end up in this
// class.
struct ScrollStyles {
// Always one of Scroll, Hidden, or Auto
StyleOverflow mHorizontal;
StyleOverflow mVertical;
// FIXME(emilio): we shouldn't propagate this.
// Always one of NS_STYLE_SCROLL_BEHAVIOR_AUTO or
// NS_STYLE_SCROLL_BEHAVIOR_SMOOTH
StyleOverscrollBehavior mOverscrollBehaviorX;
StyleOverscrollBehavior mOverscrollBehaviorY;
StyleScrollSnapStrictness mScrollSnapStrictnessX;
StyleScrollSnapStrictness mScrollSnapStrictnessY;
ScrollStyles(StyleOverflow aH, StyleOverflow aV)
: mHorizontal(aH),
mVertical(aV),
mOverscrollBehaviorX(StyleOverscrollBehavior::Auto),
mOverscrollBehaviorY(StyleOverscrollBehavior::Auto) {}
mOverscrollBehaviorY(StyleOverscrollBehavior::Auto),
mScrollSnapStrictnessX(StyleScrollSnapStrictness::None),
mScrollSnapStrictnessY(StyleScrollSnapStrictness::None) {}
ScrollStyles(WritingMode aWritingMode, const nsStyleDisplay* aDisplay);
ScrollStyles(WritingMode aWritingMode, StyleOverflow aH, StyleOverflow aV,
const nsStyleDisplay* aDisplay);
void InitializeScrollSnapStrictness(WritingMode aWritingMode,
const nsStyleDisplay* aDisplay);
bool operator==(const ScrollStyles& aStyles) const {
return aStyles.mHorizontal == mHorizontal &&
aStyles.mVertical == mVertical &&
aStyles.mOverscrollBehaviorX == mOverscrollBehaviorX &&
aStyles.mOverscrollBehaviorY == mOverscrollBehaviorY;
aStyles.mOverscrollBehaviorY == mOverscrollBehaviorY &&
aStyles.mScrollSnapStrictnessX == mScrollSnapStrictnessX &&
aStyles.mScrollSnapStrictnessY == mScrollSnapStrictnessY;
}
bool operator!=(const ScrollStyles& aStyles) const {
return !(*this == aStyles);

View File

@ -26,6 +26,10 @@ class CalcSnapPoints final {
const nsPoint& aDestination, const nsPoint& aStartPos);
void AddHorizontalEdge(nscoord aEdge);
void AddVerticalEdge(nscoord aEdge);
void AddHorizontalEdgeInterval(const nsRect& aScrollRange, nscoord aInterval,
nscoord aOffset);
void AddVerticalEdgeInterval(const nsRect& aScrollRange, nscoord aInterval,
nscoord aOffset);
void AddEdge(nscoord aEdge, nscoord aDestination, nscoord aStartPos,
nscoord aScrollingDirection, nscoord* aBestEdge,
nscoord* aSecondBestEdge, bool* aEdgeFound);
@ -98,6 +102,22 @@ void CalcSnapPoints::AddVerticalEdge(nscoord aEdge) {
&mBestEdge.x, &mSecondBestEdge.x, &mVerticalEdgeFound);
}
void CalcSnapPoints::AddHorizontalEdgeInterval(const nsRect& aScrollRange,
nscoord aInterval,
nscoord aOffset) {
AddEdgeInterval(aInterval, aScrollRange.y, aScrollRange.YMost(), aOffset,
mDestination.y, mStartPos.y, mScrollingDirection.y,
&mBestEdge.y, &mSecondBestEdge.y, &mHorizontalEdgeFound);
}
void CalcSnapPoints::AddVerticalEdgeInterval(const nsRect& aScrollRange,
nscoord aInterval,
nscoord aOffset) {
AddEdgeInterval(aInterval, aScrollRange.x, aScrollRange.XMost(), aOffset,
mDestination.x, mStartPos.x, mScrollingDirection.x,
&mBestEdge.x, &mSecondBestEdge.x, &mVerticalEdgeFound);
}
void CalcSnapPoints::AddEdge(nscoord aEdge, nscoord aDestination,
nscoord aStartPos, nscoord aScrollingDirection,
nscoord* aBestEdge, nscoord* aSecondBestEdge,
@ -238,6 +258,19 @@ static void ProcessSnapPositions(CalcSnapPoints& aCalcSnapPoints,
}
}
static void ProcessScrollSnapCoordinates(
CalcSnapPoints& aCalcSnapPoint,
const nsTArray<nsPoint>& aScrollSnapCoordinates,
const nsPoint& aScrollSnapDestination) {
for (nsPoint snapCoords : aScrollSnapCoordinates) {
// Make them relative to the scroll snap destination.
snapCoords -= aScrollSnapDestination;
aCalcSnapPoint.AddVerticalEdge(snapCoords.x);
aCalcSnapPoint.AddHorizontalEdge(snapCoords.y);
}
}
Maybe<nsPoint> ScrollSnapUtils::GetSnapPointForDestination(
const ScrollSnapInfo& aSnapInfo, nsIScrollableFrame::ScrollUnit aUnit,
const nsRect& aScrollRange, const nsPoint& aStartPos,
@ -247,37 +280,55 @@ Maybe<nsPoint> ScrollSnapUtils::GetSnapPointForDestination(
return Nothing();
}
if (!aSnapInfo.HasSnapPositions()) {
if (StaticPrefs::layout_css_scroll_snap_v1_enabled() &&
!aSnapInfo.HasSnapPositions()) {
return Nothing();
}
CalcSnapPoints calcSnapPoints(aUnit, aDestination, aStartPos);
ProcessSnapPositions(calcSnapPoints, aSnapInfo);
if (StaticPrefs::layout_css_scroll_snap_v1_enabled()) {
ProcessSnapPositions(calcSnapPoints, aSnapInfo);
// If the distance between the first and the second candidate snap points
// is larger than the snapport size and the snapport is covered by larger
// elements, any points inside the covering area should be valid snap
// points.
// https://drafts.csswg.org/css-scroll-snap-1/#snap-overflow
// NOTE: |aDestination| sometimes points outside of the scroll range, e.g.
// by the APZC fling, so for the overflow checks we need to clamp it.
nsPoint clampedDestination = aScrollRange.ClampPoint(aDestination);
for (auto range : aSnapInfo.mXRangeWiderThanSnapport) {
if (range.IsValid(clampedDestination.x, aSnapInfo.mSnapportSize.width) &&
calcSnapPoints.XDistanceBetweenBestAndSecondEdge() >
aSnapInfo.mSnapportSize.width) {
calcSnapPoints.AddVerticalEdge(clampedDestination.x);
break;
// If the distance between the first and the second candidate snap points
// is larger than the snapport size and the snapport is covered by larger
// elements, any points inside the covering area should be valid snap
// points.
// https://drafts.csswg.org/css-scroll-snap-1/#snap-overflow
// NOTE: |aDestination| sometimes points outside of the scroll range, e.g.
// by the APZC fling, so for the overflow checks we need to clamp it.
nsPoint clampedDestination = aScrollRange.ClampPoint(aDestination);
for (auto range : aSnapInfo.mXRangeWiderThanSnapport) {
if (range.IsValid(clampedDestination.x, aSnapInfo.mSnapportSize.width) &&
calcSnapPoints.XDistanceBetweenBestAndSecondEdge() >
aSnapInfo.mSnapportSize.width) {
calcSnapPoints.AddVerticalEdge(clampedDestination.x);
break;
}
}
}
for (auto range : aSnapInfo.mYRangeWiderThanSnapport) {
if (range.IsValid(clampedDestination.y, aSnapInfo.mSnapportSize.height) &&
calcSnapPoints.YDistanceBetweenBestAndSecondEdge() >
aSnapInfo.mSnapportSize.height) {
calcSnapPoints.AddHorizontalEdge(clampedDestination.y);
break;
for (auto range : aSnapInfo.mYRangeWiderThanSnapport) {
if (range.IsValid(clampedDestination.y, aSnapInfo.mSnapportSize.height) &&
calcSnapPoints.YDistanceBetweenBestAndSecondEdge() >
aSnapInfo.mSnapportSize.height) {
calcSnapPoints.AddHorizontalEdge(clampedDestination.y);
break;
}
}
} else {
nsPoint destPos = aSnapInfo.mScrollSnapDestination;
if (aSnapInfo.mScrollSnapIntervalX.isSome()) {
nscoord interval = aSnapInfo.mScrollSnapIntervalX.value();
calcSnapPoints.AddVerticalEdgeInterval(aScrollRange, interval, destPos.x);
}
if (aSnapInfo.mScrollSnapIntervalY.isSome()) {
nscoord interval = aSnapInfo.mScrollSnapIntervalY.value();
calcSnapPoints.AddHorizontalEdgeInterval(aScrollRange, interval,
destPos.y);
}
ProcessScrollSnapCoordinates(calcSnapPoints,
aSnapInfo.mScrollSnapCoordinates, destPos);
}
bool snapped = false;

View File

@ -2243,6 +2243,12 @@ void ScrollFrameHelper::ScrollTo(nsPoint aScrollPosition, ScrollMode aMode,
ScrollToWithOrigin(aScrollPosition, aMode, aOrigin, aRange, aSnap);
}
static nsIScrollbarMediator::ScrollSnapMode DefaultSnapMode() {
return StaticPrefs::layout_css_scroll_snap_v1_enabled()
? nsIScrollableFrame::ENABLE_SNAP
: nsIScrollableFrame::DISABLE_SNAP;
}
void ScrollFrameHelper::ScrollToCSSPixels(
const CSSIntPoint& aScrollPosition, ScrollMode aMode,
nsIScrollbarMediator::ScrollSnapMode aSnap, nsAtom* aOrigin) {
@ -2250,7 +2256,7 @@ void ScrollFrameHelper::ScrollToCSSPixels(
CSSIntPoint currentCSSPixels = GetScrollPositionCSSPixels();
nsPoint pt = CSSPoint::ToAppUnits(aScrollPosition);
if (aSnap == nsIScrollableFrame::DEFAULT) {
aSnap = nsIScrollableFrame::ENABLE_SNAP;
aSnap = DefaultSnapMode();
}
if (aOrigin == nullptr) {
@ -4354,7 +4360,7 @@ void ScrollFrameHelper::ScrollByCSSPixels(
nsPoint pt = CSSPoint::ToAppUnits(currentCSSPixels + aDelta);
if (aSnap == nsIScrollableFrame::DEFAULT) {
aSnap = nsIScrollableFrame::ENABLE_SNAP;
aSnap = DefaultSnapMode();
}
if (aOrigin == nullptr) {
@ -5481,12 +5487,18 @@ nsIFrame* ScrollFrameHelper::GetFrameForStyle() const {
}
bool ScrollFrameHelper::NeedsScrollSnap() const {
nsIFrame* scrollSnapFrame = GetFrameForStyle();
if (!scrollSnapFrame) {
return false;
if (StaticPrefs::layout_css_scroll_snap_v1_enabled()) {
nsIFrame* scrollSnapFrame = GetFrameForStyle();
if (!scrollSnapFrame) {
return false;
}
return scrollSnapFrame->StyleDisplay()->mScrollSnapType.strictness !=
StyleScrollSnapStrictness::None;
}
return scrollSnapFrame->StyleDisplay()->mScrollSnapType.strictness !=
StyleScrollSnapStrictness::None;
ScrollStyles styles = GetScrollStylesFromFrame();
return styles.mScrollSnapStrictnessY != StyleScrollSnapStrictness::None ||
styles.mScrollSnapStrictnessX != StyleScrollSnapStrictness::None;
}
bool ScrollFrameHelper::IsScrollbarOnRight() const {
@ -6847,6 +6859,8 @@ static void CollectScrollPositionsForSnap(
nsIFrame* aFrame, nsIFrame* aScrolledFrame, const nsRect& aScrolledRect,
const nsMargin& aScrollPadding, const Maybe<nsRect>& aSnapport,
WritingMode aWritingModeOnScroller, ScrollSnapInfo& aSnapInfo) {
MOZ_ASSERT(StaticPrefs::layout_css_scroll_snap_v1_enabled());
// Snap positions only affect the nearest ancestor scroll container on the
// element's containing block chain.
nsIScrollableFrame* sf = do_QueryFrame(aFrame);
@ -6929,6 +6943,8 @@ nsMargin ScrollFrameHelper::GetScrollPadding() const {
layers::ScrollSnapInfo ScrollFrameHelper::ComputeScrollSnapInfo(
const Maybe<nsPoint>& aDestination) const {
MOZ_ASSERT(StaticPrefs::layout_css_scroll_snap_v1_enabled());
ScrollSnapInfo result;
nsIFrame* scrollSnapFrame = GetFrameForStyle();
@ -6966,6 +6982,9 @@ layers::ScrollSnapInfo ScrollFrameHelper::ComputeScrollSnapInfo(
layers::ScrollSnapInfo ScrollFrameHelper::GetScrollSnapInfo(
const Maybe<nsPoint>& aDestination) const {
if (!StaticPrefs::layout_css_scroll_snap_v1_enabled()) {
return {};
}
// TODO(botond): Should we cache it?
return ComputeScrollSnapInfo(aDestination);
}

View File

@ -1,2 +1,4 @@
default-preferences pref(layout.css.scroll-snap-v1.enabled,true)
== scroll-margin-on-anchor.html#target scroll-margin-on-anchor-ref.html
== scroll-padding-on-anchor.html#target scroll-padding-on-anchor-ref.html

View File

@ -7189,336 +7189,6 @@ var gCSSProperties = {
other_values: ["smooth"],
invalid_values: ["none", "1px"],
},
"scroll-snap-type": {
domProp: "scrollSnapType",
inherited: false,
type: CSS_TYPE_LONGHAND,
initial_values: ["none"],
other_values: [
"both mandatory",
"y mandatory",
"inline proximity",
"both",
"x",
"y",
"block",
"inline",
],
invalid_values: [
"auto",
"1px",
"x y",
"block mandatory inline",
"mandatory",
"proximity",
"mandatory inline",
"proximity both",
"mandatory x",
"proximity y",
"mandatory block",
"proximity mandatory",
],
},
"scroll-snap-align": {
domProp: "scrollSnapAlign",
inherited: false,
type: CSS_TYPE_LONGHAND,
initial_values: ["none"],
other_values: [
"start",
"end",
"center",
"start none",
"center end",
"start start",
],
invalid_values: ["auto", "start invalid", "start end center"],
},
"scroll-margin": {
domProp: "scrollMargin",
inherited: false,
type: CSS_TYPE_TRUE_SHORTHAND,
subproperties: [
"scroll-margin-top",
"scroll-margin-right",
"scroll-margin-bottom",
"scroll-margin-left",
],
initial_values: ["0"],
other_values: [
"-10px",
"calc(2em + 3ex)",
"1px 2px",
"1px 2px 3px",
"1px 2px 3px 4px",
],
invalid_values: ["auto", "20%", "-30%", "1px 2px 3px 4px 5px"],
},
"scroll-margin-top": {
domProp: "scrollMarginTop",
inherited: false,
type: CSS_TYPE_LONGHAND,
initial_values: ["0"],
other_values: ["-10px", "calc(2em + 3ex)"],
invalid_values: ["auto", "20%", "-30%", "1px 2px"],
},
"scroll-margin-right": {
domProp: "scrollMarginRight",
inherited: false,
type: CSS_TYPE_LONGHAND,
initial_values: ["0"],
other_values: ["-10px", "calc(2em + 3ex)"],
invalid_values: ["auto", "20%", "-30%", "1px 2px"],
},
"scroll-margin-bottom": {
domProp: "scrollMarginBottom",
inherited: false,
type: CSS_TYPE_LONGHAND,
initial_values: ["0"],
other_values: ["-10px", "calc(2em + 3ex)"],
invalid_values: ["auto", "20%", "-30%", "1px 2px"],
},
"scroll-margin-left": {
domProp: "scrollMarginLeft",
inherited: false,
type: CSS_TYPE_LONGHAND,
initial_values: ["0"],
other_values: ["-10px", "calc(2em + 3ex)"],
invalid_values: ["auto", "20%", "-30%", "1px 2px"],
},
"scroll-margin-inline": {
domProp: "scrollMarginInline",
inherited: false,
type: CSS_TYPE_TRUE_SHORTHAND,
subproperties: ["scroll-margin-inline-start", "scroll-margin-inline-end"],
initial_values: ["0"],
other_values: ["-10px", "calc(2em + 3ex)", "1px 2px"],
invalid_values: ["auto", "20%", "-30%", "1px 2px 3px"],
},
"scroll-margin-inline-start": {
domProp: "scrollMarginInlineStart",
inherited: false,
type: CSS_TYPE_LONGHAND,
logical: true,
initial_values: ["0"],
other_values: ["-10px", "calc(2em + 3ex)"],
invalid_values: ["auto", "20%", "-30%", "1px 2px"],
},
"scroll-margin-inline-end": {
domProp: "scrollMarginInlineEnd",
inherited: false,
type: CSS_TYPE_LONGHAND,
logical: true,
initial_values: ["0"],
other_values: ["-10px", "calc(2em + 3ex)"],
invalid_values: ["auto", "20%", "-30%", "1px 2px"],
},
"scroll-margin-block": {
domProp: "scrollMarginBlock",
inherited: false,
type: CSS_TYPE_TRUE_SHORTHAND,
subproperties: ["scroll-margin-block-start", "scroll-margin-block-end"],
initial_values: ["0"],
other_values: ["-10px", "calc(2em + 3ex)", "1px 2px"],
invalid_values: ["auto", "20%", "-30%", "1px 2px 3px"],
},
"scroll-margin-block-start": {
domProp: "scrollMarginBlockStart",
inherited: false,
type: CSS_TYPE_LONGHAND,
logical: true,
initial_values: ["0"],
other_values: ["-10px", "calc(2em + 3ex)"],
invalid_values: ["auto", "20%", "-30%", "1px 2px"],
},
"scroll-margin-block-end": {
domProp: "scrollMarginBlockEnd",
inherited: false,
type: CSS_TYPE_LONGHAND,
logical: true,
initial_values: ["0"],
other_values: ["-10px", "calc(2em + 3ex)"],
invalid_values: ["auto", "20%", "-30%", "1px 2px"],
},
"scroll-padding": {
domProp: "scrollPadding",
inherited: false,
type: CSS_TYPE_TRUE_SHORTHAND,
subproperties: [
"scroll-padding-top",
"scroll-padding-right",
"scroll-padding-bottom",
"scroll-padding-left",
],
initial_values: ["auto"],
other_values: [
"10px",
"0",
"20%",
"calc(2em + 3ex)",
"1px 2px",
"1px 2px 3%",
"1px 2px 3% 4px",
"1px auto",
],
invalid_values: ["20", "-20px"],
},
"scroll-padding-top": {
domProp: "scrollPaddingTop",
inherited: false,
type: CSS_TYPE_LONGHAND,
initial_values: ["auto"],
other_values: [
"0",
"10px",
"20%",
"calc(2em + 3ex)",
"calc(50% + 60px)",
"calc(-50px)",
],
invalid_values: ["20", "-20px"],
},
"scroll-padding-right": {
domProp: "scrollPaddingRight",
inherited: false,
type: CSS_TYPE_LONGHAND,
initial_values: ["auto"],
other_values: [
"0",
"10px",
"20%",
"calc(2em + 3ex)",
"calc(50% + 60px)",
"calc(-50px)",
],
invalid_values: ["20", "-20px"],
},
"scroll-padding-bottom": {
domProp: "scrollPaddingBottom",
inherited: false,
type: CSS_TYPE_LONGHAND,
initial_values: ["auto"],
other_values: [
"0",
"10px",
"20%",
"calc(2em + 3ex)",
"calc(50% + 60px)",
"calc(-50px)",
],
invalid_values: ["20", "-20px"],
},
"scroll-padding-left": {
domProp: "scrollPaddingLeft",
inherited: false,
type: CSS_TYPE_LONGHAND,
initial_values: ["auto"],
other_values: [
"0",
"10px",
"20%",
"calc(2em + 3ex)",
"calc(50% + 60px)",
"calc(-50px)",
],
invalid_values: ["20", "-20px"],
},
"scroll-padding-inline": {
domProp: "scrollPaddingInline",
inherited: false,
type: CSS_TYPE_TRUE_SHORTHAND,
subproperties: ["scroll-padding-inline-start", "scroll-padding-inline-end"],
initial_values: ["auto", "auto auto"],
other_values: [
"10px",
"0",
"20%",
"calc(2em + 3ex)",
"1px 2px",
"1px auto",
],
invalid_values: ["20", "-20px"],
},
"scroll-padding-inline-start": {
domProp: "scrollPaddingInlineStart",
inherited: false,
type: CSS_TYPE_LONGHAND,
logical: true,
initial_values: ["auto"],
other_values: [
"0",
"10px",
"20%",
"calc(2em + 3ex)",
"calc(50% + 60px)",
"calc(-50px)",
],
invalid_values: ["20", "-20px"],
},
"scroll-padding-inline-end": {
domProp: "scrollPaddingInlineEnd",
inherited: false,
type: CSS_TYPE_LONGHAND,
logical: true,
initial_values: ["auto"],
other_values: [
"0",
"10px",
"20%",
"calc(2em + 3ex)",
"calc(50% + 60px)",
"calc(-50px)",
],
invalid_values: ["20", "-20px"],
},
"scroll-padding-block": {
domProp: "scrollPaddingBlock",
inherited: false,
type: CSS_TYPE_TRUE_SHORTHAND,
subproperties: ["scroll-padding-block-start", "scroll-padding-block-end"],
initial_values: ["auto", "auto auto"],
other_values: [
"10px",
"0",
"20%",
"calc(2em + 3ex)",
"1px 2px",
"1px auto",
],
invalid_values: ["20", "-20px"],
},
"scroll-padding-block-start": {
domProp: "scrollPaddingBlockStart",
inherited: false,
type: CSS_TYPE_LONGHAND,
logical: true,
initial_values: ["auto"],
other_values: [
"0",
"10px",
"20%",
"calc(2em + 3ex)",
"calc(50% + 60px)",
"calc(-50px)",
],
invalid_values: ["20", "-20px"],
},
"scroll-padding-block-end": {
domProp: "scrollPaddingBlockEnd",
inherited: false,
type: CSS_TYPE_LONGHAND,
logical: true,
initial_values: ["auto"],
other_values: [
"0",
"10px",
"20%",
"calc(2em + 3ex)",
"calc(50% + 60px)",
"calc(-50px)",
],
invalid_values: ["20", "-20px"],
},
"table-layout": {
domProp: "tableLayout",
inherited: false,
@ -12423,6 +12093,340 @@ if (IsCSSPropertyPrefEnabled("layout.css.overscroll-behavior.enabled")) {
invalid_values: ["left", "1px", "contain auto none", "contain nonsense"],
};
}
if (IsCSSPropertyPrefEnabled("layout.css.scroll-snap-v1.enabled")) {
gCSSProperties["scroll-snap-type"] = {
domProp: "scrollSnapType",
inherited: false,
type: CSS_TYPE_LONGHAND,
initial_values: ["none"],
other_values: [
"both mandatory",
"y mandatory",
"inline proximity",
"both",
"x",
"y",
"block",
"inline",
],
invalid_values: [
"auto",
"1px",
"x y",
"block mandatory inline",
"mandatory",
"proximity",
"mandatory inline",
"proximity both",
"mandatory x",
"proximity y",
"mandatory block",
"proximity mandatory",
],
};
gCSSProperties["scroll-snap-align"] = {
domProp: "scrollSnapAlign",
inherited: false,
type: CSS_TYPE_LONGHAND,
initial_values: ["none"],
other_values: [
"start",
"end",
"center",
"start none",
"center end",
"start start",
],
invalid_values: ["auto", "start invalid", "start end center"],
};
gCSSProperties["scroll-margin"] = {
domProp: "scrollMargin",
inherited: false,
type: CSS_TYPE_TRUE_SHORTHAND,
subproperties: [
"scroll-margin-top",
"scroll-margin-right",
"scroll-margin-bottom",
"scroll-margin-left",
],
initial_values: ["0"],
other_values: [
"-10px",
"calc(2em + 3ex)",
"1px 2px",
"1px 2px 3px",
"1px 2px 3px 4px",
],
invalid_values: ["auto", "20%", "-30%", "1px 2px 3px 4px 5px"],
};
gCSSProperties["scroll-margin-top"] = {
domProp: "scrollMarginTop",
inherited: false,
type: CSS_TYPE_LONGHAND,
initial_values: ["0"],
other_values: ["-10px", "calc(2em + 3ex)"],
invalid_values: ["auto", "20%", "-30%", "1px 2px"],
};
gCSSProperties["scroll-margin-right"] = {
domProp: "scrollMarginRight",
inherited: false,
type: CSS_TYPE_LONGHAND,
initial_values: ["0"],
other_values: ["-10px", "calc(2em + 3ex)"],
invalid_values: ["auto", "20%", "-30%", "1px 2px"],
};
gCSSProperties["scroll-margin-bottom"] = {
domProp: "scrollMarginBottom",
inherited: false,
type: CSS_TYPE_LONGHAND,
initial_values: ["0"],
other_values: ["-10px", "calc(2em + 3ex)"],
invalid_values: ["auto", "20%", "-30%", "1px 2px"],
};
gCSSProperties["scroll-margin-left"] = {
domProp: "scrollMarginLeft",
inherited: false,
type: CSS_TYPE_LONGHAND,
initial_values: ["0"],
other_values: ["-10px", "calc(2em + 3ex)"],
invalid_values: ["auto", "20%", "-30%", "1px 2px"],
};
gCSSProperties["scroll-margin-inline"] = {
domProp: "scrollMarginInline",
inherited: false,
type: CSS_TYPE_TRUE_SHORTHAND,
subproperties: ["scroll-margin-inline-start", "scroll-margin-inline-end"],
initial_values: ["0"],
other_values: ["-10px", "calc(2em + 3ex)", "1px 2px"],
invalid_values: ["auto", "20%", "-30%", "1px 2px 3px"],
};
gCSSProperties["scroll-margin-inline-start"] = {
domProp: "scrollMarginInlineStart",
inherited: false,
type: CSS_TYPE_LONGHAND,
logical: true,
initial_values: ["0"],
other_values: ["-10px", "calc(2em + 3ex)"],
invalid_values: ["auto", "20%", "-30%", "1px 2px"],
};
gCSSProperties["scroll-margin-inline-end"] = {
domProp: "scrollMarginInlineEnd",
inherited: false,
type: CSS_TYPE_LONGHAND,
logical: true,
initial_values: ["0"],
other_values: ["-10px", "calc(2em + 3ex)"],
invalid_values: ["auto", "20%", "-30%", "1px 2px"],
};
gCSSProperties["scroll-margin-block"] = {
domProp: "scrollMarginBlock",
inherited: false,
type: CSS_TYPE_TRUE_SHORTHAND,
subproperties: ["scroll-margin-block-start", "scroll-margin-block-end"],
initial_values: ["0"],
other_values: ["-10px", "calc(2em + 3ex)", "1px 2px"],
invalid_values: ["auto", "20%", "-30%", "1px 2px 3px"],
};
gCSSProperties["scroll-margin-block-start"] = {
domProp: "scrollMarginBlockStart",
inherited: false,
type: CSS_TYPE_LONGHAND,
logical: true,
initial_values: ["0"],
other_values: ["-10px", "calc(2em + 3ex)"],
invalid_values: ["auto", "20%", "-30%", "1px 2px"],
};
gCSSProperties["scroll-margin-block-end"] = {
domProp: "scrollMarginBlockEnd",
inherited: false,
type: CSS_TYPE_LONGHAND,
logical: true,
initial_values: ["0"],
other_values: ["-10px", "calc(2em + 3ex)"],
invalid_values: ["auto", "20%", "-30%", "1px 2px"],
};
gCSSProperties["scroll-padding"] = {
domProp: "scrollPadding",
inherited: false,
type: CSS_TYPE_TRUE_SHORTHAND,
subproperties: [
"scroll-padding-top",
"scroll-padding-right",
"scroll-padding-bottom",
"scroll-padding-left",
],
initial_values: ["auto"],
other_values: [
"10px",
"0",
"20%",
"calc(2em + 3ex)",
"1px 2px",
"1px 2px 3%",
"1px 2px 3% 4px",
"1px auto",
],
invalid_values: ["20", "-20px"],
};
gCSSProperties["scroll-padding-top"] = {
domProp: "scrollPaddingTop",
inherited: false,
type: CSS_TYPE_LONGHAND,
initial_values: ["auto"],
other_values: [
"0",
"10px",
"20%",
"calc(2em + 3ex)",
"calc(50% + 60px)",
"calc(-50px)",
],
invalid_values: ["20", "-20px"],
};
gCSSProperties["scroll-padding-right"] = {
domProp: "scrollPaddingRight",
inherited: false,
type: CSS_TYPE_LONGHAND,
initial_values: ["auto"],
other_values: [
"0",
"10px",
"20%",
"calc(2em + 3ex)",
"calc(50% + 60px)",
"calc(-50px)",
],
invalid_values: ["20", "-20px"],
};
gCSSProperties["scroll-padding-bottom"] = {
domProp: "scrollPaddingBottom",
inherited: false,
type: CSS_TYPE_LONGHAND,
initial_values: ["auto"],
other_values: [
"0",
"10px",
"20%",
"calc(2em + 3ex)",
"calc(50% + 60px)",
"calc(-50px)",
],
invalid_values: ["20", "-20px"],
};
gCSSProperties["scroll-padding-left"] = {
domProp: "scrollPaddingLeft",
inherited: false,
type: CSS_TYPE_LONGHAND,
initial_values: ["auto"],
other_values: [
"0",
"10px",
"20%",
"calc(2em + 3ex)",
"calc(50% + 60px)",
"calc(-50px)",
],
invalid_values: ["20", "-20px"],
};
gCSSProperties["scroll-padding-inline"] = {
domProp: "scrollPaddingInline",
inherited: false,
type: CSS_TYPE_TRUE_SHORTHAND,
subproperties: ["scroll-padding-inline-start", "scroll-padding-inline-end"],
initial_values: ["auto", "auto auto"],
other_values: [
"10px",
"0",
"20%",
"calc(2em + 3ex)",
"1px 2px",
"1px auto",
],
invalid_values: ["20", "-20px"],
};
gCSSProperties["scroll-padding-inline-start"] = {
domProp: "scrollPaddingInlineStart",
inherited: false,
type: CSS_TYPE_LONGHAND,
logical: true,
initial_values: ["auto"],
other_values: [
"0",
"10px",
"20%",
"calc(2em + 3ex)",
"calc(50% + 60px)",
"calc(-50px)",
],
invalid_values: ["20", "-20px"],
};
gCSSProperties["scroll-padding-inline-end"] = {
domProp: "scrollPaddingInlineEnd",
inherited: false,
type: CSS_TYPE_LONGHAND,
logical: true,
initial_values: ["auto"],
other_values: [
"0",
"10px",
"20%",
"calc(2em + 3ex)",
"calc(50% + 60px)",
"calc(-50px)",
],
invalid_values: ["20", "-20px"],
};
gCSSProperties["scroll-padding-block"] = {
domProp: "scrollPaddingBlock",
inherited: false,
type: CSS_TYPE_TRUE_SHORTHAND,
subproperties: ["scroll-padding-block-start", "scroll-padding-block-end"],
initial_values: ["auto", "auto auto"],
other_values: [
"10px",
"0",
"20%",
"calc(2em + 3ex)",
"1px 2px",
"1px auto",
],
invalid_values: ["20", "-20px"],
};
gCSSProperties["scroll-padding-block-start"] = {
domProp: "scrollPaddingBlockStart",
inherited: false,
type: CSS_TYPE_LONGHAND,
logical: true,
initial_values: ["auto"],
other_values: [
"0",
"10px",
"20%",
"calc(2em + 3ex)",
"calc(50% + 60px)",
"calc(-50px)",
],
invalid_values: ["20", "-20px"],
};
gCSSProperties["scroll-padding-block-end"] = {
domProp: "scrollPaddingBlockEnd",
inherited: false,
type: CSS_TYPE_LONGHAND,
logical: true,
initial_values: ["auto"],
other_values: [
"0",
"10px",
"20%",
"calc(2em + 3ex)",
"calc(50% + 60px)",
"calc(-50px)",
],
invalid_values: ["20", "-20px"],
};
}
if (IsCSSPropertyPrefEnabled("layout.css.webkit-appearance.enabled")) {
gCSSProperties["-webkit-appearance"] = {
domProp: "webkitAppearance",

View File

@ -324,34 +324,6 @@ var supported_properties = {
test_currentcolor_transition ],
"text-underline-offset": [ test_length_transition ],
"text-decoration-thickness": [ test_length_transition ],
"scroll-margin-top": [
test_length_transition,
],
"scroll-margin-right": [
test_length_transition,
],
"scroll-margin-bottom": [
test_length_transition,
],
"scroll-margin-left": [
test_length_transition,
],
"scroll-padding-top": [
test_length_transition, test_percent_transition,
test_length_clamped, test_percent_clamped,
],
"scroll-padding-right": [
test_length_transition, test_percent_transition,
test_length_clamped, test_percent_clamped,
],
"scroll-padding-bottom": [
test_length_transition, test_percent_transition,
test_length_clamped, test_percent_clamped,
],
"scroll-padding-left": [
test_length_transition, test_percent_transition,
test_length_clamped, test_percent_clamped,
],
};
if (IsCSSPropertyPrefEnabled("layout.css.motion-path.enabled")) {
@ -429,6 +401,37 @@ if (IsCSSPropertyPrefEnabled("layout.css.scrollbar-color.enabled")) {
];
}
if (IsCSSPropertyPrefEnabled("layout.css.scroll-snap-v1.enabled")) {
supported_properties["scroll-margin-top"] = [
test_length_transition,
];
supported_properties["scroll-margin-right"] = [
test_length_transition,
];
supported_properties["scroll-margin-bottom"] = [
test_length_transition,
];
supported_properties["scroll-margin-left"] = [
test_length_transition,
];
supported_properties["scroll-padding-top"] = [
test_length_transition, test_percent_transition,
test_length_clamped, test_percent_clamped,
];
supported_properties["scroll-padding-right"] = [
test_length_transition, test_percent_transition,
test_length_clamped, test_percent_clamped,
];
supported_properties["scroll-padding-bottom"] = [
test_length_transition, test_percent_transition,
test_length_clamped, test_percent_clamped,
];
supported_properties["scroll-padding-left"] = [
test_length_transition, test_percent_transition,
test_length_clamped, test_percent_clamped,
];
}
// For properties which are well-tested by web-platform-tests, we don't need to
// test animations/transitions again on them.
var skipped_transitionable_properties = [
@ -446,8 +449,10 @@ for (const logical_side of ["inline-start", "inline-end", "block-start", "block-
supported_properties["margin-" + logical_side] = supported_properties["margin-top"];
supported_properties["padding-" + logical_side] = supported_properties["padding-top"];
supported_properties["inset-" + logical_side] = supported_properties["top"];
supported_properties["scroll-margin-" + logical_side] = supported_properties["scroll-margin-top"];
supported_properties["scroll-padding-" + logical_side] = supported_properties["scroll-padding-top"];
if (IsCSSPropertyPrefEnabled("layout.css.scroll-snap-v1.enabled")) {
supported_properties["scroll-margin-" + logical_side] = supported_properties["scroll-margin-top"];
supported_properties["scroll-padding-" + logical_side] = supported_properties["scroll-padding-top"];
}
}
for (const logical_size of ["inline", "block"]) {

View File

@ -5240,6 +5240,19 @@
value: false
mirror: always
# Is the CSS Scroll Snap Module Level 1 enabled?
- name: layout.css.scroll-snap-v1.enabled
type: RelaxedAtomicBool
value: true
mirror: always
# Is support for the old unspecced scroll-snap enabled?
# E.g. scroll-snap-points-{x,y}, scroll-snap-coordinate, etc.
- name: layout.css.scroll-snap.enabled
type: bool
value: false
mirror: always
# Are shared memory User Agent style sheets enabled?
- name: layout.css.shared-memory-ua-sheets.enabled
type: bool

View File

@ -454,6 +454,7 @@ ${helpers.predefined_type(
"ScrollSnapAlign",
"computed::ScrollSnapAlign::none()",
engines="gecko",
gecko_pref="layout.css.scroll-snap-v1.enabled",
spec="https://drafts.csswg.org/css-scroll-snap-1/#scroll-snap-align",
animation_value_type="discrete",
)}

View File

@ -35,6 +35,7 @@
"Length",
"computed::Length::zero()",
engines="gecko",
gecko_pref="layout.css.scroll-snap-v1.enabled",
logical=side[1],
logical_group="scroll-margin",
spec="https://drafts.csswg.org/css-scroll-snap-1/#propdef-scroll-margin-%s" % side[0],

View File

@ -34,6 +34,7 @@
"NonNegativeLengthPercentageOrAuto",
"computed::NonNegativeLengthPercentageOrAuto::auto()",
engines="gecko",
gecko_pref="layout.css.scroll-snap-v1.enabled",
logical=side[1],
logical_group="scroll-padding",
spec="https://drafts.csswg.org/css-scroll-snap-1/#propdef-scroll-padding-%s" % side[0],

View File

@ -38,6 +38,7 @@ ${helpers.four_sides_shorthand(
"specified::Length::parse",
engines="gecko",
spec="https://drafts.csswg.org/css-scroll-snap-1/#propdef-scroll-margin",
gecko_pref="layout.css.scroll-snap-v1.enabled",
)}
${helpers.two_properties_shorthand(
@ -47,6 +48,7 @@ ${helpers.two_properties_shorthand(
"specified::Length::parse",
engines="gecko",
spec="https://drafts.csswg.org/css-scroll-snap-1/#propdef-scroll-margin-block",
gecko_pref="layout.css.scroll-snap-v1.enabled",
)}
${helpers.two_properties_shorthand(
@ -56,4 +58,5 @@ ${helpers.two_properties_shorthand(
"specified::Length::parse",
engines="gecko",
spec="https://drafts.csswg.org/css-scroll-snap-1/#propdef-scroll-margin-inline",
gecko_pref="layout.css.scroll-snap-v1.enabled",
)}

View File

@ -36,6 +36,7 @@ ${helpers.four_sides_shorthand(
"scroll-padding-%s",
"specified::NonNegativeLengthPercentageOrAuto::parse",
engines="gecko",
gecko_pref="layout.css.scroll-snap-v1.enabled",
spec="https://drafts.csswg.org/css-scroll-snap-1/#propdef-scroll-padding"
)}
@ -45,6 +46,7 @@ ${helpers.two_properties_shorthand(
"scroll-padding-block-end",
"specified::NonNegativeLengthPercentageOrAuto::parse",
engines="gecko",
gecko_pref="layout.css.scroll-snap-v1.enabled",
spec="https://drafts.csswg.org/css-scroll-snap-1/#propdef-scroll-padding-block"
)}
@ -54,6 +56,7 @@ ${helpers.two_properties_shorthand(
"scroll-padding-inline-end",
"specified::NonNegativeLengthPercentageOrAuto::parse",
engines="gecko",
gecko_pref="layout.css.scroll-snap-v1.enabled",
spec="https://drafts.csswg.org/css-scroll-snap-1/#propdef-scroll-padding-inline"
)}

View File

@ -0,0 +1 @@
prefs: [layout.css.scroll-snap-v1.enabled:true]

View File

@ -0,0 +1 @@
prefs: [layout.css.scroll-snap-v1.enabled:true]