Bug 783162: Make mapped attributes hold the image alive. r=bz

The nsCSSValue in nsGenericHTMLElement::MapBackgroundInto is a temporary.  This causes a problem after Bug 697230 landed, because the nsCSSValue::Image we put into that value is destroyed once we're done doing style stuff.  Previously the nsImageLoader would grab the request off the nsCSSValue::Image and hold it alive.  Bug 697230 changed the behavior here; now when the nsCSSValue::Image is destroyed it tells the image loader to drop the request.  The result is that all the references to the request are dropped and the frame is never told it has a background.

The solution is to keep the nsCSSValue::Image alive longer.  This patch adds two new types of nsAttrValue.  The first is an nsCSSValue::URL.  A ParseBackgroundAttribute method is added on nsGenericHTMLElement that the relevant elements (body/td/th/table/tr/tbody/thead/tfoot) call that parses background into an nsCSSValue::URL.  The second is an nsCSSValue::Image.  nsGenericHTMLElement::MapBackgroundInto attempts to convert the nsCSSValue::URL into an nsCSSValue::Image by kicking off the image load.  The result is that image loads are only started when the element is actually visible.  This also mirrors the way background-image works.  This also allows us to fix two longstanding bugs in this code.  Since MapBackgroundInto doesn't have a pointer to the actual element, it relied on grabbing the principal of the document.  Now we can grab the principal of the node in ParseBackgroundAttribute.  MapBackgroundInto also has no way to get at the element's base URI (to honor xml:base), which is now possible in ParseBackgroundAttribute.

nsCSSValue::[Image|URL] have also been moved to be mozilla::css::[Image|URL]Value.  nsAttrValue.h is included in external linkage code, so it can't include nsCSSValue.h to get the declarations of nsCSSValue::[Image|URL], and nested classes can't be forward declared.  Moving the classes to a namespace solves the problem.

Finally some old inoperative quirks mode code was removed.  This code has done nothing since Bug 273078 was landed in 2004.
This commit is contained in:
Kyle Huey 2012-08-24 10:50:49 -07:00
parent d8f80b82e5
commit 0cae034974
26 changed files with 429 additions and 201 deletions

View File

