Make computed style output the a part of rgba/hsla colors, and also implement the 'transparent' keyword from css3-color. b=347912 r+sr=bzbarsky

This commit is contained in:
dbaron%dbaron.org 2007-01-25 02:03:02 +00:00
parent c88c6e09b4
commit edeb781845
10 changed files with 138 additions and 48 deletions

View File

@ -72,6 +72,7 @@ XPIDLSRCS = \
nsIDOMRGBColor.idl \
nsIDOMRect.idl \
nsIDOMViewCSS.idl \
nsIDOMNSRGBAColor.idl \
$(NULL)
include $(topsrcdir)/config/rules.mk

View File

@ -0,0 +1,46 @@
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 2000
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Johnny Stenback <jst@netscape.com> (original author)
* L. David Baron <dbaron@dbaron.org> (Mozilla Corporation)
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "nsIDOMRGBColor.idl"
[scriptable, uuid(742dc816-5134-4214-adfa-cad9dd3377cd)]
interface nsIDOMNSRGBAColor : nsIDOMRGBColor
{
readonly attribute nsIDOMCSSPrimitiveValue alpha;
};

View File

@ -178,6 +178,7 @@
#include "nsIDOMCSSRuleList.h"
#include "nsIDOMRect.h"
#include "nsIDOMRGBColor.h"
#include "nsIDOMNSRGBAColor.h"
// XBL related includes.
#include "nsIXBLService.h"
@ -2366,6 +2367,7 @@ nsDOMClassInfo::Init()
DOM_CLASSINFO_MAP_BEGIN_NO_CLASS_IF(CSSRGBColor, nsIDOMRGBColor)
DOM_CLASSINFO_MAP_ENTRY(nsIDOMRGBColor)
DOM_CLASSINFO_MAP_ENTRY(nsIDOMNSRGBAColor)
DOM_CLASSINFO_MAP_END
DOM_CLASSINFO_MAP_BEGIN(Range, nsIDOMRange)

View File

