Bug 1298008 Part 2: Make nsFlexContainer update UsedMargin property after final reflow. r=dholbert
☠☠ backed out by 0f2d2c86412c ☠ ☠
authorBrad Werth <bwerth@mozilla.com>
Thu, 08 Mar 2018 17:35:47 -0800
changeset 410791 b5a4113f4649687c0ccc53d793263dd61a79c010
parent 410790 40f53976a5b8adce2955c72ca952898271c69297
child 410792 c18e2aac48a5fa8c4c4af9d245249afc2527181a
push id33739
push usernbeleuzu@mozilla.com
push dateFri, 30 Mar 2018 21:47:45 +0000
treeherdermozilla-central@10c662d8416e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdholbert
bugs1298008
milestone61.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 1298008 Part 2: Make nsFlexContainer update UsedMargin property after final reflow. r=dholbert MozReview-Commit-ID: HV4uhJqWjfj
layout/generic/nsFlexContainerFrame.cpp
--- a/layout/generic/nsFlexContainerFrame.cpp
+++ b/layout/generic/nsFlexContainerFrame.cpp
@@ -548,16 +548,19 @@ public:
   // cross axis).
   bool IsStretched() const         { return mIsStretched; }
 
   // Indicates whether we need to resolve an 'auto' value for the main-axis
   // min-[width|height] property.
   bool NeedsMinSizeAutoResolution() const
     { return mNeedsMinSizeAutoResolution; }
 
+  bool HasAnyAutoMargin() const
+    { return mHasAnyAutoMargin; }
+
   // Indicates whether this item is a "strut" left behind by an element with
   // visibility:collapse.
   bool IsStrut() const             { return mIsStrut; }
 
   // IsInlineAxisMainAxis() returns true if this item's inline axis is parallel
   // (or antiparallel) to the container's main axis. Otherwise (i.e. if this
   // item's inline axis is orthogonal to the container's main axis), this
   // function returns false. The next 3 methods are all other ways of asking
@@ -853,16 +856,19 @@ protected:
   bool mIsStretched; // See IsStretched() documentation
   bool mIsStrut;     // Is this item a "strut" left behind by an element
                      // with visibility:collapse?
   const bool mIsInlineAxisMainAxis; // See IsInlineAxisMainAxis() documentation
 
   // Does this item need to resolve a min-[width|height]:auto (in main-axis).
   bool mNeedsMinSizeAutoResolution;
 
