Bug 1300369 part 1 - Add two new ComputeSizeFlags flags e{I,B}ClampMarginBoxMinSize and associated reflow state flags to indicate we want margin-box min-size clamping in the indicated axis. r=dholbert
authorMats Palmgren <mats@mozilla.com>
Sat, 05 Nov 2016 02:57:06 +0100
changeset 351292 292c5a180ea30ee58429bf0addf74630a538b54c
parent 351291 30c652ff1d1e1bded08e12f4e6398429b2c2005b
child 351293 a89255f21073637c9c2588bc9fec6ec5de02a60f
push id6795
push userjlund@mozilla.com
push dateMon, 23 Jan 2017 14:19:46 +0000
treeherdermozilla-esr52@76101b503191 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdholbert
bugs1300369
milestone52.0a1
Bug 1300369 part 1 - Add two new ComputeSizeFlags flags e{I,B}ClampMarginBoxMinSize and associated reflow state flags to indicate we want margin-box min-size clamping in the indicated axis. r=dholbert
layout/generic/ReflowInput.cpp
layout/generic/ReflowInput.h
layout/generic/nsIFrame.h
--- a/layout/generic/ReflowInput.cpp
+++ b/layout/generic/ReflowInput.cpp
@@ -82,16 +82,22 @@ ReflowInput::ReflowInput(nsPresContext* 
     mFlags.mShrinkWrap = true;
   }
   if (aFlags & COMPUTE_SIZE_USE_AUTO_BSIZE) {
     mFlags.mUseAutoBSize = true;
   }
   if (aFlags & STATIC_POS_IS_CB_ORIGIN) {
     mFlags.mStaticPosIsCBOrigin = true;
   }