@ -2860,6 +2860,16 @@ PRBool CSSParserImpl::ParseColor(nsresult& aErrorCode, nsCSSValue& aValue)
nsCSSKeyword keyword = nsCSSKeywords::LookupKeyword(tk->mIdent);
if (eCSSKeyword_UNKNOWN < keyword) { // known keyword
PRInt32 value;
#ifdef MOZ_CAIRO_GFX
// XXX Once non-cairo is no longer supported, we should remove
// the special parsing of transparent for background-color and
// border-color. (It currently overrides this, since keywords
// are checked earlier in ParseVariant.)
#endif
if (mHandleAlphaColors && keyword == eCSSKeyword_transparent) {
aValue.SetColorValue(NS_RGBA(0, 0, 0, 0));
return PR_TRUE;
}
if (nsCSSProps::FindKeyword(keyword, nsCSSProps::kColorKTable, value)) {
aValue.SetIntValue(value, eCSSUnit_Integer);
return PR_TRUE;

View File

@ -464,30 +464,41 @@ nsComputedDOMStyle::GetBottom(nsIDOMCSSValue** aValue)
return GetOffsetWidthFor(NS_SIDE_BOTTOM, aValue);
}
nsDOMCSSRGBColor*
nsComputedDOMStyle::GetDOMCSSRGBColor(nscolor aColor)
nsresult
nsComputedDOMStyle::SetToRGBAColor(nsROCSSPrimitiveValue* aValue,
nscolor aColor)
{
if (NS_GET_A(aColor) == 0) {
aValue->SetIdent(nsGkAtoms::transparent);
return NS_OK;
}
nsROCSSPrimitiveValue *red = GetROCSSPrimitiveValue();
nsROCSSPrimitiveValue *green = GetROCSSPrimitiveValue();
nsROCSSPrimitiveValue *blue = GetROCSSPrimitiveValue();
nsROCSSPrimitiveValue *alpha = GetROCSSPrimitiveValue();
if (red && green && blue) {
nsDOMCSSRGBColor *rgbColor = new nsDOMCSSRGBColor(red, green, blue);
if (red && green && blue && alpha) {
nsDOMCSSRGBColor *rgbColor =
new nsDOMCSSRGBColor(red, green, blue, alpha, NS_GET_A(aColor) < 255);
if (rgbColor) {
red->SetNumber(NS_GET_R(aColor));
green->SetNumber(NS_GET_G(aColor));
blue->SetNumber(NS_GET_B(aColor));
alpha->SetNumber(float(NS_GET_A(aColor)) / 255.0f);
return rgbColor;
aValue->SetColor(rgbColor);
return NS_OK;
}
}
delete red;
delete green;
delete blue;
delete alpha;
return nsnull;
return NS_ERROR_OUT_OF_MEMORY;
}
nsresult
@ -498,15 +509,12 @@ nsComputedDOMStyle::GetColor(nsIDOMCSSValue** aValue)
const nsStyleColor* color = GetStyleColor();
nsDOMCSSRGBColor *rgb = GetDOMCSSRGBColor(color->mColor);
if (!rgb) {
nsresult rv = SetToRGBAColor(val, color->mColor);
if (NS_FAILED(rv)) {
delete val;
return NS_ERROR_OUT_OF_MEMORY;
return rv;
}
val->SetColor(rgb);
return CallQueryInterface(val, aValue);
}
@ -856,15 +864,11 @@ nsComputedDOMStyle::GetBackgroundColor(nsIDOMCSSValue** aValue)
nsCSSProps::kBackgroundColorKTable);
val->SetIdent(backgroundColor);
} else {
nsDOMCSSRGBColor *rgb = nsnull;
rgb = GetDOMCSSRGBColor(color->mBackgroundColor);
if (!rgb) {
nsresult rv = SetToRGBAColor(val, color->mBackgroundColor);
if (NS_FAILED(rv)) {
delete val;
return NS_ERROR_OUT_OF_MEMORY;
return rv;
}
val->SetColor(rgb);
}
return CallQueryInterface(val, aValue);
@ -1396,16 +1400,12 @@ nsComputedDOMStyle::GetOutlineColor(nsIDOMCSSValue** aValue)
nscolor color;
GetStyleOutline()->GetOutlineColor(color);
nsDOMCSSRGBColor *rgb = nsnull;
rgb = GetDOMCSSRGBColor(color);
if (!rgb) {
nsresult rv = SetToRGBAColor(val, color);
if (NS_FAILED(rv)) {
delete val;
return NS_ERROR_OUT_OF_MEMORY;
return rv;
}
val->SetColor(rgb);
return CallQueryInterface(val, aValue);
}
@ -2925,14 +2925,11 @@ nsComputedDOMStyle::GetBorderColorsFor(PRUint8 aSide, nsIDOMCSSValue** aValue)
if (borderColors->mTransparent) {
primitive->SetIdent(nsGkAtoms::transparent);
} else {
nsDOMCSSRGBColor *rgb = GetDOMCSSRGBColor(borderColors->mColor);
if (rgb) {
primitive->SetColor(rgb);
} else {
nsresult rv = SetToRGBAColor(primitive, borderColors->mColor);
if (NS_FAILED(rv)) {
delete valueList;
delete primitive;
return NS_ERROR_OUT_OF_MEMORY;
return rv;
}
}
@ -3014,15 +3011,13 @@ nsComputedDOMStyle::GetBorderColorFor(PRUint8 aSide, nsIDOMCSSValue** aValue)
const nsStyleColor* colorStruct = GetStyleColor();
color = colorStruct->mColor;
}
// XXX else?
nsDOMCSSRGBColor *rgb = GetDOMCSSRGBColor(color);
if (!rgb) {
nsresult rv = SetToRGBAColor(val, color);
if (NS_FAILED(rv)) {
delete val;
return NS_ERROR_OUT_OF_MEMORY;
return rv;
}
val->SetColor(rgb);
}
return CallQueryInterface(val, aValue);

View File

@ -272,7 +272,7 @@ private:
nsROCSSPrimitiveValue* GetROCSSPrimitiveValue();
nsDOMCSSValueList* GetROCSSValueList(PRBool aCommaDelimited);
nsDOMCSSRGBColor* GetDOMCSSRGBColor(nscolor aColor);
nsresult SetToRGBAColor(nsROCSSPrimitiveValue* aValue, nscolor aColor);
struct ComputedStyleMapEntry
{

View File

@ -46,8 +46,11 @@
nsDOMCSSRGBColor::nsDOMCSSRGBColor(nsIDOMCSSPrimitiveValue* aRed,
nsIDOMCSSPrimitiveValue* aGreen,
nsIDOMCSSPrimitiveValue* aBlue)
: mRed(aRed), mGreen(aGreen), mBlue(aBlue)
nsIDOMCSSPrimitiveValue* aBlue,
nsIDOMCSSPrimitiveValue* aAlpha,
PRBool aHasAlpha)
: mRed(aRed), mGreen(aGreen), mBlue(aBlue), mAlpha(aAlpha)
, mHasAlpha(aHasAlpha)
{
}
@ -57,6 +60,7 @@ nsDOMCSSRGBColor::~nsDOMCSSRGBColor(void)
NS_INTERFACE_MAP_BEGIN(nsDOMCSSRGBColor)
NS_INTERFACE_MAP_ENTRY(nsIDOMRGBColor)
NS_INTERFACE_MAP_ENTRY(nsIDOMNSRGBAColor)
NS_INTERFACE_MAP_ENTRY(nsISupports)
NS_INTERFACE_MAP_ENTRY_CONTENT_CLASSINFO(CSSRGBColor)
NS_INTERFACE_MAP_END
@ -91,3 +95,12 @@ nsDOMCSSRGBColor::GetBlue(nsIDOMCSSPrimitiveValue** aBlue)
NS_ADDREF(*aBlue);
return NS_OK;
}
NS_IMETHODIMP
nsDOMCSSRGBColor::GetAlpha(nsIDOMCSSPrimitiveValue** aAlpha)
{
NS_ENSURE_TRUE(mAlpha, NS_ERROR_NOT_INITIALIZED);
*aAlpha = mAlpha;
NS_ADDREF(*aAlpha);
return NS_OK;
}

