Allow selector parser to specify pseudo-element which can be used with single-colon syntax. r?heycam draft
authorXidorn Quan <me@upsuper.org>
Mon, 10 Jul 2017 13:52:38 +1000
changeset 606465 8a621554e75b0615f741c22c1b937a8c4a94a361
parent 606464 6791b53f12b3003ebe503e2e33f1e1c24dfb6624
child 606466 f982ef87e7b7091d2b1ad2de90a4d9b790c06583
push id67706
push userxquan@mozilla.com
push dateMon, 10 Jul 2017 23:54:14 +0000
reviewersheycam
milestone56.0a1
Allow selector parser to specify pseudo-element which can be used with single-colon syntax. r?heycam MozReview-Commit-ID: BqozVhhc4bV
servo/components/selectors/parser.rs
--- a/servo/components/selectors/parser.rs
+++ b/servo/components/selectors/parser.rs
@@ -126,16 +126,22 @@ with_bounds! {
     [Clone + Eq]
     [From<String> + for<'a> From<&'a str>]
 }
 
 pub trait Parser<'i> {
     type Impl: SelectorImpl;
     type Error: 'i;
 
+    /// Whether the name is a pseudo-element that can be specified with
+    /// the single colon syntax in addition to the double-colon syntax.
+    fn is_pseudo_element_allows_single_colon(name: &CompactCowStr<'i>) -> bool {
+        is_css2_pseudo_element(name)
+    }
+
     /// This function can return an "Err" pseudo-element in order to support CSS2.1
     /// pseudo-elements.
     fn parse_non_ts_pseudo_class(&self, name: CompactCowStr<'i>)
                                  -> Result<<Self::Impl as SelectorImpl>::NonTSPseudoClass,
                                            ParseError<'i, SelectorParseError<'i, Self::Error>>> {
         Err(ParseError::Custom(SelectorParseError::UnexpectedIdent(name)))
     }
 
@@ -1475,17 +1481,17 @@ where Impl: SelectorImpl, F: FnOnce(i32,
     let (a, b) = parse_nth(input)?;
     Ok(selector(a, b))
 }
 
 
 /// Returns whether the name corresponds to a CSS2 pseudo-element that
 /// can be specified with the single colon syntax (in addition to the
 /// double-colon syntax, which can be used for all pseudo-elements).
-fn is_css2_pseudo_element<'i>(name: &CompactCowStr<'i>) -> bool {
+pub fn is_css2_pseudo_element<'i>(name: &CompactCowStr<'i>) -> bool {
     // ** Do not add to this list! **
     return name.eq_ignore_ascii_case("before") ||
            name.eq_ignore_ascii_case("after") ||
            name.eq_ignore_ascii_case("first-line") ||
            name.eq_ignore_ascii_case("first-letter");
 }
 
 /// Parse a simple selector other than a type selector.
@@ -1524,17 +1530,18 @@ fn parse_one_simple_selector<'i, 't, P, 
                 Token::Colon => (false, input.next_including_whitespace()?),
                 t => (true, t),
             };
             let (name, is_functional) = match next_token {
                 Token::Ident(name) => (name, false),
                 Token::Function(name) => (name, true),
                 t => return Err(ParseError::Basic(BasicParseError::UnexpectedToken(t))),
             };
-            let is_pseudo_element = !is_single_colon || is_css2_pseudo_element(&name);
+            let is_pseudo_element = !is_single_colon ||
+                P::is_pseudo_element_allows_single_colon(&name);
             if !is_pseudo_element {
                 let pseudo_class = if !is_functional {
                     parse_simple_pseudo_class(parser, name)?
                 } else {
                     input.parse_nested_block(|input| {
                         parse_functional_pseudo_class(parser, input, name, inside_negation)
                     })?
                 };