Add slots in PerPseudoElementMap for tree pseudos.

This commit is contained in:
Xidorn Quan 2017-10-20 14:08:35 +11:00
parent b743d68ccd
commit 4ce3dc7729
6 changed files with 203 additions and 185 deletions

View file

@ -185,6 +185,12 @@ pub const EAGER_PSEUDO_COUNT: usize = 4;
/// The number of non-functional pseudo-elements.
pub const SIMPLE_PSEUDO_COUNT: usize = 71;
/// The number of tree pseudo-elements.
pub const TREE_PSEUDO_COUNT: usize = 12;
/// The number of all pseudo-elements.
pub const PSEUDO_COUNT: usize = 83;
/// The list of eager pseudos.
pub const EAGER_PSEUDOS: [PseudoElement; EAGER_PSEUDO_COUNT] = [
PseudoElement::Before,
@ -286,162 +292,184 @@ impl PseudoElement {
}
}
/// Returns an index if the pseudo-element is a simple (non-functional)
/// pseudo.
/// Returns an index of the pseudo-element.
#[inline]
pub fn simple_index(&self) -> Option<usize> {
pub fn index(&self) -> usize {
match *self {
PseudoElement::After => Some(0),
PseudoElement::Before => Some(1),
PseudoElement::Backdrop => Some(2),
PseudoElement::Cue => Some(3),
PseudoElement::FirstLetter => Some(4),
PseudoElement::FirstLine => Some(5),
PseudoElement::MozSelection => Some(6),
PseudoElement::MozFocusInner => Some(7),
PseudoElement::MozFocusOuter => Some(8),
PseudoElement::MozListBullet => Some(9),
PseudoElement::MozListNumber => Some(10),
PseudoElement::MozMathAnonymous => Some(11),
PseudoElement::MozNumberWrapper => Some(12),
PseudoElement::MozNumberText => Some(13),
PseudoElement::MozNumberSpinBox => Some(14),
PseudoElement::MozNumberSpinUp => Some(15),
PseudoElement::MozNumberSpinDown => Some(16),
PseudoElement::MozProgressBar => Some(17),
PseudoElement::MozRangeTrack => Some(18),
PseudoElement::MozRangeProgress => Some(19),
PseudoElement::MozRangeThumb => Some(20),
PseudoElement::MozMeterBar => Some(21),
PseudoElement::MozPlaceholder => Some(22),
PseudoElement::Placeholder => Some(23),
PseudoElement::MozColorSwatch => Some(24),
PseudoElement::MozText => Some(25),
PseudoElement::OofPlaceholder => Some(26),
PseudoElement::FirstLetterContinuation => Some(27),
PseudoElement::MozBlockInsideInlineWrapper => Some(28),
PseudoElement::MozMathMLAnonymousBlock => Some(29),
PseudoElement::MozXULAnonymousBlock => Some(30),
PseudoElement::HorizontalFramesetBorder => Some(31),
PseudoElement::VerticalFramesetBorder => Some(32),
PseudoElement::MozLineFrame => Some(33),
PseudoElement::ButtonContent => Some(34),
PseudoElement::CellContent => Some(35),
PseudoElement::DropDownList => Some(36),
PseudoElement::FieldsetContent => Some(37),
PseudoElement::FramesetBlank => Some(38),
PseudoElement::MozDisplayComboboxControlFrame => Some(39),
PseudoElement::HtmlCanvasContent => Some(40),
PseudoElement::InlineTable => Some(41),
PseudoElement::Table => Some(42),
PseudoElement::TableCell => Some(43),
PseudoElement::TableColGroup => Some(44),
PseudoElement::TableCol => Some(45),
PseudoElement::TableWrapper => Some(46),
PseudoElement::TableRowGroup => Some(47),
PseudoElement::TableRow => Some(48),
PseudoElement::Canvas => Some(49),
PseudoElement::PageBreak => Some(50),
PseudoElement::Page => Some(51),
PseudoElement::PageContent => Some(52),
PseudoElement::PageSequence => Some(53),
PseudoElement::ScrolledContent => Some(54),
PseudoElement::ScrolledCanvas => Some(55),
PseudoElement::ScrolledPageSequence => Some(56),
PseudoElement::ColumnContent => Some(57),
PseudoElement::Viewport => Some(58),
PseudoElement::ViewportScroll => Some(59),
PseudoElement::AnonymousFlexItem => Some(60),
PseudoElement::AnonymousGridItem => Some(61),
PseudoElement::Ruby => Some(62),
PseudoElement::RubyBase => Some(63),
PseudoElement::RubyBaseContainer => Some(64),
PseudoElement::RubyText => Some(65),
PseudoElement::RubyTextContainer => Some(66),
PseudoElement::MozSVGMarkerAnonChild => Some(67),
PseudoElement::MozSVGOuterSVGAnonChild => Some(68),
PseudoElement::MozSVGForeignContent => Some(69),
PseudoElement::MozSVGText => Some(70),
_ => None,
PseudoElement::After => 0,
PseudoElement::Before => 1,
PseudoElement::Backdrop => 2,
PseudoElement::Cue => 3,
PseudoElement::FirstLetter => 4,
PseudoElement::FirstLine => 5,
PseudoElement::MozSelection => 6,
PseudoElement::MozFocusInner => 7,
PseudoElement::MozFocusOuter => 8,
PseudoElement::MozListBullet => 9,
PseudoElement::MozListNumber => 10,
PseudoElement::MozMathAnonymous => 11,
PseudoElement::MozNumberWrapper => 12,
PseudoElement::MozNumberText => 13,
PseudoElement::MozNumberSpinBox => 14,
PseudoElement::MozNumberSpinUp => 15,
PseudoElement::MozNumberSpinDown => 16,
PseudoElement::MozProgressBar => 17,
PseudoElement::MozRangeTrack => 18,
PseudoElement::MozRangeProgress => 19,
PseudoElement::MozRangeThumb => 20,
PseudoElement::MozMeterBar => 21,
PseudoElement::MozPlaceholder => 22,
PseudoElement::Placeholder => 23,
PseudoElement::MozColorSwatch => 24,
PseudoElement::MozText => 25,
PseudoElement::OofPlaceholder => 26,
PseudoElement::FirstLetterContinuation => 27,
PseudoElement::MozBlockInsideInlineWrapper => 28,
PseudoElement::MozMathMLAnonymousBlock => 29,
PseudoElement::MozXULAnonymousBlock => 30,
PseudoElement::HorizontalFramesetBorder => 31,
PseudoElement::VerticalFramesetBorder => 32,
PseudoElement::MozLineFrame => 33,
PseudoElement::ButtonContent => 34,
PseudoElement::CellContent => 35,
PseudoElement::DropDownList => 36,
PseudoElement::FieldsetContent => 37,
PseudoElement::FramesetBlank => 38,
PseudoElement::MozDisplayComboboxControlFrame => 39,
PseudoElement::HtmlCanvasContent => 40,
PseudoElement::InlineTable => 41,
PseudoElement::Table => 42,
PseudoElement::TableCell => 43,
PseudoElement::TableColGroup => 44,
PseudoElement::TableCol => 45,
PseudoElement::TableWrapper => 46,
PseudoElement::TableRowGroup => 47,
PseudoElement::TableRow => 48,
PseudoElement::Canvas => 49,
PseudoElement::PageBreak => 50,
PseudoElement::Page => 51,
PseudoElement::PageContent => 52,
PseudoElement::PageSequence => 53,
PseudoElement::ScrolledContent => 54,
PseudoElement::ScrolledCanvas => 55,
PseudoElement::ScrolledPageSequence => 56,
PseudoElement::ColumnContent => 57,
PseudoElement::Viewport => 58,
PseudoElement::ViewportScroll => 59,
PseudoElement::AnonymousFlexItem => 60,
PseudoElement::AnonymousGridItem => 61,
PseudoElement::Ruby => 62,
PseudoElement::RubyBase => 63,
PseudoElement::RubyBaseContainer => 64,
PseudoElement::RubyText => 65,
PseudoElement::RubyTextContainer => 66,
PseudoElement::MozTreeColumn(..) => 67,
PseudoElement::MozTreeRow(..) => 68,
PseudoElement::MozTreeSeparator(..) => 69,
PseudoElement::MozTreeCell(..) => 70,
PseudoElement::MozTreeIndentation(..) => 71,
PseudoElement::MozTreeLine(..) => 72,
PseudoElement::MozTreeTwisty(..) => 73,
PseudoElement::MozTreeImage(..) => 74,
PseudoElement::MozTreeCellText(..) => 75,
PseudoElement::MozTreeCheckbox(..) => 76,
PseudoElement::MozTreeProgressmeter(..) => 77,
PseudoElement::MozTreeDropFeedback(..) => 78,
PseudoElement::MozSVGMarkerAnonChild => 79,
PseudoElement::MozSVGOuterSVGAnonChild => 80,
PseudoElement::MozSVGForeignContent => 81,
PseudoElement::MozSVGText => 82,
}
}
/// Returns an array of `None` values.
///
/// FIXME(emilio): Integer generics can't come soon enough.
pub fn simple_pseudo_none_array<T>() -> [Option<T>; SIMPLE_PSEUDO_COUNT] {
pub fn pseudo_none_array<T>() -> [Option<T>; PSEUDO_COUNT] {
[
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None
]
}

View file

@ -27,6 +27,12 @@ pub const EAGER_PSEUDO_COUNT: usize = ${len(EAGER_PSEUDOS)};
/// The number of non-functional pseudo-elements.
pub const SIMPLE_PSEUDO_COUNT: usize = ${len(SIMPLE_PSEUDOS)};
/// The number of tree pseudo-elements.
pub const TREE_PSEUDO_COUNT: usize = ${len(TREE_PSEUDOS)};
/// The number of all pseudo-elements.
pub const PSEUDO_COUNT: usize = ${len(PSEUDOS)};
/// The list of eager pseudos.
pub const EAGER_PSEUDOS: [PseudoElement; EAGER_PSEUDO_COUNT] = [
% for eager_pseudo_name in EAGER_PSEUDOS:
@ -49,24 +55,22 @@ impl PseudoElement {
}
}
/// Returns an index if the pseudo-element is a simple (non-functional)
/// pseudo.
/// Returns an index of the pseudo-element.
#[inline]
pub fn simple_index(&self) -> Option<usize> {
pub fn index(&self) -> usize {
match *self {
% for i, pseudo in enumerate(SIMPLE_PSEUDOS):
${pseudo_element_variant(pseudo)} => Some(${i}),
% for i, pseudo in enumerate(PSEUDOS):
${pseudo_element_variant(pseudo)} => ${i},
% endfor
_ => None,
}
}
/// Returns an array of `None` values.
///
/// FIXME(emilio): Integer generics can't come soon enough.
pub fn simple_pseudo_none_array<T>() -> [Option<T>; SIMPLE_PSEUDO_COUNT] {
pub fn pseudo_none_array<T>() -> [Option<T>; PSEUDO_COUNT] {
[
${",\n".join(["None" for pseudo in SIMPLE_PSEUDOS])}
${",\n ".join(["None" for pseudo in PSEUDOS])}
]
}

View file

@ -17,7 +17,7 @@ use std::fmt;
use string_cache::{Atom, Namespace, WeakAtom, WeakNamespace};
use style_traits::{ParseError, StyleParseErrorKind};
pub use gecko::pseudo_element::{PseudoElement, EAGER_PSEUDOS, EAGER_PSEUDO_COUNT, SIMPLE_PSEUDO_COUNT};
pub use gecko::pseudo_element::{PseudoElement, EAGER_PSEUDOS, EAGER_PSEUDO_COUNT, PSEUDO_COUNT};
pub use gecko::snapshot::SnapshotMap;
bitflags! {

View file

@ -102,16 +102,16 @@ pub enum PseudoElementCascadeType {
Precomputed,
}
/// A per-functional-pseudo map, from a given pseudo to a `T`.
/// A per-pseudo map, from a given pseudo to a `T`.
#[derive(MallocSizeOf)]
pub struct PerPseudoElementMap<T> {
entries: [Option<T>; SIMPLE_PSEUDO_COUNT],
entries: [Option<T>; PSEUDO_COUNT],
}
impl<T> Default for PerPseudoElementMap<T> {
fn default() -> Self {
Self {
entries: PseudoElement::simple_pseudo_none_array(),
entries: PseudoElement::pseudo_none_array(),
}
}
}
@ -137,11 +137,7 @@ where
impl<T> PerPseudoElementMap<T> {
/// Get an entry in the map.
pub fn get(&self, pseudo: &PseudoElement) -> Option<&T> {
let index = match pseudo.simple_index() {
Some(i) => i,
None => return None,
};
self.entries[index].as_ref()
self.entries[pseudo.index()].as_ref()
}
/// Clear this enumerated array.
@ -161,13 +157,8 @@ impl<T> PerPseudoElementMap<T> {
/// Set an entry value.
///
/// Returns an error if the element is not a simple pseudo.
pub fn set(&mut self, pseudo: &PseudoElement, value: T) -> Result<(), ()> {
let index = match pseudo.simple_index() {
Some(i) => i,
None => return Err(()),
};
self.entries[index] = Some(value);
Ok(())
pub fn set(&mut self, pseudo: &PseudoElement, value: T) {
self.entries[pseudo.index()] = Some(value);
}
/// Get an entry for `pseudo`, or create it with calling `f`.
@ -175,18 +166,15 @@ impl<T> PerPseudoElementMap<T> {
&mut self,
pseudo: &PseudoElement,
f: F,
) -> Result<&mut T, ()>
) -> &mut T
where
F: FnOnce() -> T,
{
let index = match pseudo.simple_index() {
Some(i) => i,
None => return Err(()),
};
let index = pseudo.index();
if self.entries[index].is_none() {
self.entries[index] = Some(f());
}
Ok(self.entries[index].as_mut().unwrap())
self.entries[index].as_mut().unwrap()
}
/// Get an iterator for the entries.

View file

@ -62,9 +62,8 @@ pub enum PseudoElement {
ServoInlineAbsolute,
}
/// The count of simple (non-functional) pseudo-elements (that is, all
/// pseudo-elements for now).
pub const SIMPLE_PSEUDO_COUNT: usize = PseudoElement::ServoInlineAbsolute as usize + 1;
/// The count of all pseudo-elements.
pub const PSEUDO_COUNT: usize = PseudoElement::ServoInlineAbsolute as usize + 1;
impl ::selectors::parser::PseudoElement for PseudoElement {
type Impl = SelectorImpl;
@ -110,12 +109,12 @@ impl PseudoElement {
/// An index for this pseudo-element to be indexed in an enumerated array.
#[inline]
pub fn simple_index(&self) -> Option<usize> {
Some(self.clone() as usize)
pub fn index(&self) -> usize {
self.clone() as usize
}
/// An array of `None`, one per simple pseudo-element.
pub fn simple_pseudo_none_array<T>() -> [Option<T>; SIMPLE_PSEUDO_COUNT] {
/// An array of `None`, one per pseudo-element.
pub fn pseudo_none_array<T>() -> [Option<T>; PSEUDO_COUNT] {
Default::default()
}

View file

@ -1995,7 +1995,6 @@ impl CascadeData {
.as_mut()
.expect("Expected precomputed declarations for the UA level")
.get_or_insert_with(&pseudo.canonical(), Vec::new)
.expect("Unexpected tree pseudo-element?")
.push(ApplicableDeclarationBlock::new(
StyleSource::Style(locked.clone()),
self.rules_source_order,
@ -2012,7 +2011,7 @@ impl CascadeData {
let mut map = Box::new(SelectorMap::new());
map.begin_mutation();
map
}).expect("Unexpected tree pseudo-element?")
})
}
};