diff --git a/components/selectors/parser.rs b/components/selectors/parser.rs index ac5d184cb9b..8cacbe6f3a2 100644 --- a/components/selectors/parser.rs +++ b/components/selectors/parser.rs @@ -50,9 +50,6 @@ fn to_ascii_lowercase(s: &str) -> Cow { pub enum SelectorParseError<'i, T> { PseudoElementInComplexSelector, NoQualifiedNameInAttributeSelector(Token<'i>), - TooManyCompoundSelectorComponentsInNegation, - NegationSelectorComponentNotNamespace, - NegationSelectorComponentNotLocalName, EmptySelector, DanglingCombinator, NonSimpleSelectorInNegation, @@ -67,6 +64,8 @@ pub enum SelectorParseError<'i, T> { BadValueInAttr(Token<'i>), InvalidQualNameInAttr(Token<'i>), ExplicitNamespaceUnexpectedToken(Token<'i>), + ClassNeedsIdent(Token<'i>), + EmptyNegation, Custom(T), } @@ -1446,13 +1445,19 @@ fn parse_negation<'i, 't, P, E, Impl>(parser: &P, // Get exactly one simple selector. The parse logic in the caller will verify // that there are no trailing tokens after we're done. - if !parse_type_selector(parser, input, &mut sequence)? { + let is_type_sel = match parse_type_selector(parser, input, &mut sequence) { + Ok(result) => result, + Err(ParseError::Basic(BasicParseError::EndOfInput)) => + return Err(SelectorParseError::EmptyNegation.into()), + Err(e) => return Err(e.into()), + }; + if !is_type_sel { match parse_one_simple_selector(parser, input, /* inside_negation = */ true)? { Some(SimpleSelectorParseResult::SimpleSelector(s)) => { sequence.push(s); }, None => { - return Err(ParseError::Custom(SelectorParseError::EmptySelector)); + return Err(ParseError::Custom(SelectorParseError::EmptyNegation)); }, Some(SimpleSelectorParseResult::PseudoElement(_)) => { return Err(ParseError::Custom(SelectorParseError::NonSimpleSelectorInNegation)); @@ -1622,7 +1627,7 @@ fn parse_one_simple_selector<'i, 't, P, E, Impl>(parser: &P, let class = Component::Class(class.as_ref().into()); Ok(Some(SimpleSelectorParseResult::SimpleSelector(class))) } - ref t => Err(ParseError::Basic(BasicParseError::UnexpectedToken(t.clone()))), + ref t => Err(SelectorParseError::ClassNeedsIdent(t.clone()).into()), } } Ok(Token::SquareBracketBlock) => { diff --git a/ports/geckolib/error_reporter.rs b/ports/geckolib/error_reporter.rs index 1f2c683aca3..67afdb0dfba 100644 --- a/ports/geckolib/error_reporter.rs +++ b/ports/geckolib/error_reporter.rs @@ -255,6 +255,7 @@ fn extract_error_params<'a>(err: ParseError<'a>) -> Option> { CssParseError::Custom(SelectorParseError::ExplicitNamespaceUnexpectedToken(t)) | CssParseError::Custom(SelectorParseError::PseudoElementExpectedIdent(t)) | CssParseError::Custom(SelectorParseError::NoIdentForPseudo(t)) | + CssParseError::Custom(SelectorParseError::ClassNeedsIdent(t)) | CssParseError::Custom(SelectorParseError::PseudoElementExpectedColon(t)) => (None, Some(ErrorString::UnexpectedToken(t))), @@ -268,6 +269,9 @@ fn extract_error_params<'a>(err: ParseError<'a>) -> Option> { CssParseError::Custom(SelectorParseError::DanglingCombinator) => (None, None), + CssParseError::Custom(SelectorParseError::EmptyNegation) => + (None, Some(ErrorString::Snippet(")".into()))), + err => match extract_error_param(err) { Some(e) => (Some(e), None), None => return None, @@ -368,6 +372,10 @@ impl<'a> ErrorHelpers<'a> for ContextualParseError<'a> { Some(&b"PEPseudoClassArgNotIdent\0"[..]), CssParseError::Custom(SelectorParseError::PseudoElementExpectedIdent(_)) => Some(&b"PEPseudoSelBadName\0"[..]), + CssParseError::Custom(SelectorParseError::ClassNeedsIdent(_)) => + Some(&b"PEClassSelNotIdent\0"[..]), + CssParseError::Custom(SelectorParseError::EmptyNegation) => + Some(&b"PENegationBadArg\0"[..]), _ => None, }; return (prefix, b"PEBadSelectorRSIgnored\0", Action::Nothing);