Bug 1257688 part 1: Change "-webkit-box-pack" & "-webkit-box-align" to alias their -moz equivalents, & change nsFlexContainerFrame to respect them in a -webkit-box. r=mats
authorDaniel Holbert <dholbert@cs.stanford.edu>
Mon, 04 Apr 2016 18:32:12 -0700
changeset 347715 a9a79edf76f0d5171ec095f2b2d3156c2609fd0e
parent 347714 5d3bd2e9a019c867294bdab5a31817d4de1287f3
child 347716 bd3daa360f1b95d56bc6422f9b02f0497df99805
push id14653
push userolivier@olivieryiptong.com
push dateTue, 05 Apr 2016 19:21:01 +0000
reviewersmats
bugs1257688
milestone48.0a1
Bug 1257688 part 1: Change "-webkit-box-pack" & "-webkit-box-align" to alias their -moz equivalents, & change nsFlexContainerFrame to respect them in a -webkit-box. r=mats MozReview-Commit-ID: HtwVbtaVf8v
layout/generic/nsFlexContainerFrame.cpp
layout/style/nsCSSPropAliasList.h
layout/style/test/property_database.js
--- a/layout/generic/nsFlexContainerFrame.cpp
+++ b/layout/generic/nsFlexContainerFrame.cpp
@@ -111,16 +111,61 @@ IsLegacyBox(const nsStyleDisplay* aStyle
     if (IsDisplayValueLegacyBox(parentStyleContext->StyleDisplay())) {
       return true;
     }
   }
 
   return false;
 }
 
+// Returns the "align-items" value that's equivalent to the legacy "box-align"
+// value in the given style struct.
+static uint8_t
+ConvertLegacyStyleToAlignItems(const nsStyleXUL* aStyleXUL)
+{
+  // -[moz|webkit]-box-align corresponds to modern "align-items"
+  switch (aStyleXUL->mBoxAlign) {
+    case NS_STYLE_BOX_ALIGN_STRETCH:
+      return NS_STYLE_ALIGN_STRETCH;
+    case NS_STYLE_BOX_ALIGN_START:
+      return NS_STYLE_ALIGN_FLEX_START;
+    case NS_STYLE_BOX_ALIGN_CENTER:
+      return NS_STYLE_ALIGN_CENTER;
+    case NS_STYLE_BOX_ALIGN_BASELINE:
+      return NS_STYLE_ALIGN_BASELINE;
+    case NS_STYLE_BOX_ALIGN_END:
+      return NS_STYLE_ALIGN_FLEX_END;
+  }
+
+  MOZ_ASSERT_UNREACHABLE("Unrecognized mBoxAlign enum value");
+  // Fall back to default value of "align-items" property:
+  return NS_STYLE_ALIGN_STRETCH;
+}
+
+// Returns the "justify-content" value that's equivalent to the legacy
+// "box-pack" value in the given style struct.
+static uint8_t
+ConvertLegacyStyleToJustifyContent(const nsStyleXUL* aStyleXUL)
+{
+  // -[moz|webkit]-box-pack corresponds to modern "justify-content"
+  switch (aStyleXUL->mBoxPack) {
+    case NS_STYLE_BOX_PACK_START:
+      return NS_STYLE_ALIGN_FLEX_START;
+    case NS_STYLE_BOX_PACK_CENTER:
+      return NS_STYLE_ALIGN_CENTER;
+    case NS_STYLE_BOX_PACK_END:
+      return NS_STYLE_ALIGN_FLEX_END;
+    case NS_STYLE_BOX_PACK_JUSTIFY:
+      return NS_STYLE_ALIGN_SPACE_BETWEEN;
+  }
+
+  MOZ_ASSERT_UNREACHABLE("Unrecognized mBoxPack enum value");
+  // Fall back to default value of "justify-content" property:
+  return NS_STYLE_ALIGN_FLEX_START;
+}
 
 // Indicates whether advancing along the given axis is equivalent to
 // increasing our X or Y position (as opposed to decreasing it).
 static inline bool
 AxisGrowsInPositiveDirection(AxisOrientationType aAxis)
 {
   return eAxis_LR == aAxis || eAxis_TB == aAxis;
 }
