tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

commit c8558d0a6d93c5d1121bf4a26675c089f0065db3
parent 48564078bcf0ecc4dcee85da6765e42992bebaeb
Author: Jonathan Watt <jwatt@jwatt.org>
Date:   Wed, 10 Dec 2025 17:56:28 +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:
Mlayout/generic/CSSAlignUtils.cpp | 4++--
Mlayout/generic/ReflowInput.cpp | 22++++++++++++++++++++++
Mlayout/generic/ReflowInput.h | 19-------------------
Mlayout/generic/nsContainerFrame.cpp | 15++++++++-------
Mlayout/generic/nsContainerFrame.h | 3++-
Mlayout/generic/nsIFrame.cpp | 11+++++++----
Mlayout/style/nsStyleStruct.h | 9+++++----
7 files changed, 46 insertions(+), 37 deletions(-)

diff --git a/layout/generic/CSSAlignUtils.cpp b/layout/generic/CSSAlignUtils.cpp @@ -30,8 +30,8 @@ StyleAlignFlags CSSAlignUtils::UsedAlignmentForAbsPos(nsIFrame* aFrame, // absolutely-positioned boxes." // https://drafts.csswg.org/css-align/#align-abspos // https://drafts.csswg.org/css-align/#justify-abspos - aFlags = aFrame->IsReplaced() ? StyleAlignFlags::START - : StyleAlignFlags::STRETCH; + aFlags = aFrame->HasReplacedSizing() ? StyleAlignFlags::START + : StyleAlignFlags::STRETCH; } else if (aFlags == StyleAlignFlags::FLEX_START) { aFlags = StyleAlignFlags::START; } else if (aFlags == StyleAlignFlags::FLEX_END) { 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 @@ -2518,13 +2519,13 @@ nsContainerFrame::CSSAlignmentForAbsPosChildWithinContainingBlock( const auto axis = ToStyleLogicalAxis(aLogicalAxis); const auto cbSWM = cbWM.ToStyleWritingMode(); const auto selfWM = - aChildRI.mFrame->GetWritingMode().ToStyleWritingMode(); + aSizingInput.mFrame->GetWritingMode().ToStyleWritingMode(); Servo_ResolvePositionAreaSelfAlignment(&aResolvedPositionArea, axis, &cbSWM, &selfWM, &alignment); } } - 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 @@ -7289,14 +7289,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); };