Bug 1227285 part 1 - Add a nsHTMLReflowState ctor flag to request shrink-wrap behavior. r=dholbert
authorMats Palmgren <mats@mozilla.com>
Wed, 02 Dec 2015 14:12:23 +0100
changeset 275118 fd03238ebdb51450e42a76d188fae5ed0bfbb066
parent 275117 984115c3af750b37c549642760c7802d8f531a08
child 275119 ba839fc1b5d77ed5e8e24786846104461cd9341a
push id68774
push usermpalmgren@mozilla.com
push dateWed, 02 Dec 2015 13:12:36 +0000
treeherdermozilla-inbound@349b2d9ac5aa [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdholbert
bugs1227285
milestone45.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 1227285 part 1 - Add a nsHTMLReflowState ctor flag to request shrink-wrap behavior. r=dholbert
layout/generic/nsHTMLReflowState.cpp
layout/generic/nsHTMLReflowState.h
--- a/layout/generic/nsHTMLReflowState.cpp
+++ b/layout/generic/nsHTMLReflowState.cpp
@@ -74,16 +74,19 @@ nsHTMLReflowState::nsHTMLReflowState(nsP
   mLineLayout = nullptr;
   memset(&mFlags, 0, sizeof(mFlags));
   mDiscoveredClearance = nullptr;
   mPercentBSizeObserver = nullptr;
 
   if (aFlags & DUMMY_PARENT_REFLOW_STATE) {
     mFlags.mDummyParentReflowState = true;
   }
+  if (aFlags & COMPUTE_SIZE_SHRINK_WRAP) {
+    mFlags.mShrinkWrap = true;
+  }
 
   if (!(aFlags & CALLER_WILL_INIT)) {
     Init(aPresContext);
   }
 }
 
 static bool CheckNextInFlowParenthood(nsIFrame* aFrame, nsIFrame* aParent)
 {
@@ -214,16 +217,17 @@ nsHTMLReflowState::nsHTMLReflowState(
   // 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.mIsColumnBalancing = false;
   mFlags.mIsFlexContainerMeasuringHeight = false;
   mFlags.mDummyParentReflowState = false;
+  mFlags.mShrinkWrap = !!(aFlags & COMPUTE_SIZE_SHRINK_WRAP);
 
   mDiscoveredClearance = nullptr;
   mPercentBSizeObserver = (aParentReflowState.mPercentBSizeObserver &&
                             aParentReflowState.mPercentBSizeObserver->NeedsToObserve(*this))
                            ? aParentReflowState.mPercentBSizeObserver : nullptr;
 
   if ((aFlags & DUMMY_PARENT_REFLOW_STATE) ||
       (parentReflowState->mFlags.mDummyParentReflowState &&
@@ -1583,16 +1587,20 @@ nsHTMLReflowState::InitAbsoluteConstrain
 
   SetComputedLogicalOffsets(offsets.ConvertTo(wm, cbwm));
 
   bool iSizeIsAuto = eStyleUnit_Auto == mStylePosition->ISize(cbwm).GetUnit();
   bool bSizeIsAuto = eStyleUnit_Auto == mStylePosition->BSize(cbwm).GetUnit();
 
   typedef nsIFrame::ComputeSizeFlags ComputeSizeFlags;
   ComputeSizeFlags computeSizeFlags = ComputeSizeFlags::eDefault;
+  if (mFlags.mShrinkWrap) {
+    computeSizeFlags =
+      ComputeSizeFlags(computeSizeFlags | ComputeSizeFlags::eShrinkWrap);
+  }
   if (wm.IsOrthogonalTo(cbwm)) {
     if (bStartIsAuto || bEndIsAuto) {
       computeSizeFlags =
         ComputeSizeFlags(computeSizeFlags | ComputeSizeFlags::eShrinkWrap);
     }
   } else {
     if (iStartIsAuto || iEndIsAuto) {
       computeSizeFlags =
@@ -2283,16 +2291,20 @@ nsHTMLReflowState::InitConstraints(nsPre
       InitAbsoluteConstraints(aPresContext, cbrs, cbSize.ConvertTo(cbrs->GetWritingMode(), wm), aFrameType);
     } else {
       AutoMaybeDisableFontInflation an(frame);
 
       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.mShrinkWrap) {
+        computeSizeFlags =
+          ComputeSizeFlags(computeSizeFlags | ComputeSizeFlags::eShrinkWrap);
+      }
 
       nsIFrame* parent = frame->GetParent();
       nsIAtom* parentFrameType = parent ? parent->GetType() : nullptr;
       if (parentFrameType == nsGkAtoms::gridContainerFrame) {
         // Shrink-wrap grid items that will be aligned (rather than stretched)
         // in its inline axis.
         auto inlineAxisAlignment = wm.IsOrthogonalTo(cbwm) ?
           mStylePosition->ComputedAlignSelf(mStyleDisplay,
--- a/layout/generic/nsHTMLReflowState.h
+++ b/layout/generic/nsHTMLReflowState.h
@@ -578,16 +578,17 @@ public:
                                         // in order to be the parent
                                         // of a real one
     uint16_t mMustReflowPlaceholders:1; // Should this frame reflow its place-
                                         // 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.
+    uint16_t mShrinkWrap:1; // stores the COMPUTE_SIZE_SHRINK_WRAP ctor flag
   } mFlags;
 
   // Logical and physical accessors for the resize flags. All users should go
   // via these accessors, so that in due course we can change the storage from
   // physical to logical.
   bool IsHResize() const {
     return mFlags.mIsHResize;
   }
@@ -668,17 +669,21 @@ public:
   // Values for |aFlags| passed to constructor
   enum {
     // Indicates that the parent of this reflow state is "fake" (see
     // mDummyParentReflowState in mFlags).
     DUMMY_PARENT_REFLOW_STATE = (1<<0),
 
     // Indicates that the calling function will initialize the reflow state, and
     // that the constructor should not call Init().
-    CALLER_WILL_INIT = (1<<1)
+    CALLER_WILL_INIT = (1<<1),
+
+    // The caller wants shrink-wrap behavior (i.e. ComputeSizeFlags::eShrinkWrap
+    // will be passed to ComputeSize()).
+    COMPUTE_SIZE_SHRINK_WRAP = (1<<2),
   };
 
   // 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);