Bug 1300369 Part 1: Implement revised automatic minimum size for grid items which have fixed max track sizing functions. r?mats draft
authorBrad Werth <bwerth@mozilla.com>
Fri, 21 Oct 2016 12:55:58 -0700
changeset 428211 a685f9f71ed7122c27309cd95f05135ad32204dc
parent 427560 3f0aeafe59c40c5e92ba9636fa718cf26088e127
child 428212 c0eeed47dc6048eb20355c67ae8620c7048546ec
push id33255
push userbwerth@mozilla.com
push dateFri, 21 Oct 2016 20:03:35 +0000
reviewersmats
bugs1300369
milestone52.0a1
Bug 1300369 Part 1: Implement revised automatic minimum size for grid items which have fixed max track sizing functions. r?mats MozReview-Commit-ID: 8lTJgUYV0Cb
layout/generic/nsFrame.cpp
layout/generic/nsGridContainerFrame.cpp
layout/generic/nsGridContainerFrame.h
--- a/layout/generic/nsFrame.cpp
+++ b/layout/generic/nsFrame.cpp
@@ -4736,19 +4736,17 @@ nsFrame::ComputeSize(nsRenderingContext 
     minISize =
       nsLayoutUtils::ComputeISizeValue(aRenderingContext, this,
         aCBSize.ISize(aWM), boxSizingAdjust.ISize(aWM), boxSizingToMarginEdgeISize,
         minISizeCoord);
   } else if (MOZ_UNLIKELY(isGridItem)) {
     // This implements "Implied Minimum Size of Grid Items".
     // https://drafts.csswg.org/css-grid/#min-size-auto
     minISize = std::min(maxISize, GetMinISize(aRenderingContext));
-    if (inlineStyleCoord->IsCoordPercentCalcUnit()) {
-      minISize = std::min(minISize, result.ISize(aWM));
-    }
+    minISize = std::min(minISize, result.ISize(aWM));
   } else {
     // Treat "min-width: auto" as 0.
     // NOTE: Technically, "auto" is supposed to behave like "min-content" on
     // flex items. However, we don't need to worry about that here, because
     // flex items' min-sizes are intentionally ignored until the flex
     // container explicitly considers them during space distribution.
     minISize = 0;
   }
--- a/layout/generic/nsGridContainerFrame.cpp
+++ b/layout/generic/nsGridContainerFrame.cpp
@@ -3940,16 +3940,57 @@ MinSize(const GridItemInfo&    aGridItem
   if (unit == eStyleUnit_Enumerated ||
       (unit == eStyleUnit_Auto &&
        child->StyleDisplay()->mOverflowX == NS_STYLE_OVERFLOW_VISIBLE)) {
     // Now calculate the "content size" part and return whichever is smaller.
     MOZ_ASSERT(unit != eStyleUnit_Enumerated || sz == NS_UNCONSTRAINEDSIZE);
     sz = std::min(sz, ContentContribution(aGridItem, aState, aRC, aCBWM, aAxis,
                                           nsLayoutUtils::MIN_ISIZE,
                                           nsLayoutUtils::MIN_INTRINSIC_ISIZE));
+
+    // If the item spans only tracks with a fixed max track sizing function,
+    // further clamp this value to be no more than the sum of those track sizes.
+    const nsGridContainerFrame::GridArea& area = aGridItem.mArea;
+    const nsGridContainerFrame::LineRange& lineRange =
+      axis == eAxisHorizontal ? area.mCols : area.mRows;
+    MOZ_ASSERT(lineRange.IsDefinite(), "line ranges should be resolved by now");
+
+    const nsGridContainerFrame::TrackSizingFunctions& sizingFunctions =
+      axis == eAxisHorizontal ? aState.mColFunctions : aState.mRowFunctions;
+    const nsGridContainerFrame::Tracks& tracks =
+      axis == eAxisHorizontal ? aState.mCols : aState.mRows;
+
+    bool allTrackMaxSizesAreFixed = true;
+    nscoord sumOfMaxTrackSizes(0);
+    for (uint32_t i = lineRange.mStart; i < lineRange.mEnd; i++) {
+      // This track has a fixed max sizing function if it has a calculatable
+      // length or percentage.
+      // https://drafts.csswg.org/css-grid/#layout-algorithm
+      nsStyleCoord trackMaxSize = sizingFunctions.MaxSizingFor(i);
+      if (trackMaxSize.ConvertsToLength() || trackMaxSize.HasPercent()) {
+        if ((tracks.mSizes[i].mLimit != NS_UNCONSTRAINEDSIZE) &&
+            ((tracks.mSizes[i].mState &
+              nsGridContainerFrame::TrackSize::eFlexMaxSizing) == 0)) {
+          // This track has a fixed max sizing function, but we'll get the
+          // actual max size from the track, not from the sizing function,
+          // since the sizing function can't calculate percentages.
+          sumOfMaxTrackSizes += tracks.mSizes[i].mLimit;
+        } else {
+          allTrackMaxSizesAreFixed = false;
+          break;
+        }
+      } else {
+        allTrackMaxSizesAreFixed = false;
+        break;
+      }
+    }
+
+    if (allTrackMaxSizesAreFixed) {
+      sz = std::min(sz, sumOfMaxTrackSizes);
+    }
   }
   aCache->mMinSize.emplace(sz);
   return sz;
 }
 
 void
 nsGridContainerFrame::Tracks::CalculateSizes(
   GridReflowInput&            aState,
--- a/layout/generic/nsGridContainerFrame.h
+++ b/layout/generic/nsGridContainerFrame.h
@@ -223,22 +223,28 @@ protected:
   typedef mozilla::LogicalPoint LogicalPoint;
   typedef mozilla::LogicalRect LogicalRect;
   typedef mozilla::LogicalSize LogicalSize;
   typedef mozilla::WritingMode WritingMode;
   typedef mozilla::css::GridNamedArea GridNamedArea;
   typedef mozilla::layout::AutoFrameListPtr AutoFrameListPtr;
   typedef nsLayoutUtils::IntrinsicISizeType IntrinsicISizeType;
   struct Grid;
+public:
   struct GridArea;
+protected:
   class LineNameMap;
+public:
   struct LineRange;
+protected:
   struct SharedGridData;
+public:
   struct TrackSizingFunctions;
   struct Tracks;
+protected:
   struct TranslatedLineRange;
   friend nsContainerFrame* NS_NewGridContainerFrame(nsIPresShell* aPresShell,
                                                     nsStyleContext* aContext);
   explicit nsGridContainerFrame(nsStyleContext* aContext)
     : nsContainerFrame(aContext)
     , mCachedMinISize(NS_INTRINSIC_WIDTH_UNKNOWN)
     , mCachedPrefISize(NS_INTRINSIC_WIDTH_UNKNOWN)
   {