tor-browser

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

commit 6572b7509a9036d73e396cee6b4b1e1f3c58623b
parent 45879990e9f1aa6481a9c973491bf8c418cbb21d
Author: Emilio Cobos Álvarez <emilio@crisal.io>
Date:   Wed, 17 Dec 2025 19:42:35 +0000

Bug 2006499 - Consider exposing active fallback style in getComputedStyle(). r=jwatt

This has bit us consistently, and I guess it's not that hard to do if we
want.

Differential Revision: https://phabricator.services.mozilla.com/D276757

Diffstat:
Mlayout/base/AnchorPositioningUtils.h | 1+
Mlayout/generic/AbsoluteContainingBlock.cpp | 23++++++++++-------------
Mlayout/style/nsComputedDOMStyle.cpp | 42+++++++++++++++++++++++++++++++++++-------
Mlayout/style/nsComputedDOMStyle.h | 4++--
Dtesting/web-platform/meta/css/css-anchor-position/position-try-backdrop.html.ini | 3---
Dtesting/web-platform/meta/css/css-anchor-position/try-tactic-sizing.html.ini | 9---------
6 files changed, 48 insertions(+), 34 deletions(-)

diff --git a/layout/base/AnchorPositioningUtils.h b/layout/base/AnchorPositioningUtils.h @@ -163,6 +163,7 @@ class AnchorPosReferenceData { }; struct LastSuccessfulPositionData { + RefPtr<const ComputedStyle> mStyle; uint32_t mIndex = 0; bool mTriedAllFallbacks = false; }; diff --git a/layout/generic/AbsoluteContainingBlock.cpp b/layout/generic/AbsoluteContainingBlock.cpp @@ -1193,17 +1193,13 @@ void AbsoluteContainingBlock::ReflowAbsoluteFrame( Maybe<uint32_t> firstTryIndex; Maybe<nsPoint> firstTryNormalPosition; - // TODO(emilio): Right now fallback only applies to position-area, which only - // makes a difference with a default anchor... Generalize it? - if (aAnchorPosResolutionCache) { - const auto* lastSuccessfulPosition = - aKidFrame->GetProperty(nsIFrame::LastSuccessfulPositionFallback()); - if (lastSuccessfulPosition) { - if (!SeekFallbackTo(lastSuccessfulPosition->mIndex)) { - aKidFrame->RemoveProperty(nsIFrame::LastSuccessfulPositionFallback()); - } else { - firstTryIndex = Some(lastSuccessfulPosition->mIndex); - } + const auto* lastSuccessfulPosition = + aKidFrame->GetProperty(nsIFrame::LastSuccessfulPositionFallback()); + if (lastSuccessfulPosition) { + if (!SeekFallbackTo(lastSuccessfulPosition->mIndex)) { + aKidFrame->RemoveProperty(nsIFrame::LastSuccessfulPositionFallback()); + } else { + firstTryIndex = Some(lastSuccessfulPosition->mIndex); } } @@ -1607,8 +1603,9 @@ void AbsoluteContainingBlock::ReflowAbsoluteFrame( if (currentFallbackIndex) { aKidFrame->SetOrUpdateDeletableProperty( - nsIFrame::LastSuccessfulPositionFallback(), *currentFallbackIndex, - isOverflowingCB); + nsIFrame::LastSuccessfulPositionFallback(), + LastSuccessfulPositionData{currentFallbackStyle, *currentFallbackIndex, + isOverflowingCB}); } #ifdef DEBUG diff --git a/layout/style/nsComputedDOMStyle.cpp b/layout/style/nsComputedDOMStyle.cpp @@ -10,6 +10,7 @@ #include <algorithm> +#include "AnchorPositioningUtils.h" #include "mozilla/AppUnits.h" #include "mozilla/ComputedStyle.h" #include "mozilla/ComputedStyleInlines.h" @@ -758,26 +759,30 @@ void nsComputedDOMStyle::ClearComputedStyle() { } void nsComputedDOMStyle::SetResolvedComputedStyle( - RefPtr<const ComputedStyle>&& aContext, uint64_t aGeneration) { + RefPtr<const ComputedStyle> aStyle, uint64_t aGeneration) { if (!mResolvedComputedStyle) { mResolvedComputedStyle = true; mElement->AddMutationObserver(this); } - mComputedStyle = aContext; + mComputedStyle = std::move(aStyle); mComputedStyleGeneration = aGeneration; mPresShellId = mPresShell->GetPresShellId(); } -void nsComputedDOMStyle::SetFrameComputedStyle(mozilla::ComputedStyle* aStyle, - uint64_t aGeneration) { +void nsComputedDOMStyle::SetFrameComputedStyle( + RefPtr<const ComputedStyle> aStyle, uint64_t aGeneration) { ClearComputedStyle(); - mComputedStyle = aStyle; + mComputedStyle = std::move(aStyle); mComputedStyleGeneration = aGeneration; mPresShellId = mPresShell->GetPresShellId(); } static bool MayNeedToFlushLayout(NonCustomCSSPropertyId aPropId) { switch (aPropId) { + case eCSSProperty_max_width: + case eCSSProperty_max_height: + case eCSSProperty_min_width: + case eCSSProperty_min_height: case eCSSProperty_width: case eCSSProperty_height: case eCSSProperty_block_size: @@ -882,6 +887,11 @@ static bool PaddingNeedsUsedValue(const LengthPercentage& aValue, return !aValue.ConvertsToLength() || aStyle.StyleDisplay()->HasAppearance(); } +static bool HasPositionFallbacks(nsIFrame* aFrame) { + return aFrame->HasAnyStateBits(NS_FRAME_OUT_OF_FLOW) && + !aFrame->StylePosition()->mPositionTryFallbacks._0.IsEmpty(); +} + bool nsComputedDOMStyle::NeedsToFlushLayout( NonCustomCSSPropertyId aPropId) const { MOZ_ASSERT(aPropId != eCSSProperty_UNKNOWN); @@ -899,6 +909,18 @@ bool nsComputedDOMStyle::NeedsToFlushLayout( } switch (aPropId) { + case eCSSProperty_max_width: + return HasPositionFallbacks(frame) || + frame->StylePosition()->mMaxWidth.HasAnchorPositioningFunction(); + case eCSSProperty_max_height: + return HasPositionFallbacks(frame) || + frame->StylePosition()->mMaxHeight.HasAnchorPositioningFunction(); + case eCSSProperty_min_width: + return HasPositionFallbacks(frame) || + frame->StylePosition()->mMinWidth.HasAnchorPositioningFunction(); + case eCSSProperty_min_height: + return HasPositionFallbacks(frame) || + frame->StylePosition()->mMinHeight.HasAnchorPositioningFunction(); case eCSSProperty_width: case eCSSProperty_height: return !IsNonReplacedInline(frame); @@ -941,7 +963,8 @@ bool nsComputedDOMStyle::NeedsToFlushLayout( // NOTE(dshin): Raw margin value access since we want to flush // anchor-dependent values here. Side side = SideForPaddingOrMarginOrInsetProperty(aPropId); - return !style->StyleMargin()->mMargin.Get(side).ConvertsToLength(); + return !style->StyleMargin()->mMargin.Get(side).ConvertsToLength() || + HasPositionFallbacks(frame); } default: return false; @@ -1057,7 +1080,12 @@ void nsComputedDOMStyle::UpdateCurrentStyleSources( mInnerFrame = mOuterFrame; if (mOuterFrame) { mInnerFrame = nsLayoutUtils::GetStyleFrame(mOuterFrame); - SetFrameComputedStyle(mInnerFrame->Style(), currentGeneration); + const auto* style = mInnerFrame->Style(); + if (auto* data = mInnerFrame->GetProperty( + nsIFrame::LastSuccessfulPositionFallback())) { + style = data->mStyle.get(); + } + SetFrameComputedStyle(std::move(style), currentGeneration); NS_ASSERTION(mComputedStyle, "Frame without style?"); } } diff --git a/layout/style/nsComputedDOMStyle.h b/layout/style/nsComputedDOMStyle.h @@ -167,9 +167,9 @@ class nsComputedDOMStyle final : public nsDOMCSSDeclaration, // Helper functions called by UpdateCurrentStyleSources. void ClearComputedStyle(); - void SetResolvedComputedStyle(RefPtr<const ComputedStyle>&& aContext, + void SetResolvedComputedStyle(RefPtr<const ComputedStyle>, uint64_t aGeneration); - void SetFrameComputedStyle(ComputedStyle* aStyle, uint64_t aGeneration); + void SetFrameComputedStyle(RefPtr<const ComputedStyle>, uint64_t aGeneration); static already_AddRefed<const ComputedStyle> DoGetComputedStyleNoFlush( const Element*, const PseudoStyleRequest&, mozilla::PresShell*, diff --git a/testing/web-platform/meta/css/css-anchor-position/position-try-backdrop.html.ini b/testing/web-platform/meta/css/css-anchor-position/position-try-backdrop.html.ini @@ -1,3 +0,0 @@ -[position-try-backdrop.html] - [::backdrop can use position-try-fallbacks] - expected: FAIL diff --git a/testing/web-platform/meta/css/css-anchor-position/try-tactic-sizing.html.ini b/testing/web-platform/meta/css/css-anchor-position/try-tactic-sizing.html.ini @@ -1,9 +0,0 @@ -[try-tactic-sizing.html] - [flip-block does not affect sizing] - expected: FAIL - - [flip-inline does not affect sizing] - expected: FAIL - - [flip-start affects sizing] - expected: FAIL