Add calc() support for two properties I missed: outline-width and column-gap. (Bug 363249) r=bzbarsky a2.0=blocking2.0:beta6
authorL. David Baron <dbaron@dbaron.org>
Thu, 09 Sep 2010 08:21:46 -0700
changeset 52285 36bcecd7cd32bc1fd584d4e7bac43505f6d0c765
parent 52284 1ad67ed26a45194e67cc4e1b6538343558af6f65
child 52286 dd7bbf7febcb5cc4a75a3123602308464938b9a3
push id1
push userroot
push dateTue, 26 Apr 2011 22:38:44 +0000
treeherdermozilla-beta@bfdb6e623a36 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbzbarsky
bugs363249
milestone2.0b6pre
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Add calc() support for two properties I missed: outline-width and column-gap. (Bug 363249) r=bzbarsky a2.0=blocking2.0:beta6
layout/style/nsCSSParser.cpp
layout/style/nsRuleNode.cpp
layout/style/nsStyleStruct.cpp
layout/style/test/property_database.js
--- a/layout/style/nsCSSParser.cpp
+++ b/layout/style/nsCSSParser.cpp
@@ -5635,17 +5635,18 @@ CSSParserImpl::ParseSingleValueProperty(
                                    nsCSSProps::kBorderWidthKTable);
   case eCSSProperty__moz_column_count:
     // Need to reject 0 in addition to negatives.  If we accept 0, we
     // need to change NS_STYLE_COLUMN_COUNT_AUTO to something else.
     return ParsePositiveNonZeroVariant(aValue, VARIANT_AHI, nsnull);
   case eCSSProperty__moz_column_width:
     return ParseNonNegativeVariant(aValue, VARIANT_AHL | VARIANT_CALC, nsnull);
   case eCSSProperty__moz_column_gap:
-    return ParseNonNegativeVariant(aValue, VARIANT_HL | VARIANT_NORMAL, nsnull);
+    return ParseNonNegativeVariant(aValue, VARIANT_HL | VARIANT_NORMAL |
+                                   VARIANT_CALC, nsnull);
   case eCSSProperty_bottom:
   case eCSSProperty_top:
   case eCSSProperty_left:
   case eCSSProperty_right:
     return ParseVariant(aValue, VARIANT_AHLP | VARIANT_CALC, nsnull);
   case eCSSProperty_box_align:
     return ParseVariant(aValue, VARIANT_HK,
                         nsCSSProps::kBoxAlignKTable);
