Bug 1235922 Part 2: Add support for "justify-content: space-evenly" to flexbox layout. r?mats draft
authorDaniel Holbert <dholbert@cs.stanford.edu>
Fri, 14 Oct 2016 17:16:00 -0700
changeset 425668 dc741993cc3934d290adaee0ab07c15ff533ef10
parent 425667 faf5bd6eea515459fe37fb9bffbf93e3249e127c
child 425669 58c7416117bb678faa52de13b7c716eed81e2bff
push id32490
push userbwerth@mozilla.com
push dateSat, 15 Oct 2016 19:31:46 +0000
reviewersmats
bugs1235922
milestone52.0a1
Bug 1235922 Part 2: Add support for "justify-content: space-evenly" to flexbox layout. r?mats MozReview-Commit-ID: 6Am15EIVAXH
layout/generic/nsFlexContainerFrame.cpp
layout/generic/nsFlexContainerFrame.h
--- a/layout/generic/nsFlexContainerFrame.cpp
+++ b/layout/generic/nsFlexContainerFrame.cpp
@@ -2600,23 +2600,25 @@ MainAxisPositionTracker::
     mNumAutoMarginsInMainAxis += item->GetNumAutoMarginsInAxis(mAxis);
   }
 
   if (mPackingSpaceRemaining <= 0) {
     // No available packing space to use for resolving auto margins.
     mNumAutoMarginsInMainAxis = 0;
   }
 
