Bug 719286 - Add support for objectfill and objectstroke values to CSS parser r=dbaron
authorEdwin Flores <eflores@mozilla.com>
Thu, 06 Sep 2012 16:58:46 +1200
changeset 110724 1ea9c7730f9754bf321d1d9365bffee3de06bf35
parent 110723 585eba0ca2a7e1d2c89586518d9290a8941f945b
child 110725 a0c93525cfba43767f05865415ed8c786afa39be
push id1708
push userakeybl@mozilla.com
push dateMon, 19 Nov 2012 21:10:21 +0000
treeherdermozilla-beta@27b14fe50103 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdbaron
bugs719286
milestone18.0a1
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
Bug 719286 - Add support for objectfill and objectstroke values to CSS parser r=dbaron
layout/base/nsStyleConsts.h
layout/style/nsCSSKeywordList.h
layout/style/nsCSSParser.cpp
layout/style/nsCSSPropList.h
layout/style/nsCSSProps.cpp
layout/style/nsCSSProps.h
layout/style/nsComputedDOMStyle.cpp
layout/style/nsRuleNode.cpp
layout/style/nsStyleStruct.cpp
layout/style/nsStyleStruct.h
layout/style/test/property_database.js
layout/svg/base/src/nsSVGUtils.cpp
--- a/layout/base/nsStyleConsts.h
+++ b/layout/base/nsStyleConsts.h
@@ -201,16 +201,19 @@ static inline mozilla::css::Side operato
 
 // See nsStyleColor
 #define NS_COLOR_CURRENTCOLOR                   -1
 #define NS_COLOR_MOZ_DEFAULT_COLOR              -2
 #define NS_COLOR_MOZ_DEFAULT_BACKGROUND_COLOR   -3
 #define NS_COLOR_MOZ_HYPERLINKTEXT              -4
 #define NS_COLOR_MOZ_VISITEDHYPERLINKTEXT       -5
 #define NS_COLOR_MOZ_ACTIVEHYPERLINKTEXT        -6
+// Only valid as paints in SVG glyphs
+#define NS_COLOR_OBJECTFILL                     -7
+#define NS_COLOR_OBJECTSTROKE                   -8
 
 // See nsStyleDisplay
 #define NS_STYLE_ANIMATION_DIRECTION_NORMAL       0
 #define NS_STYLE_ANIMATION_DIRECTION_REVERSE      1
 #define NS_STYLE_ANIMATION_DIRECTION_ALTERNATE    2
 #define NS_STYLE_ANIMATION_DIRECTION_ALTERNATE_REVERSE    3
 
 // See nsStyleDisplay
--- a/layout/style/nsCSSKeywordList.h
+++ b/layout/style/nsCSSKeywordList.h
@@ -125,16 +125,18 @@ CSS_KEY(-moz-menuhover, _moz_menuhover)
 CSS_KEY(-moz-menuhovertext, _moz_menuhovertext)
 CSS_KEY(-moz-menubartext, _moz_menubartext)
 CSS_KEY(-moz-menubarhovertext, _moz_menubarhovertext)
 CSS_KEY(-moz-middle-with-baseline, _moz_middle_with_baseline)
 CSS_KEY(-moz-min-content, _moz_min_content)
 CSS_KEY(-moz-myanmar, _moz_myanmar)
 CSS_KEY(-moz-nativehyperlinktext, _moz_nativehyperlinktext)
 CSS_KEY(-moz-none, _moz_none)
+CSS_KEY(-moz-objectfill, _moz_objectfill)
+CSS_KEY(-moz-objectstroke, _moz_objectstroke)
 CSS_KEY(-moz-oddtreerow, _moz_oddtreerow)
 CSS_KEY(-moz-oriya, _moz_oriya)
 CSS_KEY(-moz-persian, _moz_persian)
 CSS_KEY(-moz-plaintext, _moz_plaintext)
 CSS_KEY(-moz-popup, _moz_popup)
 CSS_KEY(-moz-pull-down-menu, _moz_pull_down_menu)
 CSS_KEY(-moz-right, _moz_right)
 CSS_KEY(-moz-scrollbars-horizontal, _moz_scrollbars_horizontal)