@@ -5855,17 +5856,17 @@ CSSParserImpl::ParseSingleValueProperty(
     return ParsePositiveNonZeroVariant(aValue, VARIANT_HI, nsnull);
   case eCSSProperty_outline_color:
     return ParseVariant(aValue, VARIANT_HCK,
                         nsCSSProps::kOutlineColorKTable);
   case eCSSProperty_outline_style:
     return ParseVariant(aValue, VARIANT_HK,
                         nsCSSProps::kOutlineStyleKTable);
   case eCSSProperty_outline_width:
-    return ParseNonNegativeVariant(aValue, VARIANT_HKL,
+    return ParseNonNegativeVariant(aValue, VARIANT_HKL | VARIANT_CALC,
                                    nsCSSProps::kBorderWidthKTable);
   case eCSSProperty_outline_offset:
     return ParseVariant(aValue, VARIANT_HL | VARIANT_CALC, nsnull);
   case eCSSProperty_overflow_x:
   case eCSSProperty_overflow_y:
     return ParseVariant(aValue, VARIANT_HK,
                         nsCSSProps::kOverflowSubKTable);
   case eCSSProperty_padding_bottom:
--- a/layout/style/nsRuleNode.cpp
+++ b/layout/style/nsRuleNode.cpp
@@ -5340,17 +5340,18 @@ nsRuleNode::ComputeOutlineData(void* aSt
 
   // outline-width: length, enum, inherit
   if (eCSSUnit_Initial == marginData.mOutlineWidth.GetUnit()) {
     outline->mOutlineWidth =
       nsStyleCoord(NS_STYLE_BORDER_WIDTH_MEDIUM, eStyleUnit_Enumerated);
   }
   else {
     SetCoord(marginData.mOutlineWidth, outline->mOutlineWidth,
-             parentOutline->mOutlineWidth, SETCOORD_LEH, aContext,
+             parentOutline->mOutlineWidth,
+             SETCOORD_LEH | SETCOORD_CALC_LENGTH_ONLY, aContext,
              mPresContext, canStoreInRuleTree);
   }
 
   // outline-offset: length, inherit
   nsStyleCoord tempCoord;
   if (SetCoord(marginData.mOutlineOffset, tempCoord,
                nsStyleCoord(parentOutline->mOutlineOffset,
                             nsStyleCoord::CoordConstructor),
@@ -6019,21 +6020,27 @@ nsRuleNode::ComputeColumnData(void* aSta
 
   // column-width: length, auto, inherit
   SetCoord(columnData.mColumnWidth,
            column->mColumnWidth, parent->mColumnWidth,
            SETCOORD_LAH | SETCOORD_INITIAL_AUTO |
            SETCOORD_CALC_LENGTH_ONLY | SETCOORD_CALC_CLAMP_NONNEGATIVE,
            aContext, mPresContext, canStoreInRuleTree);
 
-  // column-gap: length, percentage, inherit, normal
+  // column-gap: length, inherit, normal
   SetCoord(columnData.mColumnGap,
            column->mColumnGap, parent->mColumnGap,
-           SETCOORD_LPH | SETCOORD_NORMAL | SETCOORD_INITIAL_NORMAL,
+           SETCOORD_LH | SETCOORD_NORMAL | SETCOORD_INITIAL_NORMAL |
+           SETCOORD_CALC_LENGTH_ONLY,
            aContext, mPresContext, canStoreInRuleTree);
+  // clamp negative calc() to 0
+  if (column->mColumnGap.GetUnit() == eStyleUnit_Coord) {
+    column->mColumnGap.SetCoordValue(
+      NS_MAX(column->mColumnGap.GetCoordValue(), 0));
+  }
 
   // column-count: auto, integer, inherit
   if (eCSSUnit_Auto == columnData.mColumnCount.GetUnit() ||
       eCSSUnit_Initial == columnData.mColumnCount.GetUnit()) {
     column->mColumnCount = NS_STYLE_COLUMN_COUNT_AUTO;
   } else if (eCSSUnit_Integer == columnData.mColumnCount.GetUnit()) {
     column->mColumnCount = columnData.mColumnCount.GetIntValue();
     // Max 1000 columns - wallpaper for bug 345583.
--- a/layout/style/nsStyleStruct.cpp
+++ b/layout/style/nsStyleStruct.cpp
@@ -625,18 +625,19 @@ nsStyleOutline::nsStyleOutline(const nsS
 
 void 
 nsStyleOutline::RecalcData(nsPresContext* aContext)
 {
   if (NS_STYLE_BORDER_STYLE_NONE == GetOutlineStyle()) {
     mCachedOutlineWidth = 0;
     mHasCachedOutline = PR_TRUE;
   } else if (IsFixedUnit(mOutlineWidth, PR_TRUE)) {
+    // Clamp negative calc() to 0.
     mCachedOutlineWidth =
-      CalcCoord(mOutlineWidth, aContext->GetBorderWidthTable(), 3);
+      NS_MAX(CalcCoord(mOutlineWidth, aContext->GetBorderWidthTable(), 3), 0);
     mCachedOutlineWidth =
       NS_ROUND_BORDER_TO_PIXELS(mCachedOutlineWidth, mTwipsPerPixel);
     mHasCachedOutline = PR_TRUE;
   }
   else
     mHasCachedOutline = PR_FALSE;
 }
 
--- a/layout/style/test/property_database.js
+++ b/layout/style/test/property_database.js
@@ -401,18 +401,28 @@ var gCSSProperties = {
 		other_values: [ "1", "17" ],
 		// negative and zero invalid per editor's draft
 		invalid_values: [ "-1", "0", "3px" ]
 	},
 	"-moz-column-gap": {
 		domProp: "MozColumnGap",
 		inherited: false,
 		type: CSS_TYPE_LONGHAND,
-		initial_values: [ "normal", "1em" ],
-		other_values: [ "2px", "4em" ],
+		initial_values: [ "normal", "1em", "-moz-calc(-2em + 3em)" ],
+		other_values: [ "2px", "4em",
+			"-moz-calc(2px)",
+			"-moz-calc(-2px)",
+			"-moz-calc(0)",
+			"-moz-calc(0pt)",
+			"-moz-calc(5em)",
+			"-moz-calc(3*25px)",
+			"-moz-calc(25px*3)",
+			"-moz-calc(3*25px + 5em)",
+			"-moz-min(3em, 30em,200px, min(500px ,40em))",
+		],
 		invalid_values: [ "3%", "-1px" ]
 	},
 	"-moz-column-rule": {
 		domProp: "MozColumnRule",
 		inherited: false,
 		type: CSS_TYPE_TRUE_SHORTHAND,
 		prerequisites: { "color": "green" },
 		subproperties: [ "-moz-column-rule-width", "-moz-column-rule-style", "-moz-column-rule-color" ],
@@ -2071,18 +2081,28 @@ var gCSSProperties = {
 		other_values: [ "solid", "dashed", "dotted", "double", "outset", "inset", "groove", "ridge" ],
 		invalid_values: []
 	},
 	"outline-width": {
 		domProp: "outlineWidth",
 		inherited: false,
 		type: CSS_TYPE_LONGHAND,
 		prerequisites: { "outline-style": "solid" },
-		initial_values: [ "medium", "3px" ],
-		other_values: [ "thin", "thick", "1px", "2em" ],
+		initial_values: [ "medium", "3px", "-moz-calc(4px - 1px)" ],
+		other_values: [ "thin", "thick", "1px", "2em",
+			"-moz-calc(2px)",
+			"-moz-calc(-2px)",
+			"-moz-calc(0)",
+			"-moz-calc(0px)",
+			"-moz-calc(5em)",
+			"-moz-calc(3*25px)",
+			"-moz-calc(25px*3)",
+			"-moz-calc(3*25px + 5em)",
+			"-moz-min(3em, 30em,200px, min(500px ,40em))",
+		],
 		invalid_values: [ "5%" ]
 	},
 	"overflow": {
 		domProp: "overflow",
 		inherited: false,
 		type: CSS_TYPE_SHORTHAND_AND_LONGHAND,
 		prerequisites: { "display": "block" },
 		subproperties: [ "overflow-x", "overflow-y" ],