diff --git a/layout/base/nsLayoutUtils.cpp b/layout/base/nsLayoutUtils.cpp index 381aa049e27d..68d7fbc38d92 100644 --- a/layout/base/nsLayoutUtils.cpp +++ b/layout/base/nsLayoutUtils.cpp @@ -5349,7 +5349,12 @@ nsLayoutUtils::ComputeSizeWithIntrinsicDimensions(WritingMode aWM, const nsStyleCoord* inlineStyleCoord = &stylePos->ISize(aWM); const nsStyleCoord* blockStyleCoord = &stylePos->BSize(aWM); - bool isFlexItem = aFrame->IsFlexItem(); + nsIAtom* parentFrameType = + aFrame->GetParent() ? aFrame->GetParent()->GetType() : nullptr; + const bool isGridItem = (parentFrameType == nsGkAtoms::gridContainerFrame && + !(aFrame->GetStateBits() & NS_FRAME_OUT_OF_FLOW)); + const bool isFlexItem = (parentFrameType == nsGkAtoms::flexContainerFrame && + !(aFrame->GetStateBits() & NS_FRAME_OUT_OF_FLOW)); bool isInlineFlexItem = false; Maybe imposedMainSizeStyleCoord; @@ -5418,7 +5423,7 @@ nsLayoutUtils::ComputeSizeWithIntrinsicDimensions(WritingMode aWM, // or (a * b) / c (which are equivalent). const bool isAutoISize = inlineStyleCoord->GetUnit() == eStyleUnit_Auto; - const bool isAutoBSize = IsAutoBSize(*blockStyleCoord, aCBSize.BSize(aWM)); + bool isAutoBSize = IsAutoBSize(*blockStyleCoord, aCBSize.BSize(aWM)); LogicalSize boxSizingAdjust(aWM); switch (stylePos->mBoxSizing) { @@ -5479,6 +5484,25 @@ nsLayoutUtils::ComputeSizeWithIntrinsicDimensions(WritingMode aWM, bSize = nsLayoutUtils::ComputeBSizeValue(aCBSize.BSize(aWM), boxSizingAdjust.BSize(aWM), *blockStyleCoord); + } else if (MOZ_UNLIKELY(isGridItem)) { + MOZ_ASSERT(!IS_TRUE_OVERFLOW_CONTAINER(aFrame)); + // 'auto' block-size for grid-level box - apply 'stretch' as needed: + auto cbSize = aCBSize.BSize(aWM); + if (cbSize != NS_AUTOHEIGHT && + !aFrame->StyleMargin()->HasBlockAxisAuto(aWM)) { + auto blockAxisAlignment = + !aWM.IsOrthogonalTo(aFrame->GetParent()->GetWritingMode()) ? + stylePos->ComputedAlignSelf(aFrame->StyleContext()->GetParent()) : + stylePos->ComputedJustifySelf(aFrame->StyleContext()->GetParent()); + if (blockAxisAlignment == NS_STYLE_ALIGN_NORMAL || + blockAxisAlignment == NS_STYLE_ALIGN_STRETCH) { + bSize = std::max(nscoord(0), cbSize - + aPadding.BSize(aWM) - + aBorder.BSize(aWM) - + aMargin.BSize(aWM)); + isAutoBSize = false; + } + } } const nsStyleCoord& maxBSizeCoord = stylePos->MaxBSize(aWM); diff --git a/layout/generic/nsFrame.cpp b/layout/generic/nsFrame.cpp index 9ac49bf5ceee..33c6d37a1961 100644 --- a/layout/generic/nsFrame.cpp +++ b/layout/generic/nsFrame.cpp @@ -4729,12 +4729,32 @@ nsFrame::ComputeSize(nsRenderingContext *aRenderingContext, // (but not if we're auto-height or if we recieved the "eUseAutoHeight" // flag -- then, we'll just stick with the height that we already calculated // in the initial ComputeAutoSize() call.) - if (!nsLayoutUtils::IsAutoBSize(*blockStyleCoord, aCBSize.BSize(aWM)) && - !(aFlags & nsIFrame::eUseAutoHeight)) { - result.BSize(aWM) = - nsLayoutUtils::ComputeBSizeValue(aCBSize.BSize(aWM), - boxSizingAdjust.BSize(aWM), - *blockStyleCoord); + if (!(aFlags & nsIFrame::eUseAutoHeight)) { + if (!nsLayoutUtils::IsAutoBSize(*blockStyleCoord, aCBSize.BSize(aWM))) { + result.BSize(aWM) = + nsLayoutUtils::ComputeBSizeValue(aCBSize.BSize(aWM), + boxSizingAdjust.BSize(aWM), + *blockStyleCoord); + } else if (MOZ_UNLIKELY(isGridItem) && + blockStyleCoord->GetUnit() == eStyleUnit_Auto && + !IS_TRUE_OVERFLOW_CONTAINER(this)) { + // 'auto' block-size for grid-level box - apply 'stretch' as needed: + auto cbSize = aCBSize.BSize(aWM); + if (cbSize != NS_AUTOHEIGHT && + !StyleMargin()->HasBlockAxisAuto(aWM)) { + auto blockAxisAlignment = + !aWM.IsOrthogonalTo(GetParent()->GetWritingMode()) ? + StylePosition()->ComputedAlignSelf(StyleContext()->GetParent()) : + StylePosition()->ComputedJustifySelf(StyleContext()->GetParent()); + if (blockAxisAlignment == NS_STYLE_ALIGN_NORMAL || + blockAxisAlignment == NS_STYLE_ALIGN_STRETCH) { + result.BSize(aWM) = std::max(nscoord(0), cbSize - + aPadding.BSize(aWM) - + aBorder.BSize(aWM) - + aMargin.BSize(aWM)); + } + } + } } const nsStyleCoord& maxBSizeCoord = stylePos->MaxBSize(aWM); diff --git a/layout/generic/nsGridContainerFrame.cpp b/layout/generic/nsGridContainerFrame.cpp index 6f88a03df732..56d0db5816d2 100644 --- a/layout/generic/nsGridContainerFrame.cpp +++ b/layout/generic/nsGridContainerFrame.cpp @@ -2185,6 +2185,8 @@ AlignJustifySelf(uint8_t aAlignment, bool aOverflowSafe, LogicalAxis aAxis, case NS_STYLE_ALIGN_LAST_BASELINE: NS_WARNING("NYI: baseline/last-baseline for grid (bug 1151204)"); // XXX MOZ_FALLTHROUGH; + case NS_STYLE_ALIGN_STRETCH: + MOZ_FALLTHROUGH; // ComputeSize() deals with it case NS_STYLE_ALIGN_START: offset = marginStart; break; @@ -2200,6 +2202,7 @@ AlignJustifySelf(uint8_t aAlignment, bool aOverflowSafe, LogicalAxis aAxis, offset = (aCBSize - size + marginStart - marginEnd) / 2; break; } +#if 0 case NS_STYLE_ALIGN_STRETCH: { MOZ_ASSERT(!hasAutoMarginStart && !hasAutoMarginEnd); offset = marginStart; @@ -2242,6 +2245,7 @@ AlignJustifySelf(uint8_t aAlignment, bool aOverflowSafe, LogicalAxis aAxis, } break; } +#endif default: MOZ_ASSERT_UNREACHABLE("unknown align-/justify-self value"); } @@ -3268,7 +3272,8 @@ ContentContribution(nsIFrame* aChild, // XXX this will give mostly correct results for now (until bug 1174569). LogicalSize availableSize(wm, INFINITE_ISIZE_COORD, NS_UNCONSTRAINEDSIZE); nsHTMLReflowState childRS(pc, *rs, aChild, availableSize, nullptr, - nsHTMLReflowState::COMPUTE_SIZE_SHRINK_WRAP); + nsHTMLReflowState::COMPUTE_SIZE_SHRINK_WRAP | + nsHTMLReflowState::COMPUTE_SIZE_USE_AUTO_BSIZE); nsHTMLReflowMetrics childSize(childRS); nsReflowStatus childStatus; const uint32_t flags = NS_FRAME_NO_MOVE_FRAME | NS_FRAME_NO_SIZE_VIEW; @@ -4149,12 +4154,7 @@ nsGridContainerFrame::ReflowInFlowChild(nsIFrame* aChild, cb = aState.ContainingBlockFor(area); isConstrainedBSize = aFragmentainer && !wm.IsOrthogonalTo(childWM); if (isConstrainedBSize) { - nscoord fragCBOffset = cb.BStart(wm) - aState.mFragBStart; - if (fragCBOffset < 0) { - // Subtract the "consumed" part of the grid area. - cb.BSize(wm) = std::max(fragCBOffset + cb.BSize(wm), 0); - } - cb.BStart(wm) = std::max(fragCBOffset, 0); + cb.BStart(wm) = std::max(0, cb.BStart(wm) - aState.mFragBStart); toFragmentainerEnd = aFragmentainer->mToFragmentainerEnd - aState.mFragBStart - cb.BStart(wm); toFragmentainerEnd = std::max(toFragmentainerEnd, 0); diff --git a/layout/generic/nsHTMLReflowState.cpp b/layout/generic/nsHTMLReflowState.cpp index 8b752bc8d9df..4c2190cf972a 100644 --- a/layout/generic/nsHTMLReflowState.cpp +++ b/layout/generic/nsHTMLReflowState.cpp @@ -82,6 +82,9 @@ nsHTMLReflowState::nsHTMLReflowState(nsPresContext* aPresContext, if (aFlags & COMPUTE_SIZE_SHRINK_WRAP) { mFlags.mShrinkWrap = true; } + if (aFlags & COMPUTE_SIZE_USE_AUTO_BSIZE) { + mFlags.mUseAutoBSize = true; + } if (aFlags & STATIC_POS_IS_CB_ORIGIN) { mFlags.mStaticPosIsCBOrigin = true; } @@ -226,6 +229,7 @@ nsHTMLReflowState::nsHTMLReflowState( mFlags.mIsFlexContainerMeasuringHeight = false; mFlags.mDummyParentReflowState = false; mFlags.mShrinkWrap = !!(aFlags & COMPUTE_SIZE_SHRINK_WRAP); + mFlags.mUseAutoBSize = !!(aFlags & COMPUTE_SIZE_USE_AUTO_BSIZE); mFlags.mStaticPosIsCBOrigin = !!(aFlags & STATIC_POS_IS_CB_ORIGIN); mDiscoveredClearance = nullptr; @@ -1618,6 +1622,10 @@ nsHTMLReflowState::InitAbsoluteConstraints(nsPresContext* aPresContext, computeSizeFlags = ComputeSizeFlags(computeSizeFlags | ComputeSizeFlags::eShrinkWrap); } + if (mFlags.mUseAutoBSize) { + computeSizeFlags = + ComputeSizeFlags(computeSizeFlags | ComputeSizeFlags::eUseAutoHeight); + } if (wm.IsOrthogonalTo(cbwm)) { if (bStartIsAuto || bEndIsAuto) { computeSizeFlags = @@ -2319,6 +2327,10 @@ nsHTMLReflowState::InitConstraints(nsPresContext* aPresContext, computeSizeFlags = ComputeSizeFlags(computeSizeFlags | ComputeSizeFlags::eShrinkWrap); } + if (mFlags.mUseAutoBSize) { + computeSizeFlags = + ComputeSizeFlags(computeSizeFlags | ComputeSizeFlags::eUseAutoHeight); + } nsIFrame* parent = frame->GetParent(); nsIAtom* parentFrameType = parent ? parent->GetType() : nullptr; diff --git a/layout/generic/nsHTMLReflowState.h b/layout/generic/nsHTMLReflowState.h index 1fca0b3c5365..f3ba1a234cd0 100644 --- a/layout/generic/nsHTMLReflowState.h +++ b/layout/generic/nsHTMLReflowState.h @@ -584,6 +584,7 @@ public: // (e.g. columns), it should always // reflow its placeholder children. uint16_t mShrinkWrap:1; // stores the COMPUTE_SIZE_SHRINK_WRAP ctor flag + uint16_t mUseAutoBSize:1; // stores the COMPUTE_SIZE_USE_AUTO_BSIZE ctor flag uint16_t mStaticPosIsCBOrigin:1; // the STATIC_POS_IS_CB_ORIGIN ctor flag } mFlags; @@ -681,9 +682,13 @@ public: // will be passed to ComputeSize()). COMPUTE_SIZE_SHRINK_WRAP = (1<<2), + // The caller wants height:auto behavior (ComputeSizeFlags::eUseAutoHeight + // will be be passed to ComputeSize()). + COMPUTE_SIZE_USE_AUTO_BSIZE = (1<<3), + // The caller wants the abs.pos. static-position resolved at the origin // of the containing block, i.e. at LogicalPoint(0, 0). - STATIC_POS_IS_CB_ORIGIN = (1<<3), + STATIC_POS_IS_CB_ORIGIN = (1<<4), }; // This method initializes various data members. It is automatically