Bug 1495994 - Part 4: Merge css::{URLValueData, ImageValue} into css::URLValue r=emilio

Depends on D7595

Differential Revision: https://phabricator.services.mozilla.com/D8061
This commit is contained in:
Cameron McCormack
2018-10-10 02:58:20 +00:00
parent 9d2d1b91e9
commit e389012eee
16 changed files with 197 additions and 326 deletions

View File

@@ -53,7 +53,7 @@ ImageLoader::DropDocumentReference()
request->CancelAndForgetObserver(NS_BINDING_ABORTED);
}
// Need to check whether the entry exists, since the css::ImageValue might
// Need to check whether the entry exists, since the css::URLValue might
// go away before ImageLoader::DropDocumentReference is called.
uint64_t imageLoadID = it.Key();
if (auto entry = sImages->Lookup(imageLoadID)) {
@@ -208,7 +208,7 @@ ImageLoader::AssociateRequestToFrame(imgIRequest* aRequest,
}
imgRequestProxy*
ImageLoader::RegisterCSSImage(ImageLoader::Image* aImage)
ImageLoader::RegisterCSSImage(URLValue* aImage)
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(aImage);
@@ -254,7 +254,7 @@ ImageLoader::RegisterCSSImage(ImageLoader::Image* aImage)
}
/* static */ void
ImageLoader::DeregisterCSSImageFromAllLoaders(ImageLoader::Image* aImage)
ImageLoader::DeregisterCSSImageFromAllLoaders(URLValue* aImage)
{
MOZ_ASSERT(aImage);
@@ -455,7 +455,7 @@ ImageLoader::LoadImage(nsIURI* aURI,
nsIURI* aReferrer,
mozilla::net::ReferrerPolicy aPolicy,
nsIDocument* aDocument,
ImageLoader::Image* aImage,
URLValue* aImage,
CORSMode aCorsMode)
{
MOZ_ASSERT(NS_IsMainThread());
@@ -469,7 +469,7 @@ ImageLoader::LoadImage(nsIURI* aURI,
}
if (sImages->Contains(aImage->LoadID())) {
// This css::ImageValue has already been loaded.
// This css::URLValue has already been loaded.
return;
}

View File

@@ -31,7 +31,7 @@ class nsIPrincipal;
namespace mozilla {
namespace css {
struct ImageValue;
struct URLValue;
/**
* NOTE: All methods must be called from the main thread unless otherwise
@@ -51,8 +51,6 @@ public:
REQUEST_HAS_BLOCKED_ONLOAD = 1u << 1,
};
typedef mozilla::css::ImageValue Image;
explicit ImageLoader(nsIDocument* aDocument)
: mDocument(aDocument),
mInClone(false)
@@ -65,7 +63,7 @@ public:
void DropDocumentReference();
imgRequestProxy* RegisterCSSImage(Image* aImage);
imgRequestProxy* RegisterCSSImage(URLValue* aImage);
void AssociateRequestToFrame(imgIRequest* aRequest,
nsIFrame* aFrame,
@@ -88,14 +86,14 @@ public:
nsIURI* aReferrer,
mozilla::net::ReferrerPolicy aPolicy,
nsIDocument* aDocument,
Image* aCSSValue,
URLValue* aImage,
CORSMode aCorsMode);
// Cancels the image load for the given css::ImageValue and deregisters
// Cancels the image load for the given css::URLValue and deregisters
// it from any ImageLoaders it was registered with.
//
// May be called from any thread.
static void DeregisterCSSImageFromAllLoaders(Image* aImage);
static void DeregisterCSSImageFromAllLoaders(URLValue* aImage);
void FlushUseCounters();
@@ -187,39 +185,39 @@ private:
// A weak pointer to our document. Nulled out by DropDocumentReference.
nsIDocument* mDocument;
// A map of css::ImageValues, keyed by their LoadID(), to the imgRequestProxy
// A map of css::URLValues, keyed by their LoadID(), to the imgRequestProxy
// representing the load of the image for this ImageLoader's document.
//
// We use the LoadID() as the key since we can only access mRegisteredImages
// on the main thread, but css::ImageValues might be destroyed from other
// on the main thread, but css::URLValues might be destroyed from other
// threads, and we don't want to leave dangling pointers around.
nsRefPtrHashtable<nsUint64HashKey, imgRequestProxy> mRegisteredImages;
// Are we cloning? If so, ignore any notifications we get.
bool mInClone;
// Data associated with every css::ImageValue object that has had a load
// Data associated with every css::URLValue object that has had a load
// started.
struct ImageTableEntry
{
// Set of all ImageLoaders that have registered this css::ImageValue.
// Set of all ImageLoaders that have registered this css::URLValue.
nsTHashtable<nsPtrHashKey<ImageLoader>> mImageLoaders;
// The "canonical" image request for this css::ImageValue.
// The "canonical" image request for this css::URLValue.
//
// This request is held on to as long as the specified css::ImageValue
// This request is held on to as long as the specified css::URLValue
// object is, so that any image that has already started loading (or
// has completed loading) will stay alive even if all computed values
// referencing the image requesst have gone away.
RefPtr<imgRequestProxy> mCanonicalRequest;
};
// A table of all css::ImageValues that have been loaded, keyed by their
// A table of all css::URLValues that have been loaded, keyed by their
// LoadID(), mapping them to the set of ImageLoaders they have been registered
// in, and recording their "canonical" image request.
//
// We use the LoadID() as the key since we can only access sImages on the
// main thread, but css::ImageValues might be destroyed from other threads,
// main thread, but css::URLValues might be destroyed from other threads,
// and we don't want to leave dangling pointers around.
static nsClassHashtable<nsUint64HashKey, ImageTableEntry>* sImages;
};

View File

@@ -1386,21 +1386,12 @@ Gecko_CounterStyle_GetAnonymous(const CounterStylePtr* aPtr)
}
already_AddRefed<css::URLValue>
ServoBundledURI::IntoCssUrl()
ServoBundledURI::IntoCssUrl(CORSMode aCorsMode)
{
MOZ_ASSERT(mExtraData->GetReferrer());
MOZ_ASSERT(mExtraData->GetPrincipal());
RefPtr<css::URLValue> urlValue =
new css::URLValue(mURLString, do_AddRef(mExtraData), CORSMode::CORS_NONE);
return urlValue.forget();
}
already_AddRefed<css::ImageValue>
ServoBundledURI::IntoCssImage(mozilla::CORSMode aCorsMode)
{
RefPtr<css::ImageValue> urlValue =
new css::ImageValue(mURLString, do_AddRef(mExtraData), aCorsMode);
new css::URLValue(mURLString, do_AddRef(mExtraData), aCorsMode);
return urlValue.forget();
}
@@ -1418,35 +1409,18 @@ Gecko_SetGradientImageValue(nsStyleImage* aImage, nsStyleGradient* aGradient)
aImage->SetGradientData(aGradient);
}
NS_IMPL_THREADSAFE_FFI_REFCOUNTING(mozilla::css::ImageValue, ImageValue);
static already_AddRefed<nsStyleImageRequest>
CreateStyleImageRequest(nsStyleImageRequest::Mode aModeFlags,
mozilla::css::ImageValue* aImageValue)
URLValue* aImageValue)
{
RefPtr<nsStyleImageRequest> req =
new nsStyleImageRequest(aModeFlags, aImageValue);
return req.forget();
}
mozilla::css::ImageValue*
Gecko_ImageValue_Create(ServoBundledURI aURI, mozilla::CORSMode aCORSMode)
{
return aURI.IntoCssImage(aCORSMode).take();
}
MOZ_DEFINE_MALLOC_SIZE_OF(GeckoImageValueMallocSizeOf)
size_t
Gecko_ImageValue_SizeOfIncludingThis(mozilla::css::ImageValue* aImageValue)
{
MOZ_ASSERT(NS_IsMainThread());
return aImageValue->SizeOfIncludingThis(GeckoImageValueMallocSizeOf);
}
void
Gecko_SetLayerImageImageValue(nsStyleImage* aImage,
mozilla::css::ImageValue* aImageValue)
URLValue* aImageValue)
{
MOZ_ASSERT(aImage && aImageValue);
@@ -1486,7 +1460,7 @@ Gecko_SetCursorArrayLength(nsStyleUI* aStyleUI, size_t aLen)
void
Gecko_SetCursorImageValue(nsCursorImage* aCursor,
mozilla::css::ImageValue* aImageValue)
URLValue* aImageValue)
{
MOZ_ASSERT(aCursor && aImageValue);
@@ -1502,7 +1476,7 @@ Gecko_CopyCursorArrayFrom(nsStyleUI* aDest, const nsStyleUI* aSrc)
void
Gecko_SetContentDataImageValue(nsStyleContentData* aContent,
mozilla::css::ImageValue* aImageValue)
URLValue* aImageValue)
{
MOZ_ASSERT(aContent && aImageValue);
@@ -1584,7 +1558,7 @@ Gecko_SetListStyleImageNone(nsStyleList* aList)
void
Gecko_SetListStyleImageImageValue(nsStyleList* aList,
mozilla::css::ImageValue* aImageValue)
URLValue* aImageValue)
{
MOZ_ASSERT(aList && aImageValue);
@@ -1652,17 +1626,17 @@ Gecko_CopyStyleGridTemplateValues(UniquePtr<nsStyleGridTemplate>* aGridTemplate,
}
}
mozilla::css::GridTemplateAreasValue*
GridTemplateAreasValue*
Gecko_NewGridTemplateAreasValue(uint32_t aAreas, uint32_t aTemplates, uint32_t aColumns)
{
RefPtr<mozilla::css::GridTemplateAreasValue> value = new mozilla::css::GridTemplateAreasValue;
RefPtr<GridTemplateAreasValue> value = new GridTemplateAreasValue;
value->mNamedAreas.SetLength(aAreas);
value->mTemplates.SetLength(aTemplates);
value->mNColumns = aColumns;
return value.forget().take();
}
NS_IMPL_THREADSAFE_FFI_REFCOUNTING(mozilla::css::GridTemplateAreasValue, GridTemplateAreasValue);
NS_IMPL_THREADSAFE_FFI_REFCOUNTING(GridTemplateAreasValue, GridTemplateAreasValue);
void
Gecko_ClearAndResizeStyleContents(nsStyleContent* aContent, uint32_t aHowMany)
@@ -2037,9 +2011,9 @@ Gecko_nsStyleSVG_CopyContextProperties(nsStyleSVG* aDst, const nsStyleSVG* aSrc)
css::URLValue*
Gecko_NewURLValue(ServoBundledURI aURI)
Gecko_URLValue_Create(ServoBundledURI aURI, mozilla::CORSMode aCORSMode)
{
RefPtr<css::URLValue> url = aURI.IntoCssUrl();
RefPtr<css::URLValue> url = aURI.IntoCssUrl(aCORSMode);
return url.forget().take();
}
@@ -2053,7 +2027,7 @@ Gecko_URLValue_SizeOfIncludingThis(URLValue* aURL)
}
void
Gecko_GetComputedURLSpec(const URLValueData* aURL, nsCString* aOut)
Gecko_GetComputedURLSpec(const URLValue* aURL, nsCString* aOut)
{
MOZ_ASSERT(aURL);
MOZ_ASSERT(aOut);
@@ -2065,7 +2039,7 @@ Gecko_GetComputedURLSpec(const URLValueData* aURL, nsCString* aOut)
}
void
Gecko_GetComputedImageURLSpec(const URLValueData* aURL, nsCString* aOut)
Gecko_GetComputedImageURLSpec(const URLValue* aURL, nsCString* aOut)
{
// Image URIs don't serialize local refs as local.
if (nsIURI* uri = aURL->GetURI()) {
@@ -2627,7 +2601,10 @@ Gecko_LoadStyleSheet(css::Loader* aLoader,
RawServoMediaListStrong aMediaList)
{
MOZ_ASSERT(NS_IsMainThread());
RefPtr<css::URLValue> url = aServoURL.IntoCssUrl();
// The CORS mode in the URLValue is irrelevant here.
// (CORS_NONE is used for all imported sheets in Load::LoadChildSheet.)
RefPtr<css::URLValue> url = aServoURL.IntoCssUrl(CORS_NONE);
return LoadImportSheet(aLoader, aParent, aParentLoadData, aReusableSheets,
url, aMediaList.Consume()).take();
}
@@ -2639,7 +2616,9 @@ Gecko_LoadStyleSheetAsync(css::SheetLoadDataHolder* aParentData,
RawServoImportRuleStrong aImportRule)
{
RefPtr<SheetLoadDataHolder> loadData = aParentData;
RefPtr<css::URLValue> urlVal = aServoURL.IntoCssUrl();
// The CORS mode in the URLValue is irrelevant here.
// (CORS_NONE is used for all imported sheets in Load::LoadChildSheet.)
RefPtr<css::URLValue> urlVal = aServoURL.IntoCssUrl(CORS_NONE);
RefPtr<RawServoMediaList> mediaList = aMediaList.Consume();
RefPtr<RawServoImportRule> importRule = aImportRule.Consume();
NS_DispatchToMainThread(NS_NewRunnableFunction(__func__,

View File

@@ -44,7 +44,6 @@ namespace mozilla {
namespace css {
class ErrorReporter;
struct URLValue;
struct ImageValue;
class LoaderReusableStyleSheets;
};
namespace dom {
@@ -114,10 +113,9 @@ extern "C" {
class ServoBundledURI
{
public:
// NOTE(emilio): Not calling IntoCssUrl or IntoCssImage will cause to leak the
// NOTE(emilio): Not calling IntoCssUrl will cause to leak the
// string, so don't do that :)
already_AddRefed<mozilla::css::URLValue> IntoCssUrl();
already_AddRefed<mozilla::css::ImageValue> IntoCssImage(mozilla::CORSMode);
already_AddRefed<mozilla::css::URLValue> IntoCssUrl(mozilla::CORSMode);
mozilla::ServoRawOffsetArc<RustString> mURLString;
mozilla::URLExtraData* mExtraData;
};
@@ -352,12 +350,8 @@ Gecko_CounterStyle_GetAnonymous(const mozilla::CounterStylePtr* ptr);
// background-image style.
void Gecko_SetNullImageValue(nsStyleImage* image);
void Gecko_SetGradientImageValue(nsStyleImage* image, nsStyleGradient* gradient);
NS_DECL_THREADSAFE_FFI_REFCOUNTING(mozilla::css::ImageValue, ImageValue);
mozilla::css::ImageValue* Gecko_ImageValue_Create(ServoBundledURI aURI,
mozilla::CORSMode aCORSMode);
size_t Gecko_ImageValue_SizeOfIncludingThis(mozilla::css::ImageValue* aImageValue);
void Gecko_SetLayerImageImageValue(nsStyleImage* image,
mozilla::css::ImageValue* aImageValue);
mozilla::css::URLValue* image_value);
void Gecko_SetImageElement(nsStyleImage* image, nsAtom* atom);
void Gecko_CopyImageValueFrom(nsStyleImage* image, const nsStyleImage* other);
@@ -377,17 +371,17 @@ const nsStyleGradient* Gecko_GetGradientImageValue(const nsStyleImage* image);
// list-style-image style.
void Gecko_SetListStyleImageNone(nsStyleList* style_struct);
void Gecko_SetListStyleImageImageValue(nsStyleList* style_struct,
mozilla::css::ImageValue* aImageValue);
mozilla::css::URLValue* aImageValue);
void Gecko_CopyListStyleImageFrom(nsStyleList* dest, const nsStyleList* src);
// cursor style.
void Gecko_SetCursorArrayLength(nsStyleUI* ui, size_t len);
void Gecko_SetCursorImageValue(nsCursorImage* aCursor,
mozilla::css::ImageValue* aImageValue);
mozilla::css::URLValue* aImageValue);
void Gecko_CopyCursorArrayFrom(nsStyleUI* dest, const nsStyleUI* src);
void Gecko_SetContentDataImageValue(nsStyleContentData* aList,
mozilla::css::ImageValue* aImageValue);
mozilla::css::URLValue* aImageValue);
nsStyleContentData::CounterFunction* Gecko_SetCounterFunction(
nsStyleContentData* content_data, mozilla::StyleContentType);
@@ -547,10 +541,10 @@ void Gecko_nsStyleSVG_CopyDashArray(nsStyleSVG* dst, const nsStyleSVG* src);
void Gecko_nsStyleSVG_SetContextPropertiesLength(nsStyleSVG* svg, uint32_t len);
void Gecko_nsStyleSVG_CopyContextProperties(nsStyleSVG* dst, const nsStyleSVG* src);
mozilla::css::URLValue* Gecko_NewURLValue(ServoBundledURI uri);
mozilla::css::URLValue* Gecko_URLValue_Create(ServoBundledURI uri, mozilla::CORSMode aCORSMode);
size_t Gecko_URLValue_SizeOfIncludingThis(mozilla::css::URLValue* url);
void Gecko_GetComputedURLSpec(const mozilla::css::URLValueData* url, nsCString* spec);
void Gecko_GetComputedImageURLSpec(const mozilla::css::URLValueData* url, nsCString* spec);
void Gecko_GetComputedURLSpec(const mozilla::css::URLValue* url, nsCString* spec);
void Gecko_GetComputedImageURLSpec(const mozilla::css::URLValue* url, nsCString* spec);
void Gecko_nsIURI_Debug(nsIURI*, nsCString* spec);
NS_DECL_THREADSAFE_FFI_REFCOUNTING(mozilla::css::URLValue, CSSURLValue);

View File

@@ -480,9 +480,7 @@ raw-lines = [
whitelist-functions = ["Servo_.*", "Gecko_.*"]
structs-types = [
"mozilla::css::GridTemplateAreasValue",
"mozilla::css::ImageValue",
"mozilla::css::URLValue",
"mozilla::css::URLValueData",
"mozilla::dom::CallerType",
"mozilla::dom::ShadowRoot",
"mozilla::AnonymousCounterStyle",

View File

@@ -885,25 +885,17 @@ nsCSSValue::Array::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) cons
return n;
}
css::URLValueData::URLValueData(ServoRawOffsetArc<RustString> aString,
already_AddRefed<URLExtraData> aExtraData,
CORSMode aCORSMode)
: mExtraData(std::move(aExtraData))
, mURIResolved(false)
, mString(aString)
, mCORSMode(aCORSMode)
css::URLValue::~URLValue()
{
MOZ_ASSERT(mExtraData);
MOZ_ASSERT(mExtraData->GetPrincipal());
}
if (mLoadID != 0) {
ImageLoader::DeregisterCSSImageFromAllLoaders(this);
}
css::URLValueData::~URLValueData()
{
Servo_ReleaseArcStringData(&mString);
}
bool
css::URLValueData::Equals(const URLValueData& aOther) const
css::URLValue::Equals(const URLValue& aOther) const
{
MOZ_ASSERT(NS_IsMainThread());
@@ -924,7 +916,7 @@ css::URLValueData::Equals(const URLValueData& aOther) const
}
bool
css::URLValueData::DefinitelyEqualURIs(const URLValueData& aOther) const
css::URLValue::DefinitelyEqualURIs(const URLValue& aOther) const
{
if (mExtraData->BaseURI() != aOther.mExtraData->BaseURI()) {
return false;
@@ -933,15 +925,15 @@ css::URLValueData::DefinitelyEqualURIs(const URLValueData& aOther) const
}
bool
css::URLValueData::DefinitelyEqualURIsAndPrincipal(
const URLValueData& aOther) const
css::URLValue::DefinitelyEqualURIsAndPrincipal(
const URLValue& aOther) const
{
return mExtraData->GetPrincipal() == aOther.mExtraData->GetPrincipal() &&
DefinitelyEqualURIs(aOther);
}
nsDependentCSubstring
css::URLValueData::GetString() const
css::URLValue::GetString() const
{
const uint8_t* chars;
uint32_t len;
@@ -950,7 +942,7 @@ css::URLValueData::GetString() const
}
nsIURI*
css::URLValueData::GetURI() const
css::URLValue::GetURI() const
{
MOZ_ASSERT(NS_IsMainThread());
@@ -968,7 +960,7 @@ css::URLValueData::GetURI() const
}
bool
css::URLValueData::IsLocalRef() const
css::URLValue::IsLocalRef() const
{
if (mIsLocalRef.isNothing()) {
// IsLocalRefURL is O(N), use it only when IsLocalRef is called.
@@ -978,7 +970,7 @@ css::URLValueData::IsLocalRef() const
}
bool
css::URLValueData::HasRef() const
css::URLValue::HasRef() const
{
if (IsLocalRef()) {
return true;
@@ -994,7 +986,7 @@ css::URLValueData::HasRef() const
}
already_AddRefed<nsIURI>
css::URLValueData::ResolveLocalRef(nsIURI* aURI) const
css::URLValue::ResolveLocalRef(nsIURI* aURI) const
{
nsCOMPtr<nsIURI> result = GetURI();
@@ -1016,14 +1008,14 @@ css::URLValueData::ResolveLocalRef(nsIURI* aURI) const
}
already_AddRefed<nsIURI>
css::URLValueData::ResolveLocalRef(nsIContent* aContent) const
css::URLValue::ResolveLocalRef(nsIContent* aContent) const
{
nsCOMPtr<nsIURI> url = aContent->GetBaseURI();
return ResolveLocalRef(url);
}
void
css::URLValueData::GetSourceString(nsString& aRef) const
css::URLValue::GetSourceString(nsString& aRef) const
{
nsIURI* uri = GetURI();
if (!uri) {
@@ -1034,7 +1026,7 @@ css::URLValueData::GetSourceString(nsString& aRef) const
nsCString cref;
if (IsLocalRef()) {
// XXXheycam It's possible we can just return mString in this case, since
// it should be the "#fragment" string the URLValueData was created with.
// it should be the "#fragment" string the URLValue was created with.
uri->GetRef(cref);
cref.Insert('#', 0);
} else {
@@ -1050,7 +1042,7 @@ css::URLValueData::GetSourceString(nsString& aRef) const
}
bool
css::URLValueData::EqualsExceptRef(nsIURI* aURI) const
css::URLValue::EqualsExceptRef(nsIURI* aURI) const
{
nsIURI* uri = GetURI();
if (!uri) {
@@ -1063,37 +1055,24 @@ css::URLValueData::EqualsExceptRef(nsIURI* aURI) const
}
size_t
css::URLValueData::SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
css::URLValue::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
{
// Measurement of the following members may be added later if DMD finds it
// is worthwhile:
// - mURI
// - mString
// - mExtraData
return 0;
}
size_t
css::URLValue::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
{
// Only measure it if it's unshared, to avoid double-counting.
size_t n = 0;
if (mRefCnt <= 1) {
n += aMallocSizeOf(this);
n += URLValueData::SizeOfExcludingThis(aMallocSizeOf);
}
return n;
}
css::ImageValue::ImageValue(ServoRawOffsetArc<RustString> aString,
already_AddRefed<URLExtraData> aExtraData,
CORSMode aCORSMode)
: URLValueData(aString, std::move(aExtraData), aCORSMode)
{
}
imgRequestProxy*
css::ImageValue::LoadImage(nsIDocument* aDocument)
css::URLValue::LoadImage(nsIDocument* aDocument)
{
MOZ_ASSERT(NS_IsMainThread());
@@ -1124,21 +1103,6 @@ css::ImageValue::LoadImage(nsIDocument* aDocument)
return aDocument->StyleImageLoader()->RegisterCSSImage(this);
}
css::ImageValue::~ImageValue()
{
if (mLoadID != 0) {
ImageLoader::DeregisterCSSImageFromAllLoaders(this);
}
}
size_t
css::ImageValue::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const
{
size_t n = aMallocSizeOf(this);
n += css::URLValueData::SizeOfExcludingThis(aMallocSizeOf);
return n;
}
size_t
mozilla::css::GridTemplateAreasValue::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
{

View File

@@ -93,40 +93,43 @@ class CSSStyleSheet;
namespace mozilla {
namespace css {
struct URLValueData
struct URLValue final
{
protected:
// Methods are not inline because using an nsIPrincipal means requiring
// caps, which leads to REQUIRES hell, since this header is included all
// over.
public:
// aString must not be null.
// principal of aExtraData must not be null.
// Construct with a base URI; this will create the actual URI lazily from
// aString and aExtraData.
URLValueData(ServoRawOffsetArc<RustString> aString,
already_AddRefed<URLExtraData> aExtraData,
CORSMode aCORSMode);
URLValue(ServoRawOffsetArc<RustString> aString,
already_AddRefed<URLExtraData> aExtraData,
CORSMode aCORSMode)
: mExtraData(std::move(aExtraData))
, mURIResolved(false)
, mString(aString)
, mCORSMode(aCORSMode)
{
MOZ_ASSERT(mExtraData);
MOZ_ASSERT(mExtraData->GetPrincipal());
}
public:
// Returns true iff all fields of the two URLValueData objects are equal.
// Returns true iff all fields of the two URLValue objects are equal.
//
// Only safe to call on the main thread, since this will call Equals on the
// nsIURI and nsIPrincipal objects stored on the URLValueData objects.
bool Equals(const URLValueData& aOther) const;
// nsIURI and nsIPrincipal objects stored on the URLValue objects.
bool Equals(const URLValue& aOther) const;
// Returns true iff we know for sure, by comparing the mBaseURI pointer,
// the specified url() value mString, and the mIsLocalRef, that these
// two URLValueData objects represent the same computed url() value.
// two URLValue objects represent the same computed url() value.
//
// Doesn't look at mReferrer or mOriginPrincipal.
//
// Safe to call from any thread.
bool DefinitelyEqualURIs(const URLValueData& aOther) const;
bool DefinitelyEqualURIs(const URLValue& aOther) const;
// Smae as DefinitelyEqualURIs but additionally compares the nsIPrincipal
// pointers of the two URLValueData objects.
bool DefinitelyEqualURIsAndPrincipal(const URLValueData& aOther) const;
// pointers of the two URLValue objects.
bool DefinitelyEqualURIsAndPrincipal(const URLValue& aOther) const;
nsIURI* GetURI() const;
@@ -134,7 +137,7 @@ public:
bool HasRef() const;
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(URLValueData)
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(URLValue)
// When matching a url with mIsLocalRef set, resolve it against aURI;
// Otherwise, ignore aURL and return mURL directly.
@@ -154,6 +157,10 @@ public:
nsDependentCSubstring GetString() const;
size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
imgRequestProxy* LoadImage(nsIDocument* aDocument);
uint64_t LoadID() const { return mLoadID; }
private:
@@ -172,10 +179,9 @@ private:
mozilla::ServoRawOffsetArc<RustString> mString;
protected:
const CORSMode mCORSMode;
// A unique, non-reused ID value for this ImageValue over the life of the
// A unique, non-reused ID value for this URLValue over the life of the
// process. This value is only valid after LoadImage has been called.
//
// We use this as a key in some tables in ImageLoader. This is better than
@@ -186,52 +192,11 @@ protected:
// these IDs.
uint64_t mLoadID = 0;
virtual ~URLValueData();
size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
~URLValue();
private:
URLValueData(const URLValueData& aOther) = delete;
URLValueData& operator=(const URLValueData& aOther) = delete;
friend struct ImageValue;
};
struct URLValue final : public URLValueData
{
URLValue(ServoRawOffsetArc<RustString> aString,
already_AddRefed<URLExtraData> aExtraData,
CORSMode aCORSMode)
: URLValueData(aString, std::move(aExtraData), aCORSMode)
{ }
URLValue(const URLValue&) = delete;
URLValue& operator=(const URLValue&) = delete;
size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
};
struct ImageValue final : public URLValueData
{
// 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.
// This constructor is safe to call from any thread, but Initialize
// must be called later for the object to be useful.
ImageValue(ServoRawOffsetArc<RustString> aURIString,
already_AddRefed<URLExtraData> aExtraData,
CORSMode aCORSMode);
ImageValue(const ImageValue&) = delete;
ImageValue& operator=(const ImageValue&) = delete;
imgRequestProxy* LoadImage(nsIDocument* aDocument);
size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
protected:
~ImageValue();
URLValue(const URLValue& aOther) = delete;
URLValue& operator=(const URLValue& aOther) = delete;
};
struct GridNamedArea {
@@ -417,8 +382,6 @@ public:
struct Array;
friend struct Array;
friend struct mozilla::css::ImageValue;
// for valueless units only (null, auto, inherit, none, all, normal)
explicit nsCSSValue(nsCSSUnit aUnit = eCSSUnit_Null)
: mUnit(aUnit)

View File

@@ -662,7 +662,7 @@ AddImageURL(nsIURI& aURI, nsTArray<nsString>& aURLs)
static void
AddImageURL(const css::URLValueData& aURL, nsTArray<nsString>& aURLs)
AddImageURL(const css::URLValue& aURL, nsTArray<nsString>& aURLs)
{
if (aURL.IsLocalRef()) {
return;
@@ -1696,7 +1696,7 @@ nsComputedDOMStyle::SetValueToPosition(
void
nsComputedDOMStyle::SetValueToURLValue(const css::URLValueData* aURL,
nsComputedDOMStyle::SetValueToURLValue(const css::URLValue* aURL,
nsROCSSPrimitiveValue* aValue)
{
if (!aURL) {
@@ -1704,7 +1704,7 @@ nsComputedDOMStyle::SetValueToURLValue(const css::URLValueData* aURL,
return;
}
// If we have a usable nsIURI in the URLValueData, and the url() wasn't
// If we have a usable nsIURI in the URLValue, and the url() wasn't
// a fragment-only URL, serialize the nsIURI.
if (!aURL->IsLocalRef()) {
if (nsIURI* uri = aURL->GetURI()) {

View File

@@ -470,7 +470,7 @@ private:
nsROCSSPrimitiveValue* aValue);
void SetValueToPosition(const mozilla::Position& aPosition,
nsDOMCSSValueList* aValueList);
void SetValueToURLValue(const mozilla::css::URLValueData* aURL,
void SetValueToURLValue(const mozilla::css::URLValue* aURL,
nsROCSSPrimitiveValue* aValue);
/**

View File

@@ -59,16 +59,16 @@ static constexpr size_t kStyleStructSizeLimit = 504;
#undef STYLE_STRUCT
static bool
DefinitelyEqualURIs(css::URLValueData* aURI1,
css::URLValueData* aURI2)
DefinitelyEqualURIs(css::URLValue* aURI1,
css::URLValue* aURI2)
{
return aURI1 == aURI2 ||
(aURI1 && aURI2 && aURI1->DefinitelyEqualURIs(*aURI2));
}
static bool
DefinitelyEqualURIsAndPrincipal(css::URLValueData* aURI1,
css::URLValueData* aURI2)
DefinitelyEqualURIsAndPrincipal(css::URLValue* aURI1,
css::URLValue* aURI2)
{
return aURI1 == aURI2 ||
(aURI1 && aURI2 && aURI1->DefinitelyEqualURIsAndPrincipal(*aURI2));
@@ -1251,7 +1251,7 @@ nsStyleSVGReset::FinishStyle(nsPresContext* aPresContext, const nsStyleSVGReset*
NS_FOR_VISIBLE_IMAGE_LAYERS_BACK_TO_FRONT(i, mMask) {
nsStyleImage& image = mMask.mLayers[i].mImage;
if (image.GetType() == eStyleImageType_Image) {
css::URLValueData* url = image.GetURLValue();
css::URLValue* url = image.GetURLValue();
// If the url is a local ref, it must be a <mask-resource>, so we don't
// need to resolve the style image.
if (url->IsLocalRef()) {
@@ -2083,7 +2083,7 @@ private:
};
nsStyleImageRequest::nsStyleImageRequest(Mode aModeFlags,
css::ImageValue* aImageValue)
css::URLValue* aImageValue)
: mImageValue(aImageValue)
, mModeFlags(aModeFlags)
, mResolved(false)
@@ -2665,7 +2665,7 @@ nsStyleImage::GetImageURI() const
return uri.forget();
}
css::URLValueData*
css::URLValue*
nsStyleImage::GetURLValue() const
{
if (mType == eStyleImageType_Image) {

View File

@@ -219,15 +219,13 @@ private:
* RequestDiscard() are made to the imgRequestProxy and ImageTracker as
* appropriate, according to the mode flags passed in to the constructor.
*
* The constructor receives a css::ImageValue to represent the url()
* The constructor receives a css::URLValue to represent the url()
* information, which is held on to for the comparisons done in
* DefinitelyEquals().
*/
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
@@ -251,7 +249,7 @@ public:
// Can be called from any thread, but Resolve() must be called later
// on the main thread before get() can be used.
nsStyleImageRequest(Mode aModeFlags, mozilla::css::ImageValue* aImageValue);
nsStyleImageRequest(Mode aModeFlags, mozilla::css::URLValue* aImageValue);
bool Resolve(nsPresContext*, const nsStyleImageRequest* aOldImageRequest);
bool IsResolved() const { return mResolved; }
@@ -265,11 +263,11 @@ public:
return const_cast<nsStyleImageRequest*>(this)->get();
}
// Returns whether the ImageValue objects in the two nsStyleImageRequests
// return true from URLValueData::DefinitelyEqualURIs.
// Returns whether the URLValue objects in the two nsStyleImageRequests
// return true from URLValue::DefinitelyEqualURIs.
bool DefinitelyEquals(const nsStyleImageRequest& aOther) const;
mozilla::css::ImageValue* GetImageValue() const { return mImageValue; }
mozilla::css::URLValue* GetImageValue() const { return mImageValue; }
already_AddRefed<nsIURI> GetImageURI() const;
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(nsStyleImageRequest);
@@ -281,7 +279,7 @@ private:
void MaybeTrackAndLock();
RefPtr<imgRequestProxy> mRequestProxy;
RefPtr<mozilla::css::ImageValue> mImageValue;
RefPtr<mozilla::css::URLValue> mImageValue;
RefPtr<mozilla::dom::ImageTracker> mImageTracker;
// Cache DocGroup for dispatching events in the destructor.
@@ -335,8 +333,7 @@ private:
*/
struct nsStyleImage
{
typedef mozilla::css::URLValue URLValue;
typedef mozilla::css::URLValueData URLValueData;
typedef mozilla::css::URLValue URLValue;
nsStyleImage();
~nsStyleImage();
@@ -390,7 +387,7 @@ struct nsStyleImage
already_AddRefed<nsIURI> GetImageURI() const;
URLValueData* GetURLValue() const;
URLValue* GetURLValue() const;
/**
* Compute the actual crop rect in pixels, using the source image bounds.

View File

@@ -27,7 +27,7 @@
using namespace mozilla::dom;
static already_AddRefed<URLAndReferrerInfo>
ResolveURLUsingLocalRef(nsIFrame* aFrame, const css::URLValueData* aURL)
ResolveURLUsingLocalRef(nsIFrame* aFrame, const css::URLValue* aURL)
{
MOZ_ASSERT(aFrame);
@@ -800,7 +800,7 @@ SVGMaskObserverList::SVGMaskObserverList(nsIFrame* aFrame)
const nsStyleSVGReset *svgReset = aFrame->StyleSVGReset();
for (uint32_t i = 0; i < svgReset->mMask.mImageCount; i++) {
css::URLValueData* data = svgReset->mMask.mLayers[i].mImage.GetURLValue();
css::URLValue* data = svgReset->mMask.mLayers[i].mImage.GetURLValue();
RefPtr<URLAndReferrerInfo> maskUri = ResolveURLUsingLocalRef(aFrame, data);
bool hasRef = false;

View File

@@ -225,13 +225,13 @@ impl nsStyleImage {
match image {
GenericImage::Gradient(boxed_gradient) => self.set_gradient(*boxed_gradient),
GenericImage::Url(ref url) => unsafe {
bindings::Gecko_SetLayerImageImageValue(self, url.0.image_value.get());
bindings::Gecko_SetLayerImageImageValue(self, (url.0).0.url_value.get());
},
GenericImage::Rect(ref image_rect) => {
unsafe {
bindings::Gecko_SetLayerImageImageValue(
self,
image_rect.url.0.image_value.get(),
(image_rect.url.0).0.url_value.get(),
);
bindings::Gecko_InitializeImageCropRect(self);

View File

@@ -7,10 +7,9 @@
use cssparser::Parser;
use gecko_bindings::bindings;
use gecko_bindings::structs::ServoBundledURI;
use gecko_bindings::structs::mozilla::css::URLValueData;
use gecko_bindings::structs::root::{RustString, nsStyleImageRequest};
use gecko_bindings::structs::root::mozilla::CORSMode;
use gecko_bindings::structs::root::mozilla::css::{ImageValue, URLValue};
use gecko_bindings::structs::root::mozilla::css::URLValue;
use gecko_bindings::sugar::refptr::RefPtr;
use malloc_size_of::{MallocSizeOf, MallocSizeOfOps};
use nsstring::nsCString;
@@ -38,8 +37,7 @@ pub struct CssUrl {
}
impl CssUrl {
/// Try to parse a URL from a string value that is a valid CSS token for a
/// URL.
/// Parse a URL from a string value that is a valid CSS token for a URL.
pub fn parse_from_string(url: String, context: &ParserContext) -> Self {
CssUrl {
serialization: Arc::new(url),
@@ -54,8 +52,8 @@ impl CssUrl {
false
}
/// Convert from URLValueData to SpecifiedUrl.
unsafe fn from_url_value_data(url: &URLValueData) -> Self {
/// Convert from URLValue to CssUrl.
unsafe fn from_url_value(url: &URLValue) -> Self {
let arc_type = &url.mString as *const _ as *const RawOffsetArc<String>;
CssUrl {
serialization: Arc::from_raw_offset((*arc_type).clone()),
@@ -117,7 +115,7 @@ impl MallocSizeOf for CssUrl {
}
}
/// A specified url() value for general usage.
/// A specified non-image `url()` value.
#[derive(Clone, Debug, SpecifiedValueInfo, ToCss)]
pub struct SpecifiedUrl {
/// The specified url value.
@@ -129,72 +127,19 @@ pub struct SpecifiedUrl {
}
impl SpecifiedUrl {
fn from_css_url(url: CssUrl) -> Self {
let url_value = unsafe {
let ptr = bindings::Gecko_NewURLValue(url.for_ffi());
// We do not expect Gecko_NewURLValue returns null.
debug_assert!(!ptr.is_null());
RefPtr::from_addrefed(ptr)
};
Self { url, url_value }
}
}
impl PartialEq for SpecifiedUrl {
fn eq(&self, other: &Self) -> bool {
self.url.eq(&other.url)
}
}
impl Eq for SpecifiedUrl {}
impl Parse for SpecifiedUrl {
fn parse<'i, 't>(
context: &ParserContext,
input: &mut Parser<'i, 't>,
) -> Result<Self, ParseError<'i>> {
CssUrl::parse(context, input).map(Self::from_css_url)
}
}
impl MallocSizeOf for SpecifiedUrl {
fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
let mut n = self.url.size_of(ops);
// Although this is a RefPtr, this is the primary reference because
// SpecifiedUrl is responsible for creating the url_value. So we
// measure unconditionally here.
n += unsafe { bindings::Gecko_URLValue_SizeOfIncludingThis(self.url_value.get()) };
n
}
}
/// A specified url() value for image.
///
/// This exists so that we can construct `ImageValue` and reuse it.
#[derive(Clone, Debug, SpecifiedValueInfo, ToCss)]
pub struct SpecifiedImageUrl {
/// The specified url value.
pub url: CssUrl,
/// Gecko's ImageValue so that we can reuse it while rematching a
/// property with this specified value.
#[css(skip)]
pub image_value: RefPtr<ImageValue>,
}
impl SpecifiedImageUrl {
/// Parse a URL from a string value. See SpecifiedUrl::parse_from_string.
/// Parse a URL from a string value.
pub fn parse_from_string(url: String, context: &ParserContext) -> Self {
Self::from_css_url(CssUrl::parse_from_string(url, context))
}
fn from_css_url_with_cors(url: CssUrl, cors: CORSMode) -> Self {
let image_value = unsafe {
let ptr = bindings::Gecko_ImageValue_Create(url.for_ffi(), cors);
// We do not expect Gecko_ImageValue_Create returns null.
let url_value = unsafe {
let ptr = bindings::Gecko_URLValue_Create(url.for_ffi(), cors);
// We do not expect Gecko_URLValue_Create returns null.
debug_assert!(!ptr.is_null());
RefPtr::from_addrefed(ptr)
};
Self { url, image_value }
Self { url, url_value }
}
fn from_css_url(url: CssUrl) -> Self {
@@ -206,18 +151,9 @@ impl SpecifiedImageUrl {
use gecko_bindings::structs::root::mozilla::CORSMode_CORS_ANONYMOUS;
Self::from_css_url_with_cors(url, CORSMode_CORS_ANONYMOUS)
}
/// Provides an alternate method for parsing that associates the URL
/// with anonymous CORS headers.
pub fn parse_with_cors_anonymous<'i, 't>(
context: &ParserContext,
input: &mut Parser<'i, 't>,
) -> Result<Self, ParseError<'i>> {
CssUrl::parse(context, input).map(Self::from_css_url_with_cors_anonymous)
}
}
impl Parse for SpecifiedImageUrl {
impl Parse for SpecifiedUrl {
fn parse<'i, 't>(
context: &ParserContext,
input: &mut Parser<'i, 't>,
@@ -226,21 +162,21 @@ impl Parse for SpecifiedImageUrl {
}
}
impl PartialEq for SpecifiedImageUrl {
impl PartialEq for SpecifiedUrl {
fn eq(&self, other: &Self) -> bool {
self.url.eq(&other.url)
}
}
impl Eq for SpecifiedImageUrl {}
impl Eq for SpecifiedUrl {}
impl MallocSizeOf for SpecifiedImageUrl {
impl MallocSizeOf for SpecifiedUrl {
fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
let mut n = self.url.size_of(ops);
// Although this is a RefPtr, this is the primary reference because
// SpecifiedUrl is responsible for creating the image_value. So we
// SpecifiedUrl is responsible for creating the url_value. So we
// measure unconditionally here.
n += unsafe { bindings::Gecko_ImageValue_SizeOfIncludingThis(self.image_value.get()) };
n += unsafe { bindings::Gecko_URLValue_SizeOfIncludingThis(self.url_value.get()) };
n
}
}
@@ -259,6 +195,37 @@ impl ToComputedValue for SpecifiedUrl {
}
}
/// A specified image `url()` value.
#[derive(Clone, Debug, Eq, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToCss)]
pub struct SpecifiedImageUrl(pub SpecifiedUrl);
impl SpecifiedImageUrl {
/// Parse a URL from a string value that is a valid CSS token for a URL.
pub fn parse_from_string(url: String, context: &ParserContext) -> Self {
SpecifiedImageUrl(SpecifiedUrl::parse_from_string(url, context))
}
/// Provides an alternate method for parsing that associates the URL
/// with anonymous CORS headers.
pub fn parse_with_cors_anonymous<'i, 't>(
context: &ParserContext,
input: &mut Parser<'i, 't>,
) -> Result<Self, ParseError<'i>> {
CssUrl::parse(context, input)
.map(SpecifiedUrl::from_css_url_with_cors_anonymous)
.map(SpecifiedImageUrl)
}
}
impl Parse for SpecifiedImageUrl {
fn parse<'i, 't>(
context: &ParserContext,
input: &mut Parser<'i, 't>,
) -> Result<Self, ParseError<'i>> {
SpecifiedUrl::parse(context, input).map(SpecifiedImageUrl)
}
}
impl ToComputedValue for SpecifiedImageUrl {
type ComputedValue = ComputedImageUrl;
@@ -274,9 +241,9 @@ impl ToComputedValue for SpecifiedImageUrl {
}
fn serialize_computed_url<W>(
url_value_data: &URLValueData,
url_value: &URLValue,
dest: &mut CssWriter<W>,
get_url: unsafe extern "C" fn(*const URLValueData, *mut nsCString),
get_url: unsafe extern "C" fn(*const URLValue, *mut nsCString) -> (),
) -> fmt::Result
where
W: Write,
@@ -284,13 +251,13 @@ where
dest.write_str("url(")?;
unsafe {
let mut string = nsCString::new();
get_url(url_value_data, &mut string);
get_url(url_value, &mut string);
string.as_str_unchecked().to_css(dest)?;
}
dest.write_char(')')
}
/// The computed value of a CSS `url()`.
/// The computed value of a CSS non-image `url()`.
///
/// The only difference between specified and computed URLs is the
/// serialization.
@@ -303,7 +270,7 @@ impl ToCss for ComputedUrl {
W: Write,
{
serialize_computed_url(
&self.0.url_value._base,
&self.0.url_value,
dest,
bindings::Gecko_GetComputedURLSpec,
)
@@ -313,12 +280,17 @@ impl ToCss for ComputedUrl {
impl ComputedUrl {
/// Convert from RefPtr<URLValue> to ComputedUrl.
pub unsafe fn from_url_value(url_value: RefPtr<URLValue>) -> Self {
let url = CssUrl::from_url_value_data(&url_value._base);
let url = CssUrl::from_url_value(&*url_value);
ComputedUrl(SpecifiedUrl { url, url_value })
}
/// Get a raw pointer to the URLValue held by this ComputedUrl, for FFI.
pub fn url_value_ptr(&self) -> *mut URLValue {
self.0.url_value.get()
}
}
/// The computed value of a CSS `url()` for image.
/// The computed value of a CSS image `url()`.
#[derive(Clone, Debug, Eq, MallocSizeOf, PartialEq)]
pub struct ComputedImageUrl(pub SpecifiedImageUrl);
@@ -328,7 +300,7 @@ impl ToCss for ComputedImageUrl {
W: Write,
{
serialize_computed_url(
&self.0.image_value._base,
&(self.0).0.url_value,
dest,
bindings::Gecko_GetComputedImageURLSpec,
)
@@ -338,8 +310,13 @@ impl ToCss for ComputedImageUrl {
impl ComputedImageUrl {
/// Convert from nsStyleImageReques to ComputedImageUrl.
pub unsafe fn from_image_request(image_request: &nsStyleImageRequest) -> Self {
let image_value = image_request.mImageValue.to_safe();
let url = CssUrl::from_url_value_data(&image_value._base);
ComputedImageUrl(SpecifiedImageUrl { url, image_value })
let url_value = image_request.mImageValue.to_safe();
let url = CssUrl::from_url_value(&*url_value);
ComputedImageUrl(SpecifiedImageUrl(SpecifiedUrl { url, url_value }))
}
/// Get a raw pointer to the URLValue held by this ComputedImageUrl, for FFI.
pub fn url_value_ptr(&self) -> *mut URLValue {
(self.0).0.url_value.get()
}
}

View File

@@ -297,11 +297,6 @@ impl_threadsafe_refcount!(
bindings::Gecko_AddRefGridTemplateAreasValueArbitraryThread,
bindings::Gecko_ReleaseGridTemplateAreasValueArbitraryThread
);
impl_threadsafe_refcount!(
structs::ImageValue,
bindings::Gecko_AddRefImageValueArbitraryThread,
bindings::Gecko_ReleaseImageValueArbitraryThread
);
impl_threadsafe_refcount!(
structs::SharedFontList,
bindings::Gecko_AddRefSharedFontListArbitraryThread,

View File

@@ -689,7 +689,10 @@ def set_gecko_property(ffi_name, expr):
}
SVGPaintKind::PaintServer(url) => {
unsafe {
bindings::Gecko_nsStyleSVGPaint_SetURLValue(paint, url.0.url_value.get());
bindings::Gecko_nsStyleSVGPaint_SetURLValue(
paint,
url.url_value_ptr(),
)
}
}
SVGPaintKind::Color(color) => {
@@ -4153,7 +4156,10 @@ fn static_assert() {
}
UrlOrNone::Url(ref url) => {
unsafe {
Gecko_SetListStyleImageImageValue(&mut self.gecko, url.0.image_value.get());
Gecko_SetListStyleImageImageValue(
&mut self.gecko,
url.url_value_ptr(),
);
}
}
}
@@ -5358,7 +5364,7 @@ clip-path
unsafe {
Gecko_SetCursorImageValue(
&mut self.gecko.mCursorImages[i],
v.images[i].url.0.image_value.get(),
v.images[i].url.url_value_ptr(),
);
}
@@ -5659,7 +5665,7 @@ clip-path
unsafe {
bindings::Gecko_SetContentDataImageValue(
&mut self.gecko.mContents[i],
url.0.image_value.get(),
url.url_value_ptr(),
)
}
}