+  if (aFlags & I_CLAMP_MARGIN_BOX_MIN_SIZE) {
+    mFlags.mIClampMarginBoxMinSize = true;
+  }
+  if (aFlags & B_CLAMP_MARGIN_BOX_MIN_SIZE) {
+    mFlags.mBClampMarginBoxMinSize = true;
+  }
 
   if (!(aFlags & CALLER_WILL_INIT)) {
     Init(aPresContext);
   }
 }
 
 static bool CheckNextInFlowParenthood(nsIFrame* aFrame, nsIFrame* aParent)
 {
@@ -229,16 +235,18 @@ ReflowInput::ReflowInput(
   mFlags.mAssumingHScrollbar = mFlags.mAssumingVScrollbar = false;
   mFlags.mIsColumnBalancing = false;
   mFlags.mIsFlexContainerMeasuringHeight = false;
   mFlags.mDummyParentReflowInput = false;
   mFlags.mShrinkWrap = !!(aFlags & COMPUTE_SIZE_SHRINK_WRAP);
   mFlags.mUseAutoBSize = !!(aFlags & COMPUTE_SIZE_USE_AUTO_BSIZE);
   mFlags.mStaticPosIsCBOrigin = !!(aFlags & STATIC_POS_IS_CB_ORIGIN);
   mFlags.mIOffsetsNeedCSSAlign = mFlags.mBOffsetsNeedCSSAlign = false;
+  mFlags.mIClampMarginBoxMinSize = !!(aFlags & I_CLAMP_MARGIN_BOX_MIN_SIZE);
+  mFlags.mBClampMarginBoxMinSize = !!(aFlags & B_CLAMP_MARGIN_BOX_MIN_SIZE);
 
   mDiscoveredClearance = nullptr;
   mPercentBSizeObserver = (aParentReflowInput.mPercentBSizeObserver &&
                             aParentReflowInput.mPercentBSizeObserver->NeedsToObserve(*this))
                            ? aParentReflowInput.mPercentBSizeObserver : nullptr;
 
   if ((aFlags & DUMMY_PARENT_REFLOW_STATE) ||
       (mParentReflowInput->mFlags.mDummyParentReflowInput &&
@@ -1635,16 +1643,24 @@ ReflowInput::InitAbsoluteConstraints(nsP
     offsets.BStart(cbwm) = hypotheticalPos.mBStart;
     bStartIsAuto = false;
   }
 
   SetComputedLogicalOffsets(offsets.ConvertTo(wm, cbwm));
 
   typedef nsIFrame::ComputeSizeFlags ComputeSizeFlags;
   ComputeSizeFlags computeSizeFlags = ComputeSizeFlags::eDefault;
+  if (mFlags.mIClampMarginBoxMinSize) {
+    computeSizeFlags = ComputeSizeFlags(computeSizeFlags |
+                         ComputeSizeFlags::eIClampMarginBoxMinSize);
+  }
+  if (mFlags.mBClampMarginBoxMinSize) {
+    computeSizeFlags = ComputeSizeFlags(computeSizeFlags |
+                         ComputeSizeFlags::eBClampMarginBoxMinSize);
+  }
   if (mFlags.mShrinkWrap) {
     computeSizeFlags =
       ComputeSizeFlags(computeSizeFlags | ComputeSizeFlags::eShrinkWrap);
   }
   if (mFlags.mUseAutoBSize) {
     computeSizeFlags =
       ComputeSizeFlags(computeSizeFlags | ComputeSizeFlags::eUseAutoBSize);
   }
@@ -2340,16 +2356,24 @@ ReflowInput::InitConstraints(nsPresConte
       InitAbsoluteConstraints(aPresContext, cbrs, cbSize.ConvertTo(cbrs->GetWritingMode(), wm), aFrameType);
     } else {
       AutoMaybeDisableFontInflation an(mFrame);
 
       bool isBlock = NS_CSS_FRAME_TYPE_BLOCK == NS_FRAME_GET_TYPE(mFrameType);
       typedef nsIFrame::ComputeSizeFlags ComputeSizeFlags;
       ComputeSizeFlags computeSizeFlags =
         isBlock ? ComputeSizeFlags::eDefault : ComputeSizeFlags::eShrinkWrap;
+      if (mFlags.mIClampMarginBoxMinSize) {
+        computeSizeFlags = ComputeSizeFlags(computeSizeFlags |
+                             ComputeSizeFlags::eIClampMarginBoxMinSize);
+      }
+      if (mFlags.mBClampMarginBoxMinSize) {
+        computeSizeFlags = ComputeSizeFlags(computeSizeFlags |
+                             ComputeSizeFlags::eBClampMarginBoxMinSize);
+      }
       if (mFlags.mShrinkWrap) {
         computeSizeFlags =
           ComputeSizeFlags(computeSizeFlags | ComputeSizeFlags::eShrinkWrap);
       }
       if (mFlags.mUseAutoBSize) {
         computeSizeFlags =
           ComputeSizeFlags(computeSizeFlags | ComputeSizeFlags::eUseAutoBSize);
       }
--- a/layout/generic/ReflowInput.h
+++ b/layout/generic/ReflowInput.h
@@ -213,16 +213,18 @@ public:
                                         // holder children? If the available
                                         // height of this frame didn't change,
                                         // but its in a paginated environment
                                         // (e.g. columns), it should always
                                         // reflow its placeholder children.
     uint32_t mShrinkWrap:1; // stores the COMPUTE_SIZE_SHRINK_WRAP ctor flag
     uint32_t mUseAutoBSize:1; // stores the COMPUTE_SIZE_USE_AUTO_BSIZE ctor flag
     uint32_t mStaticPosIsCBOrigin:1; // the STATIC_POS_IS_CB_ORIGIN ctor flag
+    uint32_t mIClampMarginBoxMinSize:1; // the I_CLAMP_MARGIN_BOX_MIN_SIZE ctor flag
+    uint32_t mBClampMarginBoxMinSize:1; // the B_CLAMP_MARGIN_BOX_MIN_SIZE ctor flag
 
     // If set, the following two flags indicate that:
     // (1) this frame is absolutely-positioned (or fixed-positioned).
     // (2) this frame's static position depends on the CSS Box Alignment.
     // (3) we do need to compute the static position, because the frame's
     //     {Inline and/or Block} offsets actually depend on it.
     // When these bits are set, the offset values (IStart/IEnd, BStart/BEnd)
     // represent the "start" edge of the frame's CSS Box Alignment container
@@ -725,16 +727,22 @@ public:
 
     // The caller wants 'auto' bsize behavior (ComputeSizeFlags::eUseAutoBSize
     // will be be passed to ComputeSize()).
     COMPUTE_SIZE_USE_AUTO_BSIZE = (1<<3),
 
     // The caller wants the abs.pos. static-position resolved at the origin
     // of the containing block, i.e. at LogicalPoint(0, 0).
     STATIC_POS_IS_CB_ORIGIN = (1<<4),
+
+    // Pass ComputeSizeFlags::eIClampMarginBoxMinSize to ComputeSize().
+    I_CLAMP_MARGIN_BOX_MIN_SIZE = (1<<5),
+
+    // Pass ComputeSizeFlags::eBClampMarginBoxMinSize to ComputeSize().
+    B_CLAMP_MARGIN_BOX_MIN_SIZE = (1<<6),
   };
 
   // This method initializes various data members. It is automatically
   // called by the various constructors
   void Init(nsPresContext*              aPresContext,
             const mozilla::LogicalSize* aContainingBlockSize = nullptr,
             const nsMargin*             aBorder = nullptr,
             const nsMargin*             aPadding = nullptr);
--- a/layout/generic/nsIFrame.h
+++ b/layout/generic/nsIFrame.h
@@ -1967,40 +1967,51 @@ public:
   /**
    * Return the bsize components of padding, border, and margin
    * that contribute to the intrinsic width that applies to the parent.
    */
   IntrinsicISizeOffsetData IntrinsicBSizeOffsets();
 
   virtual mozilla::IntrinsicSize GetIntrinsicSize() = 0;
 
-  /*
+  /**
    * Get the intrinsic ratio of this element, or nsSize(0,0) if it has
    * no intrinsic ratio.  The intrinsic ratio is the ratio of the
    * height/width of a box with an intrinsic size or the intrinsic
    * aspect ratio of a scalable vector image without an intrinsic size.
    *
    * Either one of the sides may be zero, indicating a zero or infinite
    * ratio.
    */
   virtual nsSize GetIntrinsicRatio() = 0;
 
   /**
    * Bit-flags to pass to ComputeSize in |aFlags| parameter.
    */
   enum ComputeSizeFlags {
     eDefault =           0,
-    /* Set if the frame is in a context where non-replaced blocks should
+    /**
+     * Set if the frame is in a context where non-replaced blocks should
      * shrink-wrap (e.g., it's floating, absolutely positioned, or
-     * inline-block). */
+     * inline-block).
+     */
     eShrinkWrap =        1 << 0,
-    /* Set if we'd like to compute our 'auto' bsize, regardless of our actual
+    /**
+     * Set if we'd like to compute our 'auto' bsize, regardless of our actual
      * corresponding computed value. (e.g. to get an intrinsic height for flex
-     * items with "min-height: auto" to use during flexbox layout.) */
-    eUseAutoBSize =      1 << 1
+     * items with "min-height: auto" to use during flexbox layout.)
+     */
+    eUseAutoBSize =      1 << 1,
+    /**
+     * Indicates that we should clamp the margin-box min-size to the given CB
+     * size.  This is used for implementing the grid area clamping here:
+     * https://drafts.csswg.org/css-grid/#min-size-auto
+     */
+    eIClampMarginBoxMinSize = 1 << 2, // clamp in our inline axis
+    eBClampMarginBoxMinSize = 1 << 3, // clamp in our block axis
   };
 
   /**
    * Compute the size that a frame will occupy.  Called while
    * constructing the ReflowInput to be used to Reflow the frame,
    * in order to fill its mComputedWidth and mComputedHeight member
    * variables.
    *