commit 9fc44ce3cd0ae46d38344a9201b2c40d38fd283a
parent 7f1600615e462565231800ac0df06569962d1caf
Author: agoloman <agoloman@mozilla.com>
Date: Thu, 18 Dec 2025 19:05:46 +0200
Revert "Bug 2006402: Properly resolve auto inset/margin in nsComputedDOMStyle with anchor positioning. r=layout-anchor-positioning-reviewers,firefox-style-system-reviewers,emilio" for causing build bustages @nsStyleStruct.cpp.
This reverts commit 6e861d0db3e83e4c7c0aa74dc422b02d7514bbbf.
Revert "Bug 2006402: Use physical axes for flagging anchor-center use. r=layout-anchor-positioning-reviewers,firefox-style-system-reviewers,emilio"
This reverts commit 56907edbced39dadadc4779d62eb9dee4bedb755.
Revert "Bug 2006402: Remove anchor-center flags in reflowinput. r=layout-anchor-positioning-reviewers,layout-reviewers,emilio"
This reverts commit 3d67a1059f6f1b8b698a45fcea4f513bc4917b40.
Revert "Bug 2006402: Ensure that we override auto insets/margins only when there's position-area/anchor-center + valid default anchor. r=layout-anchor-positioning-reviewers,firefox-style-system-reviewers,layout-reviewers,emilio"
This reverts commit 8e1950452fbb5138d50c252ae3189de14b088a47.
Diffstat:
11 files changed, 179 insertions(+), 268 deletions(-)
diff --git a/layout/generic/AbsoluteContainingBlock.cpp b/layout/generic/AbsoluteContainingBlock.cpp
@@ -971,7 +971,7 @@ void AbsoluteContainingBlock::ResolveAutoMarginsAfterLayout(
const auto anchorResolutionParams =
AnchorPosResolutionParams::From(&aKidReflowInput);
- auto ResolveMarginsInAxis = [&](LogicalAxis aAxis) {
+ auto ResolveMarginsInAxis = [&](LogicalAxis aAxis, bool aAnchorCenter) {
const auto startSide = MakeLogicalSide(aAxis, LogicalEdge::Start);
const auto endSide = MakeLogicalSide(aAxis, LogicalEdge::End);
@@ -1000,18 +1000,20 @@ void AbsoluteContainingBlock::ResolveAutoMarginsAfterLayout(
->IsAuto();
if (aAxis == LogicalAxis::Inline) {
- ReflowInput::ComputeAbsPosInlineAutoMargin(availMarginSpace, outerWM,
- startSideMarginIsAuto,
- endSideMarginIsAuto, aMargin);
+ ReflowInput::ComputeAbsPosInlineAutoMargin(
+ availMarginSpace, outerWM, startSideMarginIsAuto, endSideMarginIsAuto,
+ aAnchorCenter, aMargin);
} else {
- ReflowInput::ComputeAbsPosBlockAutoMargin(availMarginSpace, outerWM,
- startSideMarginIsAuto,
- endSideMarginIsAuto, aMargin);
+ ReflowInput::ComputeAbsPosBlockAutoMargin(
+ availMarginSpace, outerWM, startSideMarginIsAuto, endSideMarginIsAuto,
+ aAnchorCenter, aMargin);
}
};
- ResolveMarginsInAxis(LogicalAxis::Inline);
- ResolveMarginsInAxis(LogicalAxis::Block);
+ ResolveMarginsInAxis(LogicalAxis::Inline,
+ aKidReflowInput.mFlags.mIAnchorCenter);
+ ResolveMarginsInAxis(LogicalAxis::Block,
+ aKidReflowInput.mFlags.mBAnchorCenter);
aKidReflowInput.SetComputedLogicalMargin(outerWM, aMargin);
nsMargin* propValue =
@@ -1462,9 +1464,10 @@ void AbsoluteContainingBlock::ReflowAbsoluteFrame(
const auto* placeholderContainer =
GetPlaceholderContainer(kidReflowInput.mFrame);
- if (!iInsetAuto) {
+ if (!iInsetAuto || kidReflowInput.mFlags.mIAnchorCenter) {
MOZ_ASSERT(
- !kidReflowInput.mFlags.mIOffsetsNeedCSSAlign,
+ !kidReflowInput.mFlags.mIOffsetsNeedCSSAlign ||
+ kidReflowInput.mFlags.mIAnchorCenter,
"Non-auto inline inset but requires CSS alignment for static "
"position?");
auto alignOffset = OffsetToAlignedStaticPos(
@@ -1481,8 +1484,9 @@ void AbsoluteContainingBlock::ReflowAbsoluteFrame(
cbSize.ISize(outerWM) -
(offsets.IStart(outerWM) + kidMarginBox.ISize(outerWM));
}
- if (!bInsetAuto) {
- MOZ_ASSERT(!kidReflowInput.mFlags.mBOffsetsNeedCSSAlign,
+ if (!bInsetAuto || kidReflowInput.mFlags.mBAnchorCenter) {
+ MOZ_ASSERT(!kidReflowInput.mFlags.mBOffsetsNeedCSSAlign ||
+ kidReflowInput.mFlags.mBAnchorCenter,
"Non-auto block inset but requires CSS alignment for static "
"position?");
auto alignOffset = OffsetToAlignedStaticPos(
diff --git a/layout/generic/ReflowInput.cpp b/layout/generic/ReflowInput.cpp
@@ -43,13 +43,23 @@ using namespace mozilla::layout;
AnchorPosResolutionParams AnchorPosResolutionParams::From(
const mozilla::SizeComputationInput* aSizingInput,
bool aIgnorePositionArea) {
- auto override = AutoResolutionOverrideParams{
- aSizingInput->mFrame, aSizingInput->mAnchorPosResolutionCache};
- if (aIgnorePositionArea) {
- override.mPositionAreaInUse = false;
- }
- return {aSizingInput->mFrame, aSizingInput->mFrame->StyleDisplay()->mPosition,
- aSizingInput->mAnchorPosResolutionCache, override};
+ const mozilla::StylePositionArea posArea =
+ aIgnorePositionArea
+ ? mozilla::StylePositionArea{}
+ : aSizingInput->mFrame->StylePosition()->mPositionArea;
+ bool inlineUsesAnchorCenter = false;
+ bool blockUsesAnchorCenter = false;
+
+ ComputeAnchorCenterUsage(aSizingInput->mFrame,
+ aSizingInput->mAnchorPosResolutionCache,
+ inlineUsesAnchorCenter, blockUsesAnchorCenter);
+
+ return {aSizingInput->mFrame,
+ aSizingInput->mFrame->StyleDisplay()->mPosition,
+ posArea,
+ aSizingInput->mAnchorPosResolutionCache,
+ inlineUsesAnchorCenter,
+ blockUsesAnchorCenter};
}
static bool CheckNextInFlowParenthood(nsIFrame* aFrame, nsIFrame* aParent) {
@@ -58,6 +68,32 @@ static bool CheckNextInFlowParenthood(nsIFrame* aFrame, nsIFrame* aParent) {
return frameNext && parentNext && frameNext->GetParent() == parentNext;
}
+void ComputeAnchorCenterUsage(
+ const nsIFrame* aFrame,
+ mozilla::AnchorPosResolutionCache* aAnchorPosResolutionCache,
+ bool& aInlineUsesAnchorCenter, bool& aBlockUsesAnchorCenter) {
+ aInlineUsesAnchorCenter = false;
+ aBlockUsesAnchorCenter = false;
+ nsIFrame* parent = aFrame->GetParent();
+ if (!parent || !aFrame->HasAnyStateBits(NS_FRAME_OUT_OF_FLOW) ||
+ !aAnchorPosResolutionCache ||
+ !aAnchorPosResolutionCache->mDefaultAnchorCache.mAnchor) {
+ return;
+ }
+
+ const auto* stylePos = aFrame->StylePosition();
+
+ auto checkAxis = [&](LogicalAxis aAxis) {
+ StyleAlignFlags alignment =
+ stylePos->UsedSelfAlignment(aAxis, parent->Style());
+ return (alignment & ~StyleAlignFlags::FLAG_BITS) ==
+ StyleAlignFlags::ANCHOR_CENTER;
+ };
+
+ aInlineUsesAnchorCenter = checkAxis(LogicalAxis::Inline);
+ aBlockUsesAnchorCenter = checkAxis(LogicalAxis::Block);
+}
+
/**
* Adjusts the margin for a list (ol, ul), if necessary, depending on
* font inflation settings. Unfortunately, because bullets from a list are
@@ -305,6 +341,7 @@ ReflowInput::ReflowInput(nsPresContext* aPresContext,
mFlags.mDummyParentReflowInput = false;
mFlags.mStaticPosIsCBOrigin = aFlags.contains(InitFlag::StaticPosIsCBOrigin);
mFlags.mIOffsetsNeedCSSAlign = mFlags.mBOffsetsNeedCSSAlign = false;
+ mFlags.mIAnchorCenter = mFlags.mBAnchorCenter = false;
// We don't want the mOrthogonalCellFinalReflow flag to be inherited; it's up
// to the table row frame to set it for its direct children as needed.
@@ -1144,7 +1181,18 @@ void ReflowInput::ComputeAbsPosInlineAutoMargin(nscoord aAvailMarginSpace,
WritingMode aContainingBlockWM,
bool aIsMarginIStartAuto,
bool aIsMarginIEndAuto,
+ bool aIsIAnchorCenter,
LogicalMargin& aMargin) {
+ if (aIsIAnchorCenter) {
+ // `anchor-center` sets any use of `auto` margin to 0.
+ if (aIsMarginIStartAuto) {
+ aMargin.IStart(aContainingBlockWM) = 0;
+ }
+ if (aIsMarginIEndAuto) {
+ aMargin.IEnd(aContainingBlockWM) = 0;
+ }
+ return;
+ }
if (aIsMarginIStartAuto) {
if (aIsMarginIEndAuto) {
if (aAvailMarginSpace < 0) {
@@ -1178,7 +1226,18 @@ void ReflowInput::ComputeAbsPosBlockAutoMargin(nscoord aAvailMarginSpace,
WritingMode aContainingBlockWM,
bool aIsMarginBStartAuto,
bool aIsMarginBEndAuto,
+ bool aIsBAnchorCenter,
LogicalMargin& aMargin) {
+ if (aIsBAnchorCenter) {
+ // `anchor-center` sets any use of `auto` margin to 0.
+ if (aIsMarginBStartAuto) {
+ aMargin.BStart(aContainingBlockWM) = 0;
+ }
+ if (aIsMarginBEndAuto) {
+ aMargin.BEnd(aContainingBlockWM) = 0;
+ }
+ return;
+ }
if (aIsMarginBStartAuto) {
if (aIsMarginBEndAuto) {
// Both 'margin-top' and 'margin-bottom' are 'auto', so they get
@@ -1696,6 +1755,16 @@ void ReflowInput::InitAbsoluteConstraints(const ReflowInput* aCBReflowInput,
bool bStartIsAuto = bStartOffset->IsAuto();
bool bEndIsAuto = bEndOffset->IsAuto();
+ mFlags.mIAnchorCenter = anchorResolutionParams.mBaseParams.mIAnchorCenter;
+ mFlags.mBAnchorCenter = anchorResolutionParams.mBaseParams.mBAnchorCenter;
+
+ // For anchor-center with both insets auto, insets need to be kept as 0
+ // so hypothetical position should be skipped.
+ const bool inlineBothInsetsAuto =
+ mFlags.mIAnchorCenter && iStartIsAuto && iEndIsAuto;
+ const bool blockBothInsetsAuto =
+ mFlags.mBAnchorCenter && bStartIsAuto && bEndIsAuto;
+
// If both 'inline-start' and 'inline-end' are 'auto' or both 'block-start'
// and 'block-end' are 'auto', then compute the hypothetical box position
// where the element would have if it were in the flow.
@@ -1781,7 +1850,7 @@ void ReflowInput::InitAbsoluteConstraints(const ReflowInput* aCBReflowInput,
nsLayoutUtils::ComputeCBDependentValue(aCBSize.ISize(cbwm), iEndOffset);
}
- if (iStartIsAuto && iEndIsAuto) {
+ if (iStartIsAuto && iEndIsAuto && !inlineBothInsetsAuto) {
if (cbwm.IsInlineReversed() !=
hypotheticalPos.mWritingMode.IsInlineReversed()) {
offsets.IEnd(cbwm) = hypotheticalPos.mIStart;
@@ -1805,7 +1874,7 @@ void ReflowInput::InitAbsoluteConstraints(const ReflowInput* aCBReflowInput,
nsLayoutUtils::ComputeCBDependentValue(aCBSize.BSize(cbwm), bEndOffset);
}
- if (bStartIsAuto && bEndIsAuto) {
+ if (bStartIsAuto && bEndIsAuto && !blockBothInsetsAuto) {
// Treat 'top' like 'static-position'
offsets.BStart(cbwm) = hypotheticalPos.mBStart;
bStartIsAuto = false;
diff --git a/layout/generic/ReflowInput.h b/layout/generic/ReflowInput.h
@@ -512,6 +512,11 @@ struct ReflowInput : public SizeComputationInput {
bool mIOffsetsNeedCSSAlign : 1;
bool mBOffsetsNeedCSSAlign : 1;
+ // True when anchor-center is being used with a valid anchor and at least
+ // one inset is auto on this axis. Used to zero out margins.
+ bool mIAnchorCenter : 1;
+ bool mBAnchorCenter : 1;
+
// Is this frame or one of its ancestors being reflowed in a different
// continuation than the one in which it was previously reflowed? In
// other words, has it moved to a different column or page than it was in
@@ -825,6 +830,7 @@ struct ReflowInput : public SizeComputationInput {
WritingMode aContainingBlockWM,
bool aIsMarginBStartAuto,
bool aIsMarginBEndAuto,
+ bool aIsIAnchorCenter,
LogicalMargin& aMargin);
// Resolve any inline-axis 'auto' margins (if any) for an absolutely
@@ -834,6 +840,7 @@ struct ReflowInput : public SizeComputationInput {
WritingMode aContainingBlockWM,
bool aIsMarginIStartAuto,
bool aIsMarginIEndAuto,
+ bool aIsBAnchorCenter,
LogicalMargin& aMargin);
protected:
@@ -975,4 +982,9 @@ struct ReflowInput : public SizeComputationInput {
} // namespace mozilla
+void ComputeAnchorCenterUsage(
+ const nsIFrame* aFrame,
+ mozilla::AnchorPosResolutionCache* aAnchorPosResolutionCache,
+ bool& aInlineUsesAnchorCenter, bool& aBlockUsesAnchorCenter);
+
#endif // mozilla_ReflowInput_h
diff --git a/layout/generic/nsIFrame.cpp b/layout/generic/nsIFrame.cpp
@@ -7229,7 +7229,7 @@ LogicalSize nsIFrame::ComputeAbsolutePosAutoSize(
const auto* stylePos = StylePosition();
const auto anchorResolutionParams =
AnchorPosOffsetResolutionParams::UseCBFrameSize(
- AnchorPosResolutionParams::From(&aSizingInput));
+ AnchorPosResolutionParams::From(this));
const auto& styleISize =
aSizeOverrides.mStyleISize
? AnchorResolvedSizeHelper::Overridden(*aSizeOverrides.mStyleISize)
diff --git a/layout/generic/nsIFrame.h b/layout/generic/nsIFrame.h
@@ -5911,8 +5911,17 @@ inline nsIFrame* nsFrameList::BackwardFrameTraversal::Prev(nsIFrame* aFrame) {
inline AnchorPosResolutionParams AnchorPosResolutionParams::From(
const nsIFrame* aFrame,
mozilla::AnchorPosResolutionCache* aAnchorPosResolutionCache) {
- return {aFrame, aFrame->StyleDisplay()->mPosition, aAnchorPosResolutionCache,
- AutoResolutionOverrideParams{aFrame, aAnchorPosResolutionCache}};
+ bool inlineUsesAnchorCenter = false;
+ bool blockUsesAnchorCenter = false;
+ ComputeAnchorCenterUsage(aFrame, aAnchorPosResolutionCache,
+ inlineUsesAnchorCenter, blockUsesAnchorCenter);
+
+ return {aFrame,
+ aFrame->StyleDisplay()->mPosition,
+ aFrame->StylePosition()->mPositionArea,
+ aAnchorPosResolutionCache,
+ inlineUsesAnchorCenter,
+ blockUsesAnchorCenter};
}
#endif /* nsIFrame_h___ */
diff --git a/layout/style/nsComputedDOMStyle.h b/layout/style/nsComputedDOMStyle.h
@@ -400,9 +400,9 @@ already_AddRefed<nsComputedDOMStyle> NS_NewComputedDOMStyle(
inline AnchorPosResolutionParams AnchorPosResolutionParams::From(
const nsComputedDOMStyle* aComputedDOMStyle) {
- AutoResolutionOverrideParams overrides{aComputedDOMStyle->mOuterFrame};
return {aComputedDOMStyle->mOuterFrame,
- aComputedDOMStyle->StyleDisplay()->mPosition, nullptr, overrides};
+ aComputedDOMStyle->StyleDisplay()->mPosition,
+ aComputedDOMStyle->StylePosition()->mPositionArea};
}
#endif /* nsComputedDOMStyle_h__ */
diff --git a/layout/style/nsStyleStruct.cpp b/layout/style/nsStyleStruct.cpp
@@ -13,7 +13,6 @@
#include <algorithm>
-#include "AnchorPositioningUtils.h"
#include "CounterStyleManager.h"
#include "ImageLoader.h"
#include "imgIContainer.h"
@@ -287,78 +286,6 @@ static StyleRect<T> StyleRectWithAllSides(const T& aSide) {
return {aSide, aSide, aSide, aSide};
}
-bool AnchorPosResolutionParams::AutoResolutionOverrideParams::OverriddenToZero(
- StylePhysicalAxis aAxis) const {
- if (mPositionAreaInUse) {
- // If `position-area` is used "Any auto inset properties resolve to 0":
- // https://drafts.csswg.org/css-anchor-position-1/#valdef-position-area-position-area
- return true;
- }
-
- // If `anchor-center` is used with a valid anchor, "auto inset
- // properties resolve to 0" on that axis:
- // https://drafts.csswg.org/css-anchor-position-1/#anchor-center
- switch (aAxis) {
- case StylePhysicalAxis::Vertical:
- return mVAnchorCenter;
- case StylePhysicalAxis::Horizontal:
- return mHAnchorCenter;
- }
-}
-
-static AnchorPosResolutionParams::AutoResolutionOverrideParams
-GetAutoResolutionOverrideParams(const nsIFrame* aFrame,
- bool aDefaultAnchorValid) {
- if (!aFrame) {
- return {};
- }
- nsIFrame* parent = aFrame->GetParent();
- if (!parent || !aFrame->HasAnyStateBits(NS_FRAME_OUT_OF_FLOW) ||
- !aDefaultAnchorValid) {
- return {};
- }
-
- const auto* stylePos = aFrame->StylePosition();
- const auto cbwm = parent->GetWritingMode();
-
- auto checkAxis = [&](LogicalAxis aAxis) {
- StyleAlignFlags alignment =
- stylePos->UsedSelfAlignment(aAxis, parent->Style());
- return (alignment & ~StyleAlignFlags::FLAG_BITS) ==
- StyleAlignFlags::ANCHOR_CENTER;
- };
-
- const auto horizontalLogicalAxis =
- cbwm.IsVertical() ? LogicalAxis::Block : LogicalAxis::Inline;
- AnchorPosResolutionParams::AutoResolutionOverrideParams result;
- result.mHAnchorCenter = checkAxis(horizontalLogicalAxis);
- result.mVAnchorCenter = checkAxis(GetOrthogonalAxis(horizontalLogicalAxis));
- result.mPositionAreaInUse = !stylePos->mPositionArea.IsNone();
- return result;
-}
-
-AnchorPosResolutionParams::AutoResolutionOverrideParams::
- AutoResolutionOverrideParams(
- const nsIFrame* aFrame, const mozilla::AnchorPosResolutionCache* aCache)
- : AutoResolutionOverrideParams{GetAutoResolutionOverrideParams(
- aFrame, aCache && aCache->mDefaultAnchorCache.mAnchor)} {}
-
-AnchorPosResolutionParams::AutoResolutionOverrideParams::
- AutoResolutionOverrideParams(const nsIFrame* aFrame)
- : AutoResolutionOverrideParams{
- GetAutoResolutionOverrideParams(aFrame, [&]() {
- if (!aFrame) {
- return false;
- }
- const auto* references =
- aFrame->GetProperty(nsIFrame::AnchorPosReferences());
- if (!references || !references->mDefaultAnchorName) {
- // It is presumed that this is called on a reflowed frame.
- return false;
- }
- return references->Lookup(references->mDefaultAnchorName)->isSome();
- }())} {}
-
AnchorResolvedMargin AnchorResolvedMarginHelper::ResolveAnchor(
const StyleMargin& aValue, StylePhysicalAxis aAxis,
const AnchorPosResolutionParams& aParams) {
@@ -1401,6 +1328,25 @@ StyleSelfAlignment nsStylePosition::UsedJustifySelf(
return {StyleAlignFlags::NORMAL};
}
+bool AnchorResolvedInsetHelper::SideUsesAnchorCenter(
+ mozilla::Side aSide, const AnchorPosOffsetResolutionParams& aParams) {
+ const nsIFrame* frame = aParams.mBaseParams.mFrame;
+ if (!frame) {
+ return false;
+ }
+ const nsIFrame* parent = frame->GetParent();
+ if (!parent) {
+ return false;
+ }
+
+ WritingMode wm = parent->GetWritingMode();
+ LogicalSide logicalSide = wm.LogicalSideForPhysicalSide(aSide);
+ LogicalAxis axis = GetAxis(logicalSide);
+
+ return axis == LogicalAxis::Inline ? aParams.mBaseParams.mIAnchorCenter
+ : aParams.mBaseParams.mBAnchorCenter;
+}
+
AnchorResolvedInset AnchorResolvedInsetHelper::ResolveAnchor(
const mozilla::StyleInset& aValue, mozilla::StylePhysicalSide aSide,
const AnchorPosOffsetResolutionParams& aParams) {
diff --git a/layout/style/nsStyleStruct.h b/layout/style/nsStyleStruct.h
@@ -42,7 +42,6 @@ class nsComputedDOMStyle;
namespace mozilla {
class ComputedStyle;
struct AnchorPosResolutionCache;
-class AnchorPosReferenceData;
struct IntrinsicSize;
struct SizeComputationInput;
@@ -379,32 +378,21 @@ using AnchorResolvedMargin =
// Base set of parameters required to resolve a reference to an anchor.
struct AnchorPosResolutionParams {
- struct AutoResolutionOverrideParams {
- // Whether anchor-center is being used on the horizontal axis.
- bool mHAnchorCenter = false;
- // Whether anchor-center is being used on the vertical axis.
- bool mVAnchorCenter = false;
- // Whether position-area is being used.
- bool mPositionAreaInUse = false;
-
- AutoResolutionOverrideParams() = default;
- AutoResolutionOverrideParams(
- const nsIFrame* aFrame,
- const mozilla::AnchorPosResolutionCache* aCache);
- explicit AutoResolutionOverrideParams(const nsIFrame* aFrame);
-
- bool OverriddenToZero(mozilla::StylePhysicalAxis aAxis) const;
- };
// Frame of the anchor positioned element.
// If nullptr, skips anchor lookup and returns invalid, resolving fallbacks.
const nsIFrame* mFrame;
// Position property of the element in question.
mozilla::StylePositionProperty mPosition;
+ // position-area property of the element in question.
+ mozilla::StylePositionArea mPositionArea;
// Cache data used for anchor resolution.
mozilla::AnchorPosResolutionCache* const mCache;
- // Set of parameters that override `auto` values to 0, if the default
- // anchor is valid.
- AutoResolutionOverrideParams mAutoResolutionOverrideParams;
+ // Whether anchor-center is being used with a valid anchor on the inline axis.
+ // When true, auto insets in the inline axis resolve to 0.
+ bool mIAnchorCenter = false;
+ // Whether anchor-center is being used with a valid anchor on the block axis.
+ // When true, auto insets in the block axis resolve to 0.
+ bool mBAnchorCenter = false;
// Helper functions for creating anchor resolution parameters.
// Defined in corresponding header files.
@@ -428,17 +416,16 @@ struct AnchorResolvedMarginHelper {
static AnchorResolvedMargin FromUnresolved(
const mozilla::StyleMargin& aValue, mozilla::StylePhysicalAxis aAxis,
const AnchorPosResolutionParams& aParams) {
- auto resolved = [&]() {
- if (aValue.HasAnchorPositioningFunction()) {
- return ResolveAnchor(aValue, aAxis, aParams);
- }
- return AnchorResolvedMargin::NonOwning(&aValue);
- }();
- if (resolved->IsAuto() &&
- aParams.mAutoResolutionOverrideParams.OverriddenToZero(aAxis)) {
+ if (aValue.HasAnchorPositioningFunction()) {
+ return ResolveAnchor(aValue, aAxis, aParams);
+ }
+ // For `position-area` values other than `none`, the used value of `auto`
+ // margin properties resolves to 0:
+ // <https://drafts.csswg.org/css-anchor-position-1/#valdef-position-area-position-area>
+ if (aValue.IsAuto() && !aParams.mPositionArea.IsNone()) {
return Zero();
}
- return resolved;
+ return AnchorResolvedMargin::NonOwning(&aValue);
}
private:
@@ -793,28 +780,24 @@ struct AnchorResolvedInsetHelper {
return value;
}
- static const mozilla::StyleInset& ZeroValue() {
- static const auto value = mozilla::StyleInset::LengthPercentage(
- mozilla::StyleLengthPercentage::Zero());
- return value;
- }
-
static AnchorResolvedInset FromUnresolved(
const mozilla::StyleInset& aValue, mozilla::Side aSide,
const AnchorPosOffsetResolutionParams& aParams) {
- auto resolved = [&]() {
- if (aValue.HasAnchorPositioningFunction()) {
- return ResolveAnchor(aValue, mozilla::ToStylePhysicalSide(aSide),
- aParams);
- }
- return AnchorResolvedInset::NonOwning(&aValue);
- }();
- if (resolved->IsAuto() &&
- aParams.mBaseParams.mAutoResolutionOverrideParams.OverriddenToZero(
- mozilla::ToStylePhysicalAxis(aSide))) {
- return AnchorResolvedInset::NonOwning(&ZeroValue());
+ if (aValue.HasAnchorPositioningFunction()) {
+ return ResolveAnchor(aValue, mozilla::ToStylePhysicalSide(aSide),
+ aParams);
+ }
+ // If `position-area` is used "Any auto inset properties resolve to 0":
+ // https://drafts.csswg.org/css-anchor-position-1/#valdef-position-area-position-area
+ // If `anchor-center` is used with a valid anchor, "auto inset
+ // properties resolve to 0":
+ // https://drafts.csswg.org/css-anchor-position-1/#anchor-center
+ if (aValue.IsAuto() && (!aParams.mBaseParams.mPositionArea.IsNone() ||
+ SideUsesAnchorCenter(aSide, aParams))) {
+ return AnchorResolvedInset::UniquelyOwning(
+ new mozilla::StyleInset(mozilla::LengthPercentage::Zero()));
}
- return resolved;
+ return AnchorResolvedInset::NonOwning(&aValue);
}
private:
@@ -822,6 +805,9 @@ struct AnchorResolvedInsetHelper {
return AnchorResolvedInset::NonOwning(&AutoValue());
}
+ static bool SideUsesAnchorCenter(
+ mozilla::Side aSide, const AnchorPosOffsetResolutionParams& aParams);
+
static AnchorResolvedInset ResolveAnchor(
const mozilla::StyleInset& aValue, mozilla::StylePhysicalSide aSide,
const AnchorPosOffsetResolutionParams& aParams);
diff --git a/servo/ports/geckolib/glue.rs b/servo/ports/geckolib/glue.rs
@@ -10799,8 +10799,10 @@ fn offset_params_from_base_params(
mBaseParams: AnchorPosResolutionParams {
mFrame: params.mFrame,
mPosition: params.mPosition,
+ mPositionArea: params.mPositionArea,
mCache: params.mCache,
- mAutoResolutionOverrideParams: params.mAutoResolutionOverrideParams,
+ mIAnchorCenter: params.mIAnchorCenter,
+ mBAnchorCenter: params.mBAnchorCenter,
},
}
}
diff --git a/testing/web-platform/meta/css/css-anchor-position/position-area-basic.html.ini b/testing/web-platform/meta/css/css-anchor-position/position-area-basic.html.ini
@@ -0,0 +1,3 @@
+[position-area-basic.html]
+ [Offsets for: span-all top]
+ expected: FAIL
diff --git a/testing/web-platform/tests/css/css-anchor-position/auto-inset-margin-getComputedStyle.html b/testing/web-platform/tests/css/css-anchor-position/auto-inset-margin-getComputedStyle.html
@@ -1,120 +0,0 @@
-<!DOCTYPE html>
-<meta charset="utf-8">
-<title>Tests that getComputedStyle() returns auto insets and margins 0 when position-area or anchor-center is used with valid default anchor</title>
-<link rel="help" href="https://drafts.csswg.org/css-anchor-position-1/#position-area">
-<link rel="help" href="https://drafts.csswg.org/css-anchor-position-1/#anchor-pos">
-<link rel="author" name="David Shin" href="mailto:dshin@mozilla.com">
-<script src="/resources/testharness.js"></script>
-<script src="/resources/testharnessreport.js"></script>
-<style>
-.abs-cb {
- width: 60px;
- height: 60px;
- border: 5px solid;
- position: relative;
- anchor-scope: all;
- display: inline-block;
- /* Nudge static position against padding box. */
- padding: 10px;
-}
-
-.anchor {
- anchor-name: --a;
- position: absolute;
- left: 20px;
- top: 20px;
- width: 20px;
- height: 20px;
- background: pink;
-}
-
-.positioned {
- position: absolute;
- background: purple;
- width: 20px;
- height: 20px;
-}
-
-.margin-auto > .positioned {
- inset: 0;
- margin: auto;
-}
-
-.inset-auto > .positioned {
- inset: auto;
-}
-
-.pa {
- position-area: bottom right;
-}
-
-.jac {
- justify-self: anchor-center;
-}
-
-.aac {
- align-self: anchor-center;
-}
-
-.valid-anchor > .positioned {
- position-anchor: --a;
-}
-</style>
-<div id=insetValidAnchor class="abs-cb inset-auto valid-anchor">
- <div class=anchor></div>
- <div class="positioned pa"></div>
- <div class="positioned jac"></div>
- <div class="positioned aac"></div>
-</div
-><div id=insetInvalidAnchor class="abs-cb inset-auto">
- <div class=anchor></div>
- <div class="positioned pa"></div>
- <div class="positioned jac"></div>
- <div class="positioned aac"></div>
-</div><br>
-<div id=marginValidAnchor class="abs-cb margin-auto valid-anchor">
- <div class=anchor></div>
- <div class="positioned pa"></div>
- <div class="positioned jac"></div>
- <div class="positioned aac"></div>
-</div
-><div id=marginInvalidAnchor class="abs-cb margin-auto">
- <div class=anchor></div>
- <div class="positioned pa"></div>
- <div class="positioned jac"></div>
- <div class="positioned aac"></div>
-</div>
-<script>
-function assert_zero(e, f, props, t) {
- test(() => {
- const s = getComputedStyle(e);
- for (const prop of props) {
- f(s.getPropertyValue(prop), "0px");
- }
- }, t);
-}
-
-const horizontalInsets = ['left', 'right'];
-const verticalInsets = ['top', 'bottom'];
-const allInsets = horizontalInsets.concat(verticalInsets);
-
-assert_zero(insetValidAnchor.querySelector('.pa'), assert_equals, allInsets, "position-area with valid anchor sets insets to zero");
-assert_zero(insetValidAnchor.querySelector('.jac'), assert_equals, horizontalInsets, "justify-self: anchor-center with valid anchor sets insets to zero");
-assert_zero(insetValidAnchor.querySelector('.aac'), assert_equals, verticalInsets, "align-self: anchor-center with valid anchor sets insets to zero");
-
-assert_zero(insetInvalidAnchor.querySelector('.pa'), assert_not_equals, allInsets, "position-area with invalid anchor does not set insets to zero");
-assert_zero(insetInvalidAnchor.querySelector('.jac'), assert_not_equals, horizontalInsets, "justify-self: anchor-center with invalid anchor does not set insets to zero");
-assert_zero(insetInvalidAnchor.querySelector('.aac'), assert_not_equals, verticalInsets, "align-self: anchor-center with invalid anchor does not set insets to zero");
-
-const horizontalMargins = ['margin-left', 'margin-right'];
-const verticalMargins = ['margin-top', 'margin-bottom'];
-const allMargins = horizontalMargins.concat(verticalMargins);
-
-assert_zero(marginValidAnchor.querySelector('.pa'), assert_equals, allMargins, "position-area with valid anchor sets margins to zero");
-assert_zero(marginValidAnchor.querySelector('.jac'), assert_equals, horizontalMargins, "justify-self: anchor-center with valid anchor sets margins to zero");
-assert_zero(marginValidAnchor.querySelector('.aac'), assert_equals, verticalMargins, "align-self: anchor-center with valid anchor sets margins to zero");
-
-assert_zero(marginInvalidAnchor.querySelector('.pa'), assert_not_equals, allMargins, "position-area with invalid anchor does not set margins to zero");
-assert_zero(marginInvalidAnchor.querySelector('.jac'), assert_not_equals, horizontalMargins, "justify-self: anchor-center with invalid anchor does not set margins to zero");
-assert_zero(marginInvalidAnchor.querySelector('.aac'), assert_not_equals, verticalMargins, "align-self: anchor-center with invalid anchor does not set margins to zero");
-</script>