servo: Merge #16092 - Handle URLs more efficiently in stylo (from bholley:specified_urls); r=emilio

Approved in https://bugzilla.mozilla.org/show_bug.cgi?id=1347435

Source-Repo: https://github.com/servo/servo
Source-Revision: d4d8293f22aaa4a310abc818c26464abceab894f

--HG--
extra : subtree_source : https%3A//hg.mozilla.org/projects/converted-servo-linear
extra : subtree_revision : 99b8281804061b321a791eb81530b652d5dba367
This commit is contained in:
Bobby Holley 2017-03-22 19:13:07 -07:00
parent 72f8a22761
commit 9595cb0a22
17 changed files with 647 additions and 672 deletions

View File

@ -429,7 +429,7 @@ impl LayoutElementHelpers for LayoutJS<Element> {
PropertyDeclaration::BackgroundImage(
background_image::SpecifiedValue(vec![
background_image::single_value::SpecifiedValue(Some(
specified::Image::for_cascade(url.into(), specified::url::UrlExtraData { })
specified::Image::for_cascade(url.into())
))
]))));
}

View File

@ -353,6 +353,7 @@ mod bindings {
"nsCursorImage",
"nsFont",
"nsIAtom",
"nsIURI",
"nsMainThreadPtrHandle",
"nsMainThreadPtrHolder",
"nsMargin",
@ -613,6 +614,7 @@ mod bindings {
"nsCursorImage",
"nsFont",
"nsIAtom",
"nsIURI",
"nsMediaFeature",
"nsRestyleHint",
"nsStyleBackground",

View File

@ -17,5 +17,6 @@ pub mod selector_parser;
pub mod snapshot;
pub mod snapshot_helpers;
pub mod traversal;
pub mod url;
pub mod values;
pub mod wrapper;

View File

@ -0,0 +1,104 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
//! Common handling for the specified value CSS url() values.
use cssparser::CssStringWriter;
use gecko_bindings::structs::ServoBundledURI;
use gecko_bindings::sugar::refptr::{GeckoArcPrincipal, GeckoArcURI};
use parser::ParserContext;
use std::borrow::Cow;
use std::fmt::{self, Write};
use std::sync::Arc;
use style_traits::ToCss;
/// A specified url() value for gecko. Gecko does not eagerly resolve SpecifiedUrls.
#[derive(Clone, Debug, PartialEq)]
pub struct SpecifiedUrl {
/// The URL in unresolved string form.
///
/// Refcounted since cloning this should be cheap and data: uris can be
/// really large.
serialization: Arc<String>,
/// The base URI.
pub base: GeckoArcURI,
/// The referrer.
pub referrer: GeckoArcURI,
/// The principal that originated this URI.
pub principal: GeckoArcPrincipal,
}
impl SpecifiedUrl {
/// Try to parse a URL from a string value that is a valid CSS token for a
/// URL.
///
/// Returns `Err` in the case that extra_data is incomplete.
pub fn parse_from_string<'a>(url: Cow<'a, str>,
context: &ParserContext)
-> Result<Self, ()> {
let extra = &context.extra_data;
if extra.base.is_none() || extra.referrer.is_none() || extra.principal.is_none() {
// FIXME(heycam) should ensure we always have a principal, etc.,
// when parsing style attributes and re-parsing due to CSS
// Variables.
warn!("stylo: skipping declaration without ParserContextExtraData");
return Err(())
}
Ok(SpecifiedUrl {
serialization: Arc::new(url.into_owned()),
base: extra.base.as_ref().unwrap().clone(),
referrer: extra.referrer.as_ref().unwrap().clone(),
principal: extra.principal.as_ref().unwrap().clone(),
})
}
/// Returns true if the URL is definitely invalid. We don't eagerly resolve
/// URLs in gecko, so we just return false here.
/// use its |resolved| status.
pub fn is_invalid(&self) -> bool {
false
}
/// 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 resolved url as string, or the empty string if it's invalid.
///
/// FIXME(bholley): This returns the unresolved URL while the servo version
/// returns the resolved URL.
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 (ptr, len) = self.as_slice_components();
ServoBundledURI {
mURLString: ptr,
mURLStringLength: len as u32,
mBaseURI: self.base.get(),
mReferrer: self.referrer.get(),
mPrincipal: self.principal.get(),
}
}
}
impl ToCss for SpecifiedUrl {
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
try!(dest.write_str("url(\""));
try!(CssStringWriter::new(dest).write_str(&*self.serialization));
dest.write_str("\")")
}
}

View File