-  // If packing space is negative, 'space-between' behaves like 'flex-start',
-  // and 'space-around' behaves like 'center'. In those cases, it's simplest to
-  // just pretend we have a different 'justify-content' value and share code.
+  // If packing space is negative, 'space-between' falls back to 'flex-start',
+  // and 'space-around' & 'space-evenly' fall back to 'center'. In those cases,
+  // it's simplest to just pretend we have a different 'justify-content' value
+  // and share code.
   if (mPackingSpaceRemaining < 0) {
     if (mJustifyContent == NS_STYLE_JUSTIFY_SPACE_BETWEEN) {
       mJustifyContent = NS_STYLE_JUSTIFY_FLEX_START;
-    } else if (mJustifyContent == NS_STYLE_JUSTIFY_SPACE_AROUND) {
+    } else if (mJustifyContent == NS_STYLE_JUSTIFY_SPACE_AROUND ||
+               mJustifyContent == NS_STYLE_JUSTIFY_SPACE_EVENLY) {
       mJustifyContent = NS_STYLE_JUSTIFY_CENTER;
     }
   }
 
   // Map 'left'/'right' to 'start'/'end'
   if (mJustifyContent == NS_STYLE_ALIGN_LEFT ||
       mJustifyContent == NS_STYLE_ALIGN_RIGHT) {
     if (aAxisTracker.IsColumnOriented()) {
@@ -2653,32 +2655,32 @@ MainAxisPositionTracker::
   // Figure out how much space we'll set aside for auto margins or
   // packing spaces, and advance past any leading packing-space.
   if (mNumAutoMarginsInMainAxis == 0 &&
       mPackingSpaceRemaining != 0 &&
       !aLine->IsEmpty()) {
     switch (mJustifyContent) {
       case NS_STYLE_JUSTIFY_BASELINE:
       case NS_STYLE_JUSTIFY_LAST_BASELINE:
-      case NS_STYLE_JUSTIFY_SPACE_EVENLY:
-        NS_WARNING("NYI: justify-content:left/right/baseline/last-baseline/space-evenly");
+        NS_WARNING("NYI: justify-content:left/right/baseline/last-baseline");
         MOZ_FALLTHROUGH;
       case NS_STYLE_JUSTIFY_FLEX_START:
         // All packing space should go at the end --> nothing to do here.
         break;
       case NS_STYLE_JUSTIFY_FLEX_END:
         // All packing space goes at the beginning
         mPosition += mPackingSpaceRemaining;
         break;
       case NS_STYLE_JUSTIFY_CENTER:
         // Half the packing space goes at the beginning
         mPosition += mPackingSpaceRemaining / 2;
         break;
       case NS_STYLE_JUSTIFY_SPACE_BETWEEN:
       case NS_STYLE_JUSTIFY_SPACE_AROUND:
+      case NS_STYLE_JUSTIFY_SPACE_EVENLY:
         nsFlexContainerFrame::CalculatePackingSpace(aLine->NumItems(),
                                                     mJustifyContent,
                                                     &mPosition,
                                                     &mNumPackingSpacesRemaining,
                                                     &mPackingSpaceRemaining);
         break;
       default:
         MOZ_ASSERT_UNREACHABLE("Unexpected justify-content value");
@@ -2716,19 +2718,20 @@ MainAxisPositionTracker::ResolveAutoMarg
   }
 }
 
 void
 MainAxisPositionTracker::TraversePackingSpace()
 {
   if (mNumPackingSpacesRemaining) {
     MOZ_ASSERT(mJustifyContent == NS_STYLE_JUSTIFY_SPACE_BETWEEN ||
-               mJustifyContent == NS_STYLE_JUSTIFY_SPACE_AROUND,
+               mJustifyContent == NS_STYLE_JUSTIFY_SPACE_AROUND ||
+               mJustifyContent == NS_STYLE_JUSTIFY_SPACE_EVENLY,
                "mNumPackingSpacesRemaining only applies for "
-               "space-between/space-around");
+               "space-between/space-around/space-evenly");
 
     MOZ_ASSERT(mPackingSpaceRemaining >= 0,
                "ran out of packing space earlier than we expected");
 
     // NOTE: This integer math will skew the distribution of remainder
     // app-units towards the end, which is fine.
     nscoord curPackingSpace =
       mPackingSpaceRemaining / mNumPackingSpacesRemaining;
@@ -3971,41 +3974,44 @@ private:
 void
 nsFlexContainerFrame::CalculatePackingSpace(uint32_t aNumThingsToPack,
                                             uint8_t aAlignVal,
                                             nscoord* aFirstSubjectOffset,
                                             uint32_t* aNumPackingSpacesRemaining,
                                             nscoord* aPackingSpaceRemaining)
 {
   MOZ_ASSERT(NS_STYLE_ALIGN_SPACE_BETWEEN == NS_STYLE_JUSTIFY_SPACE_BETWEEN &&
-             NS_STYLE_ALIGN_SPACE_AROUND == NS_STYLE_JUSTIFY_SPACE_AROUND,
+             NS_STYLE_ALIGN_SPACE_AROUND == NS_STYLE_JUSTIFY_SPACE_AROUND &&
+             NS_STYLE_ALIGN_SPACE_EVENLY == NS_STYLE_JUSTIFY_SPACE_EVENLY,
              "CalculatePackingSpace assumes that NS_STYLE_ALIGN_SPACE and "
              "NS_STYLE_JUSTIFY_SPACE constants are interchangeable");
 
   MOZ_ASSERT(aAlignVal == NS_STYLE_ALIGN_SPACE_BETWEEN ||
-             aAlignVal == NS_STYLE_ALIGN_SPACE_AROUND,
+             aAlignVal == NS_STYLE_ALIGN_SPACE_AROUND ||
+             aAlignVal == NS_STYLE_ALIGN_SPACE_EVENLY,
              "Unexpected alignment value");
 
   MOZ_ASSERT(*aPackingSpaceRemaining >= 0,
              "Should not be called with negative packing space");
 
   MOZ_ASSERT(aNumThingsToPack >= 1,
              "Should not be called with less than 1 thing to pack");
 
   // Packing spaces between items:
   *aNumPackingSpacesRemaining = aNumThingsToPack - 1;
 
   if (aAlignVal == NS_STYLE_ALIGN_SPACE_BETWEEN) {
     // No need to reserve space at beginning/end, so we're done.
     return;
   }
 
-  // We need to add 1 packing space, split between beginning/end, for
-  // space-around:
-  size_t numPackingSpacesForEdges = 1;
+  // We need to add 1 or 2 packing spaces, split between beginning/end, for
+  // space-around / space-evenly:
+  size_t numPackingSpacesForEdges =
+    aAlignVal == NS_STYLE_JUSTIFY_SPACE_AROUND ? 1 : 2;
 
   // How big will each "full" packing space be:
   nscoord packingSpaceSize = *aPackingSpaceRemaining /
     (*aNumPackingSpacesRemaining + numPackingSpacesForEdges);
   // How much packing-space are we allocating to the edges:
   nscoord totalEdgePackingSpace = numPackingSpacesForEdges * packingSpaceSize;
 
   // Use half of that edge packing space right now:
--- a/layout/generic/nsFlexContainerFrame.h
+++ b/layout/generic/nsFlexContainerFrame.h
@@ -80,17 +80,17 @@ public:
   nscoord GetLogicalBaseline(mozilla::WritingMode aWM) const override;
 
   // Flexbox-specific public methods
   bool IsHorizontal();
 
   /**
     * Helper function to calculate packing space and initial offset of alignment
     * subjects in MainAxisPositionTracker() and CrossAxisPositionTracker() for
-    * space-between and space-around.
+    * space-between, space-around, and space-evenly.
     *
     * @param aNumThingsToPack             Number of alignment subjects.
     * @param aAlignVal                    Value for align-self or justify-self.
     * @param aFirstSubjectOffset          Outparam for first subject offset.
     * @param aNumPackingSpacesRemaining   Outparam for number of equal-sized
     *                                     packing spaces to apply between each
     *                                     alignment subject.
     * @param aPackingSpaceRemaining       Outparam for total amount of packing