Bug 1301245 - Part 1. Implement nsStyleImage::SetURL and GetURLValueData.
Prerequisites of removing Layer::mSourceURI.
MozReview-Commit-ID: E20MEzXv8cg
--- a/layout/style/nsRuleNode.cpp
+++ b/layout/style/nsRuleNode.cpp
@@ -1406,17 +1406,17 @@ static void SetStyleImage(nsStyleContext
nsIURI* imageURI = aValue.GetURLValue();
imageURI->EqualsExceptRef(docURI, &isEqualExceptRef);
}
MOZ_ASSERT(aStyleContext->IsStyleIfVisited() || isEqualExceptRef ||
isLocalRef,
"unexpected unit; maybe nsCSSValue::Image::Image() failed?");
#endif
-
+ aResult.SetURL(do_AddRef(aValue.GetURLStructValue()));
break;
}
default:
MOZ_ASSERT_UNREACHABLE("Unexpected Unit type.");
break;
}
}
--- a/layout/style/nsStyleStruct.cpp
+++ b/layout/style/nsStyleStruct.cpp
@@ -2192,16 +2192,18 @@ nsStyleImage::DoCopy(const nsStyleImage&
SetNull();
if (aOther.mType == eStyleImageType_Image) {
SetImageRequest(do_AddRef(aOther.mImage));
} else if (aOther.mType == eStyleImageType_Gradient) {
SetGradientData(aOther.mGradient);
} else if (aOther.mType == eStyleImageType_Element) {
SetElementId(aOther.mElementId);
+ } else if (mType == eStyleImageType_Url) {
+ SetURL(do_AddRef(aOther.mUrlData));
}
UniquePtr<nsStyleSides> cropRectCopy;
if (aOther.mCropRect) {
cropRectCopy = MakeUnique<nsStyleSides>(*aOther.mCropRect.get());
}
SetCropRect(Move(cropRectCopy));
}
@@ -2210,16 +2212,18 @@ void
nsStyleImage::SetNull()
{
if (mType == eStyleImageType_Gradient) {
mGradient->Release();
} else if (mType == eStyleImageType_Image) {
NS_RELEASE(mImage);
} else if (mType == eStyleImageType_Element) {
free(mElementId);
+ } else if (mType == eStyleImageType_Url) {
+ NS_RELEASE(mUrlData);
}
mType = eStyleImageType_Null;
mCropRect = nullptr;
}
void
nsStyleImage::SetImageRequest(already_AddRefed<nsStyleImageRequest> aImage)
@@ -2270,16 +2274,31 @@ nsStyleImage::SetElementId(const char16_
}
void
nsStyleImage::SetCropRect(UniquePtr<nsStyleSides> aCropRect)
{
mCropRect = Move(aCropRect);
}
+void
+nsStyleImage::SetURL(already_AddRefed<URLValueData> aData)
+{
+ RefPtr<URLValueData> data = aData;
+
+ if (mType != eStyleImageType_Null) {
+ SetNull();
+ }
+
+ if (data) {
+ mUrlData = data.forget().take();
+ mType = eStyleImageType_Url;
+ }
+}
+
static int32_t
ConvertToPixelCoord(const nsStyleCoord& aCoord, int32_t aPercentScale)
{
double pixelValue;
switch (aCoord.GetUnit()) {
case eStyleUnit_Percent:
pixelValue = aCoord.GetPercentValue() * aPercentScale;
break;
@@ -2415,16 +2434,17 @@ nsStyleImage::IsOpaque() const
bool
nsStyleImage::IsComplete() const
{
switch (mType) {
case eStyleImageType_Null:
return false;
case eStyleImageType_Gradient:
case eStyleImageType_Element:
+ case eStyleImageType_Url:
return true;
case eStyleImageType_Image: {
imgRequestProxy* req = GetImageData();
if (!req) {
return false;
}
uint32_t status = imgIRequest::STATUS_ERROR;
return NS_SUCCEEDED(req->GetImageStatus(&status)) &&
@@ -2521,16 +2541,28 @@ nsStyleImage::GetImageURI() const
if (mType != eStyleImageType_Image) {
return nullptr;
}
nsCOMPtr<nsIURI> uri = mImage->GetImageURI();
return uri.forget();
}
+css::URLValueData*
+nsStyleImage::GetURLValueData() const
+{
+ if (mType == eStyleImageType_Image) {
+ return mImage->GetURLValueData();
+ } else if (mType == eStyleImageType_Url) {
+ return mUrlData;
+ }
+
+ return nullptr;
+}
+
// --------------------
// nsStyleImageLayers
//
const nsCSSPropertyID nsStyleImageLayers::kBackgroundLayerTable[] = {
eCSSProperty_background, // shorthand
eCSSProperty_background_color, // color
eCSSProperty_background_image, // image
--- a/layout/style/nsStyleStruct.h
+++ b/layout/style/nsStyleStruct.h
@@ -300,16 +300,18 @@ private:
* creates a new css::ImageValue to represent the url() information passed
* to the constructor. This ImageValue is held on to for the comparisons done
* in DefinitelyEquals(), so that we don't need to call into the non-OMT-safe
* Equals() on the nsIURI objects returned from imgRequestProxy::GetURI().
*/
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
// RequestDiscard will be called on release.
enum class Mode : uint8_t {
// The imgRequestProxy will be added to the ImageTracker when resolved
// Without this flag, the nsStyleImageRequest itself will call LockImage/
// UnlockImage on the imgRequestProxy, rather than leaving locking to the
@@ -357,17 +359,19 @@ public:
// Returns whether the ImageValue objects in the two nsStyleImageRequests
// return true from URLValueData::DefinitelyEqualURIs.
bool DefinitelyEquals(const nsStyleImageRequest& aOther) const;
mozilla::css::ImageValue* GetImageValue() const { return mImageValue; }
already_AddRefed<nsIURI> GetImageURI() const;
-
+ URLValueData* GetURLValueData() const {
+ return mImageValue;
+ }
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(nsStyleImageRequest);
private:
~nsStyleImageRequest();
nsStyleImageRequest& operator=(const nsStyleImageRequest& aOther) = delete;
void MaybeTrackAndLock();
@@ -383,17 +387,18 @@ private:
};
MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(nsStyleImageRequest::Mode)
enum nsStyleImageType {
eStyleImageType_Null,
eStyleImageType_Image,
eStyleImageType_Gradient,
- eStyleImageType_Element
+ eStyleImageType_Element,
+ eStyleImageType_Url
};
struct CachedBorderImageData
{
// Caller are expected to ensure that the value of aSVGViewportSize is
// different from the cached one since the method won't do the check.
void SetCachedSVGViewportSize(const mozilla::Maybe<nsSize>& aSVGViewportSize);
const mozilla::Maybe<nsSize>& GetCachedSVGViewportSize();
@@ -416,26 +421,29 @@ private:
* (3) An element within a document, or an <img>, <video>, or <canvas> element
* not in a document.
* (*) Optionally a crop rect can be set to paint a partial (rectangular)
* region of an image. (Currently, this feature is only supported with an
* image of type (1)).
*/
struct nsStyleImage
{
+ typedef mozilla::css::URLValueData URLValueData;
+
nsStyleImage();
~nsStyleImage();
nsStyleImage(const nsStyleImage& aOther);
nsStyleImage& operator=(const nsStyleImage& aOther);
void SetNull();
void SetImageRequest(already_AddRefed<nsStyleImageRequest> aImage);
void SetGradientData(nsStyleGradient* aGradient);
void SetElementId(const char16_t* aElementId);
void SetCropRect(mozilla::UniquePtr<nsStyleSides> aCropRect);
+ void SetURL(already_AddRefed<URLValueData> aData);
void ResolveImage(nsPresContext* aContext) {
MOZ_ASSERT(mType != eStyleImageType_Image || mImage);
if (mType == eStyleImageType_Image && !mImage->IsResolved()) {
mImage->Resolve(aContext);
}
}
@@ -461,16 +469,18 @@ struct nsStyleImage
const mozilla::UniquePtr<nsStyleSides>& GetCropRect() const {
NS_ASSERTION(mType == eStyleImageType_Image,
"Only image data can have a crop rect");
return mCropRect;
}
already_AddRefed<nsIURI> GetImageURI() const;
+ URLValueData* GetURLValueData() const;
+
/**
* Compute the actual crop rect in pixels, using the source image bounds.
* The computation involves converting percentage unit to pixel unit and
* clamping each side value to fit in the source image bounds.
* @param aActualCropRect the computed actual crop rect.
* @param aIsEntireImage true iff |aActualCropRect| is identical to the
* source image bounds.
* @return true iff |aActualCropRect| holds a meaningful value.
@@ -544,16 +554,19 @@ private:
// This variable keeps some cache data for border image and is lazily
// allocated since it is only used in border image case.
mozilla::UniquePtr<CachedBorderImageData> mCachedBIData;
nsStyleImageType mType;
union {
nsStyleImageRequest* mImage;
nsStyleGradient* mGradient;
+ URLValueData* mUrlData; // See the comment in SetStyleImage's 'case
+ // eCSSUnit_URL' section to know why we need to
+ // keep url other then mImage.
char16_t* mElementId;
};
// This is _currently_ used only in conjunction with eStyleImageType_Image.
mozilla::UniquePtr<nsStyleSides> mCropRect;
};
struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleColor