Bug 1585485 Part 3 - Use zero percentage basis to compute specified size suggestion for compressible flex items. r=dholbert

Also, add test for various types of <input> in row flex
containers (flex-item-compressible-001.html) and in column flex
containers (flex-item-compressible-002.html).

Note: Google Chrome 89 and Safari 14 fail the subtests that have a
definite value inside a calc expression in
flex-item-compressible-001.html. They also fail the entire
flex-item-compressible-002.html because they don't support <input> in
vertical writing-mode (i.e. <input> is still horizontal in vertical
writing mode).

Differential Revision: https://phabricator.services.mozilla.com/D99952
This commit is contained in:
Ting-Yu Lin 2020-12-18 18:59:47 +00:00
Родитель 378bde9842
Коммит 23425662c0
3 изменённых файлов: 316 добавлений и 5 удалений

Просмотреть файл

@ -1501,15 +1501,26 @@ static nscoord PartiallyResolveAutoMinSize(
const auto itemWM = aFlexItem.GetWritingMode();
const auto cbWM = aAxisTracker.GetWritingMode();
const auto cbSize =
aItemReflowInput.mContainingBlockSize.ConvertTo(cbWM, itemWM);
const auto& mainStyleSize =
aItemReflowInput.mStylePosition->Size(aAxisTracker.MainAxis(), cbWM);
const auto& maxMainStyleSize =
aItemReflowInput.mStylePosition->MaxSize(aAxisTracker.MainAxis(), cbWM);
const auto boxSizingAdjust =
aItemReflowInput.mStylePosition->mBoxSizing == StyleBoxSizing::Border
? aFlexItem.BorderPadding().Size(cbWM)
: LogicalSize(cbWM);
// If this flex item is a compressible replaced element list in CSS Sizing 3
// §5.2.2, CSS Sizing 3 §5.2.1c requires us to resolve the percentage part of
// the preferred main size property against zero, yielding a definite
// specified size suggestion. Here we can use a zero percentage basis to
// fulfill this requirement.
const auto percentBasis =
aFlexItem.Frame()->IsPercentageResolvedAgainstZero(mainStyleSize,
maxMainStyleSize)
? LogicalSize(cbWM, 0, 0)
: aItemReflowInput.mContainingBlockSize.ConvertTo(cbWM, itemWM);
// Compute the specified size suggestion, which is the main-size property if
// it's definite.
nscoord specifiedSizeSuggestion = nscoord_MAX;
@ -1520,16 +1531,16 @@ static nscoord PartiallyResolveAutoMinSize(
// responsible for computing the min-content inline-size and min()'ing it
// with the value we return.
specifiedSizeSuggestion = aFlexItem.Frame()->ComputeISizeValue(
cbSize.ISize(cbWM), boxSizingAdjust.ISize(cbWM),
percentBasis.ISize(cbWM), boxSizingAdjust.ISize(cbWM),
mainStyleSize.AsLengthPercentage());
}
} else {
if (!nsLayoutUtils::IsAutoBSize(mainStyleSize, cbSize.BSize(cbWM))) {
if (!nsLayoutUtils::IsAutoBSize(mainStyleSize, percentBasis.BSize(cbWM))) {
// 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(
cbSize.BSize(cbWM), boxSizingAdjust.BSize(cbWM),
percentBasis.BSize(cbWM), boxSizingAdjust.BSize(cbWM),
mainStyleSize.AsLengthPercentage());
}
}

Просмотреть файл

@ -0,0 +1,149 @@
<!DOCTYPE html>
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<html>
<meta charset="utf-8">
<title>CSS Flexbox Test: Testing automatic minimun size of &lt;input&gt; flex items in a row flex container</title>
<link rel="author" title="Ting-Yu Lin" href="mailto:tlin@mozilla.com">
<link rel="author" title="Mozilla" href="https://www.mozilla.org/">
<link rel="help" href="https://drafts.csswg.org/css-flexbox-1/#min-size-auto">
<link rel="help" href="https://drafts.csswg.org/css-sizing-3/#replaced-percentage-min-contribution">
<link rel="help" href="https://drafts.csswg.org/css-sizing-3/#min-content-zero">
<link rel="stylesheet" href="/fonts/ahem.css">
<meta name="assert" content="This test verifies that an <input> flex item should resolve its percentage part of main size to zero when computing specified size suggestion.">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/check-layout-th.js"></script>
<style>
.flexbox {
display: flex;
width: 300px;
height: 40px;
border: 1px solid black;
margin-bottom: 5px;
}
.spacer {
/* Just to occupy some space, so that the flex algorithm will try to shrink
the <input> element below its percentage specified width. */
flex: 0 0 200px;
background: lightgray;
}
input {
font: 20px/1 Ahem;
background: lightblue;
/* Get rid of native theming and UA default styles. */
appearance: none;
border: 0;
padding: 0;
margin: 0;
}
.test1 {
width: 100%;
}
.test2 {
width: calc(100%);
}
.test3 {
width: calc(140px + 100%);
}
</style>
<body onload="checkLayout('.flexbox')">
<p>Test1: "width: 100%"</p>
<div class="flexbox">
<div class="spacer"></div>
<input type="text"
class="test1" data-expected-width="100">
</div>
<div class="flexbox">
<div class="spacer"></div>
<input type="range"
class="test1" data-expected-width="100">
</div>
<div class="flexbox">
<div class="spacer"></div>
<input type="button" value="XXXXXXX"
class="test1" data-expected-width="140">
</div>
<div class="flexbox">
<div class="spacer"></div>
<input type="submit" value="XXXXXXX"
class="test1" data-expected-width="140">
</div>
<div class="flexbox">
<div class="spacer"></div>
<input type="reset" value="XXXXXXX"
class="test1" data-expected-width="140">
</div>
<p>Test2: "width: calc(100%)"</p>
<div class="flexbox">
<div class="spacer"></div>
<input type="text"
class="test2" data-expected-width="100">
</div>
<div class="flexbox">
<div class="spacer"></div>
<input type="range"
class="test2" data-expected-width="100">
</div>
<div class="flexbox">
<div class="spacer"></div>
<input type="button" value="XXXXXXX"
class="test2" data-expected-width="140">
</div>
<div class="flexbox">
<div class="spacer"></div>
<input type="submit" value="XXXXXXX"
class="test2" data-expected-width="140">
</div>
<div class="flexbox">
<div class="spacer"></div>
<input type="reset" value="XXXXXXX"
class="test2" data-expected-width="140">
</div>
<p>Test3: "width: calc(140px + 100%)"</p>
<div class="flexbox">
<div class="spacer"></div>
<input type="text"
class="test3" data-expected-width="140">
</div>
<div class="flexbox">
<div class="spacer"></div>
<input type="range"
class="test3" data-expected-width="140">
</div>
<div class="flexbox">
<div class="spacer"></div>
<input type="button" value="XXXXXXX"
class="test3" data-expected-width="140">
</div>
<div class="flexbox">
<div class="spacer"></div>
<input type="submit" value="XXXXXXX"
class="test3" data-expected-width="140">
</div>
<div class="flexbox">
<div class="spacer"></div>
<input type="reset" value="XXXXXXX"
class="test3" data-expected-width="140">
</div>
</body>
</html>

