diff --git a/layout/generic/ReflowInput.cpp b/layout/generic/ReflowInput.cpp index d51626026995..8f1eec17b08b 100644 --- a/layout/generic/ReflowInput.cpp +++ b/layout/generic/ReflowInput.cpp @@ -13,7 +13,6 @@ #include "CounterStyleManager.h" #include "LayoutLogging.h" #include "mozilla/dom/HTMLInputElement.h" -#include "mozilla/ScrollContainerFrame.h" #include "mozilla/WritingModes.h" #include "nsBlockFrame.h" #include "nsFlexContainerFrame.h" @@ -1091,9 +1090,9 @@ nsIFrame* ReflowInput::GetHypotheticalBoxContainer(nsIFrame* aFrame, struct nsHypotheticalPosition { // offset from inline-start edge of containing block (which is a padding edge) - nscoord mIStart = 0; + nscoord mIStart; // offset from block-start edge of containing block (which is a padding edge) - nscoord mBStart = 0; + nscoord mBStart; WritingMode mWritingMode; }; @@ -1212,12 +1211,19 @@ static bool BlockPolarityFlipped(WritingMode aThisWm, WritingMode aOtherWm) { return AxisPolarityFlipped(LogicalAxis::Block, aThisWm, aOtherWm); } -// In the code below, |aCBReflowInput->mFrame| is the absolute containing block, +// Calculate the position of the hypothetical box that the element would have +// if it were in the flow. +// The values returned are relative to the padding edge of the absolute +// containing block. The writing-mode of the hypothetical box position will +// have the same block direction as the absolute containing block, but may +// differ in inline-bidi direction. +// In the code below, |aCBReflowInput->frame| is the absolute containing block, // while |containingBlock| is the nearest block container of the placeholder // frame, which may be different from the absolute containing block. void ReflowInput::CalculateHypotheticalPosition( - nsPlaceholderFrame* aPlaceholderFrame, const ReflowInput* aCBReflowInput, - nsHypotheticalPosition& aHypotheticalPos) const { + nsPresContext* aPresContext, nsPlaceholderFrame* aPlaceholderFrame, + const ReflowInput* aCBReflowInput, nsHypotheticalPosition& aHypotheticalPos, + LayoutFrameType aFrameType) const { NS_ASSERTION(mStyleDisplay->mOriginalDisplay != StyleDisplay::None, "mOriginalDisplay has not been properly initialized"); @@ -1354,9 +1360,9 @@ void ReflowInput::CalculateHypotheticalPosition( aPlaceholderFrame->SetLineIsEmptySoFar(true); allEmpty = true; } else { - auto* prev = aPlaceholderFrame->GetPrevSibling(); + auto prev = aPlaceholderFrame->GetPrevSibling(); if (prev && prev->IsPlaceholderFrame()) { - auto* ph = static_cast(prev); + auto ph = static_cast(prev); if (ph->GetLineIsEmptySoFar(&allEmpty)) { aPlaceholderFrame->SetLineIsEmptySoFar(allEmpty); } @@ -1416,24 +1422,8 @@ void ReflowInput::CalculateHypotheticalPosition( // The current coordinate space is that of the nearest block to the // placeholder. Convert to the coordinate space of the absolute containing // block. - const nsIFrame* cbFrame = aCBReflowInput->mFrame; - nsPoint cbOffset = containingBlock->GetOffsetToIgnoringScrolling(cbFrame); - if (cbFrame->IsViewportFrame()) { - // When the containing block is the ViewportFrame, i.e. we are calculating - // the static position for a fixed-positioned frame, we need to adjust the - // origin to exclude the scrollbar or scrollbar-gutter area. The - // ViewportFrame's containing block rect is passed into - // nsAbsoluteContainingBlock::ReflowAbsoluteFrame(), and it will add the - // rect's origin to the fixed-positioned frame's final position if needed. - // - // Note: The origin of the containing block rect is adjusted in - // ViewportFrame::AdjustReflowInputForScrollbars(). Ensure the code there - // remains in sync with the logic here. - if (ScrollContainerFrame* sf = cbFrame->GetScrollTargetFrame()) { - const nsMargin scrollbarSizes = sf->GetActualScrollbarSizes(); - cbOffset.MoveBy(-scrollbarSizes.left, -scrollbarSizes.top); - } - } + nsPoint cbOffset = + containingBlock->GetOffsetToIgnoringScrolling(aCBReflowInput->mFrame); nsSize reflowSize = aCBReflowInput->ComputedSizeAsContainerIfConstrained(); LogicalPoint logCBOffs(wm, cbOffset, reflowSize - containerSize); @@ -1620,14 +1610,16 @@ LogicalSize ReflowInput::CalculateAbsoluteSizeWithResolvedAutoBlockSize( return resultSize; } -void ReflowInput::InitAbsoluteConstraints(const ReflowInput* aCBReflowInput, - const LogicalSize& aCBSize) { +void ReflowInput::InitAbsoluteConstraints(nsPresContext* aPresContext, + const ReflowInput* aCBReflowInput, + const LogicalSize& aCBSize, + LayoutFrameType aFrameType) { WritingMode wm = GetWritingMode(); WritingMode cbwm = aCBReflowInput->GetWritingMode(); NS_WARNING_ASSERTION(aCBSize.BSize(cbwm) != NS_UNCONSTRAINEDSIZE, "containing block bsize must be constrained"); - NS_ASSERTION(!mFrame->IsTableFrame(), + NS_ASSERTION(aFrameType != LayoutFrameType::Table, "InitAbsoluteConstraints should not be called on table frames"); NS_ASSERTION(mFrame->HasAnyStateBits(NS_FRAME_OUT_OF_FLOW), "Why are we here?"); @@ -1638,9 +1630,9 @@ void ReflowInput::InitAbsoluteConstraints(const ReflowInput* aCBReflowInput, bool bStartIsAuto = styleOffset.GetBStart(cbwm).IsAuto(); bool bEndIsAuto = styleOffset.GetBEnd(cbwm).IsAuto(); - // If both 'inline-start' and 'inline-end' are 'auto' or both 'block-start' - // and 'block-end' are 'auto', then compute the hypothetical box position; - // i.e. where the element would be, if it were in-flow. + // If both 'left' and 'right' are 'auto' or both 'top' and 'bottom' are + // 'auto', then compute the hypothetical box position where the element would + // have been if it had been in the flow nsHypotheticalPosition hypotheticalPos; if ((iStartIsAuto && iEndIsAuto) || (bStartIsAuto && bEndIsAuto)) { nsPlaceholderFrame* placeholderFrame = mFrame->GetPlaceholderFrame(); @@ -1681,8 +1673,9 @@ void ReflowInput::InitAbsoluteConstraints(const ReflowInput* aCBReflowInput, } } else { // XXXmats all this is broken for orthogonal writing-modes: bug 1521988. - CalculateHypotheticalPosition(placeholderFrame, aCBReflowInput, - hypotheticalPos); + CalculateHypotheticalPosition(aPresContext, placeholderFrame, + aCBReflowInput, hypotheticalPos, + aFrameType); if (aCBReflowInput->mFrame->IsGridContainerFrame()) { // 'hypotheticalPos' is relative to the padding rect of the CB *frame*. // In grid layout the CB is the grid area rectangle, so we translate @@ -1704,9 +1697,12 @@ void ReflowInput::InitAbsoluteConstraints(const ReflowInput* aCBReflowInput, } } + // Initialize the 'left' and 'right' computed offsets + // XXX Handle new 'static-position' value... + // Size of the containing block in its writing mode LogicalSize cbSize = aCBSize; - LogicalMargin offsets(cbwm); + LogicalMargin offsets = ComputedLogicalOffsets(cbwm); if (iStartIsAuto) { offsets.IStart(cbwm) = 0; @@ -2326,8 +2322,9 @@ void ReflowInput::InitConstraints( // XXXfr hack for making frames behave properly when in overflow // container lists, see bug 154892; need to revisit later !mFrame->GetPrevInFlow()) { - InitAbsoluteConstraints(cbri, - cbSize.ConvertTo(cbri->GetWritingMode(), wm)); + InitAbsoluteConstraints(aPresContext, cbri, + cbSize.ConvertTo(cbri->GetWritingMode(), wm), + aFrameType); } else { AutoMaybeDisableFontInflation an(mFrame); diff --git a/layout/generic/ReflowInput.h b/layout/generic/ReflowInput.h index f30aba78e196..1f64ab40b1fb 100644 --- a/layout/generic/ReflowInput.h +++ b/layout/generic/ReflowInput.h @@ -907,17 +907,16 @@ struct ReflowInput : public SizeComputationInput { nscoord& aCBIStartEdge, mozilla::LogicalSize& aCBSize) const; - // Calculate the position of the hypothetical box that the placeholder frame - // (for a position:fixed/absolute element) would be if it were in-flow (i.e., - // positioned statically). - // - // The position of the hypothetical box is relative to the padding edge of the - // absolute containing block (aCBReflowInput->mFrame). The writing mode of the - // hypothetical box will have the same block direction as the absolute - // containing block, but it may differ in the inline direction. - void CalculateHypotheticalPosition( - nsPlaceholderFrame* aPlaceholderFrame, const ReflowInput* aCBReflowInput, - nsHypotheticalPosition& aHypotheticalPos) const; + // Calculate a "hypothetical box" position where the placeholder frame + // (for a position:fixed/absolute element) would have been placed if it were + // positioned statically. The hypothetical box position will have a writing + // mode with the same block direction as the absolute containing block + // (aCBReflowInput->frame), though it may differ in inline direction. + void CalculateHypotheticalPosition(nsPresContext* aPresContext, + nsPlaceholderFrame* aPlaceholderFrame, + const ReflowInput* aCBReflowInput, + nsHypotheticalPosition& aHypotheticalPos, + mozilla::LayoutFrameType aFrameType) const; // Check if we can use the resolved auto block size (by insets) to compute // the inline size through aspect-ratio on absolute-positioned elements. @@ -931,8 +930,10 @@ struct ReflowInput : public SizeComputationInput { LogicalSize CalculateAbsoluteSizeWithResolvedAutoBlockSize( nscoord aAutoBSize, const LogicalSize& aTentativeComputedSize); - void InitAbsoluteConstraints(const ReflowInput* aCBReflowInput, - const LogicalSize& aCBSize); + void InitAbsoluteConstraints(nsPresContext* aPresContext, + const ReflowInput* aCBReflowInput, + const mozilla::LogicalSize& aContainingBlockSize, + mozilla::LayoutFrameType aFrameType); // Calculates the computed values for the 'min-inline-size', // 'max-inline-size', 'min-block-size', and 'max-block-size' properties, and diff --git a/layout/generic/ViewportFrame.cpp b/layout/generic/ViewportFrame.cpp index ade926e689a4..65e748a89513 100644 --- a/layout/generic/ViewportFrame.cpp +++ b/layout/generic/ViewportFrame.cpp @@ -285,10 +285,10 @@ nscoord ViewportFrame::GetPrefISize(gfxContext* aRenderingContext) { nsPoint ViewportFrame::AdjustReflowInputForScrollbars( ReflowInput* aReflowInput) const { - if (ScrollContainerFrame* scrollContainerFrame = GetScrollTargetFrame()) { - // Note: In ReflowInput::CalculateHypotheticalPosition(), we exclude the - // scrollbar or scrollbar-gutter area when computing the offset to - // ViewportFrame. Ensure the code there remains in sync with the logic here. + // Get our prinicpal child frame and see if we're scrollable + nsIFrame* kidFrame = mFrames.FirstChild(); + + if (ScrollContainerFrame* scrollContainerFrame = do_QueryFrame(kidFrame)) { WritingMode wm = aReflowInput->GetWritingMode(); LogicalMargin scrollbars(wm, scrollContainerFrame->GetActualScrollbarSizes()); @@ -417,10 +417,6 @@ void ViewportFrame::Reflow(nsPresContext* aPresContext, NS_FRAME_TRACE_REFLOW_OUT("ViewportFrame::Reflow", aStatus); } -ScrollContainerFrame* ViewportFrame::GetScrollTargetFrame() const { - return do_QueryFrame(mFrames.FirstChild()); -} - void ViewportFrame::UpdateStyle(ServoRestyleState& aRestyleState) { RefPtr newStyle = aRestyleState.StyleSet().ResolveInheritingAnonymousBoxStyle( diff --git a/layout/generic/ViewportFrame.h b/layout/generic/ViewportFrame.h index 8108d9d636b7..08fe97132a84 100644 --- a/layout/generic/ViewportFrame.h +++ b/layout/generic/ViewportFrame.h @@ -61,9 +61,6 @@ class ViewportFrame : public nsContainerFrame { const ReflowInput& aReflowInput, nsReflowStatus& aStatus) override; - // Get the root scroll container frame, if any. - ScrollContainerFrame* GetScrollTargetFrame() const override; - bool ComputeCustomOverflow(mozilla::OverflowAreas&) override { return false; } /** diff --git a/layout/style/nsComputedDOMStyle.cpp b/layout/style/nsComputedDOMStyle.cpp index b3ec3f9e21d4..744024a2b1d6 100644 --- a/layout/style/nsComputedDOMStyle.cpp +++ b/layout/style/nsComputedDOMStyle.cpp @@ -2011,14 +2011,17 @@ nscoord nsComputedDOMStyle::GetUsedAbsoluteOffset(mozilla::Side aSide) { // _not_ include the scrollbars. For fixed positioned frames, // the containing block is the viewport, which _does_ include // scrollbars. We have to do some extra work. - if (ScrollContainerFrame* scrollContainerFrame = - container->GetScrollTargetFrame()) { + // the first child in the default frame list is what we want + nsIFrame* scrollingChild = container->PrincipalChildList().FirstChild(); + ScrollContainerFrame* scrollContainerFrame = do_QueryFrame(scrollingChild); + if (scrollContainerFrame) { scrollbarSizes = scrollContainerFrame->GetActualScrollbarSizes(); } // The viewport size might have been expanded by the visual viewport or // the minimum-scale size. - auto* viewportFrame = static_cast(container); + const ViewportFrame* viewportFrame = do_QueryFrame(container); + MOZ_ASSERT(viewportFrame); containerRect.SizeTo( viewportFrame->AdjustViewportSizeForFixedPosition(containerRect)); } else if (container->IsGridContainerFrame() && diff --git a/testing/web-platform/tests/css/css-overflow/scrollbar-gutter-fixedpos-003-ref.html b/testing/web-platform/tests/css/css-overflow/scrollbar-gutter-fixedpos-003-ref.html deleted file mode 100644 index 72a6c087b31d..000000000000 --- a/testing/web-platform/tests/css/css-overflow/scrollbar-gutter-fixedpos-003-ref.html +++ /dev/null @@ -1,20 +0,0 @@ - -CSS Overflow Reference: Root element's scrollbar-gutter is accounted for when computing hypothetical box in fixed-pos positioning - - - - -

