Bug 1313811 - [css-flexbox] Synthesize the flex container baseline per alignment context when needed. r=dholbert a=cbook
authorMats Palmgren <mats@mozilla.com>
Thu, 22 Dec 2016 16:08:42 +0100
changeset 353174 2148950fcfa4282a87632ebab92ae680eff58334
parent 353173 b1a830373847a28230c0554b54f3c99708eb3dca
child 353175 99babeef86597888291d0e24cabb836555a2b4e0
push id6795
push userjlund@mozilla.com
push dateMon, 23 Jan 2017 14:19:46 +0000
treeherdermozilla-esr52@76101b503191 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdholbert, cbook
bugs1313811
milestone52.0a2
Bug 1313811 - [css-flexbox] Synthesize the flex container baseline per alignment context when needed. r=dholbert a=cbook
layout/generic/nsFlexContainerFrame.cpp
layout/generic/nsFrameStateBits.h
--- a/layout/generic/nsFlexContainerFrame.cpp
+++ b/layout/generic/nsFlexContainerFrame.cpp
@@ -467,17 +467,17 @@ public:
       // or a dependency.
       // Use GetFirstLineBaseline() or GetLastLineBaseline() as appropriate,
       // or just GetLogicalBaseline() if that fails.
       bool found = aUseFirstBaseline ?
         nsLayoutUtils::GetFirstLineBaseline(mWM, mFrame, &mAscent) :
         nsLayoutUtils::GetLastLineBaseline(mWM, mFrame, &mAscent);
 
       if (!found) {
-        mAscent = mFrame->GetLogicalBaseline(mWM);
+        mAscent = mFrame->SynthesizeBaselineFromBorderBox(mWM);
       }
     }
     return mAscent;
   }
 
   // Convenience methods to compute the main & cross size of our *margin-box*.
   // The caller is responsible for telling us the right axis, so that we can
   // pull out the appropriate components of our margin/border/padding structs.
@@ -2302,16 +2302,20 @@ nsFlexContainerFrame::GetFrameName(nsASt
 #endif
 
 nscoord
 nsFlexContainerFrame::GetLogicalBaseline(mozilla::WritingMode aWM) const
 {
   NS_ASSERTION(mBaselineFromLastReflow != NS_INTRINSIC_WIDTH_UNKNOWN,
                "baseline has not been set");
 
+  if (HasAnyStateBits(NS_STATE_FLEX_SYNTHESIZE_BASELINE)) {
+    // Return a baseline synthesized from our margin-box.
+    return nsContainerFrame::GetLogicalBaseline(aWM);
+  }
   return mBaselineFromLastReflow;
 }
 
 // Helper for BuildDisplayList, to implement this special-case for flex items
 // from the spec:
 //    Flex items paint exactly the same as block-level elements in the
 //    normal flow, except that 'z-index' values other than 'auto' create
 //    a stacking context even if 'position' is 'static'.
@@ -4237,16 +4241,24 @@ nsFlexContainerFrame::DoFlexLayout(nsPre
   AutoFlexLineListClearer cleanupLines(lines);
 
   GenerateFlexLines(aPresContext, aReflowInput,
                     aContentBoxMainSize,
                     aAvailableBSizeForContent,
                     aStruts, aAxisTracker,
                     placeholderKids, lines);
 
+  if (lines.getFirst()->IsEmpty() &&
+      !lines.getFirst()->getNext()) {
+    // We have no flex items, our parent should synthesize a baseline if needed.
+    AddStateBits(NS_STATE_FLEX_SYNTHESIZE_BASELINE);
+  } else {
+    RemoveStateBits(NS_STATE_FLEX_SYNTHESIZE_BASELINE);
+  }
+
   aContentBoxMainSize =
     ResolveFlexContainerMainSize(aReflowInput, aAxisTracker,
                                  aContentBoxMainSize, aAvailableBSizeForContent,
                                  lines.getFirst(), aStatus);
 
   for (FlexLine* line = lines.getFirst(); line; line = line->getNext()) {
     line->ResolveFlexibleLengths(aContentBoxMainSize);
   }
@@ -4497,19 +4509,25 @@ nsFlexContainerFrame::DoFlexLayout(nsPre
     // Per spec, synthesize baseline from the flex container's content box
     // (i.e. use block-end side of content-box)
     // XXXdholbert This only makes sense if parent's writing mode is
     // horizontal (& even then, really we should be using the BSize in terms
     // of the parent's writing mode, not ours). Clean up in bug 1155322.
     flexContainerAscent = desiredSizeInFlexWM.BSize(flexWM);
   }
 
-  // XXXdholbert flexContainerAscent needs to be in terms of
-  // our parent's writing-mode here. See bug 1155322.
-  aDesiredSize.SetBlockStartAscent(flexContainerAscent);
+  if (HasAnyStateBits(NS_STATE_FLEX_SYNTHESIZE_BASELINE)) {
+    // This will force our parent to call GetLogicalBaseline, which will
+    // 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).
--- a/layout/generic/nsFrameStateBits.h
+++ b/layout/generic/nsFrameStateBits.h
@@ -303,17 +303,16 @@ FRAME_STATE_BIT(Box, 61, NS_FRAME_MOUSE_
 
 FRAME_STATE_GROUP(FlexContainer, nsFlexContainerFrame)
 
 // Set for a flex container whose children have been reordered due to 'order'.
 // (Means that we have to be more thorough about checking them for sortedness.)
 FRAME_STATE_BIT(FlexContainer, 20, NS_STATE_FLEX_CHILDREN_REORDERED)
 
 // True if the container has no flex items; may lie if there is a pending reflow
-// XXX not used yet...
 FRAME_STATE_BIT(FlexContainer, 22, NS_STATE_FLEX_SYNTHESIZE_BASELINE)
 
 // == Frame state bits that apply to grid container frames ====================
 
 FRAME_STATE_GROUP(GridContainer, nsGridContainerFrame)
 
 // True iff the normal flow children are already in CSS 'order' in the
 // order they occur in the child frame list.