style: Make css::URLValue hold on to a CssUrlData, not just its serialization.

Differential Revision: https://phabricator.services.mozilla.com/D8874
This commit is contained in:
Cameron McCormack 2018-10-17 12:36:49 +00:00 committed by Emilio Cobos Álvarez
parent ecb9de4acd
commit c4491ea39d
No known key found for this signature in database
GPG key ID: 056B727BB9C1027C
2 changed files with 35 additions and 42 deletions

View file

@ -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<FontFaceRule> => RawServoFontFaceRule
impl_arc_ffi!(Locked<CounterStyleRule> => 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 {

View file

@ -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<CssUrlData>);
/// 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<String>,
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,44 +52,26 @@ 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<String>;
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 {
self.as_str().chars().next().map_or(false, |c| c == '#')
}
/// Return the unresolved url as string, or the empty string if it's
/// invalid.
#[inline]
pub fn as_str(&self) -> &str {
self.0.as_str()
}
}
impl CssUrlData {
/// Return the unresolved url as string, or the empty string if it's
/// invalid.
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(),
)
}
/// 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<RustString>>(arc_offset) },
mExtraData: self.extra_data.0.get(),
}
}
}
impl Parse for CssUrl {
@ -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<URLValue> to ComputedUrl.
pub unsafe fn from_url_value(url_value: RefPtr<URLValue>) -> 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 }))
}