@@ -1603,25 +1648,39 @@ FlexItem::FlexItem(nsHTMLReflowState& aF
     // mAlignSelf, see below
 {
   MOZ_ASSERT(mFrame, "expecting a non-null child frame");
   MOZ_ASSERT(mFrame->GetType() != nsGkAtoms::placeholderFrame,
              "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");
 
-  mAlignSelf = aFlexItemReflowState.mStylePosition->ComputedAlignSelf(
-                 mFrame->StyleContext()->GetParent());
-  if (MOZ_LIKELY(mAlignSelf == NS_STYLE_ALIGN_NORMAL)) {
-    mAlignSelf = NS_STYLE_ALIGN_STRETCH;
+  const nsHTMLReflowState* containerRS = aFlexItemReflowState.parentReflowState;
+  if (IsLegacyBox(containerRS->mStyleDisplay,
+                  containerRS->frame->StyleContext())) {
+    // For -webkit-box/-webkit-inline-box, we need to:
+    // (1) Use "-webkit-box-align" instead of "align-items" to determine the
+    //     container's cross-axis alignment behavior.
+    // (2) Suppress the ability for flex items to override that with their own
+    //     cross-axis alignment. (The legacy box model doesn't support this.)
+    // So, each FlexItem simply copies the container's converted "align-items"
+    // value and disregards their own "align-self" property.
+    const nsStyleXUL* containerStyleXUL = containerRS->frame->StyleXUL();
+    mAlignSelf = ConvertLegacyStyleToAlignItems(containerStyleXUL);
+  } else {
+    mAlignSelf = aFlexItemReflowState.mStylePosition->ComputedAlignSelf(
+                   mFrame->StyleContext()->GetParent());
+    if (MOZ_LIKELY(mAlignSelf == NS_STYLE_ALIGN_NORMAL)) {
+      mAlignSelf = NS_STYLE_ALIGN_STRETCH;
+    }
+
+    // XXX strip off the <overflow-position> bit until we implement that
+    mAlignSelf &= ~NS_STYLE_ALIGN_FLAG_BITS;
   }
 
-  // XXX strip off the <overflow-position> bit until we implement that
-  mAlignSelf &= ~NS_STYLE_ALIGN_FLAG_BITS;
-
   SetFlexBaseSizeAndMainSize(aFlexBaseSize);
   CheckForMinSizeAuto(aFlexItemReflowState, aAxisTracker);
 
   // 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 =
@@ -3816,21 +3875,24 @@ nsFlexContainerFrame::DoFlexLayout(nsPre
     } else  {
       flexContainerAscent =
         ComputePhysicalAscentFromFlexRelativeAscent(
           crossAxisPosnTracker.GetPosition() + firstLineBaselineOffset,
           contentBoxCrossSize, aReflowState, aAxisTracker);
     }
   }
 
+  const auto justifyContent = IsLegacyBox(aReflowState.mStyleDisplay,
+                                          mStyleContext) ?
+    ConvertLegacyStyleToJustifyContent(StyleXUL()) :
+    aReflowState.mStylePosition->ComputedJustifyContent();
+
   for (FlexLine* line = lines.getFirst(); line; line = line->getNext()) {
-
     // Main-Axis Alignment - Flexbox spec section 9.5
     // ==============================================
-    auto justifyContent = aReflowState.mStylePosition->ComputedJustifyContent();
     line->PositionItemsInMainAxis(justifyContent,
                                   aContentBoxMainSize,
                                   aAxisTracker);
 
     // Cross-Axis Alignment - Flexbox spec section 9.6
     // ===============================================
     line->PositionItemsInCrossAxis(crossAxisPosnTracker.GetPosition(),
                                    aAxisTracker);
--- a/layout/style/nsCSSPropAliasList.h
+++ b/layout/style/nsCSSPropAliasList.h
@@ -318,31 +318,37 @@ CSS_PROP_ALIAS(-webkit-box-shadow,
                box_shadow,
                WebkitBoxShadow,
                WEBKIT_PREFIX_PREF)
 CSS_PROP_ALIAS(-webkit-box-sizing,
                box_sizing,
                WebkitBoxSizing,
                WEBKIT_PREFIX_PREF)
 
-// Alias old flexbox properties to modern flexbox pseudo-equivalents:
+// Alias -webkit-box properties to their -moz-box equivalents.
+// (NOTE: Even though they're aliases, in practice these -webkit properties
+// will behave a bit differently from their -moz versions, if they're
+// accompanied by "display:-webkit-box", because we generate a different frame
+// for those two display values.)
+// XXXdholbert Not all of these are converted yet, but they will be by the
+// end of this patch stack.
 CSS_PROP_ALIAS(-webkit-box-flex,
                flex_grow,
                WebkitBoxFlex,
                WEBKIT_PREFIX_PREF)
 CSS_PROP_ALIAS(-webkit-box-ordinal-group,
                order,
                WebkitBoxOrdinalGroup,
                WEBKIT_PREFIX_PREF)
 CSS_PROP_ALIAS(-webkit-box-align,
-               align_items,
+               box_align,
                WebkitBoxAlign,
                WEBKIT_PREFIX_PREF)
 CSS_PROP_ALIAS(-webkit-box-pack,
-               justify_content,
+               box_pack,
                WebkitBoxPack,
                WEBKIT_PREFIX_PREF)
 
 CSS_PROP_ALIAS(-webkit-user-select,
                user_select,
                WebkitUserSelect,
                WEBKIT_PREFIX_PREF)
 
--- a/layout/style/test/property_database.js
+++ b/layout/style/test/property_database.js
@@ -7219,25 +7219,25 @@ if (IsCSSPropertyPrefEnabled("layout.css
       /* Flex-direction values: */
       "row", "column", "row-reverse", "column-reverse",
     ],
   };
   gCSSProperties["-webkit-box-align"] = {
     domProp: "webkitBoxAlign",
     inherited: false,
     type: CSS_TYPE_SHORTHAND_AND_LONGHAND,
-    alias_for: "align-items",
-    subproperties: [ "align-items" ],
+    alias_for: "-moz-box-align",
+    subproperties: [ "-moz-box-align" ],
   };
   gCSSProperties["-webkit-box-pack"] = {
     domProp: "webkitBoxPack",
     inherited: false,
     type: CSS_TYPE_SHORTHAND_AND_LONGHAND,
-    alias_for: "justify-content",
-    subproperties: [ "justify-content" ],
+    alias_for: "-moz-box-pack",
+    subproperties: [ "-moz-box-pack" ],
   };
   gCSSProperties["-webkit-user-select"] = {
     domProp: "webkitUserSelect",
     inherited: false,
     type: CSS_TYPE_SHORTHAND_AND_LONGHAND,
     alias_for: "-moz-user-select",
     subproperties: [ "-moz-user-select" ],
   };