From 961c31082cdf711a19f9149376ec17e1ef997b06 Mon Sep 17 00:00:00 2001 From: "L. David Baron" Date: Fri, 2 Apr 2010 18:58:25 -0700 Subject: [PATCH] Add function to nsStyleUtil for choosing the appropriate color from style data based on link visitedness. (Bug 147777) r=bzbarsky --- layout/generic/nsIFrame.h | 6 ++++ layout/style/nsStyleContext.cpp | 55 +++++++++++++++++++++++++++++++++ layout/style/nsStyleContext.h | 10 ++++++ 3 files changed, 71 insertions(+) diff --git a/layout/generic/nsIFrame.h b/layout/generic/nsIFrame.h index 81a99cbe6ba..b18b1d1bfa8 100644 --- a/layout/generic/nsIFrame.h +++ b/layout/generic/nsIFrame.h @@ -722,6 +722,12 @@ public: #include "nsStyleStructList.h" #undef STYLE_STRUCT +#ifdef _IMPL_NS_LAYOUT + /** Also forward GetVisitedDependentColor to the style context */ + nscolor GetVisitedDependentColor(nsCSSProperty aProperty) + { return mStyleContext->GetVisitedDependentColor(aProperty); } +#endif + /** * These methods are to access any additional style contexts that * the frame may be holding. These are contexts that are children diff --git a/layout/style/nsStyleContext.cpp b/layout/style/nsStyleContext.cpp index 1b16c209c76..5306f963e44 100644 --- a/layout/style/nsStyleContext.cpp +++ b/layout/style/nsStyleContext.cpp @@ -51,6 +51,7 @@ #include "nsRuleNode.h" #include "nsStyleContext.h" #include "prlog.h" +#include "nsStyleAnimation.h" #ifdef DEBUG // #define NOISY_DEBUG @@ -685,3 +686,57 @@ NS_NewStyleContext(nsStyleContext* aParentContext, return context; } +static nscolor ExtractColor(nsCSSProperty aProperty, + nsStyleContext *aStyleContext) +{ + nsStyleAnimation::Value val; +#ifdef DEBUG + PRBool success = +#endif + nsStyleAnimation::ExtractComputedValue(aProperty, aStyleContext, val); + NS_ABORT_IF_FALSE(success, + "aProperty must be extractable by nsStyleAnimation"); + return val.GetColorValue(); +} + +struct ColorIndexSet { + PRUint8 colorIndex, alphaIndex; +}; + +static const ColorIndexSet gVisitedIndices[2] = { { 0, 0 }, { 1, 0 } }; + +nscolor +nsStyleContext::GetVisitedDependentColor(nsCSSProperty aProperty) +{ + NS_ASSERTION(aProperty == eCSSProperty_color || + aProperty == eCSSProperty_background_color || + aProperty == eCSSProperty_border_top_color || + aProperty == eCSSProperty_border_right_color_value || + aProperty == eCSSProperty_border_bottom_color || + aProperty == eCSSProperty_border_left_color_value || + aProperty == eCSSProperty_outline_color || + aProperty == eCSSProperty__moz_column_rule_color || + aProperty == eCSSProperty_fill || + aProperty == eCSSProperty_stroke, + "we need to add to nsStyleContext::CalcStyleDifference"); + + nscolor colors[2]; + colors[0] = ExtractColor(aProperty, this); + + nsStyleContext *visitedStyle = this->GetStyleIfVisited(); + if (!visitedStyle) { + return colors[0]; + } + + colors[1] = ExtractColor(aProperty, visitedStyle); + + // NOTE: We want this code to have as little timing dependence as + // possible on whether this->RelevantLinkVisited() is true. + const ColorIndexSet &set = + gVisitedIndices[this->RelevantLinkVisited() ? 1 : 0]; + + nscolor colorColor = colors[set.colorIndex]; + nscolor alphaColor = colors[set.alphaIndex]; + return NS_RGBA(NS_GET_R(colorColor), NS_GET_G(colorColor), + NS_GET_B(colorColor), NS_GET_A(alphaColor)); +} diff --git a/layout/style/nsStyleContext.h b/layout/style/nsStyleContext.h index 778df6ab2dd..8bddf174f49 100644 --- a/layout/style/nsStyleContext.h +++ b/layout/style/nsStyleContext.h @@ -248,6 +248,16 @@ public: NS_HIDDEN_(nsChangeHint) CalcStyleDifference(nsStyleContext* aOther); + /** + * Get a color that depends on link-visitedness using this and + * this->GetStyleIfVisited(). + * + * aProperty must be a color-valued property that nsStyleAnimation + * knows how to extract. It must also be a property that we know to + * do change handling for in nsStyleContext::CalcDifference. + */ + NS_HIDDEN_(nscolor) GetVisitedDependentColor(nsCSSProperty aProperty); + #ifdef DEBUG NS_HIDDEN_(void) List(FILE* out, PRInt32 aIndent); #endif