Store the original string for URL values so that composer and CSSOM do not make relative URLs absolute. b=167262 r+sr=bzbarsky

This commit is contained in:
dbaron%dbaron.org 2003-10-30 01:45:37 +00:00
parent ec0bfea4ea
commit e29417ff7f
9 changed files with 157 additions and 62 deletions

View File

@ -3445,8 +3445,15 @@ nsGenericHTMLElement::MapBackgroundAttributesInto(const nsIHTMLMappedAttributes*
nsCOMPtr<nsIURI> uri; nsCOMPtr<nsIURI> uri;
rv = nsContentUtils::NewURIWithDocumentCharset( rv = nsContentUtils::NewURIWithDocumentCharset(
getter_AddRefs(uri), spec, doc, docURL); getter_AddRefs(uri), spec, doc, docURL);
if (NS_SUCCEEDED(rv)) if (NS_SUCCEEDED(rv)) {
aData->mColorData->mBackImage.SetURLValue(uri); nsCSSValue::URL *url = new nsCSSValue::URL(uri, spec.get());
if (url) {
if (url->mString)
aData->mColorData->mBackImage.SetURLValue(url);
else
delete url;
}
}
} }
} }
} }

View File

@ -405,10 +405,8 @@ PRBool nsCSSDeclaration::AppendCSSValueToString(nsCSSProperty aProperty, const n
aResult.Append(PRUnichar(')')); aResult.Append(PRUnichar(')'));
} }
else if (eCSSUnit_URL == unit) { else if (eCSSUnit_URL == unit) {
nsCAutoString spec;
aValue.GetURLValue()->GetSpec(spec);
aResult.Append(NS_LITERAL_STRING("url(") + aResult.Append(NS_LITERAL_STRING("url(") +
NS_ConvertUTF8toUCS2(spec) + nsDependentString(aValue.GetOriginalURLValue()) +
NS_LITERAL_STRING(")")); NS_LITERAL_STRING(")"));
} }
else if (eCSSUnit_Percent == unit) { else if (eCSSUnit_Percent == unit) {

View File

@ -3612,12 +3612,17 @@ PRBool CSSParserImpl::ParseURL(PRInt32& aErrorCode, nsCSSValue& aValue)
if ((eCSSToken_String == tk->mType) || (eCSSToken_URL == tk->mType)) { if ((eCSSToken_String == tk->mType) || (eCSSToken_URL == tk->mType)) {
// Translate url into an absolute url if the url is relative to // Translate url into an absolute url if the url is relative to
// the style sheet. // the style sheet.
// XXX editors won't like this - too bad for now nsCOMPtr<nsIURI> uri;
nsCOMPtr<nsIURI> url; NS_NewURI(getter_AddRefs(uri), tk->mIdent, nsnull, mURL);
NS_NewURI(getter_AddRefs(url), tk->mIdent, nsnull, mURL);
if (ExpectSymbol(aErrorCode, ')', PR_TRUE)) { if (ExpectSymbol(aErrorCode, ')', PR_TRUE)) {
// Set a null value on failure. Most failure cases should be // Set a null value on failure. Most failure cases should be
// NS_ERROR_MALFORMED_URI. // NS_ERROR_MALFORMED_URI.
nsCSSValue::URL *url = new nsCSSValue::URL(uri, tk->mIdent.get());
if (!url || !url->mString) {
aErrorCode = NS_ERROR_OUT_OF_MEMORY;
delete url;
return PR_FALSE;
}
aValue.SetURLValue(url); aValue.SetURLValue(url);
return PR_TRUE; return PR_TRUE;
} }

View File

@ -90,11 +90,11 @@ nsCSSValue::nsCSSValue(nscolor aValue)
mValue.mColor = aValue; mValue.mColor = aValue;
} }
nsCSSValue::nsCSSValue(nsIURI* aValue) nsCSSValue::nsCSSValue(nsCSSValue::URL* aValue)
: mUnit(eCSSUnit_URL) : mUnit(eCSSUnit_URL)
{ {
mValue.mURL = aValue; mValue.mURL = aValue;
NS_IF_ADDREF(aValue); mValue.mURL->AddRef();
} }
nsCSSValue::nsCSSValue(const nsCSSValue& aCopy) nsCSSValue::nsCSSValue(const nsCSSValue& aCopy)
@ -116,7 +116,7 @@ nsCSSValue::nsCSSValue(const nsCSSValue& aCopy)
} }
else if (eCSSUnit_URL == mUnit){ else if (eCSSUnit_URL == mUnit){
mValue.mURL = aCopy.mValue.mURL; mValue.mURL = aCopy.mValue.mURL;
NS_IF_ADDREF(mValue.mURL); mValue.mURL->AddRef();
} }
else { else {
mValue.mFloat = aCopy.mValue.mFloat; mValue.mFloat = aCopy.mValue.mFloat;
@ -140,7 +140,7 @@ nsCSSValue& nsCSSValue::operator=(const nsCSSValue& aCopy)
} }
else if (eCSSUnit_URL == mUnit){ else if (eCSSUnit_URL == mUnit){
mValue.mURL = aCopy.mValue.mURL; mValue.mURL = aCopy.mValue.mURL;
NS_IF_ADDREF(mValue.mURL); mValue.mURL->AddRef();
} }
else { else {
mValue.mFloat = aCopy.mValue.mFloat; mValue.mFloat = aCopy.mValue.mFloat;
@ -168,11 +168,7 @@ PRBool nsCSSValue::operator==(const nsCSSValue& aOther) const
return mValue.mColor == aOther.mValue.mColor; return mValue.mColor == aOther.mValue.mColor;
} }
else if (eCSSUnit_URL == mUnit) { else if (eCSSUnit_URL == mUnit) {
PRBool eq; return *mValue.mURL == *aOther.mValue.mURL;
return (mValue.mURL == aOther.mValue.mURL || // handles null == null
(mValue.mURL && aOther.mValue.mURL &&
NS_SUCCEEDED(mValue.mURL->Equals(aOther.mValue.mURL, &eq)) &&
eq));
} }
else { else {
return mValue.mFloat == aOther.mValue.mFloat; return mValue.mFloat == aOther.mValue.mFloat;
@ -211,12 +207,12 @@ void nsCSSValue::SetColorValue(nscolor aValue)
mValue.mColor = aValue; mValue.mColor = aValue;
} }
void nsCSSValue::SetURLValue(nsIURI* aValue) void nsCSSValue::SetURLValue(nsCSSValue::URL* aValue)
{ {
Reset(); Reset();
mUnit = eCSSUnit_URL; mUnit = eCSSUnit_URL;
mValue.mURL = aValue; mValue.mURL = aValue;
NS_IF_ADDREF(mValue.mURL); mValue.mURL->AddRef();
} }
void nsCSSValue::SetAutoValue(void) void nsCSSValue::SetAutoValue(void)
@ -319,13 +315,7 @@ void nsCSSValue::AppendToString(nsAString& aBuffer,
aBuffer.Append(PRUnichar(')')); aBuffer.Append(PRUnichar(')'));
} }
else if (eCSSUnit_URL == mUnit) { else if (eCSSUnit_URL == mUnit) {
if (mValue.mURL) { aBuffer.Append(mValue.mURL->mString);
nsCAutoString spec;
mValue.mURL->GetSpec(spec);
AppendUTF8toUTF16(spec, aBuffer);
} else {
aBuffer.Append(NS_LITERAL_STRING("url(invalid-url:)"));
}
} }
else if (eCSSUnit_Percent == mUnit) { else if (eCSSUnit_Percent == mUnit) {
nsAutoString floatString; nsAutoString floatString;

View File

@ -45,6 +45,7 @@
#include "nsCSSProperty.h" #include "nsCSSProperty.h"
#include "nsUnitConversion.h" #include "nsUnitConversion.h"
#include "nsIURI.h" #include "nsIURI.h"
#include "nsCOMPtr.h"
enum nsCSSUnit { enum nsCSSUnit {
eCSSUnit_Null = 0, // (n/a) null unit, value is not specified eCSSUnit_Null = 0, // (n/a) null unit, value is not specified
@ -57,7 +58,7 @@ enum nsCSSUnit {
eCSSUnit_Attr = 11, // (PRUnichar*) a attr(string) value eCSSUnit_Attr = 11, // (PRUnichar*) a attr(string) value
eCSSUnit_Counter = 12, // (PRUnichar*) a counter(string,[string]) value eCSSUnit_Counter = 12, // (PRUnichar*) a counter(string,[string]) value
eCSSUnit_Counters = 13, // (PRUnichar*) a counters(string,string[,string]) value eCSSUnit_Counters = 13, // (PRUnichar*) a counters(string,string[,string]) value
eCSSUnit_URL = 14, // (nsIURI*) a URL value (null == invalid URI) eCSSUnit_URL = 14, // (nsCSSValue::URL*) value
eCSSUnit_Integer = 50, // (int) simple value eCSSUnit_Integer = 50, // (int) simple value
eCSSUnit_Enumerated = 51, // (int) value has enumerated meaning eCSSUnit_Enumerated = 51, // (int) value has enumerated meaning
eCSSUnit_Color = 80, // (color) an RGBA value eCSSUnit_Color = 80, // (color) an RGBA value
@ -114,6 +115,9 @@ enum nsCSSUnit {
class nsCSSValue { class nsCSSValue {
public: public:
struct URL;
friend struct URL;
// for valueless units only (null, auto, inherit, none, normal) // for valueless units only (null, auto, inherit, none, normal)
nsCSSValue(nsCSSUnit aUnit = eCSSUnit_Null) nsCSSValue(nsCSSUnit aUnit = eCSSUnit_Null)
: mUnit(aUnit) : mUnit(aUnit)
@ -129,7 +133,7 @@ public:
nsCSSValue(float aValue, nsCSSUnit aUnit); nsCSSValue(float aValue, nsCSSUnit aUnit);
nsCSSValue(const nsAString& aValue, nsCSSUnit aUnit); nsCSSValue(const nsAString& aValue, nsCSSUnit aUnit);
nsCSSValue(nscolor aValue); nsCSSValue(nscolor aValue);
nsCSSValue(nsIURI* aValue); nsCSSValue(nsCSSValue::URL* aValue);
nsCSSValue(const nsCSSValue& aCopy); nsCSSValue(const nsCSSValue& aCopy);
~nsCSSValue(void) ~nsCSSValue(void)
{ {
@ -205,7 +209,13 @@ public:
nsIURI* GetURLValue(void) const nsIURI* GetURLValue(void) const
{ {
NS_ASSERTION(mUnit == eCSSUnit_URL, "not a URL value"); NS_ASSERTION(mUnit == eCSSUnit_URL, "not a URL value");
return mValue.mURL; return mValue.mURL->mURI;
}
const PRUnichar* GetOriginalURLValue(void) const
{
NS_ASSERTION(mUnit == eCSSUnit_URL, "not a URL value");
return mValue.mURL->mString;
} }
@ -253,7 +263,7 @@ public:
(nsnull != mValue.mString)) { (nsnull != mValue.mString)) {
nsCRT::free(mValue.mString); nsCRT::free(mValue.mString);
} else if (eCSSUnit_URL == mUnit) { } else if (eCSSUnit_URL == mUnit) {
NS_IF_RELEASE(mValue.mURL); mValue.mURL->Release();
} }
mUnit = eCSSUnit_Null; mUnit = eCSSUnit_Null;
mValue.mInt = 0; mValue.mInt = 0;
@ -279,7 +289,7 @@ public:
void SetStringValue(const nsAString& aValue, nsCSSUnit aUnit); void SetStringValue(const nsAString& aValue, nsCSSUnit aUnit);
void SetColorValue(nscolor aValue); void SetColorValue(nscolor aValue);
void SetURLValue(nsIURI* aURI); void SetURLValue(nsCSSValue::URL* aURI);
void SetAutoValue(void); void SetAutoValue(void);
void SetInheritValue(void); void SetInheritValue(void);
void SetInitialValue(void); void SetInitialValue(void);
@ -291,6 +301,47 @@ public:
void AppendToString(nsAString& aBuffer, nsCSSProperty aPropID = eCSSProperty_UNKNOWN) const; void AppendToString(nsAString& aBuffer, nsCSSProperty aPropID = eCSSProperty_UNKNOWN) const;
void ToString(nsAString& aBuffer, nsCSSProperty aPropID = eCSSProperty_UNKNOWN) const; void ToString(nsAString& aBuffer, nsCSSProperty aPropID = eCSSProperty_UNKNOWN) const;
MOZ_DECL_CTOR_COUNTER(nsCSSValue::URL)
struct URL {
// Caller must delete this object immediately if the allocation of
// |mString| fails.
URL(nsIURI* aURI, const PRUnichar* aString)
: mURI(aURI),
mString(nsCRT::strdup(aString)),
mRefCnt(0)
{
MOZ_COUNT_CTOR(nsCSSValue::URL);
}
~URL()
{
// null |mString| isn't valid normally, but is checked by callers
// of the constructor
if (mString)
nsCRT::free(mString);
MOZ_COUNT_DTOR(nsCSSValue::URL);
}
PRBool operator==(const URL& aOther)
{
PRBool eq;
return nsCRT::strcmp(mString, aOther.mString) == 0 &&
(mURI == aOther.mURI || // handles null == null
(mURI && aOther.mURI &&
NS_SUCCEEDED(mURI->Equals(aOther.mURI, &eq)) &&
eq));
}
nsCOMPtr<nsIURI> mURI; // null == invalid URL
PRUnichar* mString;
void AddRef() { ++mRefCnt; }
void Release() { if (--mRefCnt == 0) delete this; }
private:
nsrefcnt mRefCnt;
};
protected: protected:
nsCSSUnit mUnit; nsCSSUnit mUnit;
union { union {
@ -298,7 +349,7 @@ protected:
float mFloat; float mFloat;
PRUnichar* mString; PRUnichar* mString;
nscolor mColor; nscolor mColor;
nsIURI* mURL; URL* mURL;
} mValue; } mValue;
}; };

View File

@ -405,10 +405,8 @@ PRBool nsCSSDeclaration::AppendCSSValueToString(nsCSSProperty aProperty, const n
aResult.Append(PRUnichar(')')); aResult.Append(PRUnichar(')'));
} }
else if (eCSSUnit_URL == unit) { else if (eCSSUnit_URL == unit) {
nsCAutoString spec;
aValue.GetURLValue()->GetSpec(spec);
aResult.Append(NS_LITERAL_STRING("url(") + aResult.Append(NS_LITERAL_STRING("url(") +
NS_ConvertUTF8toUCS2(spec) + nsDependentString(aValue.GetOriginalURLValue()) +
NS_LITERAL_STRING(")")); NS_LITERAL_STRING(")"));
} }
else if (eCSSUnit_Percent == unit) { else if (eCSSUnit_Percent == unit) {

View File

@ -3612,12 +3612,17 @@ PRBool CSSParserImpl::ParseURL(PRInt32& aErrorCode, nsCSSValue& aValue)
if ((eCSSToken_String == tk->mType) || (eCSSToken_URL == tk->mType)) { if ((eCSSToken_String == tk->mType) || (eCSSToken_URL == tk->mType)) {
// Translate url into an absolute url if the url is relative to // Translate url into an absolute url if the url is relative to
// the style sheet. // the style sheet.
// XXX editors won't like this - too bad for now nsCOMPtr<nsIURI> uri;
nsCOMPtr<nsIURI> url; NS_NewURI(getter_AddRefs(uri), tk->mIdent, nsnull, mURL);
NS_NewURI(getter_AddRefs(url), tk->mIdent, nsnull, mURL);
if (ExpectSymbol(aErrorCode, ')', PR_TRUE)) { if (ExpectSymbol(aErrorCode, ')', PR_TRUE)) {
// Set a null value on failure. Most failure cases should be // Set a null value on failure. Most failure cases should be
// NS_ERROR_MALFORMED_URI. // NS_ERROR_MALFORMED_URI.
nsCSSValue::URL *url = new nsCSSValue::URL(uri, tk->mIdent.get());
if (!url || !url->mString) {
aErrorCode = NS_ERROR_OUT_OF_MEMORY;
delete url;
return PR_FALSE;
}
aValue.SetURLValue(url); aValue.SetURLValue(url);
return PR_TRUE; return PR_TRUE;
} }

View File

@ -90,11 +90,11 @@ nsCSSValue::nsCSSValue(nscolor aValue)
mValue.mColor = aValue; mValue.mColor = aValue;
} }
nsCSSValue::nsCSSValue(nsIURI* aValue) nsCSSValue::nsCSSValue(nsCSSValue::URL* aValue)
: mUnit(eCSSUnit_URL) : mUnit(eCSSUnit_URL)
{ {
mValue.mURL = aValue; mValue.mURL = aValue;
NS_IF_ADDREF(aValue); mValue.mURL->AddRef();
} }
nsCSSValue::nsCSSValue(const nsCSSValue& aCopy) nsCSSValue::nsCSSValue(const nsCSSValue& aCopy)
@ -116,7 +116,7 @@ nsCSSValue::nsCSSValue(const nsCSSValue& aCopy)
} }
else if (eCSSUnit_URL == mUnit){ else if (eCSSUnit_URL == mUnit){
mValue.mURL = aCopy.mValue.mURL; mValue.mURL = aCopy.mValue.mURL;
NS_IF_ADDREF(mValue.mURL); mValue.mURL->AddRef();
} }
else { else {
mValue.mFloat = aCopy.mValue.mFloat; mValue.mFloat = aCopy.mValue.mFloat;
@ -140,7 +140,7 @@ nsCSSValue& nsCSSValue::operator=(const nsCSSValue& aCopy)
} }
else if (eCSSUnit_URL == mUnit){ else if (eCSSUnit_URL == mUnit){
mValue.mURL = aCopy.mValue.mURL; mValue.mURL = aCopy.mValue.mURL;
NS_IF_ADDREF(mValue.mURL); mValue.mURL->AddRef();
} }
else { else {
mValue.mFloat = aCopy.mValue.mFloat; mValue.mFloat = aCopy.mValue.mFloat;
@ -168,11 +168,7 @@ PRBool nsCSSValue::operator==(const nsCSSValue& aOther) const
return mValue.mColor == aOther.mValue.mColor; return mValue.mColor == aOther.mValue.mColor;
} }
else if (eCSSUnit_URL == mUnit) { else if (eCSSUnit_URL == mUnit) {
PRBool eq; return *mValue.mURL == *aOther.mValue.mURL;
return (mValue.mURL == aOther.mValue.mURL || // handles null == null
(mValue.mURL && aOther.mValue.mURL &&
NS_SUCCEEDED(mValue.mURL->Equals(aOther.mValue.mURL, &eq)) &&
eq));
} }
else { else {
return mValue.mFloat == aOther.mValue.mFloat; return mValue.mFloat == aOther.mValue.mFloat;
@ -211,12 +207,12 @@ void nsCSSValue::SetColorValue(nscolor aValue)
mValue.mColor = aValue; mValue.mColor = aValue;
} }
void nsCSSValue::SetURLValue(nsIURI* aValue) void nsCSSValue::SetURLValue(nsCSSValue::URL* aValue)
{ {
Reset(); Reset();
mUnit = eCSSUnit_URL; mUnit = eCSSUnit_URL;
mValue.mURL = aValue; mValue.mURL = aValue;
NS_IF_ADDREF(mValue.mURL); mValue.mURL->AddRef();
} }
void nsCSSValue::SetAutoValue(void) void nsCSSValue::SetAutoValue(void)
@ -319,13 +315,7 @@ void nsCSSValue::AppendToString(nsAString& aBuffer,
aBuffer.Append(PRUnichar(')')); aBuffer.Append(PRUnichar(')'));
} }
else if (eCSSUnit_URL == mUnit) { else if (eCSSUnit_URL == mUnit) {
if (mValue.mURL) { aBuffer.Append(mValue.mURL->mString);
nsCAutoString spec;
mValue.mURL->GetSpec(spec);
AppendUTF8toUTF16(spec, aBuffer);
} else {
aBuffer.Append(NS_LITERAL_STRING("url(invalid-url:)"));
}
} }
else if (eCSSUnit_Percent == mUnit) { else if (eCSSUnit_Percent == mUnit) {
nsAutoString floatString; nsAutoString floatString;

View File

@ -45,6 +45,7 @@
#include "nsCSSProperty.h" #include "nsCSSProperty.h"
#include "nsUnitConversion.h" #include "nsUnitConversion.h"
#include "nsIURI.h" #include "nsIURI.h"
#include "nsCOMPtr.h"
enum nsCSSUnit { enum nsCSSUnit {
eCSSUnit_Null = 0, // (n/a) null unit, value is not specified eCSSUnit_Null = 0, // (n/a) null unit, value is not specified
@ -57,7 +58,7 @@ enum nsCSSUnit {
eCSSUnit_Attr = 11, // (PRUnichar*) a attr(string) value eCSSUnit_Attr = 11, // (PRUnichar*) a attr(string) value
eCSSUnit_Counter = 12, // (PRUnichar*) a counter(string,[string]) value eCSSUnit_Counter = 12, // (PRUnichar*) a counter(string,[string]) value
eCSSUnit_Counters = 13, // (PRUnichar*) a counters(string,string[,string]) value eCSSUnit_Counters = 13, // (PRUnichar*) a counters(string,string[,string]) value
eCSSUnit_URL = 14, // (nsIURI*) a URL value (null == invalid URI) eCSSUnit_URL = 14, // (nsCSSValue::URL*) value
eCSSUnit_Integer = 50, // (int) simple value eCSSUnit_Integer = 50, // (int) simple value
eCSSUnit_Enumerated = 51, // (int) value has enumerated meaning eCSSUnit_Enumerated = 51, // (int) value has enumerated meaning
eCSSUnit_Color = 80, // (color) an RGBA value eCSSUnit_Color = 80, // (color) an RGBA value
@ -114,6 +115,9 @@ enum nsCSSUnit {
class nsCSSValue { class nsCSSValue {
public: public:
struct URL;
friend struct URL;
// for valueless units only (null, auto, inherit, none, normal) // for valueless units only (null, auto, inherit, none, normal)
nsCSSValue(nsCSSUnit aUnit = eCSSUnit_Null) nsCSSValue(nsCSSUnit aUnit = eCSSUnit_Null)
: mUnit(aUnit) : mUnit(aUnit)
@ -129,7 +133,7 @@ public:
nsCSSValue(float aValue, nsCSSUnit aUnit); nsCSSValue(float aValue, nsCSSUnit aUnit);
nsCSSValue(const nsAString& aValue, nsCSSUnit aUnit); nsCSSValue(const nsAString& aValue, nsCSSUnit aUnit);
nsCSSValue(nscolor aValue); nsCSSValue(nscolor aValue);
nsCSSValue(nsIURI* aValue); nsCSSValue(nsCSSValue::URL* aValue);
nsCSSValue(const nsCSSValue& aCopy); nsCSSValue(const nsCSSValue& aCopy);
~nsCSSValue(void) ~nsCSSValue(void)
{ {
@ -205,7 +209,13 @@ public:
nsIURI* GetURLValue(void) const nsIURI* GetURLValue(void) const
{ {
NS_ASSERTION(mUnit == eCSSUnit_URL, "not a URL value"); NS_ASSERTION(mUnit == eCSSUnit_URL, "not a URL value");
return mValue.mURL; return mValue.mURL->mURI;
}
const PRUnichar* GetOriginalURLValue(void) const
{
NS_ASSERTION(mUnit == eCSSUnit_URL, "not a URL value");
return mValue.mURL->mString;
} }
@ -253,7 +263,7 @@ public:
(nsnull != mValue.mString)) { (nsnull != mValue.mString)) {
nsCRT::free(mValue.mString); nsCRT::free(mValue.mString);
} else if (eCSSUnit_URL == mUnit) { } else if (eCSSUnit_URL == mUnit) {
NS_IF_RELEASE(mValue.mURL); mValue.mURL->Release();
} }
mUnit = eCSSUnit_Null; mUnit = eCSSUnit_Null;
mValue.mInt = 0; mValue.mInt = 0;
@ -279,7 +289,7 @@ public:
void SetStringValue(const nsAString& aValue, nsCSSUnit aUnit); void SetStringValue(const nsAString& aValue, nsCSSUnit aUnit);
void SetColorValue(nscolor aValue); void SetColorValue(nscolor aValue);
void SetURLValue(nsIURI* aURI); void SetURLValue(nsCSSValue::URL* aURI);
void SetAutoValue(void); void SetAutoValue(void);
void SetInheritValue(void); void SetInheritValue(void);
void SetInitialValue(void); void SetInitialValue(void);
@ -291,6 +301,47 @@ public:
void AppendToString(nsAString& aBuffer, nsCSSProperty aPropID = eCSSProperty_UNKNOWN) const; void AppendToString(nsAString& aBuffer, nsCSSProperty aPropID = eCSSProperty_UNKNOWN) const;
void ToString(nsAString& aBuffer, nsCSSProperty aPropID = eCSSProperty_UNKNOWN) const; void ToString(nsAString& aBuffer, nsCSSProperty aPropID = eCSSProperty_UNKNOWN) const;
MOZ_DECL_CTOR_COUNTER(nsCSSValue::URL)
struct URL {
// Caller must delete this object immediately if the allocation of
// |mString| fails.
URL(nsIURI* aURI, const PRUnichar* aString)
: mURI(aURI),
mString(nsCRT::strdup(aString)),
mRefCnt(0)
{
MOZ_COUNT_CTOR(nsCSSValue::URL);
}
~URL()
{
// null |mString| isn't valid normally, but is checked by callers
// of the constructor
if (mString)
nsCRT::free(mString);
MOZ_COUNT_DTOR(nsCSSValue::URL);
}
PRBool operator==(const URL& aOther)
{
PRBool eq;
return nsCRT::strcmp(mString, aOther.mString) == 0 &&
(mURI == aOther.mURI || // handles null == null
(mURI && aOther.mURI &&
NS_SUCCEEDED(mURI->Equals(aOther.mURI, &eq)) &&
eq));
}
nsCOMPtr<nsIURI> mURI; // null == invalid URL
PRUnichar* mString;
void AddRef() { ++mRefCnt; }
void Release() { if (--mRefCnt == 0) delete this; }
private:
nsrefcnt mRefCnt;
};
protected: protected:
nsCSSUnit mUnit; nsCSSUnit mUnit;
union { union {
@ -298,7 +349,7 @@ protected:
float mFloat; float mFloat;
PRUnichar* mString; PRUnichar* mString;
nscolor mColor; nscolor mColor;
nsIURI* mURL; URL* mURL;
} mValue; } mValue;
}; };