View File

@ -42,26 +42,33 @@
#define nsDOMCSSRGBColor_h__
#include "nsISupports.h"
#include "nsIDOMRGBColor.h"
#include "nsIDOMNSRGBAColor.h"
#include "nsCOMPtr.h"
class nsIDOMCSSPrimitiveValue;
class nsDOMCSSRGBColor : public nsIDOMRGBColor {
class nsDOMCSSRGBColor : public nsIDOMNSRGBAColor {
public:
nsDOMCSSRGBColor(nsIDOMCSSPrimitiveValue* aRed,
nsIDOMCSSPrimitiveValue* aGreen,
nsIDOMCSSPrimitiveValue* aBlue);
nsIDOMCSSPrimitiveValue* aBlue,
nsIDOMCSSPrimitiveValue* aAlpha,
PRBool aHasAlpha);
virtual ~nsDOMCSSRGBColor(void);
NS_DECL_ISUPPORTS
NS_DECL_NSIDOMRGBCOLOR
NS_DECL_NSIDOMNSRGBACOLOR
PRBool HasAlpha() const { return mHasAlpha; }
private:
nsCOMPtr<nsIDOMCSSPrimitiveValue> mRed;
nsCOMPtr<nsIDOMCSSPrimitiveValue> mGreen;
nsCOMPtr<nsIDOMCSSPrimitiveValue> mBlue;
nsCOMPtr<nsIDOMCSSPrimitiveValue> mAlpha;
PRBool mHasAlpha;
};
#endif // nsDOMCSSRGBColor_h__

View File

@ -240,7 +240,10 @@ nsROCSSPrimitiveValue::GetCssText(nsAString& aCssText)
NS_NAMED_LITERAL_STRING(comma, ", ");
nsCOMPtr<nsIDOMCSSPrimitiveValue> colorCSSValue;
nsAutoString colorValue;
tmpStr.AssignLiteral("rgb(");
if (mValue.mColor->HasAlpha())
tmpStr.AssignLiteral("rgba(");
else
tmpStr.AssignLiteral("rgb(");
// get the red component
result = mValue.mColor->GetRed(getter_AddRefs(colorCSSValue));
@ -267,7 +270,20 @@ nsROCSSPrimitiveValue::GetCssText(nsAString& aCssText)
result = colorCSSValue->GetCssText(colorValue);
if (NS_FAILED(result))
break;
tmpStr.Append(colorValue + NS_LITERAL_STRING(")"));
tmpStr.Append(colorValue);
if (mValue.mColor->HasAlpha()) {
// get the alpha component
result = mValue.mColor->GetAlpha(getter_AddRefs(colorCSSValue));
if (NS_FAILED(result))
break;
result = colorCSSValue->GetCssText(colorValue);
if (NS_FAILED(result))
break;
tmpStr.Append(comma + colorValue);
}
tmpStr.Append(NS_LITERAL_STRING(")"));
break;
}

View File

@ -162,7 +162,7 @@ public:
mType = CSS_URI;
}
void SetColor(nsIDOMRGBColor* aColor)
void SetColor(nsDOMCSSRGBColor* aColor)
{
NS_PRECONDITION(aColor, "Null RGBColor being set!");
Reset();
@ -224,7 +224,7 @@ private:
union {
nscoord mTwips;
float mFloat;
nsIDOMRGBColor* mColor;
nsDOMCSSRGBColor* mColor;
nsIDOMRect* mRect;
PRUnichar* mString;
nsIURI* mURI;