зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1552708 - Use cbindgen for URIs. r=heycam
This doesn't clean up as much as a whole, but it's a step in the right direction. In particular, it allows us to start using simple bindings for: * Filters * Shapes and images, almost. Need to: * Get rid of the complex -moz- gradient parsing (let layout.css.simple-moz-gradient.enabled get to release). * Counters, almost. Need to: * Share the Attr representation with Gecko, by not using Option<>. * Just another variant should be enough (ContentItem::{Attr,Prefixedattr}, maybe). Which in turn allows us to remove a whole lot of bindings in followups to this. The setup changes a bit. This also removes the double pointer I complained about while reviewing the shared UA sheet patches. The old setup is: ``` SpecifiedUrl * CssUrl * Arc<CssUrlData> * String * UrlExtraData * UrlValueSource * Arc<CssUrlData> * load id * resolved uri * CORS mode. * ... ``` The new one removes the double reference to the url data via URLValue, and looks like: ``` SpecifiedUrl * CssUrl * Arc<CssUrlData> * String * UrlExtraData * CorsMode * LoadData * load id * resolved URI ``` The LoadData is the only mutable bit that C++ can change, and is not used from Rust. Ideally, in the future, we could just use rust-url to resolve the URL after parsing or something, and make it all immutable. Maybe. I've verified that this approach still works with the UA sheet patches (via the LoadDataSource::Lazy). The reordering of mWillChange is to avoid nsStyleDisplay from going over the size limit. We want to split it up anyway in bug 1552587, but mBinding gains a tag member, which means that we were having a bit of extra padding. One thing I want to explore is to see if we can abuse rustc's non-zero optimizations to predict the layout from C++, but that's something to explore at some other point in time and with a lot of care and help from Michael (who sits next to me and works on rustc ;)). Differential Revision: https://phabricator.services.mozilla.com/D31742
This commit is contained in:
Родитель
3be073fe95
Коммит
a384dedd93
|
@ -545,19 +545,19 @@ static bool MayNeedToLoadXBLBinding(const Document& aDocument,
|
|||
return aElement.IsAnyOfHTMLElements(nsGkAtoms::object, nsGkAtoms::embed);
|
||||
}
|
||||
|
||||
bool Element::GetBindingURL(Document* aDocument, css::URLValue** aResult) {
|
||||
StyleUrlOrNone Element::GetBindingURL(Document* aDocument) {
|
||||
if (!MayNeedToLoadXBLBinding(*aDocument, *this)) {
|
||||
*aResult = nullptr;
|
||||
return true;
|
||||
return StyleUrlOrNone::None();
|
||||
}
|
||||
|
||||
// Get the computed -moz-binding directly from the ComputedStyle
|
||||
RefPtr<ComputedStyle> sc =
|
||||
RefPtr<ComputedStyle> style =
|
||||
nsComputedDOMStyle::GetComputedStyleNoFlush(this, nullptr);
|
||||
NS_ENSURE_TRUE(sc, false);
|
||||
if (!style) {
|
||||
return StyleUrlOrNone::None();
|
||||
}
|
||||
|
||||
NS_IF_ADDREF(*aResult = sc->StyleDisplay()->mBinding);
|
||||
return true;
|
||||
return style->StyleDisplay()->mBinding;
|
||||
}
|
||||
|
||||
JSObject* Element::WrapObject(JSContext* aCx,
|
||||
|
@ -597,17 +597,11 @@ JSObject* Element::WrapObject(JSContext* aCx,
|
|||
// since that can destroy the relevant presshell.
|
||||
|
||||
{
|
||||
// Make a scope so that ~nsRefPtr can GC before returning obj.
|
||||
RefPtr<css::URLValue> bindingURL;
|
||||
bool ok = GetBindingURL(doc, getter_AddRefs(bindingURL));
|
||||
if (!ok) {
|
||||
dom::Throw(aCx, NS_ERROR_FAILURE);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (bindingURL) {
|
||||
nsCOMPtr<nsIURI> uri = bindingURL->GetURI();
|
||||
nsCOMPtr<nsIPrincipal> principal = bindingURL->ExtraData()->Principal();
|
||||
StyleUrlOrNone result = GetBindingURL(doc);
|
||||
if (result.IsUrl()) {
|
||||
auto& url = result.AsUrl();
|
||||
nsCOMPtr<nsIURI> uri = url.GetURI();
|
||||
nsCOMPtr<nsIPrincipal> principal = url.ExtraData().Principal();
|
||||
|
||||
// We have a binding that must be installed.
|
||||
nsXBLService* xblService = nsXBLService::GetInstance();
|
||||
|
|
|
@ -460,7 +460,7 @@ class Element : public FragmentOrElement {
|
|||
}
|
||||
}
|
||||
|
||||
bool GetBindingURL(Document* aDocument, css::URLValue** aResult);
|
||||
mozilla::StyleUrlOrNone GetBindingURL(Document* aDocument);
|
||||
|
||||
Directionality GetComputedDirectionality() const;
|
||||
|
||||
|
|
|
@ -2246,7 +2246,7 @@ nsIFrame* nsCSSFrameConstructor::ConstructDocElementFrame(
|
|||
// Ensure that our XBL bindings are installed.
|
||||
//
|
||||
// FIXME(emilio): Can we remove support for bindings on the root?
|
||||
if (display->mBinding) {
|
||||
if (display->mBinding.IsUrl()) {
|
||||
// Get the XBL loader.
|
||||
nsresult rv;
|
||||
|
||||
|
@ -2255,9 +2255,11 @@ nsIFrame* nsCSSFrameConstructor::ConstructDocElementFrame(
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
const auto& url = display->mBinding.AsUrl();
|
||||
|
||||
RefPtr<nsXBLBinding> binding;
|
||||
rv = xblService->LoadBindings(aDocElement, display->mBinding->GetURI(),
|
||||
display->mBinding->ExtraData()->Principal(),
|
||||
rv = xblService->LoadBindings(aDocElement, url.GetURI(),
|
||||
url.ExtraData().Principal(),
|
||||
getter_AddRefs(binding));
|
||||
if (NS_FAILED(rv) && rv != NS_ERROR_XBL_BLOCKED) {
|
||||
// Binding will load asynchronously.
|
||||
|
@ -5316,8 +5318,9 @@ nsCSSFrameConstructor::LoadXBLBindingIfNeeded(nsIContent& aContent,
|
|||
if (!(aFlags & ITEM_ALLOW_XBL_BASE)) {
|
||||
return XBLBindingLoadInfo(nullptr);
|
||||
}
|
||||
css::URLValue* binding = aStyle.StyleDisplay()->mBinding;
|
||||
if (!binding) {
|
||||
|
||||
const auto& binding = aStyle.StyleDisplay()->mBinding;
|
||||
if (binding.IsNone()) {
|
||||
return XBLBindingLoadInfo(nullptr);
|
||||
}
|
||||
|
||||
|
@ -5327,11 +5330,10 @@ nsCSSFrameConstructor::LoadXBLBindingIfNeeded(nsIContent& aContent,
|
|||
}
|
||||
|
||||
auto newPendingBinding = MakeUnique<PendingBinding>();
|
||||
|
||||
nsresult rv =
|
||||
xblService->LoadBindings(aContent.AsElement(), binding->GetURI(),
|
||||
binding->ExtraData()->Principal(),
|
||||
getter_AddRefs(newPendingBinding->mBinding));
|
||||
const auto& url = binding.AsUrl();
|
||||
nsresult rv = xblService->LoadBindings(
|
||||
aContent.AsElement(), url.GetURI(), url.ExtraData().Principal(),
|
||||
getter_AddRefs(newPendingBinding->mBinding));
|
||||
if (NS_FAILED(rv)) {
|
||||
if (rv == NS_ERROR_XBL_BLOCKED) {
|
||||
return XBLBindingLoadInfo(nullptr);
|
||||
|
|
|
@ -1081,14 +1081,14 @@ FontFaceSet::FindOrCreateUserFontEntryFromFontFace(
|
|||
}
|
||||
case StyleFontFaceSourceListComponent::Tag::Url: {
|
||||
face->mSourceType = gfxFontFaceSrc::eSourceType_URL;
|
||||
const URLValue* url = component.AsUrl();
|
||||
const StyleCssUrl* url = component.AsUrl();
|
||||
nsIURI* uri = url->GetURI();
|
||||
face->mURI = uri ? new gfxFontSrcURI(uri) : nullptr;
|
||||
URLExtraData* extraData = url->ExtraData();
|
||||
face->mReferrer = extraData->GetReferrer();
|
||||
face->mReferrerPolicy = extraData->GetReferrerPolicy();
|
||||
const URLExtraData& extraData = url->ExtraData();
|
||||
face->mReferrer = extraData.GetReferrer();
|
||||
face->mReferrerPolicy = extraData.GetReferrerPolicy();
|
||||
face->mOriginPrincipal =
|
||||
new gfxFontSrcPrincipal(extraData->Principal());
|
||||
new gfxFontSrcPrincipal(extraData.Principal());
|
||||
|
||||
// agent and user stylesheets are treated slightly differently,
|
||||
// the same-site origin check and access control headers are
|
||||
|
|
|
@ -45,7 +45,7 @@
|
|||
#include "nsTransitionManager.h"
|
||||
#include "nsWindowSizes.h"
|
||||
|
||||
#include "mozilla/CORSMode.h"
|
||||
#include "mozilla/css/ImageLoader.h"
|
||||
#include "mozilla/DeclarationBlock.h"
|
||||
#include "mozilla/EffectCompositor.h"
|
||||
#include "mozilla/EffectSet.h"
|
||||
|
@ -1141,18 +1141,17 @@ void Gecko_SetGradientImageValue(nsStyleImage* aImage,
|
|||
}
|
||||
|
||||
static already_AddRefed<nsStyleImageRequest> CreateStyleImageRequest(
|
||||
nsStyleImageRequest::Mode aModeFlags, URLValue* aImageValue) {
|
||||
RefPtr<nsStyleImageRequest> req =
|
||||
new nsStyleImageRequest(aModeFlags, aImageValue);
|
||||
nsStyleImageRequest::Mode aModeFlags, const StyleComputedImageUrl* aUrl) {
|
||||
RefPtr<nsStyleImageRequest> req = new nsStyleImageRequest(aModeFlags, *aUrl);
|
||||
return req.forget();
|
||||
}
|
||||
|
||||
void Gecko_SetLayerImageImageValue(nsStyleImage* aImage,
|
||||
URLValue* aImageValue) {
|
||||
MOZ_ASSERT(aImage && aImageValue);
|
||||
const StyleComputedImageUrl* aUrl) {
|
||||
MOZ_ASSERT(aImage && aUrl);
|
||||
|
||||
RefPtr<nsStyleImageRequest> req =
|
||||
CreateStyleImageRequest(nsStyleImageRequest::Mode::Track, aImageValue);
|
||||
CreateStyleImageRequest(nsStyleImageRequest::Mode::Track, aUrl);
|
||||
aImage->SetImageRequest(req.forget());
|
||||
}
|
||||
|
||||
|
@ -1179,11 +1178,12 @@ void Gecko_SetCursorArrayLength(nsStyleUI* aStyleUI, size_t aLen) {
|
|||
aStyleUI->mCursorImages.SetLength(aLen);
|
||||
}
|
||||
|
||||
void Gecko_SetCursorImageValue(nsCursorImage* aCursor, URLValue* aImageValue) {
|
||||
MOZ_ASSERT(aCursor && aImageValue);
|
||||
void Gecko_SetCursorImageValue(nsCursorImage* aCursor,
|
||||
const StyleComputedImageUrl* aUrl) {
|
||||
MOZ_ASSERT(aCursor && aUrl);
|
||||
|
||||
aCursor->mImage =
|
||||
CreateStyleImageRequest(nsStyleImageRequest::Mode::Discard, aImageValue);
|
||||
CreateStyleImageRequest(nsStyleImageRequest::Mode::Discard, aUrl);
|
||||
}
|
||||
|
||||
void Gecko_CopyCursorArrayFrom(nsStyleUI* aDest, const nsStyleUI* aSrc) {
|
||||
|
@ -1191,11 +1191,11 @@ void Gecko_CopyCursorArrayFrom(nsStyleUI* aDest, const nsStyleUI* aSrc) {
|
|||
}
|
||||
|
||||
void Gecko_SetContentDataImageValue(nsStyleContentData* aContent,
|
||||
URLValue* aImageValue) {
|
||||
MOZ_ASSERT(aContent && aImageValue);
|
||||
const StyleComputedImageUrl* aUrl) {
|
||||
MOZ_ASSERT(aContent && aUrl);
|
||||
|
||||
RefPtr<nsStyleImageRequest> req =
|
||||
CreateStyleImageRequest(nsStyleImageRequest::Mode::Track, aImageValue);
|
||||
CreateStyleImageRequest(nsStyleImageRequest::Mode::Track, aUrl);
|
||||
aContent->SetImageRequest(req.forget());
|
||||
}
|
||||
|
||||
|
@ -1255,11 +1255,11 @@ void Gecko_SetListStyleImageNone(nsStyleList* aList) {
|
|||
}
|
||||
|
||||
void Gecko_SetListStyleImageImageValue(nsStyleList* aList,
|
||||
URLValue* aImageValue) {
|
||||
MOZ_ASSERT(aList && aImageValue);
|
||||
const StyleComputedImageUrl* aUrl) {
|
||||
MOZ_ASSERT(aList && aUrl);
|
||||
|
||||
aList->mListStyleImage =
|
||||
CreateStyleImageRequest(nsStyleImageRequest::Mode(0), aImageValue);
|
||||
CreateStyleImageRequest(nsStyleImageRequest::Mode(0), aUrl);
|
||||
}
|
||||
|
||||
void Gecko_CopyListStyleImageFrom(nsStyleList* aList,
|
||||
|
@ -1560,8 +1560,9 @@ void Gecko_CopyFiltersFrom(nsStyleEffects* aSrc, nsStyleEffects* aDest) {
|
|||
aDest->mFilters = aSrc->mFilters;
|
||||
}
|
||||
|
||||
void Gecko_nsStyleFilter_SetURLValue(nsStyleFilter* aEffects, URLValue* aURL) {
|
||||
aEffects->SetURL(aURL);
|
||||
void Gecko_nsStyleFilter_SetURLValue(nsStyleFilter* aEffects,
|
||||
const StyleComputedUrl* aURL) {
|
||||
aEffects->SetURL(*aURL);
|
||||
}
|
||||
|
||||
void Gecko_nsStyleSVGPaint_CopyFrom(nsStyleSVGPaint* aDest,
|
||||
|
@ -1570,8 +1571,8 @@ void Gecko_nsStyleSVGPaint_CopyFrom(nsStyleSVGPaint* aDest,
|
|||
}
|
||||
|
||||
void Gecko_nsStyleSVGPaint_SetURLValue(nsStyleSVGPaint* aPaint,
|
||||
URLValue* aURL) {
|
||||
aPaint->SetPaintServer(aURL);
|
||||
const StyleComputedUrl* aURL) {
|
||||
aPaint->SetPaintServer(*aURL);
|
||||
}
|
||||
|
||||
void Gecko_nsStyleSVGPaint_Reset(nsStyleSVGPaint* aPaint) { aPaint->SetNone(); }
|
||||
|
@ -1585,30 +1586,18 @@ void Gecko_nsStyleSVG_CopyDashArray(nsStyleSVG* aDst, const nsStyleSVG* aSrc) {
|
|||
aDst->mStrokeDasharray = aSrc->mStrokeDasharray;
|
||||
}
|
||||
|
||||
URLValue* Gecko_URLValue_Create(StyleStrong<RawServoCssUrlData> aCssUrl,
|
||||
CORSMode aCORSMode) {
|
||||
RefPtr<URLValue> url = new URLValue(aCssUrl.Consume(), aCORSMode);
|
||||
return url.forget().take();
|
||||
}
|
||||
|
||||
MOZ_DEFINE_MALLOC_SIZE_OF(GeckoURLValueMallocSizeOf)
|
||||
|
||||
size_t Gecko_URLValue_SizeOfIncludingThis(URLValue* aURL) {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
return aURL->SizeOfIncludingThis(GeckoURLValueMallocSizeOf);
|
||||
}
|
||||
|
||||
void Gecko_GetComputedURLSpec(const URLValue* aURL, nsCString* aOut) {
|
||||
void Gecko_GetComputedURLSpec(const StyleComputedUrl* aURL, nsCString* aOut) {
|
||||
MOZ_ASSERT(aURL);
|
||||
MOZ_ASSERT(aOut);
|
||||
if (aURL->IsLocalRef()) {
|
||||
aOut->Assign(aURL->GetString());
|
||||
aOut->Assign(aURL->SpecifiedSerialization());
|
||||
return;
|
||||
}
|
||||
Gecko_GetComputedImageURLSpec(aURL, aOut);
|
||||
}
|
||||
|
||||
void Gecko_GetComputedImageURLSpec(const URLValue* aURL, nsCString* aOut) {
|
||||
void Gecko_GetComputedImageURLSpec(const StyleComputedUrl* aURL,
|
||||
nsCString* aOut) {
|
||||
// Image URIs don't serialize local refs as local.
|
||||
if (nsIURI* uri = aURL->GetURI()) {
|
||||
nsresult rv = uri->GetSpec(*aOut);
|
||||
|
@ -1627,6 +1616,11 @@ void Gecko_nsIURI_Debug(nsIURI* aURI, nsCString* aOut) {
|
|||
}
|
||||
}
|
||||
|
||||
// XXX Implemented by hand because even though it's thread-safe, only the
|
||||
// subclasses have the HasThreadSafeRefCnt bits.
|
||||
void Gecko_AddRefnsIURIArbitraryThread(nsIURI* aPtr) { NS_ADDREF(aPtr); }
|
||||
void Gecko_ReleasensIURIArbitraryThread(nsIURI* aPtr) { NS_RELEASE(aPtr); }
|
||||
|
||||
template <typename ElementLike>
|
||||
void DebugListAttributes(const ElementLike& aElement, nsCString& aOut) {
|
||||
const uint32_t kMaxAttributeLength = 40;
|
||||
|
@ -1665,8 +1659,6 @@ void Gecko_Snapshot_DebugListAttributes(const ServoElementSnapshot* aSnapshot,
|
|||
DebugListAttributes(*aSnapshot, *aOut);
|
||||
}
|
||||
|
||||
NS_IMPL_THREADSAFE_FFI_REFCOUNTING(URLValue, CSSURLValue);
|
||||
|
||||
NS_IMPL_THREADSAFE_FFI_REFCOUNTING(URLExtraData, URLExtraData);
|
||||
|
||||
NS_IMPL_THREADSAFE_FFI_REFCOUNTING(nsStyleCoord::Calc, Calc);
|
||||
|
@ -1841,15 +1833,14 @@ void Gecko_StyleSheet_FinishAsyncParse(
|
|||
|
||||
static already_AddRefed<StyleSheet> LoadImportSheet(
|
||||
Loader* aLoader, StyleSheet* aParent, SheetLoadData* aParentLoadData,
|
||||
LoaderReusableStyleSheets* aReusableSheets, URLValue* aURL,
|
||||
LoaderReusableStyleSheets* aReusableSheets, const StyleCssUrl& aURL,
|
||||
already_AddRefed<RawServoMediaList> aMediaList) {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(aLoader, "Should've catched this before");
|
||||
MOZ_ASSERT(aParent, "Only used for @import, so parent should exist!");
|
||||
MOZ_ASSERT(aURL, "Invalid URLs shouldn't be loaded!");
|
||||
|
||||
RefPtr<MediaList> media = new MediaList(std::move(aMediaList));
|
||||
nsCOMPtr<nsIURI> uri = aURL->GetURI();
|
||||
nsCOMPtr<nsIURI> uri = aURL.GetURI();
|
||||
nsresult rv = uri ? NS_OK : NS_ERROR_FAILURE;
|
||||
|
||||
StyleSheet* previousFirstChild = aParent->GetFirstChild();
|
||||
|
@ -1874,7 +1865,7 @@ static already_AddRefed<StyleSheet> LoadImportSheet(
|
|||
NS_NewURI(getter_AddRefs(uri), NS_LITERAL_CSTRING("about:invalid"));
|
||||
}
|
||||
emptySheet->SetURIs(uri, uri, uri);
|
||||
emptySheet->SetPrincipal(aURL->ExtraData()->Principal());
|
||||
emptySheet->SetPrincipal(aURL.ExtraData().Principal());
|
||||
emptySheet->SetComplete();
|
||||
aParent->PrependStyleSheet(emptySheet);
|
||||
return emptySheet.forget();
|
||||
|
@ -1887,31 +1878,27 @@ static already_AddRefed<StyleSheet> LoadImportSheet(
|
|||
StyleSheet* Gecko_LoadStyleSheet(Loader* aLoader, StyleSheet* aParent,
|
||||
SheetLoadData* aParentLoadData,
|
||||
LoaderReusableStyleSheets* aReusableSheets,
|
||||
StyleStrong<RawServoCssUrlData> aCssUrl,
|
||||
const StyleCssUrl* aUrl,
|
||||
StyleStrong<RawServoMediaList> aMediaList) {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(aUrl);
|
||||
|
||||
// The CORS mode in the URLValue is irrelevant here.
|
||||
// (CORS_NONE is used for all imported sheets in Load::LoadChildSheet.)
|
||||
RefPtr<URLValue> url = new URLValue(aCssUrl.Consume(), CORS_NONE);
|
||||
return LoadImportSheet(aLoader, aParent, aParentLoadData, aReusableSheets,
|
||||
url, aMediaList.Consume())
|
||||
*aUrl, aMediaList.Consume())
|
||||
.take();
|
||||
}
|
||||
|
||||
void Gecko_LoadStyleSheetAsync(SheetLoadDataHolder* aParentData,
|
||||
StyleStrong<RawServoCssUrlData> aCssUrl,
|
||||
const StyleCssUrl* aUrl,
|
||||
StyleStrong<RawServoMediaList> aMediaList,
|
||||
StyleStrong<RawServoImportRule> aImportRule) {
|
||||
MOZ_ASSERT(aUrl);
|
||||
RefPtr<SheetLoadDataHolder> loadData = aParentData;
|
||||
// The CORS mode in the URLValue is irrelevant here.
|
||||
// (CORS_NONE is used for all imported sheets in Load::LoadChildSheet.)
|
||||
RefPtr<URLValue> urlVal = new URLValue(aCssUrl.Consume(), CORS_NONE);
|
||||
RefPtr<RawServoMediaList> mediaList = aMediaList.Consume();
|
||||
RefPtr<RawServoImportRule> importRule = aImportRule.Consume();
|
||||
NS_DispatchToMainThread(NS_NewRunnableFunction(
|
||||
__func__,
|
||||
[data = std::move(loadData), url = std::move(urlVal),
|
||||
[data = std::move(loadData), url = StyleCssUrl(*aUrl),
|
||||
media = std::move(mediaList), import = std::move(importRule)]() mutable {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
SheetLoadData* d = data->get();
|
||||
|
@ -2100,3 +2087,8 @@ bool Gecko_AssertClassAttrValueIsSane(const nsAttrValue* aValue) {
|
|||
.IsEmpty());
|
||||
return true;
|
||||
}
|
||||
|
||||
void Gecko_LoadData_DeregisterLoad(const StyleLoadData* aData) {
|
||||
MOZ_ASSERT(aData->load_id != 0);
|
||||
ImageLoader::DeregisterCSSImageFromAllLoaders(*aData);
|
||||
}
|
||||
|
|
|
@ -61,6 +61,8 @@ const bool GECKO_IS_NIGHTLY = false;
|
|||
|
||||
extern "C" {
|
||||
|
||||
NS_DECL_THREADSAFE_FFI_REFCOUNTING(nsIURI, nsIURI);
|
||||
|
||||
// Debugging stuff.
|
||||
void Gecko_Element_DebugListAttributes(const mozilla::dom::Element*,
|
||||
nsCString*);
|
||||
|
@ -115,11 +117,11 @@ mozilla::StyleSheet* Gecko_LoadStyleSheet(
|
|||
mozilla::css::Loader* loader, mozilla::StyleSheet* parent,
|
||||
mozilla::css::SheetLoadData* parent_load_data,
|
||||
mozilla::css::LoaderReusableStyleSheets* reusable_sheets,
|
||||
mozilla::StyleStrong<RawServoCssUrlData> url,
|
||||
const mozilla::StyleCssUrl* url,
|
||||
mozilla::StyleStrong<RawServoMediaList> media_list);
|
||||
|
||||
void Gecko_LoadStyleSheetAsync(mozilla::css::SheetLoadDataHolder* parent_data,
|
||||
mozilla::StyleStrong<RawServoCssUrlData>,
|
||||
const mozilla::StyleCssUrl* url,
|
||||
mozilla::StyleStrong<RawServoMediaList>,
|
||||
mozilla::StyleStrong<RawServoImportRule>);
|
||||
|
||||
|
@ -340,7 +342,7 @@ void Gecko_SetGradientImageValue(nsStyleImage* image,
|
|||
nsStyleGradient* gradient);
|
||||
|
||||
void Gecko_SetLayerImageImageValue(nsStyleImage* image,
|
||||
mozilla::css::URLValue* image_value);
|
||||
const mozilla::StyleComputedImageUrl* url);
|
||||
|
||||
void Gecko_SetImageElement(nsStyleImage* image, nsAtom* atom);
|
||||
void Gecko_CopyImageValueFrom(nsStyleImage* image, const nsStyleImage* other);
|
||||
|
@ -357,8 +359,8 @@ 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::URLValue* aImageValue);
|
||||
void Gecko_SetListStyleImageImageValue(
|
||||
nsStyleList* style_struct, const mozilla::StyleComputedImageUrl* url);
|
||||
|
||||
void Gecko_CopyListStyleImageFrom(nsStyleList* dest, const nsStyleList* src);
|
||||
|
||||
|
@ -366,12 +368,12 @@ void Gecko_CopyListStyleImageFrom(nsStyleList* dest, const nsStyleList* src);
|
|||
void Gecko_SetCursorArrayLength(nsStyleUI* ui, size_t len);
|
||||
|
||||
void Gecko_SetCursorImageValue(nsCursorImage* aCursor,
|
||||
mozilla::css::URLValue* aImageValue);
|
||||
const mozilla::StyleComputedImageUrl* url);
|
||||
|
||||
void Gecko_CopyCursorArrayFrom(nsStyleUI* dest, const nsStyleUI* src);
|
||||
|
||||
void Gecko_SetContentDataImageValue(nsStyleContentData* aList,
|
||||
mozilla::css::URLValue* aImageValue);
|
||||
const mozilla::StyleComputedImageUrl* url);
|
||||
|
||||
nsStyleContentData::CounterFunction* Gecko_SetCounterFunction(
|
||||
nsStyleContentData* content_data, mozilla::StyleContentType);
|
||||
|
@ -535,13 +537,13 @@ void Gecko_ResetFilters(nsStyleEffects* effects, size_t new_len);
|
|||
void Gecko_CopyFiltersFrom(nsStyleEffects* aSrc, nsStyleEffects* aDest);
|
||||
|
||||
void Gecko_nsStyleFilter_SetURLValue(nsStyleFilter* effects,
|
||||
mozilla::css::URLValue* uri);
|
||||
const mozilla::StyleComputedUrl* url);
|
||||
|
||||
void Gecko_nsStyleSVGPaint_CopyFrom(nsStyleSVGPaint* dest,
|
||||
const nsStyleSVGPaint* src);
|
||||
|
||||
void Gecko_nsStyleSVGPaint_SetURLValue(nsStyleSVGPaint* paint,
|
||||
mozilla::css::URLValue* uri);
|
||||
const mozilla::StyleComputedUrl* url);
|
||||
|
||||
void Gecko_nsStyleSVGPaint_Reset(nsStyleSVGPaint* paint);
|
||||
|
||||
|
@ -554,20 +556,14 @@ void Gecko_nsStyleSVG_SetContextPropertiesLength(nsStyleSVG* svg, uint32_t len);
|
|||
void Gecko_nsStyleSVG_CopyContextProperties(nsStyleSVG* dst,
|
||||
const nsStyleSVG* src);
|
||||
|
||||
mozilla::css::URLValue* Gecko_URLValue_Create(
|
||||
mozilla::StyleStrong<RawServoCssUrlData> url, mozilla::CORSMode aCORSMode);
|
||||
|
||||
size_t Gecko_URLValue_SizeOfIncludingThis(mozilla::css::URLValue* url);
|
||||
|
||||
void Gecko_GetComputedURLSpec(const mozilla::css::URLValue* url,
|
||||
void Gecko_GetComputedURLSpec(const mozilla::StyleComputedUrl* url,
|
||||
nsCString* spec);
|
||||
|
||||
void Gecko_GetComputedImageURLSpec(const mozilla::css::URLValue* url,
|
||||
void Gecko_GetComputedImageURLSpec(const mozilla::StyleComputedUrl* url,
|
||||
nsCString* spec);
|
||||
|
||||
void Gecko_nsIURI_Debug(nsIURI*, nsCString* spec);
|
||||
|
||||
NS_DECL_THREADSAFE_FFI_REFCOUNTING(mozilla::css::URLValue, CSSURLValue);
|
||||
NS_DECL_THREADSAFE_FFI_REFCOUNTING(mozilla::URLExtraData, URLExtraData);
|
||||
|
||||
void Gecko_FillAllImageLayers(nsStyleImageLayers* layers, uint32_t max_len);
|
||||
|
@ -579,6 +575,8 @@ float Gecko_FontStretch_ToFloat(mozilla::FontStretch aStretch);
|
|||
void Gecko_FontStretch_SetFloat(mozilla::FontStretch* aStretch,
|
||||
float aFloatValue);
|
||||
|
||||
void Gecko_LoadData_DeregisterLoad(const mozilla::StyleLoadData*);
|
||||
|
||||
float Gecko_FontSlantStyle_ToFloat(mozilla::FontSlantStyle aStyle);
|
||||
void Gecko_FontSlantStyle_SetNormal(mozilla::FontSlantStyle*);
|
||||
void Gecko_FontSlantStyle_SetItalic(mozilla::FontSlantStyle*);
|
||||
|
|
|
@ -205,23 +205,23 @@ void ImageLoader::AssociateRequestToFrame(imgIRequest* aRequest,
|
|||
"We should only add to one map iff we also add to the other map.");
|
||||
}
|
||||
|
||||
imgRequestProxy* ImageLoader::RegisterCSSImage(URLValue* aImage) {
|
||||
imgRequestProxy* ImageLoader::RegisterCSSImage(const StyleLoadData& aData) {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(aImage);
|
||||
uint64_t loadId = aData.load_id;
|
||||
|
||||
if (aImage->LoadID() == 0) {
|
||||
if (loadId == 0) {
|
||||
MOZ_ASSERT_UNREACHABLE("Image should have a valid LoadID");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (imgRequestProxy* request = mRegisteredImages.GetWeak(aImage->LoadID())) {
|
||||
if (imgRequestProxy* request = mRegisteredImages.GetWeak(loadId)) {
|
||||
// This document already has a request.
|
||||
return request;
|
||||
}
|
||||
|
||||
imgRequestProxy* canonicalRequest = nullptr;
|
||||
{
|
||||
auto entry = sImages->Lookup(aImage->LoadID());
|
||||
auto entry = sImages->Lookup(loadId);
|
||||
if (entry) {
|
||||
canonicalRequest = entry.Data()->mCanonicalRequest;
|
||||
}
|
||||
|
@ -242,19 +242,16 @@ imgRequestProxy* ImageLoader::RegisterCSSImage(URLValue* aImage) {
|
|||
canonicalRequest->SyncClone(this, mDocument, getter_AddRefs(request));
|
||||
mInClone = false;
|
||||
|
||||
MOZ_ASSERT(!mRegisteredImages.Contains(aImage->LoadID()));
|
||||
MOZ_ASSERT(!mRegisteredImages.Contains(loadId));
|
||||
|
||||
imgRequestProxy* requestWeak = request;
|
||||
mRegisteredImages.Put(aImage->LoadID(), request.forget());
|
||||
mRegisteredImages.Put(loadId, request.forget());
|
||||
return requestWeak;
|
||||
}
|
||||
|
||||
/* static */
|
||||
void ImageLoader::DeregisterCSSImageFromAllLoaders(URLValue* aImage) {
|
||||
MOZ_ASSERT(aImage);
|
||||
|
||||
uint64_t loadID = aImage->LoadID();
|
||||
|
||||
void ImageLoader::DeregisterCSSImageFromAllLoaders(const StyleLoadData& aData) {
|
||||
uint64_t loadID = aData.load_id;
|
||||
if (loadID == 0) {
|
||||
MOZ_ASSERT_UNREACHABLE("Image should have a valid LoadID");
|
||||
return;
|
||||
|
@ -426,13 +423,11 @@ void ImageLoader::ClearFrames(nsPresContext* aPresContext) {
|
|||
}
|
||||
|
||||
/* static */
|
||||
void ImageLoader::LoadImage(URLValue* aImage, Document* aLoadingDoc) {
|
||||
void ImageLoader::LoadImage(const StyleComputedImageUrl& aImage,
|
||||
Document& aLoadingDoc) {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(aLoadingDoc);
|
||||
MOZ_ASSERT(aImage);
|
||||
MOZ_ASSERT(aImage->LoadID() != 0);
|
||||
|
||||
if (aImage->LoadID() == 0) {
|
||||
uint64_t loadId = aImage.LoadData().load_id;
|
||||
if (loadId == 0) {
|
||||
MOZ_ASSERT_UNREACHABLE("Image should have a valid LoadID");
|
||||
return;
|
||||
}
|
||||
|
@ -440,29 +435,29 @@ void ImageLoader::LoadImage(URLValue* aImage, Document* aLoadingDoc) {
|
|||
ImageTableEntry* entry;
|
||||
|
||||
{
|
||||
auto lookup = sImages->LookupForAdd(aImage->LoadID());
|
||||
auto lookup = sImages->LookupForAdd(loadId);
|
||||
if (lookup) {
|
||||
// This css::URLValue has already been loaded.
|
||||
// This url has already been loaded.
|
||||
return;
|
||||
}
|
||||
entry = lookup.OrInsert([]() { return new ImageTableEntry(); });
|
||||
}
|
||||
|
||||
nsIURI* uri = aImage->GetURI();
|
||||
nsIURI* uri = aImage.GetURI();
|
||||
if (!uri) {
|
||||
return;
|
||||
}
|
||||
|
||||
int32_t loadFlags =
|
||||
nsIRequest::LOAD_NORMAL |
|
||||
nsContentUtils::CORSModeToLoadImageFlags(aImage->CorsMode());
|
||||
nsContentUtils::CORSModeToLoadImageFlags(aImage.CorsMode());
|
||||
|
||||
URLExtraData* data = aImage->ExtraData();
|
||||
const URLExtraData& data = aImage.ExtraData();
|
||||
|
||||
RefPtr<imgRequestProxy> request;
|
||||
nsresult rv = nsContentUtils::LoadImage(
|
||||
uri, aLoadingDoc, aLoadingDoc, data->Principal(), 0, data->GetReferrer(),
|
||||
data->GetReferrerPolicy(), nullptr, loadFlags, NS_LITERAL_STRING("css"),
|
||||
uri, &aLoadingDoc, &aLoadingDoc, data.Principal(), 0, data.GetReferrer(),
|
||||
data.GetReferrerPolicy(), nullptr, loadFlags, NS_LITERAL_STRING("css"),
|
||||
getter_AddRefs(request));
|
||||
|
||||
if (NS_FAILED(rv) || !request) {
|
||||
|
|
|
@ -34,8 +34,6 @@ class Document;
|
|||
|
||||
namespace css {
|
||||
|
||||
struct URLValue;
|
||||
|
||||
/**
|
||||
* NOTE: All methods must be called from the main thread unless otherwise
|
||||
* specified.
|
||||
|
@ -63,7 +61,7 @@ class ImageLoader final : public imgINotificationObserver {
|
|||
|
||||
void DropDocumentReference();
|
||||
|
||||
imgRequestProxy* RegisterCSSImage(URLValue* aImage);
|
||||
imgRequestProxy* RegisterCSSImage(const StyleLoadData& aImage);
|
||||
|
||||
void AssociateRequestToFrame(imgIRequest* aRequest, nsIFrame* aFrame,
|
||||
FrameFlags aFlags);
|
||||
|
@ -79,13 +77,13 @@ class ImageLoader final : public imgINotificationObserver {
|
|||
// presshell pointer on the document has been cleared.
|
||||
void ClearFrames(nsPresContext* aPresContext);
|
||||
|
||||
static void LoadImage(URLValue* aImage, dom::Document* aLoadingDoc);
|
||||
static void LoadImage(const StyleComputedImageUrl& aImage, dom::Document&);
|
||||
|
||||
// Cancels the image load for the given css::URLValue and deregisters
|
||||
// it from any ImageLoaders it was registered with.
|
||||
// Cancels the image load for the given LoadData and deregisters it from any
|
||||
// ImageLoaders it was registered with.
|
||||
//
|
||||
// May be called from any thread.
|
||||
static void DeregisterCSSImageFromAllLoaders(URLValue* aImage);
|
||||
static void DeregisterCSSImageFromAllLoaders(const StyleLoadData&);
|
||||
|
||||
void FlushUseCounters();
|
||||
|
||||
|
@ -171,38 +169,37 @@ class ImageLoader final : public imgINotificationObserver {
|
|||
// A weak pointer to our document. Nulled out by DropDocumentReference.
|
||||
dom::Document* mDocument;
|
||||
|
||||
// A map of css::URLValues, keyed by their LoadID(), to the imgRequestProxy
|
||||
// A map of css ComputedUrls, 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::URLValues might be destroyed from other
|
||||
// threads, and we don't want to leave dangling pointers around.
|
||||
// on the main thread, but Urls 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::URLValue object that has had a load
|
||||
// started.
|
||||
// Data associated with every started load.
|
||||
struct ImageTableEntry {
|
||||
// Set of all ImageLoaders that have registered this css::URLValue.
|
||||
// Set of all ImageLoaders that have registered this URL.
|
||||
nsTHashtable<nsPtrHashKey<ImageLoader>> mImageLoaders;
|
||||
|
||||
// The "canonical" image request for this css::URLValue.
|
||||
// The "canonical" image request for this URL.
|
||||
//
|
||||
// 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.
|
||||
// This request is held on to as long as the specified URL 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::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.
|
||||
// A table of all loads, keyed by their id 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::URLValues might be destroyed from other threads,
|
||||
// We use the load id as the key since we can only access sImages on the
|
||||
// main thread, but LoadData objects might be destroyed from other threads,
|
||||
// and we don't want to leave dangling pointers around.
|
||||
static nsClassHashtable<nsUint64HashKey, ImageTableEntry>* sImages;
|
||||
};
|
||||
|
|
|
@ -500,6 +500,13 @@ cbindgen-types = [
|
|||
{ gecko = "StyleGenericTranslate", servo = "values::generics::transform::Translate" },
|
||||
{ gecko = "StyleAngle", servo = "values::computed::Angle" },
|
||||
{ gecko = "StyleGenericBorderImageSideWidth", servo = "values::generics::border::BorderImageSideWidth" },
|
||||
{ gecko = "StyleGenericUrlOrNone", servo = "values::generics::url::UrlOrNone" },
|
||||
{ gecko = "StyleCssUrl", servo = "gecko::url::CssUrl" },
|
||||
{ gecko = "StyleSpecifiedUrl", servo = "gecko::url::SpecifiedUrl" },
|
||||
{ gecko = "StyleSpecifiedImageUrl", servo = "gecko::url::SpecifiedImageUrl" },
|
||||
{ gecko = "StyleComputedUrl", servo = "gecko::url::ComputedUrl" },
|
||||
{ gecko = "StyleComputedImageUrl", servo = "gecko::url::ComputedImageUrl" },
|
||||
{ gecko = "StyleLoadData", servo = "gecko::url::LoadData" },
|
||||
]
|
||||
|
||||
mapped-generic-types = [
|
||||
|
|
|
@ -22,11 +22,13 @@
|
|||
# include "mozilla/Span.h"
|
||||
# include "Units.h"
|
||||
# include "mozilla/gfx/Types.h"
|
||||
# include "mozilla/CORSMode.h"
|
||||
# include "mozilla/MemoryReporting.h"
|
||||
# include "mozilla/ServoTypes.h"
|
||||
# include "mozilla/ServoBindingTypes.h"
|
||||
# include "nsCSSPropertyID.h"
|
||||
# include "nsCompatibility.h"
|
||||
# include "nsIURI.h"
|
||||
# include <atomic>
|
||||
|
||||
struct RawServoAnimationValueTable;
|
||||
|
@ -35,9 +37,11 @@ struct RawServoAnimationValueMap;
|
|||
class nsAtom;
|
||||
class nsIFrame;
|
||||
class nsINode;
|
||||
class nsIContent;
|
||||
class nsCSSPropertyIDSet;
|
||||
class nsPresContext;
|
||||
class nsSimpleContentList;
|
||||
class imgRequestProxy;
|
||||
struct nsCSSValueSharedList;
|
||||
struct nsTimingFunction;
|
||||
|
||||
|
@ -97,7 +101,6 @@ class Loader;
|
|||
class LoaderReusableStyleSheets;
|
||||
class SheetLoadData;
|
||||
using SheetLoadDataHolder = nsMainThreadPtrHolder<SheetLoadData>;
|
||||
struct URLValue;
|
||||
enum SheetParsingMode : uint8_t;
|
||||
} // namespace css
|
||||
|
||||
|
@ -115,7 +118,6 @@ class Document;
|
|||
using StyleLoader = css::Loader;
|
||||
using StyleLoaderReusableStyleSheets = css::LoaderReusableStyleSheets;
|
||||
using StyleCallerType = dom::CallerType;
|
||||
using StyleURLValue = css::URLValue;
|
||||
using StyleSheetParsingMode = css::SheetParsingMode;
|
||||
using StyleSheetLoadData = css::SheetLoadData;
|
||||
using StyleSheetLoadDataHolder = css::SheetLoadDataHolder;
|
||||
|
|
|
@ -10,7 +10,10 @@
|
|||
#define mozilla_ServoStyleConstsInlines_h
|
||||
|
||||
#include "mozilla/ServoStyleConsts.h"
|
||||
#include "mozilla/URLExtraData.h"
|
||||
#include "nsGkAtoms.h"
|
||||
#include "MainThreadUtils.h"
|
||||
#include "nsNetUtil.h"
|
||||
#include <type_traits>
|
||||
#include <new>
|
||||
|
||||
|
@ -65,6 +68,30 @@ static constexpr const size_t kStaticRefcount =
|
|||
std::numeric_limits<size_t>::max();
|
||||
static constexpr const size_t kMaxRefcount =
|
||||
std::numeric_limits<intptr_t>::max();
|
||||
|
||||
template <typename T>
|
||||
inline void StyleArcInner<T>::IncrementRef() {
|
||||
if (count.load(std::memory_order_relaxed) != kStaticRefcount) {
|
||||
auto old_size = count.fetch_add(1, std::memory_order_relaxed);
|
||||
if (MOZ_UNLIKELY(old_size > kMaxRefcount)) {
|
||||
::abort();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// This is a C++ port-ish of Arc::drop().
|
||||
template <typename T>
|
||||
inline bool StyleArcInner<T>::DecrementRef() {
|
||||
if (count.load(std::memory_order_relaxed) == kStaticRefcount) {
|
||||
return false;
|
||||
}
|
||||
if (count.fetch_sub(1, std::memory_order_release) != 1) {
|
||||
return false;
|
||||
}
|
||||
count.load(std::memory_order_acquire);
|
||||
return true;
|
||||
}
|
||||
|
||||
static constexpr const uint64_t kArcSliceCanary = 0xf3f3f3f3f3f3f3f3;
|
||||
|
||||
#define ASSERT_CANARY \
|
||||
|
@ -73,18 +100,14 @@ static constexpr const uint64_t kArcSliceCanary = 0xf3f3f3f3f3f3f3f3;
|
|||
template <typename T>
|
||||
inline StyleArcSlice<T>::StyleArcSlice() {
|
||||
_0.ptr = reinterpret_cast<decltype(_0.ptr)>(Servo_StyleArcSlice_EmptyPtr());
|
||||
ASSERT_CANARY
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline StyleArcSlice<T>::StyleArcSlice(const StyleArcSlice& aOther) {
|
||||
MOZ_DIAGNOSTIC_ASSERT(aOther._0.ptr);
|
||||
_0.ptr = aOther._0.ptr;
|
||||
if (_0.ptr->count.load(std::memory_order_relaxed) != kStaticRefcount) {
|
||||
auto old_size = _0.ptr->count.fetch_add(1, std::memory_order_relaxed);
|
||||
if (MOZ_UNLIKELY(old_size > kMaxRefcount)) {
|
||||
::abort();
|
||||
}
|
||||
}
|
||||
_0.ptr->IncrementRef();
|
||||
ASSERT_CANARY
|
||||
}
|
||||
|
||||
|
@ -125,17 +148,12 @@ inline bool StyleArcSlice<T>::operator!=(const StyleArcSlice& aOther) const {
|
|||
return !(*this == aOther);
|
||||
}
|
||||
|
||||
// This is a C++ port-ish of Arc::drop().
|
||||
template <typename T>
|
||||
inline StyleArcSlice<T>::~StyleArcSlice() {
|
||||
ASSERT_CANARY
|
||||
if (_0.ptr->count.load(std::memory_order_relaxed) == kStaticRefcount) {
|
||||
if (MOZ_LIKELY(!_0.ptr->DecrementRef())) {
|
||||
return;
|
||||
}
|
||||
if (_0.ptr->count.fetch_sub(1, std::memory_order_release) != 1) {
|
||||
return;
|
||||
}
|
||||
_0.ptr->count.load(std::memory_order_acquire);
|
||||
for (T& elem : MakeSpan(_0.ptr->data.slice, Length())) {
|
||||
elem.~T();
|
||||
}
|
||||
|
@ -144,11 +162,46 @@ inline StyleArcSlice<T>::~StyleArcSlice() {
|
|||
|
||||
#undef ASSERT_CANARY
|
||||
|
||||
template <typename T>
|
||||
inline StyleArc<T>::StyleArc(const StyleArc& aOther) : p(aOther.p) {
|
||||
p->IncrementRef();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline void StyleArc<T>::Release() {
|
||||
if (MOZ_LIKELY(!p->DecrementRef())) {
|
||||
return;
|
||||
}
|
||||
p->data.~T();
|
||||
free(p);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline StyleArc<T>& StyleArc<T>::operator=(const StyleArc& aOther) {
|
||||
if (p != aOther.p) {
|
||||
Release();
|
||||
p = aOther.p;
|
||||
p->IncrementRef();
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline StyleArc<T>& StyleArc<T>::operator=(StyleArc&& aOther) {
|
||||
std::swap(p, aOther.p);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline StyleArc<T>::~StyleArc() {
|
||||
Release();
|
||||
}
|
||||
|
||||
inline bool StyleAtom::IsStatic() const { return !!(_0 & 1); }
|
||||
|
||||
inline nsAtom* StyleAtom::AsAtom() const {
|
||||
if (IsStatic()) {
|
||||
return const_cast<nsStaticAtom*>(&detail::gGkAtoms.mAtoms[(_0 & ~1) >> 1]);
|
||||
return const_cast<nsStaticAtom*>(&detail::gGkAtoms.mAtoms[_0 >> 1]);
|
||||
}
|
||||
return reinterpret_cast<nsAtom*>(_0);
|
||||
}
|
||||
|
@ -191,6 +244,85 @@ inline double StyleAngle::ToRadians() const {
|
|||
return double(ToDegrees()) * M_PI / 180.0;
|
||||
}
|
||||
|
||||
inline bool StyleUrlExtraData::IsShared() const { return !!(_0 & 1); }
|
||||
|
||||
inline StyleUrlExtraData::~StyleUrlExtraData() {
|
||||
if (!IsShared()) {
|
||||
reinterpret_cast<URLExtraData*>(_0)->Release();
|
||||
}
|
||||
}
|
||||
|
||||
inline const URLExtraData& StyleUrlExtraData::get() const {
|
||||
if (IsShared()) {
|
||||
return *URLExtraData::sShared[_0 >> 1].get();
|
||||
}
|
||||
return *reinterpret_cast<const URLExtraData*>(_0);
|
||||
}
|
||||
|
||||
inline nsDependentCSubstring StyleCssUrl::SpecifiedSerialization() const {
|
||||
return _0->serialization.AsString();
|
||||
}
|
||||
|
||||
inline const URLExtraData& StyleCssUrl::ExtraData() const {
|
||||
return _0->extra_data.get();
|
||||
}
|
||||
|
||||
inline StyleLoadData& StyleCssUrl::LoadData() const {
|
||||
MOZ_DIAGNOSTIC_ASSERT(NS_IsMainThread());
|
||||
if (MOZ_LIKELY(_0->load_data.tag == StyleLoadDataSource::Tag::Owned)) {
|
||||
return const_cast<StyleLoadData&>(_0->load_data.owned._0);
|
||||
}
|
||||
return const_cast<StyleLoadData&>(*Servo_LoadData_GetLazy(&_0->load_data));
|
||||
}
|
||||
|
||||
inline nsIURI* StyleCssUrl::GetURI() const {
|
||||
MOZ_DIAGNOSTIC_ASSERT(NS_IsMainThread());
|
||||
auto& loadData = LoadData();
|
||||
if (!loadData.tried_to_resolve) {
|
||||
loadData.tried_to_resolve = true;
|
||||
NS_NewURI(getter_AddRefs(loadData.resolved), SpecifiedSerialization(),
|
||||
nullptr, ExtraData().BaseURI());
|
||||
}
|
||||
return loadData.resolved.get();
|
||||
}
|
||||
|
||||
inline nsDependentCSubstring StyleComputedUrl::SpecifiedSerialization() const {
|
||||
return _0.SpecifiedSerialization();
|
||||
}
|
||||
inline const URLExtraData& StyleComputedUrl::ExtraData() const {
|
||||
return _0.ExtraData();
|
||||
}
|
||||
inline StyleLoadData& StyleComputedUrl::LoadData() const {
|
||||
return _0.LoadData();
|
||||
}
|
||||
inline CORSMode StyleComputedUrl::CorsMode() const {
|
||||
switch (_0._0->cors_mode) {
|
||||
case StyleCorsMode::Anonymous:
|
||||
return CORSMode::CORS_ANONYMOUS;
|
||||
case StyleCorsMode::None:
|
||||
return CORSMode::CORS_NONE;
|
||||
default:
|
||||
MOZ_ASSERT_UNREACHABLE("Unknown cors-mode from style?");
|
||||
return CORSMode::CORS_NONE;
|
||||
}
|
||||
}
|
||||
inline nsIURI* StyleComputedUrl::GetURI() const { return _0.GetURI(); }
|
||||
|
||||
inline bool StyleComputedUrl::IsLocalRef() const {
|
||||
return Servo_CssUrl_IsLocalRef(&_0);
|
||||
}
|
||||
|
||||
inline bool StyleComputedUrl::HasRef() const {
|
||||
if (IsLocalRef()) {
|
||||
return true;
|
||||
}
|
||||
if (nsIURI* uri = GetURI()) {
|
||||
bool hasRef = false;
|
||||
return NS_SUCCEEDED(uri->GetHasRef(&hasRef)) && hasRef;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
||||
|
||||
#endif
|
||||
|
|
|
@ -163,166 +163,6 @@ void nsCSSValue::SetFloatValue(float aValue, nsCSSUnit aUnit) {
|
|||
}
|
||||
}
|
||||
|
||||
css::URLValue::~URLValue() {
|
||||
if (mLoadID != 0) {
|
||||
ImageLoader::DeregisterCSSImageFromAllLoaders(this);
|
||||
}
|
||||
}
|
||||
|
||||
bool css::URLValue::Equals(const URLValue& aOther) const {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
bool eq;
|
||||
const URLExtraData* self = ExtraData();
|
||||
const URLExtraData* other = aOther.ExtraData();
|
||||
return GetString() == aOther.GetString() &&
|
||||
(GetURI() == aOther.GetURI() || // handles null == null
|
||||
(mURI && aOther.mURI &&
|
||||
NS_SUCCEEDED(mURI->Equals(aOther.mURI, &eq)) && eq)) &&
|
||||
(self->BaseURI() == other->BaseURI() ||
|
||||
(NS_SUCCEEDED(self->BaseURI()->Equals(other->BaseURI(), &eq)) &&
|
||||
eq)) &&
|
||||
self->Principal()->Equals(other->Principal()) &&
|
||||
IsLocalRef() == aOther.IsLocalRef();
|
||||
}
|
||||
|
||||
bool css::URLValue::DefinitelyEqualURIs(const URLValue& aOther) const {
|
||||
if (ExtraData()->BaseURI() != aOther.ExtraData()->BaseURI()) {
|
||||
return false;
|
||||
}
|
||||
return GetString() == aOther.GetString();
|
||||
}
|
||||
|
||||
bool css::URLValue::DefinitelyEqualURIsAndPrincipal(
|
||||
const URLValue& aOther) const {
|
||||
return ExtraData()->Principal() == aOther.ExtraData()->Principal() &&
|
||||
DefinitelyEqualURIs(aOther);
|
||||
}
|
||||
|
||||
nsDependentCSubstring css::URLValue::GetString() const {
|
||||
const uint8_t* chars;
|
||||
uint32_t len;
|
||||
Servo_CssUrlData_GetSerialization(mCssUrl, &chars, &len);
|
||||
return nsDependentCSubstring(reinterpret_cast<const char*>(chars), len);
|
||||
}
|
||||
|
||||
nsIURI* css::URLValue::GetURI() const {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
if (!mURIResolved) {
|
||||
MOZ_ASSERT(!mURI);
|
||||
nsCOMPtr<nsIURI> newURI;
|
||||
NS_NewURI(getter_AddRefs(newURI), GetString(), nullptr,
|
||||
ExtraData()->BaseURI());
|
||||
mURI = newURI.forget();
|
||||
mURIResolved = true;
|
||||
}
|
||||
|
||||
return mURI;
|
||||
}
|
||||
|
||||
bool css::URLValue::HasRef() const {
|
||||
if (IsLocalRef()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (nsIURI* uri = GetURI()) {
|
||||
nsAutoCString ref;
|
||||
nsresult rv = uri->GetRef(ref);
|
||||
return NS_SUCCEEDED(rv) && !ref.IsEmpty();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
already_AddRefed<nsIURI> css::URLValue::ResolveLocalRef(nsIURI* aURI) const {
|
||||
nsCOMPtr<nsIURI> result = GetURI();
|
||||
|
||||
if (result && IsLocalRef()) {
|
||||
nsCString ref;
|
||||
mURI->GetRef(ref);
|
||||
|
||||
nsresult rv = NS_MutateURI(aURI).SetRef(ref).Finalize(result);
|
||||
|
||||
if (NS_FAILED(rv)) {
|
||||
// If setting the ref failed, just return the original URI.
|
||||
result = aURI;
|
||||
}
|
||||
}
|
||||
|
||||
return result.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<nsIURI> css::URLValue::ResolveLocalRef(
|
||||
nsIContent* aContent) const {
|
||||
nsCOMPtr<nsIURI> url = aContent->GetBaseURI();
|
||||
return ResolveLocalRef(url);
|
||||
}
|
||||
|
||||
void css::URLValue::GetSourceString(nsString& aRef) const {
|
||||
nsIURI* uri = GetURI();
|
||||
if (!uri) {
|
||||
aRef.Truncate();
|
||||
return;
|
||||
}
|
||||
|
||||
nsCString cref;
|
||||
if (IsLocalRef()) {
|
||||
// XXXheycam It's possible we can just return mString in this case, since
|
||||
// it should be the "#fragment" string the URLValue was created with.
|
||||
uri->GetRef(cref);
|
||||
cref.Insert('#', 0);
|
||||
} else {
|
||||
// It's not entirely clear how to best handle failure here. Ensuring the
|
||||
// string is empty seems safest.
|
||||
nsresult rv = uri->GetSpec(cref);
|
||||
if (NS_FAILED(rv)) {
|
||||
cref.Truncate();
|
||||
}
|
||||
}
|
||||
|
||||
aRef = NS_ConvertUTF8toUTF16(cref);
|
||||
}
|
||||
|
||||
size_t css::URLValue::SizeOfIncludingThis(
|
||||
mozilla::MallocSizeOf aMallocSizeOf) const {
|
||||
// Measurement of the following members may be added later if DMD finds it
|
||||
// is worthwhile:
|
||||
// - mURI
|
||||
// - mString
|
||||
|
||||
// Only measure it if it's unshared, to avoid double-counting.
|
||||
size_t n = 0;
|
||||
if (mRefCnt <= 1) {
|
||||
n += aMallocSizeOf(this);
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
imgRequestProxy* css::URLValue::LoadImage(Document* aDocument) {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
static uint64_t sNextLoadID = 1;
|
||||
|
||||
if (mLoadID == 0) {
|
||||
mLoadID = sNextLoadID++;
|
||||
}
|
||||
|
||||
// NB: If aDocument is not the original document, we may not be able to load
|
||||
// images from aDocument. Instead we do the image load from the original doc
|
||||
// and clone it to aDocument.
|
||||
Document* loadingDoc = aDocument->GetOriginalDocument();
|
||||
if (!loadingDoc) {
|
||||
loadingDoc = aDocument;
|
||||
}
|
||||
|
||||
// Kick off the load in the loading document.
|
||||
ImageLoader::LoadImage(this, loadingDoc);
|
||||
|
||||
// Register the image in the document that's using it.
|
||||
return aDocument->StyleImageLoader()->RegisterCSSImage(this);
|
||||
}
|
||||
|
||||
size_t mozilla::css::GridTemplateAreasValue::SizeOfIncludingThis(
|
||||
mozilla::MallocSizeOf aMallocSizeOf) const {
|
||||
// Only measure it if it's unshared, to avoid double-counting.
|
||||
|
|
|
@ -98,93 +98,6 @@ bool Servo_CssUrlData_IsLocalRef(const RawServoCssUrlData* url);
|
|||
namespace mozilla {
|
||||
namespace css {
|
||||
|
||||
struct URLValue final {
|
||||
public:
|
||||
// aCssUrl must not be null.
|
||||
URLValue(already_AddRefed<RawServoCssUrlData> aCssUrl, CORSMode aCORSMode)
|
||||
: mURIResolved(false), mCssUrl(aCssUrl), mCORSMode(aCORSMode) {
|
||||
MOZ_ASSERT(mCssUrl);
|
||||
}
|
||||
|
||||
// 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 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 IsLocalRef(), that these
|
||||
// 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 URLValue& aOther) const;
|
||||
|
||||
// Smae as DefinitelyEqualURIs but additionally compares the nsIPrincipal
|
||||
// pointers of the two URLValue objects.
|
||||
bool DefinitelyEqualURIsAndPrincipal(const URLValue& aOther) const;
|
||||
|
||||
nsIURI* GetURI() const;
|
||||
|
||||
bool IsLocalRef() const { return Servo_CssUrlData_IsLocalRef(mCssUrl); }
|
||||
|
||||
bool HasRef() const;
|
||||
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(URLValue)
|
||||
|
||||
// When matching a local ref URL, resolve it against aURI;
|
||||
// Otherwise, ignore aURL and return mURI directly.
|
||||
already_AddRefed<nsIURI> ResolveLocalRef(nsIURI* aURI) const;
|
||||
already_AddRefed<nsIURI> ResolveLocalRef(nsIContent* aContent) const;
|
||||
|
||||
// Serializes mURI as a computed URI value, taking into account IsLocalRef()
|
||||
// and serializing just the fragment if true.
|
||||
void GetSourceString(nsString& aRef) const;
|
||||
|
||||
nsDependentCSubstring GetString() const;
|
||||
|
||||
size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
|
||||
|
||||
imgRequestProxy* LoadImage(mozilla::dom::Document* aDocument);
|
||||
|
||||
uint64_t LoadID() const { return mLoadID; }
|
||||
|
||||
CORSMode CorsMode() const { return mCORSMode; }
|
||||
|
||||
URLExtraData* ExtraData() const {
|
||||
return Servo_CssUrlData_GetExtraData(mCssUrl);
|
||||
}
|
||||
|
||||
private:
|
||||
// mURI stores the lazily resolved URI. This may be null if the URI is
|
||||
// invalid, even once resolved.
|
||||
mutable nsCOMPtr<nsIURI> mURI;
|
||||
|
||||
mutable bool mURIResolved;
|
||||
|
||||
RefPtr<RawServoCssUrlData> mCssUrl;
|
||||
|
||||
const CORSMode mCORSMode;
|
||||
|
||||
// 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
|
||||
// using the pointer value of the ImageValue object, since we can sometimes
|
||||
// delete ImageValues OMT but cannot update the ImageLoader tables until
|
||||
// we're back on the main thread. So to avoid dangling pointers that might
|
||||
// get re-used by the time we want to update the ImageLoader tables, we use
|
||||
// these IDs.
|
||||
uint64_t mLoadID = 0;
|
||||
|
||||
~URLValue();
|
||||
|
||||
private:
|
||||
URLValue(const URLValue& aOther) = delete;
|
||||
URLValue& operator=(const URLValue& aOther) = delete;
|
||||
};
|
||||
|
||||
struct GridNamedArea {
|
||||
nsString mName;
|
||||
uint32_t mColumnStart;
|
||||
|
|
|
@ -619,7 +619,8 @@ static void AddImageURL(nsIURI& aURI, nsTArray<nsString>& aURLs) {
|
|||
aURLs.AppendElement(NS_ConvertUTF8toUTF16(spec));
|
||||
}
|
||||
|
||||
static void AddImageURL(const css::URLValue& aURL, nsTArray<nsString>& aURLs) {
|
||||
static void AddImageURL(const StyleComputedUrl& aURL,
|
||||
nsTArray<nsString>& aURLs) {
|
||||
if (aURL.IsLocalRef()) {
|
||||
return;
|
||||
}
|
||||
|
@ -631,9 +632,7 @@ static void AddImageURL(const css::URLValue& aURL, nsTArray<nsString>& aURLs) {
|
|||
|
||||
static void AddImageURL(const nsStyleImageRequest& aRequest,
|
||||
nsTArray<nsString>& aURLs) {
|
||||
if (auto* value = aRequest.GetImageValue()) {
|
||||
AddImageURL(*value, aURLs);
|
||||
}
|
||||
AddImageURL(aRequest.GetImageValue(), aURLs);
|
||||
}
|
||||
|
||||
static void AddImageURL(const nsStyleImage& aImage, nsTArray<nsString>& aURLs) {
|
||||
|
@ -660,9 +659,8 @@ static void AddImageURLs(const nsStyleImageLayers& aLayers,
|
|||
}
|
||||
}
|
||||
|
||||
// FIXME(stylo-everywhere): This should be `const ComputedStyle&`.
|
||||
static void CollectImageURLsForProperty(nsCSSPropertyID aProp,
|
||||
ComputedStyle& aStyle,
|
||||
const ComputedStyle& aStyle,
|
||||
nsTArray<nsString>& aURLs) {
|
||||
if (nsCSSProps::IsShorthand(aProp)) {
|
||||
CSSPROPS_FOR_SHORTHAND_SUBPROPERTIES(p, aProp,
|
||||
|
@ -1221,7 +1219,7 @@ void nsComputedDOMStyle::SetValueToPosition(const Position& aPosition,
|
|||
aValueList->AppendCSSValue(valY.forget());
|
||||
}
|
||||
|
||||
void nsComputedDOMStyle::SetValueToURLValue(const css::URLValue* aURL,
|
||||
void nsComputedDOMStyle::SetValueToURLValue(const StyleComputedUrl* aURL,
|
||||
nsROCSSPrimitiveValue* aValue) {
|
||||
if (!aURL) {
|
||||
aValue->SetIdent(eCSSKeyword_none);
|
||||
|
@ -1238,9 +1236,7 @@ void nsComputedDOMStyle::SetValueToURLValue(const css::URLValue* aURL,
|
|||
}
|
||||
|
||||
// Otherwise, serialize the specified URL value.
|
||||
nsAutoString source;
|
||||
aURL->GetSourceString(source);
|
||||
|
||||
NS_ConvertUTF8toUTF16 source(aURL->SpecifiedSerialization());
|
||||
nsAutoString url;
|
||||
url.AppendLiteral(u"url(");
|
||||
nsStyleUtil::AppendEscapedCSSString(source, url, '"');
|
||||
|
|
|
@ -291,7 +291,7 @@ class nsComputedDOMStyle final : public nsDOMCSSDeclaration,
|
|||
const mozilla::StyleColor& aColor);
|
||||
void SetValueToPosition(const mozilla::Position& aPosition,
|
||||
nsDOMCSSValueList* aValueList);
|
||||
void SetValueToURLValue(const mozilla::css::URLValue* aURL,
|
||||
void SetValueToURLValue(const mozilla::StyleComputedUrl* aURL,
|
||||
nsROCSSPrimitiveValue* aValue);
|
||||
|
||||
void SetValueToSize(nsROCSSPrimitiveValue* aValue, const mozilla::StyleSize&);
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include "nsCSSProps.h"
|
||||
#include "nsDeviceContext.h"
|
||||
#include "nsStyleUtil.h"
|
||||
#include "nsIURIMutator.h"
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
|
||||
|
@ -60,18 +61,6 @@ static constexpr size_t kStyleStructSizeLimit = 504;
|
|||
#include "nsStyleStructList.h"
|
||||
#undef STYLE_STRUCT
|
||||
|
||||
static bool DefinitelyEqualURIs(const css::URLValue* aURI1,
|
||||
const css::URLValue* aURI2) {
|
||||
return aURI1 == aURI2 ||
|
||||
(aURI1 && aURI2 && aURI1->DefinitelyEqualURIs(*aURI2));
|
||||
}
|
||||
|
||||
static bool DefinitelyEqualURIsAndPrincipal(const css::URLValue* aURI1,
|
||||
const css::URLValue* aURI2) {
|
||||
return aURI1 == aURI2 ||
|
||||
(aURI1 && aURI2 && aURI1->DefinitelyEqualURIsAndPrincipal(*aURI2));
|
||||
}
|
||||
|
||||
static bool DefinitelyEqualImages(const nsStyleImageRequest* aRequest1,
|
||||
const nsStyleImageRequest* aRequest2) {
|
||||
if (aRequest1 == aRequest2) {
|
||||
|
@ -85,6 +74,73 @@ static bool DefinitelyEqualImages(const nsStyleImageRequest* aRequest1,
|
|||
return aRequest1->DefinitelyEquals(*aRequest2);
|
||||
}
|
||||
|
||||
bool StyleCssUrlData::operator==(const StyleCssUrlData& aOther) const {
|
||||
// This very intentionally avoids comparing LoadData and such.
|
||||
const auto& extra = extra_data.get();
|
||||
const auto& otherExtra = aOther.extra_data.get();
|
||||
if (extra.BaseURI() != otherExtra.BaseURI() ||
|
||||
extra.Principal() != otherExtra.Principal() ||
|
||||
cors_mode != aOther.cors_mode) {
|
||||
// NOTE(emilio): This does pointer comparison, but it's what URLValue used
|
||||
// to do. That's ok though since this is only used for style struct diffing.
|
||||
return false;
|
||||
}
|
||||
return serialization == aOther.serialization;
|
||||
}
|
||||
|
||||
StyleLoadData::~StyleLoadData() {
|
||||
if (load_id != 0) {
|
||||
css::ImageLoader::DeregisterCSSImageFromAllLoaders(*this);
|
||||
}
|
||||
}
|
||||
|
||||
already_AddRefed<nsIURI> StyleComputedUrl::ResolveLocalRef(nsIURI* aURI) const {
|
||||
nsCOMPtr<nsIURI> result = GetURI();
|
||||
if (result && IsLocalRef()) {
|
||||
nsCString ref;
|
||||
result->GetRef(ref);
|
||||
|
||||
nsresult rv = NS_MutateURI(aURI).SetRef(ref).Finalize(result);
|
||||
|
||||
if (NS_FAILED(rv)) {
|
||||
// If setting the ref failed, just return the original URI.
|
||||
result = aURI;
|
||||
}
|
||||
}
|
||||
return result.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<nsIURI> StyleComputedUrl::ResolveLocalRef(
|
||||
const nsIContent* aContent) const {
|
||||
nsCOMPtr<nsIURI> url = aContent->GetBaseURI();
|
||||
return ResolveLocalRef(url);
|
||||
}
|
||||
|
||||
imgRequestProxy* StyleComputedUrl::LoadImage(Document& aDocument) {
|
||||
MOZ_DIAGNOSTIC_ASSERT(NS_IsMainThread());
|
||||
|
||||
static uint64_t sNextLoadID = 1;
|
||||
|
||||
StyleLoadData& data = LoadData();
|
||||
if (data.load_id == 0) {
|
||||
data.load_id = sNextLoadID++;
|
||||
}
|
||||
|
||||
// NB: If aDocument is not the original document, we may not be able to load
|
||||
// images from aDocument. Instead we do the image load from the original doc
|
||||
// and clone it to aDocument.
|
||||
Document* loadingDoc = aDocument.GetOriginalDocument();
|
||||
if (!loadingDoc) {
|
||||
loadingDoc = &aDocument;
|
||||
}
|
||||
|
||||
// Kick off the load in the loading document.
|
||||
css::ImageLoader::LoadImage(*this, *loadingDoc);
|
||||
|
||||
// Register the image in the document that's using it.
|
||||
return aDocument.StyleImageLoader()->RegisterCSSImage(data);
|
||||
}
|
||||
|
||||
// --------------------
|
||||
// nsStyleFont
|
||||
//
|
||||
|
@ -672,6 +728,9 @@ nsChangeHint nsStyleColumn::CalcDifference(
|
|||
nsStyleSVG::nsStyleSVG(const Document& aDocument)
|
||||
: mFill(eStyleSVGPaintType_Color), // Will be initialized to NS_RGB(0,0,0)
|
||||
mStroke(eStyleSVGPaintType_None),
|
||||
mMarkerEnd(StyleUrlOrNone::None()),
|
||||
mMarkerMid(StyleUrlOrNone::None()),
|
||||
mMarkerStart(StyleUrlOrNone::None()),
|
||||
mMozContextProperties{{}, {0}},
|
||||
mStrokeDashoffset(LengthPercentage::Zero()),
|
||||
mStrokeWidth(LengthPercentage::FromPixels(1.0f)),
|
||||
|
@ -728,16 +787,14 @@ static bool PaintURIChanged(const nsStyleSVGPaint& aPaint1,
|
|||
aPaint2.Type() == eStyleSVGPaintType_Server;
|
||||
}
|
||||
return aPaint1.Type() == eStyleSVGPaintType_Server &&
|
||||
!DefinitelyEqualURIs(aPaint1.GetPaintServer(),
|
||||
aPaint2.GetPaintServer());
|
||||
aPaint1.GetPaintServer() != aPaint2.GetPaintServer();
|
||||
}
|
||||
|
||||
nsChangeHint nsStyleSVG::CalcDifference(const nsStyleSVG& aNewData) const {
|
||||
nsChangeHint hint = nsChangeHint(0);
|
||||
|
||||
if (!DefinitelyEqualURIs(mMarkerEnd, aNewData.mMarkerEnd) ||
|
||||
!DefinitelyEqualURIs(mMarkerMid, aNewData.mMarkerMid) ||
|
||||
!DefinitelyEqualURIs(mMarkerStart, aNewData.mMarkerStart)) {
|
||||
if (mMarkerEnd != aNewData.mMarkerEnd || mMarkerMid != aNewData.mMarkerMid ||
|
||||
mMarkerStart != aNewData.mMarkerStart) {
|
||||
// Markers currently contribute to SVGGeometryFrame::mRect,
|
||||
// so we need a reflow as well as a repaint. No intrinsic sizes need
|
||||
// to change, so nsChangeHint_NeedReflow is sufficient.
|
||||
|
@ -956,12 +1013,12 @@ void StyleShapeSource::DoDestroy() {
|
|||
// --------------------
|
||||
// nsStyleFilter
|
||||
//
|
||||
nsStyleFilter::nsStyleFilter() : mType(NS_STYLE_FILTER_NONE), mURL(nullptr) {
|
||||
nsStyleFilter::nsStyleFilter() : mType(NS_STYLE_FILTER_NONE) {
|
||||
MOZ_COUNT_CTOR(nsStyleFilter);
|
||||
}
|
||||
|
||||
nsStyleFilter::nsStyleFilter(const nsStyleFilter& aSource)
|
||||
: mType(NS_STYLE_FILTER_NONE), mURL(nullptr) {
|
||||
: mType(NS_STYLE_FILTER_NONE) {
|
||||
MOZ_COUNT_CTOR(nsStyleFilter);
|
||||
if (aSource.mType == NS_STYLE_FILTER_URL) {
|
||||
SetURL(aSource.mURL);
|
||||
|
@ -1002,7 +1059,7 @@ bool nsStyleFilter::operator==(const nsStyleFilter& aOther) const {
|
|||
}
|
||||
|
||||
if (mType == NS_STYLE_FILTER_URL) {
|
||||
return DefinitelyEqualURIs(mURL, aOther.mURL);
|
||||
return mURL == aOther.mURL;
|
||||
} else if (mType == NS_STYLE_FILTER_DROP_SHADOW) {
|
||||
return mDropShadow == aOther.mDropShadow;
|
||||
} else if (mType != NS_STYLE_FILTER_NONE) {
|
||||
|
@ -1016,10 +1073,8 @@ void nsStyleFilter::ReleaseRef() {
|
|||
if (mType == NS_STYLE_FILTER_DROP_SHADOW) {
|
||||
mDropShadow.~StyleSimpleShadow();
|
||||
} else if (mType == NS_STYLE_FILTER_URL) {
|
||||
NS_ASSERTION(mURL, "expected pointer");
|
||||
mURL->Release();
|
||||
mURL.~StyleComputedUrl();
|
||||
}
|
||||
mURL = nullptr;
|
||||
}
|
||||
|
||||
void nsStyleFilter::SetFilterParameter(const nsStyleCoord& aFilterParameter,
|
||||
|
@ -1029,10 +1084,9 @@ void nsStyleFilter::SetFilterParameter(const nsStyleCoord& aFilterParameter,
|
|||
mType = aType;
|
||||
}
|
||||
|
||||
bool nsStyleFilter::SetURL(css::URLValue* aURL) {
|
||||
bool nsStyleFilter::SetURL(const StyleComputedUrl& aUrl) {
|
||||
ReleaseRef();
|
||||
mURL = aURL;
|
||||
mURL->AddRef();
|
||||
new (&mURL) StyleComputedUrl(aUrl);
|
||||
mType = NS_STYLE_FILTER_URL;
|
||||
return true;
|
||||
}
|
||||
|
@ -1202,8 +1256,7 @@ void nsStyleSVGPaint::Reset() {
|
|||
mPaint.mColor = StyleColor::Black();
|
||||
break;
|
||||
case eStyleSVGPaintType_Server:
|
||||
mPaint.mPaintServer->Release();
|
||||
mPaint.mPaintServer = nullptr;
|
||||
mPaint.mPaintServer.~StyleComputedUrl();
|
||||
MOZ_FALLTHROUGH;
|
||||
case eStyleSVGPaintType_ContextFill:
|
||||
case eStyleSVGPaintType_ContextStroke:
|
||||
|
@ -1266,14 +1319,12 @@ void nsStyleSVGPaint::SetColor(StyleColor aColor) {
|
|||
mPaint.mColor = aColor;
|
||||
}
|
||||
|
||||
void nsStyleSVGPaint::SetPaintServer(css::URLValue* aPaintServer,
|
||||
void nsStyleSVGPaint::SetPaintServer(const StyleComputedUrl& aPaintServer,
|
||||
nsStyleSVGFallbackType aFallbackType,
|
||||
StyleColor aFallbackColor) {
|
||||
MOZ_ASSERT(aPaintServer);
|
||||
Reset();
|
||||
mType = eStyleSVGPaintType_Server;
|
||||
mPaint.mPaintServer = aPaintServer;
|
||||
mPaint.mPaintServer->AddRef();
|
||||
new (&mPaint.mPaintServer) StyleComputedUrl(aPaintServer);
|
||||
mFallbackType = aFallbackType;
|
||||
mFallbackColor = aFallbackColor;
|
||||
}
|
||||
|
@ -1286,8 +1337,7 @@ bool nsStyleSVGPaint::operator==(const nsStyleSVGPaint& aOther) const {
|
|||
case eStyleSVGPaintType_Color:
|
||||
return mPaint.mColor == aOther.mPaint.mColor;
|
||||
case eStyleSVGPaintType_Server:
|
||||
return DefinitelyEqualURIs(mPaint.mPaintServer,
|
||||
aOther.mPaint.mPaintServer) &&
|
||||
return mPaint.mPaintServer == aOther.mPaint.mPaintServer &&
|
||||
mFallbackType == aOther.mFallbackType &&
|
||||
mFallbackColor == aOther.mFallbackColor;
|
||||
case eStyleSVGPaintType_ContextFill:
|
||||
|
@ -1808,8 +1858,8 @@ class StyleImageRequestCleanupTask : public mozilla::Runnable {
|
|||
};
|
||||
|
||||
nsStyleImageRequest::nsStyleImageRequest(Mode aModeFlags,
|
||||
css::URLValue* aImageValue)
|
||||
: mImageValue(aImageValue), mModeFlags(aModeFlags), mResolved(false) {}
|
||||
const StyleComputedImageUrl& aImageURL)
|
||||
: mImageURL(aImageURL), mModeFlags(aModeFlags), mResolved(false) {}
|
||||
|
||||
nsStyleImageRequest::~nsStyleImageRequest() {
|
||||
// We may or may not be being destroyed on the main thread. To clean
|
||||
|
@ -1843,7 +1893,7 @@ bool nsStyleImageRequest::Resolve(Document& aDocument,
|
|||
mResolved = true;
|
||||
|
||||
nsIURI* docURI = aDocument.GetDocumentURI();
|
||||
if (GetImageValue()->HasRef()) {
|
||||
if (GetImageValue().HasRef()) {
|
||||
bool isEqualExceptRef = false;
|
||||
RefPtr<nsIURI> imageURI = GetImageURI();
|
||||
if (!imageURI) {
|
||||
|
@ -1870,11 +1920,12 @@ bool nsStyleImageRequest::Resolve(Document& aDocument,
|
|||
MOZ_ASSERT(mModeFlags == aOldImageRequest->mModeFlags);
|
||||
|
||||
mDocGroup = aOldImageRequest->mDocGroup;
|
||||
mImageValue = aOldImageRequest->mImageValue;
|
||||
mImageURL = aOldImageRequest->mImageURL;
|
||||
|
||||
mRequestProxy = aOldImageRequest->mRequestProxy;
|
||||
} else {
|
||||
mDocGroup = aDocument.GetDocGroup();
|
||||
imgRequestProxy* request = mImageValue->LoadImage(&aDocument);
|
||||
imgRequestProxy* request = mImageURL.LoadImage(aDocument);
|
||||
bool isPrint = !!aDocument.GetOriginalDocument();
|
||||
if (!isPrint) {
|
||||
mRequestProxy = request;
|
||||
|
@ -1916,7 +1967,7 @@ void nsStyleImageRequest::MaybeTrackAndLock() {
|
|||
|
||||
bool nsStyleImageRequest::DefinitelyEquals(
|
||||
const nsStyleImageRequest& aOther) const {
|
||||
return DefinitelyEqualURIs(mImageValue, aOther.mImageValue);
|
||||
return mImageURL == aOther.mImageURL;
|
||||
}
|
||||
|
||||
// --------------------
|
||||
|
@ -2105,12 +2156,8 @@ already_AddRefed<nsIURI> nsStyleImageRequest::GetImageURI() const {
|
|||
}
|
||||
|
||||
// If we had some problem resolving the mRequestProxy, use the URL stored
|
||||
// in the mImageValue.
|
||||
if (!mImageValue) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
uri = mImageValue->GetURI();
|
||||
// in the mImageURL.
|
||||
uri = mImageURL.GetURI();
|
||||
return uri.forget();
|
||||
}
|
||||
|
||||
|
@ -2309,8 +2356,8 @@ already_AddRefed<nsIURI> nsStyleImage::GetImageURI() const {
|
|||
return uri.forget();
|
||||
}
|
||||
|
||||
const css::URLValue* nsStyleImage::GetURLValue() const {
|
||||
return mType == eStyleImageType_Image ? mImage->GetImageValue() : nullptr;
|
||||
const StyleComputedImageUrl* nsStyleImage::GetURLValue() const {
|
||||
return mType == eStyleImageType_Image ? &mImage->GetImageValue() : nullptr;
|
||||
}
|
||||
|
||||
// --------------------
|
||||
|
@ -2573,8 +2620,6 @@ bool nsStyleImageLayers::operator==(const nsStyleImageLayers& aOther) const {
|
|||
|
||||
for (uint32_t i = 0; i < mLayers.Length(); i++) {
|
||||
if (mLayers[i].mPosition != aOther.mLayers[i].mPosition ||
|
||||
!DefinitelyEqualURIs(mLayers[i].mImage.GetURLValue(),
|
||||
aOther.mLayers[i].mImage.GetURLValue()) ||
|
||||
mLayers[i].mImage != aOther.mLayers[i].mImage ||
|
||||
mLayers[i].mSize != aOther.mLayers[i].mSize ||
|
||||
mLayers[i].mClip != aOther.mLayers[i].mClip ||
|
||||
|
@ -2767,11 +2812,17 @@ void nsStyleImageLayers::FillAllLayers(uint32_t aMaxItemCount) {
|
|||
FillImageLayerList(mLayers, &Layer::mComposite, mCompositeCount, fillCount);
|
||||
}
|
||||
|
||||
static bool UrlValuesEqual(const nsStyleImage& aImage,
|
||||
const nsStyleImage& aOtherImage) {
|
||||
auto* url = aImage.GetURLValue();
|
||||
auto* other = aOtherImage.GetURLValue();
|
||||
return url == other || (url && other && *url == *other);
|
||||
}
|
||||
|
||||
nsChangeHint nsStyleImageLayers::Layer::CalcDifference(
|
||||
const nsStyleImageLayers::Layer& aNewLayer) const {
|
||||
nsChangeHint hint = nsChangeHint(0);
|
||||
if (!DefinitelyEqualURIs(mImage.GetURLValue(),
|
||||
aNewLayer.mImage.GetURLValue())) {
|
||||
if (!UrlValuesEqual(mImage, aNewLayer.mImage)) {
|
||||
hint |= nsChangeHint_RepaintFrame | nsChangeHint_UpdateEffects;
|
||||
} else if (mAttachment != aNewLayer.mAttachment || mClip != aNewLayer.mClip ||
|
||||
mOrigin != aNewLayer.mOrigin || mRepeat != aNewLayer.mRepeat ||
|
||||
|
@ -2907,7 +2958,8 @@ bool StyleAnimation::operator==(const StyleAnimation& aOther) const {
|
|||
// nsStyleDisplay
|
||||
//
|
||||
nsStyleDisplay::nsStyleDisplay(const Document& aDocument)
|
||||
: mTransitions(
|
||||
: mBinding(StyleUrlOrNone::None()),
|
||||
mTransitions(
|
||||
nsStyleAutoArray<StyleTransition>::WITH_SINGLE_INITIAL_ELEMENT),
|
||||
mTransitionTimingFunctionCount(1),
|
||||
mTransitionDurationCount(1),
|
||||
|
@ -3092,9 +3144,8 @@ nsChangeHint nsStyleDisplay::CalcDifference(
|
|||
const nsStyleDisplay& aNewData) const {
|
||||
nsChangeHint hint = nsChangeHint(0);
|
||||
|
||||
if (!DefinitelyEqualURIsAndPrincipal(mBinding, aNewData.mBinding) ||
|
||||
mPosition != aNewData.mPosition || mDisplay != aNewData.mDisplay ||
|
||||
mContain != aNewData.mContain ||
|
||||
if (mBinding != aNewData.mBinding || mPosition != aNewData.mPosition ||
|
||||
mDisplay != aNewData.mDisplay || mContain != aNewData.mContain ||
|
||||
(mFloat == StyleFloat::None) != (aNewData.mFloat == StyleFloat::None) ||
|
||||
mScrollBehavior != aNewData.mScrollBehavior ||
|
||||
mScrollSnapType != aNewData.mScrollSnapType ||
|
||||
|
|
|
@ -215,7 +215,7 @@ class nsStyleImageRequest {
|
|||
|
||||
// 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::URLValue* aImageValue);
|
||||
nsStyleImageRequest(Mode aModeFlags, const mozilla::StyleComputedImageUrl&);
|
||||
|
||||
bool Resolve(mozilla::dom::Document&,
|
||||
const nsStyleImageRequest* aOldImageRequest);
|
||||
|
@ -234,7 +234,9 @@ class nsStyleImageRequest {
|
|||
// return true from URLValue::DefinitelyEqualURIs.
|
||||
bool DefinitelyEquals(const nsStyleImageRequest& aOther) const;
|
||||
|
||||
mozilla::css::URLValue* GetImageValue() const { return mImageValue; }
|
||||
const mozilla::StyleComputedImageUrl& GetImageValue() const {
|
||||
return mImageURL;
|
||||
}
|
||||
|
||||
already_AddRefed<nsIURI> GetImageURI() const;
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(nsStyleImageRequest);
|
||||
|
@ -246,7 +248,7 @@ class nsStyleImageRequest {
|
|||
void MaybeTrackAndLock();
|
||||
|
||||
RefPtr<imgRequestProxy> mRequestProxy;
|
||||
RefPtr<mozilla::css::URLValue> mImageValue;
|
||||
mozilla::StyleComputedImageUrl mImageURL;
|
||||
RefPtr<mozilla::dom::ImageTracker> mImageTracker;
|
||||
|
||||
// Cache DocGroup for dispatching events in the destructor.
|
||||
|
@ -295,8 +297,6 @@ struct CachedBorderImageData {
|
|||
* image of type (1)).
|
||||
*/
|
||||
struct nsStyleImage {
|
||||
typedef mozilla::css::URLValue URLValue;
|
||||
|
||||
nsStyleImage();
|
||||
~nsStyleImage();
|
||||
nsStyleImage(const nsStyleImage& aOther);
|
||||
|
@ -346,7 +346,7 @@ struct nsStyleImage {
|
|||
|
||||
already_AddRefed<nsIURI> GetImageURI() const;
|
||||
|
||||
const URLValue* GetURLValue() const;
|
||||
const mozilla::StyleComputedImageUrl* GetURLValue() const;
|
||||
|
||||
/**
|
||||
* Compute the actual crop rect in pixels, using the source image bounds.
|
||||
|
@ -1603,10 +1603,7 @@ struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleDisplay {
|
|||
|
||||
nsChangeHint CalcDifference(const nsStyleDisplay& aNewData) const;
|
||||
|
||||
// We guarantee that if mBinding is non-null, so are mBinding->GetURI() and
|
||||
// mBinding->mOriginPrincipal.
|
||||
RefPtr<mozilla::css::URLValue> mBinding;
|
||||
|
||||
mozilla::StyleUrlOrNone mBinding;
|
||||
nsStyleAutoArray<mozilla::StyleTransition> mTransitions;
|
||||
// The number of elements in mTransitions that are not from repeating
|
||||
// a list due to another property being longer.
|
||||
|
@ -2393,10 +2390,10 @@ class nsStyleSVGPaint {
|
|||
|
||||
void SetNone();
|
||||
void SetColor(mozilla::StyleColor aColor);
|
||||
void SetPaintServer(mozilla::css::URLValue* aPaintServer,
|
||||
void SetPaintServer(const mozilla::StyleComputedUrl& aPaintServer,
|
||||
nsStyleSVGFallbackType aFallbackType,
|
||||
mozilla::StyleColor aFallbackColor);
|
||||
void SetPaintServer(mozilla::css::URLValue* aPaintServer) {
|
||||
void SetPaintServer(const mozilla::StyleComputedUrl& aPaintServer) {
|
||||
SetPaintServer(aPaintServer, eStyleSVGFallbackType_NotSet,
|
||||
mozilla::StyleColor::Black());
|
||||
}
|
||||
|
@ -2413,7 +2410,7 @@ class nsStyleSVGPaint {
|
|||
return mPaint.mColor.CalcColor(*aComputedStyle);
|
||||
}
|
||||
|
||||
mozilla::css::URLValue* GetPaintServer() const {
|
||||
const mozilla::StyleComputedUrl& GetPaintServer() const {
|
||||
MOZ_ASSERT(mType == eStyleSVGPaintType_Server);
|
||||
return mPaint.mPaintServer;
|
||||
}
|
||||
|
@ -2438,7 +2435,7 @@ class nsStyleSVGPaint {
|
|||
|
||||
union ColorOrPaintServer {
|
||||
mozilla::StyleColor mColor;
|
||||
mozilla::css::URLValue* mPaintServer;
|
||||
mozilla::StyleComputedUrl mPaintServer;
|
||||
explicit ColorOrPaintServer(mozilla::StyleColor c) : mColor(c) {}
|
||||
~ColorOrPaintServer() {} // Caller must call Reset().
|
||||
};
|
||||
|
@ -2459,9 +2456,9 @@ struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleSVG {
|
|||
|
||||
nsStyleSVGPaint mFill;
|
||||
nsStyleSVGPaint mStroke;
|
||||
RefPtr<mozilla::css::URLValue> mMarkerEnd;
|
||||
RefPtr<mozilla::css::URLValue> mMarkerMid;
|
||||
RefPtr<mozilla::css::URLValue> mMarkerStart;
|
||||
mozilla::StyleUrlOrNone mMarkerEnd;
|
||||
mozilla::StyleUrlOrNone mMarkerMid;
|
||||
mozilla::StyleUrlOrNone mMarkerStart;
|
||||
nsTArray<mozilla::NonNegativeLengthPercentage> mStrokeDasharray;
|
||||
mozilla::StyleMozContextProperties mMozContextProperties;
|
||||
|
||||
|
@ -2508,7 +2505,9 @@ struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleSVG {
|
|||
return mContextFlags & STROKE_WIDTH_CONTEXT;
|
||||
}
|
||||
|
||||
bool HasMarker() const { return mMarkerStart || mMarkerMid || mMarkerEnd; }
|
||||
bool HasMarker() const {
|
||||
return mMarkerStart.IsUrl() || mMarkerMid.IsUrl() || mMarkerEnd.IsUrl();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the stroke is not "none" and the stroke-opacity is greater
|
||||
|
@ -2572,12 +2571,12 @@ struct nsStyleFilter {
|
|||
}
|
||||
void SetFilterParameter(const nsStyleCoord& aFilterParameter, int32_t aType);
|
||||
|
||||
mozilla::css::URLValue* GetURL() const {
|
||||
const mozilla::StyleComputedUrl& GetURL() const {
|
||||
MOZ_ASSERT(mType == NS_STYLE_FILTER_URL, "wrong filter type");
|
||||
return mURL;
|
||||
}
|
||||
|
||||
bool SetURL(mozilla::css::URLValue* aValue);
|
||||
bool SetURL(const mozilla::StyleComputedUrl& aUrl);
|
||||
|
||||
const mozilla::StyleSimpleShadow& GetDropShadow() const {
|
||||
NS_ASSERTION(mType == NS_STYLE_FILTER_DROP_SHADOW, "wrong filter type");
|
||||
|
@ -2591,7 +2590,7 @@ struct nsStyleFilter {
|
|||
uint32_t mType; // NS_STYLE_FILTER_*
|
||||
nsStyleCoord mFilterParameter; // coord, percent, factor, angle
|
||||
union {
|
||||
mozilla::css::URLValue* mURL;
|
||||
mozilla::StyleComputedUrl mURL;
|
||||
mozilla::StyleSimpleShadow mDropShadow;
|
||||
};
|
||||
};
|
||||
|
|
|
@ -93,18 +93,14 @@ class URLAndReferrerInfoHashKey : public PLDHashEntryHdr {
|
|||
};
|
||||
|
||||
static already_AddRefed<URLAndReferrerInfo> ResolveURLUsingLocalRef(
|
||||
nsIFrame* aFrame, const css::URLValue* aURL) {
|
||||
nsIFrame* aFrame, const StyleComputedImageUrl& aURL) {
|
||||
MOZ_ASSERT(aFrame);
|
||||
|
||||
if (!aURL) {
|
||||
return nullptr;
|
||||
}
|
||||
nsCOMPtr<nsIURI> uri = aURL.GetURI();
|
||||
|
||||
nsCOMPtr<nsIURI> uri = aURL->GetURI();
|
||||
|
||||
if (aURL->IsLocalRef()) {
|
||||
if (aURL.IsLocalRef()) {
|
||||
uri = SVGObserverUtils::GetBaseURLForLocalRef(aFrame->GetContent(), uri);
|
||||
uri = aURL->ResolveLocalRef(uri);
|
||||
uri = aURL.ResolveLocalRef(uri);
|
||||
}
|
||||
|
||||
if (!uri) {
|
||||
|
@ -112,7 +108,7 @@ static already_AddRefed<URLAndReferrerInfo> ResolveURLUsingLocalRef(
|
|||
}
|
||||
|
||||
RefPtr<URLAndReferrerInfo> info =
|
||||
new URLAndReferrerInfo(uri, aURL->ExtraData());
|
||||
new URLAndReferrerInfo(uri, aURL.ExtraData());
|
||||
return info.forget();
|
||||
}
|
||||
|
||||
|
@ -703,10 +699,10 @@ SVGFilterObserverList::SVGFilterObserverList(
|
|||
filterURL = ResolveURLUsingLocalRef(aFilteredFrame, aFilters[i].GetURL());
|
||||
} else {
|
||||
nsCOMPtr<nsIURI> resolvedURI =
|
||||
aFilters[i].GetURL()->ResolveLocalRef(aFilteredElement);
|
||||
aFilters[i].GetURL().ResolveLocalRef(aFilteredElement);
|
||||
if (resolvedURI) {
|
||||
filterURL = new URLAndReferrerInfo(resolvedURI,
|
||||
aFilters[i].GetURL()->ExtraData());
|
||||
aFilters[i].GetURL().ExtraData());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -820,8 +816,12 @@ SVGMaskObserverList::SVGMaskObserverList(nsIFrame* aFrame) : mFrame(aFrame) {
|
|||
const nsStyleSVGReset* svgReset = aFrame->StyleSVGReset();
|
||||
|
||||
for (uint32_t i = 0; i < svgReset->mMask.mImageCount; i++) {
|
||||
const css::URLValue* data = svgReset->mMask.mLayers[i].mImage.GetURLValue();
|
||||
RefPtr<URLAndReferrerInfo> maskUri = ResolveURLUsingLocalRef(aFrame, data);
|
||||
const StyleComputedImageUrl* data =
|
||||
svgReset->mMask.mLayers[i].mImage.GetURLValue();
|
||||
RefPtr<URLAndReferrerInfo> maskUri;
|
||||
if (data) {
|
||||
maskUri = ResolveURLUsingLocalRef(aFrame, *data);
|
||||
}
|
||||
|
||||
bool hasRef = false;
|
||||
if (maskUri) {
|
||||
|
@ -1110,8 +1110,12 @@ static nsSVGPaintingProperty* GetPaintingProperty(
|
|||
}
|
||||
|
||||
static already_AddRefed<URLAndReferrerInfo> GetMarkerURI(
|
||||
nsIFrame* aFrame, RefPtr<css::URLValue> nsStyleSVG::*aMarker) {
|
||||
return ResolveURLUsingLocalRef(aFrame, aFrame->StyleSVG()->*aMarker);
|
||||
nsIFrame* aFrame, const StyleUrlOrNone nsStyleSVG::*aMarker) {
|
||||
const StyleUrlOrNone& url = aFrame->StyleSVG()->*aMarker;
|
||||
if (url.IsNone()) {
|
||||
return nullptr;
|
||||
}
|
||||
return ResolveURLUsingLocalRef(aFrame, url.AsUrl());
|
||||
}
|
||||
|
||||
bool SVGObserverUtils::GetAndObserveMarkers(nsIFrame* aMarkedFrame,
|
||||
|
@ -1234,11 +1238,10 @@ static nsSVGPaintingProperty* GetOrCreateClipPathObserver(
|
|||
if (svgStyleReset->mClipPath.GetType() != StyleShapeSourceType::Image) {
|
||||
return nullptr;
|
||||
}
|
||||
const css::URLValue* url =
|
||||
svgStyleReset->mClipPath.ShapeImage().GetURLValue();
|
||||
const auto* url = svgStyleReset->mClipPath.ShapeImage().GetURLValue();
|
||||
MOZ_ASSERT(url);
|
||||
RefPtr<URLAndReferrerInfo> pathURI =
|
||||
ResolveURLUsingLocalRef(aClippedFrame, url);
|
||||
ResolveURLUsingLocalRef(aClippedFrame, *url);
|
||||
return GetPaintingProperty(pathURI, aClippedFrame, ClipPathProperty());
|
||||
}
|
||||
|
||||
|
|
|
@ -51,10 +51,10 @@ class URLAndReferrerInfo {
|
|||
MOZ_ASSERT(aURI);
|
||||
}
|
||||
|
||||
URLAndReferrerInfo(nsIURI* aURI, URLExtraData* aExtraData)
|
||||
URLAndReferrerInfo(nsIURI* aURI, const URLExtraData& aExtraData)
|
||||
: mURI(aURI),
|
||||
mReferrer(aExtraData->GetReferrer()),
|
||||
mReferrerPolicy(aExtraData->GetReferrerPolicy()) {
|
||||
mReferrer(aExtraData.GetReferrer()),
|
||||
mReferrerPolicy(aExtraData.GetReferrerPolicy()) {
|
||||
MOZ_ASSERT(aURI);
|
||||
}
|
||||
|
||||
|
|
|
@ -134,7 +134,7 @@ nsSVGFilterFrame* nsSVGFilterInstance::GetFilterFrame(nsIFrame* aTargetFrame) {
|
|||
|
||||
url = urlExtraReferrer->GetURI();
|
||||
} else {
|
||||
url = mFilter.GetURL()->ResolveLocalRef(mTargetContent);
|
||||
url = mFilter.GetURL().ResolveLocalRef(mTargetContent);
|
||||
}
|
||||
|
||||
if (!url) {
|
||||
|
@ -147,8 +147,8 @@ nsSVGFilterFrame* nsSVGFilterInstance::GetFilterFrame(nsIFrame* aTargetFrame) {
|
|||
IDTracker idTracker;
|
||||
bool watch = false;
|
||||
idTracker.ResetToURIFragmentID(
|
||||
mTargetContent, url, mFilter.GetURL()->ExtraData()->GetReferrer(),
|
||||
mFilter.GetURL()->ExtraData()->GetReferrerPolicy(), watch);
|
||||
mTargetContent, url, mFilter.GetURL().ExtraData().GetReferrer(),
|
||||
mFilter.GetURL().ExtraData().GetReferrerPolicy(), watch);
|
||||
Element* element = idTracker.get();
|
||||
if (!element) {
|
||||
// The URL points to no element.
|
||||
|
|
|
@ -90,6 +90,9 @@ const STATIC_REFCOUNT: usize = usize::MAX;
|
|||
/// usage of PhantomData.
|
||||
///
|
||||
/// [`Arc`]: https://doc.rust-lang.org/stable/std/sync/struct.Arc.html
|
||||
///
|
||||
/// cbindgen:derive-eq=false
|
||||
/// cbindgen:derive-neq=false
|
||||
#[repr(C)]
|
||||
pub struct Arc<T: ?Sized> {
|
||||
p: ptr::NonNull<ArcInner<T>>,
|
||||
|
|
|
@ -55,7 +55,7 @@ impl OneOrMoreSeparated for Source {
|
|||
#[repr(u8)]
|
||||
#[allow(missing_docs)]
|
||||
pub enum FontFaceSourceListComponent {
|
||||
Url(*const crate::gecko_bindings::structs::mozilla::css::URLValue),
|
||||
Url(*const crate::gecko::url::CssUrl),
|
||||
Local(*mut crate::gecko_bindings::structs::nsAtom),
|
||||
FormatHint {
|
||||
length: usize,
|
||||
|
|
|
@ -122,11 +122,11 @@ impl nsStyleImage {
|
|||
match image {
|
||||
GenericImage::Gradient(boxed_gradient) => self.set_gradient(*boxed_gradient),
|
||||
GenericImage::Url(ref url) => unsafe {
|
||||
bindings::Gecko_SetLayerImageImageValue(self, url.url_value_ptr())
|
||||
bindings::Gecko_SetLayerImageImageValue(self, url);
|
||||
},
|
||||
GenericImage::Rect(ref image_rect) => {
|
||||
unsafe {
|
||||
bindings::Gecko_SetLayerImageImageValue(self, image_rect.url.url_value_ptr());
|
||||
bindings::Gecko_SetLayerImageImageValue(self, &image_rect.url);
|
||||
bindings::Gecko_InitializeImageCropRect(self);
|
||||
|
||||
// Set CropRect
|
||||
|
@ -584,9 +584,10 @@ pub mod basic_shape {
|
|||
|
||||
impl<'a> From<&'a StyleShapeSource> for ClippingShape {
|
||||
fn from(other: &'a StyleShapeSource) -> Self {
|
||||
use crate::values::generics::image::Image as GenericImage;
|
||||
match other.mType {
|
||||
StyleShapeSourceType::Image => unsafe {
|
||||
use crate::values::generics::image::Image as GenericImage;
|
||||
|
||||
let shape_image = &*other.__bindgen_anon_1.mShapeImage.as_ref().mPtr;
|
||||
let image = shape_image.into_image().expect("Cannot convert to Image");
|
||||
match image {
|
||||
|
|
|
@ -5,13 +5,11 @@
|
|||
//! Common handling for the specified value CSS url() values.
|
||||
|
||||
use crate::gecko_bindings::bindings;
|
||||
use crate::gecko_bindings::structs::root::mozilla::css::URLValue;
|
||||
use crate::gecko_bindings::structs::root::mozilla::CORSMode;
|
||||
use crate::gecko_bindings::structs::root::nsStyleImageRequest;
|
||||
use crate::gecko_bindings::sugar::ownership::{FFIArcHelpers, HasArcFFI};
|
||||
use crate::gecko_bindings::structs;
|
||||
use crate::gecko_bindings::structs::nsStyleImageRequest;
|
||||
use crate::gecko_bindings::sugar::refptr::RefPtr;
|
||||
use crate::parser::{Parse, ParserContext};
|
||||
use crate::stylesheets::UrlExtraData;
|
||||
use crate::stylesheets::{UrlExtraData, CorsMode};
|
||||
use crate::values::computed::{Context, ToComputedValue};
|
||||
use cssparser::Parser;
|
||||
use malloc_size_of::{MallocSizeOf, MallocSizeOfOps};
|
||||
|
@ -27,25 +25,63 @@ use to_shmem::{SharedMemoryBuilder, ToShmem};
|
|||
/// A CSS url() value for gecko.
|
||||
#[css(function = "url")]
|
||||
#[derive(Clone, Debug, PartialEq, SpecifiedValueInfo, ToCss, ToShmem)]
|
||||
#[repr(C)]
|
||||
pub struct CssUrl(pub Arc<CssUrlData>);
|
||||
|
||||
/// Data shared between CssUrls.
|
||||
#[derive(Clone, Debug, PartialEq, SpecifiedValueInfo, ToCss, ToShmem)]
|
||||
///
|
||||
/// cbindgen:derive-eq=false
|
||||
/// cbindgen:derive-neq=false
|
||||
#[derive(Debug, SpecifiedValueInfo, ToCss, ToShmem)]
|
||||
#[repr(C)]
|
||||
pub struct CssUrlData {
|
||||
/// The URL in unresolved string form.
|
||||
serialization: String,
|
||||
serialization: crate::OwnedStr,
|
||||
|
||||
/// The URL extra data.
|
||||
#[css(skip)]
|
||||
pub extra_data: UrlExtraData,
|
||||
|
||||
/// The CORS mode that will be used for the load.
|
||||
#[css(skip)]
|
||||
cors_mode: CorsMode,
|
||||
|
||||
/// Data to trigger a load from Gecko. This is mutable in C++.
|
||||
///
|
||||
/// TODO(emilio): Maybe we can eagerly resolve URLs and make this immutable?
|
||||
#[css(skip)]
|
||||
load_data: LoadDataSource,
|
||||
}
|
||||
|
||||
impl PartialEq for CssUrlData {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.serialization == other.serialization &&
|
||||
self.extra_data == other.extra_data &&
|
||||
self.cors_mode == other.cors_mode
|
||||
}
|
||||
}
|
||||
|
||||
impl CssUrl {
|
||||
fn parse_with_cors_mode<'i, 't>(
|
||||
context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>,
|
||||
cors_mode: CorsMode,
|
||||
) -> Result<Self, ParseError<'i>> {
|
||||
let url = input.expect_url()?;
|
||||
Ok(Self::parse_from_string(url.as_ref().to_owned(), context, cors_mode))
|
||||
}
|
||||
|
||||
/// 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 {
|
||||
pub fn parse_from_string(
|
||||
url: String,
|
||||
context: &ParserContext,
|
||||
cors_mode: CorsMode,
|
||||
) -> Self {
|
||||
CssUrl(Arc::new(CssUrlData {
|
||||
serialization: url,
|
||||
serialization: url.into(),
|
||||
extra_data: context.url_data.clone(),
|
||||
cors_mode,
|
||||
load_data: LoadDataSource::Owned(LoadData::default()),
|
||||
}))
|
||||
}
|
||||
|
||||
|
@ -85,27 +121,12 @@ impl CssUrlData {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(debug_assertions)]
|
||||
impl Drop for CssUrlData {
|
||||
fn drop(&mut self) {
|
||||
assert!(
|
||||
!URL_VALUE_TABLE
|
||||
.read()
|
||||
.unwrap()
|
||||
.contains_key(&CssUrlDataKey(self as *mut _ as *const _)),
|
||||
"All CssUrlData objects used as keys in URL_VALUE_TABLE should be \
|
||||
from shared memory style sheets, and so should never be dropped",
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
impl Parse for CssUrl {
|
||||
fn parse<'i, 't>(
|
||||
context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<Self, ParseError<'i>> {
|
||||
let url = input.expect_url()?;
|
||||
Ok(Self::parse_from_string(url.as_ref().to_owned(), context))
|
||||
Self::parse_with_cors_mode(context, input, CorsMode::None)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -122,143 +143,101 @@ impl MallocSizeOf for CssUrl {
|
|||
}
|
||||
}
|
||||
|
||||
/// A key type for URL_VALUE_TABLE.
|
||||
/// A key type for LOAD_DATA_TABLE.
|
||||
#[derive(Eq, Hash, PartialEq)]
|
||||
struct CssUrlDataKey(*const CssUrlData);
|
||||
struct LoadDataKey(*const LoadDataSource);
|
||||
|
||||
unsafe impl Sync for CssUrlDataKey {}
|
||||
unsafe impl Send for CssUrlDataKey {}
|
||||
unsafe impl Sync for LoadDataKey {}
|
||||
unsafe impl Send for LoadDataKey {}
|
||||
|
||||
/// The source of a Gecko URLValue object for a SpecifiedUrl.
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum URLValueSource {
|
||||
/// A strong reference to a Gecko URLValue object.
|
||||
URLValue(RefPtr<URLValue>),
|
||||
/// A CORSMode value used to lazily construct a Gecko URLValue object.
|
||||
///
|
||||
/// The lazily created object will be stored in URL_VALUE_TABLE.
|
||||
CORSMode(CORSMode),
|
||||
/// The load data for a given URL. This is mutable from C++, for now at least.
|
||||
#[repr(C)]
|
||||
#[derive(Debug)]
|
||||
pub struct LoadData {
|
||||
resolved: RefPtr<structs::nsIURI>,
|
||||
load_id: u64,
|
||||
tried_to_resolve: bool,
|
||||
}
|
||||
|
||||
impl ToShmem for URLValueSource {
|
||||
impl Drop for LoadData {
|
||||
fn drop(&mut self) {
|
||||
if self.load_id != 0 {
|
||||
unsafe {
|
||||
bindings::Gecko_LoadData_DeregisterLoad(self);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for LoadData {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
resolved: RefPtr::null(),
|
||||
load_id: 0,
|
||||
tried_to_resolve: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// The data for a load, or a lazy-loaded, static member that will be stored in
|
||||
/// LOAD_DATA_TABLE, keyed by the memory location of this object, which is
|
||||
/// always in the heap because it's inside the CssUrlData object.
|
||||
///
|
||||
/// This type is meant not to be used from C++ so we don't derive helper
|
||||
/// methods.
|
||||
///
|
||||
/// cbindgen:derive-helper-methods=false
|
||||
#[derive(Debug)]
|
||||
#[repr(u8, C)]
|
||||
pub enum LoadDataSource {
|
||||
/// An owned copy of the load data.
|
||||
Owned(LoadData),
|
||||
/// A lazily-resolved copy of it.
|
||||
Lazy,
|
||||
}
|
||||
|
||||
impl LoadDataSource {
|
||||
/// Gets the load data associated with the source.
|
||||
///
|
||||
/// This relies on the source on being in a stable location if lazy.
|
||||
#[inline]
|
||||
pub unsafe fn get(&self) -> *const LoadData {
|
||||
match *self {
|
||||
LoadDataSource::Owned(ref d) => return d,
|
||||
LoadDataSource::Lazy => {},
|
||||
}
|
||||
|
||||
let key = LoadDataKey(self);
|
||||
|
||||
{
|
||||
let guard = LOAD_DATA_TABLE.read().unwrap();
|
||||
if let Some(r) = guard.get(&key) {
|
||||
return &**r;
|
||||
}
|
||||
}
|
||||
let mut guard = LOAD_DATA_TABLE.write().unwrap();
|
||||
let r = guard.entry(key).or_insert_with(Default::default);
|
||||
&**r
|
||||
}
|
||||
}
|
||||
|
||||
impl ToShmem for LoadDataSource {
|
||||
fn to_shmem(&self, _builder: &mut SharedMemoryBuilder) -> ManuallyDrop<Self> {
|
||||
ManuallyDrop::new(match self {
|
||||
URLValueSource::URLValue(r) => URLValueSource::CORSMode(r.mCORSMode),
|
||||
URLValueSource::CORSMode(c) => URLValueSource::CORSMode(*c),
|
||||
LoadDataSource::Owned(..) => LoadDataSource::Lazy,
|
||||
LoadDataSource::Lazy => LoadDataSource::Lazy,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/// A specified non-image `url()` value.
|
||||
#[derive(Clone, Debug, SpecifiedValueInfo, ToCss, ToShmem)]
|
||||
pub struct SpecifiedUrl {
|
||||
/// The specified url value.
|
||||
pub url: CssUrl,
|
||||
/// Gecko's URLValue so that we can reuse it while rematching a
|
||||
/// property with this specified value.
|
||||
///
|
||||
/// Box this to avoid SpecifiedUrl getting bigger than two words,
|
||||
/// and increasing the size of PropertyDeclaration.
|
||||
#[css(skip)]
|
||||
url_value: Box<URLValueSource>,
|
||||
}
|
||||
pub type SpecifiedUrl = CssUrl;
|
||||
|
||||
fn make_url_value(url: &CssUrl, cors_mode: CORSMode) -> RefPtr<URLValue> {
|
||||
unsafe {
|
||||
let ptr = bindings::Gecko_URLValue_Create(url.0.clone().into_strong(), cors_mode);
|
||||
// We do not expect Gecko_URLValue_Create returns null.
|
||||
debug_assert!(!ptr.is_null());
|
||||
RefPtr::from_addrefed(ptr)
|
||||
}
|
||||
}
|
||||
|
||||
impl SpecifiedUrl {
|
||||
/// 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 url_value = Box::new(URLValueSource::URLValue(make_url_value(&url, cors)));
|
||||
Self { url, url_value }
|
||||
}
|
||||
|
||||
fn from_css_url(url: CssUrl) -> Self {
|
||||
use crate::gecko_bindings::structs::root::mozilla::CORSMode_CORS_NONE;
|
||||
Self::from_css_url_with_cors(url, CORSMode_CORS_NONE)
|
||||
}
|
||||
|
||||
fn from_css_url_with_cors_anonymous(url: CssUrl) -> Self {
|
||||
use crate::gecko_bindings::structs::root::mozilla::CORSMode_CORS_ANONYMOUS;
|
||||
Self::from_css_url_with_cors(url, CORSMode_CORS_ANONYMOUS)
|
||||
}
|
||||
|
||||
fn with_url_value<F, T>(&self, f: F) -> T
|
||||
where
|
||||
F: FnOnce(&RefPtr<URLValue>) -> T,
|
||||
{
|
||||
match *self.url_value {
|
||||
URLValueSource::URLValue(ref r) => f(r),
|
||||
URLValueSource::CORSMode(cors_mode) => {
|
||||
{
|
||||
let guard = URL_VALUE_TABLE.read().unwrap();
|
||||
if let Some(r) = guard.get(&(CssUrlDataKey(&*self.url.0 as *const _))) {
|
||||
return f(r);
|
||||
}
|
||||
}
|
||||
let mut guard = URL_VALUE_TABLE.write().unwrap();
|
||||
let r = guard
|
||||
.entry(CssUrlDataKey(&*self.url.0 as *const _))
|
||||
.or_insert_with(|| make_url_value(&self.url, cors_mode));
|
||||
f(r)
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
/// Clone a new, strong reference to the Gecko URLValue.
|
||||
pub fn clone_url_value(&self) -> RefPtr<URLValue> {
|
||||
self.with_url_value(RefPtr::clone)
|
||||
}
|
||||
|
||||
/// Get a raw pointer to the URLValue held by this SpecifiedUrl, for FFI.
|
||||
pub fn url_value_ptr(&self) -> *mut URLValue {
|
||||
self.with_url_value(RefPtr::get)
|
||||
}
|
||||
}
|
||||
|
||||
/// Clears URL_VALUE_TABLE. Entries in this table, which are for specified URL
|
||||
/// Clears LOAD_DATA_TABLE. Entries in this table, which are for specified URL
|
||||
/// values that come from shared memory style sheets, would otherwise persist
|
||||
/// until the end of the process and be reported as leaks.
|
||||
pub fn shutdown() {
|
||||
URL_VALUE_TABLE.write().unwrap().clear();
|
||||
}
|
||||
|
||||
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 PartialEq for SpecifiedUrl {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.url.eq(&other.url)
|
||||
}
|
||||
}
|
||||
|
||||
impl Eq for SpecifiedUrl {}
|
||||
|
||||
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_ptr()) };
|
||||
n
|
||||
}
|
||||
LOAD_DATA_TABLE.write().unwrap().clear();
|
||||
}
|
||||
|
||||
impl ToComputedValue for SpecifiedUrl {
|
||||
|
@ -277,12 +256,13 @@ impl ToComputedValue for SpecifiedUrl {
|
|||
|
||||
/// A specified image `url()` value.
|
||||
#[derive(Clone, Debug, Eq, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToCss, ToShmem)]
|
||||
#[repr(C)]
|
||||
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))
|
||||
SpecifiedImageUrl(SpecifiedUrl::parse_from_string(url, context, CorsMode::None))
|
||||
}
|
||||
|
||||
/// Provides an alternate method for parsing that associates the URL
|
||||
|
@ -291,9 +271,11 @@ impl SpecifiedImageUrl {
|
|||
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)
|
||||
Ok(SpecifiedImageUrl(SpecifiedUrl::parse_with_cors_mode(
|
||||
context,
|
||||
input,
|
||||
CorsMode::Anonymous,
|
||||
)?))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -320,59 +302,39 @@ impl ToComputedValue for SpecifiedImageUrl {
|
|||
}
|
||||
}
|
||||
|
||||
fn serialize_computed_url<W>(
|
||||
url_value: &URLValue,
|
||||
dest: &mut CssWriter<W>,
|
||||
get_url: unsafe extern "C" fn(*const URLValue, *mut nsCString),
|
||||
) -> fmt::Result
|
||||
where
|
||||
W: Write,
|
||||
{
|
||||
dest.write_str("url(")?;
|
||||
unsafe {
|
||||
let mut string = nsCString::new();
|
||||
get_url(url_value, &mut string);
|
||||
string.as_str_unchecked().to_css(dest)?;
|
||||
}
|
||||
dest.write_char(')')
|
||||
}
|
||||
|
||||
/// The computed value of a CSS non-image `url()`.
|
||||
///
|
||||
/// The only difference between specified and computed URLs is the
|
||||
/// serialization.
|
||||
#[derive(Clone, Debug, Eq, MallocSizeOf, PartialEq)]
|
||||
#[repr(C)]
|
||||
pub struct ComputedUrl(pub SpecifiedUrl);
|
||||
|
||||
impl ComputedUrl {
|
||||
fn serialize_with<W>(
|
||||
&self,
|
||||
function: unsafe extern "C" fn(*const Self, *mut nsCString),
|
||||
dest: &mut CssWriter<W>,
|
||||
) -> fmt::Result
|
||||
where
|
||||
W: Write,
|
||||
{
|
||||
dest.write_str("url(")?;
|
||||
unsafe {
|
||||
let mut string = nsCString::new();
|
||||
function(self, &mut string);
|
||||
string.as_str_unchecked().to_css(dest)?;
|
||||
}
|
||||
dest.write_char(')')
|
||||
}
|
||||
}
|
||||
|
||||
impl ToCss for ComputedUrl {
|
||||
fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
|
||||
where
|
||||
W: Write,
|
||||
{
|
||||
self.0
|
||||
.with_url_value(|r| serialize_computed_url(r, dest, bindings::Gecko_GetComputedURLSpec))
|
||||
}
|
||||
}
|
||||
|
||||
impl ComputedUrl {
|
||||
/// Convert from RefPtr<URLValue> to ComputedUrl.
|
||||
pub unsafe fn from_url_value(url_value: RefPtr<URLValue>) -> Self {
|
||||
let css_url = &*url_value.mCssUrl.mRawPtr;
|
||||
let url = CssUrl(CssUrlData::as_arc(&css_url).clone_arc());
|
||||
ComputedUrl(SpecifiedUrl {
|
||||
url,
|
||||
url_value: Box::new(URLValueSource::URLValue(url_value)),
|
||||
})
|
||||
}
|
||||
|
||||
/// Clone a new, strong reference to the Gecko URLValue.
|
||||
pub fn clone_url_value(&self) -> RefPtr<URLValue> {
|
||||
self.0.clone_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_ptr()
|
||||
self.serialize_with(bindings::Gecko_GetComputedURLSpec, dest)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -380,39 +342,26 @@ impl ComputedUrl {
|
|||
#[derive(Clone, Debug, Eq, MallocSizeOf, PartialEq)]
|
||||
pub struct ComputedImageUrl(pub ComputedUrl);
|
||||
|
||||
impl ComputedImageUrl {
|
||||
/// Convert from nsStyleImageRequest to ComputedImageUrl.
|
||||
pub unsafe fn from_image_request(image_request: &nsStyleImageRequest) -> Self {
|
||||
image_request.mImageURL.clone()
|
||||
}
|
||||
}
|
||||
|
||||
impl ToCss for ComputedImageUrl {
|
||||
fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
|
||||
where
|
||||
W: Write,
|
||||
{
|
||||
(self.0).0.with_url_value(|r| {
|
||||
serialize_computed_url(r, dest, bindings::Gecko_GetComputedImageURLSpec)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl ComputedImageUrl {
|
||||
/// Convert from nsStyleImageReques to ComputedImageUrl.
|
||||
pub unsafe fn from_image_request(image_request: &nsStyleImageRequest) -> Self {
|
||||
let url_value = image_request.mImageValue.to_safe();
|
||||
ComputedImageUrl(ComputedUrl::from_url_value(url_value))
|
||||
}
|
||||
|
||||
/// Clone a new, strong reference to the Gecko URLValue.
|
||||
pub fn clone_url_value(&self) -> RefPtr<URLValue> {
|
||||
self.0.clone_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.url_value_ptr()
|
||||
self.0.serialize_with(bindings::Gecko_GetComputedImageURLSpec, dest)
|
||||
}
|
||||
}
|
||||
|
||||
lazy_static! {
|
||||
/// A table mapping CssUrlData objects to their lazily created Gecko
|
||||
/// URLValue objects.
|
||||
static ref URL_VALUE_TABLE: RwLock<HashMap<CssUrlDataKey, RefPtr<URLValue>>> = {
|
||||
/// A table mapping CssUrlData objects to their lazily created LoadData
|
||||
/// objects.
|
||||
static ref LOAD_DATA_TABLE: RwLock<HashMap<LoadDataKey, Box<LoadData>>> = {
|
||||
Default::default()
|
||||
};
|
||||
}
|
||||
|
|
|
@ -63,15 +63,25 @@ impl<T: RefCounted> RefPtr<T> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Returns whether the current pointer is null.
|
||||
pub fn is_null(&self) -> bool {
|
||||
self.ptr.is_null()
|
||||
}
|
||||
|
||||
/// Returns a null pointer.
|
||||
pub fn null() -> Self {
|
||||
Self {
|
||||
ptr: ptr::null_mut(),
|
||||
_marker: PhantomData,
|
||||
}
|
||||
}
|
||||
|
||||
/// Create a new RefPtr from a pointer obtained from FFI.
|
||||
///
|
||||
/// The pointer must be valid and non null.
|
||||
///
|
||||
/// This method calls addref() internally
|
||||
pub unsafe fn new(ptr: *mut T) -> Self {
|
||||
debug_assert!(!ptr.is_null());
|
||||
let ret = RefPtr {
|
||||
ptr: ptr,
|
||||
ptr,
|
||||
_marker: PhantomData,
|
||||
};
|
||||
ret.addref();
|
||||
|
@ -97,8 +107,10 @@ impl<T: RefCounted> RefPtr<T> {
|
|||
|
||||
/// Addref the inner data, obviously leaky on its own.
|
||||
pub fn addref(&self) {
|
||||
unsafe {
|
||||
(*self.ptr).addref();
|
||||
if !self.ptr.is_null() {
|
||||
unsafe {
|
||||
(*self.ptr).addref();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -106,7 +118,9 @@ impl<T: RefCounted> RefPtr<T> {
|
|||
///
|
||||
/// Call only when the data actually needs releasing.
|
||||
pub unsafe fn release(&self) {
|
||||
(*self.ptr).release();
|
||||
if !self.ptr.is_null() {
|
||||
(*self.ptr).release();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -130,6 +144,7 @@ impl<T: RefCounted> UniqueRefPtr<T> {
|
|||
impl<T: RefCounted> Deref for RefPtr<T> {
|
||||
type Target = T;
|
||||
fn deref(&self) -> &T {
|
||||
debug_assert!(!self.ptr.is_null());
|
||||
unsafe { &*self.ptr }
|
||||
}
|
||||
}
|
||||
|
@ -152,7 +167,6 @@ impl<T: RefCounted> structs::RefPtr<T> {
|
|||
///
|
||||
/// Must be called on a valid, non-null structs::RefPtr<T>.
|
||||
pub unsafe fn to_safe(&self) -> RefPtr<T> {
|
||||
debug_assert!(!self.mRawPtr.is_null());
|
||||
let r = RefPtr {
|
||||
ptr: self.mRawPtr,
|
||||
_marker: PhantomData,
|
||||
|
@ -290,9 +304,9 @@ impl_threadsafe_refcount!(
|
|||
bindings::Gecko_ReleaseURLExtraDataArbitraryThread
|
||||
);
|
||||
impl_threadsafe_refcount!(
|
||||
structs::mozilla::css::URLValue,
|
||||
bindings::Gecko_AddRefCSSURLValueArbitraryThread,
|
||||
bindings::Gecko_ReleaseCSSURLValueArbitraryThread
|
||||
structs::nsIURI,
|
||||
bindings::Gecko_AddRefnsIURIArbitraryThread,
|
||||
bindings::Gecko_ReleasensIURIArbitraryThread
|
||||
);
|
||||
impl_threadsafe_refcount!(
|
||||
structs::mozilla::css::GridTemplateAreasValue,
|
||||
|
|
|
@ -278,7 +278,7 @@ impl ComputedValuesInner {
|
|||
|
||||
#[allow(non_snake_case)]
|
||||
pub fn has_moz_binding(&self) -> bool {
|
||||
!self.get_box().gecko.mBinding.mRawPtr.is_null()
|
||||
!self.get_box().gecko.mBinding.is_none()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -550,7 +550,7 @@ def set_gecko_property(ffi_name, expr):
|
|||
unsafe {
|
||||
bindings::Gecko_nsStyleSVGPaint_SetURLValue(
|
||||
paint,
|
||||
url.url_value_ptr(),
|
||||
&url
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -591,7 +591,6 @@ def set_gecko_property(ffi_name, expr):
|
|||
|
||||
#[allow(non_snake_case)]
|
||||
pub fn clone_${ident}(&self) -> longhands::${ident}::computed_value::T {
|
||||
use crate::values::computed::url::ComputedUrl;
|
||||
use crate::values::generics::svg::{SVGPaint, SVGPaintKind};
|
||||
use self::structs::nsStyleSVGPaintType;
|
||||
use self::structs::nsStyleSVGFallbackType;
|
||||
|
@ -613,8 +612,7 @@ def set_gecko_property(ffi_name, expr):
|
|||
nsStyleSVGPaintType::eStyleSVGPaintType_ContextStroke => SVGPaintKind::ContextStroke,
|
||||
nsStyleSVGPaintType::eStyleSVGPaintType_Server => {
|
||||
SVGPaintKind::PaintServer(unsafe {
|
||||
let url = RefPtr::new(*paint.mPaint.mPaintServer.as_ref());
|
||||
ComputedUrl::from_url_value(url)
|
||||
paint.mPaint.mPaintServer.as_ref().clone()
|
||||
})
|
||||
}
|
||||
nsStyleSVGPaintType::eStyleSVGPaintType_Color => {
|
||||
|
@ -735,45 +733,6 @@ def set_gecko_property(ffi_name, expr):
|
|||
}
|
||||
</%def>
|
||||
|
||||
<%def name="impl_css_url(ident, gecko_ffi_name)">
|
||||
#[allow(non_snake_case)]
|
||||
pub fn set_${ident}(&mut self, v: longhands::${ident}::computed_value::T) {
|
||||
match v {
|
||||
UrlOrNone::Url(ref url) => {
|
||||
self.gecko.${gecko_ffi_name}.set_move(url.clone_url_value())
|
||||
}
|
||||
UrlOrNone::None => {
|
||||
unsafe {
|
||||
self.gecko.${gecko_ffi_name}.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#[allow(non_snake_case)]
|
||||
pub fn copy_${ident}_from(&mut self, other: &Self) {
|
||||
unsafe {
|
||||
self.gecko.${gecko_ffi_name}.set(&other.gecko.${gecko_ffi_name});
|
||||
}
|
||||
}
|
||||
#[allow(non_snake_case)]
|
||||
pub fn reset_${ident}(&mut self, other: &Self) {
|
||||
self.copy_${ident}_from(other)
|
||||
}
|
||||
|
||||
#[allow(non_snake_case)]
|
||||
pub fn clone_${ident}(&self) -> longhands::${ident}::computed_value::T {
|
||||
use crate::values::computed::url::ComputedUrl;
|
||||
|
||||
if self.gecko.${gecko_ffi_name}.mRawPtr.is_null() {
|
||||
return UrlOrNone::none()
|
||||
}
|
||||
|
||||
UrlOrNone::Url(unsafe {
|
||||
ComputedUrl::from_url_value(self.gecko.${gecko_ffi_name}.to_safe())
|
||||
})
|
||||
}
|
||||
</%def>
|
||||
|
||||
<%def name="impl_logical(name, **kwargs)">
|
||||
${helpers.logical_setter(name)}
|
||||
</%def>
|
||||
|
@ -879,7 +838,6 @@ impl Clone for ${style_struct.gecko_struct_name} {
|
|||
"SVGOpacity": impl_svg_opacity,
|
||||
"SVGPaint": impl_svg_paint,
|
||||
"SVGWidth": impl_svg_length,
|
||||
"url::UrlOrNone": impl_css_url,
|
||||
}
|
||||
|
||||
def longhand_method(longhand):
|
||||
|
@ -2164,8 +2122,7 @@ fn static_assert() {
|
|||
animation-iteration-count animation-timing-function
|
||||
clear transition-duration transition-delay
|
||||
transition-timing-function transition-property
|
||||
transform-style -moz-binding shape-outside
|
||||
-webkit-line-clamp""" %>
|
||||
transform-style shape-outside -webkit-line-clamp""" %>
|
||||
<%self:impl_trait style_struct_name="Box" skip_longhands="${skip_box_longhands}">
|
||||
#[inline]
|
||||
pub fn set_display(&mut self, v: longhands::display::computed_value::T) {
|
||||
|
@ -2205,7 +2162,6 @@ fn static_assert() {
|
|||
gecko_inexhaustive=True,
|
||||
) %>
|
||||
${impl_keyword('clear', 'mBreakType', clear_keyword)}
|
||||
${impl_css_url('_moz_binding', 'mBinding')}
|
||||
${impl_transition_time_value('delay', 'Delay')}
|
||||
${impl_transition_time_value('duration', 'Duration')}
|
||||
${impl_transition_timing_function()}
|
||||
|
@ -2834,10 +2790,7 @@ fn static_assert() {
|
|||
}
|
||||
UrlOrNone::Url(ref url) => {
|
||||
unsafe {
|
||||
Gecko_SetListStyleImageImageValue(
|
||||
&mut *self.gecko,
|
||||
url.url_value_ptr(),
|
||||
);
|
||||
Gecko_SetListStyleImageImageValue(&mut *self.gecko, url);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3145,7 +3098,7 @@ fn static_assert() {
|
|||
},
|
||||
Url(ref url) => {
|
||||
unsafe {
|
||||
bindings::Gecko_nsStyleFilter_SetURLValue(gecko_filter, url.url_value_ptr());
|
||||
bindings::Gecko_nsStyleFilter_SetURLValue(gecko_filter, url);
|
||||
}
|
||||
},
|
||||
}
|
||||
|
@ -3164,7 +3117,6 @@ fn static_assert() {
|
|||
|
||||
pub fn clone_filter(&self) -> longhands::filter::computed_value::T {
|
||||
use crate::values::generics::effects::Filter;
|
||||
use crate::values::computed::url::ComputedUrl;
|
||||
use crate::gecko_bindings::structs::NS_STYLE_FILTER_BLUR;
|
||||
use crate::gecko_bindings::structs::NS_STYLE_FILTER_BRIGHTNESS;
|
||||
use crate::gecko_bindings::structs::NS_STYLE_FILTER_CONTRAST;
|
||||
|
@ -3205,8 +3157,7 @@ fn static_assert() {
|
|||
},
|
||||
NS_STYLE_FILTER_URL => {
|
||||
Filter::Url(unsafe {
|
||||
let url = RefPtr::new(*filter.__bindgen_anon_1.mURL.as_ref());
|
||||
ComputedUrl::from_url_value(url)
|
||||
filter.__bindgen_anon_1.mURL.as_ref().clone()
|
||||
})
|
||||
}
|
||||
_ => unreachable!("Unknown filter function?"),
|
||||
|
@ -3550,7 +3501,7 @@ clip-path
|
|||
unsafe {
|
||||
Gecko_SetCursorImageValue(
|
||||
&mut self.gecko.mCursorImages[i],
|
||||
v.images[i].url.url_value_ptr(),
|
||||
&v.images[i].url
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -3769,7 +3720,7 @@ clip-path
|
|||
unsafe {
|
||||
bindings::Gecko_SetContentDataImageValue(
|
||||
&mut self.gecko.mContents[i],
|
||||
url.url_value_ptr(),
|
||||
url,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -644,7 +644,6 @@ ${helpers.predefined_type(
|
|||
"basic_shape::FloatAreaShape",
|
||||
"generics::basic_shape::ShapeSource::None",
|
||||
products="gecko",
|
||||
boxed=True,
|
||||
animation_value_type="basic_shape::FloatAreaShape",
|
||||
flags="APPLIES_TO_FIRST_LETTER",
|
||||
spec="https://drafts.csswg.org/css-shapes/#shape-outside-property",
|
||||
|
|
|
@ -63,9 +63,15 @@ pub use self::stylesheet::{StylesheetContents, StylesheetInDocument, UserAgentSt
|
|||
pub use self::supports_rule::SupportsRule;
|
||||
pub use self::viewport_rule::ViewportRule;
|
||||
|
||||
/// Extra data that the backend may need to resolve url values.
|
||||
#[cfg(not(feature = "gecko"))]
|
||||
pub type UrlExtraData = ::servo_url::ServoUrl;
|
||||
/// The CORS mode used for a CSS load.
|
||||
#[repr(u8)]
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, ToShmem)]
|
||||
pub enum CorsMode {
|
||||
/// No CORS mode, so cross-origin loads can be done.
|
||||
None,
|
||||
/// Anonymous CORS request.
|
||||
Anonymous,
|
||||
}
|
||||
|
||||
/// Extra data that the backend may need to resolve url values.
|
||||
///
|
||||
|
@ -82,8 +88,13 @@ pub type UrlExtraData = ::servo_url::ServoUrl;
|
|||
/// `from_ptr_ref` can work.
|
||||
#[cfg(feature = "gecko")]
|
||||
#[derive(PartialEq)]
|
||||
#[repr(C)]
|
||||
pub struct UrlExtraData(usize);
|
||||
|
||||
/// Extra data that the backend may need to resolve url values.
|
||||
#[cfg(not(feature = "gecko"))]
|
||||
pub type UrlExtraData = ::servo_url::ServoUrl;
|
||||
|
||||
#[cfg(feature = "gecko")]
|
||||
impl Clone for UrlExtraData {
|
||||
fn clone(&self) -> UrlExtraData {
|
||||
|
|
|
@ -20,7 +20,7 @@ use crate::stylesheets::stylesheet::Namespaces;
|
|||
use crate::stylesheets::supports_rule::SupportsCondition;
|
||||
use crate::stylesheets::viewport_rule;
|
||||
use crate::stylesheets::{CssRule, CssRuleType, CssRules, RulesMutateError, StylesheetLoader};
|
||||
use crate::stylesheets::{DocumentRule, FontFeatureValuesRule, KeyframesRule, MediaRule};
|
||||
use crate::stylesheets::{CorsMode, DocumentRule, FontFeatureValuesRule, KeyframesRule, MediaRule};
|
||||
use crate::stylesheets::{NamespaceRule, PageRule, StyleRule, SupportsRule, ViewportRule};
|
||||
use crate::values::computed::font::FamilyName;
|
||||
use crate::values::{CssUrl, CustomIdent, KeyframesName};
|
||||
|
@ -197,7 +197,7 @@ impl<'a, 'i> AtRuleParser<'i> for TopLevelRuleParser<'a> {
|
|||
}
|
||||
|
||||
let url_string = input.expect_url_or_string()?.as_ref().to_owned();
|
||||
let url = CssUrl::parse_from_string(url_string, &self.context);
|
||||
let url = CssUrl::parse_from_string(url_string, &self.context, CorsMode::None);
|
||||
|
||||
let media = MediaList::parse(&self.context, input);
|
||||
let media = Arc::new(self.shared_lock.wrap(media));
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
//! Generic types for url properties.
|
||||
|
||||
/// An image url or none, used for example in list-style-image
|
||||
///
|
||||
/// cbindgen:derive-tagged-enum-copy-constructor=true
|
||||
#[derive(
|
||||
Animate,
|
||||
Clone,
|
||||
|
@ -21,16 +23,27 @@
|
|||
ToResolvedValue,
|
||||
ToShmem,
|
||||
)]
|
||||
pub enum UrlOrNone<Url> {
|
||||
#[repr(C, u8)]
|
||||
pub enum GenericUrlOrNone<U> {
|
||||
/// `none`
|
||||
None,
|
||||
/// `A URL`
|
||||
Url(Url),
|
||||
/// A URL.
|
||||
Url(U),
|
||||
}
|
||||
|
||||
pub use self::GenericUrlOrNone as UrlOrNone;
|
||||
|
||||
impl<Url> UrlOrNone<Url> {
|
||||
/// Initial "none" value for properties such as `list-style-image`
|
||||
pub fn none() -> Self {
|
||||
UrlOrNone::None
|
||||
}
|
||||
|
||||
/// Returns whether the value is `none`.
|
||||
pub fn is_none(&self) -> bool {
|
||||
match *self {
|
||||
UrlOrNone::None => true,
|
||||
UrlOrNone::Url(..) => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
//! Common handling for the specified value CSS url() values.
|
||||
|
||||
use crate::values::generics::url::UrlOrNone as GenericUrlOrNone;
|
||||
use crate::values::generics::url::GenericUrlOrNone;
|
||||
|
||||
#[cfg(feature = "gecko")]
|
||||
pub use crate::gecko::url::{SpecifiedImageUrl, SpecifiedUrl};
|
||||
|
|
|
@ -140,6 +140,9 @@ include = [
|
|||
"Scale",
|
||||
"Translate",
|
||||
"BorderImageWidth",
|
||||
"ComputedUrl",
|
||||
"ComputedImageUrl",
|
||||
"UrlOrNone",
|
||||
]
|
||||
item_types = ["enums", "structs", "typedefs", "functions"]
|
||||
renaming_overrides_prefixing = true
|
||||
|
@ -148,6 +151,7 @@ renaming_overrides_prefixing = true
|
|||
[export.rename]
|
||||
"nscolor" = "nscolor"
|
||||
"nsAtom" = "nsAtom"
|
||||
"nsIURI" = "nsIURI"
|
||||
"nsCompatibility" = "nsCompatibility"
|
||||
"SharedFontList" = "SharedFontList"
|
||||
"nsSimpleContentList" = "nsSimpleContentList"
|
||||
|
@ -390,6 +394,13 @@ renaming_overrides_prefixing = true
|
|||
}
|
||||
"""
|
||||
|
||||
"ArcInner" = """
|
||||
// Increase the reference count.
|
||||
inline void IncrementRef();
|
||||
// Release the reference count, and return whether the result must be freed or not.
|
||||
MOZ_MUST_USE inline bool DecrementRef();
|
||||
"""
|
||||
|
||||
"ArcSlice" = """
|
||||
inline StyleArcSlice();
|
||||
inline StyleArcSlice(const StyleArcSlice& aOther);
|
||||
|
@ -407,6 +418,33 @@ renaming_overrides_prefixing = true
|
|||
inline bool operator!=(const StyleArcSlice& other) const;
|
||||
"""
|
||||
|
||||
"Arc" = """
|
||||
StyleArc() = delete;
|
||||
inline StyleArc(const StyleArc& Other);
|
||||
private:
|
||||
inline void Release();
|
||||
public:
|
||||
inline ~StyleArc();
|
||||
|
||||
inline StyleArc& operator=(const StyleArc&);
|
||||
inline StyleArc& operator=(StyleArc&&);
|
||||
|
||||
const T* operator->() const {
|
||||
MOZ_DIAGNOSTIC_ASSERT(p, "Arc shouldn't be null");
|
||||
return &p->data;
|
||||
}
|
||||
const T& operator*() const {
|
||||
MOZ_DIAGNOSTIC_ASSERT(p, "Arc shouldn't be null");
|
||||
return p->data;
|
||||
}
|
||||
bool operator==(const StyleArc& other) const {
|
||||
return p == other.p || *(*this) == *other;
|
||||
}
|
||||
bool operator!=(const StyleArc& other) const {
|
||||
return !(*this == other);
|
||||
}
|
||||
"""
|
||||
|
||||
"CustomIdent" = """
|
||||
inline nsAtom* AsAtom() const;
|
||||
"""
|
||||
|
@ -441,6 +479,14 @@ renaming_overrides_prefixing = true
|
|||
public:
|
||||
"""
|
||||
|
||||
"GenericUrlOrNone" = """
|
||||
private:
|
||||
// Private default constructor without initialization so that the helper
|
||||
// constructor functions still work as expected. They take care of
|
||||
// initializing the fields properly.
|
||||
StyleGenericUrlOrNone() {}
|
||||
public:
|
||||
"""
|
||||
"Angle" = """
|
||||
inline static StyleAngle Zero();
|
||||
inline float ToDegrees() const;
|
||||
|
@ -471,3 +517,50 @@ renaming_overrides_prefixing = true
|
|||
second(StyleTextOverflowSide::Clip()),
|
||||
sides_are_logical(true) {}
|
||||
"""
|
||||
|
||||
"UrlExtraData" = """
|
||||
StyleUrlExtraData() = delete;
|
||||
|
||||
// Could be implemented if wanted.
|
||||
StyleUrlExtraData(const StyleUrlExtraData&) = delete;
|
||||
StyleUrlExtraData& operator=(const StyleUrlExtraData&) = delete;
|
||||
|
||||
inline bool IsShared() const;
|
||||
|
||||
inline ~StyleUrlExtraData();
|
||||
inline const URLExtraData& get() const;
|
||||
"""
|
||||
|
||||
"CssUrlData" = """
|
||||
// Implemented in nsStyleStruct.cpp
|
||||
bool operator==(const StyleCssUrlData& other) const;
|
||||
bool operator!=(const StyleCssUrlData& other) const {
|
||||
return !(*this == other);
|
||||
}
|
||||
"""
|
||||
|
||||
"LoadData" = """
|
||||
~StyleLoadData();
|
||||
"""
|
||||
|
||||
"CssUrl" = """
|
||||
inline nsDependentCSubstring SpecifiedSerialization() const;
|
||||
inline const URLExtraData& ExtraData() const;
|
||||
inline StyleLoadData& LoadData() const;
|
||||
inline nsIURI* GetURI() const;
|
||||
"""
|
||||
|
||||
"ComputedUrl" = """
|
||||
// Forwarded from CssUrl.
|
||||
inline nsDependentCSubstring SpecifiedSerialization() const;
|
||||
inline const URLExtraData& ExtraData() const;
|
||||
inline nsIURI* GetURI() const;
|
||||
inline StyleLoadData& LoadData() const;
|
||||
|
||||
inline bool IsLocalRef() const;
|
||||
inline bool HasRef() const;
|
||||
inline CORSMode CorsMode() const;
|
||||
already_AddRefed<nsIURI> ResolveLocalRef(nsIURI* aBase) const;
|
||||
already_AddRefed<nsIURI> ResolveLocalRef(const nsIContent* aContent) const;
|
||||
imgRequestProxy* LoadImage(mozilla::dom::Document&);
|
||||
"""
|
||||
|
|
|
@ -35,7 +35,7 @@ use style::gecko::data::{GeckoStyleSheet, PerDocumentStyleData, PerDocumentStyle
|
|||
use style::gecko::restyle_damage::GeckoRestyleDamage;
|
||||
use style::gecko::selector_parser::{NonTSPseudoClass, PseudoElement};
|
||||
use style::gecko::traversal::RecalcStyleOnly;
|
||||
use style::gecko::url::{self, CssUrlData};
|
||||
use style::gecko::url;
|
||||
use style::gecko::wrapper::{GeckoElement, GeckoNode};
|
||||
use style::gecko_bindings::bindings;
|
||||
use style::gecko_bindings::bindings::nsACString;
|
||||
|
@ -50,13 +50,12 @@ use style::gecko_bindings::bindings::Gecko_HaveSeenPtr;
|
|||
use style::gecko_bindings::structs;
|
||||
use style::gecko_bindings::structs::{Element as RawGeckoElement, nsINode as RawGeckoNode};
|
||||
use style::gecko_bindings::structs::{
|
||||
RawServoStyleSet, RawServoAuthorStyles,
|
||||
RawServoCssUrlData, RawServoDeclarationBlock, RawServoMediaList,
|
||||
RawServoCounterStyleRule, RawServoAnimationValue, RawServoSupportsRule,
|
||||
RawServoKeyframesRule, ServoCssRules, RawServoStyleSheetContents,
|
||||
RawServoPageRule, RawServoNamespaceRule, RawServoMozDocumentRule,
|
||||
RawServoKeyframe, RawServoMediaRule, RawServoImportRule,
|
||||
RawServoFontFaceRule, RawServoFontFeatureValuesRule,
|
||||
RawServoStyleSet, RawServoAuthorStyles, RawServoDeclarationBlock,
|
||||
RawServoMediaList, RawServoCounterStyleRule, RawServoAnimationValue,
|
||||
RawServoSupportsRule, RawServoKeyframesRule, ServoCssRules,
|
||||
RawServoStyleSheetContents, RawServoPageRule, RawServoNamespaceRule,
|
||||
RawServoMozDocumentRule, RawServoKeyframe, RawServoMediaRule,
|
||||
RawServoImportRule, RawServoFontFaceRule, RawServoFontFeatureValuesRule,
|
||||
RawServoSharedMemoryBuilder
|
||||
};
|
||||
use style::gecko_bindings::structs::gfxFontFeatureValueSet;
|
||||
|
@ -2786,7 +2785,7 @@ pub unsafe extern "C" fn Servo_FontFaceRule_GetSources(
|
|||
for source in sources.iter() {
|
||||
match *source {
|
||||
Source::Url(ref url) => {
|
||||
set_next(FontFaceSourceListComponent::Url(url.url.url_value_ptr()));
|
||||
set_next(FontFaceSourceListComponent::Url(&url.url));
|
||||
for hint in url.format_hints.iter() {
|
||||
set_next(FontFaceSourceListComponent::FormatHint {
|
||||
length: hint.len(),
|
||||
|
@ -6021,27 +6020,8 @@ pub extern "C" fn Servo_GetCustomPropertyNameAt(
|
|||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn Servo_CssUrlData_GetSerialization(
|
||||
url: &RawServoCssUrlData,
|
||||
utf8_chars: *mut *const u8,
|
||||
utf8_len: *mut u32,
|
||||
) {
|
||||
let url_data = CssUrlData::as_arc(&url);
|
||||
let string = url_data.as_str();
|
||||
*utf8_len = string.len() as u32;
|
||||
*utf8_chars = string.as_ptr();
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn Servo_CssUrlData_GetExtraData(
|
||||
url: &RawServoCssUrlData,
|
||||
) -> &mut URLExtraData {
|
||||
unsafe { &mut *CssUrlData::as_arc(&url).extra_data.ptr() }
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn Servo_CssUrlData_IsLocalRef(url: &RawServoCssUrlData) -> bool {
|
||||
CssUrlData::as_arc(&url).is_fragment()
|
||||
pub extern "C" fn Servo_CssUrl_IsLocalRef(url: &url::CssUrl) -> bool {
|
||||
url.is_fragment()
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
|
@ -6596,3 +6576,8 @@ pub unsafe extern "C" fn Servo_CloneBasicShape(v: &computed::basic_shape::BasicS
|
|||
pub unsafe extern "C" fn Servo_StyleArcSlice_EmptyPtr() -> *mut c_void {
|
||||
style_traits::arc_slice::ArcSlice::<u64>::leaked_empty_ptr()
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn Servo_LoadData_GetLazy(source: &url::LoadDataSource) -> *const url::LoadData {
|
||||
source.get()
|
||||
}
|
||||
|
|
|
@ -63,7 +63,7 @@ impl StyleStylesheetLoader for StylesheetLoader {
|
|||
self.1,
|
||||
self.2,
|
||||
self.3,
|
||||
url.0.clone().into_strong(),
|
||||
&url,
|
||||
media.into_strong(),
|
||||
)
|
||||
};
|
||||
|
@ -171,7 +171,7 @@ impl StyleStylesheetLoader for AsyncStylesheetParser {
|
|||
unsafe {
|
||||
bindings::Gecko_LoadStyleSheetAsync(
|
||||
self.load_data.get(),
|
||||
url.0.into_strong(),
|
||||
&url,
|
||||
media.into_strong(),
|
||||
rule.clone().into_strong(),
|
||||
);
|
||||
|
|
|
@ -62,18 +62,18 @@ size_of_test!(
|
|||
608
|
||||
);
|
||||
|
||||
size_of_test!(test_size_of_computed_image, computed::image::Image, 24);
|
||||
size_of_test!(test_size_of_specified_image, specified::image::Image, 24);
|
||||
size_of_test!(test_size_of_computed_image, computed::image::Image, 16);
|
||||
size_of_test!(test_size_of_specified_image, specified::image::Image, 16);
|
||||
|
||||
// FIXME(bz): These can shrink if we move the None_ value inside the
|
||||
// enum instead of paying an extra word for the Either discriminant.
|
||||
size_of_test!(
|
||||
test_size_of_computed_image_layer,
|
||||
computed::image::ImageLayer,
|
||||
24
|
||||
16
|
||||
);
|
||||
size_of_test!(
|
||||
test_size_of_specified_image_layer,
|
||||
specified::image::ImageLayer,
|
||||
24
|
||||
16
|
||||
);
|
||||
|
|
Загрузка…
Ссылка в новой задаче