Bug 1474663 - Implement contain:size for nsColumnSetFrame. r=dholbert
☠☠ backed out by 0287f9144ec2 ☠ ☠
authorMorgan Rae Reschenberg <mreschenberg@mozilla.com>
Thu, 12 Jul 2018 09:10:52 -0700
changeset 426797 4aa2f74bad5b77dd8f8c7e6e0e9eacafd64ef95d
parent 426796 d104946698b2d05ccc0529837cd7136790b36c34
child 426798 f98112e495824b4d710ccedee63c8fc1f1aa4047
push id34285
push userbtara@mozilla.com
push dateMon, 16 Jul 2018 21:58:41 +0000
treeherdermozilla-central@f6df6a982ee9 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdholbert
bugs1474663
milestone63.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 1474663 - Implement contain:size for nsColumnSetFrame. r=dholbert MozReview-Commit-ID: EE7Un9LUJcV
layout/generic/nsColumnSetFrame.cpp
layout/reftests/w3c-css/submitted/contain/contain-size-multicol-002-ref.html
layout/reftests/w3c-css/submitted/contain/contain-size-multicol-002.html
layout/reftests/w3c-css/submitted/contain/contain-size-multicol-003-ref.html
layout/reftests/w3c-css/submitted/contain/contain-size-multicol-003.html
layout/reftests/w3c-css/submitted/contain/reftest.list
--- a/layout/generic/nsColumnSetFrame.cpp
+++ b/layout/generic/nsColumnSetFrame.cpp
@@ -489,17 +489,21 @@ static void MoveChildTo(nsIFrame* aChild
   nsContainerFrame::PlaceFrameView(aChild);
 }
 
 nscoord
 nsColumnSetFrame::GetMinISize(gfxContext *aRenderingContext)
 {
   nscoord iSize = 0;
   DISPLAY_MIN_WIDTH(this, iSize);
-  if (mFrames.FirstChild()) {
+
+  if (mFrames.FirstChild() && !StyleDisplay()->IsContainSize()) {
+    // We want to ignore this in the case that we're size contained
+    // because our children should not contribute to our
+    // intrinsic size.
     iSize = mFrames.FirstChild()->GetMinISize(aRenderingContext);
   }
   const nsStyleColumn* colStyle = StyleColumn();
   nscoord colISize;
   if (colStyle->mColumnWidth.GetUnit() == eStyleUnit_Coord) {
     colISize = colStyle->mColumnWidth.GetCoordValue();
     // As available width reduces to zero, we reduce our number of columns
     // to one, and don't enforce the column width, so just return the min
@@ -534,17 +538,20 @@ nsColumnSetFrame::GetPrefISize(gfxContex
   nscoord result = 0;
   DISPLAY_PREF_WIDTH(this, result);
   const nsStyleColumn* colStyle = StyleColumn();
   nscoord colGap = GetColumnGap(this, NS_UNCONSTRAINEDSIZE);
 
   nscoord colISize;
   if (colStyle->mColumnWidth.GetUnit() == eStyleUnit_Coord) {
     colISize = colStyle->mColumnWidth.GetCoordValue();
-  } else if (mFrames.FirstChild()) {
+  } else if (mFrames.FirstChild() && !StyleDisplay()->IsContainSize()) {
+    // We want to ignore this in the case that we're size contained
+    // because our children should not contribute to our
+    // intrinsic size.
     colISize = mFrames.FirstChild()->GetPrefISize(aRenderingContext);
   } else {
     colISize = 0;
   }
 
   int32_t numColumns = colStyle->mColumnCount;
   if (numColumns <= 0) {
     // if column-count is auto, assume one column
@@ -903,16 +910,21 @@ nsColumnSetFrame::ReflowChildren(ReflowO
   // Apply computed and min/max values
   if (aConfig.mComputedBSize != NS_INTRINSICSIZE) {
     if (aReflowInput.AvailableBSize() != NS_INTRINSICSIZE) {
       contentSize.BSize(wm) = std::min(contentSize.BSize(wm),
                                        aConfig.mComputedBSize);
     } else {
       contentSize.BSize(wm) = aConfig.mComputedBSize;
     }
+  } else if (aReflowInput.mStyleDisplay->IsContainSize()) {
+    // If we are intrinsically sized, but are size contained,
+    // we need to behave as if we have no contents. Our BSize
+    // should be zero or minBSize if specified.
+    contentSize.BSize(wm) = aReflowInput.ApplyMinMaxBSize(0);
   } else {
     // We add the "consumed" block-size back in so that we're applying
     // constraints to the correct bSize value, then subtract it again
     // after we've finished with the min/max calculation. This prevents us from
     // having a last continuation that is smaller than the min bSize. but which
     // has prev-in-flows, trigger a larger bSize than actually required.
     contentSize.BSize(wm) =
       aReflowInput.ApplyMinMaxBSize(contentSize.BSize(wm),
new file mode 100644
--- /dev/null
+++ b/layout/reftests/w3c-css/submitted/contain/contain-size-multicol-002-ref.html
@@ -0,0 +1,49 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <meta charset="utf-8">
+  <title>CSS Reftest Reference</title>
+  <link rel="author" title="Morgan Rae Reschenberg" href="mailto:mreschenberg@berkeley.edu">
+  <style>
+  .basic {
+    border: 1em solid green;
+    column-count: 3;
+  }
+  .height-ref {
+    height: 20px;
+    background: lightblue;
+  }
+  .width-ref {
+    width: 20px;
+  }
+  .floatLBasic-ref {
+    float: left;
+  }
+  .floatLWidth-ref {
+    float: left;
+    width: 20px;
+  }
+  </style>
+</head>
+<body>
+  <div class="basic"></div>
+  <br>
+
+  <div class="basic height-ref"></div>
+  <br>
+
+  <div class="basic height-ref"></div>
+  <br>
+
+  <div class="basic width-ref"></div>
+  <br>
+
+  <div class="basic width-ref"></div>
+  <br>
+
+  <div class="basic floatLBasic-ref"></div>
+  <br>
+
+  <div class="basic floatLWidth-ref"></div>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/w3c-css/submitted/contain/contain-size-multicol-002.html
@@ -0,0 +1,72 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <meta charset="utf-8">
+  <title>CSS Test: 'contain: size' on multicol elements should cause them to be sized as if they had no contents.</title>
+  <link rel="author" title="Morgan Rae Reschenberg" href="mailto:mreschenberg@berkeley.edu">
+  <link rel="help" href="https://drafts.csswg.org/css-contain/#containment-size">
+  <link rel="match" href="contain-size-multicol-002-ref.html">
+  <style>
+  .contain {
+    contain: size;
+    border: 1em solid green;
+    background: red;
+    column-count: 3;
+  }
+  .innerContents {
+    color: transparent;
+    height: 100px;
+    width: 100px;
+  }
+  .minHeight {
+    min-height: 20px;
+    background: lightblue;
+  }
+  .height {
+    height: 20px;
+    background: lightblue;
+  }
+  .maxWidth {
+    max-width: 20px;
+  }
+  .width {
+    width: 20px;
+  }
+  .floatLBasic {
+    float: left;
+  }
+  .floatLWidth {
+    float: left;
+    width: 20px;
+  }
+  </style>
+</head>
+<body>
+  <!--CSS Test: A size-contained multicol element with no specified size should render at 0 height regardless of content.-->
+  <div class="contain"><div class="innerContents">inner</div></div>
+  <br>
+
+  <!--CSS Test: A size-contained multicol element with specified min-height should render at given min-height regardless of content.-->
+  <div class="contain minHeight"><div class="innerContents">inner</div></div>
+  <br>
+
+  <!--CSS Test: A size-contained multicol element with specified height should render at given height regardless of content.-->
+  <div class="contain height"><div class="innerContents">inner</div></div>
+  <br>
+
+  <!--CSS Test: A size-contained multicol element with specified max-width should render at given max-width and zero height regardless of content.-->
+  <div class="contain maxWidth"><div class="innerContents">inner</div></div>
+  <br>
+
+  <!--CSS Test: A size-contained multicol element with specified width should render at given width and zero height regardless of content.-->
+  <div class="contain width"><div class="innerContents">inner</div></div>
+  <br>
+
+  <!--CSS Test: A size-contained floated multicol element with no specified size should render at 0px by 0px regardless of content.-->
+  <div class="contain floatLBasic"><div class="innerContents">inner</div></div>
+  <br>
+
+  <!--CSS Test: A size-contained floated multicol element with specified width and no specified height should render at given width and 0 height regardless of content.-->
+  <div class="contain floatLWidth"><div class="innerContents">inner</div></div>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/w3c-css/submitted/contain/contain-size-multicol-003-ref.html
@@ -0,0 +1,57 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <meta charset="utf-8">
+  <title>CSS Reftest Reference</title>
+  <link rel="author" title="Morgan Rae Reschenberg" href="mailto:mreschenberg@berkeley.edu">
+  <style>
+  .basic {
+    border: 1em solid green;
+    columns-count: 3;
+  }
+  .col-width-ref {
+    column-width: 20px;
+  }
+  .col-gap-ref {
+    column-gap: 5px;
+  }
+  .flexBaselineCheck {
+    display: flex;
+    align-items: baseline;
+  }
+  .min {
+    width: -moz-min-content;
+  }
+  .max {
+    width: -moz-max-content;
+  }
+  </style>
+</head>
+<body>
+  <div class="flexBaselineCheck">
+  outside before<div class="basic"></div>outside after
+  </div>
+  <br>
+
+  <div class="basic min col-width-ref"></div>
+  <br>
+
+  <div class="basic max col-width-ref"></div>
+  <br>
+
+  <div class="basic min col-gap-ref col-width-ref"></div>
+  <br>
+
+  <div class="basic max col-gap-ref col-width-ref"></div>
+  <br>
+
+  <div class="min">
+    <div class="basic"></div>
+  </div>
+  <br>
+
+  <div class="max">
+    <div class="basic"></div>
+  </div>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/w3c-css/submitted/contain/contain-size-multicol-003.html
@@ -0,0 +1,73 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <meta charset="utf-8">
+  <title>CSS Test: 'contain: size' on multicol elements should cause them to be sized and baseline-aligned as if they had no contents.</title>
+  <link rel="author" title="Morgan Rae Reschenberg" href="mailto:mreschenberg@berkeley.edu">
+  <link rel="help" href="https://drafts.csswg.org/css-contain/#containment-size">
+  <link rel="match" href="contain-size-multicol-003-ref.html">
+  <style>
+  .contain {
+    contain: size;
+    border: 1em solid green;
+    background: red;
+    column-count: 3;
+  }
+  .innerContents {
+    color: transparent;
+    height: 100px;
+    width: 100px;
+  }
+  .col-width {
+    column-width: 20px;
+  }
+  .col-gap {
+    column-gap: 5px;
+  }
+  .flexBaselineCheck {
+    display: flex;
+    align-items: baseline;
+  }
+  .min {
+    width: -moz-min-content;
+  }
+  .max {
+    width: -moz-max-content;
+  }
+  </style>
+</head>
+<body>
+  <!--CSS Test: A size-contained multicol element should perform baseline alignment as if it had no contents.-->
+  <div class="flexBaselineCheck">
+  outside before<div class="contain"><div class="innerContents">inner</div></div>outside after
+  </div>
+  <br>
+
+  <!--The following tests are used to ensure column-gaps and column-widths continue to contribute to the minimum and maximum width of a size-contained multicol element. Each should render as if it had no contents.-->
+
+  <div class="contain min col-width"><div class="innerContents">inner</div></div>
+  <br>
+
+  <div class="contain max col-width"><div class="innerContents">inner</div></div>
+  <br>
+
+  <div class="contain min col-gap col-width"><div class="innerContents">inner</div></div>
+  <br>
+
+  <div class="contain max col-gap col-width"><div class="innerContents">inner</div></div>
+  <br>
+
+  <div class="min">
+    <div class="contain">
+      <div class="innerContents">inner</div>
+    </div>
+  </div>
+  <br>
+
+  <div class="max">
+    <div class="contain">
+      <div class="innerContents">inner</div>
+    </div>
+  </div>
+</body>
+</html>
--- a/layout/reftests/w3c-css/submitted/contain/reftest.list
+++ b/layout/reftests/w3c-css/submitted/contain/reftest.list
@@ -18,8 +18,10 @@ pref(layout.css.overflow-clip-box.enable
 == contain-paint-stacking-context-001a.html contain-paint-stacking-context-001-ref.html
 == contain-paint-stacking-context-001b.html contain-paint-stacking-context-001-ref.html
 == contain-size-button-001.html contain-size-button-001-ref.html
 == contain-size-block-001.html contain-size-block-001-ref.html
 == contain-size-inline-block-001.html contain-size-inline-block-001-ref.html
 == contain-size-flex-001.html contain-size-flex-001-ref.html
 fuzzy-if(webrender&&winWidget,3,2) == contain-size-inline-flex-001.html contain-size-inline-flex-001-ref.html # bug 1474093
 == contain-size-multicol-001.html contain-size-multicol-001-ref.html
+== contain-size-multicol-002.html contain-size-multicol-002-ref.html
+== contain-size-multicol-003.html contain-size-multicol-003-ref.html