Bug 1387152 part 2: Don't let unrelated property "flex-basis" influence the sizing inside of -webkit-box containers. r=mats
authorDaniel Holbert <dholbert@cs.stanford.edu>
Thu, 03 Aug 2017 11:18:13 -0700
changeset 378335 d5110841090cc545500ce537d021d1d8230798c0
parent 378334 929f225ca7206f4647f9e44c3f4c6aaf62ea661f
child 378336 c54db40f50d7b28208b79fdc6907bcc220f9c13d
push id32428
push userarchaeopteryx@coole-files.de
push dateSat, 02 Sep 2017 08:52:28 +0000
treeherdermozilla-central@b01a7e57425b [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmats
bugs1387152
milestone57.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
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
layout/generic/nsFrame.cpp
layout/reftests/webkit-box/reftest.list
layout/reftests/webkit-box/webkit-box-with-modern-css-1-ref.html
layout/reftests/webkit-box/webkit-box-with-modern-css-1.html
layout/reftests/webkit-box/webkit-box-with-modern-css-2-ref.html
layout/reftests/webkit-box/webkit-box-with-modern-css-2.html
--- a/layout/generic/nsFrame.cpp
+++ b/layout/generic/nsFrame.cpp
@@ -5087,16 +5087,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;
@@ -5317,16 +5318,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>