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,90 +292,100 @@ 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,
@ -441,6 +457,18 @@ 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?")
})
}
};