commit 70c1ed629c2c203865009c16600e135caf16fc43
parent ac0aa650de14ffd196c2c55fd255b1c86c86fc17
Author: Jonathan Watt <jwatt@jwatt.org>
Date: Tue, 9 Dec 2025 08:00:43 +0000
Bug 1991929 p3. Make shrink-wrapping work for anchor positioned elements. r=dshin,layout-reviewers,layout-anchor-positioning-reviewers,firefox-style-system-reviewers
Differential Revision: https://phabricator.services.mozilla.com/D275465
Diffstat:
6 files changed, 43 insertions(+), 34 deletions(-)
diff --git a/layout/generic/ReflowInput.cpp b/layout/generic/ReflowInput.cpp
@@ -40,6 +40,28 @@ using namespace mozilla::css;
using namespace mozilla::dom;
using namespace mozilla::layout;
+AnchorPosResolutionParams AnchorPosResolutionParams::From(
+ const mozilla::SizeComputationInput* aSizingInput,
+ bool aIgnorePositionArea) {
+ 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) {
nsIFrame* frameNext = aFrame->GetNextInFlow();
nsIFrame* parentNext = aParent->GetNextInFlow();
diff --git a/layout/generic/ReflowInput.h b/layout/generic/ReflowInput.h
@@ -979,23 +979,4 @@ void ComputeAnchorCenterUsage(
mozilla::AnchorPosResolutionCache* aAnchorPosResolutionCache,
bool& aInlineUsesAnchorCenter, bool& aBlockUsesAnchorCenter);
-inline AnchorPosResolutionParams AnchorPosResolutionParams::From(
- const mozilla::ReflowInput* aRI, bool aIgnorePositionArea) {
- const mozilla::StylePositionArea posArea =
- aIgnorePositionArea ? mozilla::StylePositionArea{}
- : aRI->mStylePosition->mPositionArea;
- bool inlineUsesAnchorCenter = false;
- bool blockUsesAnchorCenter = false;
-
- ComputeAnchorCenterUsage(aRI->mFrame, aRI->mAnchorPosResolutionCache,
- inlineUsesAnchorCenter, blockUsesAnchorCenter);
-
- return {aRI->mFrame,
- aRI->mStyleDisplay->mPosition,
- posArea,
- aRI->mAnchorPosResolutionCache,
- inlineUsesAnchorCenter,
- blockUsesAnchorCenter};
-}
-
#endif // mozilla_ReflowInput_h
diff --git a/layout/generic/nsContainerFrame.cpp b/layout/generic/nsContainerFrame.cpp
@@ -2472,29 +2472,30 @@ StyleAlignFlags nsContainerFrame::CSSAlignmentForAbsPosChild(
StyleAlignFlags
nsContainerFrame::CSSAlignmentForAbsPosChildWithinContainingBlock(
- const ReflowInput& aChildRI, LogicalAxis aLogicalAxis,
+ const SizeComputationInput& aSizingInput, LogicalAxis aLogicalAxis,
const StylePositionArea& aResolvedPositionArea,
const LogicalSize& aCBSize) const {
- MOZ_ASSERT(aChildRI.mFrame->IsAbsolutelyPositioned(),
+ MOZ_ASSERT(aSizingInput.mFrame->IsAbsolutelyPositioned(),
"This method should only be called for abspos children");
// When determining the position of absolutely-positioned boxes,
// `auto` behaves as `normal`.
StyleAlignFlags alignment =
- aChildRI.mStylePosition->UsedSelfAlignment(aLogicalAxis, nullptr);
+ aSizingInput.mFrame->StylePosition()->UsedSelfAlignment(aLogicalAxis,
+ nullptr);
// Check if position-area is set - if so, it determines the default alignment
// https://drafts.csswg.org/css-anchor-position/#position-area-alignment
if (!aResolvedPositionArea.IsNone() && alignment == StyleAlignFlags::NORMAL) {
const WritingMode cbWM = GetWritingMode();
const auto anchorResolutionParams = AnchorPosResolutionParams::From(
- &aChildRI, /* aIgnorePositionArea = */ true);
+ &aSizingInput, /* aIgnorePositionArea = */ true);
const auto anchorOffsetResolutionParams =
AnchorPosOffsetResolutionParams::ExplicitCBFrameSize(
anchorResolutionParams, &aCBSize);
// Check if we have exactly one auto inset in this axis (IMCB situation)
const auto singleAutoInset =
- aChildRI.mStylePosition->GetSingleAutoInsetInAxis(
+ aSizingInput.mFrame->StylePosition()->GetSingleAutoInsetInAxis(
aLogicalAxis, cbWM, anchorOffsetResolutionParams);
// Check if exactly one inset in the axis is auto
@@ -2521,7 +2522,7 @@ nsContainerFrame::CSSAlignmentForAbsPosChildWithinContainingBlock(
}
}
- return CSSAlignUtils::UsedAlignmentForAbsPos(aChildRI.mFrame, alignment,
+ return CSSAlignUtils::UsedAlignmentForAbsPos(aSizingInput.mFrame, alignment,
aLogicalAxis, GetWritingMode());
}
diff --git a/layout/generic/nsContainerFrame.h b/layout/generic/nsContainerFrame.h
@@ -481,7 +481,8 @@ class nsContainerFrame : public nsSplittableFrame {
* on its type (By overriding `CSSAlignmentForAbsPosChild`).
*/
mozilla::StyleAlignFlags CSSAlignmentForAbsPosChildWithinContainingBlock(
- const ReflowInput& aChildRI, mozilla::LogicalAxis aLogicalAxis,
+ const SizeComputationInput& aSizingInput,
+ mozilla::LogicalAxis aLogicalAxis,
const mozilla::StylePositionArea& aResolvedPositionArea,
const mozilla::LogicalSize& aContainingBlockSize) const;
diff --git a/layout/generic/nsIFrame.cpp b/layout/generic/nsIFrame.cpp
@@ -7267,14 +7267,17 @@ LogicalSize nsIFrame::ComputeAbsolutePosAutoSize(
};
// i.e. Absolute containing block
- const auto* parent = GetParent();
- const auto parentWM = parent->GetWritingMode();
+
// Self alignment properties translate `auto` to normal for this purpose.
// https://drafts.csswg.org/css-align-3/#valdef-justify-self-auto
+ nsContainerFrame* contFrame = static_cast<nsContainerFrame*>(this);
+ const StylePositionArea posArea = stylePos->mPositionArea;
const auto inlineSelfAlign =
- stylePos->UsedSelfAlignment(aWM, LogicalAxis::Inline, parentWM, nullptr);
+ contFrame->CSSAlignmentForAbsPosChildWithinContainingBlock(
+ aSizingInput, LogicalAxis::Inline, posArea, aCBSize);
const auto blockSelfAlign =
- stylePos->UsedSelfAlignment(aWM, LogicalAxis::Block, parentWM, nullptr);
+ contFrame->CSSAlignmentForAbsPosChildWithinContainingBlock(
+ aSizingInput, LogicalAxis::Block, posArea, aCBSize);
const auto iShouldStretch = shouldStretch(
inlineSelfAlign, this, iStartOffsetIsAuto, iEndOffsetIsAuto);
const auto bShouldStretch =
diff --git a/layout/style/nsStyleStruct.h b/layout/style/nsStyleStruct.h
@@ -41,9 +41,9 @@ struct nsStyleVisibility;
class nsComputedDOMStyle;
namespace mozilla {
class ComputedStyle;
-struct IntrinsicSize;
-struct ReflowInput;
struct AnchorPosResolutionCache;
+struct IntrinsicSize;
+struct SizeComputationInput;
} // namespace mozilla
@@ -399,8 +399,9 @@ struct AnchorPosResolutionParams {
static inline AnchorPosResolutionParams From(
const nsIFrame* aFrame,
mozilla::AnchorPosResolutionCache* aAnchorPosResolutionCache = nullptr);
- static inline AnchorPosResolutionParams From(
- const mozilla::ReflowInput* aRI, bool aIgnorePositionArea = false);
+ static AnchorPosResolutionParams From(
+ const mozilla::SizeComputationInput* aSizingInput,
+ bool aIgnorePositionArea = false);
static inline AnchorPosResolutionParams From(
const nsComputedDOMStyle* aComputedDOMStyle);
};