@ -210,6 +210,16 @@ nsAttrValue::SetTo(const nsAttrValue& aOther)
NS_ADDREF(cont->mCSSStyleRule = otherCont->mCSSStyleRule); NS_ADDREF(cont->mCSSStyleRule = otherCont->mCSSStyleRule);
break; break;
} }
case eURL:
{
NS_ADDREF(cont->mURL = otherCont->mURL);
break;
}
case eImage:
{
NS_ADDREF(cont->mImage = otherCont->mImage);
break;
}
case eAtomArray: case eAtomArray:
{ {
if (!EnsureEmptyAtomArray() || if (!EnsureEmptyAtomArray() ||
@ -314,6 +324,17 @@ nsAttrValue::SetTo(css::StyleRule* aValue, const nsAString* aSerialized)
} }
} }
void
nsAttrValue::SetTo(css::URLValue* aValue, const nsAString* aSerialized)
{
if (EnsureEmptyMiscContainer()) {
MiscContainer* cont = GetMiscContainer();
NS_ADDREF(cont->mURL = aValue);
cont->mType = eURL;
SetMiscAtomOrString(aSerialized);
}
}
void void
nsAttrValue::SetTo(const nsIntMargin& aValue) nsAttrValue::SetTo(const nsIntMargin& aValue)
{ {
@ -774,6 +795,15 @@ nsAttrValue::HashValue() const
{ {
return NS_PTR_TO_INT32(cont->mCSSStyleRule); return NS_PTR_TO_INT32(cont->mCSSStyleRule);
} }
// Intentionally identical, so that loading the image does not change the
// hash code.
case eURL:
case eImage:
{
nsString str;
ToString(str);
return HashString(str);
}
case eAtomArray: case eAtomArray:
{ {
uint32_t hash = 0; uint32_t hash = 0;
@ -870,6 +900,14 @@ nsAttrValue::Equals(const nsAttrValue& aOther) const
{ {
return thisCont->mCSSStyleRule == otherCont->mCSSStyleRule; return thisCont->mCSSStyleRule == otherCont->mCSSStyleRule;
} }
case eURL:
{
return thisCont->mURL == otherCont->mURL;
}
case eImage:
{
return thisCont->mImage == otherCont->mImage;
}
case eAtomArray: case eAtomArray:
{ {
// For classlists we could be insensitive to order, however // For classlists we could be insensitive to order, however
@ -1500,6 +1538,31 @@ nsAttrValue::ParseIntMarginValue(const nsAString& aString)
return false; return false;
} }
bool
nsAttrValue::LoadImage(nsIDocument* aDocument)
{
NS_ASSERTION(Type() == eURL, "wrong type");
nsString val;
ToString(val);
if (val.IsEmpty()) {
return false;
}
MiscContainer* cont = GetMiscContainer();
mozilla::css::URLValue* url = cont->mURL;
mozilla::css::ImageValue* image =
new css::ImageValue(url->GetURI(), url->mString, url->mReferrer,
url->mOriginPrincipal, aDocument);
NS_ADDREF(image);
cont->mImage = image;
NS_RELEASE(url);
cont->mType = eImage;
return true;
}
void void
nsAttrValue::SetMiscAtomOrString(const nsAString* aValue) nsAttrValue::SetMiscAtomOrString(const nsAString* aValue)
{ {
@ -1576,6 +1639,16 @@ nsAttrValue::EnsureEmptyMiscContainer()
NS_RELEASE(cont->mCSSStyleRule); NS_RELEASE(cont->mCSSStyleRule);
break; break;
} }
case eURL:
{
NS_RELEASE(cont->mURL);
break;
}
case eImage:
{
NS_RELEASE(cont->mImage);
break;
}
case eAtomArray: case eAtomArray:
{ {
delete cont->mAtomArray; delete cont->mAtomArray;

View File

@ -23,12 +23,15 @@
typedef PRUptrdiff PtrBits; typedef PRUptrdiff PtrBits;
class nsAString; class nsAString;
class nsIAtom; class nsIAtom;
class nsIDocument;
template<class E, class A> class nsTArray; template<class E, class A> class nsTArray;
struct nsTArrayDefaultAllocator; struct nsTArrayDefaultAllocator;
namespace mozilla { namespace mozilla {
namespace css { namespace css {
class StyleRule; class StyleRule;
struct URLValue;
struct ImageValue;
} }
} }
@ -91,22 +94,24 @@ public:
// Values below here won't matter, they'll be always stored in the 'misc' // Values below here won't matter, they'll be always stored in the 'misc'
// struct. // struct.
eCSSStyleRule = 0x10 eCSSStyleRule = 0x10
,eAtomArray = 0x11 ,eURL = 0x11
,eDoubleValue = 0x12 ,eImage = 0x12
,eIntMarginValue = 0x13 ,eAtomArray = 0x13
,eSVGTypesBegin = 0x14 ,eDoubleValue = 0x14
,eIntMarginValue = 0x15
,eSVGTypesBegin = 0x16
,eSVGAngle = eSVGTypesBegin ,eSVGAngle = eSVGTypesBegin
,eSVGIntegerPair = 0x15 ,eSVGIntegerPair = 0x17
,eSVGLength = 0x16 ,eSVGLength = 0x18
,eSVGLengthList = 0x17 ,eSVGLengthList = 0x19
,eSVGNumberList = 0x18 ,eSVGNumberList = 0x20
,eSVGNumberPair = 0x19 ,eSVGNumberPair = 0x21
,eSVGPathData = 0x20 ,eSVGPathData = 0x22
,eSVGPointList = 0x21 ,eSVGPointList = 0x23
,eSVGPreserveAspectRatio = 0x22 ,eSVGPreserveAspectRatio = 0x24
,eSVGStringList = 0x23 ,eSVGStringList = 0x25
,eSVGTransformList = 0x24 ,eSVGTransformList = 0x26
,eSVGViewBox = 0x25 ,eSVGViewBox = 0x27
,eSVGTypesEnd = 0x34 ,eSVGTypesEnd = 0x34
}; };
@ -121,6 +126,7 @@ public:
void SetTo(int32_t aInt, const nsAString* aSerialized); void SetTo(int32_t aInt, const nsAString* aSerialized);
void SetTo(double aValue, const nsAString* aSerialized); void SetTo(double aValue, const nsAString* aSerialized);
void SetTo(mozilla::css::StyleRule* aValue, const nsAString* aSerialized); void SetTo(mozilla::css::StyleRule* aValue, const nsAString* aSerialized);
void SetTo(mozilla::css::URLValue* aValue, const nsAString* aSerialized);
void SetTo(const nsIntMargin& aValue); void SetTo(const nsIntMargin& aValue);
void SetTo(const nsSVGAngle& aValue, const nsAString* aSerialized); void SetTo(const nsSVGAngle& aValue, const nsAString* aSerialized);
void SetTo(const nsSVGIntegerPair& aValue, const nsAString* aSerialized); void SetTo(const nsSVGIntegerPair& aValue, const nsAString* aSerialized);
@ -169,6 +175,8 @@ public:
inline float GetPercentValue() const; inline float GetPercentValue() const;
inline AtomArray* GetAtomArrayValue() const; inline AtomArray* GetAtomArrayValue() const;
inline mozilla::css::StyleRule* GetCSSStyleRuleValue() const; inline mozilla::css::StyleRule* GetCSSStyleRuleValue() const;
inline mozilla::css::URLValue* GetURLValue() const;
inline mozilla::css::ImageValue* GetImageValue() const;
inline double GetDoubleValue() const; inline double GetDoubleValue() const;
bool GetIntMarginValue(nsIntMargin& aMargin) const; bool GetIntMarginValue(nsIntMargin& aMargin) const;
@ -342,6 +350,14 @@ public:
*/ */
bool ParseIntMarginValue(const nsAString& aString); bool ParseIntMarginValue(const nsAString& aString);
/**
* Convert a URL nsAttrValue to an Image nsAttrValue.
*
* @param aDocument the document this nsAttrValue belongs to.
* @return whether an image load was attempted
*/
bool LoadImage(nsIDocument* aDocument);
size_t SizeOfExcludingThis(nsMallocSizeOfFun aMallocSizeOf) const; size_t SizeOfExcludingThis(nsMallocSizeOfFun aMallocSizeOf) const;
private: private:
@ -367,6 +383,8 @@ private:
uint32_t mEnumValue; uint32_t mEnumValue;
int32_t mPercent; int32_t mPercent;
mozilla::css::StyleRule* mCSSStyleRule; mozilla::css::StyleRule* mCSSStyleRule;
mozilla::css::URLValue* mURL;
mozilla::css::ImageValue* mImage;
AtomArray* mAtomArray; AtomArray* mAtomArray;
double mDoubleValue; double mDoubleValue;
nsIntMargin* mIntMargin; nsIntMargin* mIntMargin;
@ -495,6 +513,20 @@ nsAttrValue::GetCSSStyleRuleValue() const
return GetMiscContainer()->mCSSStyleRule; return GetMiscContainer()->mCSSStyleRule;
} }
inline mozilla::css::URLValue*
nsAttrValue::GetURLValue() const
{
NS_PRECONDITION(Type() == eURL, "wrong type");
return GetMiscContainer()->mURL;
}
inline mozilla::css::ImageValue*
nsAttrValue::GetImageValue() const
{
NS_PRECONDITION(Type() == eImage, "wrong type");
return GetMiscContainer()->mImage;
}
inline double inline double
nsAttrValue::GetDoubleValue() const nsAttrValue::GetDoubleValue() const
{ {

View File

@ -2134,6 +2134,39 @@ nsGenericHTMLElement::ParseAttribute(int32_t aNamespaceID,
aValue, aResult); aValue, aResult);
} }
bool
nsGenericHTMLElement::ParseBackgroundAttribute(int32_t aNamespaceID,
nsIAtom* aAttribute,
const nsAString& aValue,
nsAttrValue& aResult)
{
if (aNamespaceID == kNameSpaceID_None &&
aAttribute == nsGkAtoms::background) {
// Resolve url to an absolute url
nsIDocument* doc = OwnerDoc();
nsCOMPtr<nsIURI> baseURI = GetBaseURI();
nsCOMPtr<nsIURI> uri;
nsresult rv = nsContentUtils::NewURIWithDocumentCharset(
getter_AddRefs(uri), aValue, doc, baseURI);
if (NS_FAILED(rv)) {
return false;
}
nsString value(aValue);
nsRefPtr<nsStringBuffer> buffer = nsCSSValue::BufferFromString(value);
if (NS_UNLIKELY(!buffer)) {
return false;
}
mozilla::css::URLValue *url =
new mozilla::css::URLValue(buffer, baseURI, uri, NodePrincipal());
aResult.SetTo(url, &aValue);
return true;
}
return false;
}
bool bool
nsGenericHTMLElement::IsAttributeMapped(const nsIAtom* aAttribute) const nsGenericHTMLElement::IsAttributeMapped(const nsIAtom* aAttribute) const
{ {
@ -2739,45 +2772,16 @@ nsGenericHTMLElement::MapBackgroundInto(const nsMappedAttributes* aAttributes,
if (backImage->GetUnit() == eCSSUnit_Null && if (backImage->GetUnit() == eCSSUnit_Null &&
presContext->UseDocumentColors()) { presContext->UseDocumentColors()) {
// background // background
const nsAttrValue* value = aAttributes->GetAttr(nsGkAtoms::background); nsAttrValue* value =
if (value && value->Type() == nsAttrValue::eString) { const_cast<nsAttrValue*>(aAttributes->GetAttr(nsGkAtoms::background));
const nsString& spec = value->GetStringValue(); // If the value is an image, or it is a URL and we attempted a load,
if (!spec.IsEmpty()) { // put it in the style tree.
// Resolve url to an absolute url if (value &&
// XXX this breaks if the HTML element has an xml:base (value->Type() == nsAttrValue::eImage ||
// attribute (the xml:base will not be taken into account) (value->Type() == nsAttrValue::eURL &&
// as well as elements with _baseHref set. We need to be able value->LoadImage(presContext->Document())))) {
// to get to the element somehow, or store the base URI in the nsCSSValueList* list = backImage->SetListValue();
// attributes. list->mValue.SetImageValue(value->GetImageValue());
nsIDocument* doc = presContext->Document();
nsCOMPtr<nsIURI> uri;
nsresult rv = nsContentUtils::NewURIWithDocumentCharset(
getter_AddRefs(uri), spec, doc, doc->GetDocBaseURI());
if (NS_SUCCEEDED(rv)) {
// Note that this should generally succeed here, due to the way
// |spec| is created. Maybe we should just add an nsStringBuffer
// accessor on nsAttrValue?
nsRefPtr<nsStringBuffer> buffer = nsCSSValue::BufferFromString(spec);
if (NS_LIKELY(buffer)) {
// XXXbz it would be nice to assert that doc->NodePrincipal() is
// the same as the principal of the node (which we'd need to store
// in the mapped attrs or something?)
nsCSSValue::Image *img =
new nsCSSValue::Image(uri, buffer, doc->GetDocumentURI(),
doc->NodePrincipal(), doc);
if (NS_LIKELY(img)) {
nsCSSValueList* list = backImage->SetListValue();
list->mValue.SetImageValue(img);
}
}
}
}
else if (presContext->CompatibilityMode() == eCompatibility_NavQuirks) {
// in NavQuirks mode, allow the empty string to set the
// background to empty
nsCSSValueList* list = backImage->SetListValue();
list->mValue.SetNoneValue();
}
} }
} }
} }

View File

@ -213,6 +213,11 @@ public:
} }
virtual bool ParseAttribute(int32_t aNamespaceID, virtual bool ParseAttribute(int32_t aNamespaceID,
nsIAtom* aAttribute,
const nsAString& aValue,
nsAttrValue& aResult);
bool ParseBackgroundAttribute(int32_t aNamespaceID,
nsIAtom* aAttribute, nsIAtom* aAttribute,
const nsAString& aValue, const nsAString& aValue,
nsAttrValue& aResult); nsAttrValue& aResult);

