diff --git a/layout/style/nsRuleNode.cpp b/layout/style/nsRuleNode.cpp index a01d295eb6ad..abd726b8dd60 100644 --- a/layout/style/nsRuleNode.cpp +++ b/layout/style/nsRuleNode.cpp @@ -1411,7 +1411,7 @@ static void SetStyleImage(nsStyleContext* aStyleContext, isLocalRef, "unexpected unit; maybe nsCSSValue::Image::Image() failed?"); #endif - + aResult.SetURLValue(do_AddRef(aValue.GetURLStructValue())); break; } default: diff --git a/layout/style/nsStyleStruct.cpp b/layout/style/nsStyleStruct.cpp index dcffd6355dec..6a6bc4ab06a5 100644 --- a/layout/style/nsStyleStruct.cpp +++ b/layout/style/nsStyleStruct.cpp @@ -2194,6 +2194,8 @@ nsStyleImage::DoCopy(const nsStyleImage& aOther) SetGradientData(aOther.mGradient); } else if (aOther.mType == eStyleImageType_Element) { SetElementId(aOther.mElementId); + } else if (aOther.mType == eStyleImageType_URL) { + SetURLValue(do_AddRef(aOther.mURLValue)); } UniquePtr cropRectCopy; @@ -2212,6 +2214,8 @@ nsStyleImage::SetNull() NS_RELEASE(mImage); } else if (mType == eStyleImageType_Element) { free(mElementId); + } else if (mType == eStyleImageType_URL) { + NS_RELEASE(mURLValue); } mType = eStyleImageType_Null; @@ -2272,6 +2276,21 @@ nsStyleImage::SetCropRect(UniquePtr aCropRect) mCropRect = Move(aCropRect); } +void +nsStyleImage::SetURLValue(already_AddRefed aValue) +{ + RefPtr value = aValue; + + if (mType != eStyleImageType_Null) { + SetNull(); + } + + if (value) { + mURLValue = value.forget().take(); + mType = eStyleImageType_URL; + } +} + static int32_t ConvertToPixelCoord(const nsStyleCoord& aCoord, int32_t aPercentScale) { @@ -2417,6 +2436,7 @@ nsStyleImage::IsComplete() const return false; case eStyleImageType_Gradient: case eStyleImageType_Element: + case eStyleImageType_URL: return true; case eStyleImageType_Image: { imgRequestProxy* req = GetImageData(); @@ -2442,6 +2462,7 @@ nsStyleImage::IsLoaded() const return false; case eStyleImageType_Gradient: case eStyleImageType_Element: + case eStyleImageType_URL: return true; case eStyleImageType_Image: { imgRequestProxy* req = GetImageData(); @@ -2489,6 +2510,10 @@ nsStyleImage::operator==(const nsStyleImage& aOther) const return NS_strcmp(mElementId, aOther.mElementId) == 0; } + if (mType == eStyleImageType_URL) { + return DefinitelyEqualURIs(mURLValue, aOther.mURLValue); + } + return true; } @@ -2523,6 +2548,18 @@ nsStyleImage::GetImageURI() const return uri.forget(); } +css::URLValueData* +nsStyleImage::GetURLValue() const +{ + if (mType == eStyleImageType_Image) { + return mImage->GetImageValue(); + } else if (mType == eStyleImageType_URL) { + return mURLValue; + } + + return nullptr; +} + // -------------------- // nsStyleImageLayers // diff --git a/layout/style/nsStyleStruct.h b/layout/style/nsStyleStruct.h index faca7fe05a08..1f1f09473388 100644 --- a/layout/style/nsStyleStruct.h +++ b/layout/style/nsStyleStruct.h @@ -305,6 +305,8 @@ private: class nsStyleImageRequest { public: + typedef mozilla::css::URLValueData URLValueData; + // Flags describing whether the imgRequestProxy must be tracked in the // ImageTracker, whether LockImage/UnlockImage calls will be made // when obtaining and releasing the imgRequestProxy, and whether @@ -360,7 +362,6 @@ public: mozilla::css::ImageValue* GetImageValue() const { return mImageValue; } already_AddRefed GetImageURI() const; - NS_INLINE_DECL_THREADSAFE_REFCOUNTING(nsStyleImageRequest); private: @@ -386,7 +387,8 @@ enum nsStyleImageType { eStyleImageType_Null, eStyleImageType_Image, eStyleImageType_Gradient, - eStyleImageType_Element + eStyleImageType_Element, + eStyleImageType_URL }; struct CachedBorderImageData @@ -419,6 +421,9 @@ private: */ struct nsStyleImage { + typedef mozilla::css::URLValue URLValue; + typedef mozilla::css::URLValueData URLValueData; + nsStyleImage(); ~nsStyleImage(); nsStyleImage(const nsStyleImage& aOther); @@ -429,6 +434,7 @@ struct nsStyleImage void SetGradientData(nsStyleGradient* aGradient); void SetElementId(const char16_t* aElementId); void SetCropRect(mozilla::UniquePtr aCropRect); + void SetURLValue(already_AddRefed aData); void ResolveImage(nsPresContext* aContext) { MOZ_ASSERT(mType != eStyleImageType_Image || mImage); @@ -464,6 +470,8 @@ struct nsStyleImage already_AddRefed GetImageURI() const; + URLValueData* GetURLValue() const; + /** * Compute the actual crop rect in pixels, using the source image bounds. * The computation involves converting percentage unit to pixel unit and @@ -547,6 +555,9 @@ private: union { nsStyleImageRequest* mImage; nsStyleGradient* mGradient; + URLValue* mURLValue; // See the comment in SetStyleImage's 'case + // eCSSUnit_URL' section to know why we need to + // store URLValues separately from mImage. char16_t* mElementId; };