Bug 1627125 Part 1 - Allow ReflowFlexItem to take available size as an input, and output reflow status. r=dholbert
authorTing-Yu Lin <tlin@mozilla.com>
Thu, 16 Apr 2020 05:37:45 +0000
changeset 524469 36907dee3e51d41337bc7d4e7dc27c28178dfdfe
parent 524468 ffa15679931a65e6975408b75828778b1519179d
child 524470 a8e29df7db26ff1b8c7f0dfca8e944e0bfaf4ad9
push id37321
push userdluca@mozilla.com
push dateFri, 17 Apr 2020 09:38:52 +0000
treeherdermozilla-central@24537fed53e6 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdholbert
bugs1627125
milestone77.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 1627125 Part 1 - Allow ReflowFlexItem to take available size as an input, and output reflow status. r=dholbert Differential Revision: https://phabricator.services.mozilla.com/D69469
layout/generic/ReflowInput.h
layout/generic/nsFlexContainerFrame.cpp
layout/generic/nsFlexContainerFrame.h
--- a/layout/generic/ReflowInput.h
+++ b/layout/generic/ReflowInput.h
@@ -753,35 +753,37 @@ struct ReflowInput : public SizeComputat
   // call Init as desired...
 
   /**
    * Initialize a ROOT reflow input.
    *
    * @param aPresContext Must be equal to aFrame->PresContext().
    * @param aFrame The frame for whose reflow input is being constructed.
    * @param aRenderingContext The rendering context to be used for measurements.
-   * @param aAvailableSpace See comments for availableHeight and availableWidth
-   *        members.
+   * @param aAvailableSpace The available space to reflow aFrame (in aFrame's
+   *        writing-mode). See comments for mAvailableHeight and mAvailableWidth
+   *        members for more information.
    * @param aFlags A set of flags used for additional boolean parameters (see
    *        below).
    */
   ReflowInput(nsPresContext* aPresContext, nsIFrame* aFrame,
               gfxContext* aRenderingContext,
               const mozilla::LogicalSize& aAvailableSpace, uint32_t aFlags = 0);
 
   /**
    * Initialize a reflow input for a child frame's reflow. Some parts of the
    * state are copied from the parent's reflow input. The remainder is computed.
    *
    * @param aPresContext Must be equal to aFrame->PresContext().
    * @param aParentReflowInput A reference to an ReflowInput object that
    *        is to be the parent of this object.
    * @param aFrame The frame for whose reflow input is being constructed.
-   * @param aAvailableSpace See comments for availableHeight and availableWidth
-   *        members.
+   * @param aAvailableSpace The available space to reflow aFrame (in aFrame's
+   *        writing-mode). See comments for mAvailableHeight and mAvailableWidth
+   *        members for more information.
    * @param aContainingBlockSize An optional size, in app units, specifying
    *        the containing block size to use instead of the default which is
    *        computed by ComputeContainingBlockRectangle().
    * @param aFlags A set of flags used for additional boolean parameters (see
    *        below).
    */
   ReflowInput(nsPresContext* aPresContext,
               const ReflowInput& aParentReflowInput, nsIFrame* aFrame,
--- a/layout/generic/nsFlexContainerFrame.cpp
+++ b/layout/generic/nsFlexContainerFrame.cpp
@@ -4851,18 +4851,35 @@ void nsFlexContainerFrame::ReflowChildre
       // maybe use for setting the flex container's baseline.)
       const nscoord itemNormalBPos = framePos.B(flexWM);
 
       // Check if we actually need to reflow the item -- if we already reflowed
       // it with the right content-box size, and there is no need to do a reflow
       // to clear out a -webkit-line-clamp ellipsis, we can just reposition it
       // as-needed.
       if (item.NeedsFinalReflow()) {
-        ReflowFlexItem(aAxisTracker, aReflowInput, item, framePos,
-                       containerSize, aHasLineClampEllipsis);
+        // The available size must be in item's writing-mode.
+        const WritingMode itemWM = item.GetWritingMode();
+        LogicalSize availableSize = aReflowInput.ComputedSize(itemWM);
+
+        // XXX: Unconditionally give our children unconstrained block-size until
+        // we support flex item fragmentation.
+        availableSize.BSize(itemWM) = NS_UNCONSTRAINEDSIZE;
+
+        const nsReflowStatus childReflowStatus =
+            ReflowFlexItem(aAxisTracker, aReflowInput, item, framePos,
+                           availableSize, containerSize, aHasLineClampEllipsis);
+
+        // XXXdholbert Once we do pagination / splitting, we'll need to actually
+        // handle incomplete childReflowStatuses. But for now, we give our kids
+        // unconstrained available height, which means they should always
+        // complete.
+        MOZ_ASSERT(childReflowStatus.IsComplete(),
+                   "We gave flex item unconstrained available height, so it "
+                   "should be complete");
       } else {
         MoveFlexItemToFinalPosition(aReflowInput, item, framePos,
                                     containerSize);
         // We didn't perform a final reflow of the item. If we still have a
         // -webkit-line-clamp ellipsis hanging around, but we shouldn't have
         // one any more, we need to clear that now.  Technically, we only need
         // to do this if we *didn't* do a bsize measuring reflow of the item
         // earlier (since that is normally when we deal with -webkit-line-clamp
@@ -5021,26 +5038,24 @@ void nsFlexContainerFrame::MoveFlexItemT
   }
   ReflowInput::ApplyRelativePositioning(aItem.Frame(), outerWM, logicalOffsets,
                                         &aFramePos, aContainerSize);
   aItem.Frame()->SetPosition(outerWM, aFramePos, aContainerSize);
   PositionFrameView(aItem.Frame());
   PositionChildViews(aItem.Frame());
 }
 
