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 819005 4aa2f74bad5b77dd8f8c7e6e0e9eacafd64ef95d
parent 819004 d104946698b2d05ccc0529837cd7136790b36c34
child 819006 f98112e495824b4d710ccedee63c8fc1f1aa4047
push id116413
push userbgrinstead@mozilla.com
push dateMon, 16 Jul 2018 22:40:17 +0000
reviewersdholbert
bugs1474663
milestone63.0a1
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