Rename SimpleSelector to Component.

MozReview-Commit-ID: JfaZpHSkG8h
This commit is contained in:
Bobby Holley 2017-04-20 12:25:51 -07:00
parent cf06e2bf1e
commit cebacc7faa
7 changed files with 205 additions and 209 deletions

View file

@ -2,8 +2,8 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use bloom::BloomFilter; use bloom::BloomFilter;
use parser::{CaseSensitivity, Combinator, ComplexSelector, LocalName}; use parser::{CaseSensitivity, Combinator, ComplexSelector, Component, LocalName};
use parser::{SimpleSelector, Selector, SelectorInner, SelectorIter}; use parser::{Selector, SelectorInner, SelectorIter};
use std::borrow::Borrow; use std::borrow::Borrow;
use tree::Element; use tree::Element;
@ -297,7 +297,7 @@ fn matches_complex_selector_internal<E, F>(mut selector_iter: SelectorIter<E::Im
/// Determines whether the given element matches the given single selector. /// Determines whether the given element matches the given single selector.
#[inline] #[inline]
fn matches_simple_selector<E, F>( fn matches_simple_selector<E, F>(
selector: &SimpleSelector<E::Impl>, selector: &Component<E::Impl>,
element: &E, element: &E,
relations: &mut StyleRelations, relations: &mut StyleRelations,
flags_setter: &mut F) flags_setter: &mut F)
@ -317,108 +317,108 @@ fn matches_simple_selector<E, F>(
} }
match *selector { match *selector {
SimpleSelector::Combinator(_) => unreachable!(), Component::Combinator(_) => unreachable!(),
SimpleSelector::LocalName(LocalName { ref name, ref lower_name }) => { Component::LocalName(LocalName { ref name, ref lower_name }) => {
let name = if element.is_html_element_in_html_document() { lower_name } else { name }; let name = if element.is_html_element_in_html_document() { lower_name } else { name };
element.get_local_name() == name.borrow() element.get_local_name() == name.borrow()
} }
SimpleSelector::Namespace(ref namespace) => { Component::Namespace(ref namespace) => {
element.get_namespace() == namespace.url.borrow() element.get_namespace() == namespace.url.borrow()
} }
// TODO: case-sensitivity depends on the document type and quirks mode // TODO: case-sensitivity depends on the document type and quirks mode
SimpleSelector::ID(ref id) => { Component::ID(ref id) => {
relation_if!(element.get_id().map_or(false, |attr| attr == *id), relation_if!(element.get_id().map_or(false, |attr| attr == *id),
AFFECTED_BY_ID_SELECTOR) AFFECTED_BY_ID_SELECTOR)
} }
SimpleSelector::Class(ref class) => { Component::Class(ref class) => {
element.has_class(class) element.has_class(class)
} }
SimpleSelector::AttrExists(ref attr) => { Component::AttrExists(ref attr) => {
element.match_attr_has(attr) element.match_attr_has(attr)
} }
SimpleSelector::AttrEqual(ref attr, ref value, case_sensitivity) => { Component::AttrEqual(ref attr, ref value, case_sensitivity) => {
match case_sensitivity { match case_sensitivity {
CaseSensitivity::CaseSensitive => element.match_attr_equals(attr, value), CaseSensitivity::CaseSensitive => element.match_attr_equals(attr, value),
CaseSensitivity::CaseInsensitive => element.match_attr_equals_ignore_ascii_case(attr, value), CaseSensitivity::CaseInsensitive => element.match_attr_equals_ignore_ascii_case(attr, value),
} }
} }
SimpleSelector::AttrIncludes(ref attr, ref value) => { Component::AttrIncludes(ref attr, ref value) => {
element.match_attr_includes(attr, value) element.match_attr_includes(attr, value)
} }
SimpleSelector::AttrDashMatch(ref attr, ref value) => { Component::AttrDashMatch(ref attr, ref value) => {
element.match_attr_dash(attr, value) element.match_attr_dash(attr, value)
} }
SimpleSelector::AttrPrefixMatch(ref attr, ref value) => { Component::AttrPrefixMatch(ref attr, ref value) => {
element.match_attr_prefix(attr, value) element.match_attr_prefix(attr, value)
} }
SimpleSelector::AttrSubstringMatch(ref attr, ref value) => { Component::AttrSubstringMatch(ref attr, ref value) => {
element.match_attr_substring(attr, value) element.match_attr_substring(attr, value)
} }
SimpleSelector::AttrSuffixMatch(ref attr, ref value) => { Component::AttrSuffixMatch(ref attr, ref value) => {
element.match_attr_suffix(attr, value) element.match_attr_suffix(attr, value)
} }
SimpleSelector::AttrIncludesNeverMatch(..) | Component::AttrIncludesNeverMatch(..) |
SimpleSelector::AttrPrefixNeverMatch(..) | Component::AttrPrefixNeverMatch(..) |
SimpleSelector::AttrSubstringNeverMatch(..) | Component::AttrSubstringNeverMatch(..) |
SimpleSelector::AttrSuffixNeverMatch(..) => { Component::AttrSuffixNeverMatch(..) => {
false false
} }
SimpleSelector::NonTSPseudoClass(ref pc) => { Component::NonTSPseudoClass(ref pc) => {
relation_if!(element.match_non_ts_pseudo_class(pc, relations, flags_setter), relation_if!(element.match_non_ts_pseudo_class(pc, relations, flags_setter),
AFFECTED_BY_STATE) AFFECTED_BY_STATE)
} }
SimpleSelector::FirstChild => { Component::FirstChild => {
relation_if!(matches_first_child(element, flags_setter), relation_if!(matches_first_child(element, flags_setter),
AFFECTED_BY_CHILD_INDEX) AFFECTED_BY_CHILD_INDEX)
} }
SimpleSelector::LastChild => { Component::LastChild => {
relation_if!(matches_last_child(element, flags_setter), relation_if!(matches_last_child(element, flags_setter),
AFFECTED_BY_CHILD_INDEX) AFFECTED_BY_CHILD_INDEX)
} }
SimpleSelector::OnlyChild => { Component::OnlyChild => {
relation_if!(matches_first_child(element, flags_setter) && relation_if!(matches_first_child(element, flags_setter) &&
matches_last_child(element, flags_setter), matches_last_child(element, flags_setter),
AFFECTED_BY_CHILD_INDEX) AFFECTED_BY_CHILD_INDEX)
} }
SimpleSelector::Root => { Component::Root => {
// We never share styles with an element with no parent, so no point // We never share styles with an element with no parent, so no point
// in creating a new StyleRelation. // in creating a new StyleRelation.
element.is_root() element.is_root()
} }
SimpleSelector::Empty => { Component::Empty => {
flags_setter(element, HAS_EMPTY_SELECTOR); flags_setter(element, HAS_EMPTY_SELECTOR);
relation_if!(element.is_empty(), AFFECTED_BY_EMPTY) relation_if!(element.is_empty(), AFFECTED_BY_EMPTY)
} }
SimpleSelector::NthChild(a, b) => { Component::NthChild(a, b) => {
relation_if!(matches_generic_nth_child(element, a, b, false, false, flags_setter), relation_if!(matches_generic_nth_child(element, a, b, false, false, flags_setter),
AFFECTED_BY_CHILD_INDEX) AFFECTED_BY_CHILD_INDEX)
} }
SimpleSelector::NthLastChild(a, b) => { Component::NthLastChild(a, b) => {
relation_if!(matches_generic_nth_child(element, a, b, false, true, flags_setter), relation_if!(matches_generic_nth_child(element, a, b, false, true, flags_setter),
AFFECTED_BY_CHILD_INDEX) AFFECTED_BY_CHILD_INDEX)
} }
SimpleSelector::NthOfType(a, b) => { Component::NthOfType(a, b) => {
relation_if!(matches_generic_nth_child(element, a, b, true, false, flags_setter), relation_if!(matches_generic_nth_child(element, a, b, true, false, flags_setter),
AFFECTED_BY_CHILD_INDEX) AFFECTED_BY_CHILD_INDEX)
} }
SimpleSelector::NthLastOfType(a, b) => { Component::NthLastOfType(a, b) => {
relation_if!(matches_generic_nth_child(element, a, b, true, true, flags_setter), relation_if!(matches_generic_nth_child(element, a, b, true, true, flags_setter),
AFFECTED_BY_CHILD_INDEX) AFFECTED_BY_CHILD_INDEX)
} }
SimpleSelector::FirstOfType => { Component::FirstOfType => {
relation_if!(matches_generic_nth_child(element, 0, 1, true, false, flags_setter), relation_if!(matches_generic_nth_child(element, 0, 1, true, false, flags_setter),
AFFECTED_BY_CHILD_INDEX) AFFECTED_BY_CHILD_INDEX)
} }
SimpleSelector::LastOfType => { Component::LastOfType => {
relation_if!(matches_generic_nth_child(element, 0, 1, true, true, flags_setter), relation_if!(matches_generic_nth_child(element, 0, 1, true, true, flags_setter),
AFFECTED_BY_CHILD_INDEX) AFFECTED_BY_CHILD_INDEX)
} }
SimpleSelector::OnlyOfType => { Component::OnlyOfType => {
relation_if!(matches_generic_nth_child(element, 0, 1, true, false, flags_setter) && relation_if!(matches_generic_nth_child(element, 0, 1, true, false, flags_setter) &&
matches_generic_nth_child(element, 0, 1, true, true, flags_setter), matches_generic_nth_child(element, 0, 1, true, true, flags_setter),
AFFECTED_BY_CHILD_INDEX) AFFECTED_BY_CHILD_INDEX)
} }
SimpleSelector::Negation(ref negated) => { Component::Negation(ref negated) => {
!negated.iter().all(|s| { !negated.iter().all(|s| {
match matches_complex_selector_internal(s.iter(), match matches_complex_selector_internal(s.iter(),
element, element,

View file

@ -164,8 +164,8 @@ impl<Impl: SelectorImpl> SelectorInner<Impl> {
} }
} }
/// Creates a SelectorInner from a Vec of SimpleSelectors. Used in tests. /// Creates a SelectorInner from a Vec of Components. Used in tests.
pub fn from_vec(vec: Vec<SimpleSelector<Impl>>) -> Self { pub fn from_vec(vec: Vec<Component<Impl>>) -> Self {
let complex = ComplexSelector::from_vec(vec); let complex = ComplexSelector::from_vec(vec);
Self::new(complex) Self::new(complex)
} }
@ -224,13 +224,13 @@ impl<Impl: SelectorImpl> SelectorMethods for ComplexSelector<Impl> {
} }
} }
impl<Impl: SelectorImpl> SelectorMethods for SimpleSelector<Impl> { impl<Impl: SelectorImpl> SelectorMethods for Component<Impl> {
type Impl = Impl; type Impl = Impl;
fn visit<V>(&self, visitor: &mut V) -> bool fn visit<V>(&self, visitor: &mut V) -> bool
where V: SelectorVisitor<Impl = Impl>, where V: SelectorVisitor<Impl = Impl>,
{ {
use self::SimpleSelector::*; use self::Component::*;
if !visitor.visit_simple_selector(self) { if !visitor.visit_simple_selector(self) {
return false; return false;
} }
@ -275,7 +275,7 @@ impl<Impl: SelectorImpl> SelectorMethods for SimpleSelector<Impl> {
/// canonical iteration order is right-to-left (selector matching order). The /// canonical iteration order is right-to-left (selector matching order). The
/// iterators abstract over these details. /// iterators abstract over these details.
#[derive(Clone, Eq, Hash, PartialEq)] #[derive(Clone, Eq, Hash, PartialEq)]
pub struct ComplexSelector<Impl: SelectorImpl>(ArcSlice<SimpleSelector<Impl>>); pub struct ComplexSelector<Impl: SelectorImpl>(ArcSlice<Component<Impl>>);
impl<Impl: SelectorImpl> ComplexSelector<Impl> { impl<Impl: SelectorImpl> ComplexSelector<Impl> {
/// Returns an iterator over the next sequence of simple selectors. When /// Returns an iterator over the next sequence of simple selectors. When
@ -290,13 +290,13 @@ impl<Impl: SelectorImpl> ComplexSelector<Impl> {
/// Returns an iterator over the entire sequence of simple selectors and combinators, /// Returns an iterator over the entire sequence of simple selectors and combinators,
/// from right to left. /// from right to left.
pub fn iter_raw(&self) -> Rev<slice::Iter<SimpleSelector<Impl>>> { pub fn iter_raw(&self) -> Rev<slice::Iter<Component<Impl>>> {
self.iter_raw_rev().rev() self.iter_raw_rev().rev()
} }
/// Returns an iterator over the entire sequence of simple selectors and combinators, /// Returns an iterator over the entire sequence of simple selectors and combinators,
/// from left to right. /// from left to right.
pub fn iter_raw_rev(&self) -> slice::Iter<SimpleSelector<Impl>> { pub fn iter_raw_rev(&self) -> slice::Iter<Component<Impl>> {
self.0.iter() self.0.iter()
} }
@ -314,14 +314,14 @@ impl<Impl: SelectorImpl> ComplexSelector<Impl> {
ComplexSelector(self.0.clone().slice_to(self.0.len() - index)) ComplexSelector(self.0.clone().slice_to(self.0.len() - index))
} }
/// Creates a ComplexSelector from a vec of SimpleSelectors. Used in tests. /// Creates a ComplexSelector from a vec of Components. Used in tests.
pub fn from_vec(vec: Vec<SimpleSelector<Impl>>) -> Self { pub fn from_vec(vec: Vec<Component<Impl>>) -> Self {
ComplexSelector(ArcSlice::new(vec.into_boxed_slice())) ComplexSelector(ArcSlice::new(vec.into_boxed_slice()))
} }
} }
pub struct SelectorIter<'a, Impl: 'a + SelectorImpl> { pub struct SelectorIter<'a, Impl: 'a + SelectorImpl> {
iter: Rev<slice::Iter<'a, SimpleSelector<Impl>>>, iter: Rev<slice::Iter<'a, Component<Impl>>>,
next_combinator: Option<Combinator>, next_combinator: Option<Combinator>,
} }
@ -345,12 +345,12 @@ impl<'a, Impl: 'a + SelectorImpl> SelectorIter<'a, Impl> {
} }
impl<'a, Impl: SelectorImpl> Iterator for SelectorIter<'a, Impl> { impl<'a, Impl: SelectorImpl> Iterator for SelectorIter<'a, Impl> {
type Item = &'a SimpleSelector<Impl>; type Item = &'a Component<Impl>;
fn next(&mut self) -> Option<Self::Item> { fn next(&mut self) -> Option<Self::Item> {
debug_assert!(self.next_combinator.is_none(), "Should call take_combinator!"); debug_assert!(self.next_combinator.is_none(), "Should call take_combinator!");
match self.iter.next() { match self.iter.next() {
None => None, None => None,
Some(&SimpleSelector::Combinator(c)) => { Some(&Component::Combinator(c)) => {
self.next_combinator = Some(c); self.next_combinator = Some(c);
None None
}, },
@ -383,7 +383,7 @@ impl<'a, Impl: 'a + SelectorImpl> AncestorIter<'a, Impl> {
} }
impl<'a, Impl: SelectorImpl> Iterator for AncestorIter<'a, Impl> { impl<'a, Impl: SelectorImpl> Iterator for AncestorIter<'a, Impl> {
type Item = &'a SimpleSelector<Impl>; type Item = &'a Component<Impl>;
fn next(&mut self) -> Option<Self::Item> { fn next(&mut self) -> Option<Self::Item> {
// Grab the next simple selector in the sequence if available. // Grab the next simple selector in the sequence if available.
let next = self.0.next(); let next = self.0.next();
@ -425,13 +425,9 @@ impl Combinator {
/// A CSS simple selector or combinator. We store both in the same enum for /// A CSS simple selector or combinator. We store both in the same enum for
/// optimal packing and cache performance, see [1]. /// optimal packing and cache performance, see [1].
/// ///
/// We could rename this SimpleSelectorOrCombinator, but that's annoying to
/// type everywhere, and the combinators are generally filtered out and
/// handled separately by the iterator classes anyway.
///
/// [1] https://bugzilla.mozilla.org/show_bug.cgi?id=1357973 /// [1] https://bugzilla.mozilla.org/show_bug.cgi?id=1357973
#[derive(Eq, PartialEq, Clone, Hash)] #[derive(Eq, PartialEq, Clone, Hash)]
pub enum SimpleSelector<Impl: SelectorImpl> { pub enum Component<Impl: SelectorImpl> {
Combinator(Combinator), Combinator(Combinator),
ID(Impl::Identifier), ID(Impl::Identifier),
Class(Impl::ClassName), Class(Impl::ClassName),
@ -468,11 +464,11 @@ pub enum SimpleSelector<Impl: SelectorImpl> {
// ... // ...
} }
impl<Impl: SelectorImpl> SimpleSelector<Impl> { impl<Impl: SelectorImpl> Component<Impl> {
/// Compute the ancestor hash to check against the bloom filter. /// Compute the ancestor hash to check against the bloom filter.
fn ancestor_hash(&self) -> Option<u32> { fn ancestor_hash(&self) -> Option<u32> {
match *self { match *self {
SimpleSelector::LocalName(LocalName { ref name, ref lower_name }) => { Component::LocalName(LocalName { ref name, ref lower_name }) => {
// Only insert the local-name into the filter if it's all lowercase. // Only insert the local-name into the filter if it's all lowercase.
// Otherwise we would need to test both hashes, and our data structures // Otherwise we would need to test both hashes, and our data structures
// aren't really set up for that. // aren't really set up for that.
@ -482,13 +478,13 @@ impl<Impl: SelectorImpl> SimpleSelector<Impl> {
None None
} }
}, },
SimpleSelector::Namespace(ref namespace) => { Component::Namespace(ref namespace) => {
Some(namespace.url.precomputed_hash()) Some(namespace.url.precomputed_hash())
}, },
SimpleSelector::ID(ref id) => { Component::ID(ref id) => {
Some(id.precomputed_hash()) Some(id.precomputed_hash())
}, },
SimpleSelector::Class(ref class) => { Component::Class(ref class) => {
Some(class.precomputed_hash()) Some(class.precomputed_hash())
}, },
_ => None, _ => None,
@ -497,7 +493,7 @@ impl<Impl: SelectorImpl> SimpleSelector<Impl> {
/// Returns true if this is a combinator. /// Returns true if this is a combinator.
pub fn is_combinator(&self) -> bool { pub fn is_combinator(&self) -> bool {
matches!(*self, SimpleSelector::Combinator(_)) matches!(*self, Component::Combinator(_))
} }
} }
@ -558,7 +554,7 @@ impl<Impl: SelectorImpl> Debug for SelectorInner<Impl> {
impl<Impl: SelectorImpl> Debug for ComplexSelector<Impl> { impl<Impl: SelectorImpl> Debug for ComplexSelector<Impl> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { self.to_css(f) } fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { self.to_css(f) }
} }
impl<Impl: SelectorImpl> Debug for SimpleSelector<Impl> { impl<Impl: SelectorImpl> Debug for Component<Impl> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { self.to_css(f) } fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { self.to_css(f) }
} }
impl<Impl: SelectorImpl> Debug for AttrSelector<Impl> { impl<Impl: SelectorImpl> Debug for AttrSelector<Impl> {
@ -616,9 +612,9 @@ impl ToCss for Combinator {
} }
} }
impl<Impl: SelectorImpl> ToCss for SimpleSelector<Impl> { impl<Impl: SelectorImpl> ToCss for Component<Impl> {
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
use self::SimpleSelector::*; use self::Component::*;
match *self { match *self {
Combinator(ref c) => { Combinator(ref c) => {
c.to_css(dest) c.to_css(dest)
@ -821,39 +817,39 @@ fn complex_selector_specificity<Impl>(selector: &ComplexSelector<Impl>)
where Impl: SelectorImpl { where Impl: SelectorImpl {
for simple_selector in selector_iter { for simple_selector in selector_iter {
match *simple_selector { match *simple_selector {
SimpleSelector::Combinator(..) => unreachable!(), Component::Combinator(..) => unreachable!(),
SimpleSelector::LocalName(..) => Component::LocalName(..) =>
specificity.element_selectors += 1, specificity.element_selectors += 1,
SimpleSelector::ID(..) => Component::ID(..) =>
specificity.id_selectors += 1, specificity.id_selectors += 1,
SimpleSelector::Class(..) | Component::Class(..) |
SimpleSelector::AttrExists(..) | Component::AttrExists(..) |
SimpleSelector::AttrEqual(..) | Component::AttrEqual(..) |
SimpleSelector::AttrIncludes(..) | Component::AttrIncludes(..) |
SimpleSelector::AttrDashMatch(..) | Component::AttrDashMatch(..) |
SimpleSelector::AttrPrefixMatch(..) | Component::AttrPrefixMatch(..) |
SimpleSelector::AttrSubstringMatch(..) | Component::AttrSubstringMatch(..) |
SimpleSelector::AttrSuffixMatch(..) | Component::AttrSuffixMatch(..) |
SimpleSelector::AttrIncludesNeverMatch(..) | Component::AttrIncludesNeverMatch(..) |
SimpleSelector::AttrPrefixNeverMatch(..) | Component::AttrPrefixNeverMatch(..) |
SimpleSelector::AttrSubstringNeverMatch(..) | Component::AttrSubstringNeverMatch(..) |
SimpleSelector::AttrSuffixNeverMatch(..) | Component::AttrSuffixNeverMatch(..) |
SimpleSelector::FirstChild | SimpleSelector::LastChild | Component::FirstChild | Component::LastChild |
SimpleSelector::OnlyChild | SimpleSelector::Root | Component::OnlyChild | Component::Root |
SimpleSelector::Empty | Component::Empty |
SimpleSelector::NthChild(..) | Component::NthChild(..) |
SimpleSelector::NthLastChild(..) | Component::NthLastChild(..) |
SimpleSelector::NthOfType(..) | Component::NthOfType(..) |
SimpleSelector::NthLastOfType(..) | Component::NthLastOfType(..) |
SimpleSelector::FirstOfType | SimpleSelector::LastOfType | Component::FirstOfType | Component::LastOfType |
SimpleSelector::OnlyOfType | Component::OnlyOfType |
SimpleSelector::NonTSPseudoClass(..) => Component::NonTSPseudoClass(..) =>
specificity.class_like_selectors += 1, specificity.class_like_selectors += 1,
SimpleSelector::Namespace(..) => (), Component::Namespace(..) => (),
SimpleSelector::Negation(ref negated) => { Component::Negation(ref negated) => {
let max = let max =
negated.iter().map(|s| complex_selector_specificity(&s)) negated.iter().map(|s| complex_selector_specificity(&s))
.max().unwrap(); .max().unwrap();
@ -936,7 +932,7 @@ fn parse_complex_selector_and_pseudo_element<P, Impl>(
} }
} }
} }
sequence.push(SimpleSelector::Combinator(combinator)); sequence.push(Component::Combinator(combinator));
} }
let complex = ComplexSelector(ArcSlice::new(sequence.into_boxed_slice())); let complex = ComplexSelector(ArcSlice::new(sequence.into_boxed_slice()));
@ -960,7 +956,7 @@ impl<Impl: SelectorImpl> ComplexSelector<Impl> {
/// * `Err(())`: Invalid selector, abort /// * `Err(())`: Invalid selector, abort
/// * `Ok(None)`: Not a type selector, could be something else. `input` was not consumed. /// * `Ok(None)`: Not a type selector, could be something else. `input` was not consumed.
/// * `Ok(Some(vec))`: Length 0 (`*|*`), 1 (`*|E` or `ns|*`) or 2 (`|E` or `ns|E`) /// * `Ok(Some(vec))`: Length 0 (`*|*`), 1 (`*|E` or `ns|*`) or 2 (`|E` or `ns|E`)
fn parse_type_selector<P, Impl>(parser: &P, input: &mut CssParser, sequence: &mut Vec<SimpleSelector<Impl>>) fn parse_type_selector<P, Impl>(parser: &P, input: &mut CssParser, sequence: &mut Vec<Component<Impl>>)
-> Result<bool, ()> -> Result<bool, ()>
where P: Parser<Impl=Impl>, Impl: SelectorImpl where P: Parser<Impl=Impl>, Impl: SelectorImpl
{ {
@ -969,13 +965,13 @@ fn parse_type_selector<P, Impl>(parser: &P, input: &mut CssParser, sequence: &mu
Some((namespace, local_name)) => { Some((namespace, local_name)) => {
match namespace { match namespace {
NamespaceConstraint::Specific(ns) => { NamespaceConstraint::Specific(ns) => {
sequence.push(SimpleSelector::Namespace(ns)) sequence.push(Component::Namespace(ns))
}, },
NamespaceConstraint::Any => (), NamespaceConstraint::Any => (),
} }
match local_name { match local_name {
Some(name) => { Some(name) => {
sequence.push(SimpleSelector::LocalName(LocalName { sequence.push(Component::LocalName(LocalName {
lower_name: from_ascii_lowercase(&name), lower_name: from_ascii_lowercase(&name),
name: from_cow_str(name), name: from_cow_str(name),
})) }))
@ -989,7 +985,7 @@ fn parse_type_selector<P, Impl>(parser: &P, input: &mut CssParser, sequence: &mu
#[derive(Debug)] #[derive(Debug)]
enum SimpleSelectorParseResult<Impl: SelectorImpl> { enum SimpleSelectorParseResult<Impl: SelectorImpl> {
SimpleSelector(SimpleSelector<Impl>), SimpleSelector(Component<Impl>),
PseudoElement(Impl::PseudoElement), PseudoElement(Impl::PseudoElement),
} }
@ -1075,7 +1071,7 @@ fn parse_qualified_name<'i, 't, P, Impl>
fn parse_attribute_selector<P, Impl>(parser: &P, input: &mut CssParser) fn parse_attribute_selector<P, Impl>(parser: &P, input: &mut CssParser)
-> Result<SimpleSelector<Impl>, ()> -> Result<Component<Impl>, ()>
where P: Parser<Impl=Impl>, Impl: SelectorImpl where P: Parser<Impl=Impl>, Impl: SelectorImpl
{ {
let attr = match parse_qualified_name(parser, input, /* in_attr_selector = */ true)? { let attr = match parse_qualified_name(parser, input, /* in_attr_selector = */ true)? {
@ -1090,53 +1086,53 @@ fn parse_attribute_selector<P, Impl>(parser: &P, input: &mut CssParser)
match input.next() { match input.next() {
// [foo] // [foo]
Err(()) => Ok(SimpleSelector::AttrExists(attr)), Err(()) => Ok(Component::AttrExists(attr)),
// [foo=bar] // [foo=bar]
Ok(Token::Delim('=')) => { Ok(Token::Delim('=')) => {
let value = input.expect_ident_or_string()?; let value = input.expect_ident_or_string()?;
let flags = parse_attribute_flags(input)?; let flags = parse_attribute_flags(input)?;
Ok(SimpleSelector::AttrEqual(attr, from_cow_str(value), flags)) Ok(Component::AttrEqual(attr, from_cow_str(value), flags))
} }
// [foo~=bar] // [foo~=bar]
Ok(Token::IncludeMatch) => { Ok(Token::IncludeMatch) => {
let value = input.expect_ident_or_string()?; let value = input.expect_ident_or_string()?;
if value.is_empty() || value.contains(SELECTOR_WHITESPACE) { if value.is_empty() || value.contains(SELECTOR_WHITESPACE) {
Ok(SimpleSelector::AttrIncludesNeverMatch(attr, from_cow_str(value))) Ok(Component::AttrIncludesNeverMatch(attr, from_cow_str(value)))
} else { } else {
Ok(SimpleSelector::AttrIncludes(attr, from_cow_str(value))) Ok(Component::AttrIncludes(attr, from_cow_str(value)))
} }
} }
// [foo|=bar] // [foo|=bar]
Ok(Token::DashMatch) => { Ok(Token::DashMatch) => {
let value = input.expect_ident_or_string()?; let value = input.expect_ident_or_string()?;
Ok(SimpleSelector::AttrDashMatch(attr, from_cow_str(value))) Ok(Component::AttrDashMatch(attr, from_cow_str(value)))
} }
// [foo^=bar] // [foo^=bar]
Ok(Token::PrefixMatch) => { Ok(Token::PrefixMatch) => {
let value = input.expect_ident_or_string()?; let value = input.expect_ident_or_string()?;
if value.is_empty() { if value.is_empty() {
Ok(SimpleSelector::AttrPrefixNeverMatch(attr, from_cow_str(value))) Ok(Component::AttrPrefixNeverMatch(attr, from_cow_str(value)))
} else { } else {
Ok(SimpleSelector::AttrPrefixMatch(attr, from_cow_str(value))) Ok(Component::AttrPrefixMatch(attr, from_cow_str(value)))
} }
} }
// [foo*=bar] // [foo*=bar]
Ok(Token::SubstringMatch) => { Ok(Token::SubstringMatch) => {
let value = input.expect_ident_or_string()?; let value = input.expect_ident_or_string()?;
if value.is_empty() { if value.is_empty() {
Ok(SimpleSelector::AttrSubstringNeverMatch(attr, from_cow_str(value))) Ok(Component::AttrSubstringNeverMatch(attr, from_cow_str(value)))
} else { } else {
Ok(SimpleSelector::AttrSubstringMatch(attr, from_cow_str(value))) Ok(Component::AttrSubstringMatch(attr, from_cow_str(value)))
} }
} }
// [foo$=bar] // [foo$=bar]
Ok(Token::SuffixMatch) => { Ok(Token::SuffixMatch) => {
let value = input.expect_ident_or_string()?; let value = input.expect_ident_or_string()?;
if value.is_empty() { if value.is_empty() {
Ok(SimpleSelector::AttrSuffixNeverMatch(attr, from_cow_str(value))) Ok(Component::AttrSuffixNeverMatch(attr, from_cow_str(value)))
} else { } else {
Ok(SimpleSelector::AttrSuffixMatch(attr, from_cow_str(value))) Ok(Component::AttrSuffixMatch(attr, from_cow_str(value)))
} }
} }
_ => Err(()) _ => Err(())
@ -1159,11 +1155,11 @@ fn parse_attribute_flags(input: &mut CssParser) -> Result<CaseSensitivity, ()> {
/// implied "<defaultns>|*" type selector.) /// implied "<defaultns>|*" type selector.)
fn parse_negation<P, Impl>(parser: &P, fn parse_negation<P, Impl>(parser: &P,
input: &mut CssParser) input: &mut CssParser)
-> Result<SimpleSelector<Impl>, ()> -> Result<Component<Impl>, ()>
where P: Parser<Impl=Impl>, Impl: SelectorImpl where P: Parser<Impl=Impl>, Impl: SelectorImpl
{ {
input.parse_comma_separated(|input| ComplexSelector::parse(parser, input)) input.parse_comma_separated(|input| ComplexSelector::parse(parser, input))
.map(|v| SimpleSelector::Negation(v.into_boxed_slice())) .map(|v| Component::Negation(v.into_boxed_slice()))
} }
/// simple_selector_sequence /// simple_selector_sequence
@ -1174,7 +1170,7 @@ fn parse_negation<P, Impl>(parser: &P,
fn parse_compound_selector<P, Impl>( fn parse_compound_selector<P, Impl>(
parser: &P, parser: &P,
input: &mut CssParser, input: &mut CssParser,
mut sequence: &mut Vec<SimpleSelector<Impl>>) mut sequence: &mut Vec<Component<Impl>>)
-> Result<Option<Impl::PseudoElement>, ()> -> Result<Option<Impl::PseudoElement>, ()>
where P: Parser<Impl=Impl>, Impl: SelectorImpl where P: Parser<Impl=Impl>, Impl: SelectorImpl
{ {
@ -1192,7 +1188,7 @@ fn parse_compound_selector<P, Impl>(
// If there was no explicit type selector, but there is a // If there was no explicit type selector, but there is a
// default namespace, there is an implicit "<defaultns>|*" type // default namespace, there is an implicit "<defaultns>|*" type
// selector. // selector.
sequence.push(SimpleSelector::Namespace(Namespace { sequence.push(Component::Namespace(Namespace {
prefix: None, prefix: None,
url: url url: url
})); }));
@ -1228,14 +1224,14 @@ fn parse_functional_pseudo_class<P, Impl>(parser: &P,
input: &mut CssParser, input: &mut CssParser,
name: Cow<str>, name: Cow<str>,
inside_negation: bool) inside_negation: bool)
-> Result<SimpleSelector<Impl>, ()> -> Result<Component<Impl>, ()>
where P: Parser<Impl=Impl>, Impl: SelectorImpl where P: Parser<Impl=Impl>, Impl: SelectorImpl
{ {
match_ignore_ascii_case! { &name, match_ignore_ascii_case! { &name,
"nth-child" => return parse_nth_pseudo_class(input, SimpleSelector::NthChild), "nth-child" => return parse_nth_pseudo_class(input, Component::NthChild),
"nth-of-type" => return parse_nth_pseudo_class(input, SimpleSelector::NthOfType), "nth-of-type" => return parse_nth_pseudo_class(input, Component::NthOfType),
"nth-last-child" => return parse_nth_pseudo_class(input, SimpleSelector::NthLastChild), "nth-last-child" => return parse_nth_pseudo_class(input, Component::NthLastChild),
"nth-last-of-type" => return parse_nth_pseudo_class(input, SimpleSelector::NthLastOfType), "nth-last-of-type" => return parse_nth_pseudo_class(input, Component::NthLastOfType),
"not" => { "not" => {
if inside_negation { if inside_negation {
return Err(()) return Err(())
@ -1245,13 +1241,13 @@ fn parse_functional_pseudo_class<P, Impl>(parser: &P,
_ => {} _ => {}
} }
P::parse_non_ts_functional_pseudo_class(parser, name, input) P::parse_non_ts_functional_pseudo_class(parser, name, input)
.map(SimpleSelector::NonTSPseudoClass) .map(Component::NonTSPseudoClass)
} }
fn parse_nth_pseudo_class<Impl, F>(input: &mut CssParser, selector: F) fn parse_nth_pseudo_class<Impl, F>(input: &mut CssParser, selector: F)
-> Result<SimpleSelector<Impl>, ()> -> Result<Component<Impl>, ()>
where Impl: SelectorImpl, F: FnOnce(i32, i32) -> SimpleSelector<Impl> { where Impl: SelectorImpl, F: FnOnce(i32, i32) -> Component<Impl> {
let (a, b) = parse_nth(input)?; let (a, b) = parse_nth(input)?;
Ok(selector(a, b)) Ok(selector(a, b))
} }
@ -1271,13 +1267,13 @@ fn parse_one_simple_selector<P, Impl>(parser: &P,
let start_position = input.position(); let start_position = input.position();
match input.next_including_whitespace() { match input.next_including_whitespace() {
Ok(Token::IDHash(id)) => { Ok(Token::IDHash(id)) => {
let id = SimpleSelector::ID(from_cow_str(id)); let id = Component::ID(from_cow_str(id));
Ok(Some(SimpleSelectorParseResult::SimpleSelector(id))) Ok(Some(SimpleSelectorParseResult::SimpleSelector(id)))
} }
Ok(Token::Delim('.')) => { Ok(Token::Delim('.')) => {
match input.next_including_whitespace() { match input.next_including_whitespace() {
Ok(Token::Ident(class)) => { Ok(Token::Ident(class)) => {
let class = SimpleSelector::Class(from_cow_str(class)); let class = Component::Class(from_cow_str(class));
Ok(Some(SimpleSelectorParseResult::SimpleSelector(class))) Ok(Some(SimpleSelectorParseResult::SimpleSelector(class)))
} }
_ => Err(()), _ => Err(()),
@ -1328,22 +1324,22 @@ fn parse_one_simple_selector<P, Impl>(parser: &P,
} }
} }
fn parse_simple_pseudo_class<P, Impl>(parser: &P, name: Cow<str>) -> Result<SimpleSelector<Impl>, ()> fn parse_simple_pseudo_class<P, Impl>(parser: &P, name: Cow<str>) -> Result<Component<Impl>, ()>
where P: Parser<Impl=Impl>, Impl: SelectorImpl where P: Parser<Impl=Impl>, Impl: SelectorImpl
{ {
(match_ignore_ascii_case! { &name, (match_ignore_ascii_case! { &name,
"first-child" => Ok(SimpleSelector::FirstChild), "first-child" => Ok(Component::FirstChild),
"last-child" => Ok(SimpleSelector::LastChild), "last-child" => Ok(Component::LastChild),
"only-child" => Ok(SimpleSelector::OnlyChild), "only-child" => Ok(Component::OnlyChild),
"root" => Ok(SimpleSelector::Root), "root" => Ok(Component::Root),
"empty" => Ok(SimpleSelector::Empty), "empty" => Ok(Component::Empty),
"first-of-type" => Ok(SimpleSelector::FirstOfType), "first-of-type" => Ok(Component::FirstOfType),
"last-of-type" => Ok(SimpleSelector::LastOfType), "last-of-type" => Ok(Component::LastOfType),
"only-of-type" => Ok(SimpleSelector::OnlyOfType), "only-of-type" => Ok(Component::OnlyOfType),
_ => Err(()) _ => Err(())
}).or_else(|()| { }).or_else(|()| {
P::parse_non_ts_pseudo_class(parser, name) P::parse_non_ts_pseudo_class(parser, name)
.map(SimpleSelector::NonTSPseudoClass) .map(Component::NonTSPseudoClass)
}) })
} }
@ -1517,7 +1513,7 @@ pub mod tests {
assert_eq!(parse(":lang(4)"), Err(())) ; assert_eq!(parse(":lang(4)"), Err(())) ;
assert_eq!(parse(":lang(en US)"), Err(())) ; assert_eq!(parse(":lang(en US)"), Err(())) ;
assert_eq!(parse("EeÉ"), Ok(SelectorList(vec!(Selector { assert_eq!(parse("EeÉ"), Ok(SelectorList(vec!(Selector {
inner: SelectorInner::from_vec(vec!(SimpleSelector::LocalName(LocalName { inner: SelectorInner::from_vec(vec!(Component::LocalName(LocalName {
name: DummyAtom::from("EeÉ"), name: DummyAtom::from("EeÉ"),
lower_name: DummyAtom::from("eeÉ") })), lower_name: DummyAtom::from("eeÉ") })),
), ),
@ -1526,35 +1522,35 @@ pub mod tests {
})))); }))));
assert_eq!(parse(".foo:lang(en-US)"), Ok(SelectorList(vec!(Selector { assert_eq!(parse(".foo:lang(en-US)"), Ok(SelectorList(vec!(Selector {
inner: SelectorInner::from_vec(vec![ inner: SelectorInner::from_vec(vec![
SimpleSelector::Class(DummyAtom::from("foo")), Component::Class(DummyAtom::from("foo")),
SimpleSelector::NonTSPseudoClass(PseudoClass::Lang("en-US".to_owned())) Component::NonTSPseudoClass(PseudoClass::Lang("en-US".to_owned()))
]), ]),
pseudo_element: None, pseudo_element: None,
specificity: specificity(0, 2, 0), specificity: specificity(0, 2, 0),
})))); }))));
assert_eq!(parse("#bar"), Ok(SelectorList(vec!(Selector { assert_eq!(parse("#bar"), Ok(SelectorList(vec!(Selector {
inner: SelectorInner::from_vec(vec!(SimpleSelector::ID(DummyAtom::from("bar")))), inner: SelectorInner::from_vec(vec!(Component::ID(DummyAtom::from("bar")))),
pseudo_element: None, pseudo_element: None,
specificity: specificity(1, 0, 0), specificity: specificity(1, 0, 0),
})))); }))));
assert_eq!(parse("e.foo#bar"), Ok(SelectorList(vec!(Selector { assert_eq!(parse("e.foo#bar"), Ok(SelectorList(vec!(Selector {
inner: SelectorInner::from_vec(vec!(SimpleSelector::LocalName(LocalName { inner: SelectorInner::from_vec(vec!(Component::LocalName(LocalName {
name: DummyAtom::from("e"), name: DummyAtom::from("e"),
lower_name: DummyAtom::from("e") }), lower_name: DummyAtom::from("e") }),
SimpleSelector::Class(DummyAtom::from("foo")), Component::Class(DummyAtom::from("foo")),
SimpleSelector::ID(DummyAtom::from("bar")))), Component::ID(DummyAtom::from("bar")))),
pseudo_element: None, pseudo_element: None,
specificity: specificity(1, 1, 1), specificity: specificity(1, 1, 1),
})))); }))));
assert_eq!(parse("e.foo #bar"), Ok(SelectorList(vec!(Selector { assert_eq!(parse("e.foo #bar"), Ok(SelectorList(vec!(Selector {
inner: SelectorInner::from_vec(vec!( inner: SelectorInner::from_vec(vec!(
SimpleSelector::LocalName(LocalName { Component::LocalName(LocalName {
name: DummyAtom::from("e"), name: DummyAtom::from("e"),
lower_name: DummyAtom::from("e") lower_name: DummyAtom::from("e")
}), }),
SimpleSelector::Class(DummyAtom::from("foo")), Component::Class(DummyAtom::from("foo")),
SimpleSelector::Combinator(Combinator::Descendant), Component::Combinator(Combinator::Descendant),
SimpleSelector::ID(DummyAtom::from("bar")), Component::ID(DummyAtom::from("bar")),
)), )),
pseudo_element: None, pseudo_element: None,
specificity: specificity(1, 1, 1), specificity: specificity(1, 1, 1),
@ -1564,7 +1560,7 @@ pub mod tests {
let mut parser = DummyParser::default(); let mut parser = DummyParser::default();
assert_eq!(parse_ns("[Foo]", &parser), Ok(SelectorList(vec!(Selector { assert_eq!(parse_ns("[Foo]", &parser), Ok(SelectorList(vec!(Selector {
inner: SelectorInner::from_vec(vec!( inner: SelectorInner::from_vec(vec!(
SimpleSelector::AttrExists(AttrSelector { Component::AttrExists(AttrSelector {
name: DummyAtom::from("Foo"), name: DummyAtom::from("Foo"),
lower_name: DummyAtom::from("foo"), lower_name: DummyAtom::from("foo"),
namespace: NamespaceConstraint::Specific(Namespace { namespace: NamespaceConstraint::Specific(Namespace {
@ -1579,11 +1575,11 @@ pub mod tests {
assert_eq!(parse_ns("svg|circle", &parser), Ok(SelectorList(vec![Selector { assert_eq!(parse_ns("svg|circle", &parser), Ok(SelectorList(vec![Selector {
inner: SelectorInner::from_vec( inner: SelectorInner::from_vec(
vec![ vec![
SimpleSelector::Namespace(Namespace { Component::Namespace(Namespace {
prefix: Some(DummyAtom("svg".into())), prefix: Some(DummyAtom("svg".into())),
url: SVG.into(), url: SVG.into(),
}), }),
SimpleSelector::LocalName(LocalName { Component::LocalName(LocalName {
name: DummyAtom::from("circle"), name: DummyAtom::from("circle"),
lower_name: DummyAtom::from("circle"), lower_name: DummyAtom::from("circle"),
}) })
@ -1599,11 +1595,11 @@ pub mod tests {
assert_eq!(parse_ns("[Foo]", &parser), Ok(SelectorList(vec!(Selector { assert_eq!(parse_ns("[Foo]", &parser), Ok(SelectorList(vec!(Selector {
inner: SelectorInner::from_vec( inner: SelectorInner::from_vec(
vec![ vec![
SimpleSelector::Namespace(Namespace { Component::Namespace(Namespace {
prefix: None, prefix: None,
url: MATHML.into(), url: MATHML.into(),
}), }),
SimpleSelector::AttrExists(AttrSelector { Component::AttrExists(AttrSelector {
name: DummyAtom::from("Foo"), name: DummyAtom::from("Foo"),
lower_name: DummyAtom::from("foo"), lower_name: DummyAtom::from("foo"),
namespace: NamespaceConstraint::Specific(Namespace { namespace: NamespaceConstraint::Specific(Namespace {
@ -1619,11 +1615,11 @@ pub mod tests {
assert_eq!(parse_ns("e", &parser), Ok(SelectorList(vec!(Selector { assert_eq!(parse_ns("e", &parser), Ok(SelectorList(vec!(Selector {
inner: SelectorInner::from_vec( inner: SelectorInner::from_vec(
vec!( vec!(
SimpleSelector::Namespace(Namespace { Component::Namespace(Namespace {
prefix: None, prefix: None,
url: MATHML.into(), url: MATHML.into(),
}), }),
SimpleSelector::LocalName(LocalName { Component::LocalName(LocalName {
name: DummyAtom::from("e"), name: DummyAtom::from("e"),
lower_name: DummyAtom::from("e") }), lower_name: DummyAtom::from("e") }),
)), )),
@ -1633,7 +1629,7 @@ pub mod tests {
assert_eq!(parse("[attr |= \"foo\"]"), Ok(SelectorList(vec![Selector { assert_eq!(parse("[attr |= \"foo\"]"), Ok(SelectorList(vec![Selector {
inner: SelectorInner::from_vec( inner: SelectorInner::from_vec(
vec![ vec![
SimpleSelector::AttrDashMatch(AttrSelector { Component::AttrDashMatch(AttrSelector {
name: DummyAtom::from("attr"), name: DummyAtom::from("attr"),
lower_name: DummyAtom::from("attr"), lower_name: DummyAtom::from("attr"),
namespace: NamespaceConstraint::Specific(Namespace { namespace: NamespaceConstraint::Specific(Namespace {
@ -1656,10 +1652,10 @@ pub mod tests {
assert_eq!(parse("div ::after"), Ok(SelectorList(vec!(Selector { assert_eq!(parse("div ::after"), Ok(SelectorList(vec!(Selector {
inner: SelectorInner::from_vec( inner: SelectorInner::from_vec(
vec![ vec![
SimpleSelector::LocalName(LocalName { Component::LocalName(LocalName {
name: DummyAtom::from("div"), name: DummyAtom::from("div"),
lower_name: DummyAtom::from("div") }), lower_name: DummyAtom::from("div") }),
SimpleSelector::Combinator(Combinator::Descendant), Component::Combinator(Combinator::Descendant),
]), ]),
pseudo_element: Some(PseudoElement::After), pseudo_element: Some(PseudoElement::After),
specificity: specificity(0, 0, 2), specificity: specificity(0, 0, 2),
@ -1667,20 +1663,20 @@ pub mod tests {
assert_eq!(parse("#d1 > .ok"), Ok(SelectorList(vec![Selector { assert_eq!(parse("#d1 > .ok"), Ok(SelectorList(vec![Selector {
inner: SelectorInner::from_vec( inner: SelectorInner::from_vec(
vec![ vec![
SimpleSelector::ID(DummyAtom::from("d1")), Component::ID(DummyAtom::from("d1")),
SimpleSelector::Combinator(Combinator::Child), Component::Combinator(Combinator::Child),
SimpleSelector::Class(DummyAtom::from("ok")), Component::Class(DummyAtom::from("ok")),
]), ]),
pseudo_element: None, pseudo_element: None,
specificity: (1 << 20) + (1 << 10) + (0 << 0), specificity: (1 << 20) + (1 << 10) + (0 << 0),
}]))); }])));
assert_eq!(parse(":not(.babybel, #provel.old)"), Ok(SelectorList(vec!(Selector { assert_eq!(parse(":not(.babybel, #provel.old)"), Ok(SelectorList(vec!(Selector {
inner: SelectorInner::from_vec(vec!(SimpleSelector::Negation( inner: SelectorInner::from_vec(vec!(Component::Negation(
vec!( vec!(
ComplexSelector::from_vec(vec!(SimpleSelector::Class(DummyAtom::from("babybel")))), ComplexSelector::from_vec(vec!(Component::Class(DummyAtom::from("babybel")))),
ComplexSelector::from_vec(vec!( ComplexSelector::from_vec(vec!(
SimpleSelector::ID(DummyAtom::from("provel")), Component::ID(DummyAtom::from("provel")),
SimpleSelector::Class(DummyAtom::from("old")), Component::Class(DummyAtom::from("old")),
))).into_boxed_slice() ))).into_boxed_slice()
))), ))),
pseudo_element: None, pseudo_element: None,
@ -1695,7 +1691,7 @@ pub mod tests {
impl SelectorVisitor for TestVisitor { impl SelectorVisitor for TestVisitor {
type Impl = DummySelectorImpl; type Impl = DummySelectorImpl;
fn visit_simple_selector(&mut self, s: &SimpleSelector<DummySelectorImpl>) -> bool { fn visit_simple_selector(&mut self, s: &Component<DummySelectorImpl>) -> bool {
let mut dest = String::new(); let mut dest = String::new();
s.to_css(&mut dest).unwrap(); s.to_css(&mut dest).unwrap();
self.seen.push(dest); self.seen.push(dest);

View file

@ -6,8 +6,8 @@
#![deny(missing_docs)] #![deny(missing_docs)]
use parser::{AttrSelector, Combinator, SelectorImpl}; use parser::{AttrSelector, Combinator, Component};
use parser::{SelectorIter, SimpleSelector}; use parser::{SelectorImpl, SelectorIter};
/// A trait to visit selector properties. /// A trait to visit selector properties.
/// ///
@ -25,7 +25,7 @@ pub trait SelectorVisitor {
} }
/// Visit a simple selector. /// Visit a simple selector.
fn visit_simple_selector(&mut self, _: &SimpleSelector<Self::Impl>) -> bool { fn visit_simple_selector(&mut self, _: &Component<Self::Impl>) -> bool {
true true
} }

View file

@ -1198,11 +1198,11 @@ pub trait MatchMethods : TElement {
// > fn with_really_simple_selectors(&self, f: <H: Hash>|&H|); // > fn with_really_simple_selectors(&self, f: <H: Hash>|&H|);
// In terms of `SimpleSelector`s, these two functions will insert and remove: // In terms of `Component`s, these two functions will insert and remove:
// - `SimpleSelector::LocalName` // - `Component::LocalName`
// - `SimpleSelector::Namepace` // - `Component::Namepace`
// - `SimpleSelector::ID` // - `Component::ID`
// - `SimpleSelector::Class` // - `Component::Class`
/// Inserts and removes the matching `Descendant` selectors from a bloom /// Inserts and removes the matching `Descendant` selectors from a bloom
/// filter. This is used to speed up CSS selector matching to remove /// filter. This is used to speed up CSS selector matching to remove

View file

@ -17,8 +17,8 @@ use selector_parser::{AttrValue, NonTSPseudoClass, Snapshot, SelectorImpl};
use selectors::{Element, MatchAttr}; use selectors::{Element, MatchAttr};
use selectors::matching::{ElementSelectorFlags, StyleRelations}; use selectors::matching::{ElementSelectorFlags, StyleRelations};
use selectors::matching::matches_selector; use selectors::matching::matches_selector;
use selectors::parser::{AttrSelector, Combinator, ComplexSelector, SelectorInner, SelectorIter}; use selectors::parser::{AttrSelector, Combinator, ComplexSelector, Component};
use selectors::parser::{SelectorMethods, SimpleSelector}; use selectors::parser::{SelectorInner, SelectorIter, SelectorMethods};
use selectors::visitor::SelectorVisitor; use selectors::visitor::SelectorVisitor;
use std::clone::Clone; use std::clone::Clone;
@ -388,24 +388,24 @@ impl<'a, E> Element for ElementWrapper<'a, E>
} }
} }
fn selector_to_state(sel: &SimpleSelector<SelectorImpl>) -> ElementState { fn selector_to_state(sel: &Component<SelectorImpl>) -> ElementState {
match *sel { match *sel {
SimpleSelector::NonTSPseudoClass(ref pc) => pc.state_flag(), Component::NonTSPseudoClass(ref pc) => pc.state_flag(),
_ => ElementState::empty(), _ => ElementState::empty(),
} }
} }
fn is_attr_selector(sel: &SimpleSelector<SelectorImpl>) -> bool { fn is_attr_selector(sel: &Component<SelectorImpl>) -> bool {
match *sel { match *sel {
SimpleSelector::ID(_) | Component::ID(_) |
SimpleSelector::Class(_) | Component::Class(_) |
SimpleSelector::AttrExists(_) | Component::AttrExists(_) |
SimpleSelector::AttrEqual(_, _, _) | Component::AttrEqual(_, _, _) |
SimpleSelector::AttrIncludes(_, _) | Component::AttrIncludes(_, _) |
SimpleSelector::AttrDashMatch(_, _) | Component::AttrDashMatch(_, _) |
SimpleSelector::AttrPrefixMatch(_, _) | Component::AttrPrefixMatch(_, _) |
SimpleSelector::AttrSubstringMatch(_, _) | Component::AttrSubstringMatch(_, _) |
SimpleSelector::AttrSuffixMatch(_, _) => true, Component::AttrSuffixMatch(_, _) => true,
_ => false, _ => false,
} }
} }
@ -416,22 +416,22 @@ fn is_attr_selector(sel: &SimpleSelector<SelectorImpl>) -> bool {
/// ///
/// We use this for selectors that can have different matching behavior between /// We use this for selectors that can have different matching behavior between
/// siblings that are otherwise identical as far as the cache is concerned. /// siblings that are otherwise identical as far as the cache is concerned.
fn needs_cache_revalidation(sel: &SimpleSelector<SelectorImpl>) -> bool { fn needs_cache_revalidation(sel: &Component<SelectorImpl>) -> bool {
match *sel { match *sel {
SimpleSelector::Empty | Component::Empty |
SimpleSelector::FirstChild | Component::FirstChild |
SimpleSelector::LastChild | Component::LastChild |
SimpleSelector::OnlyChild | Component::OnlyChild |
SimpleSelector::NthChild(..) | Component::NthChild(..) |
SimpleSelector::NthLastChild(..) | Component::NthLastChild(..) |
SimpleSelector::NthOfType(..) | Component::NthOfType(..) |
SimpleSelector::NthLastOfType(..) | Component::NthLastOfType(..) |
SimpleSelector::FirstOfType | Component::FirstOfType |
SimpleSelector::LastOfType | Component::LastOfType |
SimpleSelector::OnlyOfType => true, Component::OnlyOfType => true,
// FIXME(emilio): This sets the "revalidation" flag for :any, which is // FIXME(emilio): This sets the "revalidation" flag for :any, which is
// probably expensive given we use it a lot in UA sheets. // probably expensive given we use it a lot in UA sheets.
SimpleSelector::NonTSPseudoClass(ref p) => p.state_flag().is_empty(), Component::NonTSPseudoClass(ref p) => p.state_flag().is_empty(),
_ => false, _ => false,
} }
} }
@ -517,7 +517,7 @@ impl SelectorVisitor for SensitivitiesVisitor {
true true
} }
fn visit_simple_selector(&mut self, s: &SimpleSelector<SelectorImpl>) -> bool { fn visit_simple_selector(&mut self, s: &Component<SelectorImpl>) -> bool {
self.sensitivities.states.insert(selector_to_state(s)); self.sensitivities.states.insert(selector_to_state(s));
if !self.sensitivities.attrs { if !self.sensitivities.attrs {

View file

@ -27,7 +27,7 @@ use selectors::bloom::BloomFilter;
use selectors::matching::{AFFECTED_BY_ANIMATIONS, AFFECTED_BY_TRANSITIONS}; use selectors::matching::{AFFECTED_BY_ANIMATIONS, AFFECTED_BY_TRANSITIONS};
use selectors::matching::{AFFECTED_BY_STYLE_ATTRIBUTE, AFFECTED_BY_PRESENTATIONAL_HINTS}; use selectors::matching::{AFFECTED_BY_STYLE_ATTRIBUTE, AFFECTED_BY_PRESENTATIONAL_HINTS};
use selectors::matching::{ElementSelectorFlags, StyleRelations, matches_selector}; use selectors::matching::{ElementSelectorFlags, StyleRelations, matches_selector};
use selectors::parser::{Selector, SelectorInner, SimpleSelector, LocalName as LocalNameSelector}; use selectors::parser::{Component, Selector, SelectorInner, LocalName as LocalNameSelector};
use shared_lock::{Locked, SharedRwLockReadGuard, StylesheetGuards}; use shared_lock::{Locked, SharedRwLockReadGuard, StylesheetGuards};
use sink::Push; use sink::Push;
use smallvec::VecLike; use smallvec::VecLike;
@ -1182,7 +1182,7 @@ impl SelectorMap {
for ss in rule.selector.complex.iter() { for ss in rule.selector.complex.iter() {
// TODO(pradeep): Implement case-sensitivity based on the // TODO(pradeep): Implement case-sensitivity based on the
// document type and quirks mode. // document type and quirks mode.
if let SimpleSelector::ID(ref id) = *ss { if let Component::ID(ref id) = *ss {
return Some(id.clone()); return Some(id.clone());
} }
} }
@ -1195,7 +1195,7 @@ impl SelectorMap {
for ss in rule.selector.complex.iter() { for ss in rule.selector.complex.iter() {
// TODO(pradeep): Implement case-sensitivity based on the // TODO(pradeep): Implement case-sensitivity based on the
// document type and quirks mode. // document type and quirks mode.
if let SimpleSelector::Class(ref class) = *ss { if let Component::Class(ref class) = *ss {
return Some(class.clone()); return Some(class.clone());
} }
} }
@ -1206,7 +1206,7 @@ impl SelectorMap {
/// Retrieve the name if it is a type selector, or None otherwise. /// Retrieve the name if it is a type selector, or None otherwise.
pub fn get_local_name(rule: &Rule) -> Option<LocalNameSelector<SelectorImpl>> { pub fn get_local_name(rule: &Rule) -> Option<LocalNameSelector<SelectorImpl>> {
for ss in rule.selector.complex.iter() { for ss in rule.selector.complex.iter() {
if let SimpleSelector::LocalName(ref n) = *ss { if let Component::LocalName(ref n) = *ss {
return Some(LocalNameSelector { return Some(LocalNameSelector {
name: n.name.clone(), name: n.name.clone(),
lower_name: n.lower_name.clone(), lower_name: n.lower_name.clone(),

View file

@ -85,15 +85,15 @@ fn test_parse_stylesheet() {
selectors: SelectorList(vec![ selectors: SelectorList(vec![
Selector { Selector {
inner: SelectorInner::from_vec(vec![ inner: SelectorInner::from_vec(vec![
SimpleSelector::Namespace(Namespace { Component::Namespace(Namespace {
prefix: None, prefix: None,
url: NsAtom::from("http://www.w3.org/1999/xhtml") url: NsAtom::from("http://www.w3.org/1999/xhtml")
}), }),
SimpleSelector::LocalName(LocalName { Component::LocalName(LocalName {
name: local_name!("input"), name: local_name!("input"),
lower_name: local_name!("input"), lower_name: local_name!("input"),
}), }),
SimpleSelector::AttrEqual(AttrSelector { Component::AttrEqual(AttrSelector {
name: local_name!("type"), name: local_name!("type"),
lower_name: local_name!("type"), lower_name: local_name!("type"),
namespace: NamespaceConstraint::Specific(Namespace { namespace: NamespaceConstraint::Specific(Namespace {
@ -118,11 +118,11 @@ fn test_parse_stylesheet() {
selectors: SelectorList(vec![ selectors: SelectorList(vec![
Selector { Selector {
inner: SelectorInner::from_vec(vec![ inner: SelectorInner::from_vec(vec![
SimpleSelector::Namespace(Namespace { Component::Namespace(Namespace {
prefix: None, prefix: None,
url: NsAtom::from("http://www.w3.org/1999/xhtml") url: NsAtom::from("http://www.w3.org/1999/xhtml")
}), }),
SimpleSelector::LocalName(LocalName { Component::LocalName(LocalName {
name: local_name!("html"), name: local_name!("html"),
lower_name: local_name!("html"), lower_name: local_name!("html"),
}), }),
@ -132,11 +132,11 @@ fn test_parse_stylesheet() {
}, },
Selector { Selector {
inner: SelectorInner::from_vec(vec![ inner: SelectorInner::from_vec(vec![
SimpleSelector::Namespace(Namespace { Component::Namespace(Namespace {
prefix: None, prefix: None,
url: NsAtom::from("http://www.w3.org/1999/xhtml") url: NsAtom::from("http://www.w3.org/1999/xhtml")
}), }),
SimpleSelector::LocalName(LocalName { Component::LocalName(LocalName {
name: local_name!("body"), name: local_name!("body"),
lower_name: local_name!("body"), lower_name: local_name!("body"),
}), }),
@ -154,17 +154,17 @@ fn test_parse_stylesheet() {
selectors: SelectorList(vec![ selectors: SelectorList(vec![
Selector { Selector {
inner: SelectorInner::from_vec(vec![ inner: SelectorInner::from_vec(vec![
SimpleSelector::Namespace(Namespace { Component::Namespace(Namespace {
prefix: None, prefix: None,
url: NsAtom::from("http://www.w3.org/1999/xhtml") url: NsAtom::from("http://www.w3.org/1999/xhtml")
}), }),
SimpleSelector::ID(Atom::from("d1")), Component::ID(Atom::from("d1")),
SimpleSelector::Combinator(Combinator::Child), Component::Combinator(Combinator::Child),
SimpleSelector::Namespace(Namespace { Component::Namespace(Namespace {
prefix: None, prefix: None,
url: NsAtom::from("http://www.w3.org/1999/xhtml") url: NsAtom::from("http://www.w3.org/1999/xhtml")
}), }),
SimpleSelector::Class(Atom::from("ok")), Component::Class(Atom::from("ok")),
]), ]),
pseudo_element: None, pseudo_element: None,
specificity: (1 << 20) + (1 << 10) + (0 << 0), specificity: (1 << 20) + (1 << 10) + (0 << 0),