View File

@ -83,9 +83,9 @@ public:
#undef EVENT #undef EVENT
virtual bool ParseAttribute(int32_t aNamespaceID, virtual bool ParseAttribute(int32_t aNamespaceID,
nsIAtom* aAttribute, nsIAtom* aAttribute,
const nsAString& aValue, const nsAString& aValue,
nsAttrValue& aResult); nsAttrValue& aResult);
virtual void UnbindFromTree(bool aDeep = true, virtual void UnbindFromTree(bool aDeep = true,
bool aNullParent = true); bool aNullParent = true);
virtual nsMapRuleToAttributesFunc GetAttributeMappingFunction() const; virtual nsMapRuleToAttributesFunc GetAttributeMappingFunction() const;
@ -324,7 +324,10 @@ nsHTMLBodyElement::ParseAttribute(int32_t aNamespaceID,
} }
} }
return nsGenericHTMLElement::ParseAttribute(aNamespaceID, aAttribute, aValue, return nsGenericHTMLElement::ParseBackgroundAttribute(aNamespaceID,
aAttribute, aValue,
aResult) ||
nsGenericHTMLElement::ParseAttribute(aNamespaceID, aAttribute, aValue,
aResult); aResult);
} }

View File

@ -44,9 +44,9 @@ public:
NS_DECL_NSIDOMHTMLTABLECELLELEMENT NS_DECL_NSIDOMHTMLTABLECELLELEMENT
virtual bool ParseAttribute(int32_t aNamespaceID, virtual bool ParseAttribute(int32_t aNamespaceID,
nsIAtom* aAttribute, nsIAtom* aAttribute,
const nsAString& aValue, const nsAString& aValue,
nsAttrValue& aResult); nsAttrValue& aResult);
virtual nsMapRuleToAttributesFunc GetAttributeMappingFunction() const; virtual nsMapRuleToAttributesFunc GetAttributeMappingFunction() const;
NS_IMETHOD WalkContentStyleRules(nsRuleWalker* aRuleWalker); NS_IMETHOD WalkContentStyleRules(nsRuleWalker* aRuleWalker);
NS_IMETHOD_(bool) IsAttributeMapped(const nsIAtom* aAttribute) const; NS_IMETHOD_(bool) IsAttributeMapped(const nsIAtom* aAttribute) const;
@ -285,7 +285,10 @@ nsHTMLTableCellElement::ParseAttribute(int32_t aNamespaceID,
} }
} }
return nsGenericHTMLElement::ParseAttribute(aNamespaceID, aAttribute, aValue, return nsGenericHTMLElement::ParseBackgroundAttribute(aNamespaceID,
aAttribute, aValue,
aResult) ||
nsGenericHTMLElement::ParseAttribute(aNamespaceID, aAttribute, aValue,
aResult); aResult);
} }

View File

@ -910,7 +910,10 @@ nsHTMLTableElement::ParseAttribute(int32_t aNamespaceID,
} }
} }
return nsGenericHTMLElement::ParseAttribute(aNamespaceID, aAttribute, aValue, return nsGenericHTMLElement::ParseBackgroundAttribute(aNamespaceID,
aAttribute, aValue,
aResult) ||
nsGenericHTMLElement::ParseAttribute(aNamespaceID, aAttribute, aValue,
aResult); aResult);
} }

View File

@ -352,7 +352,10 @@ nsHTMLTableRowElement::ParseAttribute(int32_t aNamespaceID,
} }
} }
return nsGenericHTMLElement::ParseAttribute(aNamespaceID, aAttribute, aValue, return nsGenericHTMLElement::ParseBackgroundAttribute(aNamespaceID,
aAttribute, aValue,
aResult) ||
nsGenericHTMLElement::ParseAttribute(aNamespaceID, aAttribute, aValue,
aResult); aResult);
} }

View File

@ -43,9 +43,9 @@ public:
NS_DECL_NSIDOMHTMLTABLESECTIONELEMENT NS_DECL_NSIDOMHTMLTABLESECTIONELEMENT
virtual bool ParseAttribute(int32_t aNamespaceID, virtual bool ParseAttribute(int32_t aNamespaceID,
nsIAtom* aAttribute, nsIAtom* aAttribute,
const nsAString& aValue, const nsAString& aValue,
nsAttrValue& aResult); nsAttrValue& aResult);
virtual nsMapRuleToAttributesFunc GetAttributeMappingFunction() const; virtual nsMapRuleToAttributesFunc GetAttributeMappingFunction() const;
NS_IMETHOD_(bool) IsAttributeMapped(const nsIAtom* aAttribute) const; NS_IMETHOD_(bool) IsAttributeMapped(const nsIAtom* aAttribute) const;
@ -238,7 +238,10 @@ nsHTMLTableSectionElement::ParseAttribute(int32_t aNamespaceID,
} }
} }
return nsGenericHTMLElement::ParseAttribute(aNamespaceID, aAttribute, aValue, return nsGenericHTMLElement::ParseBackgroundAttribute(aNamespaceID,
aAttribute, aValue,
aResult) ||
nsGenericHTMLElement::ParseAttribute(aNamespaceID, aAttribute, aValue,
aResult); aResult);
} }

