зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1760658 - Part 1: Apply automatic content-based minimum on flex container. r=emilio
Basides, factor out the utility function to AspectRatio so everyone can use it. Differential Revision: https://phabricator.services.mozilla.com/D144891
This commit is contained in:
Родитель
c5077a5261
Коммит
035220bf4c
|
@ -760,6 +760,13 @@ void ReflowInput::InitDynamicReflowRoot() {
|
|||
}
|
||||
}
|
||||
|
||||
bool ReflowInput::ShouldApplyAutomaticMinimumOnBlockAxis() const {
|
||||
MOZ_ASSERT(!mFrame->IsFrameOfType(nsIFrame::eReplacedSizing));
|
||||
return mFlags.mIsBSizeSetByAspectRatio &&
|
||||
!mStyleDisplay->IsScrollableOverflow() &&
|
||||
mStylePosition->MinBSize(GetWritingMode()).IsAuto();
|
||||
}
|
||||
|
||||
/* static */
|
||||
LogicalMargin ReflowInput::ComputeRelativeOffsets(WritingMode aWM,
|
||||
nsIFrame* aFrame,
|
||||
|
|
|
@ -842,6 +842,15 @@ struct ReflowInput : public SizeComputationInput {
|
|||
return mDiscoveredClearance && *mDiscoveredClearance;
|
||||
}
|
||||
|
||||
// Returns true if we should apply automatic minimum on the block axis.
|
||||
//
|
||||
// The automatic minimum size in the ratio-dependent axis of a box with a
|
||||
// preferred aspect ratio that is neither a replaced element nor a scroll
|
||||
// container is its min-content size clamped from above by its maximum size.
|
||||
//
|
||||
// https://drafts.csswg.org/css-sizing-4/#aspect-ratio-minimum
|
||||
bool ShouldApplyAutomaticMinimumOnBlockAxis() const;
|
||||
|
||||
// Compute the offsets for a relative position element
|
||||
//
|
||||
// @param aWM the writing mode of aCBSize and the returned offsets.
|
||||
|
|
|
@ -1836,19 +1836,6 @@ static nscoord ApplyLineClamp(const ReflowInput& aReflowInput,
|
|||
return edge;
|
||||
}
|
||||
|
||||
static bool ShouldApplyAutomaticMinimumOnBlockAxis(
|
||||
WritingMode aWM, const nsStyleDisplay* aDisplay,
|
||||
const nsStylePosition* aPosition) {
|
||||
// The automatic minimum size in the ratio-dependent axis of a box with a
|
||||
// preferred aspect ratio that is neither a replaced element nor a scroll
|
||||
// container is its min-content size clamped from above by its maximum size.
|
||||
//
|
||||
// https://drafts.csswg.org/css-sizing-4/#aspect-ratio-minimum
|
||||
// Note: we only need to check scroll container because replaced element
|
||||
// doesn't go into nsBlockFrame::Reflow().
|
||||
return !aDisplay->IsScrollableOverflow() && aPosition->MinBSize(aWM).IsAuto();
|
||||
}
|
||||
|
||||
void nsBlockFrame::ComputeFinalSize(const ReflowInput& aReflowInput,
|
||||
BlockReflowState& aState,
|
||||
ReflowOutput& aMetrics,
|
||||
|
@ -1930,9 +1917,7 @@ void nsBlockFrame::ComputeFinalSize(const ReflowInput& aReflowInput,
|
|||
// If the content block-size is larger than the effective computed
|
||||
// block-size, we extend the block-size to contain all the content.
|
||||
// https://drafts.csswg.org/css-sizing-4/#aspect-ratio-minimum
|
||||
if (aReflowInput.mFlags.mIsBSizeSetByAspectRatio &&
|
||||
ShouldApplyAutomaticMinimumOnBlockAxis(wm, aReflowInput.mStyleDisplay,
|
||||
aReflowInput.mStylePosition)) {
|
||||
if (aReflowInput.ShouldApplyAutomaticMinimumOnBlockAxis()) {
|
||||
// Note: finalSize.BSize(wm) is the border-box size, so we compare it with
|
||||
// the content's block-size plus our border and padding..
|
||||
finalSize.BSize(wm) =
|
||||
|
|
|
@ -4305,7 +4305,10 @@ nscoord nsFlexContainerFrame::ComputeMainSize(
|
|||
return aTentativeContentBoxMainSize;
|
||||
}
|
||||
|
||||
if (aTentativeContentBoxMainSize != NS_UNCONSTRAINEDSIZE) {
|
||||
const bool shouldApplyAutomaticMinimumOnBlockAxis =
|
||||
aReflowInput.ShouldApplyAutomaticMinimumOnBlockAxis();
|
||||
if (aTentativeContentBoxMainSize != NS_UNCONSTRAINEDSIZE &&
|
||||
!shouldApplyAutomaticMinimumOnBlockAxis) {
|
||||
// Column-oriented case, with fixed BSize:
|
||||
// Just use our fixed block-size because we always assume the available
|
||||
// block-size is unconstrained, and the reflow input has already done the
|
||||
|
@ -4319,13 +4322,24 @@ nscoord nsFlexContainerFrame::ComputeMainSize(
|
|||
return aReflowInput.ComputedMinBSize();
|
||||
}
|
||||
|
||||
const AuCoord64 largestLineMainSize = GetLargestLineMainSize(aLines);
|
||||
const nscoord contentBSize = NS_CSS_MINMAX(
|
||||
nscoord(largestLineMainSize.ToMinMaxClamped()),
|
||||
aReflowInput.ComputedMinBSize(), aReflowInput.ComputedMaxBSize());
|
||||
// If the clamped largest FlexLine length is larger than the tentative main
|
||||
// size (which is resolved by aspect-ratio), we extend it to contain the
|
||||
// entire FlexLine.
|
||||
// https://drafts.csswg.org/css-sizing-4/#aspect-ratio-minimum
|
||||
if (shouldApplyAutomaticMinimumOnBlockAxis) {
|
||||
// Column-oriented case, with auto BSize which is resolved by
|
||||
// aspect-ratio.
|
||||
return std::max(contentBSize, aTentativeContentBoxMainSize);
|
||||
}
|
||||
|
||||
// Column-oriented case, with auto BSize:
|
||||
// Resolve auto BSize to the largest FlexLine length, clamped to our
|
||||
// computed min/max main-size properties.
|
||||
const AuCoord64 largestLineMainSize = GetLargestLineMainSize(aLines);
|
||||
return NS_CSS_MINMAX(nscoord(largestLineMainSize.ToMinMaxClamped()),
|
||||
aReflowInput.ComputedMinBSize(),
|
||||
aReflowInput.ComputedMaxBSize());
|
||||
return contentBSize;
|
||||
}
|
||||
|
||||
nscoord nsFlexContainerFrame::ComputeCrossSize(
|
||||
|
@ -4349,8 +4363,11 @@ nscoord nsFlexContainerFrame::ComputeCrossSize(
|
|||
return aTentativeContentBoxCrossSize;
|
||||
}
|
||||
|
||||
const bool shouldApplyAutomaticMinimumOnBlockAxis =
|
||||
aReflowInput.ShouldApplyAutomaticMinimumOnBlockAxis();
|
||||
const nscoord computedBSize = aReflowInput.ComputedBSize();
|
||||
if (computedBSize != NS_UNCONSTRAINEDSIZE) {
|
||||
if (computedBSize != NS_UNCONSTRAINEDSIZE &&
|
||||
!shouldApplyAutomaticMinimumOnBlockAxis) {
|
||||
// Row-oriented case (cross axis is block-axis), with fixed BSize:
|
||||
*aIsDefinite = true;
|
||||
|
||||
|
@ -4367,12 +4384,25 @@ nscoord nsFlexContainerFrame::ComputeCrossSize(
|
|||
return aReflowInput.ComputedMinBSize();
|
||||
}
|
||||
|
||||
// The cross size must not be definite in the following cases.
|
||||
*aIsDefinite = false;
|
||||
|
||||
const nscoord contentBSize =
|
||||
NS_CSS_MINMAX(aSumLineCrossSizes, aReflowInput.ComputedMinBSize(),
|
||||
aReflowInput.ComputedMaxBSize());
|
||||
// If the content block-size is larger than the effective computed
|
||||
// block-size, we extend the block-size to contain all the content.
|
||||
// https://drafts.csswg.org/css-sizing-4/#aspect-ratio-minimum
|
||||
if (shouldApplyAutomaticMinimumOnBlockAxis) {
|
||||
// Row-oriented case (cross axis is block-axis), with auto BSize which is
|
||||
// resolved by aspect-ratio or content size.
|
||||
return std::max(contentBSize, computedBSize);
|
||||
}
|
||||
|
||||
// Row-oriented case (cross axis is block axis), with auto BSize:
|
||||
// Shrink-wrap our line(s), subject to our min-size / max-size
|
||||
// constraints in that (block) axis.
|
||||
*aIsDefinite = false;
|
||||
return NS_CSS_MINMAX(aSumLineCrossSizes, aReflowInput.ComputedMinBSize(),
|
||||
aReflowInput.ComputedMaxBSize());
|
||||
return contentBSize;
|
||||
}
|
||||
|
||||
LogicalSize nsFlexContainerFrame::ComputeAvailableSizeForItems(
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
<!DOCTYPE html>
|
||||
<title>CSS aspect-ratio: Test flex container's cross size (block axis) honoring automatic content-based minimum</title>
|
||||
<link rel="author" title="Mozilla" href="https://www.mozilla.org/">
|
||||
<link rel="help" href="https://drafts.csswg.org/css-sizing-4/#aspect-ratio-minimum">
|
||||
<link rel="match" href="../../reference/ref-filled-green-100px-square.xht" />
|
||||
|
||||
<style>
|
||||
#container {
|
||||
display: flex;
|
||||
width: 100px;
|
||||
aspect-ratio: 2 / 1;
|
||||
background: green;
|
||||
}
|
||||
#item {
|
||||
width: 100%;
|
||||
height: 100px;
|
||||
}
|
||||
</style>
|
||||
<body>
|
||||
<p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
|
||||
<div id="container">
|
||||
<div id="item"></div>
|
||||
</div>
|
||||
</body>
|
|
@ -0,0 +1,26 @@
|
|||
<!DOCTYPE html>
|
||||
<title>CSS aspect-ratio: Test flex container's main size (block axis) honoring automatic content-based minimum</title>
|
||||
<link rel="author" title="Mozilla" href="https://www.mozilla.org/">
|
||||
<link rel="help" href="https://drafts.csswg.org/css-sizing-4/#aspect-ratio-minimum">
|
||||
<link rel="match" href="../../reference/ref-filled-green-100px-square.xht" />
|
||||
|
||||
<style>
|
||||
#container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
background: green;
|
||||
width: 100px;
|
||||
aspect-ratio: 2 / 1;
|
||||
}
|
||||
#item {
|
||||
width: 100%;
|
||||
height: 100px;
|
||||
flex: none
|
||||
}
|
||||
</style>
|
||||
<body>
|
||||
<p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
|
||||
<div id="container">
|
||||
<div id="item"></div>
|
||||
</div>
|
||||
</body>
|
Загрузка…
Ссылка в новой задаче