diff --git a/content/base/src/nsAttrValue.cpp b/content/base/src/nsAttrValue.cpp index f868eb062f6..6ab8f2f9edc 100644 --- a/content/base/src/nsAttrValue.cpp +++ b/content/base/src/nsAttrValue.cpp @@ -210,6 +210,16 @@ nsAttrValue::SetTo(const nsAttrValue& aOther) NS_ADDREF(cont->mCSSStyleRule = otherCont->mCSSStyleRule); break; } + case eURL: + { + NS_ADDREF(cont->mURL = otherCont->mURL); + break; + } + case eImage: + { + NS_ADDREF(cont->mImage = otherCont->mImage); + break; + } case eAtomArray: { 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 nsAttrValue::SetTo(const nsIntMargin& aValue) { @@ -774,6 +795,15 @@ nsAttrValue::HashValue() const { 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: { uint32_t hash = 0; @@ -870,6 +900,14 @@ nsAttrValue::Equals(const nsAttrValue& aOther) const { return thisCont->mCSSStyleRule == otherCont->mCSSStyleRule; } + case eURL: + { + return thisCont->mURL == otherCont->mURL; + } + case eImage: + { + return thisCont->mImage == otherCont->mImage; + } case eAtomArray: { // For classlists we could be insensitive to order, however @@ -1500,6 +1538,31 @@ nsAttrValue::ParseIntMarginValue(const nsAString& aString) 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 nsAttrValue::SetMiscAtomOrString(const nsAString* aValue) { @@ -1576,6 +1639,16 @@ nsAttrValue::EnsureEmptyMiscContainer() NS_RELEASE(cont->mCSSStyleRule); break; } + case eURL: + { + NS_RELEASE(cont->mURL); + break; + } + case eImage: + { + NS_RELEASE(cont->mImage); + break; + } case eAtomArray: { delete cont->mAtomArray; diff --git a/content/base/src/nsAttrValue.h b/content/base/src/nsAttrValue.h index c2fc14d5eca..2296dd275d6 100644 --- a/content/base/src/nsAttrValue.h +++ b/content/base/src/nsAttrValue.h @@ -23,12 +23,15 @@ typedef PRUptrdiff PtrBits; class nsAString; class nsIAtom; +class nsIDocument; template class nsTArray; struct nsTArrayDefaultAllocator; namespace mozilla { namespace css { 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' // struct. eCSSStyleRule = 0x10 - ,eAtomArray = 0x11 - ,eDoubleValue = 0x12 - ,eIntMarginValue = 0x13 - ,eSVGTypesBegin = 0x14 + ,eURL = 0x11 + ,eImage = 0x12 + ,eAtomArray = 0x13 + ,eDoubleValue = 0x14 + ,eIntMarginValue = 0x15 + ,eSVGTypesBegin = 0x16 ,eSVGAngle = eSVGTypesBegin - ,eSVGIntegerPair = 0x15 - ,eSVGLength = 0x16 - ,eSVGLengthList = 0x17 - ,eSVGNumberList = 0x18 - ,eSVGNumberPair = 0x19 - ,eSVGPathData = 0x20 - ,eSVGPointList = 0x21 - ,eSVGPreserveAspectRatio = 0x22 - ,eSVGStringList = 0x23 - ,eSVGTransformList = 0x24 - ,eSVGViewBox = 0x25 + ,eSVGIntegerPair = 0x17 + ,eSVGLength = 0x18 + ,eSVGLengthList = 0x19 + ,eSVGNumberList = 0x20 + ,eSVGNumberPair = 0x21 + ,eSVGPathData = 0x22 + ,eSVGPointList = 0x23 + ,eSVGPreserveAspectRatio = 0x24 + ,eSVGStringList = 0x25 + ,eSVGTransformList = 0x26 + ,eSVGViewBox = 0x27 ,eSVGTypesEnd = 0x34 }; @@ -121,6 +126,7 @@ public: void SetTo(int32_t aInt, const nsAString* aSerialized); void SetTo(double 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 nsSVGAngle& aValue, const nsAString* aSerialized); void SetTo(const nsSVGIntegerPair& aValue, const nsAString* aSerialized); @@ -169,6 +175,8 @@ public: inline float GetPercentValue() const; inline AtomArray* GetAtomArrayValue() const; inline mozilla::css::StyleRule* GetCSSStyleRuleValue() const; + inline mozilla::css::URLValue* GetURLValue() const; + inline mozilla::css::ImageValue* GetImageValue() const; inline double GetDoubleValue() const; bool GetIntMarginValue(nsIntMargin& aMargin) const; @@ -342,6 +350,14 @@ public: */ 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; private: @@ -367,6 +383,8 @@ private: uint32_t mEnumValue; int32_t mPercent; mozilla::css::StyleRule* mCSSStyleRule; + mozilla::css::URLValue* mURL; + mozilla::css::ImageValue* mImage; AtomArray* mAtomArray; double mDoubleValue; nsIntMargin* mIntMargin; @@ -495,6 +513,20 @@ nsAttrValue::GetCSSStyleRuleValue() const 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 nsAttrValue::GetDoubleValue() const { diff --git a/content/html/content/src/nsGenericHTMLElement.cpp b/content/html/content/src/nsGenericHTMLElement.cpp index 4b86b7ea848..a7950ef2447 100644 --- a/content/html/content/src/nsGenericHTMLElement.cpp +++ b/content/html/content/src/nsGenericHTMLElement.cpp @@ -2134,6 +2134,39 @@ nsGenericHTMLElement::ParseAttribute(int32_t aNamespaceID, 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 baseURI = GetBaseURI(); + nsCOMPtr uri; + nsresult rv = nsContentUtils::NewURIWithDocumentCharset( + getter_AddRefs(uri), aValue, doc, baseURI); + if (NS_FAILED(rv)) { + return false; + } + + nsString value(aValue); + nsRefPtr 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 nsGenericHTMLElement::IsAttributeMapped(const nsIAtom* aAttribute) const { @@ -2739,45 +2772,16 @@ nsGenericHTMLElement::MapBackgroundInto(const nsMappedAttributes* aAttributes, if (backImage->GetUnit() == eCSSUnit_Null && presContext->UseDocumentColors()) { // background - const nsAttrValue* value = aAttributes->GetAttr(nsGkAtoms::background); - if (value && value->Type() == nsAttrValue::eString) { - const nsString& spec = value->GetStringValue(); - if (!spec.IsEmpty()) { - // Resolve url to an absolute url - // XXX this breaks if the HTML element has an xml:base - // attribute (the xml:base will not be taken into account) - // as well as elements with _baseHref set. We need to be able - // to get to the element somehow, or store the base URI in the - // attributes. - nsIDocument* doc = presContext->Document(); - nsCOMPtr 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 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(); - } + nsAttrValue* value = + const_cast(aAttributes->GetAttr(nsGkAtoms::background)); + // If the value is an image, or it is a URL and we attempted a load, + // put it in the style tree. + if (value && + (value->Type() == nsAttrValue::eImage || + (value->Type() == nsAttrValue::eURL && + value->LoadImage(presContext->Document())))) { + nsCSSValueList* list = backImage->SetListValue(); + list->mValue.SetImageValue(value->GetImageValue()); } } } diff --git a/content/html/content/src/nsGenericHTMLElement.h b/content/html/content/src/nsGenericHTMLElement.h index 05beab02081..51294cc50a1 100644 --- a/content/html/content/src/nsGenericHTMLElement.h +++ b/content/html/content/src/nsGenericHTMLElement.h @@ -213,6 +213,11 @@ public: } virtual bool ParseAttribute(int32_t aNamespaceID, + nsIAtom* aAttribute, + const nsAString& aValue, + nsAttrValue& aResult); + + bool ParseBackgroundAttribute(int32_t aNamespaceID, nsIAtom* aAttribute, const nsAString& aValue, nsAttrValue& aResult); diff --git a/content/html/content/src/nsHTMLBodyElement.cpp b/content/html/content/src/nsHTMLBodyElement.cpp index ad7ebd45cc6..95bb9937e51 100644 --- a/content/html/content/src/nsHTMLBodyElement.cpp +++ b/content/html/content/src/nsHTMLBodyElement.cpp @@ -83,9 +83,9 @@ public: #undef EVENT virtual bool ParseAttribute(int32_t aNamespaceID, - nsIAtom* aAttribute, - const nsAString& aValue, - nsAttrValue& aResult); + nsIAtom* aAttribute, + const nsAString& aValue, + nsAttrValue& aResult); virtual void UnbindFromTree(bool aDeep = true, bool aNullParent = true); 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); } diff --git a/content/html/content/src/nsHTMLTableCellElement.cpp b/content/html/content/src/nsHTMLTableCellElement.cpp index d7d73d66cb4..477b397099d 100644 --- a/content/html/content/src/nsHTMLTableCellElement.cpp +++ b/content/html/content/src/nsHTMLTableCellElement.cpp @@ -44,9 +44,9 @@ public: NS_DECL_NSIDOMHTMLTABLECELLELEMENT virtual bool ParseAttribute(int32_t aNamespaceID, - nsIAtom* aAttribute, - const nsAString& aValue, - nsAttrValue& aResult); + nsIAtom* aAttribute, + const nsAString& aValue, + nsAttrValue& aResult); virtual nsMapRuleToAttributesFunc GetAttributeMappingFunction() const; NS_IMETHOD WalkContentStyleRules(nsRuleWalker* aRuleWalker); 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); } diff --git a/content/html/content/src/nsHTMLTableElement.cpp b/content/html/content/src/nsHTMLTableElement.cpp index 5b4113605d3..4576bb29f06 100644 --- a/content/html/content/src/nsHTMLTableElement.cpp +++ b/content/html/content/src/nsHTMLTableElement.cpp @@ -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); } diff --git a/content/html/content/src/nsHTMLTableRowElement.cpp b/content/html/content/src/nsHTMLTableRowElement.cpp index 76e2068a8e5..2a5049c99e5 100644 --- a/content/html/content/src/nsHTMLTableRowElement.cpp +++ b/content/html/content/src/nsHTMLTableRowElement.cpp @@ -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); } diff --git a/content/html/content/src/nsHTMLTableSectionElement.cpp b/content/html/content/src/nsHTMLTableSectionElement.cpp index 7f70ca24e23..8c6f232a2f0 100644 --- a/content/html/content/src/nsHTMLTableSectionElement.cpp +++ b/content/html/content/src/nsHTMLTableSectionElement.cpp @@ -43,9 +43,9 @@ public: NS_DECL_NSIDOMHTMLTABLESECTIONELEMENT virtual bool ParseAttribute(int32_t aNamespaceID, - nsIAtom* aAttribute, - const nsAString& aValue, - nsAttrValue& aResult); + nsIAtom* aAttribute, + const nsAString& aValue, + nsAttrValue& aResult); virtual nsMapRuleToAttributesFunc GetAttributeMappingFunction() 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); } diff --git a/dom/base/nsDOMClassInfo.cpp b/dom/base/nsDOMClassInfo.cpp index 9f25f29e81a..b16f583aa15 100644 --- a/dom/base/nsDOMClassInfo.cpp +++ b/dom/base/nsDOMClassInfo.cpp @@ -7960,7 +7960,7 @@ IDBEventTargetSH::PreCreate(nsISupports *aNativeObj, JSContext *aCx, static bool 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 // 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; } - nsCSSValue::URL *bindingURL; + mozilla::css::URLValue *bindingURL; bool ok = GetBindingURL(element, doc, &bindingURL); 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 // since that can destroy the relevant presshell. - nsCSSValue::URL *bindingURL; + mozilla::css::URLValue *bindingURL; bool ok = GetBindingURL(element, doc, &bindingURL); NS_ENSURE_TRUE(ok, NS_ERROR_FAILURE); diff --git a/layout/reftests/backgrounds/body-background-ref.html b/layout/reftests/backgrounds/body-background-ref.html new file mode 100644 index 00000000000..4ba77be0e8f --- /dev/null +++ b/layout/reftests/backgrounds/body-background-ref.html @@ -0,0 +1,2 @@ + + diff --git a/layout/reftests/backgrounds/body-background.html b/layout/reftests/backgrounds/body-background.html new file mode 100644 index 00000000000..c6def1b795a --- /dev/null +++ b/layout/reftests/backgrounds/body-background.html @@ -0,0 +1,2 @@ + + diff --git a/layout/reftests/backgrounds/div-background-ref.html b/layout/reftests/backgrounds/div-background-ref.html new file mode 100644 index 00000000000..7916b9cd0b5 --- /dev/null +++ b/layout/reftests/backgrounds/div-background-ref.html @@ -0,0 +1,3 @@ +
+Ohai +
diff --git a/layout/reftests/backgrounds/div-background.html b/layout/reftests/backgrounds/div-background.html new file mode 100644 index 00000000000..224da0d155b --- /dev/null +++ b/layout/reftests/backgrounds/div-background.html @@ -0,0 +1,3 @@ +
+Ohai +
diff --git a/layout/reftests/backgrounds/reftest.list b/layout/reftests/backgrounds/reftest.list index 8cbe2726500..1ed07482e84 100644 --- a/layout/reftests/backgrounds/reftest.list +++ b/layout/reftests/backgrounds/reftest.list @@ -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) == 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 diff --git a/layout/reftests/backgrounds/table-background-ref.html b/layout/reftests/backgrounds/table-background-ref.html new file mode 100644 index 00000000000..d7ca56b26bd --- /dev/null +++ b/layout/reftests/backgrounds/table-background-ref.html @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + + + + + + + + + + +
+ Foo + + Bar +
+ Foo + + Bar +
+ Foo + + Bar +
+ Baz +
+ diff --git a/layout/reftests/backgrounds/table-background.html b/layout/reftests/backgrounds/table-background.html new file mode 100644 index 00000000000..cf21768498e --- /dev/null +++ b/layout/reftests/backgrounds/table-background.html @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + + + + + + + + + + +
+ Foo + + Bar +
+ Foo + + Bar +
+ Foo + + Bar +
+ Baz +
+ diff --git a/layout/style/ImageLoader.cpp b/layout/style/ImageLoader.cpp index ef211f6a540..63adbd7b5fc 100644 --- a/layout/style/ImageLoader.cpp +++ b/layout/style/ImageLoader.cpp @@ -108,7 +108,7 @@ ImageLoader::AssociateRequestToFrame(imgIRequest* aRequest, } void -ImageLoader::MaybeRegisterCSSImage(nsCSSValue::Image* aImage) +ImageLoader::MaybeRegisterCSSImage(ImageLoader::Image* aImage) { NS_ASSERTION(aImage, "This should never be null!"); @@ -139,7 +139,7 @@ ImageLoader::MaybeRegisterCSSImage(nsCSSValue::Image* aImage) } void -ImageLoader::DeregisterCSSImage(nsCSSValue::Image* aImage) +ImageLoader::DeregisterCSSImage(ImageLoader::Image* aImage) { RemoveImage(aImage); } @@ -219,10 +219,10 @@ ImageLoader::SetAnimationMode(uint16_t aMode) } static PLDHashOperator -ClearImageHashSet(nsPtrHashKey* aKey, void* aClosure) +ClearImageHashSet(nsPtrHashKey* aKey, void* aClosure) { nsIDocument* doc = static_cast(aClosure); - nsCSSValue::Image* image = aKey->GetKey(); + ImageLoader::Image* image = aKey->GetKey(); imgIRequest* request = image->mRequests.GetWeak(doc); if (request) { @@ -244,7 +244,7 @@ ImageLoader::ClearAll() void ImageLoader::LoadImage(nsIURI* aURI, nsIPrincipal* aOriginPrincipal, - nsIURI* aReferrer, nsCSSValue::Image* aImage) + nsIURI* aReferrer, ImageLoader::Image* aImage) { NS_ASSERTION(aImage->mRequests.Count() == 0, "Huh?"); @@ -284,7 +284,7 @@ ImageLoader::LoadImage(nsIURI* aURI, nsIPrincipal* aOriginPrincipal, } void -ImageLoader::AddImage(nsCSSValue::Image* aImage) +ImageLoader::AddImage(ImageLoader::Image* aImage) { NS_ASSERTION(!mImages.Contains(aImage), "Huh?"); if (!mImages.PutEntry(aImage)) { @@ -293,7 +293,7 @@ ImageLoader::AddImage(nsCSSValue::Image* aImage) } void -ImageLoader::RemoveImage(nsCSSValue::Image* aImage) +ImageLoader::RemoveImage(ImageLoader::Image* aImage) { NS_ASSERTION(mImages.Contains(aImage), "Huh?"); mImages.RemoveEntry(aImage); diff --git a/layout/style/ImageLoader.h b/layout/style/ImageLoader.h index 882f1ba2684..55de0a9bf72 100644 --- a/layout/style/ImageLoader.h +++ b/layout/style/ImageLoader.h @@ -26,6 +26,8 @@ namespace css { class ImageLoader : public nsStubImageDecoderObserver, public imgIOnloadBlocker { public: + typedef mozilla::css::ImageValue Image; + ImageLoader(nsIDocument* aDocument) : mDocument(aDocument), mInClone(false) @@ -55,8 +57,8 @@ public: void DropDocumentReference(); - void MaybeRegisterCSSImage(nsCSSValue::Image* aImage); - void DeregisterCSSImage(nsCSSValue::Image* aImage); + void MaybeRegisterCSSImage(Image* aImage); + void DeregisterCSSImage(Image* aImage); void AssociateRequestToFrame(imgIRequest* aRequest, nsIFrame* aFrame); @@ -71,7 +73,7 @@ public: void ClearAll(); void LoadImage(nsIURI* aURI, nsIPrincipal* aPrincipal, nsIURI* aReferrer, - nsCSSValue::Image* aCSSValue); + Image* aCSSValue); void DestroyRequest(imgIRequest* aRequest); @@ -83,14 +85,14 @@ private: typedef nsTArray FrameSet; typedef nsTArray > RequestSet; - typedef nsTHashtable > ImageHashSet; + typedef nsTHashtable > ImageHashSet; typedef nsClassHashtable RequestToFrameMap; typedef nsClassHashtable, RequestSet> FrameToRequestMap; - void AddImage(nsCSSValue::Image* aCSSImage); - void RemoveImage(nsCSSValue::Image* aCSSImage); + void AddImage(Image* aCSSImage); + void RemoveImage(Image* aCSSImage); nsPresContext* GetPresContext(); diff --git a/layout/style/nsCSSParser.cpp b/layout/style/nsCSSParser.cpp index 4d77604d667..7c374296bae 100644 --- a/layout/style/nsCSSParser.cpp +++ b/layout/style/nsCSSParser.cpp @@ -5041,8 +5041,8 @@ CSSParserImpl::SetValueToURL(nsCSSValue& aValue, const nsString& aURL) nsRefPtr buffer(nsCSSValue::BufferFromString(aURL)); // Note: urlVal retains its own reference to |buffer|. - nsCSSValue::URL *urlVal = - new nsCSSValue::URL(buffer, mBaseURI, mSheetURI, mSheetPrincipal); + mozilla::css::URLValue *urlVal = + new mozilla::css::URLValue(buffer, mBaseURI, mSheetURI, mSheetPrincipal); aValue.SetURLValue(urlVal); return true; } diff --git a/layout/style/nsCSSValue.cpp b/layout/style/nsCSSValue.cpp index 7951bbbd086..505bd1bd96a 100644 --- a/layout/style/nsCSSValue.cpp +++ b/layout/style/nsCSSValue.cpp @@ -73,14 +73,14 @@ nsCSSValue::nsCSSValue(nsCSSValue::Array* aValue, nsCSSUnit aUnit) mValue.mArray->AddRef(); } -nsCSSValue::nsCSSValue(nsCSSValue::URL* aValue) +nsCSSValue::nsCSSValue(mozilla::css::URLValue* aValue) : mUnit(eCSSUnit_URL) { mValue.mURL = aValue; mValue.mURL->AddRef(); } -nsCSSValue::nsCSSValue(nsCSSValue::Image* aValue) +nsCSSValue::nsCSSValue(mozilla::css::ImageValue* aValue) : mUnit(eCSSUnit_Image) { mValue.mImage = aValue; @@ -364,7 +364,7 @@ void nsCSSValue::SetArrayValue(nsCSSValue::Array* aValue, nsCSSUnit aUnit) mValue.mArray->AddRef(); } -void nsCSSValue::SetURLValue(nsCSSValue::URL* aValue) +void nsCSSValue::SetURLValue(mozilla::css::URLValue* aValue) { Reset(); mUnit = eCSSUnit_URL; @@ -372,7 +372,7 @@ void nsCSSValue::SetURLValue(nsCSSValue::URL* aValue) mValue.mURL->AddRef(); } -void nsCSSValue::SetImageValue(nsCSSValue::Image* aValue) +void nsCSSValue::SetImageValue(mozilla::css::ImageValue* aValue) { Reset(); mUnit = eCSSUnit_Image; @@ -563,12 +563,12 @@ void nsCSSValue::SetDummyInheritValue() void nsCSSValue::StartImageLoad(nsIDocument* aDocument) const { NS_ABORT_IF_FALSE(eCSSUnit_URL == mUnit, "Not a URL value!"); - nsCSSValue::Image* image = - new nsCSSValue::Image(mValue.mURL->GetURI(), - mValue.mURL->mString, - mValue.mURL->mReferrer, - mValue.mURL->mOriginPrincipal, - aDocument); + mozilla::css::ImageValue* image = + new mozilla::css::ImageValue(mValue.mURL->GetURI(), + mValue.mURL->mString, + mValue.mURL->mReferrer, + mValue.mURL->mOriginPrincipal, + aDocument); if (image) { nsCSSValue* writable = const_cast(this); writable->SetImageValue(image); @@ -1600,8 +1600,8 @@ nsCSSValue::Array::SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf) const return n; } -nsCSSValue::URL::URL(nsIURI* aURI, nsStringBuffer* aString, - nsIURI* aReferrer, nsIPrincipal* aOriginPrincipal) +css::URLValue::URLValue(nsIURI* aURI, nsStringBuffer* aString, + nsIURI* aReferrer, nsIPrincipal* aOriginPrincipal) : mURI(aURI), mString(aString), mReferrer(aReferrer), @@ -1612,8 +1612,8 @@ nsCSSValue::URL::URL(nsIURI* aURI, nsStringBuffer* aString, mString->AddRef(); } -nsCSSValue::URL::URL(nsStringBuffer* aString, nsIURI* aBaseURI, - nsIURI* aReferrer, nsIPrincipal* aOriginPrincipal) +css::URLValue::URLValue(nsStringBuffer* aString, nsIURI* aBaseURI, + nsIURI* aReferrer, nsIPrincipal* aOriginPrincipal) : mURI(aBaseURI), mString(aString), mReferrer(aReferrer), @@ -1624,17 +1624,17 @@ nsCSSValue::URL::URL(nsStringBuffer* aString, nsIURI* aBaseURI, mString->AddRef(); } -nsCSSValue::URL::~URL() +css::URLValue::~URLValue() { mString->Release(); } bool -nsCSSValue::URL::operator==(const URL& aOther) const +css::URLValue::operator==(const URLValue& aOther) const { bool eq; - return NS_strcmp(GetBufferValue(mString), - GetBufferValue(aOther.mString)) == 0 && + return NS_strcmp(nsCSSValue::GetBufferValue(mString), + nsCSSValue::GetBufferValue(aOther.mString)) == 0 && (GetURI() == aOther.GetURI() || // handles null == null (mURI && aOther.mURI && NS_SUCCEEDED(mURI->Equals(aOther.mURI, &eq)) && @@ -1645,7 +1645,7 @@ nsCSSValue::URL::operator==(const URL& aOther) const } bool -nsCSSValue::URL::URIEquals(const URL& aOther) const +css::URLValue::URIEquals(const URLValue& aOther) const { NS_ABORT_IF_FALSE(mURIResolved && aOther.mURIResolved, "How do you know the URIs aren't null?"); @@ -1662,14 +1662,15 @@ nsCSSValue::URL::URIEquals(const URL& aOther) const } nsIURI* -nsCSSValue::URL::GetURI() const +css::URLValue::GetURI() const { if (!mURIResolved) { mURIResolved = true; // Be careful to not null out mURI before we've passed it as the base URI nsCOMPtr newURI; NS_NewURI(getter_AddRefs(newURI), - NS_ConvertUTF16toUTF8(GetBufferValue(mString)), nullptr, mURI); + NS_ConvertUTF16toUTF8(nsCSSValue::GetBufferValue(mString)), + nullptr, mURI); newURI.swap(mURI); } @@ -1677,7 +1678,7 @@ nsCSSValue::URL::GetURI() const } size_t -nsCSSValue::URL::SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf) const +css::URLValue::SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf) const { size_t n = aMallocSizeOf(this); @@ -1694,10 +1695,10 @@ nsCSSValue::URL::SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf) const } -nsCSSValue::Image::Image(nsIURI* aURI, nsStringBuffer* aString, - nsIURI* aReferrer, nsIPrincipal* aOriginPrincipal, - nsIDocument* aDocument) - : URL(aURI, aString, aReferrer, aOriginPrincipal) +css::ImageValue::ImageValue(nsIURI* aURI, nsStringBuffer* aString, + nsIURI* aReferrer, nsIPrincipal* aOriginPrincipal, + nsIDocument* aDocument) + : URLValue(aURI, aString, aReferrer, aOriginPrincipal) { if (aDocument->GetOriginalDocument()) { aDocument = aDocument->GetOriginalDocument(); @@ -1713,7 +1714,8 @@ static PLDHashOperator ClearRequestHashtable(nsISupports* aKey, nsCOMPtr& aValue, void* aClosure) { - nsCSSValue::Image* image = static_cast(aClosure); + mozilla::css::ImageValue* image = + static_cast(aClosure); nsIDocument* doc = static_cast(aKey); #ifdef DEBUG @@ -1734,7 +1736,7 @@ ClearRequestHashtable(nsISupports* aKey, nsCOMPtr& aValue, return PL_DHASH_REMOVE; } -nsCSSValue::Image::~Image() +css::ImageValue::~ImageValue() { mRequests.Enumerate(&ClearRequestHashtable, this); } diff --git a/layout/style/nsCSSValue.h b/layout/style/nsCSSValue.h index 2b485806210..03eac7f2152 100644 --- a/layout/style/nsCSSValue.h +++ b/layout/style/nsCSSValue.h @@ -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 mURI; +public: + nsStringBuffer* mString; // Could use nsRefPtr, but it'd add useless + // null-checks; this is never null. + nsCOMPtr mReferrer; + nsCOMPtr 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 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 { eCSSUnit_Null = 0, // (n/a) null unit, value is not specified eCSSUnit_Auto = 1, // (n/a) value is algorithmic @@ -182,11 +255,9 @@ public: struct Array; friend struct Array; - struct URL; - friend struct URL; + friend struct mozilla::css::URLValue; - struct Image; - friend struct Image; + friend struct mozilla::css::ImageValue; // for valueless units only (null, auto, inherit, none, all, normal) explicit nsCSSValue(nsCSSUnit aUnit = eCSSUnit_Null) @@ -199,8 +270,8 @@ public: nsCSSValue(float aValue, nsCSSUnit aUnit); nsCSSValue(const nsString& aValue, nsCSSUnit aUnit); nsCSSValue(Array* aArray, nsCSSUnit aUnit); - explicit nsCSSValue(URL* aValue); - explicit nsCSSValue(Image* aValue); + explicit nsCSSValue(mozilla::css::URLValue* aValue); + explicit nsCSSValue(mozilla::css::ImageValue* aValue); explicit nsCSSValue(nsCSSValueGradient* aValue); nsCSSValue(const nsCSSValue& aCopy); ~nsCSSValue() { Reset(); } @@ -349,7 +420,7 @@ public: inline nsCSSValueTriplet& GetTripletValue(); inline const nsCSSValueTriplet& GetTripletValue() const; - URL* GetURLStructValue() const + mozilla::css::URLValue* GetURLStructValue() const { // Not allowing this for Image values, because if the caller takes // a ref to them they won't be able to delete them properly. @@ -357,7 +428,7 @@ public: return mValue.mURL; } - Image* GetImageStructValue() const + mozilla::css::ImageValue* GetImageStructValue() const { NS_ABORT_IF_FALSE(mUnit == eCSSUnit_Image, "not an Image value"); return mValue.mImage; @@ -395,8 +466,8 @@ public: void SetStringValue(const nsString& aValue, nsCSSUnit aUnit); void SetColorValue(nscolor aValue); void SetArrayValue(nsCSSValue::Array* aArray, nsCSSUnit aUnit); - void SetURLValue(nsCSSValue::URL* aURI); - void SetImageValue(nsCSSValue::Image* aImage); + void SetURLValue(mozilla::css::URLValue* aURI); + void SetImageValue(mozilla::css::ImageValue* aImage); void SetGradientValue(nsCSSValueGradient* aGradient); void SetPairValue(const nsCSSValuePair* aPair); void SetPairValue(const nsCSSValue& xValue, const nsCSSValue& yValue); @@ -434,73 +505,6 @@ public: 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 mURI; - public: - nsStringBuffer* mString; // Could use nsRefPtr, but it'd add useless - // null-checks; this is never null. - nsCOMPtr mReferrer; - nsCOMPtr 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 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: static const PRUnichar* GetBufferValue(nsStringBuffer* aBuffer) { return static_cast(aBuffer->Data()); @@ -516,8 +520,8 @@ protected: nsStringBuffer* mString; nscolor mColor; Array* mArray; - URL* mURL; - Image* mImage; + mozilla::css::URLValue* mURL; + mozilla::css::ImageValue* mImage; nsCSSValueGradient* mGradient; nsCSSValuePair_heap* mPair; nsCSSRect_heap* mRect; diff --git a/layout/style/nsRuleNode.cpp b/layout/style/nsRuleNode.cpp index 55be64bfc3e..a16923a01de 100644 --- a/layout/style/nsRuleNode.cpp +++ b/layout/style/nsRuleNode.cpp @@ -4658,7 +4658,7 @@ nsRuleNode::ComputeDisplayData(void* aStartStruct, // binding: url, none, inherit const nsCSSValue* bindingValue = aRuleData->ValueForBinding(); if (eCSSUnit_URL == bindingValue->GetUnit()) { - nsCSSValue::URL* url = bindingValue->GetURLStructValue(); + mozilla::css::URLValue* url = bindingValue->GetURLStructValue(); NS_ASSERTION(url, "What's going on here?"); if (NS_LIKELY(url->GetURI())) { diff --git a/layout/style/nsStyleAnimation.cpp b/layout/style/nsStyleAnimation.cpp index 7e0b4f03d8d..cbb370242b7 100644 --- a/layout/style/nsStyleAnimation.cpp +++ b/layout/style/nsStyleAnimation.cpp @@ -3124,11 +3124,11 @@ nsStyleAnimation::ExtractComputedValue(nsCSSProperty aProperty, GetURIAsUtf16StringBuffer(paint.mPaint.mPaintServer); NS_ENSURE_TRUE(!!uriAsStringBuffer, false); nsIDocument* doc = aStyleContext->PresContext()->Document(); - nsRefPtr url = - new nsCSSValue::URL(paint.mPaint.mPaintServer, - uriAsStringBuffer, - doc->GetDocumentURI(), - doc->NodePrincipal()); + nsRefPtr url = + new mozilla::css::URLValue(paint.mPaint.mPaintServer, + uriAsStringBuffer, + doc->GetDocumentURI(), + doc->NodePrincipal()); pair->mXValue.SetURLValue(url); pair->mYValue.SetColorValue(paint.mFallbackColor); aComputedValue.SetAndAdoptCSSValuePairValue(pair.forget(), diff --git a/layout/style/nsStyleStruct.cpp b/layout/style/nsStyleStruct.cpp index be67a041760..379ee1ab2bd 100644 --- a/layout/style/nsStyleStruct.cpp +++ b/layout/style/nsStyleStruct.cpp @@ -51,7 +51,7 @@ static bool EqualURIs(nsIURI *aURI1, nsIURI *aURI2) 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 (aURI1 && aURI2 && aURI1->URIEquals(*aURI2)); diff --git a/layout/style/nsStyleStruct.h b/layout/style/nsStyleStruct.h index 03871a75ee4..5b3d3d254a0 100644 --- a/layout/style/nsStyleStruct.h +++ b/layout/style/nsStyleStruct.h @@ -1556,7 +1556,7 @@ struct nsStyleDisplay { // We guarantee that if mBinding is non-null, so are mBinding->GetURI() and // mBinding->mOriginPrincipal. - nsRefPtr mBinding; // [reset] + nsRefPtr mBinding; // [reset] nsRect mClip; // [reset] offsets from upper-left border edge float mOpacity; // [reset] uint8_t mDisplay; // [reset] see nsStyleConsts.h NS_STYLE_DISPLAY_*