Bug 1523071 - Use Rust lengths for margin / padding / inset. r=jwatt
Also for the intersection observer root margin, since it was easier to fix it up and clean it up than not doing it. This is the first big step to get rid of nscoord. It duplicates a bit of logic in nsLayoutUtils since for now max/min-width/height are still represented with nsStyleCoord, but I think I prefer to land this incrementally. I didn't add helpers for the physical accessors of the style rect sides that nsStyleSides has (top/bottom/left/right) since I think we generally should encourage the logical versions, but let me know if you want me to do that. Differential Revision: https://phabricator.services.mozilla.com/D17739
This commit is contained in:
@@ -285,9 +285,8 @@ void DOMIntersectionObserver::Update(Document* aDocument,
|
||||
NS_FOR_CSS_SIDES(side) {
|
||||
nscoord basis = side == eSideTop || side == eSideBottom ? rootRect.Height()
|
||||
: rootRect.Width();
|
||||
nsStyleCoord coord = mRootMargin.Get(side);
|
||||
rootMargin.Side(side) =
|
||||
nsLayoutUtils::ComputeCBDependentValue(basis, coord);
|
||||
nsLayoutUtils::ComputeCBDependentValue(basis, mRootMargin.Get(side));
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < mObservationTargets.Length(); ++i) {
|
||||
|
||||
@@ -147,7 +147,7 @@ class DOMIntersectionObserver final : public nsISupports,
|
||||
RefPtr<Document> mDocument;
|
||||
RefPtr<mozilla::dom::IntersectionCallback> mCallback;
|
||||
RefPtr<Element> mRoot;
|
||||
nsStyleSides mRootMargin;
|
||||
StyleRect<LengthPercentage> mRootMargin;
|
||||
nsTArray<double> mThresholds;
|
||||
|
||||
// Holds raw pointers which are explicitly cleared by UnlinkTarget().
|
||||
|
||||
@@ -1761,26 +1761,26 @@ nsIScrollableFrame* nsLayoutUtils::GetScrollableFrameFor(
|
||||
int32_t sides = eSideBitsNone;
|
||||
if (aFixedPosFrame != aViewportFrame) {
|
||||
const nsStylePosition* position = aFixedPosFrame->StylePosition();
|
||||
if (position->mOffset.GetRightUnit() != eStyleUnit_Auto) {
|
||||
if (!position->mOffset.Get(eSideRight).IsAuto()) {
|
||||
sides |= eSideBitsRight;
|
||||
if (position->mOffset.GetLeftUnit() != eStyleUnit_Auto) {
|
||||
if (!position->mOffset.Get(eSideLeft).IsAuto()) {
|
||||
sides |= eSideBitsLeft;
|
||||
anchor.x = anchorRect.x + anchorRect.width / 2.f;
|
||||
} else {
|
||||
anchor.x = anchorRect.XMost();
|
||||
}
|
||||
} else if (position->mOffset.GetLeftUnit() != eStyleUnit_Auto) {
|
||||
} else if (!position->mOffset.Get(eSideLeft).IsAuto()) {
|
||||
sides |= eSideBitsLeft;
|
||||
}
|
||||
if (position->mOffset.GetBottomUnit() != eStyleUnit_Auto) {
|
||||
if (!position->mOffset.Get(eSideBottom).IsAuto()) {
|
||||
sides |= eSideBitsBottom;
|
||||
if (position->mOffset.GetTopUnit() != eStyleUnit_Auto) {
|
||||
if (!position->mOffset.Get(eSideTop).IsAuto()) {
|
||||
sides |= eSideBitsTop;
|
||||
anchor.y = anchorRect.y + anchorRect.height / 2.f;
|
||||
} else {
|
||||
anchor.y = anchorRect.YMost();
|
||||
}
|
||||
} else if (position->mOffset.GetTopUnit() != eStyleUnit_Auto) {
|
||||
} else if (!position->mOffset.Get(eSideTop).IsAuto()) {
|
||||
sides |= eSideBitsTop;
|
||||
}
|
||||
}
|
||||
@@ -4611,6 +4611,15 @@ bool nsLayoutUtils::IsViewportScrollbarFrame(nsIFrame* aFrame) {
|
||||
IsProperAncestorFrame(rootScrolledFrame, aFrame));
|
||||
}
|
||||
|
||||
// Use only for paddings, since it clamps negative calc() to 0.
|
||||
static bool GetAbsoluteCoord(const LengthPercentage& aStyle, nscoord& aResult) {
|
||||
if (!aStyle.ConvertsToLength()) {
|
||||
return false;
|
||||
}
|
||||
aResult = std::max(0, aStyle.ToLength());
|
||||
return true;
|
||||
}
|
||||
|
||||
// Use only for widths/heights (or their min/max), since it clamps
|
||||
// negative calc() results to 0.
|
||||
static bool GetAbsoluteCoord(const nsStyleCoord& aStyle, nscoord& aResult) {
|
||||
@@ -4727,6 +4736,54 @@ static bool GetPercentBSize(const nsStyleCoord& aStyle, nsIFrame* aFrame,
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool GetPercentBSize(const LengthPercentage& aStyle, nsIFrame* aFrame,
|
||||
bool aHorizontalAxis, nscoord& aResult) {
|
||||
if (!aStyle.HasPercent()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// TODO(emilio): Temporary until I convert width / height to Servo too.
|
||||
nsStyleCoord coord;
|
||||
if (aStyle.was_calc) {
|
||||
nscoord length = CSSPixel::ToAppUnits(aStyle.LengthInCSSPixels());
|
||||
float percent = aStyle.Percentage();
|
||||
auto* calc = new nsStyleCoord::Calc();
|
||||
calc->mLength = length;
|
||||
calc->mPercent = percent;
|
||||
calc->mHasPercent = true;
|
||||
coord.SetCalcValue(calc); // Takes ownership.
|
||||
} else {
|
||||
coord.SetPercentValue(aStyle.Percentage());
|
||||
}
|
||||
|
||||
return GetPercentBSize(coord, aFrame, aHorizontalAxis, aResult);
|
||||
}
|
||||
|
||||
// Return true if aStyle can be resolved to a definite value and if so
|
||||
// return that value in aResult.
|
||||
static bool GetDefiniteSize(const LengthPercentage& aStyle, nsIFrame* aFrame,
|
||||
bool aIsInlineAxis,
|
||||
const Maybe<LogicalSize>& aPercentageBasis,
|
||||
nscoord* aResult) {
|
||||
if (aStyle.ConvertsToLength()) {
|
||||
*aResult = aStyle.ToLength();
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!aPercentageBasis) {
|
||||
return false;
|
||||
}
|
||||
|
||||
auto wm = aFrame->GetWritingMode();
|
||||
nscoord pb = aIsInlineAxis ? aPercentageBasis.value().ISize(wm)
|
||||
: aPercentageBasis.value().BSize(wm);
|
||||
if (pb == NS_UNCONSTRAINEDSIZE) {
|
||||
return false;
|
||||
}
|
||||
*aResult = std::max(0, aStyle.Resolve(pb));
|
||||
return true;
|
||||
}
|
||||
|
||||
// Return true if aStyle can be resolved to a definite value and if so
|
||||
// return that value in aResult.
|
||||
static bool GetDefiniteSize(const nsStyleCoord& aStyle, nsIFrame* aFrame,
|
||||
@@ -4795,10 +4852,10 @@ static nscoord GetBSizeTakenByBoxSizing(StyleBoxSizing aBoxSizing,
|
||||
? styleBorder->GetComputedBorder().TopBottom()
|
||||
: styleBorder->GetComputedBorder().LeftRight();
|
||||
if (!aIgnorePadding) {
|
||||
const nsStyleSides& stylePadding = aFrame->StylePadding()->mPadding;
|
||||
const nsStyleCoord& paddingStart =
|
||||
const auto& stylePadding = aFrame->StylePadding()->mPadding;
|
||||
const LengthPercentage& paddingStart =
|
||||
stylePadding.Get(aHorizontalAxis ? eSideTop : eSideLeft);
|
||||
const nsStyleCoord& paddingEnd =
|
||||
const LengthPercentage& paddingEnd =
|
||||
stylePadding.Get(aHorizontalAxis ? eSideBottom : eSideRight);
|
||||
nscoord pad;
|
||||
// XXXbz Calling GetPercentBSize on padding values looks bogus, since
|
||||
@@ -4837,10 +4894,10 @@ static nscoord GetDefiniteSizeTakenByBoxSizing(
|
||||
? styleBorder->GetComputedBorder().LeftRight()
|
||||
: styleBorder->GetComputedBorder().TopBottom();
|
||||
if (!aIgnorePadding) {
|
||||
const nsStyleSides& stylePadding = aFrame->StylePadding()->mPadding;
|
||||
const nsStyleCoord& pStart =
|
||||
const auto& stylePadding = aFrame->StylePadding()->mPadding;
|
||||
const LengthPercentage& pStart =
|
||||
stylePadding.Get(isHorizontalAxis ? eSideLeft : eSideTop);
|
||||
const nsStyleCoord& pEnd =
|
||||
const LengthPercentage& pEnd =
|
||||
stylePadding.Get(isHorizontalAxis ? eSideRight : eSideBottom);
|
||||
nscoord pad;
|
||||
// XXXbz Calling GetPercentBSize on padding values looks bogus, since
|
||||
@@ -5478,24 +5535,8 @@ static void AddStateBitToAncestors(nsIFrame* aFrame, nsFrameState aBit) {
|
||||
return result;
|
||||
}
|
||||
|
||||
/* static */ nscoord nsLayoutUtils::ComputeCBDependentValue(
|
||||
nscoord aPercentBasis, const nsStyleCoord& aCoord) {
|
||||
NS_WARNING_ASSERTION(
|
||||
aPercentBasis != NS_UNCONSTRAINEDSIZE,
|
||||
"have unconstrained width or height; this should only result from very "
|
||||
"large sizes, not attempts at intrinsic size calculation");
|
||||
|
||||
if (aCoord.IsCoordPercentCalcUnit()) {
|
||||
return aCoord.ComputeCoordPercentCalc(aPercentBasis);
|
||||
}
|
||||
NS_ASSERTION(aCoord.GetUnit() == eStyleUnit_None ||
|
||||
aCoord.GetUnit() == eStyleUnit_Auto,
|
||||
"unexpected width value");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* static */ nscoord nsLayoutUtils::ComputeBSizeDependentValue(
|
||||
nscoord aContainingBlockBSize, const nsStyleCoord& aCoord) {
|
||||
nscoord aContainingBlockBSize, const LengthPercentageOrAuto& aCoord) {
|
||||
// XXXldb Some callers explicitly check aContainingBlockBSize
|
||||
// against NS_AUTOHEIGHT *and* unit against eStyleUnit_Percent or
|
||||
// calc()s containing percents before calling this function.
|
||||
@@ -5506,14 +5547,11 @@ static void AddStateBitToAncestors(nsIFrame* aFrame, nsFrameState aBit) {
|
||||
MOZ_ASSERT(NS_AUTOHEIGHT != aContainingBlockBSize || !aCoord.HasPercent(),
|
||||
"unexpected containing block block-size");
|
||||
|
||||
if (aCoord.IsCoordPercentCalcUnit()) {
|
||||
return aCoord.ComputeCoordPercentCalc(aContainingBlockBSize);
|
||||
if (aCoord.IsAuto()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
NS_ASSERTION(aCoord.GetUnit() == eStyleUnit_None ||
|
||||
aCoord.GetUnit() == eStyleUnit_Auto,
|
||||
"unexpected block-size value");
|
||||
return 0;
|
||||
return aCoord.AsLengthPercentage().Resolve(aContainingBlockBSize);
|
||||
}
|
||||
|
||||
/* static */ void nsLayoutUtils::MarkDescendantsDirty(nsIFrame* aSubtreeRoot) {
|
||||
|
||||
@@ -147,6 +147,7 @@ enum class ReparentingDirection {
|
||||
class nsLayoutUtils {
|
||||
typedef mozilla::ComputedStyle ComputedStyle;
|
||||
typedef mozilla::LengthPercentage LengthPercentage;
|
||||
typedef mozilla::LengthPercentageOrAuto LengthPercentageOrAuto;
|
||||
typedef mozilla::dom::DOMRectList DOMRectList;
|
||||
typedef mozilla::layers::Layer Layer;
|
||||
typedef mozilla::layers::StackingContextHelper StackingContextHelper;
|
||||
@@ -1462,16 +1463,29 @@ class nsLayoutUtils {
|
||||
uint32_t aFlags = 0);
|
||||
|
||||
/*
|
||||
* Convert nsStyleCoord to nscoord when percentages depend on the
|
||||
* Convert LengthPercentage to nscoord when percentages depend on the
|
||||
* containing block size.
|
||||
* @param aPercentBasis The width or height of the containing block
|
||||
* (whichever the client wants to use for resolving percentages).
|
||||
*/
|
||||
static nscoord ComputeCBDependentValue(nscoord aPercentBasis,
|
||||
const nsStyleCoord& aCoord);
|
||||
const LengthPercentage& aCoord) {
|
||||
NS_WARNING_ASSERTION(
|
||||
aPercentBasis != NS_UNCONSTRAINEDSIZE,
|
||||
"have unconstrained width or height; this should only result from very "
|
||||
"large sizes, not attempts at intrinsic size calculation");
|
||||
return aCoord.Resolve(aPercentBasis);
|
||||
}
|
||||
static nscoord ComputeCBDependentValue(nscoord aPercentBasis,
|
||||
const LengthPercentageOrAuto& aCoord) {
|
||||
if (aCoord.IsAuto()) {
|
||||
return 0;
|
||||
}
|
||||
return ComputeCBDependentValue(aPercentBasis, aCoord.AsLengthPercentage());
|
||||
}
|
||||
|
||||
static nscoord ComputeBSizeDependentValue(nscoord aContainingBlockBSize,
|
||||
const nsStyleCoord& aCoord);
|
||||
const LengthPercentageOrAuto&);
|
||||
|
||||
static nscoord ComputeBSizeValue(nscoord aContainingBlockBSize,
|
||||
nscoord aContentEdgeToBoxSizingBoxEdge,
|
||||
@@ -1502,25 +1516,13 @@ class nsLayoutUtils {
|
||||
(aCBBSize == nscoord_MAX && aCoord.HasPercent());
|
||||
}
|
||||
|
||||
static bool IsPaddingZero(const nsStyleCoord& aCoord) {
|
||||
return (aCoord.GetUnit() == eStyleUnit_Coord &&
|
||||
aCoord.GetCoordValue() == 0) ||
|
||||
(aCoord.GetUnit() == eStyleUnit_Percent &&
|
||||
aCoord.GetPercentValue() == 0.0f) ||
|
||||
(aCoord.IsCalcUnit() &&
|
||||
static bool IsPaddingZero(const LengthPercentage& aLength) {
|
||||
// clamp negative calc() to 0
|
||||
aCoord.ComputeCoordPercentCalc(nscoord_MAX) <= 0 &&
|
||||
aCoord.ComputeCoordPercentCalc(0) <= 0);
|
||||
return aLength.Resolve(nscoord_MAX) <= 0 && aLength.Resolve(0) <= 0;
|
||||
}
|
||||
|
||||
static bool IsMarginZero(const nsStyleCoord& aCoord) {
|
||||
return (aCoord.GetUnit() == eStyleUnit_Coord &&
|
||||
aCoord.GetCoordValue() == 0) ||
|
||||
(aCoord.GetUnit() == eStyleUnit_Percent &&
|
||||
aCoord.GetPercentValue() == 0.0f) ||
|
||||
(aCoord.IsCalcUnit() &&
|
||||
aCoord.ComputeCoordPercentCalc(nscoord_MAX) == 0 &&
|
||||
aCoord.ComputeCoordPercentCalc(0) == 0);
|
||||
static bool IsMarginZero(const LengthPercentage& aLength) {
|
||||
return aLength.Resolve(nscoord_MAX) == 0 && aLength.Resolve(0) == 0;
|
||||
}
|
||||
|
||||
static void MarkDescendantsDirty(nsIFrame* aSubtreeRoot);
|
||||
|
||||
@@ -87,11 +87,11 @@ nscoord CSSAlignUtils::AlignJustifySelf(uint8_t aAlignment, LogicalAxis aAxis,
|
||||
// don't need to do anything special to avoid expanding them.)
|
||||
hasAutoMarginStart = hasAutoMarginEnd = false;
|
||||
} else if (aAxis == eLogicalAxisBlock) {
|
||||
hasAutoMarginStart = styleMargin.GetBStartUnit(wm) == eStyleUnit_Auto;
|
||||
hasAutoMarginEnd = styleMargin.GetBEndUnit(wm) == eStyleUnit_Auto;
|
||||
hasAutoMarginStart = styleMargin.GetBStart(wm).IsAuto();
|
||||
hasAutoMarginEnd = styleMargin.GetBEnd(wm).IsAuto();
|
||||
} else { /* aAxis == eLogicalAxisInline */
|
||||
hasAutoMarginStart = styleMargin.GetIStartUnit(wm) == eStyleUnit_Auto;
|
||||
hasAutoMarginEnd = styleMargin.GetIEndUnit(wm) == eStyleUnit_Auto;
|
||||
hasAutoMarginStart = styleMargin.GetIStart(wm).IsAuto();
|
||||
hasAutoMarginEnd = styleMargin.GetIEnd(wm).IsAuto();
|
||||
}
|
||||
|
||||
// https://drafts.csswg.org/css-align-3/#overflow-values
|
||||
|
||||
@@ -732,8 +732,7 @@ void ReflowInput::InitResizeFlags(nsPresContext* aPresContext,
|
||||
mStylePosition->MinBSizeDependsOnContainer(wm) ||
|
||||
mStylePosition->MaxBSizeDependsOnContainer(wm) ||
|
||||
mStylePosition->OffsetHasPercent(wm.PhysicalSide(eLogicalSideBStart)) ||
|
||||
mStylePosition->mOffset.GetBEndUnit(wm) != eStyleUnit_Auto ||
|
||||
mFrame->IsXULBoxFrame();
|
||||
!mStylePosition->mOffset.GetBEnd(wm).IsAuto() || mFrame->IsXULBoxFrame();
|
||||
|
||||
if (mStyleText->mLineHeight.GetUnit() == eStyleUnit_Enumerated) {
|
||||
NS_ASSERTION(mStyleText->mLineHeight.GetIntValue() ==
|
||||
@@ -1016,10 +1015,8 @@ void ReflowInput::InitFrameType(LayoutFrameType aFrameType) {
|
||||
// moves the boxes to the end of the line, and 'inlineEnd' moves the
|
||||
// boxes to the start of the line. The computed values are always:
|
||||
// inlineStart=-inlineEnd
|
||||
bool inlineStartIsAuto =
|
||||
eStyleUnit_Auto == position->mOffset.GetUnit(inlineStart);
|
||||
bool inlineEndIsAuto =
|
||||
eStyleUnit_Auto == position->mOffset.GetUnit(inlineEnd);
|
||||
bool inlineStartIsAuto = position->mOffset.Get(inlineStart).IsAuto();
|
||||
bool inlineEndIsAuto = position->mOffset.Get(inlineEnd).IsAuto();
|
||||
|
||||
// If neither 'inlineStart' nor 'inlineEnd' is auto, then we're
|
||||
// over-constrained and we ignore one of them
|
||||
@@ -1055,9 +1052,8 @@ void ReflowInput::InitFrameType(LayoutFrameType aFrameType) {
|
||||
// and 'blockEnd' properties move relatively positioned elements in
|
||||
// the block progression direction. They also must be each other's
|
||||
// negative
|
||||
bool blockStartIsAuto =
|
||||
eStyleUnit_Auto == position->mOffset.GetUnit(blockStart);
|
||||
bool blockEndIsAuto = eStyleUnit_Auto == position->mOffset.GetUnit(blockEnd);
|
||||
bool blockStartIsAuto = position->mOffset.Get(blockStart).IsAuto();
|
||||
bool blockEndIsAuto = position->mOffset.Get(blockEnd).IsAuto();
|
||||
|
||||
// Check for percentage based values and a containing block block-size
|
||||
// that depends on the content block-size. Treat them like 'auto'
|
||||
@@ -1281,7 +1277,7 @@ void ReflowInput::CalculateBorderPaddingMargin(
|
||||
} else {
|
||||
nscoord start, end;
|
||||
// We have to compute the start and end values
|
||||
if (eStyleUnit_Auto == mStyleMargin->mMargin.GetUnit(startSide)) {
|
||||
if (mStyleMargin->mMargin.Get(startSide).IsAuto()) {
|
||||
// We set this to 0 for now, and fix it up later in
|
||||
// InitAbsoluteConstraints (which is caller of this function, via
|
||||
// CalculateHypotheticalPosition).
|
||||
@@ -1290,7 +1286,7 @@ void ReflowInput::CalculateBorderPaddingMargin(
|
||||
start = nsLayoutUtils::ComputeCBDependentValue(
|
||||
aContainingBlockSize, mStyleMargin->mMargin.Get(startSide));
|
||||
}
|
||||
if (eStyleUnit_Auto == mStyleMargin->mMargin.GetUnit(endSide)) {
|
||||
if (mStyleMargin->mMargin.Get(endSide).IsAuto()) {
|
||||
// We set this to 0 for now, and fix it up later in
|
||||
// InitAbsoluteConstraints (which is caller of this function, via
|
||||
// CalculateHypotheticalPosition).
|
||||
@@ -1643,10 +1639,10 @@ void ReflowInput::InitAbsoluteConstraints(nsPresContext* aPresContext,
|
||||
"Why are we here?");
|
||||
|
||||
const auto& styleOffset = mStylePosition->mOffset;
|
||||
bool iStartIsAuto = styleOffset.GetIStartUnit(cbwm) == eStyleUnit_Auto;
|
||||
bool iEndIsAuto = styleOffset.GetIEndUnit(cbwm) == eStyleUnit_Auto;
|
||||
bool bStartIsAuto = styleOffset.GetBStartUnit(cbwm) == eStyleUnit_Auto;
|
||||
bool bEndIsAuto = styleOffset.GetBEndUnit(cbwm) == eStyleUnit_Auto;
|
||||
bool iStartIsAuto = styleOffset.GetIStart(cbwm).IsAuto();
|
||||
bool iEndIsAuto = styleOffset.GetIEnd(cbwm).IsAuto();
|
||||
bool bStartIsAuto = styleOffset.GetBStart(cbwm).IsAuto();
|
||||
bool bEndIsAuto = styleOffset.GetBEnd(cbwm).IsAuto();
|
||||
|
||||
// If both 'left' and 'right' are 'auto' or both 'top' and 'bottom' are
|
||||
// 'auto', then compute the hypothetical box position where the element would
|
||||
@@ -1886,10 +1882,8 @@ void ReflowInput::InitAbsoluteConstraints(nsPresContext* aPresContext,
|
||||
nscoord availMarginSpace =
|
||||
aCBSize.ISize(cbwm) - offsets.IStartEnd(cbwm) - margin.IStartEnd(cbwm) -
|
||||
borderPadding.IStartEnd(cbwm) - computedSize.ISize(cbwm);
|
||||
marginIStartIsAuto =
|
||||
eStyleUnit_Auto == mStyleMargin->mMargin.GetIStartUnit(cbwm);
|
||||
marginIEndIsAuto =
|
||||
eStyleUnit_Auto == mStyleMargin->mMargin.GetIEndUnit(cbwm);
|
||||
marginIStartIsAuto = mStyleMargin->mMargin.GetIStart(cbwm).IsAuto();
|
||||
marginIEndIsAuto = mStyleMargin->mMargin.GetIEnd(cbwm).IsAuto();
|
||||
|
||||
if (marginIStartIsAuto) {
|
||||
if (marginIEndIsAuto) {
|
||||
@@ -1974,10 +1968,8 @@ void ReflowInput::InitAbsoluteConstraints(nsPresContext* aPresContext,
|
||||
// * we're dealing with a replaced element
|
||||
// * bsize was constrained by min- or max-bsize.
|
||||
nscoord availMarginSpace = autoBSize - computedSize.BSize(cbwm);
|
||||
marginBStartIsAuto =
|
||||
eStyleUnit_Auto == mStyleMargin->mMargin.GetBStartUnit(cbwm);
|
||||
marginBEndIsAuto =
|
||||
eStyleUnit_Auto == mStyleMargin->mMargin.GetBEndUnit(cbwm);
|
||||
marginBStartIsAuto = mStyleMargin->mMargin.GetBStart(cbwm).IsAuto();
|
||||
marginBEndIsAuto = mStyleMargin->mMargin.GetBEnd(cbwm).IsAuto();
|
||||
|
||||
if (marginBStartIsAuto) {
|
||||
if (marginBEndIsAuto) {
|
||||
@@ -2482,8 +2474,8 @@ void ReflowInput::InitConstraints(nsPresContext* aPresContext,
|
||||
: mStylePosition->UsedJustifySelf(alignCB->Style());
|
||||
if ((inlineAxisAlignment != NS_STYLE_ALIGN_STRETCH &&
|
||||
inlineAxisAlignment != NS_STYLE_ALIGN_NORMAL) ||
|
||||
mStyleMargin->mMargin.GetIStartUnit(wm) == eStyleUnit_Auto ||
|
||||
mStyleMargin->mMargin.GetIEndUnit(wm) == eStyleUnit_Auto) {
|
||||
mStyleMargin->mMargin.GetIStart(wm).IsAuto() ||
|
||||
mStyleMargin->mMargin.GetIEnd(wm).IsAuto()) {
|
||||
computeSizeFlags = ComputeSizeFlags(computeSizeFlags |
|
||||
ComputeSizeFlags::eShrinkWrap);
|
||||
}
|
||||
@@ -2747,9 +2739,9 @@ void ReflowInput::CalculateBlockSideMargins(LayoutFrameType aFrameType) {
|
||||
|
||||
// The css2 spec clearly defines how block elements should behave
|
||||
// in section 10.3.3.
|
||||
const nsStyleSides& styleSides = mStyleMargin->mMargin;
|
||||
bool isAutoStartMargin = eStyleUnit_Auto == styleSides.GetIStartUnit(cbWM);
|
||||
bool isAutoEndMargin = eStyleUnit_Auto == styleSides.GetIEndUnit(cbWM);
|
||||
const auto& styleSides = mStyleMargin->mMargin;
|
||||
bool isAutoStartMargin = styleSides.GetIStart(cbWM).IsAuto();
|
||||
bool isAutoEndMargin = styleSides.GetIEnd(cbWM).IsAuto();
|
||||
if (!isAutoStartMargin && !isAutoEndMargin) {
|
||||
// Neither margin is 'auto' so we're over constrained. Use the
|
||||
// 'direction' property of the parent to tell which margin to
|
||||
|
||||
@@ -92,14 +92,14 @@ StickyScrollContainer::GetStickyScrollContainerForScrollFrame(
|
||||
return aFrame->GetProperty(StickyScrollContainerProperty());
|
||||
}
|
||||
|
||||
static nscoord ComputeStickySideOffset(Side aSide, const nsStyleSides& aOffset,
|
||||
static nscoord ComputeStickySideOffset(
|
||||
Side aSide, const StyleRect<LengthPercentageOrAuto>& aOffset,
|
||||
nscoord aPercentBasis) {
|
||||
if (eStyleUnit_Auto == aOffset.GetUnit(aSide)) {
|
||||
auto& side = aOffset.Get(aSide);
|
||||
if (side.IsAuto()) {
|
||||
return NS_AUTOOFFSET;
|
||||
} else {
|
||||
return nsLayoutUtils::ComputeCBDependentValue(aPercentBasis,
|
||||
aOffset.Get(aSide));
|
||||
}
|
||||
return nsLayoutUtils::ComputeCBDependentValue(aPercentBasis, side);
|
||||
}
|
||||
|
||||
// static
|
||||
|
||||
@@ -1896,6 +1896,32 @@ class LogicalRect {
|
||||
nscoord mBSize; // block-size
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
const T& StyleRect<T>::Get(mozilla::WritingMode aWM,
|
||||
mozilla::LogicalSide aSide) const {
|
||||
return Get(aWM.PhysicalSide(aSide));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
const T& StyleRect<T>::GetIStart(mozilla::WritingMode aWM) const {
|
||||
return Get(aWM, mozilla::eLogicalSideIStart);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
const T& StyleRect<T>::GetBStart(mozilla::WritingMode aWM) const {
|
||||
return Get(aWM, mozilla::eLogicalSideBStart);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
const T& StyleRect<T>::GetIEnd(mozilla::WritingMode aWM) const {
|
||||
return Get(aWM, mozilla::eLogicalSideIEnd);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
const T& StyleRect<T>::GetBEnd(mozilla::WritingMode aWM) const {
|
||||
return Get(aWM, mozilla::eLogicalSideBEnd);
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
||||
|
||||
// Definitions of inline methods for nsStyleSides, declared in nsStyleCoord.h
|
||||
@@ -2043,10 +2069,11 @@ inline bool nsStylePosition::MaxBSizeDependsOnContainer(
|
||||
}
|
||||
|
||||
inline bool nsStyleMargin::HasBlockAxisAuto(mozilla::WritingMode aWM) const {
|
||||
return mMargin.HasBlockAxisAuto(aWM);
|
||||
return mMargin.GetBStart(aWM).IsAuto() || mMargin.GetBEnd(aWM).IsAuto();
|
||||
}
|
||||
|
||||
inline bool nsStyleMargin::HasInlineAxisAuto(mozilla::WritingMode aWM) const {
|
||||
return mMargin.HasInlineAxisAuto(aWM);
|
||||
return mMargin.GetIStart(aWM).IsAuto() || mMargin.GetIEnd(aWM).IsAuto();
|
||||
}
|
||||
|
||||
#endif // WritingModes_h_
|
||||
|
||||
@@ -218,13 +218,13 @@ void nsAbsoluteContainingBlock::Reflow(nsContainerFrame* aDelegatingFrame,
|
||||
aReflowStatus.MergeCompletionStatusFrom(reflowStatus);
|
||||
}
|
||||
|
||||
static inline bool IsFixedPaddingSize(const nsStyleCoord& aCoord) {
|
||||
static inline bool IsFixedPaddingSize(const LengthPercentage& aCoord) {
|
||||
return aCoord.ConvertsToLength();
|
||||
}
|
||||
static inline bool IsFixedMarginSize(const nsStyleCoord& aCoord) {
|
||||
static inline bool IsFixedMarginSize(const LengthPercentageOrAuto& aCoord) {
|
||||
return aCoord.ConvertsToLength();
|
||||
}
|
||||
static inline bool IsFixedOffset(const nsStyleCoord& aCoord) {
|
||||
static inline bool IsFixedOffset(const LengthPercentageOrAuto& aCoord) {
|
||||
return aCoord.ConvertsToLength();
|
||||
}
|
||||
|
||||
@@ -243,10 +243,10 @@ bool nsAbsoluteContainingBlock::FrameDependsOnContainer(nsIFrame* f,
|
||||
// whichever of them is not auto and the width).
|
||||
// See ReflowInput::InitAbsoluteConstraints -- these are the
|
||||
// only cases when we call CalculateHypotheticalBox().
|
||||
if ((pos->mOffset.GetTopUnit() == eStyleUnit_Auto &&
|
||||
pos->mOffset.GetBottomUnit() == eStyleUnit_Auto) ||
|
||||
(pos->mOffset.GetLeftUnit() == eStyleUnit_Auto &&
|
||||
pos->mOffset.GetRightUnit() == eStyleUnit_Auto)) {
|
||||
if ((pos->mOffset.Get(eSideTop).IsAuto() &&
|
||||
pos->mOffset.Get(eSideBottom).IsAuto()) ||
|
||||
(pos->mOffset.Get(eSideLeft).IsAuto() ||
|
||||
pos->mOffset.Get(eSideRight).IsAuto())) {
|
||||
return true;
|
||||
}
|
||||
if (!aCBWidthChanged && !aCBHeightChanged) {
|
||||
@@ -288,8 +288,8 @@ bool nsAbsoluteContainingBlock::FrameDependsOnContainer(nsIFrame* f,
|
||||
// Note that borders never depend on the parent bsize.
|
||||
if ((pos->BSizeDependsOnContainer(wm) &&
|
||||
!(pos->BSize(wm).GetUnit() == eStyleUnit_Auto &&
|
||||
pos->mOffset.GetBEndUnit(wm) == eStyleUnit_Auto &&
|
||||
pos->mOffset.GetBStartUnit(wm) != eStyleUnit_Auto)) ||
|
||||
pos->mOffset.GetBEnd(wm).IsAuto() &&
|
||||
!pos->mOffset.GetBStart(wm).IsAuto())) ||
|
||||
pos->MinBSizeDependsOnContainer(wm) ||
|
||||
pos->MaxBSizeDependsOnContainer(wm) ||
|
||||
!IsFixedPaddingSize(padding->mPadding.GetBStart(wm)) ||
|
||||
@@ -311,7 +311,7 @@ bool nsAbsoluteContainingBlock::FrameDependsOnContainer(nsIFrame* f,
|
||||
// sides (left and top) that we use to store coordinates, these tests
|
||||
// are easier to do using physical coordinates rather than logical.
|
||||
if (aCBWidthChanged) {
|
||||
if (!IsFixedOffset(pos->mOffset.GetLeft())) {
|
||||
if (!IsFixedOffset(pos->mOffset.Get(eSideLeft))) {
|
||||
return true;
|
||||
}
|
||||
// Note that even if 'left' is a length, our position can still
|
||||
@@ -323,17 +323,17 @@ bool nsAbsoluteContainingBlock::FrameDependsOnContainer(nsIFrame* f,
|
||||
// sure of.
|
||||
if ((wm.GetInlineDir() == WritingMode::eInlineRTL ||
|
||||
wm.GetBlockDir() == WritingMode::eBlockRL) &&
|
||||
pos->mOffset.GetRightUnit() != eStyleUnit_Auto) {
|
||||
!pos->mOffset.Get(eSideRight).IsAuto()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (aCBHeightChanged) {
|
||||
if (!IsFixedOffset(pos->mOffset.GetTop())) {
|
||||
if (!IsFixedOffset(pos->mOffset.Get(eSideTop))) {
|
||||
return true;
|
||||
}
|
||||
// See comment above for width changes.
|
||||
if (wm.GetInlineDir() == WritingMode::eInlineBTT &&
|
||||
pos->mOffset.GetBottomUnit() != eStyleUnit_Auto) {
|
||||
!pos->mOffset.Get(eSideBottom).IsAuto()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1900,10 +1900,11 @@ static inline bool IsAlignedLeft(uint8_t aAlignment, uint8_t aDirection,
|
||||
|
||||
void nsBlockFrame::PrepareResizeReflow(BlockReflowInput& aState) {
|
||||
// See if we can try and avoid marking all the lines as dirty
|
||||
// FIXME(emilio): This should be writing-mode aware, I guess.
|
||||
bool tryAndSkipLines =
|
||||
// The left content-edge must be a constant distance from the left
|
||||
// border-edge.
|
||||
!StylePadding()->mPadding.GetLeft().HasPercent();
|
||||
!StylePadding()->mPadding.Get(eSideLeft).HasPercent();
|
||||
|
||||
#ifdef DEBUG
|
||||
if (gDisableResizeOpt) {
|
||||
|
||||
@@ -674,13 +674,21 @@ void nsContainerFrame::SyncFrameViewAfterReflow(
|
||||
}
|
||||
}
|
||||
|
||||
static nscoord GetCoord(const nsStyleCoord& aCoord, nscoord aIfNotCoord) {
|
||||
static nscoord GetCoord(const LengthPercentage& aCoord, nscoord aIfNotCoord) {
|
||||
if (aCoord.ConvertsToLength()) {
|
||||
return aCoord.ComputeCoordPercentCalc(0);
|
||||
return aCoord.ToLength();
|
||||
}
|
||||
return aIfNotCoord;
|
||||
}
|
||||
|
||||
static nscoord GetCoord(const LengthPercentageOrAuto& aCoord,
|
||||
nscoord aIfNotCoord) {
|
||||
if (aCoord.IsAuto()) {
|
||||
return aIfNotCoord;
|
||||
}
|
||||
return GetCoord(aCoord.AsLengthPercentage(), aIfNotCoord);
|
||||
}
|
||||
|
||||
void nsContainerFrame::DoInlineIntrinsicISize(
|
||||
gfxContext* aRenderingContext, InlineIntrinsicISizeData* aData,
|
||||
nsLayoutUtils::IntrinsicISizeType aType) {
|
||||
|
||||
@@ -1937,16 +1937,16 @@ FlexItem::FlexItem(ReflowInput& aFlexItemReflowInput, float aFlexGrow,
|
||||
SetFlexBaseSizeAndMainSize(aFlexBaseSize);
|
||||
CheckForMinSizeAuto(aFlexItemReflowInput, aAxisTracker);
|
||||
|
||||
const nsStyleSides& styleMargin = aFlexItemReflowInput.mStyleMargin->mMargin;
|
||||
const nsStyleMargin* styleMargin = aFlexItemReflowInput.mStyleMargin;
|
||||
mHasAnyAutoMargin =
|
||||
styleMargin.HasInlineAxisAuto(mWM) || styleMargin.HasBlockAxisAuto(mWM);
|
||||
styleMargin->HasInlineAxisAuto(mWM) || styleMargin->HasBlockAxisAuto(mWM);
|
||||
|
||||
// Assert that any "auto" margin components are set to 0.
|
||||
// (We'll resolve them later; until then, we want to treat them as 0-sized.)
|
||||
#ifdef DEBUG
|
||||
{
|
||||
NS_FOR_CSS_SIDES(side) {
|
||||
if (styleMargin.GetUnit(side) == eStyleUnit_Auto) {
|
||||
if (styleMargin->mMargin.Get(side).IsAuto()) {
|
||||
MOZ_ASSERT(GetMarginComponentForSide(side) == 0,
|
||||
"Someone else tried to resolve our auto margin");
|
||||
}
|
||||
@@ -2090,10 +2090,10 @@ bool FlexItem::IsCrossSizeAuto() const {
|
||||
|
||||
uint32_t FlexItem::GetNumAutoMarginsInAxis(AxisOrientationType aAxis) const {
|
||||
uint32_t numAutoMargins = 0;
|
||||
const nsStyleSides& styleMargin = mFrame->StyleMargin()->mMargin;
|
||||
const auto& styleMargin = mFrame->StyleMargin()->mMargin;
|
||||
for (uint32_t i = 0; i < eNumAxisEdges; i++) {
|
||||
mozilla::Side side = kAxisOrientationToSidesMap[aAxis][i];
|
||||
if (styleMargin.GetUnit(side) == eStyleUnit_Auto) {
|
||||
if (styleMargin.Get(side).IsAuto()) {
|
||||
numAutoMargins++;
|
||||
}
|
||||
}
|
||||
@@ -3002,10 +3002,10 @@ MainAxisPositionTracker::MainAxisPositionTracker(
|
||||
|
||||
void MainAxisPositionTracker::ResolveAutoMarginsInMainAxis(FlexItem& aItem) {
|
||||
if (mNumAutoMarginsInMainAxis) {
|
||||
const nsStyleSides& styleMargin = aItem.Frame()->StyleMargin()->mMargin;
|
||||
const auto& styleMargin = aItem.Frame()->StyleMargin()->mMargin;
|
||||
for (uint32_t i = 0; i < eNumAxisEdges; i++) {
|
||||
mozilla::Side side = kAxisOrientationToSidesMap[mAxis][i];
|
||||
if (styleMargin.GetUnit(side) == eStyleUnit_Auto) {
|
||||
if (styleMargin.Get(side).IsAuto()) {
|
||||
// NOTE: This integer math will skew the distribution of remainder
|
||||
// app-units towards the end, which is fine.
|
||||
nscoord curAutoMarginSize =
|
||||
@@ -3385,10 +3385,10 @@ void SingleLineCrossAxisPositionTracker::ResolveAutoMarginsInCrossAxis(
|
||||
|
||||
// OK, we have at least one auto margin and we have some available space.
|
||||
// Give each auto margin a share of the space.
|
||||
const nsStyleSides& styleMargin = aItem.Frame()->StyleMargin()->mMargin;
|
||||
const auto& styleMargin = aItem.Frame()->StyleMargin()->mMargin;
|
||||
for (uint32_t i = 0; i < eNumAxisEdges; i++) {
|
||||
mozilla::Side side = kAxisOrientationToSidesMap[mAxis][i];
|
||||
if (styleMargin.GetUnit(side) == eStyleUnit_Auto) {
|
||||
if (styleMargin.Get(side).IsAuto()) {
|
||||
MOZ_ASSERT(aItem.GetMarginComponentForSide(side) == 0,
|
||||
"Expecting auto margins to have value '0' before we "
|
||||
"update them");
|
||||
@@ -4209,8 +4209,8 @@ void nsFlexContainerFrame::Reflow(nsPresContext* aPresContext,
|
||||
const nsStyleCoord& bsize = stylePos->BSize(wm);
|
||||
if (bsize.HasPercent() ||
|
||||
(StyleDisplay()->IsAbsolutelyPositionedStyle() && bsize.IsAutoOrEnum() &&
|
||||
eStyleUnit_Auto != stylePos->mOffset.GetBStartUnit(wm) &&
|
||||
eStyleUnit_Auto != stylePos->mOffset.GetBEndUnit(wm))) {
|
||||
!stylePos->mOffset.GetBStart(wm).IsAuto() &&
|
||||
!stylePos->mOffset.GetBEnd(wm).IsAuto())) {
|
||||
AddStateBits(NS_FRAME_CONTAINS_RELATIVE_BSIZE);
|
||||
}
|
||||
|
||||
|
||||
@@ -1104,8 +1104,7 @@ void nsIFrame::MarkNeedsDisplayItemRebuild() {
|
||||
}
|
||||
|
||||
if (mInScrollAnchorChain) {
|
||||
const nsStylePosition* oldPosition =
|
||||
aOldComputedStyle->StylePosition();
|
||||
const nsStylePosition* oldPosition = aOldComputedStyle->StylePosition();
|
||||
if (oldPosition->mOffset != StylePosition()->mOffset ||
|
||||
oldPosition->mWidth != StylePosition()->mWidth ||
|
||||
oldPosition->mMinWidth != StylePosition()->mMinWidth ||
|
||||
@@ -5256,15 +5255,16 @@ void nsIFrame::InlinePrefISizeData::ForceBreak(StyleClear aBreakType) {
|
||||
mLineIsEmpty = true;
|
||||
}
|
||||
|
||||
static nscoord ResolveMargin(const nsStyleCoord& aStyle,
|
||||
static nscoord ResolveMargin(const LengthPercentageOrAuto& aStyle,
|
||||
nscoord aPercentageBasis) {
|
||||
if (aStyle.GetUnit() == eStyleUnit_Auto) {
|
||||
if (aStyle.IsAuto()) {
|
||||
return nscoord(0);
|
||||
}
|
||||
return nsLayoutUtils::ResolveToLength<false>(aStyle, aPercentageBasis);
|
||||
return nsLayoutUtils::ResolveToLength<false>(aStyle.AsLengthPercentage(),
|
||||
aPercentageBasis);
|
||||
}
|
||||
|
||||
static nscoord ResolvePadding(const nsStyleCoord& aStyle,
|
||||
static nscoord ResolvePadding(const LengthPercentage& aStyle,
|
||||
nscoord aPercentageBasis) {
|
||||
return nsLayoutUtils::ResolveToLength<true>(aStyle, aPercentageBasis);
|
||||
}
|
||||
@@ -5276,20 +5276,22 @@ static nsIFrame::IntrinsicISizeOffsetData IntrinsicSizeOffsets(
|
||||
const auto& margin = aFrame->StyleMargin()->mMargin;
|
||||
bool verticalAxis = aForISize == wm.IsVertical();
|
||||
if (verticalAxis) {
|
||||
result.hMargin += ResolveMargin(margin.GetTop(), aPercentageBasis);
|
||||
result.hMargin += ResolveMargin(margin.GetBottom(), aPercentageBasis);
|
||||
result.hMargin += ResolveMargin(margin.Get(eSideTop), aPercentageBasis);
|
||||
result.hMargin += ResolveMargin(margin.Get(eSideBottom), aPercentageBasis);
|
||||
} else {
|
||||
result.hMargin += ResolveMargin(margin.GetLeft(), aPercentageBasis);
|
||||
result.hMargin += ResolveMargin(margin.GetRight(), aPercentageBasis);
|
||||
result.hMargin += ResolveMargin(margin.Get(eSideLeft), aPercentageBasis);
|
||||
result.hMargin += ResolveMargin(margin.Get(eSideRight), aPercentageBasis);
|
||||
}
|
||||
|
||||
const auto& padding = aFrame->StylePadding()->mPadding;
|
||||
if (verticalAxis) {
|
||||
result.hPadding += ResolvePadding(padding.GetTop(), aPercentageBasis);
|
||||
result.hPadding += ResolvePadding(padding.GetBottom(), aPercentageBasis);
|
||||
result.hPadding += ResolvePadding(padding.Get(eSideTop), aPercentageBasis);
|
||||
result.hPadding +=
|
||||
ResolvePadding(padding.Get(eSideBottom), aPercentageBasis);
|
||||
} else {
|
||||
result.hPadding += ResolvePadding(padding.GetLeft(), aPercentageBasis);
|
||||
result.hPadding += ResolvePadding(padding.GetRight(), aPercentageBasis);
|
||||
result.hPadding += ResolvePadding(padding.Get(eSideLeft), aPercentageBasis);
|
||||
result.hPadding +=
|
||||
ResolvePadding(padding.Get(eSideRight), aPercentageBasis);
|
||||
}
|
||||
|
||||
const nsStyleBorder* styleBorder = aFrame->StyleBorder();
|
||||
|
||||
@@ -75,9 +75,9 @@ void nsInlineFrame::InvalidateFrameWithRect(const nsRect& aRect,
|
||||
aRebuildDisplayItems);
|
||||
}
|
||||
|
||||
static inline bool IsMarginZero(const nsStyleCoord& aCoord) {
|
||||
return aCoord.GetUnit() == eStyleUnit_Auto ||
|
||||
nsLayoutUtils::IsMarginZero(aCoord);
|
||||
static inline bool IsMarginZero(const LengthPercentageOrAuto& aLength) {
|
||||
return aLength.IsAuto() ||
|
||||
nsLayoutUtils::IsMarginZero(aLength.AsLengthPercentage());
|
||||
}
|
||||
|
||||
/* virtual */ bool nsInlineFrame::IsSelfEmpty() {
|
||||
@@ -96,23 +96,21 @@ static inline bool IsMarginZero(const nsStyleCoord& aCoord) {
|
||||
// ZeroEffectiveSpanBox, anymore, so what should this really be?
|
||||
WritingMode wm = GetWritingMode();
|
||||
bool haveStart, haveEnd;
|
||||
|
||||
auto HaveSide = [&](mozilla::Side aSide) -> bool {
|
||||
return border->GetComputedBorderWidth(aSide) != 0 ||
|
||||
!nsLayoutUtils::IsPaddingZero(padding->mPadding.Get(aSide)) ||
|
||||
!IsMarginZero(margin->mMargin.Get(aSide));
|
||||
};
|
||||
// Initially set up haveStart and haveEnd in terms of visual (LTR/TTB)
|
||||
// coordinates; we'll exchange them later if bidi-RTL is in effect to
|
||||
// get logical start and end flags.
|
||||
if (wm.IsVertical()) {
|
||||
haveStart = border->GetComputedBorderWidth(eSideTop) != 0 ||
|
||||
!nsLayoutUtils::IsPaddingZero(padding->mPadding.GetTop()) ||
|
||||
!IsMarginZero(margin->mMargin.GetTop());
|
||||
haveEnd = border->GetComputedBorderWidth(eSideBottom) != 0 ||
|
||||
!nsLayoutUtils::IsPaddingZero(padding->mPadding.GetBottom()) ||
|
||||
!IsMarginZero(margin->mMargin.GetBottom());
|
||||
haveStart = HaveSide(eSideTop);
|
||||
haveEnd = HaveSide(eSideBottom);
|
||||
} else {
|
||||
haveStart = border->GetComputedBorderWidth(eSideLeft) != 0 ||
|
||||
!nsLayoutUtils::IsPaddingZero(padding->mPadding.GetLeft()) ||
|
||||
!IsMarginZero(margin->mMargin.GetLeft());
|
||||
haveEnd = border->GetComputedBorderWidth(eSideRight) != 0 ||
|
||||
!nsLayoutUtils::IsPaddingZero(padding->mPadding.GetRight()) ||
|
||||
!IsMarginZero(margin->mMargin.GetRight());
|
||||
haveStart = HaveSide(eSideLeft);
|
||||
haveEnd = HaveSide(eSideRight);
|
||||
}
|
||||
if (haveStart || haveEnd) {
|
||||
// We skip this block and return false for box-decoration-break:clone since
|
||||
|
||||
@@ -666,11 +666,9 @@ bool nsLineLayout::LineIsBreakable() const {
|
||||
// only be used for things (margin, padding) where percentages on top
|
||||
// and bottom depend on the *width* just like percentages on left and
|
||||
// right.
|
||||
static bool HasPercentageUnitSide(const nsStyleSides& aSides) {
|
||||
NS_FOR_CSS_SIDES(side) {
|
||||
if (aSides.Get(side).HasPercent()) return true;
|
||||
}
|
||||
return false;
|
||||
template <typename T>
|
||||
static bool HasPercentageUnitSide(const StyleRect<T>& aSides) {
|
||||
return aSides.Any([](const auto& aLength) { return aLength.HasPercent(); });
|
||||
}
|
||||
|
||||
static bool IsPercentageAware(const nsIFrame* aFrame, WritingMode aWM) {
|
||||
|
||||
@@ -94,9 +94,9 @@ void nsPageFrame::Reflow(nsPresContext* aPresContext,
|
||||
// Use the margins given in the @page rule.
|
||||
// If a margin is 'auto', use the margin from the print settings for that
|
||||
// side.
|
||||
const nsStyleSides& marginStyle = kidReflowInput.mStyleMargin->mMargin;
|
||||
const auto& marginStyle = kidReflowInput.mStyleMargin->mMargin;
|
||||
NS_FOR_CSS_SIDES(side) {
|
||||
if (marginStyle.GetUnit(side) == eStyleUnit_Auto) {
|
||||
if (marginStyle.Get(side).IsAuto()) {
|
||||
mPageContentMargin.Side(side) = mPD->mReflowMargin.Side(side);
|
||||
} else {
|
||||
mPageContentMargin.Side(side) =
|
||||
|
||||
@@ -1866,11 +1866,12 @@ bool BuildTextRunsScanner::ContinueTextRunAcrossFrames(nsTextFrame* aFrame1,
|
||||
//
|
||||
// 1. Any of margin/border/padding separating the two typographic
|
||||
// character units in the inline axis is non-zero.
|
||||
const nsStyleCoord& margin = ctx->StyleMargin()->mMargin.Get(aSide);
|
||||
if (!margin.ConvertsToLength() || margin.ToLength() != 0) {
|
||||
const auto& margin = ctx->StyleMargin()->mMargin.Get(aSide);
|
||||
if (!margin.ConvertsToLength() ||
|
||||
margin.AsLengthPercentage().ToLength() != 0) {
|
||||
return true;
|
||||
}
|
||||
const nsStyleCoord& padding = ctx->StylePadding()->mPadding.Get(aSide);
|
||||
const auto& padding = ctx->StylePadding()->mPadding.Get(aSide);
|
||||
if (!padding.ConvertsToLength() || padding.ToLength() != 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -933,11 +933,12 @@ bool Servo_ComputeColor(RawServoStyleSetBorrowedOrNull set,
|
||||
nscolor* result_color, bool* was_current_color,
|
||||
mozilla::css::Loader* loader);
|
||||
|
||||
bool Servo_IntersectionObserverRootMargin_Parse(const nsAString* value,
|
||||
nsStyleSides* result);
|
||||
bool Servo_IntersectionObserverRootMargin_Parse(
|
||||
const nsAString* value,
|
||||
mozilla::StyleIntersectionObserverRootMargin* result);
|
||||
|
||||
void Servo_IntersectionObserverRootMargin_ToString(const nsStyleSides* rect,
|
||||
nsAString* result);
|
||||
void Servo_IntersectionObserverRootMargin_ToString(
|
||||
const mozilla::StyleIntersectionObserverRootMargin*, nsAString* result);
|
||||
|
||||
// Returning false means the parsed transform contains relative lengths or
|
||||
// percentage value, so we cannot compute the matrix. In this case, we keep
|
||||
|
||||
@@ -415,6 +415,10 @@ cbindgen-types = [
|
||||
{ gecko = "StyleOverflow", servo = "values::computed::Overflow" },
|
||||
{ gecko = "StyleOverflowAnchor", servo = "values::computed::OverflowAnchor" },
|
||||
{ gecko = "StyleLengthPercentage", servo = "values::computed::LengthPercentage" },
|
||||
{ gecko = "StyleNonNegativeLengthPercentage", servo = "values::computed::NonNegativeLengthPercentage" },
|
||||
{ gecko = "StyleLengthPercentageOrAuto", servo = "values::computed::LengthPercentageOrAuto" },
|
||||
{ gecko = "StyleRect", servo = "values::generics::rect::Rect" },
|
||||
{ gecko = "StyleIntersectionObserverRootMargin", servo = "values::specified::gecko::IntersectionObserverRootMargin" },
|
||||
]
|
||||
|
||||
mapped-generic-types = [
|
||||
@@ -474,6 +478,7 @@ structs-types = [
|
||||
"mozilla::StyleMotion",
|
||||
"mozilla::UniquePtr",
|
||||
"mozilla::StyleDisplayMode",
|
||||
"mozilla::StyleIntersectionObserverRootMargin",
|
||||
"mozilla::StyleComputedFontStretchRange",
|
||||
"mozilla::StyleComputedFontStyleDescriptor",
|
||||
"mozilla::StyleComputedFontWeightRange",
|
||||
|
||||
@@ -2614,6 +2614,32 @@ already_AddRefed<CSSValue> nsComputedDOMStyle::GetOffsetWidthFor(
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
// FIXME(emilio): Remove these when nsStyleCoord is gone.
|
||||
static nsStyleCoord ToCoord(const LengthPercentage& aLength) {
|
||||
nsStyleCoord ret;
|
||||
if (aLength.was_calc) {
|
||||
auto* calc = new nsStyleCoord::Calc();
|
||||
calc->mLength = CSSPixel::ToAppUnits(aLength.LengthInCSSPixels());
|
||||
calc->mPercent = aLength.Percentage();
|
||||
calc->mHasPercent = aLength.HasPercent();
|
||||
ret.SetCalcValue(calc); // takes ownership.
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (aLength.HasPercent()) {
|
||||
ret.SetPercentValue(aLength.Percentage());
|
||||
} else {
|
||||
ret.SetCoordValue(aLength.ToLength());
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static nsStyleCoord ToCoord(const LengthPercentageOrAuto& aLength) {
|
||||
if (aLength.IsAuto()) {
|
||||
return nsStyleCoord(eStyleUnit_Auto);
|
||||
}
|
||||
return ToCoord(aLength.AsLengthPercentage());
|
||||
}
|
||||
|
||||
static_assert(eSideTop == 0 && eSideRight == 1 && eSideBottom == 2 &&
|
||||
eSideLeft == 3,
|
||||
@@ -2627,14 +2653,9 @@ already_AddRefed<CSSValue> nsComputedDOMStyle::GetNonStaticPositionOffset(
|
||||
|
||||
const nsStylePosition* positionData = StylePosition();
|
||||
int32_t sign = 1;
|
||||
nsStyleCoord coord = positionData->mOffset.Get(aSide);
|
||||
LengthPercentageOrAuto coord = positionData->mOffset.Get(aSide);
|
||||
|
||||
NS_ASSERTION(coord.GetUnit() == eStyleUnit_Coord ||
|
||||
coord.GetUnit() == eStyleUnit_Percent ||
|
||||
coord.GetUnit() == eStyleUnit_Auto || coord.IsCalcUnit(),
|
||||
"Unexpected unit");
|
||||
|
||||
if (coord.GetUnit() == eStyleUnit_Auto) {
|
||||
if (coord.IsAuto()) {
|
||||
if (!aResolveAuto) {
|
||||
val->SetIdent(eCSSKeyword_auto);
|
||||
return val.forget();
|
||||
@@ -2647,18 +2668,18 @@ already_AddRefed<CSSValue> nsComputedDOMStyle::GetNonStaticPositionOffset(
|
||||
? aWidthGetter
|
||||
: aHeightGetter;
|
||||
|
||||
val->SetAppUnits(sign * StyleCoordToNSCoord(coord, baseGetter, 0, false));
|
||||
val->SetAppUnits(sign *
|
||||
StyleCoordToNSCoord(ToCoord(coord), baseGetter, 0, false));
|
||||
return val.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<CSSValue> nsComputedDOMStyle::GetAbsoluteOffset(
|
||||
mozilla::Side aSide) {
|
||||
const auto& offset = StylePosition()->mOffset;
|
||||
const nsStyleCoord& coord = offset.Get(aSide);
|
||||
const nsStyleCoord& oppositeCoord = offset.Get(NS_OPPOSITE_SIDE(aSide));
|
||||
const auto& coord = offset.Get(aSide);
|
||||
const auto& oppositeCoord = offset.Get(NS_OPPOSITE_SIDE(aSide));
|
||||
|
||||
if (coord.GetUnit() == eStyleUnit_Auto ||
|
||||
oppositeCoord.GetUnit() == eStyleUnit_Auto) {
|
||||
if (coord.IsAuto() || oppositeCoord.IsAuto()) {
|
||||
RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
|
||||
val->SetAppUnits(GetUsedAbsoluteOffset(aSide));
|
||||
return val.forget();
|
||||
@@ -2728,7 +2749,7 @@ nscoord nsComputedDOMStyle::GetUsedAbsoluteOffset(mozilla::Side aSide) {
|
||||
already_AddRefed<CSSValue> nsComputedDOMStyle::GetStaticOffset(
|
||||
mozilla::Side aSide) {
|
||||
RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
|
||||
SetValueToCoord(val, StylePosition()->mOffset.Get(aSide), false);
|
||||
SetValueToCoord(val, ToCoord(StylePosition()->mOffset.Get(aSide)), false);
|
||||
return val.forget();
|
||||
}
|
||||
|
||||
@@ -2737,7 +2758,7 @@ already_AddRefed<CSSValue> nsComputedDOMStyle::GetPaddingWidthFor(
|
||||
RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
|
||||
|
||||
if (!mInnerFrame) {
|
||||
SetValueToCoord(val, StylePadding()->mPadding.Get(aSide), true);
|
||||
SetValueToCoord(val, ToCoord(StylePadding()->mPadding.Get(aSide)), true);
|
||||
} else {
|
||||
AssertFlushedPendingReflows();
|
||||
|
||||
@@ -2812,7 +2833,7 @@ already_AddRefed<CSSValue> nsComputedDOMStyle::GetMarginWidthFor(
|
||||
RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
|
||||
|
||||
if (!mInnerFrame) {
|
||||
SetValueToCoord(val, StyleMargin()->mMargin.Get(aSide), false);
|
||||
SetValueToCoord(val, ToCoord(StyleMargin()->mMargin.Get(aSide)), false);
|
||||
} else {
|
||||
AssertFlushedPendingReflows();
|
||||
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
#include "mozilla/gfx/Types.h"
|
||||
#include "Units.h"
|
||||
#include "nsCoord.h"
|
||||
#include "LayoutConstants.h"
|
||||
#include "nsISupportsImpl.h"
|
||||
#include "nsStyleConsts.h"
|
||||
|
||||
@@ -26,7 +25,7 @@ class WritingMode;
|
||||
// Logical axis, edge, side and corner constants for use in various places.
|
||||
enum LogicalAxis { eLogicalAxisBlock = 0x0, eLogicalAxisInline = 0x1 };
|
||||
enum LogicalEdge { eLogicalEdgeStart = 0x0, eLogicalEdgeEnd = 0x1 };
|
||||
enum LogicalSide {
|
||||
enum LogicalSide : uint8_t {
|
||||
eLogicalSideBStart = (eLogicalAxisBlock << 1) | eLogicalEdgeStart, // 0x0
|
||||
eLogicalSideBEnd = (eLogicalAxisBlock << 1) | eLogicalEdgeEnd, // 0x1
|
||||
eLogicalSideIStart = (eLogicalAxisInline << 1) | eLogicalEdgeStart, // 0x2
|
||||
@@ -41,8 +40,10 @@ enum LogicalCorner {
|
||||
};
|
||||
|
||||
using LengthPercentage = StyleLengthPercentage;
|
||||
using LengthPercentageOrAuto = StyleLengthPercentageOrAuto;
|
||||
using NonNegativeLengthPercentage = StyleNonNegativeLengthPercentage;
|
||||
|
||||
LengthPercentage LengthPercentage::Zero() {
|
||||
constexpr LengthPercentage LengthPercentage::Zero() {
|
||||
return {{0.}, {0.}, StyleAllowedNumericType::All, false, false};
|
||||
}
|
||||
|
||||
@@ -84,8 +85,6 @@ CSSCoord LengthPercentage::ResolveToCSSPixelsWith(T aPercentageGetter) const {
|
||||
|
||||
nscoord LengthPercentage::Resolve(nscoord aPercentageBasis) const {
|
||||
NS_WARNING_ASSERTION(aPercentageBasis >= 0, "nscoord overflow?");
|
||||
NS_WARNING_ASSERTION(aPercentageBasis != NS_UNCONSTRAINEDSIZE,
|
||||
"Should handle that somewhere else");
|
||||
return CSSPixel::ToAppUnits(LengthInCSSPixels()) +
|
||||
NSToCoordFloorClamped(aPercentageBasis * Percentage());
|
||||
}
|
||||
@@ -100,6 +99,38 @@ nscoord LengthPercentage::ResolveWith(T aPercentageGetter) const {
|
||||
return Resolve(aPercentageGetter());
|
||||
}
|
||||
|
||||
const LengthPercentage& LengthPercentageOrAuto::AsLengthPercentage() const {
|
||||
MOZ_ASSERT(IsLengthPercentage());
|
||||
return length_percentage._0;
|
||||
}
|
||||
|
||||
bool LengthPercentageOrAuto::ConvertsToLength() const {
|
||||
return IsLengthPercentage() && AsLengthPercentage().ConvertsToLength();
|
||||
}
|
||||
|
||||
bool LengthPercentageOrAuto::HasPercent() const {
|
||||
return IsLengthPercentage() && AsLengthPercentage().HasPercent();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
const T& StyleRect<T>::Get(mozilla::Side aSide) const {
|
||||
static_assert(sizeof(StyleRect<T>) == sizeof(T) * 4, "");
|
||||
static_assert(alignof(StyleRect<T>) == alignof(T), "");
|
||||
return reinterpret_cast<const T*>(this)[aSide];
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
template <typename Predicate>
|
||||
bool StyleRect<T>::All(Predicate aPredicate) const {
|
||||
return aPredicate(_0) && aPredicate(_1) && aPredicate(_2) && aPredicate(_3);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
template <typename Predicate>
|
||||
bool StyleRect<T>::Any(Predicate aPredicate) const {
|
||||
return aPredicate(_0) || aPredicate(_1) || aPredicate(_2) || aPredicate(_3);
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
||||
|
||||
enum nsStyleUnit : uint8_t {
|
||||
|
||||
@@ -182,10 +182,15 @@ nscoord nsStyleFont::ZoomText(const Document& aDocument, nscoord aSize) {
|
||||
return NSToCoordTruncClamped(float(aSize) * textZoom);
|
||||
}
|
||||
|
||||
nsStyleMargin::nsStyleMargin(const Document& aDocument) {
|
||||
template <typename T>
|
||||
static StyleRect<T> StyleRectWithAllSides(const T& aSide) {
|
||||
return {aSide, aSide, aSide, aSide};
|
||||
}
|
||||
|
||||
nsStyleMargin::nsStyleMargin(const Document& aDocument)
|
||||
: mMargin(StyleRectWithAllSides(
|
||||
LengthPercentageOrAuto::LengthPercentage(LengthPercentage::Zero()))) {
|
||||
MOZ_COUNT_CTOR(nsStyleMargin);
|
||||
nsStyleCoord zero(0, nsStyleCoord::CoordConstructor);
|
||||
NS_FOR_CSS_SIDES(side) { mMargin.Set(side, zero); }
|
||||
}
|
||||
|
||||
nsStyleMargin::nsStyleMargin(const nsStyleMargin& aSrc)
|
||||
@@ -204,10 +209,9 @@ nsChangeHint nsStyleMargin::CalcDifference(
|
||||
nsChangeHint_ClearAncestorIntrinsics;
|
||||
}
|
||||
|
||||
nsStylePadding::nsStylePadding(const Document& aDocument) {
|
||||
nsStylePadding::nsStylePadding(const Document& aDocument)
|
||||
: mPadding(StyleRectWithAllSides(LengthPercentage::Zero())) {
|
||||
MOZ_COUNT_CTOR(nsStylePadding);
|
||||
nsStyleCoord zero(0, nsStyleCoord::CoordConstructor);
|
||||
NS_FOR_CSS_SIDES(side) { mPadding.Set(side, zero); }
|
||||
}
|
||||
|
||||
nsStylePadding::nsStylePadding(const nsStylePadding& aSrc)
|
||||
@@ -1291,7 +1295,8 @@ bool nsStyleSVGPaint::operator==(const nsStyleSVGPaint& aOther) const {
|
||||
// nsStylePosition
|
||||
//
|
||||
nsStylePosition::nsStylePosition(const Document& aDocument)
|
||||
: mWidth(eStyleUnit_Auto),
|
||||
: mOffset(StyleRectWithAllSides(LengthPercentageOrAuto::Auto())),
|
||||
mWidth(eStyleUnit_Auto),
|
||||
mMinWidth(eStyleUnit_Auto),
|
||||
mMaxWidth(eStyleUnit_None),
|
||||
mHeight(eStyleUnit_Auto),
|
||||
@@ -1326,9 +1331,6 @@ nsStylePosition::nsStylePosition(const Document& aDocument)
|
||||
|
||||
mObjectPosition.SetInitialPercentValues(0.5f);
|
||||
|
||||
nsStyleCoord autoCoord(eStyleUnit_Auto);
|
||||
NS_FOR_CSS_SIDES(side) { mOffset.Set(side, autoCoord); }
|
||||
|
||||
// The initial value of grid-auto-columns and grid-auto-rows is 'auto',
|
||||
// which computes to 'minmax(auto, auto)'.
|
||||
|
||||
@@ -1390,11 +1392,10 @@ nsStylePosition::nsStylePosition(const nsStylePosition& aSource)
|
||||
}
|
||||
}
|
||||
|
||||
static bool IsAutonessEqual(const nsStyleSides& aSides1,
|
||||
const nsStyleSides& aSides2) {
|
||||
static bool IsAutonessEqual(const StyleRect<LengthPercentageOrAuto>& aSides1,
|
||||
const StyleRect<LengthPercentageOrAuto>& aSides2) {
|
||||
NS_FOR_CSS_SIDES(side) {
|
||||
if ((aSides1.GetUnit(side) == eStyleUnit_Auto) !=
|
||||
(aSides2.GetUnit(side) == eStyleUnit_Auto)) {
|
||||
if (aSides1.Get(side).IsAuto() != aSides2.Get(side).IsAuto()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -772,11 +772,16 @@ struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleMargin {
|
||||
nsChangeHint CalcDifference(const nsStyleMargin& aNewData) const;
|
||||
|
||||
bool GetMargin(nsMargin& aMargin) const {
|
||||
if (!mMargin.ConvertsToLength()) {
|
||||
bool convertsToLength = mMargin.All(
|
||||
[](const auto& aLength) { return aLength.ConvertsToLength(); });
|
||||
|
||||
if (!convertsToLength) {
|
||||
return false;
|
||||
}
|
||||
|
||||
NS_FOR_CSS_SIDES(side) { aMargin.Side(side) = mMargin.ToLength(side); }
|
||||
NS_FOR_CSS_SIDES(side) {
|
||||
aMargin.Side(side) = mMargin.Get(side).AsLengthPercentage().ToLength();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -785,7 +790,7 @@ struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleMargin {
|
||||
inline bool HasBlockAxisAuto(mozilla::WritingMode aWM) const;
|
||||
inline bool HasInlineAxisAuto(mozilla::WritingMode aWM) const;
|
||||
|
||||
nsStyleSides mMargin; // coord, percent, calc, auto
|
||||
mozilla::StyleRect<mozilla::LengthPercentageOrAuto> mMargin;
|
||||
};
|
||||
|
||||
struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStylePadding {
|
||||
@@ -797,18 +802,21 @@ struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStylePadding {
|
||||
|
||||
nsChangeHint CalcDifference(const nsStylePadding& aNewData) const;
|
||||
|
||||
nsStyleSides mPadding; // coord, percent, calc
|
||||
mozilla::StyleRect<mozilla::NonNegativeLengthPercentage> mPadding;
|
||||
|
||||
bool IsWidthDependent() const { return !mPadding.ConvertsToLength(); }
|
||||
inline bool IsWidthDependent() const {
|
||||
return !mPadding.All(
|
||||
[](const auto& aLength) { return aLength.ConvertsToLength(); });
|
||||
}
|
||||
|
||||
bool GetPadding(nsMargin& aPadding) const {
|
||||
if (!mPadding.ConvertsToLength()) {
|
||||
if (IsWidthDependent()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
NS_FOR_CSS_SIDES(side) {
|
||||
// Clamp negative calc() to 0.
|
||||
aPadding.Side(side) = std::max(mPadding.ToLength(side), 0);
|
||||
aPadding.Side(side) = std::max(mPadding.Get(side).ToLength(), 0);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -1314,7 +1322,7 @@ struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStylePosition {
|
||||
uint8_t UsedJustifySelf(mozilla::ComputedStyle* aParent) const;
|
||||
|
||||
mozilla::Position mObjectPosition;
|
||||
nsStyleSides mOffset; // coord, percent, calc, auto
|
||||
mozilla::StyleRect<mozilla::LengthPercentageOrAuto> mOffset;
|
||||
nsStyleCoord mWidth; // coord, percent, enum, calc, auto
|
||||
nsStyleCoord mMinWidth; // coord, percent, enum, calc
|
||||
nsStyleCoord mMaxWidth; // coord, percent, enum, calc, none
|
||||
|
||||
@@ -9,11 +9,15 @@ autogen_warning = """/* DO NOT MODIFY THIS MANUALLY! This file was generated usi
|
||||
*/
|
||||
#include "nsCoord.h"
|
||||
#include "Units.h"
|
||||
#include "mozilla/gfx/Types.h"
|
||||
class nsAtom;
|
||||
namespace mozilla {
|
||||
class WritingMode;
|
||||
enum LogicalSide : uint8_t;
|
||||
namespace css {
|
||||
struct URLValue;
|
||||
}
|
||||
|
||||
// Work-around weird cbindgen renaming.
|
||||
typedef css::URLValue StyleURLValue;
|
||||
typedef nsAtom StylensAtom;
|
||||
@@ -71,13 +75,17 @@ include = [
|
||||
"Resize",
|
||||
"Overflow",
|
||||
"LengthPercentage",
|
||||
"NonNegativeLengthPercentage",
|
||||
"LengthPercentageOrAuto",
|
||||
"Rect",
|
||||
"IntersectionObserverRootMargin",
|
||||
]
|
||||
item_types = ["enums", "structs", "typedefs"]
|
||||
|
||||
[export.body]
|
||||
"LengthPercentage" = """
|
||||
// Defined in nsStyleCoord.h
|
||||
static inline StyleLengthPercentage Zero();
|
||||
static constexpr inline StyleLengthPercentage Zero();
|
||||
inline bool HasPercent() const;
|
||||
inline bool ConvertsToLength() const;
|
||||
inline nscoord ToLength() const;
|
||||
@@ -90,3 +98,23 @@ item_types = ["enums", "structs", "typedefs"]
|
||||
inline nscoord Resolve(nscoord aPercentageBasis) const;
|
||||
template<typename T> inline nscoord ResolveWith(T aPercentageGetter) const;
|
||||
"""
|
||||
|
||||
"LengthPercentageOrAuto" = """
|
||||
inline const StyleLengthPercentage& AsLengthPercentage() const;
|
||||
inline bool HasPercent() const;
|
||||
inline bool ConvertsToLength() const;
|
||||
"""
|
||||
|
||||
"Rect" = """
|
||||
// Defined in nsStyleCoord.h
|
||||
template<typename Predicate> inline bool All(Predicate) const;
|
||||
template<typename Predicate> inline bool Any(Predicate) const;
|
||||
|
||||
// Defined in WritingModes.h
|
||||
inline const T& Get(mozilla::Side) const;
|
||||
inline const T& Get(mozilla::WritingMode, mozilla::LogicalSide) const;
|
||||
inline const T& GetIStart(mozilla::WritingMode) const;
|
||||
inline const T& GetBStart(mozilla::WritingMode) const;
|
||||
inline const T& GetIEnd(mozilla::WritingMode) const;
|
||||
inline const T& GetBEnd(mozilla::WritingMode) const;
|
||||
"""
|
||||
|
||||
@@ -772,11 +772,12 @@ def set_gecko_property(ffi_name, expr):
|
||||
<%def name="impl_split_style_coord(ident, gecko_ffi_name, index)">
|
||||
#[allow(non_snake_case)]
|
||||
pub fn set_${ident}(&mut self, v: longhands::${ident}::computed_value::T) {
|
||||
v.to_gecko_style_coord(&mut self.gecko.${gecko_ffi_name}.data_at_mut(${index}));
|
||||
self.gecko.${gecko_ffi_name}.${index} = v;
|
||||
}
|
||||
#[allow(non_snake_case)]
|
||||
pub fn copy_${ident}_from(&mut self, other: &Self) {
|
||||
self.gecko.${gecko_ffi_name}.data_at_mut(${index}).copy_from(&other.gecko.${gecko_ffi_name}.data_at(${index}));
|
||||
self.gecko.${gecko_ffi_name}.${index} =
|
||||
other.gecko.${gecko_ffi_name}.${index};
|
||||
}
|
||||
#[allow(non_snake_case)]
|
||||
pub fn reset_${ident}(&mut self, other: &Self) {
|
||||
@@ -785,9 +786,7 @@ def set_gecko_property(ffi_name, expr):
|
||||
|
||||
#[allow(non_snake_case)]
|
||||
pub fn clone_${ident}(&self) -> longhands::${ident}::computed_value::T {
|
||||
use crate::properties::longhands::${ident}::computed_value::T;
|
||||
T::from_gecko_style_coord(&self.gecko.${gecko_ffi_name}.data_at(${index}))
|
||||
.expect("clone for ${ident} failed")
|
||||
self.gecko.${gecko_ffi_name}.${index}
|
||||
}
|
||||
</%def>
|
||||
|
||||
|
||||
@@ -457,6 +457,7 @@ impl IsZeroLength for LengthPercentage {
|
||||
#[derive(
|
||||
Animate, Clone, ComputeSquaredDistance, Copy, MallocSizeOf, PartialEq, ToAnimatedZero, ToCss,
|
||||
)]
|
||||
#[repr(C, u8)]
|
||||
pub enum LengthPercentageOrAuto {
|
||||
LengthPercentage(LengthPercentage),
|
||||
Auto,
|
||||
|
||||
@@ -23,6 +23,7 @@ use style_traits::{CssWriter, ParseError, ToCss};
|
||||
ToAnimatedValue,
|
||||
ToComputedValue,
|
||||
)]
|
||||
#[repr(C)]
|
||||
pub struct Rect<T>(pub T, pub T, pub T, pub T);
|
||||
|
||||
impl<T> Rect<T> {
|
||||
|
||||
@@ -4,21 +4,19 @@
|
||||
|
||||
//! Specified types for legacy Gecko-only properties.
|
||||
|
||||
use crate::gecko::values::GeckoStyleCoordConvertible;
|
||||
use crate::gecko_bindings::sugar::ns_style_coord::{CoordData, CoordDataMut};
|
||||
use crate::parser::{Parse, ParserContext};
|
||||
use crate::values::computed;
|
||||
use crate::values::computed::{self, LengthPercentage};
|
||||
use crate::values::computed::length::CSSPixelLength;
|
||||
use crate::values::generics::gecko::ScrollSnapPoint as GenericScrollSnapPoint;
|
||||
use crate::values::generics::rect::Rect;
|
||||
use crate::values::specified::length::LengthPercentage;
|
||||
use crate::values::specified::length::LengthPercentage as SpecifiedLengthPercentage;
|
||||
use cssparser::{Parser, Token};
|
||||
use std::fmt;
|
||||
use style_traits::values::SequenceWriter;
|
||||
use style_traits::{CssWriter, ParseError, StyleParseErrorKind, ToCss};
|
||||
|
||||
/// A specified type for scroll snap points.
|
||||
pub type ScrollSnapPoint = GenericScrollSnapPoint<LengthPercentage>;
|
||||
pub type ScrollSnapPoint = GenericScrollSnapPoint<SpecifiedLengthPercentage>;
|
||||
|
||||
impl Parse for ScrollSnapPoint {
|
||||
fn parse<'i, 't>(
|
||||
@@ -29,26 +27,17 @@ impl Parse for ScrollSnapPoint {
|
||||
return Ok(GenericScrollSnapPoint::None);
|
||||
}
|
||||
input.expect_function_matching("repeat")?;
|
||||
// FIXME(emilio): This won't clamp properly when animating.
|
||||
let length =
|
||||
input.parse_nested_block(|i| LengthPercentage::parse_non_negative(context, i))?;
|
||||
input.parse_nested_block(|i| SpecifiedLengthPercentage::parse_non_negative(context, i))?;
|
||||
Ok(GenericScrollSnapPoint::Repeat(length))
|
||||
}
|
||||
}
|
||||
|
||||
/// A component of an IntersectionObserverRootMargin.
|
||||
#[derive(Clone, Copy, Debug, PartialEq, ToCss)]
|
||||
pub enum PixelOrPercentage {
|
||||
/// An absolute length in pixels (px)
|
||||
Pixel(CSSPixelLength),
|
||||
/// A percentage (%)
|
||||
Percentage(computed::Percentage),
|
||||
}
|
||||
|
||||
impl Parse for PixelOrPercentage {
|
||||
fn parse<'i, 't>(
|
||||
fn parse_pixel_or_percent<'i, 't>(
|
||||
_context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<Self, ParseError<'i>> {
|
||||
) -> Result<LengthPercentage, ParseError<'i>> {
|
||||
let location = input.current_source_location();
|
||||
let token = input.next()?;
|
||||
let value = match *token {
|
||||
@@ -56,36 +45,17 @@ impl Parse for PixelOrPercentage {
|
||||
value, ref unit, ..
|
||||
} => {
|
||||
match_ignore_ascii_case! { unit,
|
||||
"px" => Ok(PixelOrPercentage::Pixel(CSSPixelLength::new(value))),
|
||||
"px" => Ok(LengthPercentage::new(CSSPixelLength::new(value), None)),
|
||||
_ => Err(()),
|
||||
}
|
||||
},
|
||||
Token::Percentage { unit_value, .. } => Ok(PixelOrPercentage::Percentage(
|
||||
computed::Percentage(unit_value),
|
||||
)),
|
||||
Token::Percentage { unit_value, .. } => Ok(
|
||||
LengthPercentage::new_percent(computed::Percentage(unit_value))
|
||||
),
|
||||
_ => Err(()),
|
||||
};
|
||||
value.map_err(|()| location.new_custom_error(StyleParseErrorKind::UnspecifiedError))
|
||||
}
|
||||
}
|
||||
|
||||
impl GeckoStyleCoordConvertible for PixelOrPercentage {
|
||||
fn to_gecko_style_coord<T: CoordDataMut>(&self, coord: &mut T) {
|
||||
match *self {
|
||||
PixelOrPercentage::Pixel(ref l) => l.to_gecko_style_coord(coord),
|
||||
PixelOrPercentage::Percentage(ref pc) => pc.to_gecko_style_coord(coord),
|
||||
}
|
||||
}
|
||||
|
||||
fn from_gecko_style_coord<T: CoordData>(coord: &T) -> Option<Self> {
|
||||
CSSPixelLength::from_gecko_style_coord(coord)
|
||||
.map(PixelOrPercentage::Pixel)
|
||||
.or_else(|| {
|
||||
computed::Percentage::from_gecko_style_coord(coord)
|
||||
.map(PixelOrPercentage::Percentage)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/// The value of an IntersectionObserver's rootMargin property.
|
||||
///
|
||||
@@ -93,14 +63,15 @@ impl GeckoStyleCoordConvertible for PixelOrPercentage {
|
||||
/// calc() values are not allowed.
|
||||
///
|
||||
/// <https://w3c.github.io/IntersectionObserver/#parse-a-root-margin>
|
||||
pub struct IntersectionObserverRootMargin(pub Rect<PixelOrPercentage>);
|
||||
#[repr(transparent)]
|
||||
pub struct IntersectionObserverRootMargin(pub Rect<LengthPercentage>);
|
||||
|
||||
impl Parse for IntersectionObserverRootMargin {
|
||||
fn parse<'i, 't>(
|
||||
context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<Self, ParseError<'i>> {
|
||||
let rect = Rect::parse_with(context, input, PixelOrPercentage::parse)?;
|
||||
let rect = Rect::parse_with(context, input, parse_pixel_or_percent)?;
|
||||
Ok(IntersectionObserverRootMargin(rect))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -201,9 +201,8 @@ use style::use_counters::UseCounters;
|
||||
use style::values::animated::{Animate, Procedure, ToAnimatedZero};
|
||||
use style::values::computed::{self, Context, QuotePair, ToComputedValue};
|
||||
use style::values::distance::ComputeSquaredDistance;
|
||||
use style::values::generics::rect::Rect;
|
||||
use style::values::specified;
|
||||
use style::values::specified::gecko::{IntersectionObserverRootMargin, PixelOrPercentage};
|
||||
use style::values::specified::gecko::IntersectionObserverRootMargin;
|
||||
use style::values::specified::source_size_list::SourceSizeList;
|
||||
use style::values::{CustomIdent, KeyframesName};
|
||||
use style_traits::{CssType, CssWriter, ParsingMode, StyleParseErrorKind, ToCss};
|
||||
@@ -6002,7 +6001,7 @@ pub extern "C" fn Servo_ComputeColor(
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn Servo_IntersectionObserverRootMargin_Parse(
|
||||
value: *const nsAString,
|
||||
result: *mut structs::nsStyleSides,
|
||||
result: *mut IntersectionObserverRootMargin,
|
||||
) -> bool {
|
||||
let value = value.as_ref().unwrap().to_string();
|
||||
let result = result.as_mut().unwrap();
|
||||
@@ -6024,7 +6023,7 @@ pub unsafe extern "C" fn Servo_IntersectionObserverRootMargin_Parse(
|
||||
let margin = parser.parse_entirely(|p| IntersectionObserverRootMargin::parse(&context, p));
|
||||
match margin {
|
||||
Ok(margin) => {
|
||||
margin.0.to_gecko_rect(result);
|
||||
*result = margin;
|
||||
true
|
||||
},
|
||||
Err(..) => false,
|
||||
@@ -6033,13 +6032,11 @@ pub unsafe extern "C" fn Servo_IntersectionObserverRootMargin_Parse(
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn Servo_IntersectionObserverRootMargin_ToString(
|
||||
rect: *const structs::nsStyleSides,
|
||||
root_margin: *const IntersectionObserverRootMargin,
|
||||
result: *mut nsAString,
|
||||
) {
|
||||
let rect = Rect::<PixelOrPercentage>::from_gecko_rect(rect.as_ref().unwrap()).unwrap();
|
||||
let root_margin = IntersectionObserverRootMargin(rect);
|
||||
let mut writer = CssWriter::new(result.as_mut().unwrap());
|
||||
root_margin.to_css(&mut writer).unwrap();
|
||||
let mut writer = CssWriter::new(&mut *result);
|
||||
(*root_margin).to_css(&mut writer).unwrap();
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
|
||||
Reference in New Issue
Block a user