-void nsFlexContainerFrame::ReflowFlexItem(
+nsReflowStatus nsFlexContainerFrame::ReflowFlexItem(
     const FlexboxAxisTracker& aAxisTracker, const ReflowInput& aReflowInput,
     const FlexItem& aItem, LogicalPoint& aFramePos,
-    const nsSize& aContainerSize, bool aHasLineClampEllipsis) {
+    const LogicalSize& aAvailableSize, const nsSize& aContainerSize,
+    bool aHasLineClampEllipsis) {
   WritingMode outerWM = aReflowInput.GetWritingMode();
-  WritingMode wm = aItem.Frame()->GetWritingMode();
-  LogicalSize availSize = aReflowInput.ComputedSize(wm);
-  availSize.BSize(wm) = NS_UNCONSTRAINEDSIZE;
   ReflowInput childReflowInput(PresContext(), aReflowInput, aItem.Frame(),
-                               availSize);
+                               aAvailableSize);
   childReflowInput.mFlags.mInsideLineClamp = GetLineClampValue() != 0;
   // This is the final reflow of this flex item; if we previously had a
   // -webkit-line-clamp, and we missed our chance to clear the ellipsis
   // because we didn't need to call MeasureFlexItemContentBSize, we set
   // mApplyLineClamp to cause it to get cleared here.
   childReflowInput.mFlags.mApplyLineClamp =
       !childReflowInput.mFlags.mInsideLineClamp && aHasLineClampEllipsis;
 
@@ -5119,29 +5134,23 @@ void nsFlexContainerFrame::ReflowFlexIte
   ReflowOutput childReflowOutput(childReflowInput);
   nsReflowStatus childReflowStatus;
   ReflowChild(aItem.Frame(), PresContext(), childReflowOutput, childReflowInput,
               outerWM, aFramePos, aContainerSize, ReflowChildFlags::Default,
               childReflowStatus);
 
   // XXXdholbert Perhaps we should call CheckForInterrupt here; see bug 1495532.
 
-  // XXXdholbert Once we do pagination / splitting, we'll need to actually
-  // handle incomplete childReflowStatuses. But for now, we give our kids
-  // unconstrained available height, which means they should always
-  // complete.
-  MOZ_ASSERT(childReflowStatus.IsComplete(),
-             "We gave flex item unconstrained available height, so it "
-             "should be complete");
-
   FinishReflowChild(aItem.Frame(), PresContext(), childReflowOutput,
                     &childReflowInput, outerWM, aFramePos, aContainerSize,
                     ReflowChildFlags::ApplyRelativePositioning);
 
   aItem.SetAscent(childReflowOutput.BlockStartAscent());
+
+  return childReflowStatus;
 }
 
 void nsFlexContainerFrame::ReflowPlaceholders(
     const ReflowInput& aReflowInput, nsTArray<nsIFrame*>& aPlaceholders,
     const LogicalPoint& aContentBoxOrigin, const nsSize& aContainerSize) {
   WritingMode outerWM = aReflowInput.GetWritingMode();
 
   // As noted in this method's documentation, we'll reflow every entry in
--- a/layout/generic/nsFlexContainerFrame.h
+++ b/layout/generic/nsFlexContainerFrame.h
@@ -497,23 +497,29 @@ class nsFlexContainerFrame final : publi
    * Helper-function to reflow a child frame, at its final position determined
    * by flex layout.
    *
    * @param aAxisTracker    A FlexboxAxisTracker with the flex container's axes.
    * @param aReflowInput    The flex container's reflow input.
    * @param aItem           The flex item to be reflowed.
    * @param aFramePos       The position where the flex item's frame should
    *                        be placed. (pre-relative positioning)
+   * @param aAvailableSize  The available size to reflow the child frame (in the
+   *                        child frame's writing-mode).
    * @param aContainerSize  The flex container's size (required by some methods
    *                        that we call, to interpret aFramePos correctly).
+   * @return the child frame's reflow status.
    */
-  void ReflowFlexItem(const FlexboxAxisTracker& aAxisTracker,
-                      const ReflowInput& aReflowInput, const FlexItem& aItem,
-                      mozilla::LogicalPoint& aFramePos,
-                      const nsSize& aContainerSize, bool aHasLineClampEllipsis);
+  nsReflowStatus ReflowFlexItem(const FlexboxAxisTracker& aAxisTracker,
+                                const ReflowInput& aReflowInput,
+                                const FlexItem& aItem,
+                                mozilla::LogicalPoint& aFramePos,
+                                const mozilla::LogicalSize& aAvailableSize,
+                                const nsSize& aContainerSize,
+                                bool aHasLineClampEllipsis);
 
   /**
    * Helper-function to perform a "dummy reflow" on all our nsPlaceholderFrame
    * children, at the container's content-box origin.
    *
    * This doesn't actually represent the static position of the placeholders'
    * out-of-flow (OOF) frames -- we can't compute that until we've reflowed the
    * OOF, because (depending on the CSS Align properties) the static position