mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-18 14:56:07 +00:00
Bug 1909761 Part 4 - Construct a percentage basis when computing children's intrinsic inline size contributions. r=dholbert
A percentage basis is needed to resolve percentage block size when computing children's intrinsic inline size contributions. This is necessary for a child or descendants with a preferred aspect-ratio so that the block size can transfer through the aspect-ratio to become an intrinsic inline size. The change in `nsFlexContainerFrame::ComputeIntrinsicISize()` is necessary to keep us passing `testing/web-platform/tests/css/css-flexbox/image-nested-within-definite-column-flexbox.html`. The change in `nsPlaceholderFrame::AddFloatToIntrinsicISizeData()` is necessary to keep us passing `testing/web-platform/tests/css/css-sizing/intrinsic-percent-replaced-dynamic-010.html`. `GetISizeInfo()` in BasicTableLayoutStrategy.cpp is modified to pass table cell frame's bsize as percentage basis. Otherwise, `layout/reftests/bugs/522632-1.html` fails. This is our current behavior, but it is bug 1461852. Differential Revision: https://phabricator.services.mozilla.com/D219523
This commit is contained in:
parent
520580e888
commit
55248224df
@ -2622,7 +2622,7 @@ MOZ_CAN_RUN_SCRIPT_BOUNDARY NS_IMETHODIMP nsDocumentViewer::GetContentSize(
|
||||
const nscoord minISize = wm.IsVertical() ? constraints.mMinSize.height
|
||||
: constraints.mMinSize.width;
|
||||
const nscoord maxISize = wm.IsVertical() ? aMaxHeight : aMaxWidth;
|
||||
const IntrinsicSizeInput input(rcx.get());
|
||||
const IntrinsicSizeInput input(rcx.get(), Nothing());
|
||||
if (aPrefWidth) {
|
||||
prefISize = std::max(root->GetMinISize(input), aPrefWidth);
|
||||
} else {
|
||||
|
@ -4041,6 +4041,9 @@ static Maybe<nscoord> GetPercentBSize(const LengthPercentage& aSize,
|
||||
nsIFrame* aFrame, bool aHorizontalAxis);
|
||||
|
||||
// Only call on aSize for which GetAbsoluteSize returned Nothing().
|
||||
//
|
||||
// Bug 1363918: We can remove GetPercentBSize() after we've updated all of
|
||||
// IntrinsicForAxis()'s callsites to pass it a percentage basis.
|
||||
template <typename SizeOrMaxSize>
|
||||
static Maybe<nscoord> GetPercentBSize(const SizeOrMaxSize& aSize,
|
||||
nsIFrame* aFrame, bool aHorizontalAxis) {
|
||||
@ -4309,7 +4312,9 @@ static Maybe<nscoord> GetIntrinsicSize(nsIFrame::ExtremumLength aLength,
|
||||
if (aISizeFromAspectRatio) {
|
||||
result = *aISizeFromAspectRatio;
|
||||
} else {
|
||||
const IntrinsicSizeInput input(aRenderingContext);
|
||||
// Bug 1363918: We need to refactor this function to compute a percentage
|
||||
// basis when computing intrinsic sizes.
|
||||
const IntrinsicSizeInput input(aRenderingContext, Nothing());
|
||||
auto type = aLength == nsIFrame::ExtremumLength::MaxContent
|
||||
? IntrinsicISizeType::PrefISize
|
||||
: IntrinsicISizeType::MinISize;
|
||||
@ -4439,7 +4444,9 @@ static nscoord AddIntrinsicSizeOffset(
|
||||
if (aISizeFromAspectRatio) {
|
||||
minContent = maxContent = *aISizeFromAspectRatio;
|
||||
} else {
|
||||
const IntrinsicSizeInput input(aRenderingContext);
|
||||
// Bug 1363918: We need to refactor this function to compute a percentage
|
||||
// basis when computing intrinsic sizes.
|
||||
const IntrinsicSizeInput input(aRenderingContext, Nothing());
|
||||
minContent = aFrame->GetMinISize(input);
|
||||
maxContent = aFrame->GetPrefISize(input);
|
||||
}
|
||||
@ -4643,6 +4650,32 @@ nscoord nsLayoutUtils::IntrinsicForAxis(
|
||||
fixedMinISize = GetAbsoluteSize(styleMinISize);
|
||||
}
|
||||
|
||||
// Handle elements with an intrinsic ratio (or size) and a specified
|
||||
// height, min-height, or max-height.
|
||||
// NOTE:
|
||||
// 1. We treat "min-height:auto" as "0" for the purpose of this code,
|
||||
// since that's what it means in all cases except for on flex items -- and
|
||||
// even there, we're supposed to ignore it (i.e. treat it as 0) until the
|
||||
// flex container explicitly considers it.
|
||||
// 2. The 'B' in |styleBSize|, |styleMinBSize|, and |styleMaxBSize|
|
||||
// represents the ratio-determining axis of |aFrame|. It could be the inline
|
||||
// axis or the block axis of |aFrame|. (So we are calculating the size
|
||||
// along the ratio-dependent axis in this if-branch.)
|
||||
StyleSize styleBSize = horizontalAxis ? stylePos->mHeight : stylePos->mWidth;
|
||||
StyleSize styleMinBSize =
|
||||
horizontalAxis ? stylePos->mMinHeight : stylePos->mMinWidth;
|
||||
StyleMaxSize styleMaxBSize =
|
||||
horizontalAxis ? stylePos->mMaxHeight : stylePos->mMaxWidth;
|
||||
|
||||
// According to the spec, max-content and min-content should behave as the
|
||||
// property's initial values in block axis.
|
||||
// It also make senses to use the initial values for -moz-fit-content and
|
||||
// -moz-available for intrinsic size in block axis. Therefore, we reset them
|
||||
// if needed.
|
||||
if (isInlineAxis) {
|
||||
ResetIfKeywords(styleBSize, styleMinBSize, styleMaxBSize);
|
||||
}
|
||||
|
||||
auto childWM = aFrame->GetWritingMode();
|
||||
nscoord pmPercentageBasis = NS_UNCONSTRAINEDSIZE;
|
||||
if (aPercentageBasis.isSome()) {
|
||||
@ -4734,7 +4767,37 @@ nscoord nsLayoutUtils::IntrinsicForAxis(
|
||||
result = aFrame->BSize();
|
||||
}
|
||||
} else {
|
||||
const IntrinsicSizeInput input(aRenderingContext);
|
||||
// To resolve aFrame's intrinsic inline size, we first check if we can
|
||||
// resolve a block-axis percentage basis for aFrame's children. This can
|
||||
// influence their inline size contributions, e.g. if they have an
|
||||
// aspect-ratio and a percentage-based block size.
|
||||
const nscoord percentageBasisBSizeForFrame =
|
||||
aPercentageBasis ? aPercentageBasis->BSize(childWM)
|
||||
: NS_UNCONSTRAINEDSIZE;
|
||||
nscoord percentageBasisBSizeForChildren;
|
||||
if (aFrame->IsBlockContainer()) {
|
||||
// Compute and cache the box-sizing adjustment in contentEdgeToBoxSizing
|
||||
// for later use within this function.
|
||||
contentEdgeToBoxSizing.emplace(GetContentEdgeToBoxSizing(boxSizing));
|
||||
|
||||
// aFrame is a containing block, so its block size (with min and max
|
||||
// block size constraints applied) serves as the percentage basis for
|
||||
// its children.
|
||||
percentageBasisBSizeForChildren =
|
||||
nsIFrame::ComputeBSizeValueAsPercentageBasis(
|
||||
styleBSize, styleMinBSize, styleMaxBSize,
|
||||
percentageBasisBSizeForFrame,
|
||||
contentEdgeToBoxSizing->BSize(childWM));
|
||||
} else {
|
||||
// aFrame is not a containing block, so its children share the same
|
||||
// containing block as aFrame. Therefore, the percentage basis for
|
||||
// aFrame's children is the same as that for aFrame.
|
||||
percentageBasisBSizeForChildren = percentageBasisBSizeForFrame;
|
||||
}
|
||||
const IntrinsicSizeInput input(
|
||||
aRenderingContext,
|
||||
Some(LogicalSize(childWM, NS_UNCONSTRAINEDSIZE,
|
||||
percentageBasisBSizeForChildren)));
|
||||
result = aFrame->IntrinsicISize(input, aType);
|
||||
}
|
||||
#ifdef DEBUG_INTRINSIC_WIDTH
|
||||
@ -4746,33 +4809,6 @@ nscoord nsLayoutUtils::IntrinsicForAxis(
|
||||
horizontalAxis ? "horizontal" : "vertical", result);
|
||||
#endif
|
||||
|
||||
// Handle elements with an intrinsic ratio (or size) and a specified
|
||||
// height, min-height, or max-height.
|
||||
// NOTE:
|
||||
// 1. We treat "min-height:auto" as "0" for the purpose of this code,
|
||||
// since that's what it means in all cases except for on flex items -- and
|
||||
// even there, we're supposed to ignore it (i.e. treat it as 0) until the
|
||||
// flex container explicitly considers it.
|
||||
// 2. The 'B' in |styleBSize|, |styleMinBSize|, and |styleMaxBSize|
|
||||
// represents the ratio-determining axis of |aFrame|. It could be the inline
|
||||
// axis or the block axis of |aFrame|. (So we are calculating the size
|
||||
// along the ratio-dependent axis in this if-branch.)
|
||||
StyleSize styleBSize =
|
||||
horizontalAxis ? stylePos->mHeight : stylePos->mWidth;
|
||||
StyleSize styleMinBSize =
|
||||
horizontalAxis ? stylePos->mMinHeight : stylePos->mMinWidth;
|
||||
StyleMaxSize styleMaxBSize =
|
||||
horizontalAxis ? stylePos->mMaxHeight : stylePos->mMaxWidth;
|
||||
|
||||
// According to the spec, max-content and min-content should behave as the
|
||||
// property's initial values in block axis.
|
||||
// It also make senses to use the initial values for -moz-fit-content and
|
||||
// -moz-available for intrinsic size in block axis. Therefore, we reset them
|
||||
// if needed.
|
||||
if (isInlineAxis) {
|
||||
ResetIfKeywords(styleBSize, styleMinBSize, styleMaxBSize);
|
||||
}
|
||||
|
||||
// If our BSize or min/max-BSize properties are set to values that we can
|
||||
// resolve and that will impose a constraint when transferred through our
|
||||
// aspect ratio (if we have one), then compute and apply that constraint.
|
||||
@ -4808,7 +4844,10 @@ nscoord nsLayoutUtils::IntrinsicForAxis(
|
||||
|
||||
nscoord bSizeTakenByBoxSizing = GetDefiniteSizeTakenByBoxSizing(
|
||||
boxSizing, aFrame, !isInlineAxis, ignorePadding, aPercentageBasis);
|
||||
contentEdgeToBoxSizing.emplace(GetContentEdgeToBoxSizing(boxSizing));
|
||||
if (!contentEdgeToBoxSizing) {
|
||||
contentEdgeToBoxSizing.emplace(GetContentEdgeToBoxSizing(boxSizing));
|
||||
}
|
||||
|
||||
// NOTE: This is only the minContentSize if we've been passed
|
||||
// MIN_INTRINSIC_ISIZE (which is fine, because this should only be used
|
||||
// inside a check for that flag).
|
||||
@ -4869,7 +4908,7 @@ nscoord nsLayoutUtils::IntrinsicForAxis(
|
||||
if (aFrame->IsTableFrame()) {
|
||||
// Tables can't shrink smaller than their intrinsic minimum inline size,
|
||||
// no matter what.
|
||||
const IntrinsicSizeInput input(aRenderingContext);
|
||||
const IntrinsicSizeInput input(aRenderingContext, Nothing());
|
||||
min = aFrame->GetMinISize(input);
|
||||
}
|
||||
|
||||
|
@ -249,7 +249,7 @@ LogicalSize nsTextControlFrame::CalcIntrinsicSize(gfxContext* aRenderingContext,
|
||||
// Add the inline size of the button if our char size is explicit, so as to
|
||||
// make sure to make enough space for it.
|
||||
if (maybeCols.isSome() && mButton && mButton->GetPrimaryFrame()) {
|
||||
const IntrinsicSizeInput input(aRenderingContext);
|
||||
const IntrinsicSizeInput input(aRenderingContext, Nothing());
|
||||
intrinsicSize.ISize(aWM) += mButton->GetPrimaryFrame()->GetMinISize(input);
|
||||
}
|
||||
|
||||
|
@ -199,8 +199,9 @@ nscoord ColumnSetWrapperFrame::MinISize(const IntrinsicSizeInput& aInput) {
|
||||
}
|
||||
} else {
|
||||
for (nsIFrame* f : PrincipalChildList()) {
|
||||
const IntrinsicSizeInput input(aInput.mContext);
|
||||
iSize = std::max(iSize, f->GetMinISize(input));
|
||||
const IntrinsicSizeInput childInput(aInput, f->GetWritingMode(),
|
||||
GetWritingMode());
|
||||
iSize = std::max(iSize, f->GetMinISize(childInput));
|
||||
}
|
||||
}
|
||||
|
||||
@ -236,8 +237,9 @@ nscoord ColumnSetWrapperFrame::PrefISize(const IntrinsicSizeInput& aInput) {
|
||||
iSize = ColumnUtils::IntrinsicISize(numColumns, colGap, colISize);
|
||||
} else {
|
||||
for (nsIFrame* f : PrincipalChildList()) {
|
||||
const IntrinsicSizeInput input(aInput.mContext);
|
||||
iSize = std::max(iSize, f->GetPrefISize(input));
|
||||
const IntrinsicSizeInput childInput(aInput, f->GetWritingMode(),
|
||||
GetWritingMode());
|
||||
iSize = std::max(iSize, f->GetPrefISize(childInput));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -871,8 +871,12 @@ nscoord nsBlockFrame::MinISize(const IntrinsicSizeInput& aInput) {
|
||||
#endif
|
||||
if (line->IsBlock()) {
|
||||
data.ForceBreak();
|
||||
nsIFrame* kid = line->mFirstChild;
|
||||
const IntrinsicSizeInput kidInput(aInput, kid->GetWritingMode(),
|
||||
GetWritingMode());
|
||||
data.mCurrentLine = nsLayoutUtils::IntrinsicForContainer(
|
||||
aInput.mContext, line->mFirstChild, IntrinsicISizeType::MinISize);
|
||||
kidInput.mContext, kid, IntrinsicISizeType::MinISize,
|
||||
kidInput.mPercentageBasis);
|
||||
data.ForceBreak();
|
||||
} else {
|
||||
if (!curFrame->GetPrevContinuation() && TextIndentAppliesTo(line)) {
|
||||
@ -883,7 +887,8 @@ nscoord nsBlockFrame::MinISize(const IntrinsicSizeInput& aInput) {
|
||||
nsIFrame* kid = line->mFirstChild;
|
||||
for (int32_t i = 0, i_end = line->GetChildCount(); i != i_end;
|
||||
++i, kid = kid->GetNextSibling()) {
|
||||
const IntrinsicSizeInput kidInput(aInput.mContext);
|
||||
const IntrinsicSizeInput kidInput(aInput, kid->GetWritingMode(),
|
||||
GetWritingMode());
|
||||
kid->AddInlineMinISize(kidInput, &data);
|
||||
if (whiteSpaceCanWrap && data.mTrailingWhitespace) {
|
||||
data.OptionallyBreak();
|
||||
@ -942,15 +947,19 @@ nscoord nsBlockFrame::PrefISize(const IntrinsicSizeInput& aInput) {
|
||||
AutoNoisyIndenter lineindent(gNoisyIntrinsic);
|
||||
#endif
|
||||
if (line->IsBlock()) {
|
||||
nsIFrame* kid = line->mFirstChild;
|
||||
StyleClear clearType;
|
||||
if (!data.mLineIsEmpty || BlockCanIntersectFloats(line->mFirstChild)) {
|
||||
if (!data.mLineIsEmpty || BlockCanIntersectFloats(kid)) {
|
||||
clearType = StyleClear::Both;
|
||||
} else {
|
||||
clearType = line->mFirstChild->StyleDisplay()->mClear;
|
||||
clearType = kid->StyleDisplay()->mClear;
|
||||
}
|
||||
data.ForceBreak(clearType);
|
||||
const IntrinsicSizeInput kidInput(aInput, kid->GetWritingMode(),
|
||||
GetWritingMode());
|
||||
data.mCurrentLine = nsLayoutUtils::IntrinsicForContainer(
|
||||
aInput.mContext, line->mFirstChild, IntrinsicISizeType::PrefISize);
|
||||
kidInput.mContext, kid, IntrinsicISizeType::PrefISize,
|
||||
kidInput.mPercentageBasis);
|
||||
data.ForceBreak();
|
||||
} else {
|
||||
if (!curFrame->GetPrevContinuation() && TextIndentAppliesTo(line)) {
|
||||
@ -966,7 +975,8 @@ nscoord nsBlockFrame::PrefISize(const IntrinsicSizeInput& aInput) {
|
||||
nsIFrame* kid = line->mFirstChild;
|
||||
for (int32_t i = 0, i_end = line->GetChildCount(); i != i_end;
|
||||
++i, kid = kid->GetNextSibling()) {
|
||||
const IntrinsicSizeInput kidInput(aInput.mContext);
|
||||
const IntrinsicSizeInput kidInput(aInput, kid->GetWritingMode(),
|
||||
GetWritingMode());
|
||||
kid->AddInlinePrefISize(kidInput, &data);
|
||||
}
|
||||
}
|
||||
@ -1024,7 +1034,12 @@ nsresult nsBlockFrame::GetPrefWidthTightBounds(gfxContext* aRenderingContext,
|
||||
data.mLine = &line;
|
||||
data.SetLineContainer(curFrame);
|
||||
nsIFrame* kid = line->mFirstChild;
|
||||
const IntrinsicSizeInput kidInput(aRenderingContext);
|
||||
// Per comment in nsIFrame::GetPrefWidthTightBounds(), the function is
|
||||
// only implemented for nsBlockFrame and nsTextFrame and is used to
|
||||
// determine the intrinsic inline sizes of MathML token elements. These
|
||||
// elements shouldn't have percentage block sizes that require a
|
||||
// percentage basis for resolution.
|
||||
const IntrinsicSizeInput kidInput(aRenderingContext, Nothing());
|
||||
for (int32_t i = 0, i_end = line->GetChildCount(); i != i_end;
|
||||
++i, kid = kid->GetNextSibling()) {
|
||||
rv = kid->GetPrefWidthTightBounds(aRenderingContext, &childX,
|
||||
|
@ -792,7 +792,8 @@ void nsContainerFrame::DoInlineMinISize(const IntrinsicSizeInput& aInput,
|
||||
InlineMinISizeData* aData) {
|
||||
auto handleChildren = [&](auto frame, auto data) {
|
||||
for (nsIFrame* kid : frame->mFrames) {
|
||||
const IntrinsicSizeInput kidInput(aInput.mContext);
|
||||
const IntrinsicSizeInput kidInput(aInput, kid->GetWritingMode(),
|
||||
GetWritingMode());
|
||||
kid->AddInlineMinISize(kidInput, data);
|
||||
}
|
||||
};
|
||||
@ -803,7 +804,8 @@ void nsContainerFrame::DoInlinePrefISize(const IntrinsicSizeInput& aInput,
|
||||
InlinePrefISizeData* aData) {
|
||||
auto handleChildren = [&](auto frame, auto data) {
|
||||
for (nsIFrame* kid : frame->mFrames) {
|
||||
const IntrinsicSizeInput kidInput(aInput.mContext);
|
||||
const IntrinsicSizeInput kidInput(aInput, kid->GetWritingMode(),
|
||||
GetWritingMode());
|
||||
kid->AddInlinePrefISize(kidInput, data);
|
||||
}
|
||||
};
|
||||
@ -835,7 +837,7 @@ LogicalSize nsContainerFrame::ComputeAutoSize(
|
||||
AutoMaybeDisableFontInflation an(this);
|
||||
|
||||
WritingMode tableWM = GetParent()->GetWritingMode();
|
||||
const IntrinsicSizeInput input(aRenderingContext);
|
||||
const IntrinsicSizeInput input(aRenderingContext, Nothing());
|
||||
if (aWM.IsOrthogonalTo(tableWM)) {
|
||||
// For an orthogonal caption on a block-dir side of the table, shrink-wrap
|
||||
// to min-isize.
|
||||
|
@ -6454,8 +6454,10 @@ nscoord nsFlexContainerFrame::ComputeIntrinsicISize(
|
||||
continue;
|
||||
}
|
||||
|
||||
const IntrinsicSizeInput childInput(aInput, childFrame->GetWritingMode(),
|
||||
GetWritingMode());
|
||||
nscoord childISize = nsLayoutUtils::IntrinsicForContainer(
|
||||
aInput.mContext, childFrame, aType);
|
||||
childInput.mContext, childFrame, aType, childInput.mPercentageBasis);
|
||||
|
||||
// * For a row-oriented single-line flex container, the intrinsic
|
||||
// {min/pref}-isize is the sum of its items' {min/pref}-isizes and
|
||||
|
@ -6016,7 +6016,8 @@ void nsIFrame::MarkSubtreeDirty() {
|
||||
void nsIFrame::AddInlineMinISize(const IntrinsicSizeInput& aInput,
|
||||
InlineMinISizeData* aData) {
|
||||
nscoord isize = nsLayoutUtils::IntrinsicForContainer(
|
||||
aInput.mContext, this, IntrinsicISizeType::MinISize);
|
||||
aInput.mContext, this, IntrinsicISizeType::MinISize,
|
||||
aInput.mPercentageBasis);
|
||||
aData->DefaultAddInlineMinISize(this, isize);
|
||||
}
|
||||
|
||||
@ -6024,7 +6025,8 @@ void nsIFrame::AddInlineMinISize(const IntrinsicSizeInput& aInput,
|
||||
void nsIFrame::AddInlinePrefISize(const IntrinsicSizeInput& aInput,
|
||||
nsIFrame::InlinePrefISizeData* aData) {
|
||||
nscoord isize = nsLayoutUtils::IntrinsicForContainer(
|
||||
aInput.mContext, this, IntrinsicISizeType::PrefISize);
|
||||
aInput.mContext, this, IntrinsicISizeType::PrefISize,
|
||||
aInput.mPercentageBasis);
|
||||
aData->DefaultAddInlinePrefISize(isize);
|
||||
}
|
||||
|
||||
@ -6515,7 +6517,7 @@ nsIFrame::SizeComputationResult nsIFrame::ComputeSize(
|
||||
result.ISize(aWM) = std::min(maxISize, result.ISize(aWM));
|
||||
}
|
||||
|
||||
const IntrinsicSizeInput input(aRenderingContext);
|
||||
const IntrinsicSizeInput input(aRenderingContext, Nothing());
|
||||
const auto& minISizeCoord = stylePos->MinISize(aWM);
|
||||
nscoord minISize;
|
||||
if (!minISizeCoord.IsAuto() && !shouldIgnoreMinMaxISize) {
|
||||
@ -6684,6 +6686,31 @@ nsIFrame::SizeComputationResult nsIFrame::ComputeSize(
|
||||
return {result, aspectRatioUsage};
|
||||
}
|
||||
|
||||
nscoord nsIFrame::ComputeBSizeValueAsPercentageBasis(
|
||||
const StyleSize& aStyleBSize, const StyleSize& aStyleMinBSize,
|
||||
const StyleMaxSize& aStyleMaxBSize, nscoord aCBBSize,
|
||||
nscoord aContentEdgeToBoxSizingBSize) {
|
||||
const nscoord bSize = nsLayoutUtils::IsAutoBSize(aStyleBSize, aCBBSize)
|
||||
? NS_UNCONSTRAINEDSIZE
|
||||
: nsLayoutUtils::ComputeBSizeValue(
|
||||
aCBBSize, aContentEdgeToBoxSizingBSize,
|
||||
aStyleBSize.AsLengthPercentage());
|
||||
|
||||
const nscoord minBSize = nsLayoutUtils::IsAutoBSize(aStyleMinBSize, aCBBSize)
|
||||
? 0
|
||||
: nsLayoutUtils::ComputeBSizeValue(
|
||||
aCBBSize, aContentEdgeToBoxSizingBSize,
|
||||
aStyleMinBSize.AsLengthPercentage());
|
||||
|
||||
const nscoord maxBSize = nsLayoutUtils::IsAutoBSize(aStyleMaxBSize, aCBBSize)
|
||||
? NS_UNCONSTRAINEDSIZE
|
||||
: nsLayoutUtils::ComputeBSizeValue(
|
||||
aCBBSize, aContentEdgeToBoxSizingBSize,
|
||||
aStyleMaxBSize.AsLengthPercentage());
|
||||
|
||||
return CSSMinMax(bSize, minBSize, maxBSize);
|
||||
}
|
||||
|
||||
nsRect nsIFrame::ComputeTightBounds(DrawTarget* aDrawTarget) const {
|
||||
return InkOverflowRect();
|
||||
}
|
||||
@ -6711,7 +6738,19 @@ LogicalSize nsIFrame::ComputeAutoSize(
|
||||
if (styleISize.IsAuto()) {
|
||||
nscoord availBased =
|
||||
aAvailableISize - aMargin.ISize(aWM) - aBorderPadding.ISize(aWM);
|
||||
const IntrinsicSizeInput input(aRenderingContext);
|
||||
const auto* stylePos = StylePosition();
|
||||
const auto& styleBSize = aSizeOverrides.mStyleBSize
|
||||
? *aSizeOverrides.mStyleBSize
|
||||
: stylePos->BSize(aWM);
|
||||
const LogicalSize contentEdgeToBoxSizing =
|
||||
stylePos->mBoxSizing == StyleBoxSizing::Border ? aBorderPadding
|
||||
: LogicalSize(aWM);
|
||||
const nscoord bSize = ComputeBSizeValueAsPercentageBasis(
|
||||
styleBSize, stylePos->MinBSize(aWM), stylePos->MaxBSize(aWM),
|
||||
aCBSize.BSize(aWM), contentEdgeToBoxSizing.BSize(aWM));
|
||||
const IntrinsicSizeInput input(
|
||||
aRenderingContext, Some(LogicalSize(aWM, NS_UNCONSTRAINEDSIZE, bSize)
|
||||
.ConvertTo(GetWritingMode(), aWM)));
|
||||
result.ISize(aWM) = ShrinkISizeToFit(input, availBased, aFlags);
|
||||
}
|
||||
return result;
|
||||
@ -6802,7 +6841,12 @@ nsIFrame::ISizeComputationResult nsIFrame::ComputeISizeValue(
|
||||
aAspectRatio));
|
||||
}();
|
||||
|
||||
const IntrinsicSizeInput input(aRenderingContext);
|
||||
const auto* stylePos = StylePosition();
|
||||
const nscoord bSize = ComputeBSizeValueAsPercentageBasis(
|
||||
aStyleBSize, stylePos->MinBSize(aWM), stylePos->MaxBSize(aWM),
|
||||
aCBSize.BSize(aWM), aContentEdgeToBoxSizing.BSize(aWM));
|
||||
const IntrinsicSizeInput input(
|
||||
aRenderingContext, Some(LogicalSize(aWM, NS_UNCONSTRAINEDSIZE, bSize)));
|
||||
nscoord result;
|
||||
switch (aSize) {
|
||||
case ExtremumLength::MaxContent:
|
||||
|
@ -422,9 +422,32 @@ struct FrameBidiData {
|
||||
struct MOZ_STACK_CLASS IntrinsicSizeInput final {
|
||||
gfxContext* const mContext;
|
||||
|
||||
explicit IntrinsicSizeInput(gfxContext* aContext) : mContext(aContext) {
|
||||
// The content-box size of a frame, served as a percentage basis when
|
||||
// computing the children's intrinsic contributions. If the basis is
|
||||
// indefinite in a given axis, use NS_UNCONSTRAINEDSIZE for that component.
|
||||
//
|
||||
// In most scenarios, this struct is used when computing the inline size
|
||||
// contribution, so the inline component of the percentage basis should be set
|
||||
// to NS_UNCONSTRAINEDSIZE.
|
||||
Maybe<LogicalSize> mPercentageBasis;
|
||||
|
||||
IntrinsicSizeInput(gfxContext* aContext,
|
||||
const Maybe<LogicalSize>& aPercentageBasis)
|
||||
: mContext(aContext), mPercentageBasis(aPercentageBasis) {
|
||||
MOZ_ASSERT(mContext);
|
||||
}
|
||||
|
||||
// Construct a new IntrinsicSizeInput by copying from aSource.
|
||||
//
|
||||
// This constructor converts mPercentageBasis' writing mode, if it exists. The
|
||||
// original mPercentageBasis in aSource is expected to be in the writing mode
|
||||
// aFromWM, and it will be converted to the writing mode aToWM.
|
||||
IntrinsicSizeInput(const IntrinsicSizeInput& aSource,
|
||||
mozilla::WritingMode aToWM, mozilla::WritingMode aFromWM)
|
||||
: IntrinsicSizeInput(aSource.mContext,
|
||||
aSource.mPercentageBasis.map([&](const auto& aPB) {
|
||||
return aPB.ConvertTo(aToWM, aFromWM);
|
||||
})) {}
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
@ -2872,6 +2895,12 @@ class nsIFrame : public nsQueryFrame {
|
||||
const mozilla::StyleSizeOverrides& aSizeOverrides,
|
||||
mozilla::ComputeSizeFlags aFlags);
|
||||
|
||||
static nscoord ComputeBSizeValueAsPercentageBasis(
|
||||
const mozilla::StyleSize& aStyleBSize,
|
||||
const mozilla::StyleSize& aStyleMinBSize,
|
||||
const mozilla::StyleMaxSize& aStyleMaxBSize, nscoord aCBBSize,
|
||||
nscoord aContentEdgeToBoxSizingBSize);
|
||||
|
||||
protected:
|
||||
/**
|
||||
* A helper, used by |nsIFrame::ComputeSize| (for frames that need to
|
||||
|
@ -2850,7 +2850,8 @@ static bool IsInAutoWidthTableCellForQuirk(nsIFrame* aFrame) {
|
||||
void nsImageFrame::AddInlineMinISize(const IntrinsicSizeInput& aInput,
|
||||
InlineMinISizeData* aData) {
|
||||
nscoord isize = nsLayoutUtils::IntrinsicForContainer(
|
||||
aInput.mContext, this, IntrinsicISizeType::MinISize);
|
||||
aInput.mContext, this, IntrinsicISizeType::MinISize,
|
||||
aInput.mPercentageBasis);
|
||||
bool canBreak = !IsInAutoWidthTableCellForQuirk(this);
|
||||
aData->DefaultAddInlineMinISize(this, isize, canBreak);
|
||||
}
|
||||
|
@ -75,8 +75,11 @@ void nsPlaceholderFrame::AddFloatToIntrinsicISizeData(
|
||||
const IntrinsicSizeInput& aInput, IntrinsicISizeType aType,
|
||||
InlineIntrinsicISizeData* aData) const {
|
||||
if (mOutOfFlowFrame->IsFloating()) {
|
||||
const IntrinsicSizeInput floatInput(
|
||||
aInput, mOutOfFlowFrame->GetWritingMode(), GetWritingMode());
|
||||
const nscoord floatISize = nsLayoutUtils::IntrinsicForContainer(
|
||||
aInput.mContext, mOutOfFlowFrame, aType);
|
||||
floatInput.mContext, mOutOfFlowFrame, aType,
|
||||
floatInput.mPercentageBasis);
|
||||
aData->mFloats.EmplaceBack(mOutOfFlowFrame, floatISize);
|
||||
}
|
||||
}
|
||||
|
@ -214,7 +214,7 @@ void nsRubyBaseContainerFrame::AddInlineMinISize(
|
||||
void nsRubyBaseContainerFrame::AddInlinePrefISize(
|
||||
const IntrinsicSizeInput& aInput, InlinePrefISizeData* aData) {
|
||||
AutoRubyTextContainerArray textContainers(this);
|
||||
const IntrinsicSizeInput input(aInput.mContext);
|
||||
const IntrinsicSizeInput input(aInput.mContext, Nothing());
|
||||
|
||||
nscoord sum = 0;
|
||||
for (nsIFrame* frame = this; frame; frame = frame->GetNextInFlow()) {
|
||||
|
@ -54,7 +54,9 @@ nsresult nsRubyFrame::GetFrameName(nsAString& aResult) const {
|
||||
void nsRubyFrame::AddInlineMinISize(const IntrinsicSizeInput& aInput,
|
||||
InlineMinISizeData* aData) {
|
||||
auto handleChildren = [&](auto frame, auto data) {
|
||||
const IntrinsicSizeInput input(aInput.mContext);
|
||||
// Ruby frames shouldn't have percentage block sizes that require a
|
||||
// percentage basis for resolution.
|
||||
const IntrinsicSizeInput input(aInput.mContext, Nothing());
|
||||
for (RubySegmentEnumerator e(static_cast<nsRubyFrame*>(frame)); !e.AtEnd();
|
||||
e.Next()) {
|
||||
e.GetBaseContainer()->AddInlineMinISize(input, data);
|
||||
@ -67,7 +69,9 @@ void nsRubyFrame::AddInlineMinISize(const IntrinsicSizeInput& aInput,
|
||||
void nsRubyFrame::AddInlinePrefISize(const IntrinsicSizeInput& aInput,
|
||||
InlinePrefISizeData* aData) {
|
||||
auto handleChildren = [&](auto frame, auto data) {
|
||||
const IntrinsicSizeInput input(aInput.mContext);
|
||||
// Ruby frames shouldn't have percentage block sizes that require a
|
||||
// percentage basis for resolution.
|
||||
const IntrinsicSizeInput input(aInput.mContext, Nothing());
|
||||
for (RubySegmentEnumerator e(static_cast<nsRubyFrame*>(frame)); !e.AtEnd();
|
||||
e.Next()) {
|
||||
e.GetBaseContainer()->AddInlinePrefISize(input, data);
|
||||
|
@ -5105,7 +5105,7 @@ void SVGTextFrame::DoReflow() {
|
||||
kid->MarkIntrinsicISizesDirty();
|
||||
}
|
||||
|
||||
const IntrinsicSizeInput input(renderingContext.get());
|
||||
const IntrinsicSizeInput input(renderingContext.get(), Nothing());
|
||||
nscoord inlineSize = kid->GetPrefISize(input);
|
||||
WritingMode wm = kid->GetWritingMode();
|
||||
ReflowInput reflowInput(presContext, kid, renderingContext.get(),
|
||||
|
@ -69,11 +69,14 @@ struct CellISizeInfo {
|
||||
float prefPercent;
|
||||
};
|
||||
|
||||
// Used for both column and cell calculations. The parts needed only
|
||||
// for cells are skipped when aIsCell is false.
|
||||
// A helper for ComputeColumnIntrinsicISizes(), used for both column and cell
|
||||
// intrinsic inline size calculations. The parts needed only for cells are
|
||||
// skipped when aIsCell is false.
|
||||
static CellISizeInfo GetISizeInfo(gfxContext* aRenderingContext,
|
||||
nsIFrame* aFrame, WritingMode aWM,
|
||||
bool aIsCell) {
|
||||
MOZ_ASSERT(aFrame->GetWritingMode() == aWM,
|
||||
"The caller is expected to pass aFrame's writing mode!");
|
||||
nscoord minCoord, prefCoord;
|
||||
const nsStylePosition* stylePos = aFrame->StylePosition();
|
||||
bool isQuirks =
|
||||
@ -84,7 +87,28 @@ static CellISizeInfo GetISizeInfo(gfxContext* aRenderingContext,
|
||||
// wrapping inside of it should not apply font size inflation.
|
||||
AutoMaybeDisableFontInflation an(aFrame);
|
||||
|
||||
const IntrinsicSizeInput input(aRenderingContext);
|
||||
// Resolve the cell's block size 'cellBSize' as a percentage basis, in case
|
||||
// it impacts its children's inline-size contributions (e.g. via percentage
|
||||
// block size + aspect-ratio). However, this behavior might not be
|
||||
// web-compatible (Bug 1461852).
|
||||
//
|
||||
// Note that if the cell *itself* has a percentage-based block size, we
|
||||
// treat it as unresolvable here by using an unconstrained cbBSize. It will
|
||||
// be resolved during the "special bsize reflow" pass if the table has a
|
||||
// specified block size. See nsTableFrame::Reflow() and
|
||||
// ReflowInput::Flags::mSpecialBSizeReflow.
|
||||
const nscoord cbBSize = NS_UNCONSTRAINEDSIZE;
|
||||
const nscoord contentEdgeToBoxSizingBSize =
|
||||
stylePos->mBoxSizing == StyleBoxSizing::Border
|
||||
? aFrame->IntrinsicBSizeOffsets().BorderPadding()
|
||||
: 0;
|
||||
const nscoord cellBSize = nsIFrame::ComputeBSizeValueAsPercentageBasis(
|
||||
stylePos->BSize(aWM), stylePos->MinBSize(aWM), stylePos->MaxBSize(aWM),
|
||||
cbBSize, contentEdgeToBoxSizingBSize);
|
||||
|
||||
const IntrinsicSizeInput input(
|
||||
aRenderingContext,
|
||||
Some(LogicalSize(aWM, NS_UNCONSTRAINEDSIZE, cellBSize)));
|
||||
minCoord = aFrame->GetMinISize(input);
|
||||
prefCoord = aFrame->GetPrefISize(input);
|
||||
// Until almost the end of this function, minCoord and prefCoord
|
||||
|
@ -598,9 +598,14 @@ ScrollContainerFrame* nsTableCellFrame::GetScrollTargetFrame() const {
|
||||
|
||||
nscoord nsTableCellFrame::IntrinsicISize(const IntrinsicSizeInput& aInput,
|
||||
IntrinsicISizeType aType) {
|
||||
return nsLayoutUtils::IntrinsicForContainer(aInput.mContext, Inner(), aType,
|
||||
Nothing(),
|
||||
nsLayoutUtils::IGNORE_PADDING);
|
||||
// Note: a table cell has the same writing mode as its table ancestor, which
|
||||
// may differ from its inner frame that derives its writing mode from the
|
||||
// style of the <td> element. See nsTableCellFrame::Init().
|
||||
const IntrinsicSizeInput innerInput(aInput, Inner()->GetWritingMode(),
|
||||
GetWritingMode());
|
||||
return nsLayoutUtils::IntrinsicForContainer(
|
||||
innerInput.mContext, Inner(), aType, innerInput.mPercentageBasis,
|
||||
nsLayoutUtils::IGNORE_PADDING);
|
||||
}
|
||||
|
||||
/* virtual */ nsIFrame::IntrinsicSizeOffsetData
|
||||
|
@ -1403,7 +1403,7 @@ nsIFrame::SizeComputationResult nsTableFrame::ComputeSize(
|
||||
AutoMaybeDisableFontInflation an(this);
|
||||
|
||||
// Tables never shrink below their min inline-size.
|
||||
const IntrinsicSizeInput input(aRenderingContext);
|
||||
const IntrinsicSizeInput input(aRenderingContext, Nothing());
|
||||
nscoord minISize = GetMinISize(input);
|
||||
if (minISize > result.mLogicalSize.ISize(aWM)) {
|
||||
result.mLogicalSize.ISize(aWM) = minISize;
|
||||
@ -1419,7 +1419,7 @@ nscoord nsTableFrame::TableShrinkISizeToFit(gfxContext* aRenderingContext,
|
||||
AutoMaybeDisableFontInflation an(this);
|
||||
|
||||
nscoord result;
|
||||
const IntrinsicSizeInput input(aRenderingContext);
|
||||
const IntrinsicSizeInput input(aRenderingContext, Nothing());
|
||||
nscoord minISize = GetMinISize(input);
|
||||
if (minISize > aISizeInCB) {
|
||||
result = minISize;
|
||||
|
@ -3,6 +3,3 @@
|
||||
if (os == "android") and fission: [OK, TIMEOUT]
|
||||
[#target height matches containing block height, and target parent width matches #target width after resize]
|
||||
expected: FAIL
|
||||
|
||||
[#target height matches containing block height, and target parent width matches #target width]
|
||||
expected: FAIL
|
||||
|
@ -0,0 +1,7 @@
|
||||
[grid-aspect-ratio-041.html]
|
||||
# Before bug 1909761, we pass this test by accident. To pass this test, we
|
||||
# need to resolve row size based on the grid container's definite height, and
|
||||
# use that row size to resolve "height: 100%" when computing the intrinsic
|
||||
# size of the middle div. Bug 1300366 might fix this.
|
||||
expected: FAIL
|
||||
bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1300366
|
@ -1,2 +0,0 @@
|
||||
[abs-pos-with-replaced-child.html]
|
||||
expected: FAIL
|
Loading…
x
Reference in New Issue
Block a user