--- a/layout/style/nsCSSParser.cpp
+++ b/layout/style/nsCSSParser.cpp
@@ -9816,26 +9816,31 @@ CSSParserImpl::SetDefaultNamespaceOnSele
     aSelector.SetNameSpace(kNameSpaceID_Unknown); // wildcard
   }
 }
 
 bool
 CSSParserImpl::ParsePaint(nsCSSProperty aPropID)
 {
   nsCSSValue x, y;
-  if (!ParseVariant(x, VARIANT_HC | VARIANT_NONE | VARIANT_URL, nullptr))
-    return false;
-  if (x.GetUnit() == eCSSUnit_URL) {
+  if (!ParseVariant(x, VARIANT_HCK | VARIANT_NONE | VARIANT_URL,
+                    nsCSSProps::kObjectPatternKTable)) {
+    return false;
+  }
+
+  bool canHaveFallback = x.GetUnit() == eCSSUnit_URL ||
+                         x.GetUnit() == eCSSUnit_Enumerated;
+  if (canHaveFallback) {
     if (!ParseVariant(y, VARIANT_COLOR | VARIANT_NONE, nullptr))
       y.SetNoneValue();
   }
   if (!ExpectEndProperty())
     return false;
 
-  if (x.GetUnit() != eCSSUnit_URL) {
+  if (!canHaveFallback) {
     AppendValue(aPropID, x);
   } else {
     nsCSSValue val;
     val.SetPairValue(x, y);
     AppendValue(aPropID, val);
   }
   return true;
 }
--- a/layout/style/nsCSSPropList.h
+++ b/layout/style/nsCSSPropList.h
@@ -3089,17 +3089,17 @@ CSS_PROP_SVGRESET(
     eStyleAnimType_EnumU8)
 CSS_PROP_SVG(
     fill,
     fill,
     Fill,
     CSS_PROPERTY_PARSE_FUNCTION,
     "",
     0,
-    nullptr,
+    kObjectPatternKTable,
     offsetof(nsStyleSVG, mFill),
     eStyleAnimType_PaintServer)
 CSS_PROP_SVG(
     fill-opacity,
     fill_opacity,
     FillOpacity,
     CSS_PROPERTY_PARSE_VALUE,
     "",
@@ -3245,17 +3245,17 @@ CSS_PROP_SVGRESET(
     eStyleAnimType_float)
 CSS_PROP_SVG(
     stroke,
     stroke,
     Stroke,
     CSS_PROPERTY_PARSE_FUNCTION,
     "",
     0,
-    nullptr,
+    kObjectPatternKTable,
     offsetof(nsStyleSVG, mStroke),
     eStyleAnimType_PaintServer)
 CSS_PROP_SVG(
     stroke-dasharray,
     stroke_dasharray,
     StrokeDasharray,
     CSS_PROPERTY_PARSE_FUNCTION |
         CSS_PROPERTY_VALUE_LIST_USES_COMMAS,
--- a/layout/style/nsCSSProps.cpp
+++ b/layout/style/nsCSSProps.cpp
@@ -768,16 +768,17 @@ const int32_t nsCSSProps::kCaptionSideKT
 const int32_t nsCSSProps::kClearKTable[] = {
   eCSSKeyword_none, NS_STYLE_CLEAR_NONE,
   eCSSKeyword_left, NS_STYLE_CLEAR_LEFT,
   eCSSKeyword_right, NS_STYLE_CLEAR_RIGHT,
   eCSSKeyword_both, NS_STYLE_CLEAR_LEFT_AND_RIGHT,
   eCSSKeyword_UNKNOWN,-1
 };
 
+// See also kObjectPatternKTable for SVG paint-specific values
 const int32_t nsCSSProps::kColorKTable[] = {
   eCSSKeyword_activeborder, LookAndFeel::eColorID_activeborder,
   eCSSKeyword_activecaption, LookAndFeel::eColorID_activecaption,
   eCSSKeyword_appworkspace, LookAndFeel::eColorID_appworkspace,
   eCSSKeyword_background, LookAndFeel::eColorID_background,
   eCSSKeyword_buttonface, LookAndFeel::eColorID_buttonface,
   eCSSKeyword_buttonhighlight, LookAndFeel::eColorID_buttonhighlight,
   eCSSKeyword_buttonshadow, LookAndFeel::eColorID_buttonshadow,
@@ -1142,16 +1143,22 @@ const int32_t nsCSSProps::kListStyleKTab
   eCSSKeyword__moz_ethiopic_halehame, NS_STYLE_LIST_STYLE_MOZ_ETHIOPIC_HALEHAME,
   eCSSKeyword__moz_ethiopic_numeric, NS_STYLE_LIST_STYLE_MOZ_ETHIOPIC_NUMERIC,
   eCSSKeyword__moz_ethiopic_halehame_am, NS_STYLE_LIST_STYLE_MOZ_ETHIOPIC_HALEHAME_AM,
   eCSSKeyword__moz_ethiopic_halehame_ti_er, NS_STYLE_LIST_STYLE_MOZ_ETHIOPIC_HALEHAME_TI_ER,
   eCSSKeyword__moz_ethiopic_halehame_ti_et, NS_STYLE_LIST_STYLE_MOZ_ETHIOPIC_HALEHAME_TI_ET,
   eCSSKeyword_UNKNOWN,-1
 };
 
+const int32_t nsCSSProps::kObjectPatternKTable[] = {
+  eCSSKeyword__moz_objectfill, NS_COLOR_OBJECTFILL,
+  eCSSKeyword__moz_objectstroke, NS_COLOR_OBJECTSTROKE,
+  eCSSKeyword_UNKNOWN,-1
+};
+
 const int32_t nsCSSProps::kOrientKTable[] = {
   eCSSKeyword_horizontal, NS_STYLE_ORIENT_HORIZONTAL,
   eCSSKeyword_vertical,   NS_STYLE_ORIENT_VERTICAL,
   eCSSKeyword_UNKNOWN,    -1
 };
 
 // Same as kBorderStyleKTable except 'hidden'.
 const int32_t nsCSSProps::kOutlineStyleKTable[] = {
--- a/layout/style/nsCSSProps.h
+++ b/layout/style/nsCSSProps.h
@@ -385,16 +385,17 @@ public:
   static const int32_t kFontStretchKTable[];
   static const int32_t kFontStyleKTable[];
   static const int32_t kFontVariantKTable[];
   static const int32_t kFontWeightKTable[];
   static const int32_t kIMEModeKTable[];
   static const int32_t kLineHeightKTable[];
   static const int32_t kListStylePositionKTable[];
   static const int32_t kListStyleKTable[];
+  static const int32_t kObjectPatternKTable[];
   static const int32_t kOrientKTable[];
   static const int32_t kOutlineStyleKTable[];
   static const int32_t kOutlineColorKTable[];
   static const int32_t kOverflowKTable[];
   static const int32_t kOverflowSubKTable[];
   static const int32_t kPageBreakKTable[];
   static const int32_t kPageBreakInsideKTable[];
   static const int32_t kPageMarksKTable[];
--- a/layout/style/nsComputedDOMStyle.cpp
+++ b/layout/style/nsComputedDOMStyle.cpp
@@ -3942,16 +3942,26 @@ nsComputedDOMStyle::GetSVGPaintFor(bool 
 
       nsROCSSPrimitiveValue* fallback = GetROCSSPrimitiveValue();
       valueList->AppendCSSValue(fallback);
 
       val->SetURI(paint->mPaint.mPaintServer);
       SetToRGBAColor(fallback, paint->mFallbackColor);
       return valueList;
     }
+    case eStyleSVGPaintType_ObjectFill:
+    {
+      val->SetIdent(eCSSKeyword__moz_objectfill);
+      break;
+    }
+    case eStyleSVGPaintType_ObjectStroke:
+    {
+      val->SetIdent(eCSSKeyword__moz_objectstroke);
+      break;
+    }
   }
 
   return val;
 }
 
 nsIDOMCSSValue*
 nsComputedDOMStyle::DoGetFill()
 {
--- a/layout/style/nsRuleNode.cpp
+++ b/layout/style/nsRuleNode.cpp
@@ -7127,22 +7127,37 @@ SetSVGPaint(const nsCSSValue& aValue, co
     aResult.mPaint.mColor = NS_RGB(0, 0, 0);
     aResult.mFallbackColor = NS_RGB(0, 0, 0);
   } else if (SetColor(aValue, NS_RGB(0, 0, 0), aPresContext, aContext,
                       color, aCanStoreInRuleTree)) {
     aResult.SetType(eStyleSVGPaintType_Color);
     aResult.mPaint.mColor = color;
   } else if (aValue.GetUnit() == eCSSUnit_Pair) {
     const nsCSSValuePair& pair = aValue.GetPairValue();
-    NS_ABORT_IF_FALSE(pair.mXValue.GetUnit() == eCSSUnit_URL,
-                      "malformed paint server value");
-
-    aResult.SetType(eStyleSVGPaintType_Server);
-    aResult.mPaint.mPaintServer = pair.mXValue.GetURLValue();
-    NS_IF_ADDREF(aResult.mPaint.mPaintServer);
+
+    if (pair.mXValue.GetUnit() == eCSSUnit_URL) {
+      aResult.SetType(eStyleSVGPaintType_Server);
+      aResult.mPaint.mPaintServer = pair.mXValue.GetURLValue();
+      NS_IF_ADDREF(aResult.mPaint.mPaintServer);
+    } else if (pair.mXValue.GetUnit() == eCSSUnit_Enumerated) {
+
+      switch (pair.mXValue.GetIntValue()) {
+      case NS_COLOR_OBJECTFILL:
+        aResult.SetType(eStyleSVGPaintType_ObjectFill);
+        break;
+      case NS_COLOR_OBJECTSTROKE:
+        aResult.SetType(eStyleSVGPaintType_ObjectStroke);
+        break;
+      default:
+        NS_NOTREACHED("unknown keyword as paint server value");
+      }
+
+    } else {
+      NS_NOTREACHED("malformed paint server value");
+    }
 
     if (pair.mYValue.GetUnit() == eCSSUnit_None) {
       aResult.mFallbackColor = NS_RGBA(0, 0, 0, 0);
     } else {
       NS_ABORT_IF_FALSE(pair.mYValue.GetUnit() != eCSSUnit_Inherit,
                         "cannot inherit fallback colour");
       SetColor(pair.mYValue, NS_RGB(0, 0, 0), aPresContext, aContext,
                aResult.mFallbackColor, aCanStoreInRuleTree);
--- a/layout/style/nsStyleStruct.cpp
+++ b/layout/style/nsStyleStruct.cpp
@@ -1106,19 +1106,19 @@ nsStyleSVGPaint& nsStyleSVGPaint::operat
 
 bool nsStyleSVGPaint::operator==(const nsStyleSVGPaint& aOther) const
 {
   if (mType != aOther.mType)
     return false;
   if (mType == eStyleSVGPaintType_Server)
     return EqualURIs(mPaint.mPaintServer, aOther.mPaint.mPaintServer) &&
            mFallbackColor == aOther.mFallbackColor;
-  if (mType == eStyleSVGPaintType_None)
-    return true;
-  return mPaint.mColor == aOther.mPaint.mColor;
+  if (mType == eStyleSVGPaintType_Color)
+    return mPaint.mColor == aOther.mPaint.mColor;
+  return true;
 }
 
 
 // --------------------
 // nsStylePosition
 //
 nsStylePosition::nsStylePosition(void) 
 { 
--- a/layout/style/nsStyleStruct.h
+++ b/layout/style/nsStyleStruct.h
@@ -2158,17 +2158,19 @@ struct nsStyleColumn {
 protected:
   nscoord mColumnRuleWidth;  // [reset] coord
   nscoord mTwipsPerPixel;
 };
 
 enum nsStyleSVGPaintType {
   eStyleSVGPaintType_None = 1,
   eStyleSVGPaintType_Color,
-  eStyleSVGPaintType_Server
+  eStyleSVGPaintType_Server,
+  eStyleSVGPaintType_ObjectFill,
+  eStyleSVGPaintType_ObjectStroke
 };
 
 struct nsStyleSVGPaint
 {
   union {
     nscolor mColor;
     nsIURI *mPaintServer;
   } mPaint;
--- a/layout/style/test/property_database.js
+++ b/layout/style/test/property_database.js
@@ -3622,17 +3622,17 @@ var gCSSProperties = {
 		invalid_values: []
 	},
 	"fill": {
 		domProp: "fill",
 		inherited: true,
 		type: CSS_TYPE_LONGHAND,
 		prerequisites: { "color": "blue" },
 		initial_values: [ "black", "#000", "#000000", "rgb(0,0,0)", "rgba(0,0,0,1)" ],
-		other_values: [ "green", "#fc3", "url('#myserver')", "url(foo.svg#myserver)", 'url("#myserver") green', "none", "currentColor" ],
+		other_values: [ "green", "#fc3", "url('#myserver')", "url(foo.svg#myserver)", 'url("#myserver") green', "none", "currentColor", "-moz-objectFill", "-moz-objectStroke" ],
 		invalid_values: [ "000000", "ff00ff" ]
 	},
 	"fill-opacity": {
 		domProp: "fillOpacity",
 		inherited: true,
 		type: CSS_TYPE_LONGHAND,
 		initial_values: [ "1", "2.8", "1.000" ],
 		other_values: [ "0", "0.3", "-7.3" ],
@@ -3754,17 +3754,17 @@ var gCSSProperties = {
 		other_values: [ "0", "0.3", "-7.3" ],
 		invalid_values: []
 	},
 	"stroke": {
 		domProp: "stroke",
 		inherited: true,
 		type: CSS_TYPE_LONGHAND,
 		initial_values: [ "none" ],
-		other_values: [ "black", "#000", "#000000", "rgb(0,0,0)", "rgba(0,0,0,1)", "green", "#fc3", "url('#myserver')", "url(foo.svg#myserver)", 'url("#myserver") green', "currentColor" ],
+		other_values: [ "black", "#000", "#000000", "rgb(0,0,0)", "rgba(0,0,0,1)", "green", "#fc3", "url('#myserver')", "url(foo.svg#myserver)", 'url("#myserver") green', "currentColor", "-moz-objectFill", "-moz-objectStroke" ],
 		invalid_values: [ "000000", "ff00ff" ]
 	},
 	"stroke-dasharray": {
 		domProp: "strokeDasharray",
 		inherited: true,
 		type: CSS_TYPE_LONGHAND,
 		initial_values: [ "none" ],
 		other_values: [ "5px,3px,2px", "5px 3px 2px", "  5px ,3px	, 2px ", "1px", "5%", "3em" ],
--- a/layout/svg/base/src/nsSVGUtils.cpp
+++ b/layout/svg/base/src/nsSVGUtils.cpp
@@ -1837,17 +1837,19 @@ nsSVGUtils::PathExtentsToMaxStrokeExtent
 // ----------------------------------------------------------------------
 
 /* static */ nscolor
 nsSVGUtils::GetFallbackOrPaintColor(gfxContext *aContext, nsStyleContext *aStyleContext,
                                     nsStyleSVGPaint nsStyleSVG::*aFillOrStroke)
 {
   const nsStyleSVGPaint &paint = aStyleContext->GetStyleSVG()->*aFillOrStroke;
   nsStyleContext *styleIfVisited = aStyleContext->GetStyleIfVisited();
-  bool isServer = paint.mType == eStyleSVGPaintType_Server;
+  bool isServer = paint.mType == eStyleSVGPaintType_Server ||
+                  paint.mType == eStyleSVGPaintType_ObjectFill ||
+                  paint.mType == eStyleSVGPaintType_ObjectStroke;
   nscolor color = isServer ? paint.mFallbackColor : paint.mPaint.mColor;
   if (styleIfVisited) {
     const nsStyleSVGPaint &paintIfVisited =
       styleIfVisited->GetStyleSVG()->*aFillOrStroke;
     // To prevent Web content from detecting if a user has visited a URL
     // (via URL loading triggered by paint servers or performance
     // differences between paint servers or between a paint server and a
     // color), we do not allow whether links are visited to change which