Bug 1900232: Part 4 - Add anchor-size() to margin properties. r=firefox-style-system-reviewers,emilio

Differential Revision: https://phabricator.services.mozilla.com/D222533
This commit is contained in:
David Shin
2024-09-23 13:58:38 +00:00
parent ae690b1c13
commit 1fad4eeb43
30 changed files with 278 additions and 89 deletions

View File

@@ -1248,7 +1248,7 @@ already_AddRefed<AccAttributes> LocalAccessible::NativeAttributes() {
auto GetMargin = [&](mozilla::Side aSide) -> CSSCoord { auto GetMargin = [&](mozilla::Side aSide) -> CSSCoord {
// This is here only to guarantee that we do the same as getComputedStyle // This is here only to guarantee that we do the same as getComputedStyle
// does, so that we don't hit precision errors in tests. // does, so that we don't hit precision errors in tests.
auto& margin = f->StyleMargin()->mMargin.Get(aSide); const auto& margin = f->StyleMargin()->GetMargin(aSide);
if (margin.ConvertsToLength()) { if (margin.ConvertsToLength()) {
return margin.AsLengthPercentage().ToLengthInCSSPixels(); return margin.AsLengthPercentage().ToLengthInCSSPixels();
} }

View File

@@ -3414,11 +3414,11 @@ struct BoxToRect : public nsLayoutUtils::BoxCallback {
} else if (mFlags.contains(nsLayoutUtils::GetAllInFlowRectsFlag:: } else if (mFlags.contains(nsLayoutUtils::GetAllInFlowRectsFlag::
UseMarginBoxWithAutoResolvedAsZero)) { UseMarginBoxWithAutoResolvedAsZero)) {
r = aFrame->GetRectRelativeToSelf(); r = aFrame->GetRectRelativeToSelf();
const auto& styleMargin = aFrame->StyleMargin()->mMargin;
nsMargin usedMargin = nsMargin usedMargin =
aFrame->GetUsedMargin().ApplySkipSides(aFrame->GetSkipSides()); aFrame->GetUsedMargin().ApplySkipSides(aFrame->GetSkipSides());
const auto* styleMargin = aFrame->StyleMargin();
for (const Side side : AllPhysicalSides()) { for (const Side side : AllPhysicalSides()) {
if (styleMargin.Get(side).IsAuto()) { if (styleMargin->GetMargin(side).IsAuto()) {
usedMargin.Side(side) = 0; usedMargin.Side(side) = 0;
} }
} }

View File

@@ -1551,6 +1551,14 @@ class nsLayoutUtils {
return ComputeCBDependentValue(aPercentBasis, aInset.AsLengthPercentage()); return ComputeCBDependentValue(aPercentBasis, aInset.AsLengthPercentage());
} }
static nscoord ComputeCBDependentValue(nscoord aPercentBasis,
const mozilla::StyleMargin& aMargin) {
if (!aMargin.IsLengthPercentage()) {
return 0;
}
return ComputeCBDependentValue(aPercentBasis, aMargin.AsLengthPercentage());
}
static nscoord ComputeBSizeValue(nscoord aContainingBlockBSize, static nscoord ComputeBSizeValue(nscoord aContainingBlockBSize,
nscoord aContentEdgeToBoxSizingBoxEdge, nscoord aContentEdgeToBoxSizingBoxEdge,
const LengthPercentage& aCoord) { const LengthPercentage& aCoord) {

View File

@@ -61,7 +61,6 @@ nscoord CSSAlignUtils::AlignJustifySelf(const StyleAlignFlags& aAlignment,
const auto endSide = GetOppositeSide(startSide); const auto endSide = GetOppositeSide(startSide);
const nscoord marginEnd = margin.Side(endSide, wm); const nscoord marginEnd = margin.Side(endSide, wm);
const auto& styleMargin = aRI.mStyleMargin->mMargin;
bool hasAutoMarginStart; bool hasAutoMarginStart;
bool hasAutoMarginEnd; bool hasAutoMarginEnd;
if (aFlags & AlignJustifyFlags::IgnoreAutoMargins) { if (aFlags & AlignJustifyFlags::IgnoreAutoMargins) {
@@ -69,11 +68,15 @@ nscoord CSSAlignUtils::AlignJustifySelf(const StyleAlignFlags& aAlignment,
// don't need to do anything special to avoid expanding them.) // don't need to do anything special to avoid expanding them.)
hasAutoMarginStart = hasAutoMarginEnd = false; hasAutoMarginStart = hasAutoMarginEnd = false;
} else if (aAxis == LogicalAxis::Block) { } else if (aAxis == LogicalAxis::Block) {
hasAutoMarginStart = styleMargin.GetBStart(wm).IsAuto(); hasAutoMarginStart =
hasAutoMarginEnd = styleMargin.GetBEnd(wm).IsAuto(); aRI.mStyleMargin->GetMargin(LogicalSide::BStart, wm).IsAuto();
hasAutoMarginEnd =
aRI.mStyleMargin->GetMargin(LogicalSide::BEnd, wm).IsAuto();
} else { /* aAxis == LogicalAxis::Inline */ } else { /* aAxis == LogicalAxis::Inline */
hasAutoMarginStart = styleMargin.GetIStart(wm).IsAuto(); hasAutoMarginStart =
hasAutoMarginEnd = styleMargin.GetIEnd(wm).IsAuto(); aRI.mStyleMargin->GetMargin(LogicalSide::IStart, wm).IsAuto();
hasAutoMarginEnd =
aRI.mStyleMargin->GetMargin(LogicalSide::IEnd, wm).IsAuto();
} }
// https://drafts.csswg.org/css-align-3/#overflow-values // https://drafts.csswg.org/css-align-3/#overflow-values

View File

@@ -1135,9 +1135,9 @@ void ReflowInput::CalculateBorderPaddingMargin(
// correct margin value will be computed later in InitAbsoluteConstraints // correct margin value will be computed later in InitAbsoluteConstraints
// (which is caller of this function, via CalculateHypotheticalPosition). // (which is caller of this function, via CalculateHypotheticalPosition).
const nscoord start = nsLayoutUtils::ComputeCBDependentValue( const nscoord start = nsLayoutUtils::ComputeCBDependentValue(
aContainingBlockSize, mStyleMargin->mMargin.Get(startSide)); aContainingBlockSize, mStyleMargin->GetMargin(startSide));
const nscoord end = nsLayoutUtils::ComputeCBDependentValue( const nscoord end = nsLayoutUtils::ComputeCBDependentValue(
aContainingBlockSize, mStyleMargin->mMargin.Get(endSide)); aContainingBlockSize, mStyleMargin->GetMargin(endSide));
marginStartEnd = start + end; marginStartEnd = start + end;
} }
@@ -1865,8 +1865,10 @@ void ReflowInput::InitAbsoluteConstraints(const ReflowInput* aCBReflowInput,
nscoord availMarginSpace = nscoord availMarginSpace =
aCBSize.ISize(cbwm) - offsets.IStartEnd(cbwm) - margin.IStartEnd(cbwm) - aCBSize.ISize(cbwm) - offsets.IStartEnd(cbwm) - margin.IStartEnd(cbwm) -
borderPadding.IStartEnd(cbwm) - computedSize.ISize(cbwm); borderPadding.IStartEnd(cbwm) - computedSize.ISize(cbwm);
marginIStartIsAuto = mStyleMargin->mMargin.GetIStart(cbwm).IsAuto(); marginIStartIsAuto =
marginIEndIsAuto = mStyleMargin->mMargin.GetIEnd(cbwm).IsAuto(); mStyleMargin->GetMargin(LogicalSide::IStart, cbwm).IsAuto();
marginIEndIsAuto =
mStyleMargin->GetMargin(LogicalSide::IEnd, cbwm).IsAuto();
ComputeAbsPosInlineAutoMargin(availMarginSpace, cbwm, marginIStartIsAuto, ComputeAbsPosInlineAutoMargin(availMarginSpace, cbwm, marginIStartIsAuto,
marginIEndIsAuto, margin, offsets); marginIEndIsAuto, margin, offsets);
} }
@@ -1920,8 +1922,10 @@ void ReflowInput::InitAbsoluteConstraints(const ReflowInput* aCBReflowInput,
// * we're dealing with a replaced element // * we're dealing with a replaced element
// * bsize was constrained by min- or max-bsize. // * bsize was constrained by min- or max-bsize.
nscoord availMarginSpace = autoBSize - computedSize.BSize(cbwm); nscoord availMarginSpace = autoBSize - computedSize.BSize(cbwm);
marginBStartIsAuto = mStyleMargin->mMargin.GetBStart(cbwm).IsAuto(); marginBStartIsAuto =
marginBEndIsAuto = mStyleMargin->mMargin.GetBEnd(cbwm).IsAuto(); mStyleMargin->GetMargin(LogicalSide::BStart, cbwm).IsAuto();
marginBEndIsAuto =
mStyleMargin->GetMargin(LogicalSide::BEnd, cbwm).IsAuto();
ComputeAbsPosBlockAutoMargin(availMarginSpace, cbwm, marginBStartIsAuto, ComputeAbsPosBlockAutoMargin(availMarginSpace, cbwm, marginBStartIsAuto,
marginBEndIsAuto, margin, offsets); marginBEndIsAuto, margin, offsets);
@@ -2663,9 +2667,10 @@ void ReflowInput::CalculateBlockSideMargins() {
// The css2 spec clearly defines how block elements should behave // The css2 spec clearly defines how block elements should behave
// in section 10.3.3. // in section 10.3.3.
const auto& styleSides = mStyleMargin->mMargin; bool isAutoStartMargin =
bool isAutoStartMargin = styleSides.GetIStart(cbWM).IsAuto(); mStyleMargin->GetMargin(LogicalSide::IStart, cbWM).IsAuto();
bool isAutoEndMargin = styleSides.GetIEnd(cbWM).IsAuto(); bool isAutoEndMargin =
mStyleMargin->GetMargin(LogicalSide::IEnd, cbWM).IsAuto();
if (!isAutoStartMargin && !isAutoEndMargin) { if (!isAutoStartMargin && !isAutoEndMargin) {
// Neither margin is 'auto' so we're over constrained. Use the // Neither margin is 'auto' so we're over constrained. Use the
// 'direction' property of the parent to tell which margin to // 'direction' property of the parent to tell which margin to
@@ -2895,7 +2900,7 @@ bool SizeComputationInput::ComputeMargin(WritingMode aCBWM,
LogicalMargin m(aCBWM); LogicalMargin m(aCBWM);
for (const LogicalSide side : LogicalSides::All) { for (const LogicalSide side : LogicalSides::All) {
m.Side(side, aCBWM) = nsLayoutUtils::ComputeCBDependentValue( m.Side(side, aCBWM) = nsLayoutUtils::ComputeCBDependentValue(
aPercentBasis, styleMargin->mMargin.Get(side, aCBWM)); aPercentBasis, styleMargin->GetMargin(side, aCBWM));
} }
SetComputedLogicalMargin(aCBWM, m); SetComputedLogicalMargin(aCBWM, m);
} else { } else {

View File

@@ -2154,18 +2154,26 @@ inline bool nsStylePosition::MaxBSizeDependsOnContainer(WritingMode aWM) const {
} }
inline bool nsStyleMargin::HasBlockAxisAuto(mozilla::WritingMode aWM) const { inline bool nsStyleMargin::HasBlockAxisAuto(mozilla::WritingMode aWM) const {
return mMargin.GetBStart(aWM).IsAuto() || mMargin.GetBEnd(aWM).IsAuto(); return GetMargin(mozilla::LogicalSide::BStart, aWM).IsAuto() ||
GetMargin(mozilla::LogicalSide::BEnd, aWM).IsAuto();
} }
inline bool nsStyleMargin::HasInlineAxisAuto(mozilla::WritingMode aWM) const { inline bool nsStyleMargin::HasInlineAxisAuto(mozilla::WritingMode aWM) const {
return mMargin.GetIStart(aWM).IsAuto() || mMargin.GetIEnd(aWM).IsAuto(); return GetMargin(mozilla::LogicalSide::IStart, aWM).IsAuto() ||
GetMargin(mozilla::LogicalSide::IEnd, aWM).IsAuto();
} }
inline bool nsStyleMargin::HasAuto(mozilla::LogicalAxis aAxis, inline bool nsStyleMargin::HasAuto(mozilla::LogicalAxis aAxis,
mozilla::WritingMode aWM) const { mozilla::WritingMode aWM) const {
return aAxis == mozilla::LogicalAxis::Inline ? HasInlineAxisAuto(aWM) return aAxis == mozilla::LogicalAxis::Inline ? HasInlineAxisAuto(aWM)
: HasBlockAxisAuto(aWM); : HasBlockAxisAuto(aWM);
} }
inline const mozilla::StyleMargin& nsStyleMargin::GetMargin(
mozilla::LogicalSide aSide, mozilla::WritingMode aWM) const {
return GetMargin(aWM.PhysicalSide(aSide));
}
inline mozilla::StyleAlignFlags nsStylePosition::UsedSelfAlignment( inline mozilla::StyleAlignFlags nsStylePosition::UsedSelfAlignment(
mozilla::LogicalAxis aAxis, const mozilla::ComputedStyle* aParent) const { mozilla::LogicalAxis aAxis, const mozilla::ComputedStyle* aParent) const {
return aAxis == mozilla::LogicalAxis::Block ? UsedAlignSelf(aParent)._0 return aAxis == mozilla::LogicalAxis::Block ? UsedAlignSelf(aParent)._0

View File

@@ -282,7 +282,7 @@ void nsAbsoluteContainingBlock::Reflow(nsContainerFrame* aDelegatingFrame,
static inline bool IsFixedPaddingSize(const LengthPercentage& aCoord) { static inline bool IsFixedPaddingSize(const LengthPercentage& aCoord) {
return aCoord.ConvertsToLength(); return aCoord.ConvertsToLength();
} }
static inline bool IsFixedMarginSize(const LengthPercentageOrAuto& aCoord) { static inline bool IsFixedMarginSize(const StyleMargin& aCoord) {
return aCoord.ConvertsToLength(); return aCoord.ConvertsToLength();
} }
static inline bool IsFixedOffset(const StyleInset& aInset) { static inline bool IsFixedOffset(const StyleInset& aInset) {
@@ -323,8 +323,8 @@ bool nsAbsoluteContainingBlock::FrameDependsOnContainer(nsIFrame* f,
// See if f's position might have changed. If we're RTL then the // See if f's position might have changed. If we're RTL then the
// rules are slightly different. We'll assume percentage or auto // rules are slightly different. We'll assume percentage or auto
// margins will always induce a dependency on the size // margins will always induce a dependency on the size
if (!IsFixedMarginSize(margin->mMargin.GetIStart(wm)) || if (!IsFixedMarginSize(margin->GetMargin(LogicalSide::IStart, wm)) ||
!IsFixedMarginSize(margin->mMargin.GetIEnd(wm))) { !IsFixedMarginSize(margin->GetMargin(LogicalSide::IEnd, wm))) {
return true; return true;
} }
} }
@@ -350,8 +350,8 @@ bool nsAbsoluteContainingBlock::FrameDependsOnContainer(nsIFrame* f,
} }
// See if f's position might have changed. // See if f's position might have changed.
if (!IsFixedMarginSize(margin->mMargin.GetBStart(wm)) || if (!IsFixedMarginSize(margin->GetMargin(LogicalSide::BStart, wm)) ||
!IsFixedMarginSize(margin->mMargin.GetBEnd(wm))) { !IsFixedMarginSize(margin->GetMargin(LogicalSide::BEnd, wm))) {
return true; return true;
} }
} }
@@ -680,13 +680,15 @@ void nsAbsoluteContainingBlock::ResolveAutoMarginsAfterLayout(
if (wm.IsOrthogonalTo(outerWM)) { if (wm.IsOrthogonalTo(outerWM)) {
ReflowInput::ComputeAbsPosInlineAutoMargin( ReflowInput::ComputeAbsPosInlineAutoMargin(
availMarginSpace, outerWM, availMarginSpace, outerWM,
styleMargin->mMargin.GetIStart(outerWM).IsAuto(), styleMargin->GetMargin(LogicalSide::IStart, outerWM).IsAuto(),
styleMargin->mMargin.GetIEnd(outerWM).IsAuto(), aMargin, aOffsets); styleMargin->GetMargin(LogicalSide::IEnd, outerWM).IsAuto(), aMargin,
aOffsets);
} else { } else {
ReflowInput::ComputeAbsPosBlockAutoMargin( ReflowInput::ComputeAbsPosBlockAutoMargin(
availMarginSpace, outerWM, availMarginSpace, outerWM,
styleMargin->mMargin.GetBStart(outerWM).IsAuto(), styleMargin->GetMargin(LogicalSide::BStart, outerWM).IsAuto(),
styleMargin->mMargin.GetBEnd(outerWM).IsAuto(), aMargin, aOffsets); styleMargin->GetMargin(LogicalSide::BEnd, outerWM).IsAuto(), aMargin,
aOffsets);
} }
aKidReflowInput.SetComputedLogicalMargin(outerWM, aMargin); aKidReflowInput.SetComputedLogicalMargin(outerWM, aMargin);

View File

@@ -14,8 +14,10 @@ void nsContainerFrame::DoInlineIntrinsicISize(ISizeData* aData,
F& aHandleChildren) { F& aHandleChildren) {
using namespace mozilla; using namespace mozilla;
auto GetMargin = [](const LengthPercentageOrAuto& aCoord) -> nscoord { auto GetMargin = [](const mozilla::StyleMargin& aCoord) -> nscoord {
return aCoord.IsAuto() ? 0 : aCoord.AsLengthPercentage().Resolve(0); return !aCoord.IsLengthPercentage()
? 0
: aCoord.AsLengthPercentage().Resolve(0);
}; };
if (GetPrevInFlow()) return; // Already added. if (GetPrevInFlow()) return; // Already added.
@@ -45,7 +47,7 @@ void nsContainerFrame::DoInlineIntrinsicISize(ISizeData* aData,
// clamp negative calc() to 0 // clamp negative calc() to 0
std::max(stylePadding->mPadding.Get(startSide).Resolve(0), 0) + std::max(stylePadding->mPadding.Get(startSide).Resolve(0), 0) +
styleBorder->GetComputedBorderWidth(startSide) + styleBorder->GetComputedBorderWidth(startSide) +
GetMargin(styleMargin->mMargin.Get(startSide)); GetMargin(styleMargin->GetMargin(startSide));
if (MOZ_LIKELY(sliceBreak)) { if (MOZ_LIKELY(sliceBreak)) {
aData->mCurrentLine += startPBM; aData->mCurrentLine += startPBM;
} else { } else {
@@ -57,7 +59,7 @@ void nsContainerFrame::DoInlineIntrinsicISize(ISizeData* aData,
// clamp negative calc() to 0 // clamp negative calc() to 0
std::max(stylePadding->mPadding.Get(endSide).Resolve(0), 0) + std::max(stylePadding->mPadding.Get(endSide).Resolve(0), 0) +
styleBorder->GetComputedBorderWidth(endSide) + styleBorder->GetComputedBorderWidth(endSide) +
GetMargin(styleMargin->mMargin.Get(endSide)); GetMargin(styleMargin->GetMargin(endSide));
if (MOZ_UNLIKELY(!sliceBreak)) { if (MOZ_UNLIKELY(!sliceBreak)) {
clonePBM += endPBM; clonePBM += endPBM;
aData->mCurrentLine += clonePBM; aData->mCurrentLine += clonePBM;

View File

@@ -170,14 +170,13 @@ bool nsFirstLetterFrame::UseTightBounds() const {
} }
const auto wm = GetWritingMode(); const auto wm = GetWritingMode();
const auto& margin = StyleMargin()->mMargin; const auto& bStart = StyleMargin()->GetMargin(LogicalSide::BStart, wm);
const auto& bStart = margin.GetBStart(wm);
// Currently, we only check for margins with negative *length* values; // Currently, we only check for margins with negative *length* values;
// negative percentages seem unlikely to be used/useful in this context. // negative percentages seem unlikely to be used/useful in this context.
if (bStart.ConvertsToLength() && bStart.ToLength() < 0) { if (bStart.ConvertsToLength() && bStart.ToLength() < 0) {
return false; return false;
} }
const auto& bEnd = margin.GetBEnd(wm); const auto& bEnd = StyleMargin()->GetMargin(LogicalSide::BEnd, wm);
if (bEnd.ConvertsToLength() && bEnd.ToLength() < 0) { if (bEnd.ConvertsToLength() && bEnd.ToLength() < 0) {
return false; return false;
} }

View File

@@ -2221,7 +2221,7 @@ FlexItem::FlexItem(ReflowInput& aFlexItemReflowInput, float aFlexGrow,
#ifdef DEBUG #ifdef DEBUG
{ {
for (const auto side : LogicalSides::All) { for (const auto side : LogicalSides::All) {
if (styleMargin->mMargin.Get(side, mCBWM).IsAuto()) { if (styleMargin->GetMargin(side, mCBWM).IsAuto()) {
MOZ_ASSERT(GetMarginComponentForSide(side) == 0, MOZ_ASSERT(GetMarginComponentForSide(side) == 0,
"Someone else tried to resolve our auto margin"); "Someone else tried to resolve our auto margin");
} }
@@ -2440,10 +2440,10 @@ void FlexItem::ResolveFlexBaseSizeFromAspectRatio(
uint32_t FlexItem::NumAutoMarginsInAxis(LogicalAxis aAxis) const { uint32_t FlexItem::NumAutoMarginsInAxis(LogicalAxis aAxis) const {
uint32_t numAutoMargins = 0; uint32_t numAutoMargins = 0;
const auto& styleMargin = mFrame->StyleMargin()->mMargin; const auto* styleMargin = mFrame->StyleMargin();
for (const auto edge : {LogicalEdge::Start, LogicalEdge::End}) { for (const auto edge : {LogicalEdge::Start, LogicalEdge::End}) {
const auto side = MakeLogicalSide(aAxis, edge); const auto side = MakeLogicalSide(aAxis, edge);
if (styleMargin.Get(side, mCBWM).IsAuto()) { if (styleMargin->GetMargin(side, mCBWM).IsAuto()) {
numAutoMargins++; numAutoMargins++;
} }
} }
@@ -3522,9 +3522,9 @@ MainAxisPositionTracker::MainAxisPositionTracker(
void MainAxisPositionTracker::ResolveAutoMarginsInMainAxis(FlexItem& aItem) { void MainAxisPositionTracker::ResolveAutoMarginsInMainAxis(FlexItem& aItem) {
if (mNumAutoMarginsInMainAxis) { if (mNumAutoMarginsInMainAxis) {
const auto& styleMargin = aItem.Frame()->StyleMargin()->mMargin; const auto* styleMargin = aItem.Frame()->StyleMargin();
for (const auto side : {StartSide(), EndSide()}) { for (const auto side : {StartSide(), EndSide()}) {
if (styleMargin.Get(side, mWM).IsAuto()) { if (styleMargin->GetMargin(side, mWM).IsAuto()) {
// NOTE: This integer math will skew the distribution of remainder // NOTE: This integer math will skew the distribution of remainder
// app-units towards the end, which is fine. // app-units towards the end, which is fine.
nscoord curAutoMarginSize = nscoord curAutoMarginSize =
@@ -3918,9 +3918,9 @@ void SingleLineCrossAxisPositionTracker::ResolveAutoMarginsInCrossAxis(
// OK, we have at least one auto margin and we have some available space. // OK, we have at least one auto margin and we have some available space.
// Give each auto margin a share of the space. // Give each auto margin a share of the space.
const auto& styleMargin = aItem.Frame()->StyleMargin()->mMargin; const auto* styleMargin = aItem.Frame()->StyleMargin();
for (const auto side : {StartSide(), EndSide()}) { for (const auto side : {StartSide(), EndSide()}) {
if (styleMargin.Get(side, mWM).IsAuto()) { if (styleMargin->GetMargin(side, mWM).IsAuto()) {
MOZ_ASSERT(aItem.GetMarginComponentForSide(side) == 0, MOZ_ASSERT(aItem.GetMarginComponentForSide(side) == 0,
"Expecting auto margins to have value '0' before we " "Expecting auto margins to have value '0' before we "
"update them"); "update them");

View File

@@ -1210,7 +1210,7 @@ void nsIFrame::DidSetComputedStyle(ComputedStyle* aOldComputedStyle) {
bool needAnchorSuppression = false; bool needAnchorSuppression = false;
const nsStyleMargin* oldMargin = aOldComputedStyle->StyleMargin(); const nsStyleMargin* oldMargin = aOldComputedStyle->StyleMargin();
if (oldMargin->mMargin != StyleMargin()->mMargin) { if (!oldMargin->MarginEquals(*StyleMargin())) {
needAnchorSuppression = true; needAnchorSuppression = true;
} }
@@ -6179,9 +6179,9 @@ void nsIFrame::InlinePrefISizeData::ForceBreak(StyleClear aClearType) {
mLineIsEmpty = true; mLineIsEmpty = true;
} }
static nscoord ResolveMargin(const LengthPercentageOrAuto& aStyle, static nscoord ResolveMargin(const StyleMargin& aStyle,
nscoord aPercentageBasis) { nscoord aPercentageBasis) {
if (aStyle.IsAuto()) { if (!aStyle.IsLengthPercentage()) {
return nscoord(0); return nscoord(0);
} }
return nsLayoutUtils::ResolveToLength<false>(aStyle.AsLengthPercentage(), return nsLayoutUtils::ResolveToLength<false>(aStyle.AsLengthPercentage(),
@@ -6197,14 +6197,18 @@ static nsIFrame::IntrinsicSizeOffsetData IntrinsicSizeOffsets(
nsIFrame* aFrame, nscoord aPercentageBasis, bool aForISize) { nsIFrame* aFrame, nscoord aPercentageBasis, bool aForISize) {
nsIFrame::IntrinsicSizeOffsetData result; nsIFrame::IntrinsicSizeOffsetData result;
WritingMode wm = aFrame->GetWritingMode(); WritingMode wm = aFrame->GetWritingMode();
const auto& margin = aFrame->StyleMargin()->mMargin;
bool verticalAxis = aForISize == wm.IsVertical(); bool verticalAxis = aForISize == wm.IsVertical();
const auto* styleMargin = aFrame->StyleMargin();
if (verticalAxis) { if (verticalAxis) {
result.margin += ResolveMargin(margin.Get(eSideTop), aPercentageBasis); result.margin +=
result.margin += ResolveMargin(margin.Get(eSideBottom), aPercentageBasis); ResolveMargin(styleMargin->GetMargin(eSideTop), aPercentageBasis);
result.margin +=
ResolveMargin(styleMargin->GetMargin(eSideBottom), aPercentageBasis);
} else { } else {
result.margin += ResolveMargin(margin.Get(eSideLeft), aPercentageBasis); result.margin +=
result.margin += ResolveMargin(margin.Get(eSideRight), aPercentageBasis); ResolveMargin(styleMargin->GetMargin(eSideLeft), aPercentageBasis);
result.margin +=
ResolveMargin(styleMargin->GetMargin(eSideRight), aPercentageBasis);
} }
const auto& padding = aFrame->StylePadding()->mPadding; const auto& padding = aFrame->StylePadding()->mPadding;

View File

@@ -77,8 +77,8 @@ void nsInlineFrame::InvalidateFrameWithRect(const nsRect& aRect,
aRebuildDisplayItems); aRebuildDisplayItems);
} }
static inline bool IsMarginZero(const LengthPercentageOrAuto& aLength) { static inline bool IsMarginZero(const StyleMargin& aLength) {
return aLength.IsAuto() || return !aLength.IsLengthPercentage() ||
nsLayoutUtils::IsMarginZero(aLength.AsLengthPercentage()); nsLayoutUtils::IsMarginZero(aLength.AsLengthPercentage());
} }
@@ -103,7 +103,7 @@ bool nsInlineFrame::IsSelfEmpty() {
auto HaveSide = [&](mozilla::Side aSide) -> bool { auto HaveSide = [&](mozilla::Side aSide) -> bool {
return border->GetComputedBorderWidth(aSide) != 0 || return border->GetComputedBorderWidth(aSide) != 0 ||
!nsLayoutUtils::IsPaddingZero(padding->mPadding.Get(aSide)) || !nsLayoutUtils::IsPaddingZero(padding->mPadding.Get(aSide)) ||
!IsMarginZero(margin->mMargin.Get(aSide)); !IsMarginZero(margin->GetMargin(aSide));
}; };
// Initially set up haveStart and haveEnd in terms of visual (LTR/TTB) // 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 // coordinates; we'll exchange them later if bidi-RTL is in effect to

View File

@@ -629,6 +629,15 @@ static bool HasPercentageUnitSide(const StyleRect<T>& aSides) {
return aSides.Any([](const auto& aLength) { return aLength.HasPercent(); }); return aSides.Any([](const auto& aLength) { return aLength.HasPercent(); });
} }
static bool HasPercentageUnitMargin(const nsStyleMargin& aStyleMargin) {
for (const auto side : AllPhysicalSides()) {
if (aStyleMargin.GetMargin(side).HasPercent()) {
return true;
}
}
return false;
}
static bool IsPercentageAware(const nsIFrame* aFrame, WritingMode aWM) { static bool IsPercentageAware(const nsIFrame* aFrame, WritingMode aWM) {
MOZ_ASSERT(aFrame, "null frame is not allowed"); MOZ_ASSERT(aFrame, "null frame is not allowed");
@@ -644,7 +653,7 @@ static bool IsPercentageAware(const nsIFrame* aFrame, WritingMode aWM) {
// quite rarely. // quite rarely.
const nsStyleMargin* margin = aFrame->StyleMargin(); const nsStyleMargin* margin = aFrame->StyleMargin();
if (HasPercentageUnitSide(margin->mMargin)) { if (HasPercentageUnitMargin(*margin)) {
return true; return true;
} }

View File

@@ -125,9 +125,8 @@ nsReflowStatus nsPageFrame::ReflowPageContent(
// the document is intended to fit the paper size exactly, and the client is // the document is intended to fit the paper size exactly, and the client is
// taking full responsibility for what happens around the edges. // taking full responsibility for what happens around the edges.
if (mPD->mPrintSettings->GetHonorPageRuleMargins()) { if (mPD->mPrintSettings->GetHonorPageRuleMargins()) {
const auto& margin = kidReflowInput.mStyleMargin->mMargin;
for (const auto side : mozilla::AllPhysicalSides()) { for (const auto side : mozilla::AllPhysicalSides()) {
if (!margin.Get(side).IsAuto()) { if (!kidReflowInput.mStyleMargin->GetMargin(side).IsAuto()) {
// Computed margins are already in the coordinate space of the content, // Computed margins are already in the coordinate space of the content,
// do not scale. // do not scale.
const nscoord computed = const nscoord computed =

View File

@@ -1876,7 +1876,7 @@ bool BuildTextRunsScanner::ContinueTextRunAcrossFrames(nsTextFrame* aFrame1,
// //
// 1. Any of margin/border/padding separating the two typographic // 1. Any of margin/border/padding separating the two typographic
// character units in the inline axis is non-zero. // character units in the inline axis is non-zero.
const auto& margin = ctx->StyleMargin()->mMargin.Get(aSide); const auto& margin = ctx->StyleMargin()->GetMargin(aSide);
if (!margin.ConvertsToLength() || if (!margin.ConvertsToLength() ||
margin.AsLengthPercentage().ToLength() != 0) { margin.AsLengthPercentage().ToLength() != 0) {
return true; return true;

View File

@@ -633,6 +633,7 @@ cbindgen-types = [
{ gecko = "StyleInitialLetter", servo = "crate::values::computed::text::InitialLetter" }, { gecko = "StyleInitialLetter", servo = "crate::values::computed::text::InitialLetter" },
{ gecko = "StylePointerEvents", servo = "crate::values::computed::ui::PointerEvents" }, { gecko = "StylePointerEvents", servo = "crate::values::computed::ui::PointerEvents" },
{ gecko = "StyleInert", servo = "crate::values::computed::ui::Inert" }, { gecko = "StyleInert", servo = "crate::values::computed::ui::Inert" },
{ gecko = "StyleMargin", servo = "crate::values::computed::length::Margin" },
] ]
mapped-generic-types = [ mapped-generic-types = [

View File

@@ -808,6 +808,7 @@ IMPL_LENGTHPERCENTAGE_FORWARDS(LengthPercentageOrAuto)
IMPL_LENGTHPERCENTAGE_FORWARDS(StyleSize) IMPL_LENGTHPERCENTAGE_FORWARDS(StyleSize)
IMPL_LENGTHPERCENTAGE_FORWARDS(StyleMaxSize) IMPL_LENGTHPERCENTAGE_FORWARDS(StyleMaxSize)
IMPL_LENGTHPERCENTAGE_FORWARDS(StyleInset) IMPL_LENGTHPERCENTAGE_FORWARDS(StyleInset)
IMPL_LENGTHPERCENTAGE_FORWARDS(StyleMargin)
template <> template <>
inline bool StyleInset::IsAnchorPositioningFunction() const { inline bool StyleInset::IsAnchorPositioningFunction() const {

View File

@@ -985,7 +985,7 @@ bool nsComputedDOMStyle::NeedsToFlushLayout(nsCSSPropertyID aPropID) const {
// NOTE(emilio): This is dubious, but matches other browsers. // NOTE(emilio): This is dubious, but matches other browsers.
// See https://github.com/w3c/csswg-drafts/issues/2328 // See https://github.com/w3c/csswg-drafts/issues/2328
Side side = SideForPaddingOrMarginOrInsetProperty(aPropID); Side side = SideForPaddingOrMarginOrInsetProperty(aPropID);
return !style->StyleMargin()->mMargin.Get(side).ConvertsToLength(); return !style->StyleMargin()->GetMargin(side).ConvertsToLength();
} }
default: default:
return false; return false;
@@ -2088,10 +2088,10 @@ already_AddRefed<CSSValue> nsComputedDOMStyle::GetBorderWidthFor(
} }
already_AddRefed<CSSValue> nsComputedDOMStyle::GetMarginFor(Side aSide) { already_AddRefed<CSSValue> nsComputedDOMStyle::GetMarginFor(Side aSide) {
const auto& margin = StyleMargin()->mMargin.Get(aSide); const auto& margin = StyleMargin()->GetMargin(aSide);
if (!mInnerFrame || margin.ConvertsToLength()) { if (!mInnerFrame || margin.ConvertsToLength()) {
auto val = MakeRefPtr<nsROCSSPrimitiveValue>(); auto val = MakeRefPtr<nsROCSSPrimitiveValue>();
SetValueToLengthPercentageOrAuto(val, margin, false); SetValueToMargin(val, margin);
return val.forget(); return val.forget();
} }
AssertFlushedPendingReflows(); AssertFlushedPendingReflows();
@@ -2188,7 +2188,7 @@ void nsComputedDOMStyle::SetValueToLengthPercentageOrAuto(
void nsComputedDOMStyle::SetValueToInset(nsROCSSPrimitiveValue* aValue, void nsComputedDOMStyle::SetValueToInset(nsROCSSPrimitiveValue* aValue,
const mozilla::StyleInset& aInset) { const mozilla::StyleInset& aInset) {
// This function isn't used for absolutely positioned insets, so just assume // This function isn't used for absolutely positioned insets, so just assume
// `anchor()` is `auto`. // `anchor()` or `anchor-size()` is `auto`.
if (!aInset.IsLengthPercentage()) { if (!aInset.IsLengthPercentage()) {
aValue->SetString("auto"); aValue->SetString("auto");
return; return;
@@ -2196,6 +2196,16 @@ void nsComputedDOMStyle::SetValueToInset(nsROCSSPrimitiveValue* aValue,
SetValueToLengthPercentage(aValue, aInset.AsLengthPercentage(), false); SetValueToLengthPercentage(aValue, aInset.AsLengthPercentage(), false);
} }
void nsComputedDOMStyle::SetValueToMargin(nsROCSSPrimitiveValue* aValue,
const mozilla::StyleMargin& aMargin) {
// May have to compute `anchor-size()` value here.
if (!aMargin.IsLengthPercentage()) {
aValue->SetString("auto");
return;
}
SetValueToLengthPercentage(aValue, aMargin.AsLengthPercentage(), false);
}
void nsComputedDOMStyle::SetValueToLengthPercentage( void nsComputedDOMStyle::SetValueToLengthPercentage(
nsROCSSPrimitiveValue* aValue, const mozilla::LengthPercentage& aLength, nsROCSSPrimitiveValue* aValue, const mozilla::LengthPercentage& aLength,
bool aClampNegativeCalc) { bool aClampNegativeCalc) {

View File

@@ -297,6 +297,8 @@ class nsComputedDOMStyle final : public nsDOMCSSDeclaration,
bool aClampNegativeCalc); bool aClampNegativeCalc);
void SetValueToInset(nsROCSSPrimitiveValue* aValue, void SetValueToInset(nsROCSSPrimitiveValue* aValue,
const mozilla::StyleInset&); const mozilla::StyleInset&);
void SetValueToMargin(nsROCSSPrimitiveValue* aValue,
const mozilla::StyleMargin&);
void SetValueToLengthPercentage(nsROCSSPrimitiveValue* aValue, void SetValueToLengthPercentage(nsROCSSPrimitiveValue* aValue,
const LengthPercentage&, const LengthPercentage&,

View File

@@ -309,9 +309,12 @@ static StyleRect<T> StyleRectWithAllSides(const T& aSide) {
return {aSide, aSide, aSide, aSide}; return {aSide, aSide, aSide, aSide};
} }
const StyleMargin nsStyleMargin::kZeroMargin =
StyleMargin::LengthPercentage(StyleLengthPercentage::Zero());
nsStyleMargin::nsStyleMargin() nsStyleMargin::nsStyleMargin()
: mMargin(StyleRectWithAllSides( : mMargin(StyleRectWithAllSides(
LengthPercentageOrAuto::LengthPercentage(LengthPercentage::Zero()))), StyleMargin::LengthPercentage(LengthPercentage::Zero()))),
mScrollMargin(StyleRectWithAllSides(StyleLength{0.})), mScrollMargin(StyleRectWithAllSides(StyleLength{0.})),
mOverflowClipMargin(StyleLength::Zero()) { mOverflowClipMargin(StyleLength::Zero()) {
MOZ_COUNT_CTOR(nsStyleMargin); MOZ_COUNT_CTOR(nsStyleMargin);
@@ -328,7 +331,7 @@ nsChangeHint nsStyleMargin::CalcDifference(
const nsStyleMargin& aNewData) const { const nsStyleMargin& aNewData) const {
nsChangeHint hint = nsChangeHint(0); nsChangeHint hint = nsChangeHint(0);
if (mMargin != aNewData.mMargin) { if (!MarginEquals(aNewData)) {
// Margin differences can't affect descendant intrinsic sizes and // Margin differences can't affect descendant intrinsic sizes and
// don't need to force children to reflow. // don't need to force children to reflow.
hint |= nsChangeHint_NeedReflow | nsChangeHint_ReflowChangesSizeOrPosition | hint |= nsChangeHint_NeedReflow | nsChangeHint_ReflowChangesSizeOrPosition |

View File

@@ -368,7 +368,7 @@ struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleMargin {
} }
for (const auto side : mozilla::AllPhysicalSides()) { for (const auto side : mozilla::AllPhysicalSides()) {
aMargin.Side(side) = mMargin.Get(side).AsLengthPercentage().ToLength(); aMargin.Side(side) = GetMargin(side).AsLengthPercentage().ToLength();
} }
return true; return true;
} }
@@ -386,7 +386,33 @@ struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleMargin {
inline bool HasInlineAxisAuto(mozilla::WritingMode aWM) const; inline bool HasInlineAxisAuto(mozilla::WritingMode aWM) const;
inline bool HasAuto(mozilla::LogicalAxis, mozilla::WritingMode) const; inline bool HasAuto(mozilla::LogicalAxis, mozilla::WritingMode) const;
mozilla::StyleRect<mozilla::LengthPercentageOrAuto> mMargin; // TODO(dshin): The following functions are used as shims to deal
// anchor size functions as if it's zero, before the computation
// is implemented.
static const mozilla::StyleMargin kZeroMargin;
const mozilla::StyleMargin& GetMargin(mozilla::Side aSide) const {
const auto& result = mMargin.Get(aSide);
if (MOZ_UNLIKELY(result.IsAnchorSizeFunction())) {
return kZeroMargin;
}
return result;
}
bool MarginEquals(const nsStyleMargin& aOther) const {
for (const auto side : mozilla::AllPhysicalSides()) {
if (GetMargin(side) != aOther.GetMargin(side)) {
return false;
}
}
return true;
}
// As with other logical-coordinate accessors, definitions for these
// are found in WritingModes.h.
inline const mozilla::StyleMargin& GetMargin(mozilla::LogicalSide aSide,
mozilla::WritingMode aWM) const;
mozilla::StyleRect<mozilla::StyleMargin> mMargin;
mozilla::StyleRect<mozilla::StyleLength> mScrollMargin; mozilla::StyleRect<mozilla::StyleLength> mScrollMargin;
// TODO: Add support for overflow-clip-margin: <visual-box> and maybe // TODO: Add support for overflow-clip-margin: <visual-box> and maybe
// per-axis/side clipping, see https://github.com/w3c/csswg-drafts/issues/7245 // per-axis/side clipping, see https://github.com/w3c/csswg-drafts/issues/7245

View File

@@ -13,8 +13,8 @@
%> %>
${helpers.predefined_type( ${helpers.predefined_type(
"margin-%s" % side[0], "margin-%s" % side[0],
"LengthPercentageOrAuto", "Margin",
"computed::LengthPercentageOrAuto::zero()", "computed::Margin::zero()",
engines="gecko servo", engines="gecko servo",
aliases=maybe_moz_logical_alias(engine, side, "-moz-margin-%s"), aliases=maybe_moz_logical_alias(engine, side, "-moz-margin-%s"),
allow_quirks="No" if side[1] else "Yes", allow_quirks="No" if side[1] else "Yes",

View File

@@ -8,7 +8,7 @@
${helpers.four_sides_shorthand( ${helpers.four_sides_shorthand(
"margin", "margin",
"margin-%s", "margin-%s",
"specified::LengthPercentageOrAuto::parse", "specified::Margin::parse",
engines="gecko servo", engines="gecko servo",
spec="https://drafts.csswg.org/css-box/#propdef-margin", spec="https://drafts.csswg.org/css-box/#propdef-margin",
rule_types_allowed=DEFAULT_RULES_AND_PAGE | POSITION_TRY_RULE, rule_types_allowed=DEFAULT_RULES_AND_PAGE | POSITION_TRY_RULE,
@@ -19,7 +19,7 @@ ${helpers.two_properties_shorthand(
"margin-block", "margin-block",
"margin-block-start", "margin-block-start",
"margin-block-end", "margin-block-end",
"specified::LengthPercentageOrAuto::parse", "specified::Margin::parse",
engines="gecko servo", engines="gecko servo",
spec="https://drafts.csswg.org/css-logical/#propdef-margin-block", spec="https://drafts.csswg.org/css-logical/#propdef-margin-block",
rule_types_allowed=DEFAULT_RULES_AND_POSITION_TRY rule_types_allowed=DEFAULT_RULES_AND_POSITION_TRY
@@ -29,7 +29,7 @@ ${helpers.two_properties_shorthand(
"margin-inline", "margin-inline",
"margin-inline-start", "margin-inline-start",
"margin-inline-end", "margin-inline-end",
"specified::LengthPercentageOrAuto::parse", "specified::Margin::parse",
engines="gecko servo", engines="gecko servo",
spec="https://drafts.csswg.org/css-logical/#propdef-margin-inline", spec="https://drafts.csswg.org/css-logical/#propdef-margin-inline",
rule_types_allowed=DEFAULT_RULES_AND_POSITION_TRY rule_types_allowed=DEFAULT_RULES_AND_POSITION_TRY

View File

@@ -566,3 +566,6 @@ pub type MaxSize = GenericMaxSize<NonNegativeLengthPercentage>;
/// A computed value for `anchor-size` runction. /// A computed value for `anchor-size` runction.
pub type AnchorSizeFunction = GenericAnchorSizeFunction<LengthPercentage>; pub type AnchorSizeFunction = GenericAnchorSizeFunction<LengthPercentage>;
/// A computed type for `margin` properties.
pub type Margin = generics::GenericMargin<LengthPercentage>;

View File

@@ -74,7 +74,7 @@ pub use self::font::{MathDepth, MozScriptMinSize, MozScriptSizeMultiplier, XLang
pub use self::image::{Gradient, Image, ImageRendering, LineDirection}; pub use self::image::{Gradient, Image, ImageRendering, LineDirection};
pub use self::length::{AnchorSizeFunction, CSSPixelLength, NonNegativeLength}; pub use self::length::{AnchorSizeFunction, CSSPixelLength, NonNegativeLength};
pub use self::length::{Length, LengthOrNumber, LengthPercentage, NonNegativeLengthOrNumber}; pub use self::length::{Length, LengthOrNumber, LengthPercentage, NonNegativeLengthOrNumber};
pub use self::length::{LengthOrAuto, LengthPercentageOrAuto, MaxSize, Size}; pub use self::length::{LengthOrAuto, LengthPercentageOrAuto, MaxSize, Margin, Size};
pub use self::length::{NonNegativeLengthPercentage, NonNegativeLengthPercentageOrAuto}; pub use self::length::{NonNegativeLengthPercentage, NonNegativeLengthPercentageOrAuto};
#[cfg(feature = "gecko")] #[cfg(feature = "gecko")]
pub use self::list::ListStyleType; pub use self::list::ListStyleType;

View File

@@ -11,10 +11,10 @@ use crate::values::DashedIdent;
use crate::Zero; use crate::Zero;
use cssparser::Parser; use cssparser::Parser;
use std::fmt::Write; use std::fmt::Write;
use style_traits::CssWriter;
use style_traits::ParseError; use style_traits::ParseError;
use style_traits::StyleParseErrorKind; use style_traits::StyleParseErrorKind;
use style_traits::ToCss; use style_traits::ToCss;
use style_traits::{CssWriter, SpecifiedValueInfo};
/// A `<length-percentage> | auto` value. /// A `<length-percentage> | auto` value.
#[allow(missing_docs)] #[allow(missing_docs)]
@@ -466,3 +466,64 @@ pub enum AnchorSizeKeyword {
/// Same as `Inline`, resolved against the positioned element's writing mode. /// Same as `Inline`, resolved against the positioned element's writing mode.
SelfInline, SelfInline,
} }
/// Specified type for `margin` properties, which allows
/// the use of the `anchor-size()` function.
#[derive(
Animate,
Clone,
ComputeSquaredDistance,
Debug,
MallocSizeOf,
PartialEq,
ToCss,
ToShmem,
ToAnimatedValue,
ToAnimatedZero,
ToComputedValue,
ToResolvedValue,
)]
#[repr(C)]
pub enum GenericMargin<LP> {
/// A `<length-percentage>` value.
LengthPercentage(LP),
/// An `auto` value.
Auto,
/// Margin size defined by the anchor element.
///
/// https://drafts.csswg.org/css-anchor-position-1/#funcdef-anchor-size
AnchorSizeFunction(
#[animation(field_bound)]
#[distance(field_bound)]
Box<GenericAnchorSizeFunction<LP>>,
),
}
impl<LP> SpecifiedValueInfo for GenericMargin<LP>
where
LP: SpecifiedValueInfo,
{
fn collect_completion_keywords(f: style_traits::KeywordsCollectFn) {
LP::collect_completion_keywords(f);
f(&["auto"]);
if static_prefs::pref!("layout.css.anchor-positioning.enabled") {
f(&["anchor-size"]);
}
}
}
impl<LP> Zero for GenericMargin<LP>
where
LP: Zero,
{
fn is_zero(&self) -> bool {
match self {
Self::LengthPercentage(l) => l.is_zero(),
Self::Auto | Self::AnchorSizeFunction(_) => false,
}
}
fn zero() -> Self {
Self::LengthPercentage(LP::zero())
}
}

View File

@@ -16,7 +16,7 @@ use crate::values::computed::{self, CSSPixelLength, Context};
use crate::values::generics::length as generics; use crate::values::generics::length as generics;
use crate::values::generics::length::{ use crate::values::generics::length::{
GenericAnchorSizeFunction, GenericLengthOrNumber, GenericLengthPercentageOrNormal, GenericAnchorSizeFunction, GenericLengthOrNumber, GenericLengthPercentageOrNormal,
GenericMaxSize, GenericSize, GenericMargin, GenericMaxSize, GenericSize,
}; };
use crate::values::generics::NonNegative; use crate::values::generics::NonNegative;
use crate::values::specified::calc::{self, CalcNode}; use crate::values::specified::calc::{self, CalcNode};
@@ -2057,3 +2057,36 @@ pub type NonNegativeLengthOrNumber = GenericLengthOrNumber<NonNegativeLength, No
/// A specified value for `anchor-size` function. /// A specified value for `anchor-size` function.
pub type AnchorSizeFunction = GenericAnchorSizeFunction<LengthPercentage>; pub type AnchorSizeFunction = GenericAnchorSizeFunction<LengthPercentage>;
/// A specified value for `margin` properties.
pub type Margin = GenericMargin<LengthPercentage>;
impl Margin {
/// Parses an inset type, allowing the unitless length quirk.
/// <https://quirks.spec.whatwg.org/#the-unitless-length-quirk>
#[inline]
pub fn parse_quirky<'i, 't>(
context: &ParserContext,
input: &mut Parser<'i, 't>,
allow_quirks: AllowQuirks,
) -> Result<Self, ParseError<'i>> {
if let Ok(l) = input.try_parse(|i| LengthPercentage::parse_quirky(context, i, allow_quirks))
{
return Ok(Self::LengthPercentage(l));
}
if input.try_parse(|i| i.expect_ident_matching("auto")).is_ok() {
return Ok(Self::Auto);
}
let inner = AnchorSizeFunction::parse(context, input)?;
Ok(Self::AnchorSizeFunction(Box::new(inner)))
}
}
impl Parse for Margin {
fn parse<'i, 't>(
context: &ParserContext,
input: &mut Parser<'i, 't>,
) -> Result<Self, ParseError<'i>> {
Self::parse_quirky(context, input, AllowQuirks::No)
}
}

View File

@@ -66,7 +66,7 @@ pub use self::image::{EndingShape as GradientEndingShape, Gradient, Image, Image
pub use self::length::{AbsoluteLength, AnchorSizeFunction, CalcLengthPercentage, CharacterWidth}; pub use self::length::{AbsoluteLength, AnchorSizeFunction, CalcLengthPercentage, CharacterWidth};
pub use self::length::{FontRelativeLength, Length, LengthOrNumber, NonNegativeLengthOrNumber}; pub use self::length::{FontRelativeLength, Length, LengthOrNumber, NonNegativeLengthOrNumber};
pub use self::length::{LengthOrAuto, LengthPercentage, LengthPercentageOrAuto}; pub use self::length::{LengthOrAuto, LengthPercentage, LengthPercentageOrAuto};
pub use self::length::{MaxSize, Size}; pub use self::length::{Margin, MaxSize, Size};
pub use self::length::{NoCalcLength, ViewportPercentageLength, ViewportVariant}; pub use self::length::{NoCalcLength, ViewportPercentageLength, ViewportVariant};
pub use self::length::{ pub use self::length::{
NonNegativeLength, NonNegativeLengthPercentage, NonNegativeLengthPercentageOrAuto, NonNegativeLength, NonNegativeLengthPercentage, NonNegativeLengthPercentageOrAuto,

View File

@@ -325,6 +325,7 @@ include = [
"Inset", "Inset",
"AnchorFunction", "AnchorFunction",
"AnchorSizeFunction", "AnchorSizeFunction",
"Margin",
] ]
item_types = ["enums", "structs", "unions", "typedefs", "functions", "constants"] item_types = ["enums", "structs", "unions", "typedefs", "functions", "constants"]
renaming_overrides_prefixing = true renaming_overrides_prefixing = true
@@ -1142,3 +1143,12 @@ renaming_overrides_prefixing = true
inline bool ConvertsToPercentage() const; inline bool ConvertsToPercentage() const;
inline float ToPercentage() const; inline float ToPercentage() const;
""" """
"GenericMargin" = """
inline bool HasPercent() const;
inline bool ConvertsToLength() const;
inline bool HasLengthAndPercentage() const;
inline nscoord ToLength() const;
inline bool ConvertsToPercentage() const;
inline float ToPercentage() const;
"""

View File

@@ -5588,7 +5588,7 @@ pub extern "C" fn Servo_DeclarationBlock_SetPixelValue(
) { ) {
use style::properties::longhands::border_spacing::SpecifiedValue as BorderSpacing; use style::properties::longhands::border_spacing::SpecifiedValue as BorderSpacing;
use style::properties::PropertyDeclaration; use style::properties::PropertyDeclaration;
use style::values::generics::length::{LengthPercentageOrAuto, Size}; use style::values::generics::length::{GenericMargin, Size};
use style::values::generics::NonNegative; use style::values::generics::NonNegative;
use style::values::specified::length::{ use style::values::specified::length::{
LengthPercentage, NonNegativeLength, NonNegativeLengthPercentage, LengthPercentage, NonNegativeLength, NonNegativeLengthPercentage,
@@ -5598,7 +5598,7 @@ pub extern "C" fn Servo_DeclarationBlock_SetPixelValue(
let long = get_longhand_from_id!(property); let long = get_longhand_from_id!(property);
let nocalc = NoCalcLength::from_px(value); let nocalc = NoCalcLength::from_px(value);
let lp = LengthPercentage::Length(nocalc); let lp = LengthPercentage::Length(nocalc);
let lp_or_auto = LengthPercentageOrAuto::LengthPercentage(lp.clone()); let margin = GenericMargin::LengthPercentage(lp.clone());
let prop = match_wrap_declared! { long, let prop = match_wrap_declared! { long,
Height => Size::LengthPercentage(NonNegative(lp)), Height => Size::LengthPercentage(NonNegative(lp)),
Width => Size::LengthPercentage(NonNegative(lp)), Width => Size::LengthPercentage(NonNegative(lp)),
@@ -5606,10 +5606,10 @@ pub extern "C" fn Servo_DeclarationBlock_SetPixelValue(
BorderRightWidth => BorderSideWidth::from_px(value), BorderRightWidth => BorderSideWidth::from_px(value),
BorderBottomWidth => BorderSideWidth::from_px(value), BorderBottomWidth => BorderSideWidth::from_px(value),
BorderLeftWidth => BorderSideWidth::from_px(value), BorderLeftWidth => BorderSideWidth::from_px(value),
MarginTop => lp_or_auto, MarginTop => margin,
MarginRight => lp_or_auto, MarginRight => margin,
MarginBottom => lp_or_auto, MarginBottom => margin,
MarginLeft => lp_or_auto, MarginLeft => margin,
PaddingTop => NonNegative(lp), PaddingTop => NonNegative(lp),
PaddingRight => NonNegative(lp), PaddingRight => NonNegative(lp),
PaddingBottom => NonNegative(lp), PaddingBottom => NonNegative(lp),
@@ -5827,7 +5827,7 @@ pub extern "C" fn Servo_DeclarationBlock_SetPercentValue(
) { ) {
use style::properties::PropertyDeclaration; use style::properties::PropertyDeclaration;
use style::values::computed::Percentage; use style::values::computed::Percentage;
use style::values::generics::length::{LengthPercentageOrAuto, Size}; use style::values::generics::length::{GenericMargin, LengthPercentageOrAuto, Size};
use style::values::generics::NonNegative; use style::values::generics::NonNegative;
use style::values::specified::length::LengthPercentage; use style::values::specified::length::LengthPercentage;
use style::values::specified::FontSize; use style::values::specified::FontSize;
@@ -5835,7 +5835,7 @@ pub extern "C" fn Servo_DeclarationBlock_SetPercentValue(
let long = get_longhand_from_id!(property); let long = get_longhand_from_id!(property);
let pc = Percentage(value); let pc = Percentage(value);
let lp = LengthPercentage::Percentage(pc); let lp = LengthPercentage::Percentage(pc);
let lp_or_auto = LengthPercentageOrAuto::LengthPercentage(lp.clone()); let margin = GenericMargin::LengthPercentage(lp.clone());
let prop = match_wrap_declared! { long, let prop = match_wrap_declared! { long,
Height => Size::LengthPercentage(NonNegative(lp)), Height => Size::LengthPercentage(NonNegative(lp)),
@@ -5847,10 +5847,10 @@ pub extern "C" fn Servo_DeclarationBlock_SetPercentValue(
R => NonNegative(lp), R => NonNegative(lp),
Rx => LengthPercentageOrAuto::LengthPercentage(NonNegative(lp)), Rx => LengthPercentageOrAuto::LengthPercentage(NonNegative(lp)),
Ry => LengthPercentageOrAuto::LengthPercentage(NonNegative(lp)), Ry => LengthPercentageOrAuto::LengthPercentage(NonNegative(lp)),
MarginTop => lp_or_auto, MarginTop => margin,
MarginRight => lp_or_auto, MarginRight => margin,
MarginBottom => lp_or_auto, MarginBottom => margin,
MarginLeft => lp_or_auto, MarginLeft => margin,
FontSize => FontSize::Length(LengthPercentage::Percentage(pc)), FontSize => FontSize::Length(LengthPercentage::Percentage(pc)),
}; };
write_locked_arc(declarations, |decls: &mut PropertyDeclarationBlock| { write_locked_arc(declarations, |decls: &mut PropertyDeclarationBlock| {
@@ -5864,10 +5864,10 @@ pub extern "C" fn Servo_DeclarationBlock_SetAutoValue(
property: nsCSSPropertyID, property: nsCSSPropertyID,
) { ) {
use style::properties::PropertyDeclaration; use style::properties::PropertyDeclaration;
use style::values::generics::length::{LengthPercentageOrAuto, Size}; use style::values::generics::length::{GenericMargin, Size};
let long = get_longhand_from_id!(property); let long = get_longhand_from_id!(property);
let auto = LengthPercentageOrAuto::Auto; let auto = GenericMargin::Auto;
let prop = match_wrap_declared! { long, let prop = match_wrap_declared! { long,
Height => Size::auto(), Height => Size::auto(),