diff --git a/components/style/gecko/arc_types.rs b/components/style/gecko/arc_types.rs index 7351cbfeac4f..66d96492bd19 100644 --- a/components/style/gecko/arc_types.rs +++ b/components/style/gecko/arc_types.rs @@ -8,6 +8,7 @@ #![allow(non_snake_case, missing_docs)] +use gecko::url::CssUrlData; use gecko_bindings::bindings::RawServoCounterStyleRule; use gecko_bindings::bindings::RawServoFontFeatureValuesRule; use gecko_bindings::bindings::RawServoImportRule; @@ -27,6 +28,7 @@ use gecko_bindings::structs::RawServoFontFaceRule; use gecko_bindings::structs::RawServoMediaList; use gecko_bindings::structs::RawServoStyleRule; use gecko_bindings::structs::RawServoStyleSheetContents; +use gecko_bindings::structs::RawServoCssUrlData; use gecko_bindings::sugar::ownership::{HasArcFFI, HasFFI, Strong}; use media_queries::MediaList; use properties::{ComputedValues, PropertyDeclarationBlock}; @@ -110,6 +112,9 @@ impl_arc_ffi!(Locked => RawServoFontFaceRule impl_arc_ffi!(Locked => RawServoCounterStyleRule [Servo_CounterStyleRule_AddRef, Servo_CounterStyleRule_Release]); +impl_arc_ffi!(CssUrlData => RawServoCssUrlData + [Servo_CssUrlData_AddRef, Servo_CssUrlData_Release]); + // RuleNode is a Arc-like type but it does not use Arc. impl StrongRuleNode { diff --git a/components/style/gecko/url.rs b/components/style/gecko/url.rs index 263fa674ce2b..cdcfc37dbccc 100644 --- a/components/style/gecko/url.rs +++ b/components/style/gecko/url.rs @@ -6,17 +6,16 @@ use cssparser::Parser; use gecko_bindings::bindings; -use gecko_bindings::structs::ServoBundledURI; -use gecko_bindings::structs::root::{RustString, nsStyleImageRequest}; +use gecko_bindings::structs::root::nsStyleImageRequest; use gecko_bindings::structs::root::mozilla::CORSMode; use gecko_bindings::structs::root::mozilla::css::URLValue; +use gecko_bindings::sugar::ownership::{HasArcFFI, FFIArcHelpers}; use gecko_bindings::sugar::refptr::RefPtr; use malloc_size_of::{MallocSizeOf, MallocSizeOfOps}; use nsstring::nsCString; use parser::{Parse, ParserContext}; -use servo_arc::{Arc, RawOffsetArc}; +use servo_arc::Arc; use std::fmt::{self, Write}; -use std::mem; use style_traits::{CssWriter, ParseError, ToCss}; use stylesheets::UrlExtraData; use values::computed::{Context, ToComputedValue}; @@ -24,12 +23,13 @@ use values::computed::{Context, ToComputedValue}; /// A CSS url() value for gecko. #[css(function = "url")] #[derive(Clone, Debug, PartialEq, SpecifiedValueInfo, ToCss)] -pub struct CssUrl { +pub struct CssUrl(pub Arc); + +/// Data shared between CssUrls. +#[derive(Clone, Debug, PartialEq, SpecifiedValueInfo, ToCss)] +pub struct CssUrlData { /// The URL in unresolved string form. - /// - /// Refcounted since cloning this should be cheap and data: uris can be - /// really large. - serialization: Arc, + serialization: String, /// The URL extra data. #[css(skip)] @@ -39,10 +39,10 @@ pub struct CssUrl { impl CssUrl { /// Parse a URL from a string value that is a valid CSS token for a URL. pub fn parse_from_string(url: String, context: &ParserContext) -> Self { - CssUrl { - serialization: Arc::new(url), + CssUrl(Arc::new(CssUrlData { + serialization: url, extra_data: context.url_data.clone(), - } + })) } /// Returns true if the URL is definitely invalid. We don't eagerly resolve @@ -52,15 +52,6 @@ impl CssUrl { false } - /// Convert from URLValue to CssUrl. - unsafe fn from_url_value(url: &URLValue) -> Self { - let arc_type = &url.mString as *const _ as *const RawOffsetArc; - CssUrl { - serialization: Arc::from_raw_offset((*arc_type).clone()), - extra_data: UrlExtraData(url.mExtraData.to_safe()), - } - } - /// Returns true if this URL looks like a fragment. /// See https://drafts.csswg.org/css-values/#local-urls pub fn is_fragment(&self) -> bool { @@ -69,26 +60,17 @@ impl CssUrl { /// Return the unresolved url as string, or the empty string if it's /// invalid. + #[inline] pub fn as_str(&self) -> &str { - &*self.serialization - } - - /// Little helper for Gecko's ffi. - pub fn as_slice_components(&self) -> (*const u8, usize) { - ( - self.serialization.as_str().as_ptr(), - self.serialization.as_str().len(), - ) + self.0.as_str() } +} - /// Create a bundled URI suitable for sending to Gecko - /// to be constructed into a css::URLValue - pub fn for_ffi(&self) -> ServoBundledURI { - let arc_offset = Arc::into_raw_offset(self.serialization.clone()); - ServoBundledURI { - mURLString: unsafe { mem::transmute::<_, RawOffsetArc>(arc_offset) }, - mExtraData: self.extra_data.0.get(), - } +impl CssUrlData { + /// Return the unresolved url as string, or the empty string if it's + /// invalid. + pub fn as_str(&self) -> &str { + &*self.serialization } } @@ -134,7 +116,11 @@ impl SpecifiedUrl { fn from_css_url_with_cors(url: CssUrl, cors: CORSMode) -> Self { let url_value = unsafe { - let ptr = bindings::Gecko_URLValue_Create(url.for_ffi(), cors); + let ptr = bindings::Gecko_URLValue_Create( + url.0.clone().into_strong(), + url.0.extra_data.0.get(), + cors, + ); // We do not expect Gecko_URLValue_Create returns null. debug_assert!(!ptr.is_null()); RefPtr::from_addrefed(ptr) @@ -280,7 +266,8 @@ impl ToCss for ComputedUrl { impl ComputedUrl { /// Convert from RefPtr to ComputedUrl. pub unsafe fn from_url_value(url_value: RefPtr) -> Self { - let url = CssUrl::from_url_value(&*url_value); + let css_url = &*url_value.mCssUrl.mRawPtr; + let url = CssUrl(CssUrlData::as_arc(&css_url).clone_arc()); ComputedUrl(SpecifiedUrl { url, url_value }) } @@ -311,7 +298,8 @@ 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(); - let url = CssUrl::from_url_value(&*url_value); + let css_url = &*url_value.mCssUrl.mRawPtr; + let url = CssUrl(CssUrlData::as_arc(&css_url).clone_arc()); ComputedImageUrl(SpecifiedImageUrl(SpecifiedUrl { url, url_value })) }