mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-10 11:55:49 +00:00
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:
parent
72f8a22761
commit
9595cb0a22
@ -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())
|
||||
))
|
||||
]))));
|
||||
}
|
||||
|
@ -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",
|
||||
|
@ -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;
|
||||
|
104
servo/components/style/gecko/url.rs
Normal file
104
servo/components/style/gecko/url.rs
Normal 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("\")")
|
||||
}
|
||||
}
|
@ -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)
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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)">
|
||||
<%
|
||||
|
@ -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)))
|
||||
|
@ -9,3 +9,4 @@
|
||||
pub mod media_queries;
|
||||
pub mod restyle_damage;
|
||||
pub mod selector_parser;
|
||||
pub mod url;
|
||||
|
127
servo/components/style/servo/url.rs
Normal file
127
servo/components/style/servo/url.rs
Normal 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("\")")
|
||||
}
|
||||
}
|
@ -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
|
||||
|
@ -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};
|
||||
|
@ -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))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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);
|
@ -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 won’t,
|
||||
// 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(),
|
||||
|
Loading…
Reference in New Issue
Block a user