@ -40,6 +40,7 @@ use gecko_bindings::structs::nsChangeHint;
use gecko_bindings::structs::nsCursorImage;
use gecko_bindings::structs::nsFont;
use gecko_bindings::structs::nsIAtom;
use gecko_bindings::structs::nsIURI;
use gecko_bindings::structs::nsMediaFeature;
use gecko_bindings::structs::nsRestyleHint;
use gecko_bindings::structs::nsStyleBackground;
@ -437,8 +438,9 @@ extern "C" {
pub fn Gecko_LoadStyleSheet(loader: *mut Loader,
parent: *mut ServoStyleSheet,
import_rule: RawServoImportRuleBorrowed,
url_bytes: *const u8, url_length: u32,
media_bytes: *const u8, media_length: u32);
base_uri: *mut nsIURI, url_bytes: *const u8,
url_length: u32, media_bytes: *const u8,
media_length: u32);
}
extern "C" {
pub fn Gecko_MaybeCreateStyleChildrenIterator(node: RawGeckoNodeBorrowed)

View File

@ -8357,12 +8357,7 @@ pub mod root {
}
pub type pair_first_type<_T1> = _T1;
pub type pair_second_type<_T2> = _T2;
#[repr(C)]
pub struct atomic<_Tp> {
pub _base: (),
pub _phantom_0: ::std::marker::PhantomData<_Tp>,
}
pub type atomic___base = [u8; 0usize];
pub type pair__PCCP = [u8; 0usize];
#[repr(C)]
#[derive(Debug, Copy)]
pub struct input_iterator_tag {
@ -8382,62 +8377,6 @@ pub mod root {
fn clone(&self) -> Self { *self }
}
#[repr(C)]
#[derive(Debug, Copy)]
pub struct forward_iterator_tag {
pub _address: u8,
}
#[test]
fn bindgen_test_layout_forward_iterator_tag() {
assert_eq!(::std::mem::size_of::<forward_iterator_tag>() , 1usize
, concat ! (
"Size of: " , stringify ! ( forward_iterator_tag ) ));
assert_eq! (::std::mem::align_of::<forward_iterator_tag>() ,
1usize , concat ! (
"Alignment of " , stringify ! ( forward_iterator_tag )
));
}
impl Clone for forward_iterator_tag {
fn clone(&self) -> Self { *self }
}
#[repr(C)]
#[derive(Debug, Copy)]
pub struct bidirectional_iterator_tag {
pub _address: u8,
}
#[test]
fn bindgen_test_layout_bidirectional_iterator_tag() {
assert_eq!(::std::mem::size_of::<bidirectional_iterator_tag>() ,
1usize , concat ! (
"Size of: " , stringify ! ( bidirectional_iterator_tag
) ));
assert_eq! (::std::mem::align_of::<bidirectional_iterator_tag>() ,
1usize , concat ! (
"Alignment of " , stringify ! (
bidirectional_iterator_tag ) ));
}
impl Clone for bidirectional_iterator_tag {
fn clone(&self) -> Self { *self }
}
#[repr(C)]
#[derive(Debug, Copy)]
pub struct random_access_iterator_tag {
pub _address: u8,
}
#[test]
fn bindgen_test_layout_random_access_iterator_tag() {
assert_eq!(::std::mem::size_of::<random_access_iterator_tag>() ,
1usize , concat ! (
"Size of: " , stringify ! ( random_access_iterator_tag
) ));
assert_eq! (::std::mem::align_of::<random_access_iterator_tag>() ,
1usize , concat ! (
"Alignment of " , stringify ! (
random_access_iterator_tag ) ));
}
impl Clone for random_access_iterator_tag {
fn clone(&self) -> Self { *self }
}
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct iterator<_Category, _Tp, _Distance, _Pointer, _Reference> {
pub _address: u8,
@ -8447,209 +8386,250 @@ pub mod root {
pub _phantom_3: ::std::marker::PhantomData<_Pointer>,
pub _phantom_4: ::std::marker::PhantomData<_Reference>,
}
pub type iterator_iterator_category<_Category> = _Category;
pub type iterator_value_type<_Tp> = _Tp;
pub type iterator_difference_type<_Distance> = _Distance;
pub type iterator_pointer<_Pointer> = _Pointer;
pub type iterator_reference<_Reference> = _Reference;
pub type iterator_iterator_category<_Category> = _Category;
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct __bit_const_reference<_Cp> {
pub __seg_: root::std::__bit_const_reference___storage_pointer<_Cp>,
pub __mask_: root::std::__bit_const_reference___storage_type<_Cp>,
#[derive(Debug)]
pub struct atomic<_Tp> {
pub _M_i: _Tp,
}
pub mod chrono {
#[allow(unused_imports)]
use self::super::super::super::root;
}
pub type __bit_const_reference___storage_type<_Cp> = _Cp;
pub type __bit_const_reference___storage_pointer<_Cp> = _Cp;
}
pub type __int64_t = ::std::os::raw::c_longlong;
pub type __darwin_va_list = root::__builtin_va_list;
pub type __darwin_off_t = root::__int64_t;
pub type va_list = root::__darwin_va_list;
pub type fpos_t = root::__darwin_off_t;
pub mod __gnu_cxx {
#[allow(unused_imports)]
use self::super::super::root;
}
pub type __off_t = ::std::os::raw::c_long;
pub type __off64_t = ::std::os::raw::c_long;
#[repr(C)]
#[derive(Debug, Copy)]
pub struct __sbuf {
pub _base: *mut ::std::os::raw::c_uchar,
pub _size: ::std::os::raw::c_int,
pub struct _IO_FILE {
pub _flags: ::std::os::raw::c_int,
pub _IO_read_ptr: *mut ::std::os::raw::c_char,
pub _IO_read_end: *mut ::std::os::raw::c_char,
pub _IO_read_base: *mut ::std::os::raw::c_char,
pub _IO_write_base: *mut ::std::os::raw::c_char,
pub _IO_write_ptr: *mut ::std::os::raw::c_char,
pub _IO_write_end: *mut ::std::os::raw::c_char,
pub _IO_buf_base: *mut ::std::os::raw::c_char,
pub _IO_buf_end: *mut ::std::os::raw::c_char,
pub _IO_save_base: *mut ::std::os::raw::c_char,
pub _IO_backup_base: *mut ::std::os::raw::c_char,
pub _IO_save_end: *mut ::std::os::raw::c_char,
pub _markers: *mut root::_IO_marker,
pub _chain: *mut root::_IO_FILE,
pub _fileno: ::std::os::raw::c_int,
pub _flags2: ::std::os::raw::c_int,
pub _old_offset: root::__off_t,
pub _cur_column: ::std::os::raw::c_ushort,
pub _vtable_offset: ::std::os::raw::c_char,
pub _shortbuf: [::std::os::raw::c_char; 1usize],
pub _lock: *mut root::_IO_lock_t,
pub _offset: root::__off64_t,
pub __pad1: *mut ::std::os::raw::c_void,
pub __pad2: *mut ::std::os::raw::c_void,
pub __pad3: *mut ::std::os::raw::c_void,
pub __pad4: *mut ::std::os::raw::c_void,
pub __pad5: usize,
pub _mode: ::std::os::raw::c_int,
pub _unused2: [::std::os::raw::c_char; 20usize],
}
#[test]
fn bindgen_test_layout___sbuf() {
assert_eq!(::std::mem::size_of::<__sbuf>() , 16usize , concat ! (
"Size of: " , stringify ! ( __sbuf ) ));
assert_eq! (::std::mem::align_of::<__sbuf>() , 8usize , concat ! (
"Alignment of " , stringify ! ( __sbuf ) ));
fn bindgen_test_layout__IO_FILE() {
assert_eq!(::std::mem::size_of::<_IO_FILE>() , 216usize , concat ! (
"Size of: " , stringify ! ( _IO_FILE ) ));
assert_eq! (::std::mem::align_of::<_IO_FILE>() , 8usize , concat ! (
"Alignment of " , stringify ! ( _IO_FILE ) ));
assert_eq! (unsafe {
& ( * ( 0 as * const __sbuf ) ) . _base as * const _ as
& ( * ( 0 as * const _IO_FILE ) ) . _flags as * const _ as
usize } , 0usize , concat ! (
"Alignment of field: " , stringify ! ( __sbuf ) , "::" ,
stringify ! ( _base ) ));
assert_eq! (unsafe {
& ( * ( 0 as * const __sbuf ) ) . _size as * const _ as
usize } , 8usize , concat ! (
"Alignment of field: " , stringify ! ( __sbuf ) , "::" ,
stringify ! ( _size ) ));
}
impl Clone for __sbuf {
fn clone(&self) -> Self { *self }
}
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct __sFILEX([u8; 0]);
#[repr(C)]
#[derive(Debug, Copy)]
pub struct __sFILE {
pub _p: *mut ::std::os::raw::c_uchar,
pub _r: ::std::os::raw::c_int,
pub _w: ::std::os::raw::c_int,
pub _flags: ::std::os::raw::c_short,
pub _file: ::std::os::raw::c_short,
pub _bf: root::__sbuf,
pub _lbfsize: ::std::os::raw::c_int,
pub _cookie: *mut ::std::os::raw::c_void,
pub _close: ::std::option::Option<unsafe extern "C" fn(arg1:
*mut ::std::os::raw::c_void)
-> ::std::os::raw::c_int>,
pub _read: ::std::option::Option<unsafe extern "C" fn(arg1:
*mut ::std::os::raw::c_void,
arg2:
*mut ::std::os::raw::c_char,
arg3:
::std::os::raw::c_int)
-> ::std::os::raw::c_int>,
pub _seek: ::std::option::Option<unsafe extern "C" fn(arg1:
*mut ::std::os::raw::c_void,
arg2:
root::fpos_t,
arg3:
::std::os::raw::c_int)
-> ::std::os::raw::c_longlong>,
pub _write: ::std::option::Option<unsafe extern "C" fn(arg1:
*mut ::std::os::raw::c_void,
arg2:
*const ::std::os::raw::c_char,
arg3:
::std::os::raw::c_int)
-> ::std::os::raw::c_int>,
pub _ub: root::__sbuf,
pub _extra: *mut root::__sFILEX,
pub _ur: ::std::os::raw::c_int,
pub _ubuf: [::std::os::raw::c_uchar; 3usize],
pub _nbuf: [::std::os::raw::c_uchar; 1usize],
pub _lb: root::__sbuf,
pub _blksize: ::std::os::raw::c_int,
pub _offset: root::fpos_t,
}
#[test]
fn bindgen_test_layout___sFILE() {
assert_eq!(::std::mem::size_of::<__sFILE>() , 152usize , concat ! (
"Size of: " , stringify ! ( __sFILE ) ));
assert_eq! (::std::mem::align_of::<__sFILE>() , 8usize , concat ! (
"Alignment of " , stringify ! ( __sFILE ) ));
assert_eq! (unsafe {
& ( * ( 0 as * const __sFILE ) ) . _p as * const _ as
usize } , 0usize , concat ! (
"Alignment of field: " , stringify ! ( __sFILE ) , "::" ,
stringify ! ( _p ) ));
assert_eq! (unsafe {
& ( * ( 0 as * const __sFILE ) ) . _r as * const _ as
usize } , 8usize , concat ! (
"Alignment of field: " , stringify ! ( __sFILE ) , "::" ,
stringify ! ( _r ) ));
assert_eq! (unsafe {
& ( * ( 0 as * const __sFILE ) ) . _w as * const _ as
usize } , 12usize , concat ! (
"Alignment of field: " , stringify ! ( __sFILE ) , "::" ,
stringify ! ( _w ) ));
assert_eq! (unsafe {
& ( * ( 0 as * const __sFILE ) ) . _flags as * const _ as
usize } , 16usize , concat ! (
"Alignment of field: " , stringify ! ( __sFILE ) , "::" ,
"Alignment of field: " , stringify ! ( _IO_FILE ) , "::" ,
stringify ! ( _flags ) ));
assert_eq! (unsafe {
& ( * ( 0 as * const __sFILE ) ) . _file as * const _ as
usize } , 18usize , concat ! (
"Alignment of field: " , stringify ! ( __sFILE ) , "::" ,
stringify ! ( _file ) ));
& ( * ( 0 as * const _IO_FILE ) ) . _IO_read_ptr as *
const _ as usize } , 8usize , concat ! (
"Alignment of field: " , stringify ! ( _IO_FILE ) , "::" ,
stringify ! ( _IO_read_ptr ) ));
assert_eq! (unsafe {
& ( * ( 0 as * const __sFILE ) ) . _bf as * const _ as
usize } , 24usize , concat ! (
"Alignment of field: " , stringify ! ( __sFILE ) , "::" ,
stringify ! ( _bf ) ));
& ( * ( 0 as * const _IO_FILE ) ) . _IO_read_end as *
const _ as usize } , 16usize , concat ! (
"Alignment of field: " , stringify ! ( _IO_FILE ) , "::" ,
stringify ! ( _IO_read_end ) ));
assert_eq! (unsafe {
& ( * ( 0 as * const __sFILE ) ) . _lbfsize as * const _
as usize } , 40usize , concat ! (
"Alignment of field: " , stringify ! ( __sFILE ) , "::" ,
stringify ! ( _lbfsize ) ));
& ( * ( 0 as * const _IO_FILE ) ) . _IO_read_base as *
const _ as usize } , 24usize , concat ! (
"Alignment of field: " , stringify ! ( _IO_FILE ) , "::" ,
stringify ! ( _IO_read_base ) ));
assert_eq! (unsafe {
& ( * ( 0 as * const __sFILE ) ) . _cookie as * const _ as
usize } , 48usize , concat ! (
"Alignment of field: " , stringify ! ( __sFILE ) , "::" ,
stringify ! ( _cookie ) ));
& ( * ( 0 as * const _IO_FILE ) ) . _IO_write_base as *
const _ as usize } , 32usize , concat ! (
"Alignment of field: " , stringify ! ( _IO_FILE ) , "::" ,
stringify ! ( _IO_write_base ) ));
assert_eq! (unsafe {
& ( * ( 0 as * const __sFILE ) ) . _close as * const _ as
usize } , 56usize , concat ! (
"Alignment of field: " , stringify ! ( __sFILE ) , "::" ,
stringify ! ( _close ) ));
& ( * ( 0 as * const _IO_FILE ) ) . _IO_write_ptr as *
const _ as usize } , 40usize , concat ! (
"Alignment of field: " , stringify ! ( _IO_FILE ) , "::" ,
stringify ! ( _IO_write_ptr ) ));
assert_eq! (unsafe {
& ( * ( 0 as * const __sFILE ) ) . _read as * const _ as
usize } , 64usize , concat ! (
"Alignment of field: " , stringify ! ( __sFILE ) , "::" ,
stringify ! ( _read ) ));
& ( * ( 0 as * const _IO_FILE ) ) . _IO_write_end as *
const _ as usize } , 48usize , concat ! (
"Alignment of field: " , stringify ! ( _IO_FILE ) , "::" ,
stringify ! ( _IO_write_end ) ));
assert_eq! (unsafe {
& ( * ( 0 as * const __sFILE ) ) . _seek as * const _ as
usize } , 72usize , concat ! (
"Alignment of field: " , stringify ! ( __sFILE ) , "::" ,
stringify ! ( _seek ) ));
& ( * ( 0 as * const _IO_FILE ) ) . _IO_buf_base as *
const _ as usize } , 56usize , concat ! (
"Alignment of field: " , stringify ! ( _IO_FILE ) , "::" ,
stringify ! ( _IO_buf_base ) ));
assert_eq! (unsafe {
& ( * ( 0 as * const __sFILE ) ) . _write as * const _ as
usize } , 80usize , concat ! (
"Alignment of field: " , stringify ! ( __sFILE ) , "::" ,
stringify ! ( _write ) ));
& ( * ( 0 as * const _IO_FILE ) ) . _IO_buf_end as * const
_ as usize } , 64usize , concat ! (
"Alignment of field: " , stringify ! ( _IO_FILE ) , "::" ,
stringify ! ( _IO_buf_end ) ));
assert_eq! (unsafe {
& ( * ( 0 as * const __sFILE ) ) . _ub as * const _ as
usize } , 88usize , concat ! (
"Alignment of field: " , stringify ! ( __sFILE ) , "::" ,
stringify ! ( _ub ) ));
& ( * ( 0 as * const _IO_FILE ) ) . _IO_save_base as *
const _ as usize } , 72usize , concat ! (
"Alignment of field: " , stringify ! ( _IO_FILE ) , "::" ,
stringify ! ( _IO_save_base ) ));
assert_eq! (unsafe {
& ( * ( 0 as * const __sFILE ) ) . _extra as * const _ as
& ( * ( 0 as * const _IO_FILE ) ) . _IO_backup_base as *
const _ as usize } , 80usize , concat ! (
"Alignment of field: " , stringify ! ( _IO_FILE ) , "::" ,
stringify ! ( _IO_backup_base ) ));
assert_eq! (unsafe {
& ( * ( 0 as * const _IO_FILE ) ) . _IO_save_end as *
const _ as usize } , 88usize , concat ! (
"Alignment of field: " , stringify ! ( _IO_FILE ) , "::" ,
stringify ! ( _IO_save_end ) ));
assert_eq! (unsafe {
& ( * ( 0 as * const _IO_FILE ) ) . _markers as * const _
as usize } , 96usize , concat ! (
"Alignment of field: " , stringify ! ( _IO_FILE ) , "::" ,
stringify ! ( _markers ) ));
assert_eq! (unsafe {
& ( * ( 0 as * const _IO_FILE ) ) . _chain as * const _ as
usize } , 104usize , concat ! (
"Alignment of field: " , stringify ! ( __sFILE ) , "::" ,
stringify ! ( _extra ) ));
"Alignment of field: " , stringify ! ( _IO_FILE ) , "::" ,
stringify ! ( _chain ) ));
assert_eq! (unsafe {
& ( * ( 0 as * const __sFILE ) ) . _ur as * const _ as
usize } , 112usize , concat ! (
"Alignment of field: " , stringify ! ( __sFILE ) , "::" ,
stringify ! ( _ur ) ));
& ( * ( 0 as * const _IO_FILE ) ) . _fileno as * const _
as usize } , 112usize , concat ! (
"Alignment of field: " , stringify ! ( _IO_FILE ) , "::" ,
stringify ! ( _fileno ) ));
assert_eq! (unsafe {
& ( * ( 0 as * const __sFILE ) ) . _ubuf as * const _ as
usize } , 116usize , concat ! (
"Alignment of field: " , stringify ! ( __sFILE ) , "::" ,
stringify ! ( _ubuf ) ));
& ( * ( 0 as * const _IO_FILE ) ) . _flags2 as * const _
as usize } , 116usize , concat ! (
"Alignment of field: " , stringify ! ( _IO_FILE ) , "::" ,
stringify ! ( _flags2 ) ));
assert_eq! (unsafe {
& ( * ( 0 as * const __sFILE ) ) . _nbuf as * const _ as
usize } , 119usize , concat ! (
"Alignment of field: " , stringify ! ( __sFILE ) , "::" ,
stringify ! ( _nbuf ) ));
& ( * ( 0 as * const _IO_FILE ) ) . _old_offset as * const
_ as usize } , 120usize , concat ! (
"Alignment of field: " , stringify ! ( _IO_FILE ) , "::" ,
stringify ! ( _old_offset ) ));
assert_eq! (unsafe {
& ( * ( 0 as * const __sFILE ) ) . _lb as * const _ as
usize } , 120usize , concat ! (
"Alignment of field: " , stringify ! ( __sFILE ) , "::" ,
stringify ! ( _lb ) ));
& ( * ( 0 as * const _IO_FILE ) ) . _cur_column as * const
_ as usize } , 128usize , concat ! (
"Alignment of field: " , stringify ! ( _IO_FILE ) , "::" ,
stringify ! ( _cur_column ) ));
assert_eq! (unsafe {
& ( * ( 0 as * const __sFILE ) ) . _blksize as * const _
as usize } , 136usize , concat ! (
"Alignment of field: " , stringify ! ( __sFILE ) , "::" ,
stringify ! ( _blksize ) ));
& ( * ( 0 as * const _IO_FILE ) ) . _vtable_offset as *
const _ as usize } , 130usize , concat ! (
"Alignment of field: " , stringify ! ( _IO_FILE ) , "::" ,
stringify ! ( _vtable_offset ) ));
assert_eq! (unsafe {
& ( * ( 0 as * const __sFILE ) ) . _offset as * const _ as
usize } , 144usize , concat ! (
"Alignment of field: " , stringify ! ( __sFILE ) , "::" ,
& ( * ( 0 as * const _IO_FILE ) ) . _shortbuf as * const _
as usize } , 131usize , concat ! (
"Alignment of field: " , stringify ! ( _IO_FILE ) , "::" ,
stringify ! ( _shortbuf ) ));
assert_eq! (unsafe {
& ( * ( 0 as * const _IO_FILE ) ) . _lock as * const _ as
usize } , 136usize , concat ! (
"Alignment of field: " , stringify ! ( _IO_FILE ) , "::" ,
stringify ! ( _lock ) ));
assert_eq! (unsafe {
& ( * ( 0 as * const _IO_FILE ) ) . _offset as * const _
as usize } , 144usize , concat ! (
"Alignment of field: " , stringify ! ( _IO_FILE ) , "::" ,
stringify ! ( _offset ) ));
assert_eq! (unsafe {
& ( * ( 0 as * const _IO_FILE ) ) . __pad1 as * const _ as
usize } , 152usize , concat ! (
"Alignment of field: " , stringify ! ( _IO_FILE ) , "::" ,
stringify ! ( __pad1 ) ));
assert_eq! (unsafe {
& ( * ( 0 as * const _IO_FILE ) ) . __pad2 as * const _ as
usize } , 160usize , concat ! (
"Alignment of field: " , stringify ! ( _IO_FILE ) , "::" ,
stringify ! ( __pad2 ) ));
assert_eq! (unsafe {
& ( * ( 0 as * const _IO_FILE ) ) . __pad3 as * const _ as
usize } , 168usize , concat ! (
"Alignment of field: " , stringify ! ( _IO_FILE ) , "::" ,
stringify ! ( __pad3 ) ));
assert_eq! (unsafe {
& ( * ( 0 as * const _IO_FILE ) ) . __pad4 as * const _ as
usize } , 176usize , concat ! (
"Alignment of field: " , stringify ! ( _IO_FILE ) , "::" ,
stringify ! ( __pad4 ) ));
assert_eq! (unsafe {
& ( * ( 0 as * const _IO_FILE ) ) . __pad5 as * const _ as
usize } , 184usize , concat ! (
"Alignment of field: " , stringify ! ( _IO_FILE ) , "::" ,
stringify ! ( __pad5 ) ));
assert_eq! (unsafe {
& ( * ( 0 as * const _IO_FILE ) ) . _mode as * const _ as
usize } , 192usize , concat ! (
"Alignment of field: " , stringify ! ( _IO_FILE ) , "::" ,
stringify ! ( _mode ) ));
assert_eq! (unsafe {
& ( * ( 0 as * const _IO_FILE ) ) . _unused2 as * const _
as usize } , 196usize , concat ! (
"Alignment of field: " , stringify ! ( _IO_FILE ) , "::" ,
stringify ! ( _unused2 ) ));
}
impl Clone for __sFILE {
impl Clone for _IO_FILE {
fn clone(&self) -> Self { *self }
}
pub type FILE = root::_IO_FILE;
pub type va_list = root::__builtin_va_list;
pub type _IO_lock_t = ::std::os::raw::c_void;
#[repr(C)]
#[derive(Debug, Copy)]
pub struct _IO_marker {
pub _next: *mut root::_IO_marker,
pub _sbuf: *mut root::_IO_FILE,
pub _pos: ::std::os::raw::c_int,
}
#[test]
fn bindgen_test_layout__IO_marker() {
assert_eq!(::std::mem::size_of::<_IO_marker>() , 24usize , concat ! (
"Size of: " , stringify ! ( _IO_marker ) ));
assert_eq! (::std::mem::align_of::<_IO_marker>() , 8usize , concat ! (
"Alignment of " , stringify ! ( _IO_marker ) ));
assert_eq! (unsafe {
& ( * ( 0 as * const _IO_marker ) ) . _next as * const _
as usize } , 0usize , concat ! (
"Alignment of field: " , stringify ! ( _IO_marker ) , "::"
, stringify ! ( _next ) ));
assert_eq! (unsafe {
& ( * ( 0 as * const _IO_marker ) ) . _sbuf as * const _
as usize } , 8usize , concat ! (
"Alignment of field: " , stringify ! ( _IO_marker ) , "::"
, stringify ! ( _sbuf ) ));
assert_eq! (unsafe {
& ( * ( 0 as * const _IO_marker ) ) . _pos as * const _ as
usize } , 16usize , concat ! (
"Alignment of field: " , stringify ! ( _IO_marker ) , "::"
, stringify ! ( _pos ) ));
}
impl Clone for _IO_marker {
fn clone(&self) -> Self { *self }
}
pub type FILE = root::__sFILE;
/**
* MozRefCountType is Mozilla's reference count type.
*
@ -15664,63 +15644,63 @@ pub mod root {
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct nsDOMMutationObserver([u8; 0]);
pub const NODE_HAS_LISTENERMANAGER: root::_bindgen_ty_28 =
_bindgen_ty_28::NODE_HAS_LISTENERMANAGER;
pub const NODE_HAS_PROPERTIES: root::_bindgen_ty_28 =
_bindgen_ty_28::NODE_HAS_PROPERTIES;
pub const NODE_IS_ANONYMOUS_ROOT: root::_bindgen_ty_28 =
_bindgen_ty_28::NODE_IS_ANONYMOUS_ROOT;
pub const NODE_IS_IN_NATIVE_ANONYMOUS_SUBTREE: root::_bindgen_ty_28 =
_bindgen_ty_28::NODE_IS_IN_NATIVE_ANONYMOUS_SUBTREE;
pub const NODE_IS_NATIVE_ANONYMOUS_ROOT: root::_bindgen_ty_28 =
_bindgen_ty_28::NODE_IS_NATIVE_ANONYMOUS_ROOT;
pub const NODE_FORCE_XBL_BINDINGS: root::_bindgen_ty_28 =
_bindgen_ty_28::NODE_FORCE_XBL_BINDINGS;
pub const NODE_MAY_BE_IN_BINDING_MNGR: root::_bindgen_ty_28 =
_bindgen_ty_28::NODE_MAY_BE_IN_BINDING_MNGR;
pub const NODE_IS_EDITABLE: root::_bindgen_ty_28 =
_bindgen_ty_28::NODE_IS_EDITABLE;
pub const NODE_IS_NATIVE_ANONYMOUS: root::_bindgen_ty_28 =
_bindgen_ty_28::NODE_IS_NATIVE_ANONYMOUS;
pub const NODE_IS_IN_SHADOW_TREE: root::_bindgen_ty_28 =
_bindgen_ty_28::NODE_IS_IN_SHADOW_TREE;
pub const NODE_HAS_EMPTY_SELECTOR: root::_bindgen_ty_28 =
_bindgen_ty_28::NODE_HAS_EMPTY_SELECTOR;
pub const NODE_HAS_SLOW_SELECTOR: root::_bindgen_ty_28 =
_bindgen_ty_28::NODE_HAS_SLOW_SELECTOR;
pub const NODE_HAS_EDGE_CHILD_SELECTOR: root::_bindgen_ty_28 =
_bindgen_ty_28::NODE_HAS_EDGE_CHILD_SELECTOR;
pub const NODE_HAS_SLOW_SELECTOR_LATER_SIBLINGS: root::_bindgen_ty_28 =
_bindgen_ty_28::NODE_HAS_SLOW_SELECTOR_LATER_SIBLINGS;
pub const NODE_ALL_SELECTOR_FLAGS: root::_bindgen_ty_28 =
_bindgen_ty_28::NODE_ALL_SELECTOR_FLAGS;
pub const NODE_NEEDS_FRAME: root::_bindgen_ty_28 =
_bindgen_ty_28::NODE_NEEDS_FRAME;
pub const NODE_DESCENDANTS_NEED_FRAMES: root::_bindgen_ty_28 =
_bindgen_ty_28::NODE_DESCENDANTS_NEED_FRAMES;
pub const NODE_HAS_ACCESSKEY: root::_bindgen_ty_28 =
_bindgen_ty_28::NODE_HAS_ACCESSKEY;
pub const NODE_HAS_DIRECTION_RTL: root::_bindgen_ty_28 =
_bindgen_ty_28::NODE_HAS_DIRECTION_RTL;
pub const NODE_HAS_DIRECTION_LTR: root::_bindgen_ty_28 =
_bindgen_ty_28::NODE_HAS_DIRECTION_LTR;
pub const NODE_ALL_DIRECTION_FLAGS: root::_bindgen_ty_28 =
_bindgen_ty_28::NODE_ALL_DIRECTION_FLAGS;
pub const NODE_CHROME_ONLY_ACCESS: root::_bindgen_ty_28 =
_bindgen_ty_28::NODE_CHROME_ONLY_ACCESS;
pub const NODE_IS_ROOT_OF_CHROME_ONLY_ACCESS: root::_bindgen_ty_28 =
_bindgen_ty_28::NODE_IS_ROOT_OF_CHROME_ONLY_ACCESS;
pub const NODE_SHARED_RESTYLE_BIT_1: root::_bindgen_ty_28 =
_bindgen_ty_28::NODE_SHARED_RESTYLE_BIT_1;
pub const NODE_SHARED_RESTYLE_BIT_2: root::_bindgen_ty_28 =
_bindgen_ty_28::NODE_SHARED_RESTYLE_BIT_2;
pub const NODE_HAS_DIRTY_DESCENDANTS_FOR_SERVO: root::_bindgen_ty_28 =
_bindgen_ty_28::NODE_SHARED_RESTYLE_BIT_1;
pub const NODE_TYPE_SPECIFIC_BITS_OFFSET: root::_bindgen_ty_28 =
_bindgen_ty_28::NODE_TYPE_SPECIFIC_BITS_OFFSET;
pub const NODE_HAS_LISTENERMANAGER: root::_bindgen_ty_104 =
_bindgen_ty_104::NODE_HAS_LISTENERMANAGER;
pub const NODE_HAS_PROPERTIES: root::_bindgen_ty_104 =
_bindgen_ty_104::NODE_HAS_PROPERTIES;
pub const NODE_IS_ANONYMOUS_ROOT: root::_bindgen_ty_104 =
_bindgen_ty_104::NODE_IS_ANONYMOUS_ROOT;
pub const NODE_IS_IN_NATIVE_ANONYMOUS_SUBTREE: root::_bindgen_ty_104 =
_bindgen_ty_104::NODE_IS_IN_NATIVE_ANONYMOUS_SUBTREE;
pub const NODE_IS_NATIVE_ANONYMOUS_ROOT: root::_bindgen_ty_104 =
_bindgen_ty_104::NODE_IS_NATIVE_ANONYMOUS_ROOT;
pub const NODE_FORCE_XBL_BINDINGS: root::_bindgen_ty_104 =
_bindgen_ty_104::NODE_FORCE_XBL_BINDINGS;
pub const NODE_MAY_BE_IN_BINDING_MNGR: root::_bindgen_ty_104 =
_bindgen_ty_104::NODE_MAY_BE_IN_BINDING_MNGR;
pub const NODE_IS_EDITABLE: root::_bindgen_ty_104 =
_bindgen_ty_104::NODE_IS_EDITABLE;
pub const NODE_IS_NATIVE_ANONYMOUS: root::_bindgen_ty_104 =
_bindgen_ty_104::NODE_IS_NATIVE_ANONYMOUS;
pub const NODE_IS_IN_SHADOW_TREE: root::_bindgen_ty_104 =
_bindgen_ty_104::NODE_IS_IN_SHADOW_TREE;
pub const NODE_HAS_EMPTY_SELECTOR: root::_bindgen_ty_104 =
_bindgen_ty_104::NODE_HAS_EMPTY_SELECTOR;
pub const NODE_HAS_SLOW_SELECTOR: root::_bindgen_ty_104 =
_bindgen_ty_104::NODE_HAS_SLOW_SELECTOR;
pub const NODE_HAS_EDGE_CHILD_SELECTOR: root::_bindgen_ty_104 =
_bindgen_ty_104::NODE_HAS_EDGE_CHILD_SELECTOR;
pub const NODE_HAS_SLOW_SELECTOR_LATER_SIBLINGS: root::_bindgen_ty_104 =
_bindgen_ty_104::NODE_HAS_SLOW_SELECTOR_LATER_SIBLINGS;
pub const NODE_ALL_SELECTOR_FLAGS: root::_bindgen_ty_104 =
_bindgen_ty_104::NODE_ALL_SELECTOR_FLAGS;
pub const NODE_NEEDS_FRAME: root::_bindgen_ty_104 =
_bindgen_ty_104::NODE_NEEDS_FRAME;
pub const NODE_DESCENDANTS_NEED_FRAMES: root::_bindgen_ty_104 =
_bindgen_ty_104::NODE_DESCENDANTS_NEED_FRAMES;
pub const NODE_HAS_ACCESSKEY: root::_bindgen_ty_104 =
_bindgen_ty_104::NODE_HAS_ACCESSKEY;
pub const NODE_HAS_DIRECTION_RTL: root::_bindgen_ty_104 =
_bindgen_ty_104::NODE_HAS_DIRECTION_RTL;
pub const NODE_HAS_DIRECTION_LTR: root::_bindgen_ty_104 =
_bindgen_ty_104::NODE_HAS_DIRECTION_LTR;
pub const NODE_ALL_DIRECTION_FLAGS: root::_bindgen_ty_104 =
_bindgen_ty_104::NODE_ALL_DIRECTION_FLAGS;
pub const NODE_CHROME_ONLY_ACCESS: root::_bindgen_ty_104 =
_bindgen_ty_104::NODE_CHROME_ONLY_ACCESS;
pub const NODE_IS_ROOT_OF_CHROME_ONLY_ACCESS: root::_bindgen_ty_104 =
_bindgen_ty_104::NODE_IS_ROOT_OF_CHROME_ONLY_ACCESS;
pub const NODE_SHARED_RESTYLE_BIT_1: root::_bindgen_ty_104 =
_bindgen_ty_104::NODE_SHARED_RESTYLE_BIT_1;
pub const NODE_SHARED_RESTYLE_BIT_2: root::_bindgen_ty_104 =
_bindgen_ty_104::NODE_SHARED_RESTYLE_BIT_2;
pub const NODE_HAS_DIRTY_DESCENDANTS_FOR_SERVO: root::_bindgen_ty_104 =
_bindgen_ty_104::NODE_SHARED_RESTYLE_BIT_1;
pub const NODE_TYPE_SPECIFIC_BITS_OFFSET: root::_bindgen_ty_104 =
_bindgen_ty_104::NODE_TYPE_SPECIFIC_BITS_OFFSET;
#[repr(u32)]
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub enum _bindgen_ty_28 {
pub enum _bindgen_ty_104 {
NODE_HAS_LISTENERMANAGER = 4,
NODE_HAS_PROPERTIES = 8,
NODE_IS_ANONYMOUS_ROOT = 16,
@ -21792,7 +21772,7 @@ pub mod root {
#[repr(C)]
#[derive(Debug)]
pub struct nsStyleDisplay {
pub mBinding: root::RefPtr<root::mozilla::css::URLValue>,
pub mBinding: root::BindingHolder,
pub mDisplay: root::mozilla::StyleDisplay,
pub mOriginalDisplay: root::mozilla::StyleDisplay,
pub mContain: u8,
@ -24754,6 +24734,23 @@ pub mod root {
}
#[repr(C)]
#[derive(Debug)]
pub struct BindingHolder {
pub mPtr: root::RefPtr<root::mozilla::css::URLValue>,
}
#[test]
fn bindgen_test_layout_BindingHolder() {
assert_eq!(::std::mem::size_of::<BindingHolder>() , 8usize , concat !
( "Size of: " , stringify ! ( BindingHolder ) ));
assert_eq! (::std::mem::align_of::<BindingHolder>() , 8usize , concat
! ( "Alignment of " , stringify ! ( BindingHolder ) ));
assert_eq! (unsafe {
& ( * ( 0 as * const BindingHolder ) ) . mPtr as * const _
as usize } , 0usize , concat ! (
"Alignment of field: " , stringify ! ( BindingHolder ) ,
"::" , stringify ! ( mPtr ) ));
}
#[repr(C)]
#[derive(Debug)]
pub struct nsStyleTable {
pub mLayoutStrategy: u8,
pub mSpan: i32,

View File

@ -8169,12 +8169,7 @@ pub mod root {
}
pub type pair_first_type<_T1> = _T1;
pub type pair_second_type<_T2> = _T2;
#[repr(C)]
pub struct atomic<_Tp> {
pub _base: (),
pub _phantom_0: ::std::marker::PhantomData<_Tp>,
}
pub type atomic___base = [u8; 0usize];
pub type pair__PCCP = [u8; 0usize];
#[repr(C)]
#[derive(Debug, Copy)]
pub struct input_iterator_tag {
@ -8194,62 +8189,6 @@ pub mod root {
fn clone(&self) -> Self { *self }
}
#[repr(C)]
#[derive(Debug, Copy)]
pub struct forward_iterator_tag {
pub _address: u8,
}
#[test]
fn bindgen_test_layout_forward_iterator_tag() {
assert_eq!(::std::mem::size_of::<forward_iterator_tag>() , 1usize
, concat ! (
"Size of: " , stringify ! ( forward_iterator_tag ) ));
assert_eq! (::std::mem::align_of::<forward_iterator_tag>() ,
1usize , concat ! (
"Alignment of " , stringify ! ( forward_iterator_tag )
));
}
impl Clone for forward_iterator_tag {
fn clone(&self) -> Self { *self }
}
#[repr(C)]
#[derive(Debug, Copy)]
pub struct bidirectional_iterator_tag {
pub _address: u8,
}
#[test]
fn bindgen_test_layout_bidirectional_iterator_tag() {
assert_eq!(::std::mem::size_of::<bidirectional_iterator_tag>() ,
1usize , concat ! (
"Size of: " , stringify ! ( bidirectional_iterator_tag
) ));
assert_eq! (::std::mem::align_of::<bidirectional_iterator_tag>() ,
1usize , concat ! (
"Alignment of " , stringify ! (
bidirectional_iterator_tag ) ));
}
impl Clone for bidirectional_iterator_tag {
fn clone(&self) -> Self { *self }
}
#[repr(C)]
#[derive(Debug, Copy)]
pub struct random_access_iterator_tag {
pub _address: u8,
}
#[test]
fn bindgen_test_layout_random_access_iterator_tag() {
assert_eq!(::std::mem::size_of::<random_access_iterator_tag>() ,
1usize , concat ! (
"Size of: " , stringify ! ( random_access_iterator_tag
) ));
assert_eq! (::std::mem::align_of::<random_access_iterator_tag>() ,
1usize , concat ! (
"Alignment of " , stringify ! (
random_access_iterator_tag ) ));
}
impl Clone for random_access_iterator_tag {
fn clone(&self) -> Self { *self }
}
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct iterator<_Category, _Tp, _Distance, _Pointer, _Reference> {
pub _address: u8,
@ -8259,22 +8198,22 @@ pub mod root {
pub _phantom_3: ::std::marker::PhantomData<_Pointer>,
pub _phantom_4: ::std::marker::PhantomData<_Reference>,
}
pub type iterator_iterator_category<_Category> = _Category;
pub type iterator_value_type<_Tp> = _Tp;
pub type iterator_difference_type<_Distance> = _Distance;
pub type iterator_pointer<_Pointer> = _Pointer;
pub type iterator_reference<_Reference> = _Reference;
pub type iterator_iterator_category<_Category> = _Category;
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct __bit_const_reference<_Cp> {
pub __seg_: root::std::__bit_const_reference___storage_pointer<_Cp>,
pub __mask_: root::std::__bit_const_reference___storage_type<_Cp>,
#[derive(Debug)]
pub struct atomic<_Tp> {
pub _M_i: _Tp,
}
pub type __bit_const_reference___storage_type<_Cp> = _Cp;
pub type __bit_const_reference___storage_pointer<_Cp> = _Cp;
}
pub type __darwin_va_list = root::__builtin_va_list;
pub type va_list = root::__darwin_va_list;
pub mod __gnu_cxx {
#[allow(unused_imports)]
use self::super::super::root;
}
pub type va_list = root::__builtin_va_list;
/**
* MozRefCountType is Mozilla's reference count type.
*
@ -15132,63 +15071,63 @@ pub mod root {
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct nsDOMMutationObserver([u8; 0]);
pub const NODE_HAS_LISTENERMANAGER: root::_bindgen_ty_28 =
_bindgen_ty_28::NODE_HAS_LISTENERMANAGER;
pub const NODE_HAS_PROPERTIES: root::_bindgen_ty_28 =
_bindgen_ty_28::NODE_HAS_PROPERTIES;
pub const NODE_IS_ANONYMOUS_ROOT: root::_bindgen_ty_28 =
_bindgen_ty_28::NODE_IS_ANONYMOUS_ROOT;
pub const NODE_IS_IN_NATIVE_ANONYMOUS_SUBTREE: root::_bindgen_ty_28 =
_bindgen_ty_28::NODE_IS_IN_NATIVE_ANONYMOUS_SUBTREE;
pub const NODE_IS_NATIVE_ANONYMOUS_ROOT: root::_bindgen_ty_28 =
_bindgen_ty_28::NODE_IS_NATIVE_ANONYMOUS_ROOT;
pub const NODE_FORCE_XBL_BINDINGS: root::_bindgen_ty_28 =
_bindgen_ty_28::NODE_FORCE_XBL_BINDINGS;
pub const NODE_MAY_BE_IN_BINDING_MNGR: root::_bindgen_ty_28 =
_bindgen_ty_28::NODE_MAY_BE_IN_BINDING_MNGR;
pub const NODE_IS_EDITABLE: root::_bindgen_ty_28 =
_bindgen_ty_28::NODE_IS_EDITABLE;
pub const NODE_IS_NATIVE_ANONYMOUS: root::_bindgen_ty_28 =
_bindgen_ty_28::NODE_IS_NATIVE_ANONYMOUS;
pub const NODE_IS_IN_SHADOW_TREE: root::_bindgen_ty_28 =
_bindgen_ty_28::NODE_IS_IN_SHADOW_TREE;
pub const NODE_HAS_EMPTY_SELECTOR: root::_bindgen_ty_28 =
_bindgen_ty_28::NODE_HAS_EMPTY_SELECTOR;
pub const NODE_HAS_SLOW_SELECTOR: root::_bindgen_ty_28 =
_bindgen_ty_28::NODE_HAS_SLOW_SELECTOR;
pub const NODE_HAS_EDGE_CHILD_SELECTOR: root::_bindgen_ty_28 =
_bindgen_ty_28::NODE_HAS_EDGE_CHILD_SELECTOR;
pub const NODE_HAS_SLOW_SELECTOR_LATER_SIBLINGS: root::_bindgen_ty_28 =
_bindgen_ty_28::NODE_HAS_SLOW_SELECTOR_LATER_SIBLINGS;
pub const NODE_ALL_SELECTOR_FLAGS: root::_bindgen_ty_28 =
_bindgen_ty_28::NODE_ALL_SELECTOR_FLAGS;
pub const NODE_NEEDS_FRAME: root::_bindgen_ty_28 =
_bindgen_ty_28::NODE_NEEDS_FRAME;
pub const NODE_DESCENDANTS_NEED_FRAMES: root::_bindgen_ty_28 =
_bindgen_ty_28::NODE_DESCENDANTS_NEED_FRAMES;
pub const NODE_HAS_ACCESSKEY: root::_bindgen_ty_28 =
_bindgen_ty_28::NODE_HAS_ACCESSKEY;
pub const NODE_HAS_DIRECTION_RTL: root::_bindgen_ty_28 =
_bindgen_ty_28::NODE_HAS_DIRECTION_RTL;
pub const NODE_HAS_DIRECTION_LTR: root::_bindgen_ty_28 =
_bindgen_ty_28::NODE_HAS_DIRECTION_LTR;
pub const NODE_ALL_DIRECTION_FLAGS: root::_bindgen_ty_28 =
_bindgen_ty_28::NODE_ALL_DIRECTION_FLAGS;
pub const NODE_CHROME_ONLY_ACCESS: root::_bindgen_ty_28 =
_bindgen_ty_28::NODE_CHROME_ONLY_ACCESS;
pub const NODE_IS_ROOT_OF_CHROME_ONLY_ACCESS: root::_bindgen_ty_28 =
_bindgen_ty_28::NODE_IS_ROOT_OF_CHROME_ONLY_ACCESS;
pub const NODE_SHARED_RESTYLE_BIT_1: root::_bindgen_ty_28 =
_bindgen_ty_28::NODE_SHARED_RESTYLE_BIT_1;
pub const NODE_SHARED_RESTYLE_BIT_2: root::_bindgen_ty_28 =
_bindgen_ty_28::NODE_SHARED_RESTYLE_BIT_2;
pub const NODE_HAS_DIRTY_DESCENDANTS_FOR_SERVO: root::_bindgen_ty_28 =
_bindgen_ty_28::NODE_SHARED_RESTYLE_BIT_1;
pub const NODE_TYPE_SPECIFIC_BITS_OFFSET: root::_bindgen_ty_28 =
_bindgen_ty_28::NODE_TYPE_SPECIFIC_BITS_OFFSET;
pub const NODE_HAS_LISTENERMANAGER: root::_bindgen_ty_91 =
_bindgen_ty_91::NODE_HAS_LISTENERMANAGER;
pub const NODE_HAS_PROPERTIES: root::_bindgen_ty_91 =
_bindgen_ty_91::NODE_HAS_PROPERTIES;
pub const NODE_IS_ANONYMOUS_ROOT: root::_bindgen_ty_91 =
_bindgen_ty_91::NODE_IS_ANONYMOUS_ROOT;
pub const NODE_IS_IN_NATIVE_ANONYMOUS_SUBTREE: root::_bindgen_ty_91 =
_bindgen_ty_91::NODE_IS_IN_NATIVE_ANONYMOUS_SUBTREE;
pub const NODE_IS_NATIVE_ANONYMOUS_ROOT: root::_bindgen_ty_91 =
_bindgen_ty_91::NODE_IS_NATIVE_ANONYMOUS_ROOT;
pub const NODE_FORCE_XBL_BINDINGS: root::_bindgen_ty_91 =
_bindgen_ty_91::NODE_FORCE_XBL_BINDINGS;
pub const NODE_MAY_BE_IN_BINDING_MNGR: root::_bindgen_ty_91 =
_bindgen_ty_91::NODE_MAY_BE_IN_BINDING_MNGR;
pub const NODE_IS_EDITABLE: root::_bindgen_ty_91 =
_bindgen_ty_91::NODE_IS_EDITABLE;
pub const NODE_IS_NATIVE_ANONYMOUS: root::_bindgen_ty_91 =
_bindgen_ty_91::NODE_IS_NATIVE_ANONYMOUS;
pub const NODE_IS_IN_SHADOW_TREE: root::_bindgen_ty_91 =
_bindgen_ty_91::NODE_IS_IN_SHADOW_TREE;
pub const NODE_HAS_EMPTY_SELECTOR: root::_bindgen_ty_91 =
_bindgen_ty_91::NODE_HAS_EMPTY_SELECTOR;
pub const NODE_HAS_SLOW_SELECTOR: root::_bindgen_ty_91 =
_bindgen_ty_91::NODE_HAS_SLOW_SELECTOR;
pub const NODE_HAS_EDGE_CHILD_SELECTOR: root::_bindgen_ty_91 =
_bindgen_ty_91::NODE_HAS_EDGE_CHILD_SELECTOR;
pub const NODE_HAS_SLOW_SELECTOR_LATER_SIBLINGS: root::_bindgen_ty_91 =
_bindgen_ty_91::NODE_HAS_SLOW_SELECTOR_LATER_SIBLINGS;
pub const NODE_ALL_SELECTOR_FLAGS: root::_bindgen_ty_91 =
_bindgen_ty_91::NODE_ALL_SELECTOR_FLAGS;
pub const NODE_NEEDS_FRAME: root::_bindgen_ty_91 =
_bindgen_ty_91::NODE_NEEDS_FRAME;
pub const NODE_DESCENDANTS_NEED_FRAMES: root::_bindgen_ty_91 =
_bindgen_ty_91::NODE_DESCENDANTS_NEED_FRAMES;
pub const NODE_HAS_ACCESSKEY: root::_bindgen_ty_91 =
_bindgen_ty_91::NODE_HAS_ACCESSKEY;
pub const NODE_HAS_DIRECTION_RTL: root::_bindgen_ty_91 =
_bindgen_ty_91::NODE_HAS_DIRECTION_RTL;
pub const NODE_HAS_DIRECTION_LTR: root::_bindgen_ty_91 =
_bindgen_ty_91::NODE_HAS_DIRECTION_LTR;
pub const NODE_ALL_DIRECTION_FLAGS: root::_bindgen_ty_91 =
_bindgen_ty_91::NODE_ALL_DIRECTION_FLAGS;
pub const NODE_CHROME_ONLY_ACCESS: root::_bindgen_ty_91 =
_bindgen_ty_91::NODE_CHROME_ONLY_ACCESS;
pub const NODE_IS_ROOT_OF_CHROME_ONLY_ACCESS: root::_bindgen_ty_91 =
_bindgen_ty_91::NODE_IS_ROOT_OF_CHROME_ONLY_ACCESS;
pub const NODE_SHARED_RESTYLE_BIT_1: root::_bindgen_ty_91 =
_bindgen_ty_91::NODE_SHARED_RESTYLE_BIT_1;
pub const NODE_SHARED_RESTYLE_BIT_2: root::_bindgen_ty_91 =
_bindgen_ty_91::NODE_SHARED_RESTYLE_BIT_2;
pub const NODE_HAS_DIRTY_DESCENDANTS_FOR_SERVO: root::_bindgen_ty_91 =
_bindgen_ty_91::NODE_SHARED_RESTYLE_BIT_1;
pub const NODE_TYPE_SPECIFIC_BITS_OFFSET: root::_bindgen_ty_91 =
_bindgen_ty_91::NODE_TYPE_SPECIFIC_BITS_OFFSET;
#[repr(u32)]
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub enum _bindgen_ty_28 {
pub enum _bindgen_ty_91 {
NODE_HAS_LISTENERMANAGER = 4,
NODE_HAS_PROPERTIES = 8,
NODE_IS_ANONYMOUS_ROOT = 16,
@ -21192,7 +21131,7 @@ pub mod root {
#[repr(C)]
#[derive(Debug)]
pub struct nsStyleDisplay {
pub mBinding: root::RefPtr<root::mozilla::css::URLValue>,
pub mBinding: root::BindingHolder,
pub mDisplay: root::mozilla::StyleDisplay,
pub mOriginalDisplay: root::mozilla::StyleDisplay,
pub mContain: u8,
@ -24153,6 +24092,23 @@ pub mod root {
}
#[repr(C)]
#[derive(Debug)]
pub struct BindingHolder {
pub mPtr: root::RefPtr<root::mozilla::css::URLValue>,
}
#[test]
fn bindgen_test_layout_BindingHolder() {
assert_eq!(::std::mem::size_of::<BindingHolder>() , 8usize , concat !
( "Size of: " , stringify ! ( BindingHolder ) ));
assert_eq! (::std::mem::align_of::<BindingHolder>() , 8usize , concat
! ( "Alignment of " , stringify ! ( BindingHolder ) ));
assert_eq! (unsafe {
& ( * ( 0 as * const BindingHolder ) ) . mPtr as * const _
as usize } , 0usize , concat ! (
"Alignment of field: " , stringify ! ( BindingHolder ) ,
"::" , stringify ! ( mPtr ) ));
}
#[repr(C)]
#[derive(Debug)]
pub struct nsStyleTable {
pub mLayoutStrategy: u8,
pub mSpan: i32,

View File

@ -156,7 +156,7 @@ impl ComputedValues {
#[allow(non_snake_case)]
pub fn has_moz_binding(&self) -> bool {
!self.get_box().gecko.mBinding.mRawPtr.is_null()
!self.get_box().gecko.mBinding.mPtr.mRawPtr.is_null()
}
// FIXME(bholley): Implement this properly.
@ -507,20 +507,13 @@ fn color_to_nscolor_zero_currentcolor(color: Color) -> structs::nscolor {
% endif
</%def>
<%def name="impl_css_url(ident, gecko_ffi_name, need_clone=False, only_resolved=False)">
<%def name="impl_css_url(ident, gecko_ffi_name, need_clone=False)">
#[allow(non_snake_case)]
pub fn set_${ident}(&mut self, v: longhands::${ident}::computed_value::T) {
use gecko_bindings::sugar::refptr::RefPtr;
match v {
Either::First(url) => {
let refptr = unsafe {
% if only_resolved:
// -moz-binding can't handle relative URIs
if !url.has_resolved() {
self.gecko.${gecko_ffi_name}.clear();
return;
}
% endif
let ptr = bindings::Gecko_NewURLValue(url.for_ffi());
if ptr.is_null() {
self.gecko.${gecko_ffi_name}.clear();
@ -1632,7 +1625,7 @@ fn static_assert() {
longhands::scroll_snap_coordinate::computed_value::T(vec)
}
${impl_css_url('_moz_binding', 'mBinding', only_resolved=True)}
${impl_css_url('_moz_binding', 'mBinding.mPtr')}
<%def name="transform_function_arm(name, keyword, items)">
<%

View File

@ -259,12 +259,7 @@ ${helpers.single_keyword("mask-composite",
let image = try!(Image::parse(context, input));
match image {
Image::Url(url_value) => {
let has_valid_url = match url_value.url() {
Some(url) => url.fragment().is_some(),
None => false,
};
if has_valid_url {
if url_value.is_fragment() {
Ok(SpecifiedValue::Url(url_value))
} else {
Ok(SpecifiedValue::Image(Image::Url(url_value)))

View File

@ -9,3 +9,4 @@
pub mod media_queries;
pub mod restyle_damage;
pub mod selector_parser;
pub mod url;

View File

@ -0,0 +1,127 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
//! Common handling for the specified value CSS url() values.
use cssparser::CssStringWriter;
use parser::ParserContext;
use servo_url::ServoUrl;
use std::borrow::Cow;
use std::fmt::{self, Write};
use std::sync::Arc;
use style_traits::ToCss;
/// A specified url() value for servo.
///
/// Servo eagerly resolves SpecifiedUrls, which it can then take advantage of
/// when computing values. In contrast, Gecko uses a different URL backend, so
/// eagerly resolving with rust-url would be duplicated work.
///
/// However, this approach is still not necessarily optimal: See
/// https://bugzilla.mozilla.org/show_bug.cgi?id=1347435#c6
#[derive(Clone, Debug, HeapSizeOf, Serialize, Deserialize)]
pub struct SpecifiedUrl {
/// The original URI. This might be optional since we may insert computed
/// values of images into the cascade directly, and we don't bother to
/// convert their serialization.
///
/// Refcounted since cloning this should be cheap and data: uris can be
/// really large.
original: Option<Arc<String>>,
/// The resolved value for the url, if valid.
resolved: Option<ServoUrl>,
}
impl SpecifiedUrl {
/// Try to parse a URL from a string value that is a valid CSS token for a
/// URL. Never fails - the API is only fallible to be compatible with the
/// gecko version.
pub fn parse_from_string<'a>(url: Cow<'a, str>,
context: &ParserContext)
-> Result<Self, ()> {
let serialization = Arc::new(url.into_owned());
let resolved = context.base_url.join(&serialization).ok();
Ok(SpecifiedUrl {
original: Some(serialization),
resolved: resolved,
})
}
/// Returns true if the URL is definitely invalid. For Servo URLs, we can
/// use its |resolved| status.
pub fn is_invalid(&self) -> bool {
self.resolved.is_none()
}
/// Returns true if this URL looks like a fragment.
/// See https://drafts.csswg.org/css-values/#local-urls
///
/// Since Servo currently stores resolved URLs, this is hard to implement. We
/// either need to change servo to lazily resolve (like Gecko), or note this
/// information in the tokenizer.
pub fn is_fragment(&self) -> bool {
error!("Can't determine whether the url is a fragment.");
false
}
/// Returns the resolved url if it was valid.
pub fn url(&self) -> Option<&ServoUrl> {
self.resolved.as_ref()
}
/// Return the resolved url as string, or the empty string if it's invalid.
///
/// TODO(emilio): Should we return the original one if needed?
pub fn as_str(&self) -> &str {
match self.resolved {
Some(ref url) => url.as_str(),
None => "",
}
}
/// Creates an already specified url value from an already resolved URL
/// for insertion in the cascade.
pub fn for_cascade(url: ServoUrl) -> Self {
SpecifiedUrl {
original: None,
resolved: Some(url),
}
}
/// Gets a new url from a string for unit tests.
pub fn new_for_testing(url: &str) -> Self {
SpecifiedUrl {
original: Some(Arc::new(url.into())),
resolved: ServoUrl::parse(url).ok(),
}
}
}
impl PartialEq for SpecifiedUrl {
fn eq(&self, other: &Self) -> bool {
// TODO(emilio): maybe we care about equality of the specified values if
// present? Seems not.
self.resolved == other.resolved
}
}
impl ToCss for SpecifiedUrl {
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
try!(dest.write_str("url(\""));
let string = match self.original {
Some(ref original) => &**original,
None => match self.resolved {
Some(ref url) => url.as_str(),
// This can only happen if the url wasn't specified by the
// user *and* it's an invalid url that has been transformed
// back to specified value via the "uncompute" functionality.
None => "about:invalid",
}
};
try!(CssStringWriter::new(dest).write_str(string));
dest.write_str("\")")
}
}

View File

@ -839,8 +839,7 @@ impl<'a> AtRuleParser for TopLevelRuleParser<'a> {
let media = parse_media_query_list(input);
let noop_loader = NoOpLoader;
let is_valid_url = specified_url.url().is_some();
let loader = if is_valid_url {
let loader = if !specified_url.is_invalid() {
self.loader.expect("Expected a stylesheet loader for @import")
} else {
&noop_loader

View File

@ -21,7 +21,7 @@ pub use super::{Auto, Either, None_};
#[cfg(feature = "gecko")]
pub use super::specified::{AlignItems, AlignJustifyContent, AlignJustifySelf, JustifyItems};
pub use super::specified::{Angle, BorderStyle, GridLine, Time, UrlOrNone};
pub use super::specified::url::{SpecifiedUrl, UrlExtraData};
pub use super::specified::url::SpecifiedUrl;
pub use self::length::{CalcLengthOrPercentage, Length, LengthOrNumber, LengthOrPercentage, LengthOrPercentageOrAuto};
pub use self::length::{LengthOrPercentageOrAutoOrContent, LengthOrPercentageOrNone, LengthOrNone};
pub use self::length::{MaxLength, MinLength};

View File

@ -9,12 +9,13 @@
use cssparser::Parser;
use parser::{Parse, ParserContext};
#[cfg(feature = "servo")]
use servo_url::ServoUrl;
use std::fmt;
use style_traits::ToCss;
use values::specified::{Angle, CSSColor, Length, LengthOrPercentage};
use values::specified::position::Position;
use values::specified::url::{SpecifiedUrl, UrlExtraData};
use values::specified::url::SpecifiedUrl;
/// Specified values for an image according to CSS-IMAGES.
/// https://drafts.csswg.org/css-images/#image-values
@ -48,8 +49,9 @@ impl Image {
/// Creates an already specified image value from an already resolved URL
/// for insertion in the cascade.
pub fn for_cascade(url: ServoUrl, extra_data: UrlExtraData) -> Self {
Image::Url(SpecifiedUrl::for_cascade(url, extra_data))
#[cfg(feature = "servo")]
pub fn for_cascade(url: ServoUrl) -> Self {
Image::Url(SpecifiedUrl::for_cascade(url))
}
}

View File

@ -42,7 +42,33 @@ pub mod grid;
pub mod image;
pub mod length;
pub mod position;
pub mod url;
/// Common handling for the specified value CSS url() values.
pub mod url {
use cssparser::Parser;
use parser::{Parse, ParserContext};
use values::HasViewportPercentage;
use values::computed::ComputedValueAsSpecified;
#[cfg(feature = "servo")]
pub use ::servo::url::*;
#[cfg(feature = "gecko")]
pub use ::gecko::url::*;
impl Parse for SpecifiedUrl {
fn parse(context: &ParserContext, input: &mut Parser) -> Result<Self, ()> {
let url = try!(input.expect_url());
Self::parse_from_string(url, context)
}
}
impl Eq for SpecifiedUrl {}
// TODO(emilio): Maybe consider ComputedUrl to save a word in style structs?
impl ComputedValueAsSpecified for SpecifiedUrl {}
no_viewport_percentage!(SpecifiedUrl);
}
no_viewport_percentage!(i32); // For PropertyDeclaration::Order

View File

@ -1,231 +0,0 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
//! Common handling for the specified value CSS url() values.
use cssparser::{CssStringWriter, Parser};
#[cfg(feature = "gecko")]
use gecko_bindings::structs::ServoBundledURI;
#[cfg(feature = "gecko")]
use gecko_bindings::sugar::refptr::{GeckoArcPrincipal, GeckoArcURI};
use parser::{Parse, ParserContext};
#[cfg(feature = "gecko")]
use parser::ParserContextExtraData;
use servo_url::ServoUrl;
use std::borrow::Cow;
use std::fmt::{self, Write};
use std::sync::Arc;
use style_traits::ToCss;
use values::HasViewportPercentage;
use values::computed::ComputedValueAsSpecified;
/// A set of data needed in Gecko to represent a URL.
#[derive(PartialEq, Clone, Debug)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf, Serialize, Deserialize, Eq))]
pub struct UrlExtraData {
/// The base URI.
#[cfg(feature = "gecko")]
pub base: GeckoArcURI,
/// The referrer.
#[cfg(feature = "gecko")]
pub referrer: GeckoArcURI,
/// The principal that originated this URI.
#[cfg(feature = "gecko")]
pub principal: GeckoArcPrincipal,
}
impl UrlExtraData {
/// Constructs a `UrlExtraData`.
#[cfg(feature = "servo")]
pub fn make_from(_: &ParserContext) -> Option<UrlExtraData> {
Some(UrlExtraData { })
}
/// Constructs a `UrlExtraData`.
#[cfg(feature = "gecko")]
pub fn make_from(context: &ParserContext) -> Option<UrlExtraData> {
match context.extra_data {
ParserContextExtraData {
base: Some(ref base),
referrer: Some(ref referrer),
principal: Some(ref principal),
} => {
Some(UrlExtraData {
base: base.clone(),
referrer: referrer.clone(),
principal: principal.clone(),
})
},
_ => None,
}
}
}
/// A specified url() value.
#[derive(Clone, Debug)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf, Serialize, Deserialize))]
pub struct SpecifiedUrl {
/// The original URI. This might be optional since we may insert computed
/// values of images into the cascade directly, and we don't bother to
/// convert their serialization.
///
/// Refcounted since cloning this should be cheap and data: uris can be
/// really large.
original: Option<Arc<String>>,
/// The resolved value for the url, if valid.
resolved: Option<ServoUrl>,
/// Extra data used for Stylo.
extra_data: UrlExtraData,
}
impl Parse for SpecifiedUrl {
fn parse(context: &ParserContext, input: &mut Parser) -> Result<Self, ()> {
let url = try!(input.expect_url());
Self::parse_from_string(url, context)
}
}
impl SpecifiedUrl {
/// Try to parse a URL from a string value that is a valid CSS token for a
/// URL.
///
/// Only returns `Err` for Gecko, in the case we can't construct a
/// `URLExtraData`.
pub fn parse_from_string<'a>(url: Cow<'a, str>,
context: &ParserContext)
-> Result<Self, ()> {
let extra_data = match UrlExtraData::make_from(context) {
Some(extra_data) => extra_data,
None => {
// FIXME(heycam) should ensure we always have a principal, etc.,
// when parsing style attributes and re-parsing due to CSS
// Variables.
warn!("stylo: skipping declaration without ParserContextExtraData");
return Err(())
},
};
let serialization = Arc::new(url.into_owned());
let resolved = context.base_url.join(&serialization).ok();
Ok(SpecifiedUrl {
original: Some(serialization),
resolved: resolved,
extra_data: extra_data,
})
}
/// Get this URL's extra data.
pub fn extra_data(&self) -> &UrlExtraData {
&self.extra_data
}
/// Returns the resolved url if it was valid.
pub fn url(&self) -> Option<&ServoUrl> {
self.resolved.as_ref()
}
/// Return the resolved url as string, or the empty string if it's invalid.
///
/// TODO(emilio): Should we return the original one if needed?
pub fn as_str(&self) -> &str {
match self.resolved {
Some(ref url) => url.as_str(),
None => "",
}
}
/// Little helper for Gecko's ffi.
#[cfg(feature = "gecko")]
pub fn as_slice_components(&self) -> Result<(*const u8, usize), (*const u8, usize)> {
match self.resolved {
Some(ref url) => Ok((url.as_str().as_ptr(), url.as_str().len())),
None => {
let url = self.original.as_ref()
.expect("We should always have either the original or the resolved value");
Err((url.as_str().as_ptr(), url.as_str().len()))
}
}
}
/// Check if it has a resolved URI
pub fn has_resolved(&self) -> bool {
self.resolved.is_some()
}
/// Creates an already specified url value from an already resolved URL
/// for insertion in the cascade.
pub fn for_cascade(url: ServoUrl, extra_data: UrlExtraData) -> Self {
SpecifiedUrl {
original: None,
resolved: Some(url),
extra_data: extra_data,
}
}
/// Gets a new url from a string for unit tests.
#[cfg(feature = "servo")]
pub fn new_for_testing(url: &str) -> Self {
SpecifiedUrl {
original: Some(Arc::new(url.into())),
resolved: ServoUrl::parse(url).ok(),
extra_data: UrlExtraData {}
}
}
/// Create a bundled URI suitable for sending to Gecko
/// to be constructed into a css::URLValue
#[cfg(feature = "gecko")]
pub fn for_ffi(&self) -> ServoBundledURI {
let extra_data = self.extra_data();
let (ptr, len) = match self.as_slice_components() {
Ok(value) => value,
// we're okay with passing down the unresolved relative URI
Err(value) => value,
};
ServoBundledURI {
mURLString: ptr,
mURLStringLength: len as u32,
mBaseURI: extra_data.base.get(),
mReferrer: extra_data.referrer.get(),
mPrincipal: extra_data.principal.get(),
}
}
}
impl PartialEq for SpecifiedUrl {
fn eq(&self, other: &Self) -> bool {
// TODO(emilio): maybe we care about equality of the specified values if
// present? Seems not.
self.resolved == other.resolved &&
self.extra_data == other.extra_data
}
}
impl Eq for SpecifiedUrl {}
impl ToCss for SpecifiedUrl {
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
try!(dest.write_str("url(\""));
let string = match self.original {
Some(ref original) => &**original,
None => match self.resolved {
Some(ref url) => url.as_str(),
// This can only happen if the url wasn't specified by the
// user *and* it's an invalid url that has been transformed
// back to specified value via the "uncompute" functionality.
None => "about:invalid",
}
};
try!(CssStringWriter::new(dest).write_str(string));
dest.write_str("\")")
}
}
// TODO(emilio): Maybe consider ComputedUrl to save a word in style structs?
impl ComputedValueAsSpecified for SpecifiedUrl {}
no_viewport_percentage!(SpecifiedUrl);

View File

@ -42,14 +42,15 @@ impl StyleStylesheetLoader for StylesheetLoader {
// and so the Arc<Url> pointer inside will also move,
// but the Url it points to or the allocating backing the String inside that Url wont,
// so this raw pointer will still be valid.
let (spec_bytes, spec_len): (*const u8, usize) = import.url.as_slice_components()
.expect("Import only loads valid URLs");
let (spec_bytes, spec_len): (*const u8, usize) = import.url.as_slice_components();
let base_uri = import.url.base.mRawPtr;
let arc = make_arc(import);
unsafe {
Gecko_LoadStyleSheet(self.0,
self.1,
HasArcFFI::arc_as_borrowed(&arc),
base_uri,
spec_bytes,
spec_len as u32,
media_string.as_bytes().as_ptr(),