Bug 1387152 part 2: Don't let unrelated property "flex-basis" influence the sizing inside of -webkit-box containers. r?mats draft
authorDaniel Holbert <dholbert@cs.stanford.edu>
Thu, 03 Aug 2017 11:18:13 -0700
changeset 620623 f28ebdd6176f8df2addcc1d5895f81999ffef8a2
parent 620622 53037939edc4978c0a0647a7e40e481a909aa8e6
child 640768 b92def355255463f937c4a9a64e0f058e7914b6f
push id72113
push userdholbert@mozilla.com
push dateThu, 03 Aug 2017 18:18:42 +0000
reviewersmats
bugs1387152
milestone56.0a1
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
@@ -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>