Bug 1387152 part 2: Don't let unrelated property "flex-basis" influence the sizing inside of -webkit-box containers. r?mats
We use nsFlexContainerFrame (our modern flexbox implementation) to emulate
-webkit-box, and we use a frame state bit to tell us whether to use
modern-flexbox properties vs. legacy properties. Up until this patch, we
neglected to check that state bit when determining whether to use the modern
"flex-basis" property for sizing. This patch makes us *not* use that property
(and just use the axis-appropriate width/height property instead) for legacy
-webkit-box containers.
MozReview-Commit-ID: 14bzOCPCtUY
--- a/layout/generic/nsFrame.cpp
+++ b/layout/generic/nsFrame.cpp
@@ -5092,16 +5092,17 @@ nsFrame::ComputeSize(gfxContext*
!(tableWrapper->GetStateBits() & NS_FRAME_OUT_OF_FLOW));
if (isGridItem) {
// When resolving justify/align-self below, we want to use the grid
// container's justify/align-items value and WritingMode.
alignCB = grandParent;
}
}
bool isFlexItem = parentFrame && parentFrame->IsFlexContainerFrame() &&
+ !parentFrame->HasAnyStateBits(NS_STATE_FLEX_IS_LEGACY_WEBKIT_BOX) &&
!HasAnyStateBits(NS_FRAME_OUT_OF_FLOW);
bool isInlineFlexItem = false;
if (isFlexItem) {
// Flex items use their "flex-basis" property in place of their main-size
// property (e.g. "width") for sizing purposes, *unless* they have
// "flex-basis:auto", in which case they use their main-size property after
// all.
uint32_t flexDirection = GetParent()->StylePosition()->mFlexDirection;
@@ -5322,16 +5323,17 @@ nsFrame::ComputeSizeWithIntrinsicDimensi
{
const nsStylePosition* stylePos = StylePosition();
const nsStyleCoord* inlineStyleCoord = &stylePos->ISize(aWM);
const nsStyleCoord* blockStyleCoord = &stylePos->BSize(aWM);
auto* parentFrame = GetParent();
const bool isGridItem = parentFrame && parentFrame->IsGridContainerFrame() &&
!HasAnyStateBits(NS_FRAME_OUT_OF_FLOW);
const bool isFlexItem = parentFrame && parentFrame->IsFlexContainerFrame() &&
+ !parentFrame->HasAnyStateBits(NS_STATE_FLEX_IS_LEGACY_WEBKIT_BOX) &&
!HasAnyStateBits(NS_FRAME_OUT_OF_FLOW);
bool isInlineFlexItem = false;
Maybe<nsStyleCoord> imposedMainSizeStyleCoord;
// If this is a flex item, and we're measuring its cross size after flexing
// to resolve its main size, then we need to use the resolved main size
// that the container provides to us *instead of* the main-size coordinate
// from our style struct. (Otherwise, we'll be using an irrelevant value in
--- a/layout/reftests/webkit-box/reftest.list
+++ b/layout/reftests/webkit-box/reftest.list
@@ -39,8 +39,13 @@ fails-if(!styloVsGecko) == webkit-box-an
# on the "0" value being rejected.
fails-if(!styloVsGecko) == webkit-box-ordinal-group-2.html webkit-box-ordinal-group-2-ref.html
== webkit-box-ordinal-group-3.html webkit-box-ordinal-group-3-ref.html
# Tests for "-webkit-box-pack" (main-axis alignment):
== webkit-box-pack-horiz-1a.html webkit-box-pack-horiz-1-ref.html
== webkit-box-pack-horiz-1b.html webkit-box-pack-horiz-1-ref.html
== webkit-box-pack-vert-1.html webkit-box-pack-vert-1-ref.html
+
+# Tests for "display: -webkit-box" container mixed with modern flex properties
+# (which shouldn't influence behavior of -webkit-box)
+== webkit-box-with-modern-css-1.html webkit-box-with-modern-css-1-ref.html
+== webkit-box-with-modern-css-2.html webkit-box-with-modern-css-2-ref.html
new file mode 100644
--- /dev/null
+++ b/layout/reftests/webkit-box/webkit-box-with-modern-css-1-ref.html
@@ -0,0 +1,53 @@
+<!DOCTYPE html>
+<!--
+ Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<html>
+<head>
+ <title>
+ CSS Reference
+ </title>
+ <style>
+ .box {
+ display: flex;
+ border: 1px solid black;
+ margin: 5px 20px;
+ width: 100px;
+ float: left; /* For testing in "rows" */
+ font: 10px serif;
+ }
+
+ .box > *:nth-child(1) { background: turquoise; }
+ .box > *:nth-child(2) { background: salmon; }
+
+ br { clear: both; }
+ </style>
+</head>
+<body>
+ <!-- FIRST ROW -->
+ <div class="box">
+ <div>a</div>
+ <div>b</div>
+ </div>
+
+ <div class="box">
+ <div>a</div>
+ <div>b</div>
+ </div>
+
+ <br>
+
+ <!-- SECOND ROW -->
+ <div class="box">
+ <div>a</div>
+ <div>b</div>
+ </div>
+
+ <div class="box">
+ <div>a</div>
+ <div>b</div>
+ </div>
+
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/webkit-box/webkit-box-with-modern-css-1.html
@@ -0,0 +1,71 @@
+<!DOCTYPE html>
+<!--
+ Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<html>
+<head>
+ <title>
+ CSS Test: "flex-basis" and "flex" shouldn't impact child sizing inside of
+ horizontal "display: -webkit-box" container
+ </title>
+ <style>
+ .box {
+ display: -webkit-box;
+ border: 1px solid black;
+ margin: 5px 20px;
+ width: 100px;
+ float: left; /* For testing in "rows" */
+ font: 10px serif;
+ }
+
+ .box > *:nth-child(1) { background: turquoise; }
+ .box > *:nth-child(2) { background: salmon; }
+
+ .mw0 {
+ /* Used in some children here, to disable modern-flexbox's
+ "implied-minimum-size" feature, so that it can't inadvertantly
+ be the thing that makes our rendering match the reference . */
+ min-width: 0;
+ }
+
+ br { clear: both; }
+
+ /* The point of this testcase is to verify that none of the modern-flexbox
+ styles below have any effect on the rendering. (This is worth checking
+ because we coopt our modern-flexbox implementation in our emulation of
+ legacy -webkit-box behavior.) */
+ .fb0 { flex-basis: 0; }
+ .f1 { flex: 1; /* This shorthand sets flex-grow:1; flex-basis: 0 */ }
+
+ .fb30px { flex-basis: 30px; }
+ .f1_30px { flex: 1 30px; }
+ </style>
+</head>
+<body>
+ <!-- FIRST ROW: flex-basis is 0 -->
+ <div class="box">
+ <div class="fb0">a</div>
+ <div class="fb0 mw0">b</div>
+ </div>
+
+ <div class="box">
+ <div class="f1">a</div>
+ <div class="f1 mw0">b</div>
+ </div>
+
+ <br>
+
+ <!-- SECOND ROW: flex-basis is 30px -->
+ <div class="box">
+ <div class="fb30px">a</div>
+ <div class="fb30px mw0">b</div>
+ </div>
+
+ <div class="box">
+ <div class="f1_30px">a</div>
+ <div class="f1_30px mw0">b</div>
+ </div>
+
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/webkit-box/webkit-box-with-modern-css-2-ref.html
@@ -0,0 +1,54 @@
+<!DOCTYPE html>
+<!--
+ Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<html>
+<head>
+ <title>
+ CSS Reference
+ </title>
+ <style>
+ .box {
+ display: flex;
+ flex-direction: column;
+ border: 1px solid black;
+ margin: 5px 20px;
+ height: 100px;
+ float: left; /* For testing in "rows" */
+ font: 10px serif;
+ }
+
+ .box > *:nth-child(1) { background: turquoise; }
+ .box > *:nth-child(2) { background: salmon; }
+
+ br { clear: both; }
+ </style>
+</head>
+<body>
+ <!-- FIRST ROW -->
+ <div class="box">
+ <div>a</div>
+ <div>b</div>
+ </div>
+
+ <div class="box">
+ <div>a</div>
+ <div>b</div>
+ </div>
+
+ <br>
+
+ <!-- SECOND ROW -->
+ <div class="box">
+ <div>a</div>
+ <div>b</div>
+ </div>
+
+ <div class="box">
+ <div>a</div>
+ <div>b</div>
+ </div>
+
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/webkit-box/webkit-box-with-modern-css-2.html
@@ -0,0 +1,72 @@
+<!DOCTYPE html>
+<!--
+ Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<html>
+<head>
+ <title>
+ CSS Test: "flex-basis" and "flex" shouldn't impact child sizing inside of
+ vertical "display: -webkit-box" container
+ </title>
+ <style>
+ .box {
+ display: -webkit-box;
+ -webkit-box-orient: vertical;
+ border: 1px solid black;
+ margin: 5px 20px;
+ height: 100px;
+ float: left; /* For testing in "rows" */
+ font: 10px serif;
+ }
+
+ .box > *:nth-child(1) { background: turquoise; }
+ .box > *:nth-child(2) { background: salmon; }
+
+ .mh0 {
+ /* Used in some children here, to disable modern-flexbox's
+ "implied-minimum-size" feature, so that it can't inadvertantly
+ be the thing that makes our rendering match the reference . */
+ min-height: 0;
+ }
+
+ br { clear: both; }
+
+ /* The point of this testcase is to verify that none of the modern-flexbox
+ styles below have any effect on the rendering. (This is worth checking
+ because we coopt our modern-flexbox implementation in our emulation of
+ legacy -webkit-box behavior.) */
+ .fb0 { flex-basis: 0; }
+ .f1 { flex: 1; /* This shorthand sets flex-grow:1; flex-basis: 0 */ }
+
+ .fb30px { flex-basis: 30px; }
+ .f1_30px { flex: 1 30px; }
+ </style>
+</head>
+<body>
+ <!-- FIRST ROW: flex-basis is 0 -->
+ <div class="box">
+ <div class="fb0">a</div>
+ <div class="fb0 mh0">b</div>
+ </div>
+
+ <div class="box">
+ <div class="f1">a</div>
+ <div class="f1 mh0">b</div>
+ </div>
+
+ <br>
+
+ <!-- SECOND ROW: flex-basis is 30px -->
+ <div class="box">
+ <div class="fb30px">a</div>
+ <div class="fb30px mh0">b</div>
+ </div>
+
+ <div class="box">
+ <div class="f1_30px">a</div>
+ <div class="f1_30px mh0">b</div>
+ </div>
+
+</body>
+</html>