Bug 1933408 part 1: Implement layout support for 'stretch' as a block-axis size (with '-webkit-fill-available' as an alias). r=TYLin
Note that both keywords are disabled in the CSS parser for now, behind these about:config prefs: layout.css.stretch-size-keyword.enabled layout.css.webkit-fill-available.enabled Prior to this patch, we handled both keywords as pure aliases for '-moz-available' (which has the correct 'stretch' behavior in the inline axis but which just behaves like the initial value in the block axis). This patch changes that so that 'stretch' and '-webkit-fill-available' will now actually do the right thing in the block axis (if they're enabled at all, via their aforementioned about:config prefs). The relevant spec text here is: https://drafts.csswg.org/css-sizing-4/#valdef-width-stretch https://drafts.csswg.org/css-sizing-4/#stretch-fit-sizing Differential Revision: https://phabricator.services.mozilla.com/D217688
This commit is contained in:
@@ -1575,6 +1575,25 @@ class nsLayoutUtils {
|
||||
return std::max(0, result - aContentEdgeToBoxSizingBoxEdge);
|
||||
}
|
||||
|
||||
// Wrapper for ComputeBSizeValue that also handles 'stretch':
|
||||
template <typename SizeOrMaxSize>
|
||||
static nscoord ComputeBSizeValueHandlingStretch(
|
||||
nscoord aContainingBlockBSize, nscoord aMargin, nscoord aBorderPadding,
|
||||
nscoord aContentEdgeToBoxSizingBoxEdge, const SizeOrMaxSize& aSize) {
|
||||
if (aSize.BehavesLikeStretchOnBlockAxis()) {
|
||||
// Note: we don't need to worry about accounting for "box-sizing" when
|
||||
// resolving 'stretch' here. This function unconditionally returns a
|
||||
// content-box size, and the content-box size of a stretched element is
|
||||
// the same regardless of whether whether the author is conceptually
|
||||
// asking us to stretch the content box vs. the border-box.
|
||||
return ComputeStretchContentBoxBSize(aContainingBlockBSize, aMargin,
|
||||
aBorderPadding);
|
||||
}
|
||||
return ComputeBSizeValue(aContainingBlockBSize,
|
||||
aContentEdgeToBoxSizingBoxEdge,
|
||||
aSize.AsLengthPercentage());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the size that an element's box should take on, in order for its
|
||||
* margin-box to exactly reach a particular larger size (e.g. to fill its
|
||||
@@ -1650,20 +1669,21 @@ class nsLayoutUtils {
|
||||
}
|
||||
|
||||
/**
|
||||
* The "extremum length" values (see ExtremumLength) were originally aimed at
|
||||
* The "extremum length" values (see ExtremumLength) that return true from
|
||||
* 'BehavesLikeInitialValueOnBlockAxis()' were originally aimed at
|
||||
* inline-size (or width, as it was before logicalization). For now, we return
|
||||
* true for those here, so that we don't call ComputeBSizeValue with value
|
||||
* types that it doesn't understand. (See bug 1113216.)
|
||||
*
|
||||
* FIXME (bug 567039, bug 527285)
|
||||
* This isn't correct for the 'fill' value or for the 'min-*' or 'max-*'
|
||||
* properties, which need to be handled differently by the callers of
|
||||
* IsAutoBSize().
|
||||
*/
|
||||
template <typename SizeOrMaxSize>
|
||||
static bool IsAutoBSize(const SizeOrMaxSize& aCoord, nscoord aCBBSize) {
|
||||
// Note: percentages and 'stretch' both behave like 'auto' in the block
|
||||
// axis *if and only if* they're resolved against an unconstrained
|
||||
// block-size (on their containing block). That's what the second half of
|
||||
// this condition is handling.
|
||||
return aCoord.BehavesLikeInitialValueOnBlockAxis() ||
|
||||
(aCBBSize == nscoord_MAX && aCoord.HasPercent());
|
||||
(aCBBSize == nscoord_MAX &&
|
||||
(aCoord.HasPercent() || aCoord.BehavesLikeStretchOnBlockAxis()));
|
||||
}
|
||||
|
||||
static bool IsPaddingZero(const LengthPercentage& aLength) {
|
||||
|
||||
@@ -285,6 +285,20 @@ nscoord SizeComputationInput::ComputeISizeValue(
|
||||
.mISize;
|
||||
}
|
||||
|
||||
template <typename SizeOrMaxSize>
|
||||
nscoord SizeComputationInput::ComputeBSizeValueHandlingStretch(
|
||||
nscoord aContainingBlockBSize, StyleBoxSizing aBoxSizing,
|
||||
const SizeOrMaxSize& aSize) const {
|
||||
if (aSize.BehavesLikeStretchOnBlockAxis()) {
|
||||
WritingMode wm = GetWritingMode();
|
||||
return nsLayoutUtils::ComputeStretchContentBoxBSize(
|
||||
aContainingBlockBSize, ComputedLogicalMargin(wm).Size(wm).BSize(wm),
|
||||
ComputedLogicalBorderPadding(wm).Size(wm).BSize(wm));
|
||||
}
|
||||
return ComputeBSizeValue(aContainingBlockBSize, aBoxSizing,
|
||||
aSize.AsLengthPercentage());
|
||||
}
|
||||
|
||||
nscoord SizeComputationInput::ComputeBSizeValue(
|
||||
nscoord aContainingBlockBSize, StyleBoxSizing aBoxSizing,
|
||||
const LengthPercentage& aSize) const {
|
||||
@@ -1489,7 +1503,9 @@ void ReflowInput::CalculateHypotheticalPosition(
|
||||
|
||||
nscoord boxBSize;
|
||||
const auto& styleBSize = mStylePosition->BSize(wm);
|
||||
if (styleBSize.BehavesLikeInitialValueOnBlockAxis()) {
|
||||
const bool isAutoBSize =
|
||||
nsLayoutUtils::IsAutoBSize(styleBSize, blockContentSize.BSize(wm));
|
||||
if (isAutoBSize) {
|
||||
if (mFlags.mIsReplaced && intrinsicSize) {
|
||||
// It's a replaced element with an 'auto' block size so the box
|
||||
// block size is its intrinsic size plus any border/padding/margin
|
||||
@@ -1501,6 +1517,16 @@ void ReflowInput::CalculateHypotheticalPosition(
|
||||
// positioned frame?)
|
||||
boxBSize = 0;
|
||||
}
|
||||
} else if (styleBSize.BehavesLikeStretchOnBlockAxis()) {
|
||||
MOZ_ASSERT(blockContentSize.BSize(wm) != NS_UNCONSTRAINEDSIZE,
|
||||
"If we're 'stretch' with unconstrained size, isAutoBSize "
|
||||
"should be true which should make us skip this code");
|
||||
// TODO(dholbert) The 'insideBoxSizing' and 'outsideBoxSizing' usages
|
||||
// here aren't quite right, because we're supposed to be passing margin
|
||||
// and borderPadding specifically. The arithmetic seems to work out in
|
||||
// testcases though.
|
||||
boxBSize = nsLayoutUtils::ComputeStretchContentBoxBSize(
|
||||
blockContentSize.BSize(wm), outsideBoxSizing, insideBoxSizing);
|
||||
} else {
|
||||
// We need to compute it. It's important we do this, because if it's
|
||||
// percentage-based this computed value may be different from the
|
||||
@@ -3013,9 +3039,8 @@ void ReflowInput::ComputeMinMaxValues(const LogicalSize& aCBSize) {
|
||||
if (BSizeBehavesAsInitialValue(minBSize)) {
|
||||
SetComputedMinBSize(0);
|
||||
} else {
|
||||
SetComputedMinBSize(ComputeBSizeValue(bPercentageBasis,
|
||||
mStylePosition->mBoxSizing,
|
||||
minBSize.AsLengthPercentage()));
|
||||
SetComputedMinBSize(ComputeBSizeValueHandlingStretch(
|
||||
bPercentageBasis, mStylePosition->mBoxSizing, minBSize));
|
||||
}
|
||||
|
||||
if (mIsThemed) {
|
||||
@@ -3026,9 +3051,8 @@ void ReflowInput::ComputeMinMaxValues(const LogicalSize& aCBSize) {
|
||||
// Specified value of 'none'
|
||||
SetComputedMaxBSize(NS_UNCONSTRAINEDSIZE);
|
||||
} else {
|
||||
SetComputedMaxBSize(ComputeBSizeValue(bPercentageBasis,
|
||||
mStylePosition->mBoxSizing,
|
||||
maxBSize.AsLengthPercentage()));
|
||||
SetComputedMaxBSize(ComputeBSizeValueHandlingStretch(
|
||||
bPercentageBasis, mStylePosition->mBoxSizing, maxBSize));
|
||||
}
|
||||
|
||||
// If the computed value of 'min-height' is greater than the value of
|
||||
|
||||
@@ -169,7 +169,7 @@ struct SizeComputationInput {
|
||||
const Maybe<LogicalMargin>& aPadding,
|
||||
const nsStyleDisplay* aDisplay = nullptr);
|
||||
|
||||
/*
|
||||
/**
|
||||
* Convert StyleSize or StyleMaxSize to nscoord when percentages depend on the
|
||||
* inline size of the containing block, and enumerated values are for inline
|
||||
* size, min-inline-size, or max-inline-size. Does not handle auto inline
|
||||
@@ -180,6 +180,20 @@ struct SizeComputationInput {
|
||||
StyleBoxSizing aBoxSizing,
|
||||
const SizeOrMaxSize&) const;
|
||||
|
||||
/**
|
||||
* Wrapper for SizeComputationInput::ComputeBSizeValue (defined below, which
|
||||
* itself is a wrapper for nsLayoutUtils::ComputeBSizeValue). This one just
|
||||
* handles 'stretch' sizes first.
|
||||
*/
|
||||
template <typename SizeOrMaxSize>
|
||||
inline nscoord ComputeBSizeValueHandlingStretch(
|
||||
nscoord aContainingBlockBSize, StyleBoxSizing aBoxSizing,
|
||||
const SizeOrMaxSize& aSize) const;
|
||||
|
||||
/**
|
||||
* Wrapper for nsLayoutUtils::ComputeBSizeValue, which automatically figures
|
||||
* out the value to pass for its aContentEdgeToBoxSizingBoxEdge param.
|
||||
*/
|
||||
nscoord ComputeBSizeValue(nscoord aContainingBlockBSize,
|
||||
StyleBoxSizing aBoxSizing,
|
||||
const LengthPercentage& aCoord) const;
|
||||
|
||||
@@ -4029,17 +4029,20 @@ void nsBlockFrame::MoveChildFramesOfLine(nsLineBox* aLine,
|
||||
}
|
||||
|
||||
static inline bool IsNonAutoNonZeroBSize(const StyleSize& aCoord) {
|
||||
// The "extremum length" values (see ExtremumLength) were originally aimed at
|
||||
// The "extremum length" values (see ExtremumLength) that return true from
|
||||
// 'BehavesLikeInitialValueOnBlockAxis()' were originally aimed at
|
||||
// inline-size (or width, as it was before logicalization). For now, let them
|
||||
// return false here, so we treat them like 'auto' pending a real
|
||||
// implementation. (See bug 1126420.)
|
||||
//
|
||||
// FIXME (bug 567039, bug 527285) This isn't correct for the 'fill' value,
|
||||
// which should more likely (but not necessarily, depending on the available
|
||||
// space) be returning true.
|
||||
if (aCoord.BehavesLikeInitialValueOnBlockAxis()) {
|
||||
return false;
|
||||
}
|
||||
if (aCoord.BehavesLikeStretchOnBlockAxis()) {
|
||||
// We return true for "stretch" because it's essentially equivalent to
|
||||
// "100%" for the purposes of this function (and this function returns true
|
||||
// for nonzero percentage values, in the final return statement below).
|
||||
return true;
|
||||
}
|
||||
MOZ_ASSERT(aCoord.IsLengthPercentage());
|
||||
// If we evaluate the length/percent/calc at a percentage basis of
|
||||
// both nscoord_MAX and 0, and it's zero both ways, then it's a zero
|
||||
|
||||
@@ -2207,6 +2207,9 @@ LogicalSize nsContainerFrame::ComputeSizeWithIntrinsicDimensions(
|
||||
const auto& styleISize = aSizeOverrides.mStyleISize
|
||||
? *aSizeOverrides.mStyleISize
|
||||
: stylePos->ISize(aWM);
|
||||
|
||||
// TODO(dholbert): if styleBSize is 'stretch' here, we should probably
|
||||
// resolve it like we do in nsIFrame::ComputeSize. See bug 1937275.
|
||||
const auto& styleBSize = aSizeOverrides.mStyleBSize
|
||||
? *aSizeOverrides.mStyleBSize
|
||||
: stylePos->BSize(aWM);
|
||||
@@ -2340,9 +2343,9 @@ LogicalSize nsContainerFrame::ComputeSizeWithIntrinsicDimensions(
|
||||
}
|
||||
|
||||
if (!isAutoBSize) {
|
||||
bSize = nsLayoutUtils::ComputeBSizeValue(aCBSize.BSize(aWM),
|
||||
boxSizingAdjust.BSize(aWM),
|
||||
styleBSize.AsLengthPercentage());
|
||||
bSize = nsLayoutUtils::ComputeBSizeValueHandlingStretch(
|
||||
aCBSize.BSize(aWM), aMargin.BSize(aWM), aBorderPadding.BSize(aWM),
|
||||
boxSizingAdjust.BSize(aWM), styleBSize);
|
||||
} else if (MOZ_UNLIKELY(isGridItem) &&
|
||||
!parentFrame->IsMasonry(isOrthogonal ? LogicalAxis::Inline
|
||||
: LogicalAxis::Block)) {
|
||||
@@ -2377,9 +2380,9 @@ LogicalSize nsContainerFrame::ComputeSizeWithIntrinsicDimensions(
|
||||
const auto& maxBSizeCoord = stylePos->MaxBSize(aWM);
|
||||
if (!nsLayoutUtils::IsAutoBSize(maxBSizeCoord, aCBSize.BSize(aWM)) &&
|
||||
!isFlexItemBlockAxisMainAxis) {
|
||||
maxBSize = nsLayoutUtils::ComputeBSizeValue(
|
||||
aCBSize.BSize(aWM), boxSizingAdjust.BSize(aWM),
|
||||
maxBSizeCoord.AsLengthPercentage());
|
||||
maxBSize = nsLayoutUtils::ComputeBSizeValueHandlingStretch(
|
||||
aCBSize.BSize(aWM), aMargin.BSize(aWM), aBorderPadding.BSize(aWM),
|
||||
boxSizingAdjust.BSize(aWM), maxBSizeCoord);
|
||||
} else {
|
||||
maxBSize = nscoord_MAX;
|
||||
}
|
||||
@@ -2387,9 +2390,9 @@ LogicalSize nsContainerFrame::ComputeSizeWithIntrinsicDimensions(
|
||||
const auto& minBSizeCoord = stylePos->MinBSize(aWM);
|
||||
if (!nsLayoutUtils::IsAutoBSize(minBSizeCoord, aCBSize.BSize(aWM)) &&
|
||||
!isFlexItemBlockAxisMainAxis) {
|
||||
minBSize = nsLayoutUtils::ComputeBSizeValue(
|
||||
aCBSize.BSize(aWM), boxSizingAdjust.BSize(aWM),
|
||||
minBSizeCoord.AsLengthPercentage());
|
||||
minBSize = nsLayoutUtils::ComputeBSizeValueHandlingStretch(
|
||||
aCBSize.BSize(aWM), aMargin.BSize(aWM), aBorderPadding.BSize(aWM),
|
||||
boxSizingAdjust.BSize(aWM), minBSizeCoord);
|
||||
} else {
|
||||
minBSize = 0;
|
||||
}
|
||||
|
||||
@@ -1606,6 +1606,10 @@ nscoord nsFlexContainerFrame::PartiallyResolveAutoMinSize(
|
||||
nscoord specifiedSizeSuggestion = nscoord_MAX;
|
||||
|
||||
if (aAxisTracker.IsRowOriented()) {
|
||||
// TODO(dholbert): We need to handle 'stretch' (and its prefixed aliases)
|
||||
// here; that's tracked in bug 1936942. (Note that we do handle 'stretch'
|
||||
// in our column-oriented "else" clause below, via the call to
|
||||
// ComputeBSizeValueHandlingStretch.)
|
||||
if (mainStyleSize.IsLengthPercentage()) {
|
||||
// NOTE: We ignore extremum inline-size. This is OK because the caller is
|
||||
// responsible for computing the min-content inline-size and min()'ing it
|
||||
@@ -1615,14 +1619,16 @@ nscoord nsFlexContainerFrame::PartiallyResolveAutoMinSize(
|
||||
mainStyleSize.AsLengthPercentage());
|
||||
}
|
||||
} else {
|
||||
// NOTE: We ignore specified block-sizes that behave as 'auto', as
|
||||
// identified by IsAutoBSize(); that's OK because the caller is responsible
|
||||
// for computing the content-based block-size and and min()'ing it with the
|
||||
// value we return.
|
||||
const auto percentageBasisBSize = PercentageBasisForItem().BSize(cbWM);
|
||||
if (!nsLayoutUtils::IsAutoBSize(mainStyleSize, percentageBasisBSize)) {
|
||||
// NOTE: We ignore auto and extremum block-size. This is OK because the
|
||||
// caller is responsible for computing the min-content block-size and
|
||||
// min()'ing it with the value we return.
|
||||
specifiedSizeSuggestion = nsLayoutUtils::ComputeBSizeValue(
|
||||
percentageBasisBSize, boxSizingAdjust.BSize(cbWM),
|
||||
mainStyleSize.AsLengthPercentage());
|
||||
specifiedSizeSuggestion = nsLayoutUtils::ComputeBSizeValueHandlingStretch(
|
||||
percentageBasisBSize, aFlexItem.MarginSizeInMainAxis(),
|
||||
aFlexItem.BorderPaddingSizeInMainAxis(), boxSizingAdjust.BSize(cbWM),
|
||||
mainStyleSize);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2340,6 +2346,15 @@ bool FlexItem::IsMinSizeAutoResolutionNeeded() const {
|
||||
const auto& mainMinSize =
|
||||
Frame()->StylePosition()->MinSize(MainAxis(), ContainingBlockWM());
|
||||
|
||||
// "min-{height,width}:stretch" never produces an automatic minimum size. You
|
||||
// might think it would result in an automatic min-size if the containing
|
||||
// block size is indefinite, but "stretch" is instead treated as 0px in that
|
||||
// case rather than auto. This WPT requires this behavior:
|
||||
// https://wpt.live/css/css-sizing/stretch/indefinite-4.html More details &
|
||||
// discussion here: https://github.com/w3c/csswg-drafts/issues/11006
|
||||
if (mainMinSize.BehavesLikeStretchOnBlockAxis()) {
|
||||
return false;
|
||||
}
|
||||
return IsAutoOrEnumOnBSize(mainMinSize, IsInlineAxisMainAxis()) &&
|
||||
!Frame()->StyleDisplay()->IsScrollableOverflow();
|
||||
}
|
||||
|
||||
@@ -6394,15 +6394,30 @@ nsIFrame::SizeComputationResult nsIFrame::ComputeSize(
|
||||
aBorderPadding.ISize(aWM) -
|
||||
boxSizingAdjust.ISize(aWM);
|
||||
|
||||
const auto& styleISize = aSizeOverrides.mStyleISize
|
||||
? *aSizeOverrides.mStyleISize
|
||||
: stylePos->ISize(aWM);
|
||||
const auto& styleBSize = aSizeOverrides.mStyleBSize
|
||||
? *aSizeOverrides.mStyleBSize
|
||||
: stylePos->BSize(aWM);
|
||||
const auto& aspectRatio = aSizeOverrides.mAspectRatio
|
||||
? *aSizeOverrides.mAspectRatio
|
||||
: GetAspectRatio();
|
||||
const auto& styleISize = aSizeOverrides.mStyleISize
|
||||
? *aSizeOverrides.mStyleISize
|
||||
: stylePos->ISize(aWM);
|
||||
// For bsize, we consider overrides *and then* we resolve 'stretch' to a
|
||||
// nscoord value, for convenience (so that we can assume that either
|
||||
// isAutoBSize is true, or styleBSize is of type LengthPercentage()).
|
||||
const auto& styleBSize = [&] {
|
||||
const auto& styleBSizeConsideringOverrides =
|
||||
(aSizeOverrides.mStyleBSize) ? *aSizeOverrides.mStyleBSize
|
||||
: stylePos->BSize(aWM);
|
||||
if (styleBSizeConsideringOverrides.BehavesLikeStretchOnBlockAxis() &&
|
||||
aCBSize.BSize(aWM) != NS_UNCONSTRAINEDSIZE) {
|
||||
// We've got a 'stretch' BSize; resolve it to a length:
|
||||
nscoord stretchBSize = nsLayoutUtils::ComputeStretchBSize(
|
||||
aCBSize.BSize(aWM), aMargin.BSize(aWM), aBorderPadding.BSize(aWM),
|
||||
stylePos->mBoxSizing);
|
||||
return StyleSize::LengthPercentage(
|
||||
LengthPercentage::FromAppUnits(stretchBSize));
|
||||
}
|
||||
return styleBSizeConsideringOverrides;
|
||||
}();
|
||||
|
||||
auto parentFrame = GetParent();
|
||||
auto alignCB = parentFrame;
|
||||
@@ -6439,6 +6454,11 @@ nsIFrame::SizeComputationResult nsIFrame::ComputeSize(
|
||||
const bool isAutoBSize =
|
||||
nsLayoutUtils::IsAutoBSize(styleBSize, aCBSize.BSize(aWM));
|
||||
|
||||
MOZ_ASSERT(isAutoBSize || styleBSize.IsLengthPercentage(),
|
||||
"We should have resolved away any non-'auto'-like flavors "
|
||||
"of styleBSize into a LengthPercentage. (If this fails, we "
|
||||
"might run afoul of some AsLengthPercentage() call below.)");
|
||||
|
||||
// Compute inline-axis size
|
||||
const bool isSubgriddedInInlineAxis =
|
||||
isSubgrid && static_cast<nsGridContainerFrame*>(this)->IsColSubgrid();
|
||||
@@ -6722,16 +6742,16 @@ nsIFrame::SizeComputationResult nsIFrame::ComputeSize(
|
||||
const bool shouldIgnoreMinMaxBSize =
|
||||
isFlexItemBlockAxisMainAxis || isSubgriddedInBlockAxis;
|
||||
if (!isAutoMaxBSize && !shouldIgnoreMinMaxBSize) {
|
||||
nscoord maxBSize = nsLayoutUtils::ComputeBSizeValue(
|
||||
aCBSize.BSize(aWM), boxSizingAdjust.BSize(aWM),
|
||||
maxBSizeCoord.AsLengthPercentage());
|
||||
nscoord maxBSize = nsLayoutUtils::ComputeBSizeValueHandlingStretch(
|
||||
aCBSize.BSize(aWM), aMargin.BSize(aWM), aBorderPadding.BSize(aWM),
|
||||
boxSizingAdjust.BSize(aWM), maxBSizeCoord);
|
||||
result.BSize(aWM) = std::min(maxBSize, result.BSize(aWM));
|
||||
}
|
||||
|
||||
if (!isAutoMinBSize && !shouldIgnoreMinMaxBSize) {
|
||||
nscoord minBSize = nsLayoutUtils::ComputeBSizeValue(
|
||||
aCBSize.BSize(aWM), boxSizingAdjust.BSize(aWM),
|
||||
minBSizeCoord.AsLengthPercentage());
|
||||
nscoord minBSize = nsLayoutUtils::ComputeBSizeValueHandlingStretch(
|
||||
aCBSize.BSize(aWM), aMargin.BSize(aWM), aBorderPadding.BSize(aWM),
|
||||
boxSizingAdjust.BSize(aWM), minBSizeCoord);
|
||||
result.BSize(aWM) = std::max(minBSize, result.BSize(aWM));
|
||||
}
|
||||
}
|
||||
@@ -6770,20 +6790,32 @@ nscoord nsIFrame::ComputeBSizeValueAsPercentageBasis(
|
||||
return NS_UNCONSTRAINEDSIZE;
|
||||
}
|
||||
|
||||
const nscoord bSize = nsLayoutUtils::ComputeBSizeValue(
|
||||
aCBBSize, aContentEdgeToBoxSizingBSize, aStyleBSize.AsLengthPercentage());
|
||||
// TODO(dholbert): This is a temporary hack, to be fixed up in bug 1933604.
|
||||
// We don't know have aMargin or aBorderPadding args available,
|
||||
// so we use these dummy zero-valued variables as placeholders in
|
||||
// our call to ComputeBSizeValueHandlingStretch. (This might mean we
|
||||
// end up resolving 'stretch' to something slighlty-too-large for the
|
||||
// purposes of this call, if there's actually nonzero margin/border/padding).
|
||||
const nscoord dummyMargin = 0;
|
||||
const nscoord dummyBorderPadding = 0;
|
||||
|
||||
const nscoord minBSize = nsLayoutUtils::IsAutoBSize(aStyleMinBSize, aCBBSize)
|
||||
const nscoord bSize = nsLayoutUtils::ComputeBSizeValueHandlingStretch(
|
||||
aCBBSize, dummyMargin, dummyBorderPadding, aContentEdgeToBoxSizingBSize,
|
||||
aStyleBSize);
|
||||
|
||||
const nscoord minBSize =
|
||||
nsLayoutUtils::IsAutoBSize(aStyleMinBSize, aCBBSize)
|
||||
? 0
|
||||
: nsLayoutUtils::ComputeBSizeValue(
|
||||
aCBBSize, aContentEdgeToBoxSizingBSize,
|
||||
aStyleMinBSize.AsLengthPercentage());
|
||||
: nsLayoutUtils::ComputeBSizeValueHandlingStretch(
|
||||
aCBBSize, dummyMargin, dummyBorderPadding,
|
||||
aContentEdgeToBoxSizingBSize, aStyleMinBSize);
|
||||
|
||||
const nscoord maxBSize = nsLayoutUtils::IsAutoBSize(aStyleMaxBSize, aCBBSize)
|
||||
const nscoord maxBSize =
|
||||
nsLayoutUtils::IsAutoBSize(aStyleMaxBSize, aCBBSize)
|
||||
? NS_UNCONSTRAINEDSIZE
|
||||
: nsLayoutUtils::ComputeBSizeValue(
|
||||
aCBBSize, aContentEdgeToBoxSizingBSize,
|
||||
aStyleMaxBSize.AsLengthPercentage());
|
||||
: nsLayoutUtils::ComputeBSizeValueHandlingStretch(
|
||||
aCBBSize, dummyMargin, dummyBorderPadding,
|
||||
aContentEdgeToBoxSizingBSize, aStyleMaxBSize);
|
||||
|
||||
return CSSMinMax(bSize, minBSize, maxBSize);
|
||||
}
|
||||
|
||||
@@ -843,8 +843,14 @@ inline bool StyleFlexBasis::IsAuto() const {
|
||||
return IsStretch() || IsMozAvailable() || IsWebkitFillAvailable(); \
|
||||
} \
|
||||
template <> \
|
||||
inline bool ty_::BehavesLikeStretchOnBlockAxis() const { \
|
||||
/* TODO(dholbert): Add "|| IsMozAvailable()" in bug 527285. */ \
|
||||
return IsStretch() || IsWebkitFillAvailable(); \
|
||||
} \
|
||||
template <> \
|
||||
inline bool ty_::BehavesLikeInitialValueOnBlockAxis() const { \
|
||||
return isInitialValMethod_() || !IsLengthPercentage(); \
|
||||
return isInitialValMethod_() || \
|
||||
(!BehavesLikeStretchOnBlockAxis() && !IsLengthPercentage()); \
|
||||
}
|
||||
|
||||
IMPL_BEHAVES_LIKE_SIZE_METHODS(StyleSize, IsAuto)
|
||||
|
||||
@@ -921,8 +921,10 @@ struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStylePosition {
|
||||
|
||||
template <typename SizeOrMaxSize>
|
||||
static bool BSizeCoordDependsOnContainer(const SizeOrMaxSize& aCoord) {
|
||||
return aCoord.IsLengthPercentage() &&
|
||||
aCoord.AsLengthPercentage().HasPercent();
|
||||
if (aCoord.IsLengthPercentage()) {
|
||||
return aCoord.AsLengthPercentage().HasPercent();
|
||||
}
|
||||
return aCoord.BehavesLikeStretchOnBlockAxis();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -80,12 +80,14 @@ var gSwapInitialWhenHaveFrame = {
|
||||
|
||||
// For the block axis ('height' by default): when there's a frame, these
|
||||
// keywords work out to the same as the initial value, i.e. `auto`, given
|
||||
// the prerequisites of only 'display: block'.
|
||||
// the prerequisites of only 'display: block'. (Notably, 'stretch' and
|
||||
// its '-webkit-fill-available' alias *do not behave like auto* in the
|
||||
// block axis, so they're not listed among the keywords here.)
|
||||
"height": [ "-moz-max-content", "-moz-min-content", "-moz-fit-content",
|
||||
"-moz-available", "-webkit-fill-available",
|
||||
"-moz-available", // TODO(dholbert): remove in bug 527285.
|
||||
"max-content", "min-content", "fit-content",
|
||||
"fit-content(100px)", "fit-content(10%)",
|
||||
"fit-content(calc(3*25px + 50%))", "stretch" ],
|
||||
"fit-content(calc(3*25px + 50%))" ],
|
||||
};
|
||||
// Use the same lists for logical versions of width/height properties:
|
||||
gSwapInitialWhenHaveFrame["inline-size"] = gSwapInitialWhenHaveFrame.width;
|
||||
|
||||
@@ -500,6 +500,7 @@ renaming_overrides_prefixing = true
|
||||
inline bool HasPercent() const;
|
||||
inline bool HasLengthAndPercentage() const;
|
||||
inline bool BehavesLikeStretchOnInlineAxis() const;
|
||||
inline bool BehavesLikeStretchOnBlockAxis() const;
|
||||
inline bool BehavesLikeInitialValueOnBlockAxis() const;
|
||||
inline bool BehavesLikeInitialValue(LogicalAxis) const;
|
||||
"""
|
||||
@@ -516,6 +517,7 @@ renaming_overrides_prefixing = true
|
||||
inline bool HasPercent() const;
|
||||
inline bool HasLengthAndPercentage() const;
|
||||
inline bool BehavesLikeStretchOnInlineAxis() const;
|
||||
inline bool BehavesLikeStretchOnBlockAxis() const;
|
||||
inline bool BehavesLikeInitialValueOnBlockAxis() const;
|
||||
inline bool BehavesLikeInitialValue(LogicalAxis) const;
|
||||
"""
|
||||
|
||||
Reference in New Issue
Block a user