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;
rv = nsContentUtils::NewURIWithDocumentCharset(
getter_AddRefs(uri), spec, doc, docURL);
if (NS_SUCCEEDED(rv))
aData->mColorData->mBackImage.SetURLValue(uri);
if (NS_SUCCEEDED(rv)) {
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(')'));
}
else if (eCSSUnit_URL == unit) {
nsCAutoString spec;
aValue.GetURLValue()->GetSpec(spec);
aResult.Append(NS_LITERAL_STRING("url(") +
NS_ConvertUTF8toUCS2(spec) +
nsDependentString(aValue.GetOriginalURLValue()) +
NS_LITERAL_STRING(")"));
}
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)) {
// Translate url into an absolute url if the url is relative to
// the style sheet.
// XXX editors won't like this - too bad for now
nsCOMPtr<nsIURI> url;
NS_NewURI(getter_AddRefs(url), tk->mIdent, nsnull, mURL);
nsCOMPtr<nsIURI> uri;
NS_NewURI(getter_AddRefs(uri), tk->mIdent, nsnull, mURL);
if (ExpectSymbol(aErrorCode, ')', PR_TRUE)) {
// Set a null value on failure. Most failure cases should be
// 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);
return PR_TRUE;
}

View File

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

View File

@ -45,6 +45,7 @@
#include "nsCSSProperty.h"
#include "nsUnitConversion.h"
#include "nsIURI.h"
#include "nsCOMPtr.h"
enum nsCSSUnit {
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_Counter = 12, // (PRUnichar*) a counter(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_Enumerated = 51, // (int) value has enumerated meaning
eCSSUnit_Color = 80, // (color) an RGBA value
@ -114,6 +115,9 @@ enum nsCSSUnit {
class nsCSSValue {
public:
struct URL;
friend struct URL;
// for valueless units only (null, auto, inherit, none, normal)
nsCSSValue(nsCSSUnit aUnit = eCSSUnit_Null)
: mUnit(aUnit)
@ -129,7 +133,7 @@ public:
nsCSSValue(float aValue, nsCSSUnit aUnit);
nsCSSValue(const nsAString& aValue, nsCSSUnit aUnit);
nsCSSValue(nscolor aValue);
nsCSSValue(nsIURI* aValue);
nsCSSValue(nsCSSValue::URL* aValue);
nsCSSValue(const nsCSSValue& aCopy);
~nsCSSValue(void)
{
@ -205,7 +209,13 @@ public:
nsIURI* GetURLValue(void) const
{
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)) {
nsCRT::free(mValue.mString);
} else if (eCSSUnit_URL == mUnit) {
NS_IF_RELEASE(mValue.mURL);
mValue.mURL->Release();
}
mUnit = eCSSUnit_Null;
mValue.mInt = 0;
@ -279,7 +289,7 @@ public:
void SetStringValue(const nsAString& aValue, nsCSSUnit aUnit);
void SetColorValue(nscolor aValue);
void SetURLValue(nsIURI* aURI);
void SetURLValue(nsCSSValue::URL* aURI);
void SetAutoValue(void);
void SetInheritValue(void);
void SetInitialValue(void);
@ -291,6 +301,47 @@ public:
void AppendToString(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:
nsCSSUnit mUnit;
union {
@ -298,7 +349,7 @@ protected:
float mFloat;
PRUnichar* mString;
nscolor mColor;
nsIURI* mURL;
URL* mURL;
} mValue;
};

View File

@ -405,10 +405,8 @@ PRBool nsCSSDeclaration::AppendCSSValueToString(nsCSSProperty aProperty, const n
aResult.Append(PRUnichar(')'));
}
else if (eCSSUnit_URL == unit) {
nsCAutoString spec;
aValue.GetURLValue()->GetSpec(spec);
aResult.Append(NS_LITERAL_STRING("url(") +
NS_ConvertUTF8toUCS2(spec) +
nsDependentString(aValue.GetOriginalURLValue()) +
NS_LITERAL_STRING(")"));
}
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)) {
// Translate url into an absolute url if the url is relative to
// the style sheet.
// XXX editors won't like this - too bad for now
nsCOMPtr<nsIURI> url;
NS_NewURI(getter_AddRefs(url), tk->mIdent, nsnull, mURL);
nsCOMPtr<nsIURI> uri;
NS_NewURI(getter_AddRefs(uri), tk->mIdent, nsnull, mURL);
if (ExpectSymbol(aErrorCode, ')', PR_TRUE)) {
// Set a null value on failure. Most failure cases should be
// 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);
return PR_TRUE;
}

View File

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

View File

@ -45,6 +45,7 @@
#include "nsCSSProperty.h"
#include "nsUnitConversion.h"
#include "nsIURI.h"
#include "nsCOMPtr.h"
enum nsCSSUnit {
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_Counter = 12, // (PRUnichar*) a counter(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_Enumerated = 51, // (int) value has enumerated meaning
eCSSUnit_Color = 80, // (color) an RGBA value
@ -114,6 +115,9 @@ enum nsCSSUnit {
class nsCSSValue {
public:
struct URL;
friend struct URL;
// for valueless units only (null, auto, inherit, none, normal)
nsCSSValue(nsCSSUnit aUnit = eCSSUnit_Null)
: mUnit(aUnit)
@ -129,7 +133,7 @@ public:
nsCSSValue(float aValue, nsCSSUnit aUnit);
nsCSSValue(const nsAString& aValue, nsCSSUnit aUnit);
nsCSSValue(nscolor aValue);
nsCSSValue(nsIURI* aValue);
nsCSSValue(nsCSSValue::URL* aValue);
nsCSSValue(const nsCSSValue& aCopy);
~nsCSSValue(void)
{
@ -205,7 +209,13 @@ public:
nsIURI* GetURLValue(void) const
{
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)) {
nsCRT::free(mValue.mString);
} else if (eCSSUnit_URL == mUnit) {
NS_IF_RELEASE(mValue.mURL);
mValue.mURL->Release();
}
mUnit = eCSSUnit_Null;
mValue.mInt = 0;
@ -279,7 +289,7 @@ public:
void SetStringValue(const nsAString& aValue, nsCSSUnit aUnit);
void SetColorValue(nscolor aValue);
void SetURLValue(nsIURI* aURI);
void SetURLValue(nsCSSValue::URL* aURI);
void SetAutoValue(void);
void SetInheritValue(void);
void SetInitialValue(void);
@ -291,6 +301,47 @@ public:
void AppendToString(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:
nsCSSUnit mUnit;
union {
@ -298,7 +349,7 @@ protected:
float mFloat;
PRUnichar* mString;
nscolor mColor;
nsIURI* mURL;
URL* mURL;
} mValue;
};