tor-browser

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

commit f1dc23ae227b7948e8cf9c12eae098df74971144
parent f2c14bfe8e8cb9d25f0e6c918760e40be7c0c5e9
Author: Alexandru Marc <amarc@mozilla.com>
Date:   Thu, 11 Dec 2025 23:45:41 +0200

Revert "Bug 2005169 - Fix reftest-snapshot and overflow interaction of overflowing replaced elements. r=layout-reviewers,dholbert" for causing bc failures @ browser_ext_menus_events.js

This reverts commit 670fdc48bafd9a3a36d2e3db5d669e71576d5102.

Diffstat:
Mlayout/generic/ReflowInput.h | 6------
Mlayout/generic/nsHTMLCanvasFrame.cpp | 97+++++++++++++++++++++++++++++++++++++++++++++++++------------------------------
Mlayout/generic/nsHTMLCanvasFrame.h | 2--
Mlayout/generic/nsImageFrame.cpp | 36++++++++++++++++--------------------
Mlayout/generic/nsImageFrame.h | 2+-
Mlayout/generic/nsVideoFrame.cpp | 48++++++++++++++++++------------------------------
Mlayout/generic/nsVideoFrame.h | 4----
7 files changed, 95 insertions(+), 100 deletions(-)

diff --git a/layout/generic/ReflowInput.h b/layout/generic/ReflowInput.h @@ -368,12 +368,6 @@ struct ReflowInput : public SizeComputationInput { // unconstrained dimensions replaced by zero. nsSize ComputedSizeAsContainerIfConstrained() const; - // Return the physical content box relative to the frame itself. - nsRect ComputedPhysicalContentBoxRelativeToSelf() const { - auto bp = ComputedPhysicalBorderPadding(); - return nsRect(nsPoint(bp.left, bp.top), ComputedPhysicalSize()); - } - // Get the writing mode of the containing block, to resolve float/clear // logical sides appropriately. WritingMode GetCBWritingMode() const; diff --git a/layout/generic/nsHTMLCanvasFrame.cpp b/layout/generic/nsHTMLCanvasFrame.cpp @@ -67,23 +67,30 @@ class nsDisplayCanvas final : public nsPaintedDisplayItem { *aSnap = false; auto* f = static_cast<nsHTMLCanvasFrame*>(Frame()); auto* canvas = HTMLCanvasElement::FromNode(f->GetContent()); - if (!canvas->GetIsOpaque()) { - return {}; + nsRegion result; + if (canvas->GetIsOpaque()) { + // OK, the entire region painted by the canvas is opaque. But what is + // that region? It's the canvas's "dest rect" (controlled by the + // object-fit/object-position CSS properties), clipped to the container's + // content box (which is what GetBounds() returns). So, we grab those + // rects and intersect them. + nsRect constraintRect = GetBounds(aBuilder, aSnap); + + // Need intrinsic size & ratio, for ComputeObjectDestRect: + CSSIntSize canvasSize = f->GetCanvasSize(); + IntrinsicSize intrinsicSize = IntrinsicSizeFromCanvasSize(canvasSize); + AspectRatio intrinsicRatio = IntrinsicRatioFromCanvasSize(canvasSize); + + const nsRect destRect = nsLayoutUtils::ComputeObjectDestRect( + constraintRect, intrinsicSize, intrinsicRatio, f->StylePosition()); + return nsRegion(destRect.Intersect(constraintRect)); } - // OK, the entire region painted by the canvas is opaque. But what is - // that region? It's the canvas's "dest rect" (controlled by the - // object-fit/object-position CSS properties), clipped to the container's - // ink overflow box (which is what GetBounds() returns). So, we grab those - // rects and intersect them. - const nsRect constraintRect = GetBounds(aBuilder, aSnap); - const nsRect destRect = - f->GetDestRect(f->GetContentRectRelativeToSelf() + ToReferenceFrame()); - return nsRegion(destRect.Intersect(constraintRect)); + return result; } nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) const override { *aSnap = true; - return Frame()->InkOverflowRectRelativeToSelf() + ToReferenceFrame(); + return Frame()->GetContentRectRelativeToSelf() + ToReferenceFrame(); } bool CreateWebRenderCommands( @@ -104,8 +111,12 @@ class nsDisplayCanvas final : public nsPaintedDisplayItem { element->FlushOffscreenCanvas(); auto* canvasFrame = static_cast<nsHTMLCanvasFrame*>(mFrame); - nsRect dest = canvasFrame->GetDestRect( - mFrame->GetContentRectRelativeToSelf() + ToReferenceFrame()); + CSSIntSize canvasSizeInPx = canvasFrame->GetCanvasSize(); + IntrinsicSize intrinsicSize = IntrinsicSizeFromCanvasSize(canvasSizeInPx); + AspectRatio intrinsicRatio = IntrinsicRatioFromCanvasSize(canvasSizeInPx); + nsRect area = mFrame->GetContentRectRelativeToSelf() + ToReferenceFrame(); + nsRect dest = nsLayoutUtils::ComputeObjectDestRect( + area, intrinsicSize, intrinsicRatio, mFrame->StylePosition()); LayoutDeviceRect bounds = LayoutDeviceRect::FromAppUnits( dest, mFrame->PresContext()->AppUnitsPerDevPixel()); @@ -130,7 +141,8 @@ class nsDisplayCanvas final : public nsPaintedDisplayItem { aManager->CommandBuilder() .CreateOrRecycleWebRenderUserData<WebRenderCanvasData>( this, &isRecycled); - auto* canvasFrame = static_cast<nsHTMLCanvasFrame*>(mFrame); + nsHTMLCanvasFrame* canvasFrame = + static_cast<nsHTMLCanvasFrame*>(mFrame); if (!canvasFrame->UpdateWebRenderCanvasData(aDisplayListBuilder, canvasData)) { return true; @@ -141,8 +153,19 @@ class nsDisplayCanvas final : public nsPaintedDisplayItem { // Push IFrame for async image pipeline. // XXX Remove this once partial display list update is supported. - nsRect dest = canvasFrame->GetDestRect( - mFrame->GetContentRectRelativeToSelf() + ToReferenceFrame()); + + CSSIntSize canvasSizeInPx = + CSSIntSize::FromUnknownSize(data->GetSize()); + IntrinsicSize intrinsicSize = + IntrinsicSizeFromCanvasSize(canvasSizeInPx); + AspectRatio intrinsicRatio = + IntrinsicRatioFromCanvasSize(canvasSizeInPx); + + nsRect area = + mFrame->GetContentRectRelativeToSelf() + ToReferenceFrame(); + nsRect dest = nsLayoutUtils::ComputeObjectDestRect( + area, intrinsicSize, intrinsicRatio, mFrame->StylePosition()); + LayoutDeviceRect bounds = LayoutDeviceRect::FromAppUnits( dest, mFrame->PresContext()->AppUnitsPerDevPixel()); @@ -183,8 +206,15 @@ class nsDisplayCanvas final : public nsPaintedDisplayItem { return true; } - nsRect dest = canvasFrame->GetDestRect( - mFrame->GetContentRectRelativeToSelf() + ToReferenceFrame()); + IntrinsicSize intrinsicSize = + IntrinsicSizeFromCanvasSize(canvasSizeInPx); + AspectRatio intrinsicRatio = + IntrinsicRatioFromCanvasSize(canvasSizeInPx); + + nsRect area = + mFrame->GetContentRectRelativeToSelf() + ToReferenceFrame(); + nsRect dest = nsLayoutUtils::ComputeObjectDestRect( + area, intrinsicSize, intrinsicRatio, mFrame->StylePosition()); LayoutDeviceRect bounds = LayoutDeviceRect::FromAppUnits( dest, mFrame->PresContext()->AppUnitsPerDevPixel()); @@ -212,22 +242,25 @@ class nsDisplayCanvas final : public nsPaintedDisplayItem { } void Paint(nsDisplayListBuilder* aBuilder, gfxContext* aCtx) override { - auto* f = static_cast<nsHTMLCanvasFrame*>(Frame()); - auto* canvas = HTMLCanvasElement::FromNode(f->GetContent()); + nsHTMLCanvasFrame* f = static_cast<nsHTMLCanvasFrame*>(Frame()); + HTMLCanvasElement* canvas = HTMLCanvasElement::FromNode(f->GetContent()); + nsRect area = f->GetContentRectRelativeToSelf() + ToReferenceFrame(); CSSIntSize canvasSizeInPx = f->GetCanvasSize(); + nsPresContext* presContext = f->PresContext(); canvas->HandlePrintCallback(presContext); - if (canvasSizeInPx.width <= 0 || canvasSizeInPx.height <= 0) { + if (canvasSizeInPx.width <= 0 || canvasSizeInPx.height <= 0 || + area.IsEmpty()) { return; } - nsRect dest = f->GetDestRect(mFrame->GetContentRectRelativeToSelf() + - ToReferenceFrame()); - if (dest.IsEmpty()) { - return; - } + IntrinsicSize intrinsicSize = IntrinsicSizeFromCanvasSize(canvasSizeInPx); + AspectRatio intrinsicRatio = IntrinsicRatioFromCanvasSize(canvasSizeInPx); + + nsRect dest = nsLayoutUtils::ComputeObjectDestRect( + area, intrinsicSize, intrinsicRatio, f->StylePosition()); gfxContextMatrixAutoSaveRestore saveMatrix(aCtx); @@ -372,14 +405,6 @@ nsIFrame::SizeComputationResult nsHTMLCanvasFrame::ComputeSize( AspectRatioUsage::None}; } -nsRect nsHTMLCanvasFrame::GetDestRect(const nsRect& aFrameContentBox) const { - const CSSIntSize canvasSizeInPx = GetCanvasSize(); - IntrinsicSize intrinsicSize = IntrinsicSizeFromCanvasSize(canvasSizeInPx); - AspectRatio intrinsicRatio = IntrinsicRatioFromCanvasSize(canvasSizeInPx); - return nsLayoutUtils::ComputeObjectDestRect(aFrameContentBox, intrinsicSize, - intrinsicRatio, StylePosition()); -} - void nsHTMLCanvasFrame::Reflow(nsPresContext* aPresContext, ReflowOutput& aMetrics, const ReflowInput& aReflowInput, @@ -399,8 +424,6 @@ void nsHTMLCanvasFrame::Reflow(nsPresContext* aPresContext, aMetrics.SetSize(wm, finalSize); aMetrics.SetOverflowAreasToDesiredBounds(); - aMetrics.mOverflowAreas.UnionAllWith( - GetDestRect(aReflowInput.ComputedPhysicalContentBoxRelativeToSelf())); FinishAndStoreOverflow(&aMetrics); // Reflow the single anon block child. diff --git a/layout/generic/nsHTMLCanvasFrame.h b/layout/generic/nsHTMLCanvasFrame.h @@ -65,8 +65,6 @@ class nsHTMLCanvasFrame final : public nsContainerFrame { const ReflowInput& aReflowInput, nsReflowStatus& aStatus) override; - nsRect GetDestRect(const nsRect& aFrameContentBox) const; - #ifdef ACCESSIBILITY mozilla::a11y::AccType AccessibleType() override; #endif diff --git a/layout/generic/nsImageFrame.cpp b/layout/generic/nsImageFrame.cpp @@ -1635,11 +1635,15 @@ void nsImageFrame::Reflow(nsPresContext* aPresContext, ReflowOutput& aMetrics, } aMetrics.SetOverflowAreasToDesiredBounds(); - const bool imageOK = mKind != Kind::ImageLoadingContent || - ImageOk(mContent->AsElement()->State()); + bool imageOK = mKind != Kind::ImageLoadingContent || + ImageOk(mContent->AsElement()->State()); // Determine if the size is available - const bool haveSize = loadStatus & imgIRequest::STATUS_SIZE_AVAILABLE; + bool haveSize = false; + if (loadStatus & imgIRequest::STATUS_SIZE_AVAILABLE) { + haveSize = true; + } + if (!imageOK || !haveSize) { nsRect altFeedbackSize( 0, 0, @@ -1652,19 +1656,10 @@ void nsImageFrame::Reflow(nsPresContext* aPresContext, ReflowOutput& aMetrics, // outside the image. nsRect& inkOverflow = aMetrics.InkOverflow(); inkOverflow.UnionRect(inkOverflow, altFeedbackSize); - } else { - // Union with our dest rect (note that it will most likely get clipped in - // FinishAndStoreOverflow). Only do this if we're not fragmented, since in - // that case overflow goes into our continuation. - if (aStatus.IsComplete()) { - aMetrics.mOverflowAreas.UnionAllWith( - GetDestRect(aReflowInput.ComputedPhysicalContentBoxRelativeToSelf())); - } - if (PresShell()->IsActive()) { - // We've just reflowed and we should have an accurate size, so we're ready - // to request a decode. - MaybeDecodeForPredictedSize(); - } + } else if (PresShell()->IsActive()) { + // We've just reflowed and we should have an accurate size, so we're ready + // to request a decode. + MaybeDecodeForPredictedSize(); } FinishAndStoreOverflow(&aMetrics, aReflowInput.mStyleDisplay); @@ -2356,8 +2351,10 @@ void nsDisplayImage::Paint(nsDisplayListBuilder* aBuilder, gfxContext* aCtx) { } nsRect nsDisplayImage::GetDestRect() const { - auto* f = static_cast<nsImageFrame*>(mFrame); - return f->GetDestRect(f->GetContentRectRelativeToSelf() + ToReferenceFrame()); + bool snap = true; + const nsRect frameContentBox = GetBounds(&snap); + nsImageFrame* imageFrame = static_cast<nsImageFrame*>(mFrame); + return imageFrame->GetDestRect(frameContentBox); } nsRect nsDisplayImage::GetDestRectViewTransition() const { @@ -2584,8 +2581,7 @@ ImgDrawResult nsImageFrame::PaintImage(gfxContext& aRenderingContext, "bad width"); nsPoint anchorPoint; - const nsRect dest = - GetDestRect(GetContentRectRelativeToSelf() + aPt, &anchorPoint); + nsRect dest = GetDestRect(GetContentRectRelativeToSelf() + aPt, &anchorPoint); SVGImageContext svgContext; SVGImageContext::MaybeStoreContextPaint(svgContext, this, aImage); diff --git a/layout/generic/nsImageFrame.h b/layout/generic/nsImageFrame.h @@ -458,7 +458,7 @@ class nsDisplayImage final : public nsPaintedDisplayItem { nsRect GetBounds(bool* aSnap) const { *aSnap = true; - return Frame()->InkOverflowRectRelativeToSelf() + ToReferenceFrame(); + return Frame()->GetContentRectRelativeToSelf() + ToReferenceFrame(); } nsRect GetBounds(nsDisplayListBuilder*, bool* aSnap) const final { diff --git a/layout/generic/nsVideoFrame.cpp b/layout/generic/nsVideoFrame.cpp @@ -219,12 +219,6 @@ bool nsVideoFrame::ReflowFinished() { return false; } -nsRect nsVideoFrame::GetDestRect(const nsRect& aContentBox) const { - return nsLayoutUtils::ComputeObjectDestRect( - aContentBox, GetIntrinsicSize(/* aIgnoreContainment = */ true), - GetIntrinsicRatio(/* aIgnoreContainment = */ true), StylePosition()); -} - void nsVideoFrame::Reflow(nsPresContext* aPresContext, ReflowOutput& aMetrics, const ReflowInput& aReflowInput, nsReflowStatus& aStatus) { @@ -341,8 +335,6 @@ void nsVideoFrame::Reflow(nsPresContext* aPresContext, ReflowOutput& aMetrics, aMetrics.SetSize(myWM, logicalDesiredSize); aMetrics.SetOverflowAreasToDesiredBounds(); - aMetrics.mOverflowAreas.UnionAllWith( - GetDestRect(aReflowInput.ComputedPhysicalContentBoxRelativeToSelf())); FinishAndStoreOverflow(&aMetrics); @@ -393,17 +385,13 @@ Maybe<nsSize> nsVideoFrame::PosterImageSize() const { } AspectRatio nsVideoFrame::GetIntrinsicRatio() const { - return GetIntrinsicRatio(/* aIgnoreContainment = */ false); -} - -AspectRatio nsVideoFrame::GetIntrinsicRatio(bool aIgnoreContainment) const { if (!HasVideoElement()) { // Audio elements have no intrinsic ratio. return AspectRatio(); } // 'contain:[inline-]size' replaced elements have no intrinsic ratio. - if (!aIgnoreContainment && GetContainSizeAxes().IsAny()) { + if (GetContainSizeAxes().IsAny()) { return AspectRatio(); } @@ -454,9 +442,8 @@ bool nsVideoFrame::ShouldDisplayPoster() const { return true; } -IntrinsicSize nsVideoFrame::GetIntrinsicSize(bool aIgnoreContainment) const { - const auto containAxes = - aIgnoreContainment ? ContainSizeAxes(false, false) : GetContainSizeAxes(); +IntrinsicSize nsVideoFrame::GetIntrinsicSize() { + const auto containAxes = GetContainSizeAxes(); const auto isVideo = HasVideoElement(); // Intrinsic size will be given by contain-intrinsic-size if the element is // size-contained. If both axes have containment, FinishIntrinsicSize() will @@ -497,10 +484,6 @@ IntrinsicSize nsVideoFrame::GetIntrinsicSize(bool aIgnoreContainment) const { IntrinsicSize(kFallbackIntrinsicSize)); } -IntrinsicSize nsVideoFrame::GetIntrinsicSize() { - return GetIntrinsicSize(/* aIgnoreContainment = */ false); -} - void nsVideoFrame::UpdatePosterSource(bool aNotify) { NS_ASSERTION(HasVideoElement(), "Only call this on <video> elements."); HTMLVideoElement* element = static_cast<HTMLVideoElement*>(GetContent()); @@ -568,9 +551,9 @@ class nsDisplayVideo final : public nsPaintedDisplayItem { NS_DISPLAY_DECL_NAME("Video", TYPE_VIDEO) already_AddRefed<ImageContainer> GetImageContainer(gfxRect& aDestGFXRect) { - auto* f = static_cast<nsVideoFrame*>(Frame()); - nsRect area = f->InkOverflowRectRelativeToSelf() + ToReferenceFrame(); - auto* element = static_cast<HTMLVideoElement*>(f->GetContent()); + nsRect area = Frame()->GetContentRectRelativeToSelf() + ToReferenceFrame(); + HTMLVideoElement* element = + static_cast<HTMLVideoElement*>(Frame()->GetContent()); Maybe<CSSIntSize> videoSizeInPx = element->GetVideoSize(); if (videoSizeInPx.isNothing() || area.IsEmpty()) { @@ -590,9 +573,12 @@ class nsDisplayVideo final : public nsPaintedDisplayItem { return nullptr; } - nsRect dest = - f->GetDestRect(f->GetContentRectRelativeToSelf() + ToReferenceFrame()); - aDestGFXRect = f->PresContext()->AppUnitsToGfxUnits(dest); + const auto aspectRatio = AspectRatio::FromSize(*videoSizeInPx); + const IntrinsicSize intrinsicSize(CSSPixel::ToAppUnits(*videoSizeInPx)); + nsRect dest = nsLayoutUtils::ComputeObjectDestRect( + area, intrinsicSize, aspectRatio, Frame()->StylePosition()); + + aDestGFXRect = Frame()->PresContext()->AppUnitsToGfxUnits(dest); aDestGFXRect.Round(); if (aDestGFXRect.IsEmpty()) { return nullptr; @@ -601,7 +587,7 @@ class nsDisplayVideo final : public nsPaintedDisplayItem { return container.forget(); } - bool CreateWebRenderCommands( + virtual bool CreateWebRenderCommands( mozilla::wr::DisplayListBuilder& aBuilder, mozilla::wr::IpcResourceUpdateQueue& aResources, const mozilla::layers::StackingContextHelper& aSc, @@ -630,10 +616,11 @@ class nsDisplayVideo final : public nsPaintedDisplayItem { // For opaque videos, we will want to override GetOpaqueRegion here. // This is tracked by bug 1545498. - nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) const override { + virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, + bool* aSnap) const override { *aSnap = true; nsIFrame* f = Frame(); - return f->InkOverflowRectRelativeToSelf() + ToReferenceFrame(); + return f->GetContentRectRelativeToSelf() + ToReferenceFrame(); } // Only report FirstContentfulPaint when the video is set @@ -643,7 +630,8 @@ class nsDisplayVideo final : public nsPaintedDisplayItem { return video->VideoWidth() > 0; } - void Paint(nsDisplayListBuilder* aBuilder, gfxContext* aCtx) override { + virtual void Paint(nsDisplayListBuilder* aBuilder, + gfxContext* aCtx) override { HTMLVideoElement* element = static_cast<HTMLVideoElement*>(Frame()->GetContent()); gfxRect destGFXRect; diff --git a/layout/generic/nsVideoFrame.h b/layout/generic/nsVideoFrame.h @@ -49,9 +49,7 @@ class nsVideoFrame : public nsContainerFrame, /* get the size of the video's display */ mozilla::IntrinsicSize GetIntrinsicSize() final; - mozilla::IntrinsicSize GetIntrinsicSize(bool aIgnoreContainment) const; mozilla::AspectRatio GetIntrinsicRatio() const final; - mozilla::AspectRatio GetIntrinsicRatio(bool aIgnoreContainment) const; SizeComputationResult ComputeSize( const SizeComputationInput& aSizingInput, mozilla::WritingMode aWM, const mozilla::LogicalSize& aCBSize, nscoord aAvailableISize, @@ -63,8 +61,6 @@ class nsVideoFrame : public nsContainerFrame, nscoord IntrinsicISize(const mozilla::IntrinsicSizeInput& aInput, mozilla::IntrinsicISizeType aType) final; - nsRect GetDestRect(const nsRect& aContentBox) const; - void Destroy(DestroyContext&) final; void Reflow(nsPresContext* aPresContext, ReflowOutput& aDesiredSize,