Test passes if there is a filled green square and no red.

-
diff --git a/testing/web-platform/tests/css/css-overflow/scrollbar-gutter-fixedpos-003.html b/testing/web-platform/tests/css/css-overflow/scrollbar-gutter-fixedpos-003.html deleted file mode 100644 index cdffebb5c7b8..000000000000 --- a/testing/web-platform/tests/css/css-overflow/scrollbar-gutter-fixedpos-003.html +++ /dev/null @@ -1,22 +0,0 @@ - -CSS Overflow Test: Root element's scrollbar-gutter is accounted for when computing hypothetical box in fixed-pos positioning - - - - - - -

Test passes if there is a filled green square and no red.

-
-
diff --git a/testing/web-platform/tests/css/css-overflow/scrollbar-gutter-fixedpos-004-ref.html b/testing/web-platform/tests/css/css-overflow/scrollbar-gutter-fixedpos-004-ref.html deleted file mode 100644 index fe1b96fce8ac..000000000000 --- a/testing/web-platform/tests/css/css-overflow/scrollbar-gutter-fixedpos-004-ref.html +++ /dev/null @@ -1,21 +0,0 @@ - -CSS Overflow Reference: Root element's scrollbar-gutter is accounted for when computing hypothetical box in fixed-pos positioning - - - - -

Test passes if there is a filled green square and no red.

-
diff --git a/testing/web-platform/tests/css/css-overflow/scrollbar-gutter-fixedpos-004.html b/testing/web-platform/tests/css/css-overflow/scrollbar-gutter-fixedpos-004.html deleted file mode 100644 index debb28d397f5..000000000000 --- a/testing/web-platform/tests/css/css-overflow/scrollbar-gutter-fixedpos-004.html +++ /dev/null @@ -1,23 +0,0 @@ - -CSS Overflow Test: Root element's scrollbar-gutter is accounted for when computing hypothetical box in fixed-pos positioning - - - - - - -

Test passes if there is a filled green square and no red.

-
-