Bug 655877 - Part 21: Avoid assertions when nsStyleContext::GetVisitedDependentColor is called for an SVG paint property. r=dbaron
authorCameron McCormack <cam@mcc.id.au>
Sun, 05 Aug 2012 11:01:19 +1000
changeset 101488 6899651a0f096311cb8c1573b3854f81bb9a1ab7
parent 101487 d8c6025c0881195cf71d6dda0ed3b91c4cef7ae2
child 101489 05848864b5f9f908b60d4bac8922291119c70091
push id23235
push userkhuey@mozilla.com
push dateSun, 05 Aug 2012 15:30:53 +0000
treeherdermozilla-central@6347710412a5 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdbaron
bugs655877
milestone17.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 655877 - Part 21: Avoid assertions when nsStyleContext::GetVisitedDependentColor is called for an SVG paint property. r=dbaron
layout/style/nsStyleContext.cpp
--- a/layout/style/nsStyleContext.cpp
+++ b/layout/style/nsStyleContext.cpp
@@ -13,21 +13,24 @@
 #include "nsCOMPtr.h"
 #include "nsStyleSet.h"
 #include "nsIPresShell.h"
 
 #include "nsRuleNode.h"
 #include "nsStyleContext.h"
 #include "prlog.h"
 #include "nsStyleAnimation.h"
+#include "mozilla/Util.h"
 
 #ifdef DEBUG
 // #define NOISY_DEBUG
 #endif
 
+using namespace mozilla;
+
 //----------------------------------------------------------------------
 
 
 nsStyleContext::nsStyleContext(nsStyleContext* aParent,
                                nsIAtom* aPseudoTag,
                                nsCSSPseudoElements::Type aPseudoType,
                                nsRuleNode* aRuleNode,
                                nsPresContext* aPresContext)
@@ -694,29 +697,48 @@ NS_NewStyleContext(nsStyleContext* aPare
   nsStyleContext* context =
     new (aPresContext) nsStyleContext(aParentContext, aPseudoTag, aPseudoType,
                                       aRuleNode, aPresContext);
   if (context)
     context->AddRef();
   return context;
 }
 
-static nscolor ExtractColor(nsCSSProperty aProperty,
-                            nsStyleContext *aStyleContext)
+static inline void
+ExtractAnimationValue(nsCSSProperty aProperty,
+                      nsStyleContext* aStyleContext,
+                      nsStyleAnimation::Value& aResult)
+{
+  DebugOnly<bool> success =
+    nsStyleAnimation::ExtractComputedValue(aProperty, aStyleContext, aResult);
+  NS_ABORT_IF_FALSE(success,
+                    "aProperty must be extractable by nsStyleAnimation");
+}
+
+static nscolor
+ExtractColor(nsCSSProperty aProperty,
+             nsStyleContext *aStyleContext)
 {
   nsStyleAnimation::Value val;
-#ifdef DEBUG
-  bool success =
-#endif
-    nsStyleAnimation::ExtractComputedValue(aProperty, aStyleContext, val);
-  NS_ABORT_IF_FALSE(success,
-                    "aProperty must be extractable by nsStyleAnimation");
+  ExtractAnimationValue(aProperty, aStyleContext, val);
   return val.GetColorValue();
 }
 
+static nscolor
+ExtractColorLenient(nsCSSProperty aProperty,
+                    nsStyleContext *aStyleContext)
+{
+  nsStyleAnimation::Value val;
+  ExtractAnimationValue(aProperty, aStyleContext, val);
+  if (val.GetUnit() == nsStyleAnimation::eUnit_Color) {
+    return val.GetColorValue();
+  }
+  return NS_RGBA(0, 0, 0, 0);
+}
+
 struct ColorIndexSet {
   PRUint8 colorIndex, alphaIndex;
 };
 
 static const ColorIndexSet gVisitedIndices[2] = { { 0, 0 }, { 1, 0 } };
 
 nscolor
 nsStyleContext::GetVisitedDependentColor(nsCSSProperty aProperty)
@@ -729,25 +751,30 @@ nsStyleContext::GetVisitedDependentColor
                aProperty == eCSSProperty_border_left_color_value ||
                aProperty == eCSSProperty_outline_color ||
                aProperty == eCSSProperty__moz_column_rule_color ||
                aProperty == eCSSProperty_text_decoration_color ||
                aProperty == eCSSProperty_fill ||
                aProperty == eCSSProperty_stroke,
                "we need to add to nsStyleContext::CalcStyleDifference");
 
+  bool isPaintProperty = aProperty == eCSSProperty_fill ||
+                         aProperty == eCSSProperty_stroke;
+
   nscolor colors[2];
-  colors[0] = ExtractColor(aProperty, this);
+  colors[0] = isPaintProperty ? ExtractColorLenient(aProperty, this)
+                              : ExtractColor(aProperty, this);
 
   nsStyleContext *visitedStyle = this->GetStyleIfVisited();
   if (!visitedStyle) {
     return colors[0];
   }
 
-  colors[1] = ExtractColor(aProperty, visitedStyle);
+  colors[1] = isPaintProperty ? ExtractColorLenient(aProperty, visitedStyle)
+                              : ExtractColor(aProperty, visitedStyle);
 
   return nsStyleContext::CombineVisitedColors(colors,
                                               this->RelevantLinkVisited());
 }
 
 /* static */ nscolor
 nsStyleContext::CombineVisitedColors(nscolor *aColors, bool aLinkIsVisited)
 {