View File

@ -7960,7 +7960,7 @@ IDBEventTargetSH::PreCreate(nsISupports *aNativeObj, JSContext *aCx,
static bool static bool
GetBindingURL(Element *aElement, nsIDocument *aDocument, GetBindingURL(Element *aElement, nsIDocument *aDocument,
nsCSSValue::URL **aResult) mozilla::css::URLValue **aResult)
{ {
// If we have a frame the frame has already loaded the binding. And // If we have a frame the frame has already loaded the binding. And
// otherwise, don't do anything else here unless we're dealing with // otherwise, don't do anything else here unless we're dealing with
@ -8024,7 +8024,7 @@ nsElementSH::PreCreate(nsISupports *nativeObj, JSContext *cx,
return rv == NS_SUCCESS_ALLOW_SLIM_WRAPPERS ? NS_OK : rv; return rv == NS_SUCCESS_ALLOW_SLIM_WRAPPERS ? NS_OK : rv;
} }
nsCSSValue::URL *bindingURL; mozilla::css::URLValue *bindingURL;
bool ok = GetBindingURL(element, doc, &bindingURL); bool ok = GetBindingURL(element, doc, &bindingURL);
NS_ENSURE_TRUE(ok, NS_ERROR_FAILURE); NS_ENSURE_TRUE(ok, NS_ERROR_FAILURE);
@ -8089,7 +8089,7 @@ nsElementSH::PostCreate(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
// Make sure the style context goes away _before_ we load the binding // Make sure the style context goes away _before_ we load the binding
// since that can destroy the relevant presshell. // since that can destroy the relevant presshell.
nsCSSValue::URL *bindingURL; mozilla::css::URLValue *bindingURL;
bool ok = GetBindingURL(element, doc, &bindingURL); bool ok = GetBindingURL(element, doc, &bindingURL);
NS_ENSURE_TRUE(ok, NS_ERROR_FAILURE); NS_ENSURE_TRUE(ok, NS_ERROR_FAILURE);

View File

@ -0,0 +1,2 @@
<body style="background-image: url('aqua-yellow-32x32.png')">
</body>

View File

@ -0,0 +1,2 @@
<body background="aqua-yellow-32x32.png">
</body>

View File

@ -0,0 +1,3 @@
<div style="background-image: url('aqua-yellow-32x32.png')">
Ohai
</div>

View File

@ -0,0 +1,3 @@
<div background="aqua-yellow-32x32.png">
Ohai
</div>

View File

@ -128,5 +128,8 @@ random-if(bug685516) HTTP == root-background-1.html root-background-ref.html
random-if(bug685516) HTTP != root-background-1.html about:blank random-if(bug685516) HTTP != root-background-1.html about:blank
random-if(bug685516) == really-big-background.html really-big-background-ref.html random-if(bug685516) == really-big-background.html really-big-background-ref.html
random-if(bug685516) == body-background.html body-background-ref.html
random-if(bug685516) == table-background.html table-background-ref.html
random-if(bug685516) != div-background.html div-background-ref.html
random-if(bug685516) == background-repeat-1-ref.html background-repeat-1.html random-if(bug685516) == background-repeat-1-ref.html background-repeat-1.html

View File

@ -0,0 +1,39 @@
<body>
<table style="background-image: url('aqua-yellow-32x32.png')">
<thead style="background-image: url('blue-16x20-green-16x20.png')">
<tr>
<td>
Foo
</td>
<td style="background-image: url('yellow-32x32.png')">
Bar
</td>
</tr>
</thead>
<tbody style="background-image: url('red-32x32.png')">
<tr>
<th style="background-image: url('fuchsia-32x32.png')">
Foo
</th>
<th>
Bar
</th>
</tr>
<tr style="background-image: url('fuchsia-32x32.png')">
<td>
Foo
</td>
<td style="background-image: url('yellow-32x32.png')">
Bar
</td>
</tr>
</tbody>
<tfoot style="background-image: url('yellow-32x32.png')">
<tr>
<td>
Baz
</td>
</tr>
</tfoot>
</table>
</body>

View File

@ -0,0 +1,39 @@
<body>
<table background="aqua-yellow-32x32.png">
<thead background="blue-16x20-green-16x20.png">
<tr>
<td>
Foo
</td>
<td background="yellow-32x32.png">
Bar
</td>
</tr>
</thead>
<tbody background="red-32x32.png">
<tr>
<th background="fuchsia-32x32.png">
Foo
</th>
<th>
Bar
</th>
</tr>
<tr background="fuchsia-32x32.png">
<td>
Foo
</td>
<td background="yellow-32x32.png">
Bar
</td>
</tr>
</tbody>
<tfoot background="yellow-32x32.png">
<tr>
<td>
Baz
</td>
</tr>
</tfoot>
</table>
</body>

View File

@ -108,7 +108,7 @@ ImageLoader::AssociateRequestToFrame(imgIRequest* aRequest,
} }
void void
ImageLoader::MaybeRegisterCSSImage(nsCSSValue::Image* aImage) ImageLoader::MaybeRegisterCSSImage(ImageLoader::Image* aImage)
{ {
NS_ASSERTION(aImage, "This should never be null!"); NS_ASSERTION(aImage, "This should never be null!");
@ -139,7 +139,7 @@ ImageLoader::MaybeRegisterCSSImage(nsCSSValue::Image* aImage)
} }
void void
ImageLoader::DeregisterCSSImage(nsCSSValue::Image* aImage) ImageLoader::DeregisterCSSImage(ImageLoader::Image* aImage)
{ {
RemoveImage(aImage); RemoveImage(aImage);
} }
@ -219,10 +219,10 @@ ImageLoader::SetAnimationMode(uint16_t aMode)
} }
static PLDHashOperator static PLDHashOperator
ClearImageHashSet(nsPtrHashKey<nsCSSValue::Image>* aKey, void* aClosure) ClearImageHashSet(nsPtrHashKey<ImageLoader::Image>* aKey, void* aClosure)
{ {
nsIDocument* doc = static_cast<nsIDocument*>(aClosure); nsIDocument* doc = static_cast<nsIDocument*>(aClosure);
nsCSSValue::Image* image = aKey->GetKey(); ImageLoader::Image* image = aKey->GetKey();
imgIRequest* request = image->mRequests.GetWeak(doc); imgIRequest* request = image->mRequests.GetWeak(doc);
if (request) { if (request) {
@ -244,7 +244,7 @@ ImageLoader::ClearAll()
void void
ImageLoader::LoadImage(nsIURI* aURI, nsIPrincipal* aOriginPrincipal, ImageLoader::LoadImage(nsIURI* aURI, nsIPrincipal* aOriginPrincipal,
nsIURI* aReferrer, nsCSSValue::Image* aImage) nsIURI* aReferrer, ImageLoader::Image* aImage)
{ {
NS_ASSERTION(aImage->mRequests.Count() == 0, "Huh?"); NS_ASSERTION(aImage->mRequests.Count() == 0, "Huh?");
@ -284,7 +284,7 @@ ImageLoader::LoadImage(nsIURI* aURI, nsIPrincipal* aOriginPrincipal,
} }
void void
ImageLoader::AddImage(nsCSSValue::Image* aImage) ImageLoader::AddImage(ImageLoader::Image* aImage)
{ {
NS_ASSERTION(!mImages.Contains(aImage), "Huh?"); NS_ASSERTION(!mImages.Contains(aImage), "Huh?");
if (!mImages.PutEntry(aImage)) { if (!mImages.PutEntry(aImage)) {
@ -293,7 +293,7 @@ ImageLoader::AddImage(nsCSSValue::Image* aImage)
} }
void void
ImageLoader::RemoveImage(nsCSSValue::Image* aImage) ImageLoader::RemoveImage(ImageLoader::Image* aImage)
{ {
NS_ASSERTION(mImages.Contains(aImage), "Huh?"); NS_ASSERTION(mImages.Contains(aImage), "Huh?");
mImages.RemoveEntry(aImage); mImages.RemoveEntry(aImage);

View File

@ -26,6 +26,8 @@ namespace css {
class ImageLoader : public nsStubImageDecoderObserver, class ImageLoader : public nsStubImageDecoderObserver,
public imgIOnloadBlocker { public imgIOnloadBlocker {
public: public:
typedef mozilla::css::ImageValue Image;
ImageLoader(nsIDocument* aDocument) ImageLoader(nsIDocument* aDocument)
: mDocument(aDocument), : mDocument(aDocument),
mInClone(false) mInClone(false)
@ -55,8 +57,8 @@ public:
void DropDocumentReference(); void DropDocumentReference();
void MaybeRegisterCSSImage(nsCSSValue::Image* aImage); void MaybeRegisterCSSImage(Image* aImage);
void DeregisterCSSImage(nsCSSValue::Image* aImage); void DeregisterCSSImage(Image* aImage);
void AssociateRequestToFrame(imgIRequest* aRequest, void AssociateRequestToFrame(imgIRequest* aRequest,
nsIFrame* aFrame); nsIFrame* aFrame);
@ -71,7 +73,7 @@ public:
void ClearAll(); void ClearAll();
void LoadImage(nsIURI* aURI, nsIPrincipal* aPrincipal, nsIURI* aReferrer, void LoadImage(nsIURI* aURI, nsIPrincipal* aPrincipal, nsIURI* aReferrer,
nsCSSValue::Image* aCSSValue); Image* aCSSValue);
void DestroyRequest(imgIRequest* aRequest); void DestroyRequest(imgIRequest* aRequest);
@ -83,14 +85,14 @@ private:
typedef nsTArray<nsIFrame*> FrameSet; typedef nsTArray<nsIFrame*> FrameSet;
typedef nsTArray<nsCOMPtr<imgIRequest> > RequestSet; typedef nsTArray<nsCOMPtr<imgIRequest> > RequestSet;
typedef nsTHashtable<nsPtrHashKey<nsCSSValue::Image> > ImageHashSet; typedef nsTHashtable<nsPtrHashKey<Image> > ImageHashSet;
typedef nsClassHashtable<nsISupportsHashKey, typedef nsClassHashtable<nsISupportsHashKey,
FrameSet> RequestToFrameMap; FrameSet> RequestToFrameMap;
typedef nsClassHashtable<nsPtrHashKey<nsIFrame>, typedef nsClassHashtable<nsPtrHashKey<nsIFrame>,
RequestSet> FrameToRequestMap; RequestSet> FrameToRequestMap;
void AddImage(nsCSSValue::Image* aCSSImage); void AddImage(Image* aCSSImage);
void RemoveImage(nsCSSValue::Image* aCSSImage); void RemoveImage(Image* aCSSImage);
nsPresContext* GetPresContext(); nsPresContext* GetPresContext();

View File

@ -5041,8 +5041,8 @@ CSSParserImpl::SetValueToURL(nsCSSValue& aValue, const nsString& aURL)
nsRefPtr<nsStringBuffer> buffer(nsCSSValue::BufferFromString(aURL)); nsRefPtr<nsStringBuffer> buffer(nsCSSValue::BufferFromString(aURL));
// Note: urlVal retains its own reference to |buffer|. // Note: urlVal retains its own reference to |buffer|.
nsCSSValue::URL *urlVal = mozilla::css::URLValue *urlVal =
new nsCSSValue::URL(buffer, mBaseURI, mSheetURI, mSheetPrincipal); new mozilla::css::URLValue(buffer, mBaseURI, mSheetURI, mSheetPrincipal);
aValue.SetURLValue(urlVal); aValue.SetURLValue(urlVal);
return true; return true;
} }

View File

@ -73,14 +73,14 @@ nsCSSValue::nsCSSValue(nsCSSValue::Array* aValue, nsCSSUnit aUnit)
mValue.mArray->AddRef(); mValue.mArray->AddRef();
} }
nsCSSValue::nsCSSValue(nsCSSValue::URL* aValue) nsCSSValue::nsCSSValue(mozilla::css::URLValue* aValue)
: mUnit(eCSSUnit_URL) : mUnit(eCSSUnit_URL)
{ {
mValue.mURL = aValue; mValue.mURL = aValue;
mValue.mURL->AddRef(); mValue.mURL->AddRef();
} }
nsCSSValue::nsCSSValue(nsCSSValue::Image* aValue) nsCSSValue::nsCSSValue(mozilla::css::ImageValue* aValue)
: mUnit(eCSSUnit_Image) : mUnit(eCSSUnit_Image)
{ {
mValue.mImage = aValue; mValue.mImage = aValue;
@ -364,7 +364,7 @@ void nsCSSValue::SetArrayValue(nsCSSValue::Array* aValue, nsCSSUnit aUnit)
mValue.mArray->AddRef(); mValue.mArray->AddRef();
} }
void nsCSSValue::SetURLValue(nsCSSValue::URL* aValue) void nsCSSValue::SetURLValue(mozilla::css::URLValue* aValue)
{ {
Reset(); Reset();
mUnit = eCSSUnit_URL; mUnit = eCSSUnit_URL;
@ -372,7 +372,7 @@ void nsCSSValue::SetURLValue(nsCSSValue::URL* aValue)
mValue.mURL->AddRef(); mValue.mURL->AddRef();
} }
void nsCSSValue::SetImageValue(nsCSSValue::Image* aValue) void nsCSSValue::SetImageValue(mozilla::css::ImageValue* aValue)
{ {
Reset(); Reset();
mUnit = eCSSUnit_Image; mUnit = eCSSUnit_Image;
@ -563,12 +563,12 @@ void nsCSSValue::SetDummyInheritValue()
void nsCSSValue::StartImageLoad(nsIDocument* aDocument) const void nsCSSValue::StartImageLoad(nsIDocument* aDocument) const
{ {
NS_ABORT_IF_FALSE(eCSSUnit_URL == mUnit, "Not a URL value!"); NS_ABORT_IF_FALSE(eCSSUnit_URL == mUnit, "Not a URL value!");
nsCSSValue::Image* image = mozilla::css::ImageValue* image =
new nsCSSValue::Image(mValue.mURL->GetURI(), new mozilla::css::ImageValue(mValue.mURL->GetURI(),
mValue.mURL->mString, mValue.mURL->mString,
mValue.mURL->mReferrer, mValue.mURL->mReferrer,
mValue.mURL->mOriginPrincipal, mValue.mURL->mOriginPrincipal,
aDocument); aDocument);
if (image) { if (image) {
nsCSSValue* writable = const_cast<nsCSSValue*>(this); nsCSSValue* writable = const_cast<nsCSSValue*>(this);
writable->SetImageValue(image); writable->SetImageValue(image);
@ -1600,8 +1600,8 @@ nsCSSValue::Array::SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf) const
return n; return n;
} }
nsCSSValue::URL::URL(nsIURI* aURI, nsStringBuffer* aString, css::URLValue::URLValue(nsIURI* aURI, nsStringBuffer* aString,
nsIURI* aReferrer, nsIPrincipal* aOriginPrincipal) nsIURI* aReferrer, nsIPrincipal* aOriginPrincipal)
: mURI(aURI), : mURI(aURI),
mString(aString), mString(aString),
mReferrer(aReferrer), mReferrer(aReferrer),
@ -1612,8 +1612,8 @@ nsCSSValue::URL::URL(nsIURI* aURI, nsStringBuffer* aString,
mString->AddRef(); mString->AddRef();
} }
nsCSSValue::URL::URL(nsStringBuffer* aString, nsIURI* aBaseURI, css::URLValue::URLValue(nsStringBuffer* aString, nsIURI* aBaseURI,
nsIURI* aReferrer, nsIPrincipal* aOriginPrincipal) nsIURI* aReferrer, nsIPrincipal* aOriginPrincipal)
: mURI(aBaseURI), : mURI(aBaseURI),
mString(aString), mString(aString),
mReferrer(aReferrer), mReferrer(aReferrer),
@ -1624,17 +1624,17 @@ nsCSSValue::URL::URL(nsStringBuffer* aString, nsIURI* aBaseURI,
mString->AddRef(); mString->AddRef();
} }
nsCSSValue::URL::~URL() css::URLValue::~URLValue()
{ {
mString->Release(); mString->Release();
} }
bool bool
nsCSSValue::URL::operator==(const URL& aOther) const css::URLValue::operator==(const URLValue& aOther) const
{ {
bool eq; bool eq;
return NS_strcmp(GetBufferValue(mString), return NS_strcmp(nsCSSValue::GetBufferValue(mString),
GetBufferValue(aOther.mString)) == 0 && nsCSSValue::GetBufferValue(aOther.mString)) == 0 &&
(GetURI() == aOther.GetURI() || // handles null == null (GetURI() == aOther.GetURI() || // handles null == null
(mURI && aOther.mURI && (mURI && aOther.mURI &&
NS_SUCCEEDED(mURI->Equals(aOther.mURI, &eq)) && NS_SUCCEEDED(mURI->Equals(aOther.mURI, &eq)) &&
@ -1645,7 +1645,7 @@ nsCSSValue::URL::operator==(const URL& aOther) const
} }
bool bool
nsCSSValue::URL::URIEquals(const URL& aOther) const css::URLValue::URIEquals(const URLValue& aOther) const
{ {
NS_ABORT_IF_FALSE(mURIResolved && aOther.mURIResolved, NS_ABORT_IF_FALSE(mURIResolved && aOther.mURIResolved,
"How do you know the URIs aren't null?"); "How do you know the URIs aren't null?");
@ -1662,14 +1662,15 @@ nsCSSValue::URL::URIEquals(const URL& aOther) const
} }
nsIURI* nsIURI*
nsCSSValue::URL::GetURI() const css::URLValue::GetURI() const
{ {
if (!mURIResolved) { if (!mURIResolved) {
mURIResolved = true; mURIResolved = true;
// Be careful to not null out mURI before we've passed it as the base URI // Be careful to not null out mURI before we've passed it as the base URI
nsCOMPtr<nsIURI> newURI; nsCOMPtr<nsIURI> newURI;
NS_NewURI(getter_AddRefs(newURI), NS_NewURI(getter_AddRefs(newURI),
NS_ConvertUTF16toUTF8(GetBufferValue(mString)), nullptr, mURI); NS_ConvertUTF16toUTF8(nsCSSValue::GetBufferValue(mString)),
nullptr, mURI);
newURI.swap(mURI); newURI.swap(mURI);
} }
@ -1677,7 +1678,7 @@ nsCSSValue::URL::GetURI() const
} }
size_t size_t
nsCSSValue::URL::SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf) const css::URLValue::SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf) const
{ {
size_t n = aMallocSizeOf(this); size_t n = aMallocSizeOf(this);
@ -1694,10 +1695,10 @@ nsCSSValue::URL::SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf) const
} }
nsCSSValue::Image::Image(nsIURI* aURI, nsStringBuffer* aString, css::ImageValue::ImageValue(nsIURI* aURI, nsStringBuffer* aString,
nsIURI* aReferrer, nsIPrincipal* aOriginPrincipal, nsIURI* aReferrer, nsIPrincipal* aOriginPrincipal,
nsIDocument* aDocument) nsIDocument* aDocument)
: URL(aURI, aString, aReferrer, aOriginPrincipal) : URLValue(aURI, aString, aReferrer, aOriginPrincipal)
{ {
if (aDocument->GetOriginalDocument()) { if (aDocument->GetOriginalDocument()) {
aDocument = aDocument->GetOriginalDocument(); aDocument = aDocument->GetOriginalDocument();
@ -1713,7 +1714,8 @@ static PLDHashOperator
ClearRequestHashtable(nsISupports* aKey, nsCOMPtr<imgIRequest>& aValue, ClearRequestHashtable(nsISupports* aKey, nsCOMPtr<imgIRequest>& aValue,
void* aClosure) void* aClosure)
{ {
nsCSSValue::Image* image = static_cast<nsCSSValue::Image*>(aClosure); mozilla::css::ImageValue* image =
static_cast<mozilla::css::ImageValue*>(aClosure);
nsIDocument* doc = static_cast<nsIDocument*>(aKey); nsIDocument* doc = static_cast<nsIDocument*>(aKey);
#ifdef DEBUG #ifdef DEBUG
@ -1734,7 +1736,7 @@ ClearRequestHashtable(nsISupports* aKey, nsCOMPtr<imgIRequest>& aValue,
return PL_DHASH_REMOVE; return PL_DHASH_REMOVE;
} }
nsCSSValue::Image::~Image() css::ImageValue::~ImageValue()
{ {
mRequests.Enumerate(&ClearRequestHashtable, this); mRequests.Enumerate(&ClearRequestHashtable, this);
} }

View File

@ -61,6 +61,79 @@ class nsPtrHashKey;
} \ } \
} }
namespace mozilla {
namespace css {
struct URLValue {
// Methods are not inline because using an nsIPrincipal means requiring
// caps, which leads to REQUIRES hell, since this header is included all
// over.
// For both constructors aString must not be null.
// For both constructors aOriginPrincipal must not be null.
// Construct with a base URI; this will create the actual URI lazily from
// aString and aBaseURI.
URLValue(nsStringBuffer* aString, nsIURI* aBaseURI, nsIURI* aReferrer,
nsIPrincipal* aOriginPrincipal);
// Construct with the actual URI.
URLValue(nsIURI* aURI, nsStringBuffer* aString, nsIURI* aReferrer,
nsIPrincipal* aOriginPrincipal);
~URLValue();
bool operator==(const URLValue& aOther) const;
// URIEquals only compares URIs and principals (unlike operator==, which
// also compares the original strings). URIEquals also assumes that the
// mURI member of both URL objects is non-null. Do NOT call this method
// unless you're sure this is the case.
bool URIEquals(const URLValue& aOther) const;
nsIURI* GetURI() const;
size_t SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf) const;
private:
// If mURIResolved is false, mURI stores the base URI.
// If mURIResolved is true, mURI stores the URI we resolve to; this may be
// null if the URI is invalid.
mutable nsCOMPtr<nsIURI> mURI;
public:
nsStringBuffer* mString; // Could use nsRefPtr, but it'd add useless
// null-checks; this is never null.
nsCOMPtr<nsIURI> mReferrer;
nsCOMPtr<nsIPrincipal> mOriginPrincipal;
NS_INLINE_DECL_REFCOUNTING(URLValue)
private:
mutable bool mURIResolved;
URLValue(const URLValue& aOther) MOZ_DELETE;
URLValue& operator=(const URLValue& aOther) MOZ_DELETE;
};
struct ImageValue : public URLValue {
// Not making the constructor and destructor inline because that would
// force us to include imgIRequest.h, which leads to REQUIRES hell, since
// this header is included all over.
// aString must not be null.
ImageValue(nsIURI* aURI, nsStringBuffer* aString, nsIURI* aReferrer,
nsIPrincipal* aOriginPrincipal, nsIDocument* aDocument);
~ImageValue();
// Inherit operator== from URLValue
nsInterfaceHashtable<nsISupportsHashKey, imgIRequest> mRequests;
// Override AddRef and Release to not only log ourselves correctly, but
// also so that we delete correctly without a virtual destructor
NS_INLINE_DECL_REFCOUNTING(ImageValue)
};
}
}
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
eCSSUnit_Auto = 1, // (n/a) value is algorithmic eCSSUnit_Auto = 1, // (n/a) value is algorithmic
@ -182,11 +255,9 @@ public:
struct Array; struct Array;
friend struct Array; friend struct Array;
struct URL; friend struct mozilla::css::URLValue;
friend struct URL;
struct Image; friend struct mozilla::css::ImageValue;
friend struct Image;
// for valueless units only (null, auto, inherit, none, all, normal) // for valueless units only (null, auto, inherit, none, all, normal)
explicit nsCSSValue(nsCSSUnit aUnit = eCSSUnit_Null) explicit nsCSSValue(nsCSSUnit aUnit = eCSSUnit_Null)
@ -199,8 +270,8 @@ public:
nsCSSValue(float aValue, nsCSSUnit aUnit); nsCSSValue(float aValue, nsCSSUnit aUnit);
nsCSSValue(const nsString& aValue, nsCSSUnit aUnit); nsCSSValue(const nsString& aValue, nsCSSUnit aUnit);
nsCSSValue(Array* aArray, nsCSSUnit aUnit); nsCSSValue(Array* aArray, nsCSSUnit aUnit);
explicit nsCSSValue(URL* aValue); explicit nsCSSValue(mozilla::css::URLValue* aValue);
explicit nsCSSValue(Image* aValue); explicit nsCSSValue(mozilla::css::ImageValue* aValue);
explicit nsCSSValue(nsCSSValueGradient* aValue); explicit nsCSSValue(nsCSSValueGradient* aValue);
nsCSSValue(const nsCSSValue& aCopy); nsCSSValue(const nsCSSValue& aCopy);
~nsCSSValue() { Reset(); } ~nsCSSValue() { Reset(); }
@ -349,7 +420,7 @@ public:
inline nsCSSValueTriplet& GetTripletValue(); inline nsCSSValueTriplet& GetTripletValue();
inline const nsCSSValueTriplet& GetTripletValue() const; inline const nsCSSValueTriplet& GetTripletValue() const;
URL* GetURLStructValue() const mozilla::css::URLValue* GetURLStructValue() const
{ {
// Not allowing this for Image values, because if the caller takes // Not allowing this for Image values, because if the caller takes
// a ref to them they won't be able to delete them properly. // a ref to them they won't be able to delete them properly.
@ -357,7 +428,7 @@ public:
return mValue.mURL; return mValue.mURL;
} }
Image* GetImageStructValue() const mozilla::css::ImageValue* GetImageStructValue() const
{ {
NS_ABORT_IF_FALSE(mUnit == eCSSUnit_Image, "not an Image value"); NS_ABORT_IF_FALSE(mUnit == eCSSUnit_Image, "not an Image value");
return mValue.mImage; return mValue.mImage;
@ -395,8 +466,8 @@ public:
void SetStringValue(const nsString& aValue, nsCSSUnit aUnit); void SetStringValue(const nsString& aValue, nsCSSUnit aUnit);
void SetColorValue(nscolor aValue); void SetColorValue(nscolor aValue);
void SetArrayValue(nsCSSValue::Array* aArray, nsCSSUnit aUnit); void SetArrayValue(nsCSSValue::Array* aArray, nsCSSUnit aUnit);
void SetURLValue(nsCSSValue::URL* aURI); void SetURLValue(mozilla::css::URLValue* aURI);
void SetImageValue(nsCSSValue::Image* aImage); void SetImageValue(mozilla::css::ImageValue* aImage);
void SetGradientValue(nsCSSValueGradient* aGradient); void SetGradientValue(nsCSSValueGradient* aGradient);
void SetPairValue(const nsCSSValuePair* aPair); void SetPairValue(const nsCSSValuePair* aPair);
void SetPairValue(const nsCSSValue& xValue, const nsCSSValue& yValue); void SetPairValue(const nsCSSValue& xValue, const nsCSSValue& yValue);
@ -434,73 +505,6 @@ public:
size_t SizeOfExcludingThis(nsMallocSizeOfFun aMallocSizeOf) const; size_t SizeOfExcludingThis(nsMallocSizeOfFun aMallocSizeOf) const;
struct URL {
// Methods are not inline because using an nsIPrincipal means requiring
// caps, which leads to REQUIRES hell, since this header is included all
// over.
// For both constructors aString must not be null.
// For both constructors aOriginPrincipal must not be null.
// Construct with a base URI; this will create the actual URI lazily from
// aString and aBaseURI.
URL(nsStringBuffer* aString, nsIURI* aBaseURI, nsIURI* aReferrer,
nsIPrincipal* aOriginPrincipal);
// Construct with the actual URI.
URL(nsIURI* aURI, nsStringBuffer* aString, nsIURI* aReferrer,
nsIPrincipal* aOriginPrincipal);
~URL();
bool operator==(const URL& aOther) const;
// URIEquals only compares URIs and principals (unlike operator==, which
// also compares the original strings). URIEquals also assumes that the
// mURI member of both URL objects is non-null. Do NOT call this method
// unless you're sure this is the case.
bool URIEquals(const URL& aOther) const;
nsIURI* GetURI() const;
size_t SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf) const;
private:
// If mURIResolved is false, mURI stores the base URI.
// If mURIResolved is true, mURI stores the URI we resolve to; this may be
// null if the URI is invalid.
mutable nsCOMPtr<nsIURI> mURI;
public:
nsStringBuffer* mString; // Could use nsRefPtr, but it'd add useless
// null-checks; this is never null.
nsCOMPtr<nsIURI> mReferrer;
nsCOMPtr<nsIPrincipal> mOriginPrincipal;
NS_INLINE_DECL_REFCOUNTING(nsCSSValue::URL)
private:
mutable bool mURIResolved;
URL(const URL& aOther) MOZ_DELETE;
URL& operator=(const URL& aOther) MOZ_DELETE;
};
struct Image : public URL {
// Not making the constructor and destructor inline because that would
// force us to include imgIRequest.h, which leads to REQUIRES hell, since
// this header is included all over.
// aString must not be null.
Image(nsIURI* aURI, nsStringBuffer* aString, nsIURI* aReferrer,
nsIPrincipal* aOriginPrincipal, nsIDocument* aDocument);
~Image();
// Inherit operator== from nsCSSValue::URL
nsInterfaceHashtable<nsISupportsHashKey, imgIRequest> mRequests;
// Override AddRef and Release to not only log ourselves correctly, but
// also so that we delete correctly without a virtual destructor
NS_INLINE_DECL_REFCOUNTING(nsCSSValue::Image)
};
private: private:
static const PRUnichar* GetBufferValue(nsStringBuffer* aBuffer) { static const PRUnichar* GetBufferValue(nsStringBuffer* aBuffer) {
return static_cast<PRUnichar*>(aBuffer->Data()); return static_cast<PRUnichar*>(aBuffer->Data());
@ -516,8 +520,8 @@ protected:
nsStringBuffer* mString; nsStringBuffer* mString;
nscolor mColor; nscolor mColor;
Array* mArray; Array* mArray;
URL* mURL; mozilla::css::URLValue* mURL;
Image* mImage; mozilla::css::ImageValue* mImage;
nsCSSValueGradient* mGradient; nsCSSValueGradient* mGradient;
nsCSSValuePair_heap* mPair; nsCSSValuePair_heap* mPair;
nsCSSRect_heap* mRect; nsCSSRect_heap* mRect;

View File

@ -4658,7 +4658,7 @@ nsRuleNode::ComputeDisplayData(void* aStartStruct,
// binding: url, none, inherit // binding: url, none, inherit
const nsCSSValue* bindingValue = aRuleData->ValueForBinding(); const nsCSSValue* bindingValue = aRuleData->ValueForBinding();
if (eCSSUnit_URL == bindingValue->GetUnit()) { if (eCSSUnit_URL == bindingValue->GetUnit()) {
nsCSSValue::URL* url = bindingValue->GetURLStructValue(); mozilla::css::URLValue* url = bindingValue->GetURLStructValue();
NS_ASSERTION(url, "What's going on here?"); NS_ASSERTION(url, "What's going on here?");
if (NS_LIKELY(url->GetURI())) { if (NS_LIKELY(url->GetURI())) {

View File

@ -3124,11 +3124,11 @@ nsStyleAnimation::ExtractComputedValue(nsCSSProperty aProperty,
GetURIAsUtf16StringBuffer(paint.mPaint.mPaintServer); GetURIAsUtf16StringBuffer(paint.mPaint.mPaintServer);
NS_ENSURE_TRUE(!!uriAsStringBuffer, false); NS_ENSURE_TRUE(!!uriAsStringBuffer, false);
nsIDocument* doc = aStyleContext->PresContext()->Document(); nsIDocument* doc = aStyleContext->PresContext()->Document();
nsRefPtr<nsCSSValue::URL> url = nsRefPtr<mozilla::css::URLValue> url =
new nsCSSValue::URL(paint.mPaint.mPaintServer, new mozilla::css::URLValue(paint.mPaint.mPaintServer,
uriAsStringBuffer, uriAsStringBuffer,
doc->GetDocumentURI(), doc->GetDocumentURI(),
doc->NodePrincipal()); doc->NodePrincipal());
pair->mXValue.SetURLValue(url); pair->mXValue.SetURLValue(url);
pair->mYValue.SetColorValue(paint.mFallbackColor); pair->mYValue.SetColorValue(paint.mFallbackColor);
aComputedValue.SetAndAdoptCSSValuePairValue(pair.forget(), aComputedValue.SetAndAdoptCSSValuePairValue(pair.forget(),

View File

@ -51,7 +51,7 @@ static bool EqualURIs(nsIURI *aURI1, nsIURI *aURI2)
eq); eq);
} }
static bool EqualURIs(nsCSSValue::URL *aURI1, nsCSSValue::URL *aURI2) static bool EqualURIs(mozilla::css::URLValue *aURI1, mozilla::css::URLValue *aURI2)
{ {
return aURI1 == aURI2 || // handle null==null, and optimize return aURI1 == aURI2 || // handle null==null, and optimize
(aURI1 && aURI2 && aURI1->URIEquals(*aURI2)); (aURI1 && aURI2 && aURI1->URIEquals(*aURI2));

View File

@ -1556,7 +1556,7 @@ struct nsStyleDisplay {
// We guarantee that if mBinding is non-null, so are mBinding->GetURI() and // We guarantee that if mBinding is non-null, so are mBinding->GetURI() and
// mBinding->mOriginPrincipal. // mBinding->mOriginPrincipal.
nsRefPtr<nsCSSValue::URL> mBinding; // [reset] nsRefPtr<mozilla::css::URLValue> mBinding; // [reset]
nsRect mClip; // [reset] offsets from upper-left border edge nsRect mClip; // [reset] offsets from upper-left border edge
float mOpacity; // [reset] float mOpacity; // [reset]
uint8_t mDisplay; // [reset] see nsStyleConsts.h NS_STYLE_DISPLAY_* uint8_t mDisplay; // [reset] see nsStyleConsts.h NS_STYLE_DISPLAY_*