From fc90ebe7cb27a219c1caca06ff0cfb5884fc8fa4 Mon Sep 17 00:00:00 2001 From: "tor%cs.brown.edu" Date: Thu, 9 Dec 2004 23:51:25 +0000 Subject: [PATCH] Bug 216559 - CSS3 currentColor. Patch by scootermorris@comcast.net. r=bz, sr=dbaron. git-svn-id: svn://10.0.0.236/trunk@166517 18797224-902f-48f8-a5cc-f745e15eee43 --- .../svg/content/src/nsSVGDefsElement.cpp | 3 +- .../content/svg/content/src/nsSVGElement.cpp | 8 ++++ .../content/svg/content/src/nsSVGElement.h | 1 + .../content/svg/content/src/nsSVGGElement.cpp | 3 +- .../svg/content/src/nsSVGGradientElement.cpp | 18 ++++++++ .../svg/content/src/nsSVGGraphicElement.cpp | 1 + mozilla/layout/base/nsStyleConsts.h | 1 + mozilla/layout/style/nsCSSKeywordList.h | 1 + mozilla/layout/style/nsCSSProps.cpp | 1 + mozilla/layout/style/nsRuleNode.cpp | 41 +++++++++++++------ 10 files changed, 64 insertions(+), 14 deletions(-) diff --git a/mozilla/content/svg/content/src/nsSVGDefsElement.cpp b/mozilla/content/svg/content/src/nsSVGDefsElement.cpp index 8f0af53d7d6..8358f4722e6 100644 --- a/mozilla/content/svg/content/src/nsSVGDefsElement.cpp +++ b/mozilla/content/svg/content/src/nsSVGDefsElement.cpp @@ -116,7 +116,8 @@ nsSVGDefsElement::IsAttributeMapped(const nsIAtom* name) const { static const MappedAttributeEntry* const map[] = { sTextContentElementsMap, - sFontSpecificationMap + sFontSpecificationMap, + sColorMap }; return FindAttributeDependence(name, map, NS_ARRAY_LENGTH(map)) || diff --git a/mozilla/content/svg/content/src/nsSVGElement.cpp b/mozilla/content/svg/content/src/nsSVGElement.cpp index c91ea100bf9..470ca74ed6c 100644 --- a/mozilla/content/svg/content/src/nsSVGElement.cpp +++ b/mozilla/content/svg/content/src/nsSVGElement.cpp @@ -433,6 +433,14 @@ nsSVGElement::sMarkersMap[] = { { nsnull } }; +// PresentationAttributes-Color +/* static */ const nsGenericElement::MappedAttributeEntry +nsSVGElement::sColorMap[] = { + { &nsSVGAtoms::color }, + { nsnull } +}; + + //---------------------------------------------------------------------- // nsIDOMNode methods diff --git a/mozilla/content/svg/content/src/nsSVGElement.h b/mozilla/content/svg/content/src/nsSVGElement.h index ad459095f55..c19011cc872 100644 --- a/mozilla/content/svg/content/src/nsSVGElement.h +++ b/mozilla/content/svg/content/src/nsSVGElement.h @@ -97,6 +97,7 @@ public: static const MappedAttributeEntry sGradientStopMap[]; static const MappedAttributeEntry sViewportsMap[]; static const MappedAttributeEntry sMarkersMap[]; + static const MappedAttributeEntry sColorMap[]; // nsIDOMNode NS_IMETHOD IsSupported(const nsAString& aFeature, const nsAString& aVersion, PRBool* aReturn); diff --git a/mozilla/content/svg/content/src/nsSVGGElement.cpp b/mozilla/content/svg/content/src/nsSVGGElement.cpp index 2bc9013245b..c9a74c03018 100644 --- a/mozilla/content/svg/content/src/nsSVGGElement.cpp +++ b/mozilla/content/svg/content/src/nsSVGGElement.cpp @@ -117,7 +117,8 @@ nsSVGGElement::IsAttributeMapped(const nsIAtom* name) const { static const MappedAttributeEntry* const map[] = { sTextContentElementsMap, - sFontSpecificationMap + sFontSpecificationMap, + sColorMap }; return FindAttributeDependence(name, map, NS_ARRAY_LENGTH(map)) || diff --git a/mozilla/content/svg/content/src/nsSVGGradientElement.cpp b/mozilla/content/svg/content/src/nsSVGGradientElement.cpp index e793e56042a..8a496f8441e 100644 --- a/mozilla/content/svg/content/src/nsSVGGradientElement.cpp +++ b/mozilla/content/svg/content/src/nsSVGGradientElement.cpp @@ -76,6 +76,9 @@ public: // nsISVGContent specializations: virtual void ParentChainChanged(); + // nsIStyledContent + NS_IMETHOD_(PRBool) IsAttributeMapped(const nsIAtom* aAttribute) const; + protected: // nsIDOMSVGGradientElement values @@ -234,6 +237,21 @@ void nsSVGGradientElement::ParentChainChanged() // properties, so no need to recurse into children here. } +//---------------------------------------------------------------------- +// nsIStyledContent methods + +NS_IMETHODIMP_(PRBool) +nsSVGGradientElement::IsAttributeMapped(const nsIAtom* name) const +{ + static const MappedAttributeEntry* const map[] = { + sGradientStopMap, + sColorMap + }; + + return FindAttributeDependence(name, map, NS_ARRAY_LENGTH(map)) || + nsSVGGradientElementBase::IsAttributeMapped(name); +} + //---------------------Linear Gradients------------------------ typedef nsSVGGradientElement nsSVGLinearGradientElementBase; diff --git a/mozilla/content/svg/content/src/nsSVGGraphicElement.cpp b/mozilla/content/svg/content/src/nsSVGGraphicElement.cpp index 39d0c5bd947..9ca84191bcf 100644 --- a/mozilla/content/svg/content/src/nsSVGGraphicElement.cpp +++ b/mozilla/content/svg/content/src/nsSVGGraphicElement.cpp @@ -328,6 +328,7 @@ nsSVGGraphicElement::IsAttributeMapped(const nsIAtom* name) const static const MappedAttributeEntry* const map[] = { sFillStrokeMap, sGraphicsMap, + sColorMap }; return FindAttributeDependence(name, map, NS_ARRAY_LENGTH(map)) || diff --git a/mozilla/layout/base/nsStyleConsts.h b/mozilla/layout/base/nsStyleConsts.h index c1f2c350152..aed6780e9ed 100644 --- a/mozilla/layout/base/nsStyleConsts.h +++ b/mozilla/layout/base/nsStyleConsts.h @@ -191,6 +191,7 @@ #define NS_COLOR_MOZ_HYPERLINKTEXT -1 #define NS_COLOR_MOZ_VISITEDHYPERLINKTEXT -2 #define NS_COLOR_MOZ_ACTIVEHYPERLINKTEXT -3 +#define NS_COLOR_CURRENTCOLOR -4 // See nsStyleBackground #define NS_STYLE_BG_COLOR_TRANSPARENT 0x01 diff --git a/mozilla/layout/style/nsCSSKeywordList.h b/mozilla/layout/style/nsCSSKeywordList.h index 25b6e0a9c84..806494c0862 100644 --- a/mozilla/layout/style/nsCSSKeywordList.h +++ b/mozilla/layout/style/nsCSSKeywordList.h @@ -228,6 +228,7 @@ CSS_KEY(copy, copy) CSS_KEY(crop, crop) CSS_KEY(cross, cross) CSS_KEY(crosshair, crosshair) +CSS_KEY(currentcolor, currentcolor) CSS_KEY(dashed, dashed) CSS_KEY(decimal, decimal) CSS_KEY(decimal-leading-zero, decimal_leading_zero) diff --git a/mozilla/layout/style/nsCSSProps.cpp b/mozilla/layout/style/nsCSSProps.cpp index 4193019c1d2..2046596232c 100644 --- a/mozilla/layout/style/nsCSSProps.cpp +++ b/mozilla/layout/style/nsCSSProps.cpp @@ -427,6 +427,7 @@ const PRInt32 nsCSSProps::kColorKTable[] = { eCSSKeyword__moz_menuhover, nsILookAndFeel::eColor__moz_menuhover, eCSSKeyword__moz_menuhovertext, nsILookAndFeel::eColor__moz_menuhovertext, eCSSKeyword__moz_visitedhyperlinktext, NS_COLOR_MOZ_VISITEDHYPERLINKTEXT, + eCSSKeyword_currentcolor, NS_COLOR_CURRENTCOLOR, eCSSKeyword_UNKNOWN,-1 }; diff --git a/mozilla/layout/style/nsRuleNode.cpp b/mozilla/layout/style/nsRuleNode.cpp index d44e4dd97ab..dfbd7031176 100644 --- a/mozilla/layout/style/nsRuleNode.cpp +++ b/mozilla/layout/style/nsRuleNode.cpp @@ -310,7 +310,8 @@ static PRBool SetCoord(const nsCSSValue& aValue, nsStyleCoord& aCoord, } static PRBool SetColor(const nsCSSValue& aValue, const nscolor aParentColor, - nsPresContext* aPresContext, nscolor& aResult, PRBool& aInherited) + nsPresContext* aPresContext, nsStyleContext *aContext, + nscolor& aResult, PRBool& aInherited) { PRBool result = PR_FALSE; nsCSSUnit unit = aValue.GetUnit(); @@ -348,10 +349,17 @@ static PRBool SetColor(const nsCSSValue& aValue, const nscolor aParentColor, case NS_COLOR_MOZ_ACTIVEHYPERLINKTEXT: aResult = aPresContext->DefaultActiveLinkColor(); break; + case NS_COLOR_CURRENTCOLOR: + // The data computed from this can't be shared in the rule tree + // because they could be used on a node with a different color + aInherited = PR_TRUE; + aResult = aContext->GetStyleColor()->mColor; + break; default: NS_NOTREACHED("Should never have an unknown negative colorID."); break; } + result = PR_TRUE; } } else if (eCSSUnit_Inherit == unit) { @@ -2928,8 +2936,16 @@ nsRuleNode::ComputeColorData(nsStyleStruct* aStartStruct, parentColor = color; // color: color, string, inherit - SetColor(colorData.mColor, parentColor->mColor, mPresContext, color->mColor, - inherited); + // Special case for currentColor. According to CSS3, setting color to 'currentColor' + // should behave as if it is inherited + if (colorData.mColor.GetUnit() == eCSSUnit_Integer && + colorData.mColor.GetIntValue() == NS_COLOR_CURRENTCOLOR) { + color->mColor = parentColor->mColor; + inherited = PR_TRUE; + } else { + SetColor(colorData.mColor, parentColor->mColor, mPresContext, aContext, color->mColor, + inherited); + } if (inherited) // We inherited, and therefore can't be cached in the rule node. We have to be put right on the @@ -2983,7 +2999,7 @@ nsRuleNode::ComputeBackgroundData(nsStyleStruct* aStartStruct, inherited = PR_TRUE; } else if (SetColor(colorData.mBackColor, parentBG->mBackgroundColor, - mPresContext, bg->mBackgroundColor, inherited)) { + mPresContext, aContext, bg->mBackgroundColor, inherited)) { bg->mBackgroundFlags &= ~NS_STYLE_BG_COLOR_TRANSPARENT; } else if (eCSSUnit_Enumerated == colorData.mBackColor.GetUnit()) { @@ -3264,7 +3280,7 @@ nsRuleNode::ComputeBorderData(nsStyleStruct* aStartStruct, border->EnsureBorderColors(); border->ClearBorderColors(side); while (list) { - if (SetColor(list->mValue, unused, mPresContext, borderColor, inherited)) + if (SetColor(list->mValue, unused, mPresContext, aContext, borderColor, inherited)) border->AppendBorderColor(side, borderColor, PR_FALSE); else if (eCSSUnit_Enumerated == list->mValue.GetUnit() && NS_STYLE_COLOR_TRANSPARENT == list->mValue.GetIntValue()) @@ -3304,7 +3320,7 @@ nsRuleNode::ComputeBorderData(nsStyleStruct* aStartStruct, border->SetBorderToForeground(side); } } - else if (SetColor(value, unused, mPresContext, borderColor, inherited)) { + else if (SetColor(value, unused, mPresContext, aContext, borderColor, inherited)) { border->SetBorderColor(side, borderColor); } else if (eCSSUnit_Enumerated == value.GetUnit()) { @@ -3469,7 +3485,7 @@ nsRuleNode::ComputeOutlineData(nsStyleStruct* aStartStruct, else outline->SetOutlineInvert(); } - else if (SetColor(marginData.mOutlineColor, unused, mPresContext, outlineColor, inherited)) + else if (SetColor(marginData.mOutlineColor, unused, mPresContext, aContext, outlineColor, inherited)) outline->SetOutlineColor(outlineColor); else if (eCSSUnit_Enumerated == marginData.mOutlineColor.GetUnit()) outline->SetOutlineInvert(); @@ -4339,7 +4355,8 @@ nsRuleNode::ComputeColumnData(nsStyleStruct* aStartStruct, #ifdef MOZ_SVG static void SetSVGPaint(const nsCSSValue& aValue, const nsStyleSVGPaint& parentPaint, - nsPresContext* aPresContext, nsStyleSVGPaint& aResult, PRBool& aInherited) + nsPresContext* aPresContext, nsStyleContext *aContext, + nsStyleSVGPaint& aResult, PRBool& aInherited) { if (aValue.GetUnit() == eCSSUnit_Inherit) { aResult = parentPaint; @@ -4350,7 +4367,7 @@ SetSVGPaint(const nsCSSValue& aValue, const nsStyleSVGPaint& parentPaint, aResult.mType = eStyleSVGPaintType_Server; aResult.mPaint.mPaintServer = aValue.GetURLValue(); NS_IF_ADDREF(aResult.mPaint.mPaintServer); - } else if (SetColor(aValue, parentPaint.mPaint.mColor, aPresContext, aResult.mPaint.mColor, aInherited)) { + } else if (SetColor(aValue, parentPaint.mPaint.mColor, aPresContext, aContext, aResult.mPaint.mColor, aInherited)) { aResult.mType = eStyleSVGPaintType_Color; } else { // XXX Check for "currentColor" @@ -4433,7 +4450,7 @@ nsRuleNode::ComputeSVGData(nsStyleStruct* aStartStruct, parentSVG = svg; // fill: - SetSVGPaint(SVGData.mFill, parentSVG->mFill, mPresContext, svg->mFill, inherited); + SetSVGPaint(SVGData.mFill, parentSVG->mFill, mPresContext, aContext, svg->mFill, inherited); // fill-opacity: SetSVGOpacity(SVGData.mFillOpacity, parentSVG->mFillOpacity, svg->mFillOpacity, inherited); @@ -4478,7 +4495,7 @@ nsRuleNode::ComputeSVGData(nsStyleStruct* aStartStruct, } // stop-color: - SetSVGPaint(SVGData.mStopColor, parentSVG->mStopColor, mPresContext, svg->mStopColor, inherited); + SetSVGPaint(SVGData.mStopColor, parentSVG->mStopColor, mPresContext, aContext, svg->mStopColor, inherited); // stop-opacity: SetSVGOpacity(SVGData.mStopOpacity, parentSVG->mStopOpacity, svg->mStopOpacity, inherited); @@ -4505,7 +4522,7 @@ nsRuleNode::ComputeSVGData(nsStyleStruct* aStartStruct, } // stroke: - SetSVGPaint(SVGData.mStroke, parentSVG->mStroke, mPresContext, svg->mStroke, inherited); + SetSVGPaint(SVGData.mStroke, parentSVG->mStroke, mPresContext, aContext, svg->mStroke, inherited); // stroke-dasharray: , none, inherit nsCSSValueList *list = SVGData.mStrokeDasharray;