Bug 666041 patch 6.5: Add flag to nsHTMLReflowState & ComputeSize for measuring auto height. r=dbaron
authorDaniel Holbert <dholbert@cs.stanford.edu>
Sat, 29 Sep 2012 23:38:46 -0700
changeset 108681 129629b6106fb033310e9cb8f363c2fa00e586c9
parent 108680 aaf9e3020132bbeeaff9180d9da9d1da76b81f53
child 108682 076d87bf30d091738dc355b817e928d5d6faae8c
push id23577
push usermlamouri@mozilla.com
push dateSun, 30 Sep 2012 12:19:29 +0000
treeherdermozilla-central@0df33af01cee [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdbaron
bugs666041
milestone18.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 666041 patch 6.5: Add flag to nsHTMLReflowState & ComputeSize for measuring auto height. r=dbaron
layout/generic/nsFrame.cpp
layout/generic/nsHTMLReflowState.cpp
layout/generic/nsHTMLReflowState.h
layout/generic/nsIFrame.h
--- a/layout/generic/nsFrame.cpp
+++ b/layout/generic/nsFrame.cpp
@@ -3999,17 +3999,21 @@ nsFrame::ComputeSize(nsRenderingContext 
     // 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.
     minWidth = 0;
   }
   result.width = NS_MAX(minWidth, result.width);
 
   // Compute height
-  if (!nsLayoutUtils::IsAutoHeight(*heightStyleCoord, aCBSize.height)) {
+  // (but not if we're auto-height or if we recieved the "eUseAutoHeight"
+  // flag -- then, we'll just stick with the height that we already calculated
+  // in the initial ComputeAutoSize() call.)
+  if (!nsLayoutUtils::IsAutoHeight(*heightStyleCoord, aCBSize.height) &&
+      !(aFlags & nsIFrame::eUseAutoHeight)) {
     result.height =
       nsLayoutUtils::ComputeHeightValue(aCBSize.height, 
                                         boxSizingAdjust.height,
                                         *heightStyleCoord);
   }
 
   if (result.height != NS_UNCONSTRAINEDSIZE) {
     if (!nsLayoutUtils::IsAutoHeight(stylePos->mMaxHeight, aCBSize.height) &&
--- a/layout/generic/nsHTMLReflowState.cpp
+++ b/layout/generic/nsHTMLReflowState.cpp
@@ -169,16 +169,17 @@ nsHTMLReflowState::nsHTMLReflowState(nsP
   // Note: mFlags was initialized as a copy of aParentReflowState.mFlags up in
   // this constructor's init list, so the only flags that we need to explicitly
   // initialize here are those that may need a value other than our parent's.
   mFlags.mNextInFlowUntouched = aParentReflowState.mFlags.mNextInFlowUntouched &&
     CheckNextInFlowParenthood(aFrame, aParentReflowState.frame);
   mFlags.mAssumingHScrollbar = mFlags.mAssumingVScrollbar = false;
   mFlags.mHasClearance = false;
   mFlags.mIsColumnBalancing = false;
+  mFlags.mIsFlexContainerMeasuringHeight = false;
   mFlags.mDummyParentReflowState = false;
 
   mDiscoveredClearance = nullptr;
   mPercentHeightObserver = (aParentReflowState.mPercentHeightObserver && 
                             aParentReflowState.mPercentHeightObserver->NeedsToObserve(*this)) 
                            ? aParentReflowState.mPercentHeightObserver : nullptr;
 
   if (aInit) {
@@ -2004,16 +2005,22 @@ nsHTMLReflowState::InitConstraints(nsPre
       if (isBlock &&
           ((aFrameType == nsGkAtoms::legendFrame &&
             frame->GetStyleContext()->GetPseudo() != nsCSSAnonBoxes::scrolledContent) ||
            (aFrameType == nsGkAtoms::scrollFrame &&
             frame->GetContentInsertionFrame()->GetType() == nsGkAtoms::legendFrame))) {
         computeSizeFlags |= nsIFrame::eShrinkWrap;
       }
 
+      // If we're inside of a flexbox that needs to measure our auto height,
+      // pass that information along to ComputeSize().
+      if (mFlags.mIsFlexContainerMeasuringHeight) {
+        computeSizeFlags |= nsIFrame::eUseAutoHeight;
+      }
+
       nsSize size =
         frame->ComputeSize(rendContext,
                            nsSize(aContainingBlockWidth,
                                   aContainingBlockHeight),
                            availableWidth,
                            nsSize(mComputedMargin.LeftRight(),
                                   mComputedMargin.TopBottom()),
                            nsSize(mComputedBorderPadding.LeftRight() -
@@ -2482,46 +2489,53 @@ nsHTMLReflowState::ComputeMinMaxValues(n
   if (mComputedMinWidth > mComputedMaxWidth) {
     mComputedMaxWidth = mComputedMinWidth;
   }
 
   // Check for percentage based values and a containing block height that
   // depends on the content height. Treat them like 'auto'
   // Likewise, check for calc() on internal table elements; calc() on
   // such elements is unsupported.
+  // Likewise, if we're a child of a flex container who's measuring our
+  // intrinsic height, then we want to disregard our min-height.
+
   // NOTE: We treat "min-height:auto" as "0" for the purpose of this code,
   // since that's what it means in all cases except for on flex items -- and
   // even there, we're supposed to ignore it (i.e. treat it as 0) until the
   // flex container explicitly considers it.
   const nsStyleCoord &minHeight = mStylePosition->mMinHeight;
   if (eStyleUnit_Auto == minHeight.GetUnit() ||
       (NS_AUTOHEIGHT == aContainingBlockHeight &&
        minHeight.HasPercent()) ||
       (mFrameType == NS_CSS_FRAME_TYPE_INTERNAL_TABLE &&
-       minHeight.IsCalcUnit())) {
+       minHeight.IsCalcUnit()) ||
+      mFlags.mIsFlexContainerMeasuringHeight) {
     mComputedMinHeight = 0;
   } else {
     mComputedMinHeight = ComputeHeightValue(aContainingBlockHeight, 
                                             mStylePosition->mBoxSizing, 
                                             minHeight);
   }
   const nsStyleCoord &maxHeight = mStylePosition->mMaxHeight;
   nsStyleUnit maxHeightUnit = maxHeight.GetUnit();
   if (eStyleUnit_None == maxHeightUnit) {
     // Specified value of 'none'
     mComputedMaxHeight = NS_UNCONSTRAINEDSIZE;  // no limit
   } else {
     // Check for percentage based values and a containing block height that
-    // depends on the content height. Treat them like 'auto'
+    // depends on the content height. Treat them like 'none'
     // Likewise, check for calc() on internal table elements; calc() on
     // such elements is unsupported.
+    // Likewise, if we're a child of a flex container who's measuring our
+    // intrinsic height, then we want to disregard our max-height.
     if ((NS_AUTOHEIGHT == aContainingBlockHeight && 
          maxHeight.HasPercent()) ||
         (mFrameType == NS_CSS_FRAME_TYPE_INTERNAL_TABLE &&
-         maxHeight.IsCalcUnit())) {
+         maxHeight.IsCalcUnit()) ||
+        mFlags.mIsFlexContainerMeasuringHeight) {
       mComputedMaxHeight = NS_UNCONSTRAINEDSIZE;
     } else {
       mComputedMaxHeight = ComputeHeightValue(aContainingBlockHeight, 
                                               mStylePosition->mBoxSizing,
                                               maxHeight);
     }
   }
 
--- a/layout/generic/nsHTMLReflowState.h
+++ b/layout/generic/nsHTMLReflowState.h
@@ -344,16 +344,19 @@ public:
                                      // (potentially) in a context where
                                      // percent heights have a different
                                      // basis?
     uint16_t mTableIsSplittable:1;   // tables are splittable, this should happen only inside a page
                                      // and never insider a column frame
     uint16_t mHeightDependsOnAncestorCell:1;   // Does frame height depend on
                                                // an ancestor table-cell?
     uint16_t mIsColumnBalancing:1;   // nsColumnSetFrame is balancing columns
+    uint16_t mIsFlexContainerMeasuringHeight:1; // nsFlexContainerFrame is
+                                                // reflowing this child to
+                                                // measure its intrinsic height.
     uint16_t mDummyParentReflowState:1; // a "fake" reflow state made
                                         // in order to be the parent
                                         // of a real one
   } mFlags;
 
   // Note: The copy constructor is written by the compiler automatically. You
   // can use that and then override specific values if you want, or you can
   // call Init as desired...
--- a/layout/generic/nsIFrame.h
+++ b/layout/generic/nsIFrame.h
@@ -1733,17 +1733,21 @@ public:
 
   /**
    * Bit-flags to pass to ComputeSize in |aFlags| parameter.
    */
   enum {
     /* 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). */
-    eShrinkWrap =        1 << 0
+    eShrinkWrap =        1 << 0,
+    /* Set if we'd like to compute our 'auto' height, regardless of our actual
+     * computed value of 'height'. (e.g. to get an intrinsic height for flex
+     * items with "min-height: auto" to use during flexbox layout.) */
+    eUseAutoHeight =     1 << 1
   };
 
   /**
    * Compute the size that a frame will occupy.  Called while
    * constructing the nsHTMLReflowState to be used to Reflow the frame,
    * in order to fill its mComputedWidth and mComputedHeight member
    * variables.
    *