Bug 1312379 part 2 - [css-flexbox] Improve support for CSS Alignment 'last baseline' alignment by exporting the last baseline when asked for. r=dholbert a=cbook
☠☠ backed out by 321139b54a82 ☠ ☠
authorMats Palmgren <mats@mozilla.com>
Thu, 22 Dec 2016 16:08:42 +0100
changeset 455689 2973e5aa9d5cf9e6e147aea4cec33a2a80a5f124
parent 455688 b4f1387cf20b8817ef2fac7014deb77d16d8ab79
child 455690 e341f4fa167cae19c0a81660f6ffae628061c519
push id40304
push userbmo:wpan@mozilla.com
push dateWed, 04 Jan 2017 10:03:07 +0000
reviewersdholbert, cbook
bugs1312379
milestone52.0a2
Bug 1312379 part 2 - [css-flexbox] Improve support for CSS Alignment 'last baseline' alignment by exporting the last baseline when asked for. r=dholbert a=cbook
layout/generic/nsFlexContainerFrame.cpp
layout/generic/nsFlexContainerFrame.h
--- a/layout/generic/nsFlexContainerFrame.cpp
+++ b/layout/generic/nsFlexContainerFrame.cpp
@@ -4520,19 +4520,16 @@ nsFlexContainerFrame::DoFlexLayout(nsPre
     // synthesize a margin-box baseline.
     aDesiredSize.SetBlockStartAscent(ReflowOutput::ASK_FOR_BASELINE);
   } else {
     // XXXdholbert flexContainerAscent needs to be in terms of
     // our parent's writing-mode here. See bug 1155322.
     aDesiredSize.SetBlockStartAscent(flexContainerAscent);
   }
 
-  // Cache this baseline for use outside of this call.
-  mBaselineFromLastReflow = flexContainerAscent;
-
   // Now: If we're complete, add bottom border/padding to desired height (which
   // we skipped via skipSides) -- unless that pushes us over available height,
   // in which case we become incomplete (unless we already weren't asking for
   // any height, in which case we stay complete to avoid looping forever).
   // NOTE: If we're auto-height, we allow our bottom border/padding to push us
   // over the available height without requesting a continuation, for
   // consistency with the behavior of "display:block" elements.
   if (NS_FRAME_IS_COMPLETE(aStatus)) {
@@ -4546,16 +4543,26 @@ nsFlexContainerFrame::DoFlexLayout(nsPre
       // Update desired height to include block-end border/padding
       desiredSizeInFlexWM.BSize(flexWM) = desiredBSizeWithBEndBP;
     } else {
       // We couldn't fit bottom border/padding, so we'll need a continuation.
       NS_FRAME_SET_INCOMPLETE(aStatus);
     }
   }
 
+  // Calculate the container baselines so that our parent can baseline-align us.
+  mBaselineFromLastReflow = flexContainerAscent;
+  mLastBaselineFromLastReflow = lines.getLast()->GetLastBaselineOffset();
+  if (mLastBaselineFromLastReflow == nscoord_MIN) {
+    // XXX we fall back to a mirrored first baseline here for now, but this
+    // should probably use the last baseline of the last item or something.
+    mLastBaselineFromLastReflow =
+      desiredSizeInFlexWM.BSize(flexWM) - flexContainerAscent;
+  }
+
   // Convert flex container's final desired size to parent's WM, for outparam.
   aDesiredSize.SetSize(flexWM, desiredSizeInFlexWM);
 
   // Overflow area = union(my overflow area, kids' overflow areas)
   aDesiredSize.SetOverflowAreasToDesiredBounds();
   for (nsIFrame* childFrame : mFrames) {
     ConsiderChildOverflow(aDesiredSize.mOverflowAreas, childFrame);
   }
--- a/layout/generic/nsFlexContainerFrame.h
+++ b/layout/generic/nsFlexContainerFrame.h
@@ -87,17 +87,18 @@ public:
 
   bool GetNaturalBaselineBOffset(mozilla::WritingMode aWM,
                                  BaselineSharingGroup aBaselineGroup,
                                  nscoord*             aBaseline) const override
   {
     if (HasAnyStateBits(NS_STATE_FLEX_SYNTHESIZE_BASELINE)) {
       return false;
     }
-    *aBaseline = GetLogicalBaseline(aWM);
+    *aBaseline = aBaselineGroup == BaselineSharingGroup::eFirst ?
+                   mBaselineFromLastReflow : mLastBaselineFromLastReflow;
     return true;
   }
 
   // nsContainerFrame overrides
   uint16_t CSSAlignmentForAbsPosChild(
             const ReflowInput& aChildRI,
             mozilla::LogicalAxis aLogicalAxis) const override;
 
@@ -130,16 +131,17 @@ public:
    */
   static bool IsLegacyBox(const nsIFrame* aFrame);
 
 protected:
   // Protected constructor & destructor
   explicit nsFlexContainerFrame(nsStyleContext* aContext)
     : nsContainerFrame(aContext)
     , mBaselineFromLastReflow(NS_INTRINSIC_WIDTH_UNKNOWN)
+    , mLastBaselineFromLastReflow(NS_INTRINSIC_WIDTH_UNKNOWN)
   {}
   virtual ~nsFlexContainerFrame();
 
   /*
    * This method does the bulk of the flex layout, implementing the algorithm
    * described at:
    *   http://dev.w3.org/csswg/css-flexbox/#layout-algorithm
    * (with a few initialization pieces happening in the caller, Reflow().
@@ -315,11 +317,13 @@ protected:
                           nsTArray<nsIFrame*>& aPlaceholders,
                           const mozilla::LogicalPoint& aContentBoxOrigin,
                           const nsSize& aContainerSize);
 
   bool mChildrenHaveBeenReordered; // Have we ever had to reorder our kids
                                    // to satisfy their 'order' values?
 
   nscoord mBaselineFromLastReflow;
+  // Note: the last baseline is a distance from our border-box end edge.
+  nscoord mLastBaselineFromLastReflow;
 };
 
 #endif /* nsFlexContainerFrame_h___ */