aboutsummaryrefslogtreecommitdiffstats
path: root/components/style
diff options
context:
space:
mode:
authorEmilio Cobos Álvarez <emilio@crisal.io>2023-04-12 21:58:29 +0000
committerMartin Robinson <mrobinson@igalia.com>2023-11-21 15:36:35 +0100
commit0709e13446ed186d6868e82887ebda4850c69365 (patch)
tree169a9eefcadc2008600518106efce2329b3844af /components/style
parenta2df8f7ea5e76e7753d9649b7dfb1b0329510078 (diff)
downloadservo-0709e13446ed186d6868e82887ebda4850c69365.tar.gz
servo-0709e13446ed186d6868e82887ebda4850c69365.zip
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
Diffstat (limited to 'components/style')
-rw-r--r--components/style/Cargo.toml1
-rw-r--r--components/style/gecko/pseudo_element_definition.mako.rs8
-rw-r--r--components/style/gecko/selector_parser.rs33
-rw-r--r--components/style/gecko/wrapper.rs28
4 files changed, 22 insertions, 48 deletions
diff --git a/components/style/Cargo.toml b/components/style/Cargo.toml
index 802aefb988d..3a6ac07539b 100644
--- a/components/style/Cargo.toml
+++ b/components/style/Cargo.toml
@@ -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"
diff --git a/components/style/gecko/pseudo_element_definition.mako.rs b/components/style/gecko/pseudo_element_definition.mako.rs
index b7f8cca409c..73e7893c998 100644
--- a/components/style/gecko/pseudo_element_definition.mako.rs
+++ b/components/style/gecko/pseudo_element_definition.mako.rs
@@ -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
diff --git a/components/style/gecko/selector_parser.rs b/components/style/gecko/selector_parser.rs
index 2beaaa238d2..db1fda493c4 100644
--- a/components/style/gecko/selector_parser.rs
+++ b/components/style/gecko/selector_parser.rs
@@ -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);
diff --git a/components/style/gecko/wrapper.rs b/components/style/gecko/wrapper.rs
index 762ff037416..de2bd4c5f4c 100644
--- a/components/style/gecko/wrapper.rs
+++ b/components/style/gecko/wrapper.rs
@@ -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 {