mirror of
https://github.com/servo/servo.git
synced 2025-08-07 22:45:34 +01:00
style: Allow to use ThinVec/nsTArray in the style crate
This allows to clean-up the previous patches by using a single ThinVec (which stores length / capacity along with the allocation). Differential Revision: https://phabricator.services.mozilla.com/D175029
This commit is contained in:
parent
a2df8f7ea5
commit
0709e13446
9 changed files with 110 additions and 48 deletions
|
@ -77,6 +77,7 @@ string_cache = { version = "0.8", optional = true }
|
|||
style_derive = { path = "../style_derive" }
|
||||
style_traits = { workspace = true }
|
||||
time = "0.1"
|
||||
thin-vec = { version = "0.2.1", features = ["gecko-ffi"] }
|
||||
to_shmem = { path = "../to_shmem" }
|
||||
to_shmem_derive = { path = "../to_shmem_derive" }
|
||||
uluru = "3.0"
|
||||
|
|
|
@ -11,7 +11,7 @@ pub enum PseudoElement {
|
|||
% for pseudo in PSEUDOS:
|
||||
/// ${pseudo.value}
|
||||
% if pseudo.is_tree_pseudo_element():
|
||||
${pseudo.capitalized_pseudo()}(Box<Box<[Atom]>>),
|
||||
${pseudo.capitalized_pseudo()}(thin_vec::ThinVec<Atom>),
|
||||
% elif pseudo.pseudo_ident == "highlight":
|
||||
${pseudo.capitalized_pseudo()}(AtomIdent),
|
||||
% else:
|
||||
|
@ -210,7 +210,7 @@ impl PseudoElement {
|
|||
},
|
||||
_ => {
|
||||
if starts_with_ignore_ascii_case(name, "-moz-tree-") {
|
||||
return PseudoElement::tree_pseudo_element(name, Box::new([]))
|
||||
return PseudoElement::tree_pseudo_element(name, Default::default())
|
||||
}
|
||||
const WEBKIT_PREFIX: &str = "-webkit-";
|
||||
if allow_unkown_webkit && starts_with_ignore_ascii_case(name, WEBKIT_PREFIX) {
|
||||
|
@ -228,12 +228,12 @@ impl PseudoElement {
|
|||
///
|
||||
/// Returns `None` if the pseudo-element is not recognized.
|
||||
#[inline]
|
||||
pub fn tree_pseudo_element(name: &str, args: Box<[Atom]>) -> Option<Self> {
|
||||
pub fn tree_pseudo_element(name: &str, args: thin_vec::ThinVec<Atom>) -> Option<Self> {
|
||||
debug_assert!(starts_with_ignore_ascii_case(name, "-moz-tree-"));
|
||||
let tree_part = &name[10..];
|
||||
% for pseudo in TREE_PSEUDOS:
|
||||
if tree_part.eq_ignore_ascii_case("${pseudo.value[11:]}") {
|
||||
return Some(${pseudo_element_variant(pseudo, "args.into()")});
|
||||
return Some(${pseudo_element_variant(pseudo, "args")});
|
||||
}
|
||||
% endfor
|
||||
None
|
||||
|
|
|
@ -19,7 +19,8 @@ use dom::{DocumentState, ElementState};
|
|||
use selectors::parser::SelectorParseErrorKind;
|
||||
use selectors::SelectorList;
|
||||
use std::fmt;
|
||||
use style_traits::{Comma, CssWriter, OneOrMoreSeparated, ParseError, StyleParseErrorKind, ToCss as ToCss_};
|
||||
use style_traits::{CssWriter, ParseError, StyleParseErrorKind, ToCss as ToCss_};
|
||||
use thin_vec::ThinVec;
|
||||
|
||||
pub use crate::gecko::pseudo_element::{
|
||||
PseudoElement, EAGER_PSEUDOS, EAGER_PSEUDO_COUNT, PSEUDO_COUNT,
|
||||
|
@ -38,13 +39,9 @@ bitflags! {
|
|||
}
|
||||
|
||||
/// The type used to store the language argument to the `:lang` pseudo-class.
|
||||
#[derive(Clone, Debug, Eq, MallocSizeOf, PartialEq, ToShmem)]
|
||||
pub enum Lang {
|
||||
/// A single language code.
|
||||
Single(AtomIdent),
|
||||
/// A list of language codes.
|
||||
List(Box<Vec<AtomIdent>>),
|
||||
}
|
||||
#[derive(Clone, Debug, Eq, MallocSizeOf, PartialEq, ToCss, ToShmem)]
|
||||
#[css(comma)]
|
||||
pub struct Lang(#[css(iterable)] pub ThinVec<AtomIdent>);
|
||||
|
||||
macro_rules! pseudo_class_name {
|
||||
([$(($css:expr, $name:ident, $state:tt, $flags:tt),)*]) => {
|
||||
|
@ -66,10 +63,6 @@ macro_rules! pseudo_class_name {
|
|||
}
|
||||
apply_non_ts_list!(pseudo_class_name);
|
||||
|
||||
impl OneOrMoreSeparated for AtomIdent {
|
||||
type S = Comma;
|
||||
}
|
||||
|
||||
impl ToCss for NonTSPseudoClass {
|
||||
fn to_css<W>(&self, dest: &mut W) -> fmt::Result
|
||||
where
|
||||
|
@ -79,12 +72,9 @@ impl ToCss for NonTSPseudoClass {
|
|||
([$(($css:expr, $name:ident, $state:tt, $flags:tt),)*]) => {
|
||||
match *self {
|
||||
$(NonTSPseudoClass::$name => concat!(":", $css),)*
|
||||
NonTSPseudoClass::Lang(ref s) => {
|
||||
NonTSPseudoClass::Lang(ref lang) => {
|
||||
dest.write_str(":lang(")?;
|
||||
match &s {
|
||||
Lang::Single(lang) => cssparser::ToCss::to_css(lang, dest)?,
|
||||
Lang::List(list) => list.to_css(&mut CssWriter::new(dest))?,
|
||||
}
|
||||
lang.to_css(&mut CssWriter::new(dest))?;
|
||||
return dest.write_char(')');
|
||||
},
|
||||
NonTSPseudoClass::MozLocaleDir(ref dir) => {
|
||||
|
@ -394,11 +384,7 @@ impl<'a, 'i> ::selectors::Parser<'i> for SelectorParser<'a> {
|
|||
if result.is_empty() {
|
||||
return Err(parser.new_custom_error(StyleParseErrorKind::UnspecifiedError));
|
||||
}
|
||||
if result.len() == 1 {
|
||||
NonTSPseudoClass::Lang(Lang::Single(result[0].clone()))
|
||||
} else {
|
||||
NonTSPseudoClass::Lang(Lang::List(Box::new(result)))
|
||||
}
|
||||
NonTSPseudoClass::Lang(Lang(result.into()))
|
||||
},
|
||||
"-moz-locale-dir" => {
|
||||
NonTSPseudoClass::MozLocaleDir(Direction::parse(parser)?)
|
||||
|
@ -448,7 +434,7 @@ impl<'a, 'i> ::selectors::Parser<'i> for SelectorParser<'a> {
|
|||
if starts_with_ignore_ascii_case(&name, "-moz-tree-") {
|
||||
// Tree pseudo-elements can have zero or more arguments, separated
|
||||
// by either comma or space.
|
||||
let mut args = Vec::new();
|
||||
let mut args = ThinVec::new();
|
||||
loop {
|
||||
let location = parser.current_source_location();
|
||||
match parser.next() {
|
||||
|
@ -462,7 +448,6 @@ impl<'a, 'i> ::selectors::Parser<'i> for SelectorParser<'a> {
|
|||
_ => unreachable!("Parser::next() shouldn't return any other error"),
|
||||
}
|
||||
}
|
||||
let args = args.into_boxed_slice();
|
||||
if let Some(pseudo) = PseudoElement::tree_pseudo_element(&name, args) {
|
||||
if self.is_pseudo_element_enabled(&pseudo) {
|
||||
return Ok(pseudo);
|
||||
|
|
|
@ -1566,26 +1566,14 @@ impl<'le> TElement for GeckoElement<'le> {
|
|||
Some(Some(ref atom)) => atom.as_ptr(),
|
||||
_ => ptr::null_mut(),
|
||||
};
|
||||
match value {
|
||||
Lang::Single(lang) => unsafe {
|
||||
Gecko_MatchLang(
|
||||
self.0,
|
||||
override_lang_ptr,
|
||||
override_lang.is_some(),
|
||||
lang.as_slice().as_ptr(),
|
||||
)
|
||||
},
|
||||
Lang::List(list) => {
|
||||
list.iter().any(|lang| unsafe {
|
||||
Gecko_MatchLang(
|
||||
self.0,
|
||||
override_lang_ptr,
|
||||
override_lang.is_some(),
|
||||
lang.as_slice().as_ptr(),
|
||||
)
|
||||
})
|
||||
},
|
||||
}
|
||||
value.0.iter().any(|lang| unsafe {
|
||||
Gecko_MatchLang(
|
||||
self.0,
|
||||
override_lang_ptr,
|
||||
override_lang.is_some(),
|
||||
lang.as_slice().as_ptr(),
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
fn is_html_document_body_element(&self) -> bool {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue