From be9bd84788c551d642b3d3eeb29d5f3ac793dce2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Sat, 9 Dec 2017 17:15:14 -0600 Subject: [PATCH] servo: Merge #19536 - style: Move the code to parse a list of compound selectors (from emilio:compound-selector-list); r=mbrubeck I'll need this for ::slotted(). Source-Repo: https://github.com/servo/servo Source-Revision: c6bf85eca90b9cb71ff05d4454a43a7da5fc3ac8 --HG-- extra : subtree_source : https%3A//hg.mozilla.org/projects/converted-servo-linear extra : subtree_revision : 02f9868af7469734b70d02e8ddb0470a9c8d407d --- servo/components/selectors/parser.rs | 28 +++++++++++++++++++ .../components/style/gecko/selector_parser.rs | 18 +++++------- 2 files changed, 35 insertions(+), 11 deletions(-) diff --git a/servo/components/selectors/parser.rs b/servo/components/selectors/parser.rs index ff9f45eac853..cf84648760b9 100644 --- a/servo/components/selectors/parser.rs +++ b/servo/components/selectors/parser.rs @@ -55,6 +55,7 @@ pub enum SelectorParseErrorKind<'i> { EmptySelector, DanglingCombinator, NonSimpleSelectorInNegation, + NonCompoundSelector, UnexpectedTokenInAttributeSelector(Token<'i>), PseudoElementExpectedColon(Token<'i>), PseudoElementExpectedIdent(Token<'i>), @@ -209,6 +210,33 @@ impl SelectorList { } } +/// Parse a comma separated list of compound selectors. +pub fn parse_compound_selector_list<'i, 't, P, Impl>( + parser: &P, + input: &mut CssParser<'i, 't>, +) -> Result]>, ParseError<'i, P::Error>> +where + P: Parser<'i, Impl=Impl>, + Impl: SelectorImpl, +{ + let location = input.current_source_location(); + let selectors = input.parse_comma_separated(|input| { + Selector::parse(parser, input) + })?; + + // Ensure they're actually all compound selectors. + if selectors + .iter() + .flat_map(|x| x.iter_raw_match_order()) + .any(|s| s.is_combinator()) { + return Err(location.new_custom_error( + SelectorParseErrorKind::NonCompoundSelector + )) + } + + Ok(selectors.into_boxed_slice()) +} + /// Ancestor hashes for the bloom filter. We precompute these and store them /// inline with selectors to optimize cache performance during matching. /// This matters a lot. diff --git a/servo/components/style/gecko/selector_parser.rs b/servo/components/style/gecko/selector_parser.rs index 4da4d9c9c585..0dec6ed479a7 100644 --- a/servo/components/style/gecko/selector_parser.rs +++ b/servo/components/style/gecko/selector_parser.rs @@ -11,7 +11,7 @@ use gecko_bindings::structs::RawServoSelectorList; use gecko_bindings::sugar::ownership::{HasBoxFFI, HasFFI, HasSimpleFFI}; use selector_parser::{Direction, SelectorParser}; use selectors::SelectorList; -use selectors::parser::{Selector, SelectorMethods, SelectorParseErrorKind}; +use selectors::parser::{self as selector_parser, Selector, SelectorMethods, SelectorParseErrorKind}; use selectors::visitor::SelectorVisitor; use std::fmt; use string_cache::{Atom, Namespace, WeakAtom, WeakNamespace}; @@ -400,16 +400,12 @@ impl<'a, 'i> ::selectors::Parser<'i> for SelectorParser<'a> { NonTSPseudoClass::Dir(Box::new(direction)) }, "-moz-any" => { - let selectors = parser.parse_comma_separated(|input| { - Selector::parse(self, input) - })?; - // Selectors inside `:-moz-any` may not include combinators. - if selectors.iter().flat_map(|x| x.iter_raw_match_order()).any(|s| s.is_combinator()) { - return Err(parser.new_custom_error( - SelectorParseErrorKind::UnexpectedIdent("-moz-any".into()) - )) - } - NonTSPseudoClass::MozAny(selectors.into_boxed_slice()) + NonTSPseudoClass::MozAny( + selector_parser::parse_compound_selector_list( + self, + parser, + )? + ) } _ => return Err(parser.new_custom_error( SelectorParseErrorKind::UnsupportedPseudoClassOrElement(name.clone())