Bug 696253, patch 7: implement parsing/computation for CSS property 'flex-basis'. r=dbaron
authorDaniel Holbert <dholbert@cs.stanford.edu>
Fri, 06 Jul 2012 17:06:23 -0700
changeset 98589 57126745d4629a4be7049756fb649f59bd4de2d5
parent 98588 10d1162cd4e1c2fbd9344dd42e874dd2886dcff6
child 98590 a112868224d10b3924a28e6752edf6336c6e62ba
push id903
push usertim.taubert@gmx.de
push dateSun, 08 Jul 2012 11:40:07 +0000
treeherderfx-team@1751d97cc9e4 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdbaron
bugs696253
milestone16.0a1
Bug 696253, patch 7: implement parsing/computation for CSS property 'flex-basis'. r=dbaron
dom/interfaces/css/nsIDOMCSS2Properties.idl
layout/style/nsCSSPropList.h
layout/style/nsComputedDOMStyle.cpp
layout/style/nsComputedDOMStyle.h
layout/style/nsRuleNode.cpp
layout/style/nsStyleStruct.cpp
layout/style/nsStyleStruct.h
layout/style/test/property_database.js
layout/style/test/test_transitions_per_property.html
--- a/dom/interfaces/css/nsIDOMCSS2Properties.idl
+++ b/dom/interfaces/css/nsIDOMCSS2Properties.idl
@@ -763,16 +763,19 @@ interface nsIDOMCSS2Properties : nsISupp
    block should be uncommented (and this interface's uuid should be revved).
    (This would be #ifdef MOZ_FLEXBOX, if that worked in IDL files.)
            attribute DOMString        MozAlignItems;
                                         // raises(DOMException) on setting
 
            attribute DOMString        MozAlignSelf;
                                         // raises(DOMException) on setting
 
+           attribute DOMString        MozFlexBasis;
+                                        // raises(DOMException) on setting
+
            attribute DOMString        MozFlexDirection;
                                         // raises(DOMException) on setting
 
            attribute DOMString        MozFlexGrow;
                                         // raises(DOMException) on setting
 
            attribute DOMString        MozFlexShrink;
                                         // raises(DOMException) on setting
--- a/layout/style/nsCSSPropList.h
+++ b/layout/style/nsCSSPropList.h
@@ -1528,16 +1528,28 @@ CSS_PROP_POSITION(
     CSS_PROP_DOMPROP_PREFIXED(AlignSelf),
     CSS_PROPERTY_PARSE_VALUE,
     "",
     VARIANT_HK,
     kAlignSelfKTable,
     offsetof(nsStylePosition, mAlignSelf),
     eStyleAnimType_EnumU8)
 CSS_PROP_POSITION(
+    -moz-flex-basis,
+    flex_basis,
+    CSS_PROP_DOMPROP_PREFIXED(FlexBasis),
+    CSS_PROPERTY_PARSE_VALUE |
+        CSS_PROPERTY_VALUE_NONNEGATIVE |
+        CSS_PROPERTY_STORES_CALC,
+    "",
+    VARIANT_AHKLP | VARIANT_CALC,
+    kWidthKTable,
+    offsetof(nsStylePosition, mFlexBasis),
+    eStyleAnimType_Coord)
+CSS_PROP_POSITION(
     -moz-flex-direction,
     flex_direction,
     CSS_PROP_DOMPROP_PREFIXED(FlexDirection),
     CSS_PROPERTY_PARSE_VALUE,
     "",
     VARIANT_HK,
     kFlexDirectionKTable,
     offsetof(nsStylePosition, mFlexDirection),
--- a/layout/style/nsComputedDOMStyle.cpp
+++ b/layout/style/nsComputedDOMStyle.cpp
@@ -2957,16 +2957,37 @@ nsComputedDOMStyle::DoGetAlignSelf()
                     "Should have swapped out 'auto' for something non-auto");
   val->SetIdent(
     nsCSSProps::ValueToKeywordEnum(computedAlignSelf,
                                    nsCSSProps::kAlignSelfKTable));
   return val;
 }
 
 nsIDOMCSSValue*
+nsComputedDOMStyle::DoGetFlexBasis()
+{
+  nsROCSSPrimitiveValue* val = GetROCSSPrimitiveValue();
+
+  // XXXdholbert We could make this more automagic and resolve percentages
+  // if we wanted, by passing in a PercentageBaseGetter instead of nsnull
+  // below.  Logic would go like this:
+  //   if (i'm a flex item) {
+  //     if (my flex container is horizontal) {
+  //       percentageBaseGetter = &nsComputedDOMStyle::GetCBContentWidth;
+  //     } else {
+  //       percentageBaseGetter = &nsComputedDOMStyle::GetCBContentHeight;
+  //     }
+  //   }
+
+  SetValueToCoord(val, GetStylePosition()->mFlexBasis, true,
+                  nsnull, nsCSSProps::kWidthKTable);
+  return val;
+}
+
+nsIDOMCSSValue*
 nsComputedDOMStyle::DoGetFlexDirection()
 {
   nsROCSSPrimitiveValue* val = GetROCSSPrimitiveValue();
   val->SetIdent(
     nsCSSProps::ValueToKeywordEnum(GetStylePosition()->mFlexDirection,
                                    nsCSSProps::kFlexDirectionKTable));
   return val;
 }
@@ -4720,16 +4741,17 @@ nsComputedDOMStyle::GetQueryableProperty
     COMPUTED_STYLE_MAP_ENTRY(_moz_column_count,             ColumnCount),
     COMPUTED_STYLE_MAP_ENTRY(_moz_column_gap,               ColumnGap),
     //// COMPUTED_STYLE_MAP_ENTRY(_moz_column_rule,         ColumnRule),
     COMPUTED_STYLE_MAP_ENTRY(_moz_column_rule_color,        ColumnRuleColor),
     COMPUTED_STYLE_MAP_ENTRY(_moz_column_rule_style,        ColumnRuleStyle),
     COMPUTED_STYLE_MAP_ENTRY(_moz_column_rule_width,        ColumnRuleWidth),
     COMPUTED_STYLE_MAP_ENTRY(_moz_column_width,             ColumnWidth),
 #ifdef MOZ_FLEXBOX
+    COMPUTED_STYLE_MAP_ENTRY(flex_basis,                    FlexBasis),
     COMPUTED_STYLE_MAP_ENTRY(flex_direction,                FlexDirection),
     COMPUTED_STYLE_MAP_ENTRY(flex_grow,                     FlexGrow),
     COMPUTED_STYLE_MAP_ENTRY(flex_shrink,                   FlexShrink),
 #endif // MOZ_FLEXBOX
     COMPUTED_STYLE_MAP_ENTRY(float_edge,                    FloatEdge),
     COMPUTED_STYLE_MAP_ENTRY(font_feature_settings,         FontFeatureSettings),
     COMPUTED_STYLE_MAP_ENTRY(font_language_override,        FontLanguageOverride),
     COMPUTED_STYLE_MAP_ENTRY(force_broken_image_icon,       ForceBrokenImageIcon),
--- a/layout/style/nsComputedDOMStyle.h
+++ b/layout/style/nsComputedDOMStyle.h
@@ -356,16 +356,17 @@ private:
   nsIDOMCSSValue* DoGetAnimationFillMode();
   nsIDOMCSSValue* DoGetAnimationIterationCount();
   nsIDOMCSSValue* DoGetAnimationPlayState();
 
 #ifdef MOZ_FLEXBOX
   /* CSS Flexbox properties */
   nsIDOMCSSValue* DoGetAlignItems();
   nsIDOMCSSValue* DoGetAlignSelf();
+  nsIDOMCSSValue* DoGetFlexBasis();
   nsIDOMCSSValue* DoGetFlexDirection();
   nsIDOMCSSValue* DoGetFlexGrow();
   nsIDOMCSSValue* DoGetFlexShrink();
   nsIDOMCSSValue* DoGetOrder();
   nsIDOMCSSValue* DoGetJustifyContent();
 #endif // MOZ_FLEXBOX
 
   /* SVG properties */
--- a/layout/style/nsRuleNode.cpp
+++ b/layout/style/nsRuleNode.cpp
@@ -6480,16 +6480,22 @@ nsRuleNode::ComputePositionData(void* aS
     SetDiscrete(*aRuleData->ValueForAlignSelf(),
                 pos->mAlignSelf, canStoreInRuleTree,
                 SETDSC_ENUMERATED,
                 parentPos->mAlignSelf, // (unused -- we handled inherit above)
                 NS_STYLE_ALIGN_SELF_AUTO, // initial == auto
                 0, 0, 0, 0);
   }
 
+  // flex-basis: auto, length, percent, enum, calc, inherit, initial
+  // (Note: The flags here should match those used for 'width' property above.)
+  SetCoord(*aRuleData->ValueForFlexBasis(), pos->mFlexBasis, parentPos->mFlexBasis,
+           SETCOORD_LPAEH | SETCOORD_INITIAL_AUTO | SETCOORD_STORE_CALC,
+           aContext, mPresContext, canStoreInRuleTree);
+
   // flex-direction: enum, inherit, initial
   SetDiscrete(*aRuleData->ValueForFlexDirection(),
               pos->mFlexDirection, canStoreInRuleTree,
               SETDSC_ENUMERATED, parentPos->mFlexDirection,
               NS_STYLE_FLEX_DIRECTION_ROW, 0, 0, 0, 0);
 
   // flex-grow: float, inherit, initial
   SetFactor(*aRuleData->ValueForFlexGrow(),
--- a/layout/style/nsStyleStruct.cpp
+++ b/layout/style/nsStyleStruct.cpp
@@ -1119,16 +1119,19 @@ nsStylePosition::nsStylePosition(void)
   mOffset.SetRight(autoCoord);
   mOffset.SetBottom(autoCoord);
   mWidth.SetAutoValue();
   mMinWidth.SetCoordValue(0);
   mMaxWidth.SetNoneValue();
   mHeight.SetAutoValue();
   mMinHeight.SetCoordValue(0);
   mMaxHeight.SetNoneValue();
+#ifdef MOZ_FLEXBOX
+  mFlexBasis.SetAutoValue();
+#endif // MOZ_FLEXBOX
   mBoxSizing = NS_STYLE_BOX_SIZING_CONTENT;
 #ifdef MOZ_FLEXBOX
   mAlignItems = NS_STYLE_ALIGN_ITEMS_INITIAL_VALUE;
   mAlignSelf = NS_STYLE_ALIGN_SELF_AUTO;
   mFlexDirection = NS_STYLE_FLEX_DIRECTION_ROW;
   mJustifyContent = NS_STYLE_JUSTIFY_CONTENT_FLEX_START;
   mOrder = NS_STYLE_ORDER_INITIAL;
   mFlexGrow = 0.0f;
@@ -1159,16 +1162,17 @@ nsChangeHint nsStylePosition::CalcDiffer
   }
 
 #ifdef MOZ_FLEXBOX
   // Properties that apply to flex items:
   // NOTE: Changes to "order" on a flex item may trigger some repositioning.
   // If we're in a multi-line flex container, it also may affect our size
   // (and that of our container & siblings) by shuffling items between lines.
   if (mAlignSelf != aOther.mAlignSelf ||
+      mFlexBasis != aOther.mFlexBasis ||
       mFlexGrow != aOther.mFlexGrow ||
       mFlexShrink != aOther.mFlexShrink ||
       mOrder != aOther.mOrder) {
     return NS_CombineHint(hint, nsChangeHint_ReflowFrame);
   }
 
   // Properties that apply to flexbox containers:
 
--- a/layout/style/nsStyleStruct.h
+++ b/layout/style/nsStyleStruct.h
@@ -1087,16 +1087,19 @@ struct nsStylePosition {
 
   nsStyleSides  mOffset;                // [reset] coord, percent, calc, auto
   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
+#ifdef MOZ_FLEXBOX
+  nsStyleCoord  mFlexBasis;             // [reset] coord, percent, enum, calc, auto
+#endif // MOZ_FLEXBOX
   PRUint8       mBoxSizing;             // [reset] see nsStyleConsts.h
 #ifdef MOZ_FLEXBOX
   PRUint8       mAlignItems;            // [reset] see nsStyleConsts.h
   PRUint8       mAlignSelf;             // [reset] see nsStyleConsts.h
   PRUint8       mFlexDirection;         // [reset] see nsStyleConsts.h
   PRUint8       mJustifyContent;        // [reset] see nsStyleConsts.h
   PRInt32       mOrder;                 // [reset] integer
   float         mFlexGrow;              // [reset] float
--- a/layout/style/test/property_database.js
+++ b/layout/style/test/property_database.js
@@ -750,16 +750,83 @@ var gCSSProperties = {
 		domProp: "MozAlignSelf",
 		inherited: false,
 		type: CSS_TYPE_LONGHAND,
 		// (Assuming defaults on the parent, 'auto' will compute to 'stretch'.)
 		initial_values: [ "auto", "stretch" ],
 		other_values: [ "flex-start", "flex-end", "center", "baseline" ],
 		invalid_values: [ "space-between", "abc", "30px" ]
 	},
+	"-moz-flex-basis": {
+		domProp: "MozFlexBasis",
+		inherited: false,
+		type: CSS_TYPE_LONGHAND,
+		initial_values: [ " auto" ],
+        // NOTE: This is cribbed directly from the "width" chunk, since this
+        // property takes the exact same values as width (albeit with
+        // different semantics on 'auto').
+        // XXXdholbert (Maybe these should get separated out into
+        // a reusable array defined at the top of this file?)
+		other_values: [ "15px", "3em", "15%", "-moz-max-content", "-moz-min-content", "-moz-fit-content", "-moz-available",
+			// valid calc() values
+			"-moz-calc(-2px)",
+			"-moz-calc(2px)",
+			"-moz-calc(50%)",
+			"-moz-calc(50% + 2px)",
+			"-moz-calc( 50% + 2px)",
+			"-moz-calc(50% + 2px )",
+			"-moz-calc( 50% + 2px )",
+			"-moz-calc(50% - -2px)",
+			"-moz-calc(2px - -50%)",
+			"-moz-calc(3*25px)",
+			"-moz-calc(3 *25px)",
+			"-moz-calc(3 * 25px)",
+			"-moz-calc(3* 25px)",
+			"-moz-calc(25px*3)",
+			"-moz-calc(25px *3)",
+			"-moz-calc(25px* 3)",
+			"-moz-calc(25px * 3)",
+			"-moz-calc(3*25px + 50%)",
+			"-moz-calc(50% - 3em + 2px)",
+			"-moz-calc(50% - (3em + 2px))",
+			"-moz-calc((50% - 3em) + 2px)",
+			"-moz-calc(2em)",
+			"-moz-calc(50%)",
+			"-moz-calc(50px/2)",
+			"-moz-calc(50px/(2 - 1))"
+		],
+		invalid_values: [ "none", "-2px",
+			// invalid calc() values
+			"-moz-calc(50%+ 2px)",
+			"-moz-calc(50% +2px)",
+			"-moz-calc(50%+2px)",
+			"-moz-min()",
+			"-moz-calc(min())",
+			"-moz-max()",
+			"-moz-calc(max())",
+			"-moz-min(5px)",
+			"-moz-calc(min(5px))",
+			"-moz-max(5px)",
+			"-moz-calc(max(5px))",
+			"-moz-min(5px,2em)",
+			"-moz-calc(min(5px,2em))",
+			"-moz-max(5px,2em)",
+			"-moz-calc(max(5px,2em))",
+			"-moz-calc(50px/(2 - 2))",
+			// If we ever support division by values, which is
+			// complicated for the reasons described in
+			// http://lists.w3.org/Archives/Public/www-style/2010Jan/0007.html
+			// , we should support all 4 of these as described in
+			// http://lists.w3.org/Archives/Public/www-style/2009Dec/0296.html
+			"-moz-calc((3em / 100%) * 3em)",
+			"-moz-calc(3em / 100% * 3em)",
+			"-moz-calc(3em * (3em / 100%))",
+			"-moz-calc(3em * 3em / 100%)"
+		]
+	},
 	"-moz-flex-direction": {
 		domProp: "MozFlexDirection",
 		inherited: false,
 		type: CSS_TYPE_LONGHAND,
 		initial_values: [ "row" ],
 		other_values: [ "row-reverse", "column", "column-reverse" ],
 		invalid_values: [ "10px", "30%", "justify", "column wrap" ]
 	},
--- a/layout/style/test/test_transitions_per_property.html
+++ b/layout/style/test/test_transitions_per_property.html
@@ -113,16 +113,18 @@ var supported_properties = {
     "fill": [ test_color_transition ],
     "fill-opacity" : [ test_float_zeroToOne_transition,
                        // opacity is clamped in computed style
                        // (not parsing/interpolation)
                        test_float_zeroToOne_clamped ],
 /* XXXdholbert In builds with MOZ_FLEXBOX enabled, this should be uncommented.
    (This would be #ifdef MOZ_FLEXBOX, if that worked in JS files.)
 
+    "-moz-flex-basis": [ test_length_transition, test_percent_transition,
+                         test_length_clamped, test_percent_clamped ],
     "-moz-flex-grow": [ test_float_zeroToOne_transition,
                         test_float_aboveOne_transition ],
     "-moz-flex-shrink": [ test_float_zeroToOne_transition,
                           test_float_aboveOne_transition ],
     "-moz-order": [ test_integer_transition ],
 
 */
     "flood-color": [ test_color_transition ],