servo: Merge #20577 - Avoid Gecko Namespace registration from Servo (from bholley:no_namespace_registration); r=upsuper

https://bugzilla.mozilla.org/show_bug.cgi?id=1451421

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

--HG--
extra : subtree_source : https%3A//hg.mozilla.org/projects/converted-servo-linear
extra : subtree_revision : b25e1a7becc43a31c2144b2389e7c01c79d83f6d
This commit is contained in:
Bobby Holley 2018-04-06 17:33:07 -04:00
Родитель 758bc8158f
Коммит 915ff8eb0e
11 изменённых файлов: 163 добавлений и 88 удалений

Просмотреть файл

@ -1596,9 +1596,6 @@ extern "C" {
extern "C" { extern "C" {
pub fn Gecko_AddPropertyToSet(arg1: nsCSSPropertyIDSetBorrowedMut, arg2: nsCSSPropertyID); pub fn Gecko_AddPropertyToSet(arg1: nsCSSPropertyIDSetBorrowedMut, arg2: nsCSSPropertyID);
} }
extern "C" {
pub fn Gecko_RegisterNamespace(ns: *mut nsAtom) -> i32;
}
extern "C" { extern "C" {
pub fn Gecko_Construct_Default_nsStyleFont( pub fn Gecko_Construct_Default_nsStyleFont(
ptr: *mut nsStyleFont, ptr: *mut nsStyleFont,

Просмотреть файл

@ -26311,6 +26311,47 @@ pub mod root {
} }
#[repr(C)] #[repr(C)]
#[derive(Debug)] #[derive(Debug)]
pub struct nsStyleContentAttr {
pub mName: root::RefPtr<root::nsAtom>,
pub mNamespaceURL: root::RefPtr<root::nsAtom>,
}
#[test]
fn bindgen_test_layout_nsStyleContentAttr() {
assert_eq!(
::std::mem::size_of::<nsStyleContentAttr>(),
16usize,
concat!("Size of: ", stringify!(nsStyleContentAttr))
);
assert_eq!(
::std::mem::align_of::<nsStyleContentAttr>(),
8usize,
concat!("Alignment of ", stringify!(nsStyleContentAttr))
);
assert_eq!(
unsafe { &(*(::std::ptr::null::<nsStyleContentAttr>())).mName as *const _ as usize },
0usize,
concat!(
"Offset of field: ",
stringify!(nsStyleContentAttr),
"::",
stringify!(mName)
)
);
assert_eq!(
unsafe {
&(*(::std::ptr::null::<nsStyleContentAttr>())).mNamespaceURL as *const _ as usize
},
8usize,
concat!(
"Offset of field: ",
stringify!(nsStyleContentAttr),
"::",
stringify!(mNamespaceURL)
)
);
}
#[repr(C)]
#[derive(Debug)]
pub struct nsStyleContentData { pub struct nsStyleContentData {
pub mType: root::nsStyleContentType, pub mType: root::nsStyleContentType,
pub mContent: root::nsStyleContentData__bindgen_ty_1, pub mContent: root::nsStyleContentData__bindgen_ty_1,
@ -26395,6 +26436,7 @@ pub mod root {
#[derive(Debug, Copy)] #[derive(Debug, Copy)]
pub struct nsStyleContentData__bindgen_ty_1 { pub struct nsStyleContentData__bindgen_ty_1 {
pub mString: root::__BindgenUnionField<*mut u16>, pub mString: root::__BindgenUnionField<*mut u16>,
pub mAttr: root::__BindgenUnionField<*mut root::nsStyleContentAttr>,
pub mImage: root::__BindgenUnionField<*mut root::nsStyleImageRequest>, pub mImage: root::__BindgenUnionField<*mut root::nsStyleImageRequest>,
pub mCounters: root::__BindgenUnionField<*mut root::nsStyleContentData_CounterFunction>, pub mCounters: root::__BindgenUnionField<*mut root::nsStyleContentData_CounterFunction>,
pub bindgen_union_field: u64, pub bindgen_union_field: u64,
@ -26427,6 +26469,19 @@ pub mod root {
stringify!(mString) stringify!(mString)
) )
); );
assert_eq!(
unsafe {
&(*(::std::ptr::null::<nsStyleContentData__bindgen_ty_1>())).mAttr as *const _
as usize
},
0usize,
concat!(
"Offset of field: ",
stringify!(nsStyleContentData__bindgen_ty_1),
"::",
stringify!(mAttr)
)
);
assert_eq!( assert_eq!(
unsafe { unsafe {
&(*(::std::ptr::null::<nsStyleContentData__bindgen_ty_1>())).mImage as *const _ &(*(::std::ptr::null::<nsStyleContentData__bindgen_ty_1>())).mImage as *const _
@ -41719,6 +41774,44 @@ pub mod root {
); );
} }
#[test] #[test]
fn __bindgen_test_layout_RefPtr_open0_nsAtom_close0_instantiation_4() {
assert_eq!(
::std::mem::size_of::<root::RefPtr<root::nsAtom>>(),
8usize,
concat!(
"Size of template specialization: ",
stringify!(root::RefPtr<root::nsAtom>)
)
);
assert_eq!(
::std::mem::align_of::<root::RefPtr<root::nsAtom>>(),
8usize,
concat!(
"Alignment of template specialization: ",
stringify!(root::RefPtr<root::nsAtom>)
)
);
}
#[test]
fn __bindgen_test_layout_RefPtr_open0_nsAtom_close0_instantiation_5() {
assert_eq!(
::std::mem::size_of::<root::RefPtr<root::nsAtom>>(),
8usize,
concat!(
"Size of template specialization: ",
stringify!(root::RefPtr<root::nsAtom>)
)
);
assert_eq!(
::std::mem::align_of::<root::RefPtr<root::nsAtom>>(),
8usize,
concat!(
"Alignment of template specialization: ",
stringify!(root::RefPtr<root::nsAtom>)
)
);
}
#[test]
fn __bindgen_test_layout_nsTArray_open0_nsStyleContentData_close0_instantiation() { fn __bindgen_test_layout_nsTArray_open0_nsStyleContentData_close0_instantiation() {
assert_eq!( assert_eq!(
::std::mem::size_of::<root::nsTArray<root::nsStyleContentData>>(), ::std::mem::size_of::<root::nsTArray<root::nsStyleContentData>>(),
@ -41928,7 +42021,7 @@ pub mod root {
); );
} }
#[test] #[test]
fn __bindgen_test_layout_RefPtr_open0_nsAtom_close0_instantiation_4() { fn __bindgen_test_layout_RefPtr_open0_nsAtom_close0_instantiation_6() {
assert_eq!( assert_eq!(
::std::mem::size_of::<root::RefPtr<root::nsAtom>>(), ::std::mem::size_of::<root::RefPtr<root::nsAtom>>(),
8usize, 8usize,
@ -43679,7 +43772,7 @@ pub mod root {
); );
} }
#[test] #[test]
fn __bindgen_test_layout_RefPtr_open0_nsAtom_close0_instantiation_5() { fn __bindgen_test_layout_RefPtr_open0_nsAtom_close0_instantiation_7() {
assert_eq!( assert_eq!(
::std::mem::size_of::<root::RefPtr<root::nsAtom>>(), ::std::mem::size_of::<root::RefPtr<root::nsAtom>>(),
8usize, 8usize,
@ -44126,7 +44219,7 @@ pub mod root {
); );
} }
#[test] #[test]
fn __bindgen_test_layout_RefPtr_open0_nsAtom_close0_instantiation_6() { fn __bindgen_test_layout_RefPtr_open0_nsAtom_close0_instantiation_8() {
assert_eq!( assert_eq!(
::std::mem::size_of::<root::RefPtr<root::nsAtom>>(), ::std::mem::size_of::<root::RefPtr<root::nsAtom>>(),
8usize, 8usize,
@ -44255,7 +44348,7 @@ pub mod root {
); );
} }
#[test] #[test]
fn __bindgen_test_layout_RefPtr_open0_nsAtom_close0_instantiation_7() { fn __bindgen_test_layout_RefPtr_open0_nsAtom_close0_instantiation_9() {
assert_eq!( assert_eq!(
::std::mem::size_of::<root::RefPtr<root::nsAtom>>(), ::std::mem::size_of::<root::RefPtr<root::nsAtom>>(),
8usize, 8usize,
@ -46639,7 +46732,7 @@ pub mod root {
); );
} }
#[test] #[test]
fn __bindgen_test_layout_RefPtr_open0_nsAtom_close0_instantiation_8() { fn __bindgen_test_layout_RefPtr_open0_nsAtom_close0_instantiation_10() {
assert_eq!( assert_eq!(
::std::mem::size_of::<root::RefPtr<root::nsAtom>>(), ::std::mem::size_of::<root::RefPtr<root::nsAtom>>(),
8usize, 8usize,
@ -46658,7 +46751,7 @@ pub mod root {
); );
} }
#[test] #[test]
fn __bindgen_test_layout_RefPtr_open0_nsAtom_close0_instantiation_9() { fn __bindgen_test_layout_RefPtr_open0_nsAtom_close0_instantiation_11() {
assert_eq!( assert_eq!(
::std::mem::size_of::<root::RefPtr<root::nsAtom>>(), ::std::mem::size_of::<root::RefPtr<root::nsAtom>>(),
8usize, 8usize,
@ -46905,7 +46998,7 @@ pub mod root {
); );
} }
#[test] #[test]
fn __bindgen_test_layout_RefPtr_open0_nsAtom_close0_instantiation_10() { fn __bindgen_test_layout_RefPtr_open0_nsAtom_close0_instantiation_12() {
assert_eq!( assert_eq!(
::std::mem::size_of::<root::RefPtr<root::nsAtom>>(), ::std::mem::size_of::<root::RefPtr<root::nsAtom>>(),
8usize, 8usize,
@ -46943,7 +47036,7 @@ pub mod root {
); );
} }
#[test] #[test]
fn __bindgen_test_layout_RefPtr_open0_nsAtom_close0_instantiation_11() { fn __bindgen_test_layout_RefPtr_open0_nsAtom_close0_instantiation_13() {
assert_eq!( assert_eq!(
::std::mem::size_of::<root::RefPtr<root::nsAtom>>(), ::std::mem::size_of::<root::RefPtr<root::nsAtom>>(),
8usize, 8usize,
@ -47518,7 +47611,7 @@ pub mod root {
); );
} }
#[test] #[test]
fn __bindgen_test_layout_RefPtr_open0_nsAtom_close0_instantiation_12() { fn __bindgen_test_layout_RefPtr_open0_nsAtom_close0_instantiation_14() {
assert_eq!( assert_eq!(
::std::mem::size_of::<root::RefPtr<root::nsAtom>>(), ::std::mem::size_of::<root::RefPtr<root::nsAtom>>(),
8usize, 8usize,
@ -48017,7 +48110,7 @@ pub mod root {
); );
} }
#[test] #[test]
fn __bindgen_test_layout_RefPtr_open0_nsAtom_close0_instantiation_13() { fn __bindgen_test_layout_RefPtr_open0_nsAtom_close0_instantiation_15() {
assert_eq!( assert_eq!(
::std::mem::size_of::<root::RefPtr<root::nsAtom>>(), ::std::mem::size_of::<root::RefPtr<root::nsAtom>>(),
8usize, 8usize,
@ -48093,7 +48186,7 @@ pub mod root {
); );
} }
#[test] #[test]
fn __bindgen_test_layout_RefPtr_open0_nsAtom_close0_instantiation_14() { fn __bindgen_test_layout_RefPtr_open0_nsAtom_close0_instantiation_16() {
assert_eq!( assert_eq!(
::std::mem::size_of::<root::RefPtr<root::nsAtom>>(), ::std::mem::size_of::<root::RefPtr<root::nsAtom>>(),
8usize, 8usize,

Просмотреть файл

@ -470,11 +470,11 @@ impl<'a, 'i> ::selectors::Parser<'i> for SelectorParser<'a> {
} }
fn default_namespace(&self) -> Option<Namespace> { fn default_namespace(&self) -> Option<Namespace> {
self.namespaces.default.clone().as_ref().map(|&(ref ns, _)| ns.clone()) self.namespaces.default.as_ref().map(|ns| ns.clone())
} }
fn namespace_for_prefix(&self, prefix: &Atom) -> Option<Namespace> { fn namespace_for_prefix(&self, prefix: &Atom) -> Option<Namespace> {
self.namespaces.prefixes.get(prefix).map(|&(ref ns, _)| ns.clone()) self.namespaces.prefixes.get(prefix).cloned()
} }
} }

Просмотреть файл

@ -55,6 +55,7 @@ use properties::{PropertyDeclaration, PropertyDeclarationBlock, PropertyDeclarat
use rule_tree::StrongRuleNode; use rule_tree::StrongRuleNode;
use selector_parser::PseudoElement; use selector_parser::PseudoElement;
use servo_arc::{Arc, RawOffsetArc}; use servo_arc::{Arc, RawOffsetArc};
use std::marker::PhantomData;
use std::mem::{forget, uninitialized, transmute, zeroed}; use std::mem::{forget, uninitialized, transmute, zeroed};
use std::{cmp, ops, ptr}; use std::{cmp, ops, ptr};
use values::{self, CustomIdent, Either, KeyframesName, None_}; use values::{self, CustomIdent, Either, KeyframesName, None_};
@ -5429,6 +5430,7 @@ clip-path
use values::computed::counters::{Content, ContentItem}; use values::computed::counters::{Content, ContentItem};
use values::generics::CounterStyleOrNone; use values::generics::CounterStyleOrNone;
use gecko_bindings::structs::nsStyleContentData; use gecko_bindings::structs::nsStyleContentData;
use gecko_bindings::structs::nsStyleContentAttr;
use gecko_bindings::structs::nsStyleContentType; use gecko_bindings::structs::nsStyleContentType;
use gecko_bindings::structs::nsStyleContentType::*; use gecko_bindings::structs::nsStyleContentType::*;
use gecko_bindings::bindings::Gecko_ClearAndResizeStyleContents; use gecko_bindings::bindings::Gecko_ClearAndResizeStyleContents;
@ -5505,14 +5507,19 @@ clip-path
self.gecko.mContents[i].mType = eStyleContentType_Attr; self.gecko.mContents[i].mType = eStyleContentType_Attr;
unsafe { unsafe {
// NB: we share allocators, so doing this is fine. // NB: we share allocators, so doing this is fine.
*self.gecko.mContents[i].mContent.mString.as_mut() = match attr.namespace { let maybe_ns = attr.namespace.clone();
Some((_, ns)) => { let attr_struct = Box::new(nsStyleContentAttr {
as_utf16_and_forget(&format!("{}|{}", ns, attr.attribute)) mName: structs::RefPtr {
mRawPtr: attr.attribute.clone().into_addrefed(),
_phantom_0: PhantomData,
}, },
None => { mNamespaceURL: structs::RefPtr {
as_utf16_and_forget(&attr.attribute) mRawPtr: maybe_ns.map_or(ptr::null_mut(), |x| (x.1).0.into_addrefed()),
} _phantom_0: PhantomData,
}; },
});
*self.gecko.mContents[i].mContent.mAttr.as_mut() =
Box::into_raw(attr_struct);
} }
} }
ContentItem::OpenQuote ContentItem::OpenQuote
@ -5569,7 +5576,7 @@ clip-path
} }
pub fn clone_content(&self) -> longhands::content::computed_value::T { pub fn clone_content(&self) -> longhands::content::computed_value::T {
use Atom; use {Atom, Namespace};
use gecko::conversions::string_from_chars_pointer; use gecko::conversions::string_from_chars_pointer;
use gecko_bindings::structs::nsStyleContentType::*; use gecko_bindings::structs::nsStyleContentType::*;
use values::computed::counters::{Content, ContentItem}; use values::computed::counters::{Content, ContentItem};
@ -5600,19 +5607,17 @@ clip-path
ContentItem::String(string.into_boxed_str()) ContentItem::String(string.into_boxed_str())
}, },
eStyleContentType_Attr => { eStyleContentType_Attr => {
let gecko_chars = unsafe { gecko_content.mContent.mString.as_ref() }; let (namespace, attribute) = unsafe {
let string = unsafe { string_from_chars_pointer(*gecko_chars) }; let s = &**gecko_content.mContent.mAttr.as_ref();
let (namespace, attribute) = let ns = if s.mNamespaceURL.mRawPtr.is_null() {
match string.find('|') { None
None => (None, string), } else {
Some(index) => { // FIXME(bholley): We don't have any way to get the prefix here. :-(
let (_, val) = string.split_at(index); let prefix = atom!("");
// FIXME: We should give NamespaceId as well to make Attr Some((prefix, Namespace(Atom::from_raw(s.mNamespaceURL.mRawPtr))))
// struct. However, there is no field for it in Gecko.
debug_assert!(false, "Attr with namespace does not support yet");
(None, val.to_string())
}
}; };
(ns, Atom::from_raw(s.mName.mRawPtr))
};
ContentItem::Attr(Attr { namespace, attribute }) ContentItem::Attr(Attr { namespace, attribute })
}, },
eStyleContentType_Counter | eStyleContentType_Counters => { eStyleContentType_Counter | eStyleContentType_Counters => {

Просмотреть файл

@ -591,11 +591,11 @@ impl<'a, 'i> ::selectors::Parser<'i> for SelectorParser<'a> {
} }
fn default_namespace(&self) -> Option<Namespace> { fn default_namespace(&self) -> Option<Namespace> {
self.namespaces.default.as_ref().map(|&(ref ns, _)| ns.clone()) self.namespaces.default.as_ref().map(|ns| ns.clone())
} }
fn namespace_for_prefix(&self, prefix: &Prefix) -> Option<Namespace> { fn namespace_for_prefix(&self, prefix: &Prefix) -> Option<Namespace> {
self.namespaces.prefixes.get(prefix).map(|&(ref ns, _)| ns.clone()) self.namespaces.prefixes.get(prefix).cloned()
} }
} }

Просмотреть файл

@ -137,20 +137,6 @@ pub enum AtRuleNonBlockPrelude {
Namespace(Option<Prefix>, Namespace, SourceLocation), Namespace(Option<Prefix>, Namespace, SourceLocation),
} }
#[cfg(feature = "gecko")]
fn register_namespace(ns: &Namespace) -> i32 {
use gecko_bindings::bindings;
let id = unsafe { bindings::Gecko_RegisterNamespace(ns.0.as_ptr()) };
debug_assert!(id >= 0);
id
}
#[cfg(feature = "servo")]
fn register_namespace(_: &Namespace) {
// servo doesn't use namespace ids
}
impl<'a, 'i, R: ParseErrorReporter> AtRuleParser<'i> for TopLevelRuleParser<'a, R> { impl<'a, 'i, R: ParseErrorReporter> AtRuleParser<'i> for TopLevelRuleParser<'a, R> {
type PreludeNoBlock = AtRuleNonBlockPrelude; type PreludeNoBlock = AtRuleNonBlockPrelude;
type PreludeBlock = AtRuleBlockPrelude; type PreludeBlock = AtRuleBlockPrelude;
@ -242,15 +228,13 @@ impl<'a, 'i, R: ParseErrorReporter> AtRuleParser<'i> for TopLevelRuleParser<'a,
CssRule::Import(import_rule) CssRule::Import(import_rule)
} }
AtRuleNonBlockPrelude::Namespace(prefix, url, location) => { AtRuleNonBlockPrelude::Namespace(prefix, url, location) => {
let id = register_namespace(&url);
let opt_prefix = if let Some(prefix) = prefix { let opt_prefix = if let Some(prefix) = prefix {
self.namespaces self.namespaces
.prefixes .prefixes
.insert(prefix.clone(), (url.clone(), id)); .insert(prefix.clone(), url.clone());
Some(prefix) Some(prefix)
} else { } else {
self.namespaces.default = Some((url.clone(), id)); self.namespaces.default = Some(url.clone());
None None
}; };

Просмотреть файл

@ -23,7 +23,6 @@ use stylesheets::{CssRule, CssRules, Origin, UrlExtraData};
use stylesheets::loader::StylesheetLoader; use stylesheets::loader::StylesheetLoader;
use stylesheets::rule_parser::{State, TopLevelRuleParser}; use stylesheets::rule_parser::{State, TopLevelRuleParser};
use stylesheets::rules_iterator::{EffectiveRules, EffectiveRulesIterator, NestedRuleIterationCondition, RulesIterator}; use stylesheets::rules_iterator::{EffectiveRules, EffectiveRulesIterator, NestedRuleIterationCondition, RulesIterator};
use values::specified::NamespaceId;
/// This structure holds the user-agent and user stylesheets. /// This structure holds the user-agent and user stylesheets.
pub struct UserAgentStylesheets { pub struct UserAgentStylesheets {
@ -41,8 +40,8 @@ pub struct UserAgentStylesheets {
#[derive(Clone, Debug, Default, MallocSizeOf)] #[derive(Clone, Debug, Default, MallocSizeOf)]
#[allow(missing_docs)] #[allow(missing_docs)]
pub struct Namespaces { pub struct Namespaces {
pub default: Option<(Namespace, NamespaceId)>, pub default: Option<Namespace>,
pub prefixes: FnvHashMap<Prefix, (Namespace, NamespaceId)>, pub prefixes: FnvHashMap<Prefix, Namespace>,
} }
/// The contents of a given stylesheet. This effectively maps to a /// The contents of a given stylesheet. This effectively maps to a

Просмотреть файл

@ -6,9 +6,9 @@
//! //!
//! TODO(emilio): Enhance docs. //! TODO(emilio): Enhance docs.
use Prefix; use {Atom, Namespace, Prefix};
use context::QuirksMode; use context::QuirksMode;
use cssparser::{Parser, Token, serialize_identifier}; use cssparser::{Parser, Token};
use num_traits::One; use num_traits::One;
use parser::{ParserContext, Parse}; use parser::{ParserContext, Parse};
use std::f32; use std::f32;
@ -685,24 +685,15 @@ impl AllowQuirks {
} }
} }
#[cfg(feature = "gecko")]
/// A namespace ID
pub type NamespaceId = i32;
#[cfg(feature = "servo")]
/// A namespace ID (used by gecko only)
pub type NamespaceId = ();
/// An attr(...) rule /// An attr(...) rule
/// ///
/// `[namespace? `|`]? ident` /// `[namespace? `|`]? ident`
#[derive(Clone, Debug, Eq, MallocSizeOf, PartialEq, ToComputedValue)] #[derive(Clone, Debug, Eq, MallocSizeOf, PartialEq, ToComputedValue)]
pub struct Attr { pub struct Attr {
/// Optional namespace prefix, with the actual namespace id. /// Optional namespace prefix and URL.
pub namespace: Option<(Prefix, NamespaceId)>, pub namespace: Option<(Prefix, Namespace)>,
/// Attribute name /// Attribute name
pub attribute: String, pub attribute: Atom,
} }
impl Parse for Attr { impl Parse for Attr {
@ -712,9 +703,9 @@ impl Parse for Attr {
} }
} }
/// Get the Namespace id from the namespace map. /// Get the Namespace for a given prefix from the namespace map.
fn get_id_for_namespace(prefix: &Prefix, context: &ParserContext) -> Option<NamespaceId> { fn get_namespace_for_prefix(prefix: &Prefix, context: &ParserContext) -> Option<Namespace> {
Some(context.namespaces.as_ref()?.prefixes.get(prefix)?.1) context.namespaces.as_ref()?.prefixes.get(prefix).map(|x| x.clone())
} }
impl Attr { impl Attr {
@ -737,21 +728,21 @@ impl Attr {
ref t => return Err(location.new_unexpected_token_error(t.clone())), ref t => return Err(location.new_unexpected_token_error(t.clone())),
}; };
let ns_with_id = if let Some(ns) = first { let prefix_and_ns = if let Some(ns) = first {
let ns = Prefix::from(ns.as_ref()); let prefix = Prefix::from(ns.as_ref());
let id = match get_id_for_namespace(&ns, context) { let ns = match get_namespace_for_prefix(&prefix, context) {
Some(id) => id, Some(ns) => ns,
None => return Err(location.new_custom_error( None => return Err(location.new_custom_error(
StyleParseErrorKind::UnspecifiedError StyleParseErrorKind::UnspecifiedError
)), )),
}; };
Some((ns, id)) Some((prefix, ns))
} else { } else {
None None
}; };
return Ok(Attr { return Ok(Attr {
namespace: ns_with_id, namespace: prefix_and_ns,
attribute: second_token.as_ref().to_owned(), attribute: Atom::from(second_token.as_ref()),
}) })
} }
// In the case of attr(foobar ) we don't want to error out // In the case of attr(foobar ) we don't want to error out
@ -764,7 +755,7 @@ impl Attr {
if let Some(first) = first { if let Some(first) = first {
Ok(Attr { Ok(Attr {
namespace: None, namespace: None,
attribute: first.as_ref().to_owned(), attribute: Atom::from(first.as_ref()),
}) })
} else { } else {
Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError))
@ -778,11 +769,11 @@ impl ToCss for Attr {
W: Write, W: Write,
{ {
dest.write_str("attr(")?; dest.write_str("attr(")?;
if let Some((ref prefix, _id)) = self.namespace { if let Some((ref prefix, ref _url)) = self.namespace {
serialize_atom_identifier(prefix, dest)?; serialize_atom_identifier(prefix, dest)?;
dest.write_str("|")?; dest.write_str("|")?;
} }
serialize_identifier(&self.attribute, dest)?; serialize_atom_identifier(&self.attribute, dest)?;
dest.write_str(")") dest.write_str(")")
} }
} }

Просмотреть файл

@ -559,6 +559,12 @@ macro_rules! define_string_types {
hdr: $StringRepr::new(ClassFlags::NULL_TERMINATED), hdr: $StringRepr::new(ClassFlags::NULL_TERMINATED),
} }
} }
/// Converts this String into a StringRepr, which will leak if the
/// repr is not passed to something that knows how to free it.
pub fn into_repr(mut self) -> $StringRepr {
mem::replace(&mut self.hdr, $StringRepr::new(ClassFlags::NULL_TERMINATED))
}
} }
impl Drop for $String { impl Drop for $String {

Просмотреть файл

@ -10,7 +10,7 @@ use style_traits::ParseError;
fn parse_selector<'i, 't>(input: &mut Parser<'i, 't>) -> Result<SelectorList<SelectorImpl>, ParseError<'i>> { fn parse_selector<'i, 't>(input: &mut Parser<'i, 't>) -> Result<SelectorList<SelectorImpl>, ParseError<'i>> {
let mut ns = Namespaces::default(); let mut ns = Namespaces::default();
ns.prefixes.insert("svg".into(), (ns!(svg), ())); ns.prefixes.insert("svg".into(), ns!(svg));
let parser = SelectorParser { let parser = SelectorParser {
stylesheet_origin: Origin::UserAgent, stylesheet_origin: Origin::UserAgent,
namespaces: &ns, namespaces: &ns,

Просмотреть файл

@ -73,7 +73,7 @@ fn test_parse_stylesheet() {
let stylesheet = Stylesheet::from_str(css, url.clone(), Origin::UserAgent, media, lock, let stylesheet = Stylesheet::from_str(css, url.clone(), Origin::UserAgent, media, lock,
None, &CSSErrorReporterTest, QuirksMode::NoQuirks, 0); None, &CSSErrorReporterTest, QuirksMode::NoQuirks, 0);
let mut namespaces = Namespaces::default(); let mut namespaces = Namespaces::default();
namespaces.default = Some((ns!(html), ())); namespaces.default = Some(ns!(html));
let expected = Stylesheet { let expected = Stylesheet {
contents: StylesheetContents { contents: StylesheetContents {
origin: Origin::UserAgent, origin: Origin::UserAgent,