Просмотреть файл

@ -0,0 +1,151 @@
<!DOCTYPE html>
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<html>
<meta charset="utf-8">
<title>CSS Flexbox Test: Testing automatic minimun size of &lt;input&gt; flex items in a column flex container</title>
<link rel="author" title="Ting-Yu Lin" href="mailto:tlin@mozilla.com">
<link rel="author" title="Mozilla" href="https://www.mozilla.org/">
<link rel="help" href="https://drafts.csswg.org/css-flexbox-1/#min-size-auto">
<link rel="help" href="https://drafts.csswg.org/css-sizing-3/#replaced-percentage-min-contribution">
<link rel="help" href="https://drafts.csswg.org/css-sizing-3/#min-content-zero">
<link rel="stylesheet" href="/fonts/ahem.css">
<meta name="assert" content="This test verifies that an <input> flex item should resolve its percentage part of main size to zero when computing specified size suggestion.">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/check-layout-th.js"></script>
<style>
.flexbox {
display: inline-flex;
flex-direction: column;
width: 40px;
height: 300px;
border: 1px solid black;
margin-bottom: 40px;
}
.spacer {
/* Just to occupy some space, so that the flex algorithm will try to shrink
the <input> element below its percentage specified height. */
flex: 0 0 200px;
background: lightgray;
}
input {
writing-mode: vertical-lr;
font: 20px/1 Ahem;
background: lightblue;
/* Get rid of native theming and UA default styles. */
appearance: none;
border: 0;
padding: 0;
margin: 0;
}
.test1 {
height: 100%;
}
.test2 {
height: calc(100%);
}
.test3 {
height: calc(140px + 100%);
}
</style>
<body onload="checkLayout('.flexbox')">
<p>Test1: "height: 100%"</p>
<div class="flexbox">
<div class="spacer"></div>
<input type="text"
class="test1" data-expected-height="100">
</div>
<div class="flexbox">
<div class="spacer"></div>
<input type="range"
class="test1" data-expected-height="100">
</div>
<div class="flexbox">
<div class="spacer"></div>
<input type="button" value="XXXXXXX"
class="test1" data-expected-height="140">
</div>
<div class="flexbox">
<div class="spacer"></div>
<input type="submit" value="XXXXXXX"
class="test1" data-expected-height="140">
</div>
<div class="flexbox">
<div class="spacer"></div>
<input type="reset" value="XXXXXXX"
class="test1" data-expected-height="140">
</div>
<p>Test2: "height: calc(100%)"</p>
<div class="flexbox">
<div class="spacer"></div>
<input type="text"
class="test2" data-expected-height="100">
</div>
<div class="flexbox">
<div class="spacer"></div>
<input type="range"
class="test2" data-expected-height="100">
</div>
<div class="flexbox">
<div class="spacer"></div>
<input type="button" value="XXXXXXX"
class="test2" data-expected-height="140">
</div>
<div class="flexbox">
<div class="spacer"></div>
<input type="submit" value="XXXXXXX"
class="test2" data-expected-height="140">
</div>
<div class="flexbox">
<div class="spacer"></div>
<input type="reset" value="XXXXXXX"
class="test2" data-expected-height="140">
</div>
<p>Test3: "height: calc(140px + 100%)"</p>
<div class="flexbox">
<div class="spacer"></div>
<input type="text"
class="test3" data-expected-height="140">
</div>
<div class="flexbox">
<div class="spacer"></div>
<input type="range"
class="test3" data-expected-height="140">
</div>
<div class="flexbox">
<div class="spacer"></div>
<input type="button" value="XXXXXXX"
class="test3" data-expected-height="140">
</div>
<div class="flexbox">
<div class="spacer"></div>
<input type="submit" value="XXXXXXX"
class="test3" data-expected-height="140">
</div>
<div class="flexbox">
<div class="spacer"></div>
<input type="reset" value="XXXXXXX"
class="test3" data-expected-height="140">
</div>
</body>
</html>