+  // Does this item have an auto margin in either main or cross axis?
+  bool mHasAnyAutoMargin;
+
   uint8_t mAlignSelf; // My "align-self" computed value (with "auto"
                       // swapped out for parent"s "align-items" value,
                       // in our constructor).
 };
 
 /**
  * Represents a single flex line in a flex container.
  * Manages a linked list of the FlexItems that are in the line.
@@ -1811,17 +1817,17 @@ FlexItem::FlexItem(ReflowInput& aFlexIte
     mHadMinViolation(false),
     mHadMaxViolation(false),
     mHadMeasuringReflow(false),
     mIsStretched(false),
     mIsStrut(false),
     mIsInlineAxisMainAxis(aAxisTracker.IsRowOriented() !=
                           aAxisTracker.GetWritingMode().IsOrthogonalTo(mWM))
     // mNeedsMinSizeAutoResolution is initialized in CheckForMinSizeAuto()
-    // mAlignSelf, see below
+    // mAlignSelf, mHasAnyAutoMargin see below
 {
   MOZ_ASSERT(mFrame, "expecting a non-null child frame");
   MOZ_ASSERT(!mFrame->IsPlaceholderFrame(),
              "placeholder frames should not be treated as flex items");
   MOZ_ASSERT(!(mFrame->GetStateBits() & NS_FRAME_OUT_OF_FLOW),
              "out-of-flow frames should not be treated as flex items");
   MOZ_ASSERT(mIsInlineAxisMainAxis ==
              nsFlexContainerFrame::IsItemInlineAxisMainAxis(mFrame),
@@ -1848,22 +1854,26 @@ FlexItem::FlexItem(ReflowInput& aFlexIte
 
     // XXX strip off the <overflow-position> bit until we implement that
     mAlignSelf &= ~NS_STYLE_ALIGN_FLAG_BITS;
   }
 
   SetFlexBaseSizeAndMainSize(aFlexBaseSize);
   CheckForMinSizeAuto(aFlexItemReflowInput, aAxisTracker);
 
+
+  const nsStyleSides& styleMargin =
+    aFlexItemReflowInput.mStyleMargin->mMargin;
+  mHasAnyAutoMargin = styleMargin.HasInlineAxisAuto(mWM) ||
+                      styleMargin.HasBlockAxisAuto(mWM);
+
   // Assert that any "auto" margin components are set to 0.
   // (We'll resolve them later; until then, we want to treat them as 0-sized.)
 #ifdef DEBUG
   {
-    const nsStyleSides& styleMargin =
-      aFlexItemReflowInput.mStyleMargin->mMargin;
     NS_FOR_CSS_SIDES(side) {
       if (styleMargin.GetUnit(side) == eStyleUnit_Auto) {
         MOZ_ASSERT(GetMarginComponentForSide(side) == 0,
                    "Someone else tried to resolve our auto margin");
       }
     }
   }
 #endif // DEBUG
@@ -1914,16 +1924,17 @@ FlexItem::FlexItem(nsIFrame* aChildFrame
     mIsFrozen(true),
     mHadMinViolation(false),
     mHadMaxViolation(false),
     mHadMeasuringReflow(false),
     mIsStretched(false),
     mIsStrut(true), // (this is the constructor for making struts, after all)
     mIsInlineAxisMainAxis(true), // (doesn't matter b/c we're not doing layout)
     mNeedsMinSizeAutoResolution(false),
+    mHasAnyAutoMargin(false),
     mAlignSelf(NS_STYLE_ALIGN_FLEX_START)
 {
   MOZ_ASSERT(mFrame, "expecting a non-null child frame");
   MOZ_ASSERT(NS_STYLE_VISIBILITY_COLLAPSE ==
              mFrame->StyleVisibility()->mVisible,
              "Should only make struts for children with 'visibility:collapse'");
   MOZ_ASSERT(!mFrame->IsPlaceholderFrame(),
              "placeholder frames should not be treated as flex items");
@@ -4750,16 +4761,26 @@ nsFlexContainerFrame::DoFlexLayout(nsPre
           }
         }
       }
       if (itemNeedsReflow) {
         ReflowFlexItem(aPresContext, aAxisTracker, aReflowInput,
                        *item, framePos, containerSize);
       }
 
+      // If the item has auto margins, and we were tracking the UsedMargin
+      // property, set the property to the computed margin values.
+      if (item->HasAnyAutoMargin()) {
+        nsMargin* propValue =
+          item->Frame()->GetProperty(nsIFrame::UsedMarginProperty());
+        if (propValue) {
+          *propValue = item->GetMargin();
+        }
+      }
+
       // If this is our first item and we haven't established a baseline for
       // the container yet (i.e. if we don't have 'align-self: baseline' on any
       // children), then use this child's first baseline as the container's
       // baseline.
       if (item == firstItem &&
           flexContainerAscent == nscoord_MIN) {
         flexContainerAscent = itemNormalBPos + item->ResolvedAscent(true);
       }
@@ -4950,20 +4971,16 @@ nsFlexContainerFrame::ReflowFlexItem(nsP
     // the changes in bug 851607. So this has no effect right now, but it might
     // make a difference if we optimize to use dirty bits in the
     // future. (Reftests flexbox-resizeviewport-1.xhtml and -2.xhtml are
     // intended to catch any regressions here, if we end up relying on this bit
     // & neglecting to set it.)
     aItem.Frame()->AddStateBits(NS_FRAME_CONTAINS_RELATIVE_BSIZE);
   }
 
-  // XXXdholbert Might need to actually set the correct margins in the
-  // reflow state at some point, so that they can be saved on the frame for
-  // UsedMarginProperty().  Maybe doesn't matter though...?
-
   // If we're overriding the computed width or height, *and* we had an
   // earlier "measuring" reflow, then this upcoming reflow needs to be
   // treated as a resize.
   if (aItem.HadMeasuringReflow()) {
     if (didOverrideComputedISize) {
       // (This is somewhat redundant, since ReflowInput::InitResizeFlags()
       // already calls SetIResize() whenever our computed ISize has changed
       // since the previous reflow. Still, it's nice for symmetry, and it might