Bug 702508 part 2: Support parsing/computing the CSS property "align-content". r=dbaron
authorDaniel Holbert <dholbert@cs.stanford.edu>
Thu, 05 Dec 2013 10:57:50 -0800
changeset 159042 2539dbed0ca8
parent 159041 8f49fff73d6e
child 159043 872e64c93fda
push id25771
push usercbook@mozilla.com
push date2013-12-06 12:30 +0000
treeherdermozilla-central@9a92e42151dc [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdbaron
bugs702508
milestone28.0a1
Bug 702508 part 2: Support parsing/computing the CSS property "align-content". r=dbaron
layout/style/nsCSSPropList.h
layout/style/nsCSSProps.cpp
layout/style/nsCSSProps.h
layout/style/nsComputedDOMStyle.cpp
layout/style/nsComputedDOMStyle.h
layout/style/nsComputedDOMStylePropertyList.h
layout/style/nsRuleNode.cpp
layout/style/nsStyleConsts.h
layout/style/nsStyleStruct.cpp
layout/style/nsStyleStruct.h
layout/style/test/property_database.js
--- a/layout/style/nsCSSPropList.h
+++ b/layout/style/nsCSSPropList.h
@@ -1594,16 +1594,26 @@ CSS_PROP_TABLEBORDER(
     EmptyCells,
     CSS_PROPERTY_PARSE_VALUE,
     "",
     VARIANT_HK,
     kEmptyCellsKTable,
     CSS_PROP_NO_OFFSET,
     eStyleAnimType_None)
 CSS_PROP_POSITION(
+    align-content,
+    align_content,
+    AlignContent,
+    CSS_PROPERTY_PARSE_VALUE,
+    "",
+    VARIANT_HK,
+    kAlignContentKTable,
+    offsetof(nsStylePosition, mAlignContent),
+    eStyleAnimType_EnumU8)
+CSS_PROP_POSITION(
     align-items,
     align_items,
     AlignItems,
     CSS_PROPERTY_PARSE_VALUE,
     "",
     VARIANT_HK,
     kAlignItemsKTable,
     offsetof(nsStylePosition, mAlignItems),
--- a/layout/style/nsCSSProps.cpp
+++ b/layout/style/nsCSSProps.cpp
@@ -968,16 +968,26 @@ const int32_t nsCSSProps::kDisplayKTable
 
 const int32_t nsCSSProps::kEmptyCellsKTable[] = {
   eCSSKeyword_show,                 NS_STYLE_TABLE_EMPTY_CELLS_SHOW,
   eCSSKeyword_hide,                 NS_STYLE_TABLE_EMPTY_CELLS_HIDE,
   eCSSKeyword__moz_show_background, NS_STYLE_TABLE_EMPTY_CELLS_SHOW_BACKGROUND,
   eCSSKeyword_UNKNOWN,-1
 };
 
+const int32_t nsCSSProps::kAlignContentKTable[] = {
+  eCSSKeyword_flex_start,    NS_STYLE_ALIGN_CONTENT_FLEX_START,
+  eCSSKeyword_flex_end,      NS_STYLE_ALIGN_CONTENT_FLEX_END,
+  eCSSKeyword_center,        NS_STYLE_ALIGN_CONTENT_CENTER,
+  eCSSKeyword_space_between, NS_STYLE_ALIGN_CONTENT_SPACE_BETWEEN,
+  eCSSKeyword_space_around,  NS_STYLE_ALIGN_CONTENT_SPACE_AROUND,
+  eCSSKeyword_stretch,       NS_STYLE_ALIGN_CONTENT_STRETCH,
+  eCSSKeyword_UNKNOWN,-1
+};
+
 const int32_t nsCSSProps::kAlignItemsKTable[] = {
   eCSSKeyword_flex_start, NS_STYLE_ALIGN_ITEMS_FLEX_START,
   eCSSKeyword_flex_end,   NS_STYLE_ALIGN_ITEMS_FLEX_END,
   eCSSKeyword_center,     NS_STYLE_ALIGN_ITEMS_CENTER,
   eCSSKeyword_baseline,   NS_STYLE_ALIGN_ITEMS_BASELINE,
   eCSSKeyword_stretch,    NS_STYLE_ALIGN_ITEMS_STRETCH,
   eCSSKeyword_UNKNOWN,-1
 };
--- a/layout/style/nsCSSProps.h
+++ b/layout/style/nsCSSProps.h
@@ -474,16 +474,17 @@ public:
   static const int32_t kClearKTable[];
   static const int32_t kColorKTable[];
   static const int32_t kContentKTable[];
   static const int32_t kCursorKTable[];
   static const int32_t kDirectionKTable[];
   static const int32_t kDisplayKTable[];
   static const int32_t kElevationKTable[];
   static const int32_t kEmptyCellsKTable[];
+  static const int32_t kAlignContentKTable[];
   static const int32_t kAlignItemsKTable[];
   static const int32_t kAlignSelfKTable[];
   static const int32_t kFlexDirectionKTable[];
   static const int32_t kFlexWrapKTable[];
   static const int32_t kJustifyContentKTable[];
   static const int32_t kFloatKTable[];
   static const int32_t kFloatEdgeKTable[];
   static const int32_t kFontKTable[];
--- a/layout/style/nsComputedDOMStyle.cpp
+++ b/layout/style/nsComputedDOMStyle.cpp
@@ -3351,16 +3351,26 @@ nsComputedDOMStyle::DoGetBorderImageRepe
   valueList->AppendCSSValue(valY);
   valY->SetIdent(
     nsCSSProps::ValueToKeywordEnum(border->mBorderImageRepeatV,
                                    nsCSSProps::kBorderImageRepeatKTable));
   return valueList;
 }
 
 CSSValue*
+nsComputedDOMStyle::DoGetAlignContent()
+{
+  nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue;
+  val->SetIdent(
+    nsCSSProps::ValueToKeywordEnum(StylePosition()->mAlignContent,
+                                   nsCSSProps::kAlignContentKTable));
+  return val;
+}
+
+CSSValue*
 nsComputedDOMStyle::DoGetAlignItems()
 {
   nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue;
   val->SetIdent(
     nsCSSProps::ValueToKeywordEnum(StylePosition()->mAlignItems,
                                    nsCSSProps::kAlignItemsKTable));
   return val;
 }
--- a/layout/style/nsComputedDOMStyle.h
+++ b/layout/style/nsComputedDOMStyle.h
@@ -434,16 +434,17 @@ private:
   mozilla::dom::CSSValue* DoGetAnimationDelay();
   mozilla::dom::CSSValue* DoGetAnimationTimingFunction();
   mozilla::dom::CSSValue* DoGetAnimationDirection();
   mozilla::dom::CSSValue* DoGetAnimationFillMode();
   mozilla::dom::CSSValue* DoGetAnimationIterationCount();
   mozilla::dom::CSSValue* DoGetAnimationPlayState();
 
   /* CSS Flexbox properties */
+  mozilla::dom::CSSValue* DoGetAlignContent();
   mozilla::dom::CSSValue* DoGetAlignItems();
   mozilla::dom::CSSValue* DoGetAlignSelf();
   mozilla::dom::CSSValue* DoGetFlexBasis();
   mozilla::dom::CSSValue* DoGetFlexDirection();
   mozilla::dom::CSSValue* DoGetFlexGrow();
   mozilla::dom::CSSValue* DoGetFlexShrink();
   mozilla::dom::CSSValue* DoGetFlexWrap();
   mozilla::dom::CSSValue* DoGetOrder();
--- a/layout/style/nsComputedDOMStylePropertyList.h
+++ b/layout/style/nsComputedDOMStylePropertyList.h
@@ -34,16 +34,17 @@
  * Properties commented out with // are not yet implemented            *
  * Properties commented out with //// are shorthands and not queryable *
 \* ******************************************************************* */
 
 /* ***************************** *\
  * Implementations of CSS styles *
 \* ***************************** */
 
+COMPUTED_STYLE_PROP(align_content,                   AlignContent)
 COMPUTED_STYLE_PROP(align_items,                   AlignItems)
 COMPUTED_STYLE_PROP(align_self,                    AlignSelf)
 //// COMPUTED_STYLE_PROP(animation,                Animation)
 COMPUTED_STYLE_PROP(animation_delay,               AnimationDelay)
 COMPUTED_STYLE_PROP(animation_direction,           AnimationDirection)
 COMPUTED_STYLE_PROP(animation_duration,            AnimationDuration)
 COMPUTED_STYLE_PROP(animation_fill_mode,           AnimationFillMode)
 COMPUTED_STYLE_PROP(animation_iteration_count,     AnimationIterationCount)
--- a/layout/style/nsRuleNode.cpp
+++ b/layout/style/nsRuleNode.cpp
@@ -6953,16 +6953,23 @@ nsRuleNode::ComputePositionData(void* aS
 
   // box-sizing: enum, inherit, initial
   SetDiscrete(*aRuleData->ValueForBoxSizing(),
               pos->mBoxSizing, canStoreInRuleTree,
               SETDSC_ENUMERATED | SETDSC_UNSET_INITIAL,
               parentPos->mBoxSizing,
               NS_STYLE_BOX_SIZING_CONTENT, 0, 0, 0, 0);
 
+  // align-content: enum, inherit, initial
+  SetDiscrete(*aRuleData->ValueForAlignContent(),
+              pos->mAlignContent, canStoreInRuleTree,
+              SETDSC_ENUMERATED | SETDSC_UNSET_INITIAL,
+              parentPos->mAlignContent,
+              NS_STYLE_ALIGN_CONTENT_STRETCH, 0, 0, 0, 0);
+
   // align-items: enum, inherit, initial
   SetDiscrete(*aRuleData->ValueForAlignItems(),
               pos->mAlignItems, canStoreInRuleTree,
               SETDSC_ENUMERATED | SETDSC_UNSET_INITIAL,
               parentPos->mAlignItems,
               NS_STYLE_ALIGN_ITEMS_INITIAL_VALUE, 0, 0, 0, 0);
 
   // align-self: enum, inherit, initial
--- a/layout/style/nsStyleConsts.h
+++ b/layout/style/nsStyleConsts.h
@@ -398,16 +398,24 @@ static inline mozilla::css::Side operato
 #define NS_STYLE_DISPLAY_DECK                   26
 #define NS_STYLE_DISPLAY_POPUP                  27
 #define NS_STYLE_DISPLAY_GROUPBOX               28
 #endif
 #define NS_STYLE_DISPLAY_FLEX                   29
 #define NS_STYLE_DISPLAY_INLINE_FLEX            30
 
 // See nsStylePosition
+#define NS_STYLE_ALIGN_CONTENT_FLEX_START       0
+#define NS_STYLE_ALIGN_CONTENT_FLEX_END         1
+#define NS_STYLE_ALIGN_CONTENT_CENTER           2
+#define NS_STYLE_ALIGN_CONTENT_SPACE_BETWEEN    3
+#define NS_STYLE_ALIGN_CONTENT_SPACE_AROUND     4
+#define NS_STYLE_ALIGN_CONTENT_STRETCH          5
+
+// See nsStylePosition
 #define NS_STYLE_ALIGN_ITEMS_FLEX_START         0
 #define NS_STYLE_ALIGN_ITEMS_FLEX_END           1
 #define NS_STYLE_ALIGN_ITEMS_CENTER             2
 #define NS_STYLE_ALIGN_ITEMS_BASELINE           3
 #define NS_STYLE_ALIGN_ITEMS_STRETCH            4
 
 // For convenience/clarity (since we use this default value in multiple places)
 #define NS_STYLE_ALIGN_ITEMS_INITIAL_VALUE      NS_STYLE_ALIGN_ITEMS_STRETCH
--- a/layout/style/nsStyleStruct.cpp
+++ b/layout/style/nsStyleStruct.cpp
@@ -1267,16 +1267,17 @@ nsStylePosition::nsStylePosition(void)
   mWidth.SetAutoValue();
   mMinWidth.SetCoordValue(0);
   mMaxWidth.SetNoneValue();
   mHeight.SetAutoValue();
   mMinHeight.SetCoordValue(0);
   mMaxHeight.SetNoneValue();
   mFlexBasis.SetAutoValue();
   mBoxSizing = NS_STYLE_BOX_SIZING_CONTENT;
+  mAlignContent = NS_STYLE_ALIGN_CONTENT_STRETCH;
   mAlignItems = NS_STYLE_ALIGN_ITEMS_INITIAL_VALUE;
   mAlignSelf = NS_STYLE_ALIGN_SELF_AUTO;
   mFlexDirection = NS_STYLE_FLEX_DIRECTION_ROW;
   mFlexWrap = NS_STYLE_FLEX_WRAP_NOWRAP;
   mJustifyContent = NS_STYLE_JUSTIFY_CONTENT_FLEX_START;
   mOrder = NS_STYLE_ORDER_INITIAL;
   mFlexGrow = 0.0f;
   mFlexShrink = 1.0f;
@@ -1335,22 +1336,36 @@ nsChangeHint nsStylePosition::CalcDiffer
   // - flex-wrap changes whether a flex container's children are wrapped, which
   //   impacts their sizing/positioning and hence impacts the container's size.
   if (mAlignItems != aOther.mAlignItems ||
       mFlexDirection != aOther.mFlexDirection ||
       mFlexWrap != aOther.mFlexWrap) {
     return NS_CombineHint(hint, nsChangeHint_AllReflowHints);
   }
 
+
   // Changing justify-content on a flexbox might affect the positioning of its
   // children, but it won't affect any sizing.
   if (mJustifyContent != aOther.mJustifyContent) {
     NS_UpdateHint(hint, nsChangeHint_NeedReflow);
   }
 
+  // Properties that apply only to multi-line flex containers:
+  // 'align-content' can change the positioning & sizing of a multi-line flex
+  // container's children when there's extra space in the cross axis, but it
+  // shouldn't affect the container's own sizing.
+  //
+  // NOTE: If we get here, we know that mFlexWrap == aOther.mFlexWrap
+  // (otherwise, we would've returned earlier). So it doesn't matter which one
+  // of those we check to see if we're multi-line.
+  if (mFlexWrap != NS_STYLE_FLEX_WRAP_NOWRAP &&
+      mAlignContent != aOther.mAlignContent) {
+    NS_UpdateHint(hint, nsChangeHint_NeedReflow);
+  }
+
   if (mHeight != aOther.mHeight ||
       mMinHeight != aOther.mMinHeight ||
       mMaxHeight != aOther.mMaxHeight) {
     // Height changes can affect descendant intrinsic sizes due to replaced
     // elements with percentage heights in descendants which also have
     // percentage heights.  And due to our not-so-great computation of mVResize
     // in nsHTMLReflowState, they do need to force reflow of the whole subtree.
     // XXXbz due to XUL caching heights as well, height changes also need to
--- a/layout/style/nsStyleStruct.h
+++ b/layout/style/nsStyleStruct.h
@@ -1124,16 +1124,17 @@ struct nsStylePosition {
   nsStyleCoord  mWidth;                 // [reset] coord, percent, enum, calc, auto
   nsStyleCoord  mMinWidth;              // [reset] coord, percent, enum, calc
   nsStyleCoord  mMaxWidth;              // [reset] coord, percent, enum, calc, none
   nsStyleCoord  mHeight;                // [reset] coord, percent, calc, auto
   nsStyleCoord  mMinHeight;             // [reset] coord, percent, calc
   nsStyleCoord  mMaxHeight;             // [reset] coord, percent, calc, none
   nsStyleCoord  mFlexBasis;             // [reset] coord, percent, enum, calc, auto
   uint8_t       mBoxSizing;             // [reset] see nsStyleConsts.h
+  uint8_t       mAlignContent;          // [reset] see nsStyleConsts.h
   uint8_t       mAlignItems;            // [reset] see nsStyleConsts.h
   uint8_t       mAlignSelf;             // [reset] see nsStyleConsts.h
   uint8_t       mFlexDirection;         // [reset] see nsStyleConsts.h
   uint8_t       mFlexWrap;              // [reset] see nsStyleConsts.h
   uint8_t       mJustifyContent;        // [reset] see nsStyleConsts.h
   int32_t       mOrder;                 // [reset] integer
   float         mFlexGrow;              // [reset] float
   float         mFlexShrink;            // [reset] float
--- a/layout/style/test/property_database.js
+++ b/layout/style/test/property_database.js
@@ -3691,16 +3691,30 @@ var gCSSProperties = {
 	"vector-effect": {
 		domProp: "vectorEffect",
 		inherited: false,
 		type: CSS_TYPE_LONGHAND,
 		initial_values: [ "none" ],
 		other_values: [ "non-scaling-stroke" ],
 		invalid_values: []
 	},
+	"align-content": {
+		domProp: "alignContent",
+		inherited: false,
+		type: CSS_TYPE_LONGHAND,
+		initial_values: [ "stretch" ],
+		other_values: [
+			"flex-start",
+			"flex-end",
+			"center",
+			"space-between",
+			"space-around"
+		],
+		invalid_values: [ "abc", "30px", "0", "auto" ]
+	},
 	"align-items": {
 		domProp: "alignItems",
 		inherited: false,
 		type: CSS_TYPE_LONGHAND,
 		initial_values: [ "stretch" ],
 		other_values: [ "flex-start", "flex-end", "center", "baseline" ],
 		invalid_values: [ "space-between", "abc", "30px" ]
 	},