Bug 1000957: For single-line flex containers, clamp the flex line to container's min/max cross size. r?dholbert draft
authorEmilio Cobos Álvarez <ecoal95@gmail.com>
Tue, 09 Aug 2016 10:17:24 -0700
changeset 398759 0e2b1dc013213675ab35042b8a931f8226a3d7bc
parent 398752 40b121ee222da16181f0d521dd4705eeed3da86d
child 398760 c10648a9e9fc726795e1cc97d8bfb5baeddf8bbb
child 398818 5c1f003cafb9dead4c706c0242438e1124763c2b
child 398829 929d2f7a3dbc9a2d296023a7306c2028a45921fd
push id25619
push userbmo:ealvarez@mozilla.com
push dateTue, 09 Aug 2016 17:34:58 +0000
reviewersdholbert
bugs1000957
milestone51.0a1
Bug 1000957: For single-line flex containers, clamp the flex line to container's min/max cross size. r?dholbert MozReview-Commit-ID: 9Kqg0lPnkv0
layout/generic/nsFlexContainerFrame.cpp
--- a/layout/generic/nsFlexContainerFrame.cpp
+++ b/layout/generic/nsFlexContainerFrame.cpp
@@ -2028,17 +2028,17 @@ private:
 
 // Utility class for managing our position along the cross axis along
 // the whole flex container (at a higher level than a single line).
 // The "0" position represents the cross-start edge of the flex container's
 // content-box.
 class MOZ_STACK_CLASS CrossAxisPositionTracker : public PositionTracker {
 public:
   CrossAxisPositionTracker(FlexLine* aFirstLine,
-                           uint8_t aAlignContent,
+                           const ReflowInput& aReflowInput,
                            nscoord aContentBoxCrossSize,
                            bool aIsCrossSizeDefinite,
                            const FlexboxAxisTracker& aAxisTracker);
 
   // Advances past the packing space (if any) between two flex lines
   void TraversePackingSpace();
 
   // Advances past the given FlexLine
@@ -2732,47 +2732,56 @@ MainAxisPositionTracker::TraversePacking
     mPosition += curPackingSpace;
     mNumPackingSpacesRemaining--;
     mPackingSpaceRemaining -= curPackingSpace;
   }
 }
 
 CrossAxisPositionTracker::
   CrossAxisPositionTracker(FlexLine* aFirstLine,
-                           uint8_t aAlignContent,
+                           const ReflowInput& aReflowInput,
                            nscoord aContentBoxCrossSize,
                            bool aIsCrossSizeDefinite,
                            const FlexboxAxisTracker& aAxisTracker)
   : PositionTracker(aAxisTracker.GetCrossAxis(),
                     aAxisTracker.IsCrossAxisReversed()),
     mPackingSpaceRemaining(0),
     mNumPackingSpacesRemaining(0),
-    mAlignContent(aAlignContent)
+    mAlignContent(aReflowInput.mStylePosition->ComputedAlignContent())
 {
   MOZ_ASSERT(aFirstLine, "null first line pointer");
 
   // 'normal' behaves as 'stretch'
   if (mAlignContent == NS_STYLE_ALIGN_NORMAL) {
     mAlignContent = NS_STYLE_ALIGN_STRETCH;
   }
 
   // XXX strip of the <overflow-position> bit until we implement that
   mAlignContent &= ~NS_STYLE_ALIGN_FLAG_BITS;
 
-  if (aIsCrossSizeDefinite && !aFirstLine->getNext()) {
-    // "If the flex container has only a single line (even if it's a
-    // multi-line flex container) and has a definite cross size, the cross
-    // size of the flex line is the flex container's inner cross size."
+  if (!aFirstLine->getNext()) {
+    // "If the flex container is single-line and has a definite cross size, the
+    // cross size of the flex line is the flex container's inner cross size."
+    //
     // SOURCE: http://dev.w3.org/csswg/css-flexbox/#algo-line-break
     // NOTE: This means (by definition) that there's no packing space, which
     // means we don't need to be concerned with "align-conent" at all and we
     // can return early. This is handy, because this is the usual case (for
     // single-line flexbox).
-    aFirstLine->SetLineCrossSize(aContentBoxCrossSize);
-    return;
+    if (aIsCrossSizeDefinite) {
+      aFirstLine->SetLineCrossSize(aContentBoxCrossSize);
+      return;
+    }
+
+    // "If the flex container is single-line, then clamp the line's
+    // cross-size to be within the container's computed min and max cross-size
+    // properties."
+    aFirstLine->SetLineCrossSize(NS_CSS_MINMAX(aFirstLine->GetLineCrossSize(),
+                                               aReflowInput.ComputedMinBSize(),
+                                               aReflowInput.ComputedMaxBSize()));
   }
 
   // NOTE: The rest of this function should essentially match
   // MainAxisPositionTracker's constructor, though with FlexLines instead of
   // FlexItems, and with the additional value "stretch" (and of course with
   // cross sizes instead of main sizes.)
 
   // Figure out how much packing space we have (container's cross size minus
@@ -4015,19 +4024,18 @@ nsFlexContainerFrame::DoFlexLayout(nsPre
   const nscoord contentBoxCrossSize =
     ComputeCrossSize(aReflowInput, aAxisTracker, sumLineCrossSizes,
                      aAvailableBSizeForContent, &isCrossSizeDefinite, aStatus);
 
   // Set up state for cross-axis alignment, at a high level (outside the
   // scope of a particular flex line)
   CrossAxisPositionTracker
     crossAxisPosnTracker(lines.getFirst(),
-                         aReflowInput.mStylePosition->ComputedAlignContent(),
-                         contentBoxCrossSize, isCrossSizeDefinite,
-                         aAxisTracker);
+                         aReflowInput, contentBoxCrossSize,
+                         isCrossSizeDefinite, aAxisTracker);
 
   // Now that we know the cross size of each line (including
   // "align-content:stretch" adjustments, from the CrossAxisPositionTracker
   // constructor), we can create struts for any flex items with
   // "visibility: collapse" (and restart flex layout).
   if (aStruts.IsEmpty()) { // (Don't make struts if we already did)
     BuildStrutInfoFromCollapsedItems(lines.getFirst(), aStruts);
     if (!aStruts.IsEmpty()) {