Use a more compact representation to store eager pseudo-elements.

This means that ElementStyles only need a single word to store eager pseudos.

MozReview-Commit-ID: 5bDXlDweN46
This commit is contained in:
Bobby Holley 2017-03-31 18:04:29 -07:00
parent 1ff008caa3
commit 3f0d022ba2
6 changed files with 207 additions and 97 deletions

View file

@ -42,7 +42,39 @@ use string_cache::{Atom, Namespace, WeakAtom, WeakNamespace};
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct PseudoElement(Atom, bool);
/// List of eager pseudos. Keep this in sync with the count below.
macro_rules! each_eager_pseudo {
($macro_name:ident, $atom_macro:ident) => {
$macro_name!($atom_macro!(":after"), 0);
$macro_name!($atom_macro!(":before"), 1);
}
}
/// The number of eager pseudo-elements (just ::before and ::after).
pub const EAGER_PSEUDO_COUNT: usize = 2;
impl PseudoElement {
/// Gets the canonical index of this eagerly-cascaded pseudo-element.
#[inline]
pub fn eager_index(&self) -> usize {
macro_rules! case {
($atom:expr, $idx:expr) => { if *self.as_atom() == $atom { return $idx; } }
}
each_eager_pseudo!(case, atom);
panic!("Not eager")
}
/// Creates a pseudo-element from an eager index.
#[inline]
pub fn from_eager_index(i: usize) -> Self {
macro_rules! case {
($atom:expr, $idx:expr) => { if i == $idx { return PseudoElement($atom, false); } }
}
each_eager_pseudo!(case, atom);
panic!("Not eager")
}
/// Get the pseudo-element as an atom.
#[inline]
pub fn as_atom(&self) -> &Atom {
@ -65,7 +97,11 @@ impl PseudoElement {
/// Whether this pseudo-element is eagerly-cascaded.
#[inline]
pub fn is_eager(&self) -> bool {
self.is_before_or_after()
macro_rules! case {
($atom:expr, $idx:expr) => { if *self.as_atom() == $atom { return true; } }
}
each_eager_pseudo!(case, atom);
return false;
}
/// Whether this pseudo-element is lazily-cascaded.
@ -435,6 +471,19 @@ impl SelectorImpl {
PseudoElementCascadeType::Lazy
}
/// A helper to traverse each eagerly cascaded pseudo-element, executing
/// `fun` on it.
#[inline]
pub fn each_eagerly_cascaded_pseudo_element<F>(mut fun: F)
where F: FnMut(PseudoElement),
{
macro_rules! case {
($atom:expr, $idx:expr) => { fun(PseudoElement($atom, false)); }
}
each_eager_pseudo!(case, atom);
}
#[inline]
/// Executes a function for each pseudo-element.
pub fn each_pseudo_element<F>(mut fun: F)