summaryrefslogtreecommitdiffstats
path: root/third_party/rust/cssparser/src/rules_and_declarations.rs
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/rust/cssparser/src/rules_and_declarations.rs')
-rw-r--r--third_party/rust/cssparser/src/rules_and_declarations.rs87
1 files changed, 59 insertions, 28 deletions
diff --git a/third_party/rust/cssparser/src/rules_and_declarations.rs b/third_party/rust/cssparser/src/rules_and_declarations.rs
index fb33a7d0cd..48da02b5cc 100644
--- a/third_party/rust/cssparser/src/rules_and_declarations.rs
+++ b/third_party/rust/cssparser/src/rules_and_declarations.rs
@@ -4,9 +4,7 @@
// https://drafts.csswg.org/css-syntax/#parsing
-use super::{
- BasicParseError, BasicParseErrorKind, Delimiter, Delimiters, ParseError, Parser, Token,
-};
+use super::{BasicParseError, BasicParseErrorKind, Delimiter, ParseError, Parser, Token};
use crate::cow_rc_str::CowRcStr;
use crate::parser::{parse_nested_block, parse_until_after, ParseUntilErrorBehavior, ParserState};
@@ -14,7 +12,7 @@ use crate::parser::{parse_nested_block, parse_until_after, ParseUntilErrorBehavi
///
/// Typical usage is `input.try_parse(parse_important).is_ok()`
/// at the end of a `DeclarationParser::parse_value` implementation.
-pub fn parse_important<'i, 't>(input: &mut Parser<'i, 't>) -> Result<(), BasicParseError<'i>> {
+pub fn parse_important<'i>(input: &mut Parser<'i, '_>) -> Result<(), BasicParseError<'i>> {
input.expect_delim('!')?;
input.expect_ident_matching("important")
}
@@ -34,7 +32,7 @@ pub trait DeclarationParser<'i> {
///
/// Return the finished representation for the declaration
/// as returned by `DeclarationListParser::next`,
- /// or `Err(())` to ignore the entire declaration as invalid.
+ /// or an `Err(..)` to ignore the entire declaration as invalid.
///
/// Declaration name matching should be case-insensitive in the ASCII range.
/// This can be done with `std::ascii::Ascii::eq_ignore_ascii_case`,
@@ -78,7 +76,7 @@ pub trait AtRuleParser<'i> {
/// Parse the prelude of an at-rule with the given `name`.
///
/// Return the representation of the prelude and the type of at-rule,
- /// or `Err(())` to ignore the entire at-rule as invalid.
+ /// or an `Err(..)` to ignore the entire at-rule as invalid.
///
/// The prelude is the part after the at-keyword
/// and before the `;` semicolon or `{ /* ... */ }` block.
@@ -106,6 +104,7 @@ pub trait AtRuleParser<'i> {
/// This is only called when `parse_prelude` returned `WithoutBlock`, and
/// either the `;` semicolon indeed follows the prelude, or parser is at
/// the end of the input.
+ #[allow(clippy::result_unit_err)]
fn rule_without_block(
&mut self,
prelude: Self::Prelude,
@@ -122,7 +121,7 @@ pub trait AtRuleParser<'i> {
///
/// Return the finished representation of the at-rule
/// as returned by `RuleListParser::next` or `DeclarationListParser::next`,
- /// or `Err(())` to ignore the entire at-rule as invalid.
+ /// or an `Err(..)` to ignore the entire at-rule as invalid.
///
/// This is only called when `parse_prelude` returned `WithBlock`, and a block
/// was indeed found following the prelude.
@@ -161,7 +160,7 @@ pub trait QualifiedRuleParser<'i> {
/// Parse the prelude of a qualified rule. For style rules, this is as Selector list.
///
/// Return the representation of the prelude,
- /// or `Err(())` to ignore the entire at-rule as invalid.
+ /// or an `Err(..)` to ignore the entire at-rule as invalid.
///
/// The prelude is the part before the `{ /* ... */ }` block.
///
@@ -180,7 +179,7 @@ pub trait QualifiedRuleParser<'i> {
///
/// Return the finished representation of the qualified rule
/// as returned by `RuleListParser::next`,
- /// or `Err(())` to ignore the entire at-rule as invalid.
+ /// or an `Err(..)` to ignore the entire at-rule as invalid.
fn parse_block<'t>(
&mut self,
prelude: Self::Prelude,
@@ -253,10 +252,10 @@ where
self.input.skip_whitespace();
let start = self.input.state();
match self.input.next_including_whitespace_and_comments().ok()? {
- Token::CloseCurlyBracket |
- Token::WhiteSpace(..) |
- Token::Semicolon |
- Token::Comment(..) => continue,
+ Token::CloseCurlyBracket
+ | Token::WhiteSpace(..)
+ | Token::Semicolon
+ | Token::Comment(..) => continue,
Token::AtKeyword(ref name) => {
let name = name.clone();
return Some(parse_at_rule(&start, name, self.input, &mut *self.parser));
@@ -292,9 +291,9 @@ where
&start,
self.input,
&mut *self.parser,
- Delimiter::Semicolon | Delimiter::CurlyBracketBlock,
+ /* nested = */ true,
) {
- return Some(Ok(qual))
+ return Some(Ok(qual));
}
}
@@ -303,12 +302,8 @@ where
token => {
let result = if self.parser.parse_qualified() {
self.input.reset(&start);
- let delimiters = if self.parser.parse_declarations() {
- Delimiter::Semicolon | Delimiter::CurlyBracketBlock
- } else {
- Delimiter::CurlyBracketBlock
- };
- parse_qualified_rule(&start, self.input, &mut *self.parser, delimiters)
+ let nested = self.parser.parse_declarations();
+ parse_qualified_rule(&start, self.input, &mut *self.parser, nested)
} else {
let token = token.clone();
self.input.parse_until_after(Delimiter::Semicolon, |_| {
@@ -353,7 +348,7 @@ where
}
}
-/// `RuleListParser` is an iterator that yields `Ok(_)` for a rule or `Err(())` for an invalid one.
+/// `RuleListParser` is an iterator that yields `Ok(_)` for a rule or an `Err(..)` for an invalid one.
impl<'i, 't, 'a, R, P, E: 'i> Iterator for StyleSheetParser<'i, 't, 'a, P>
where
P: QualifiedRuleParser<'i, QualifiedRule = R, Error = E>
@@ -367,7 +362,7 @@ where
let start = self.input.state();
let at_keyword = match self.input.next_byte()? {
b'@' => match self.input.next_including_whitespace_and_comments() {
- Ok(&Token::AtKeyword(ref name)) => Some(name.clone()),
+ Ok(Token::AtKeyword(name)) => Some(name.clone()),
_ => {
self.input.reset(&start);
None
@@ -397,7 +392,7 @@ where
&start,
self.input,
&mut *self.parser,
- Delimiter::CurlyBracketBlock,
+ /* nested = */ false,
);
return Some(result.map_err(|e| (e, self.input.slice_from(start.position()))));
}
@@ -450,7 +445,7 @@ where
if let Some(name) = at_keyword {
parse_at_rule(&start, name, input, parser).map_err(|e| e.0)
} else {
- parse_qualified_rule(&start, input, parser, Delimiter::CurlyBracketBlock)
+ parse_qualified_rule(&start, input, parser, /* nested = */ false)
}
})
}
@@ -490,18 +485,54 @@ where
}
}
+// If the first two non-<whitespace-token> values of rule’s prelude are an <ident-token> whose
+// value starts with "--" followed by a <colon-token>, then...
+fn looks_like_a_custom_property(input: &mut Parser) -> bool {
+ let ident = match input.expect_ident() {
+ Ok(i) => i,
+ Err(..) => return false,
+ };
+ ident.starts_with("--") && input.expect_colon().is_ok()
+}
+
+// https://drafts.csswg.org/css-syntax/#consume-a-qualified-rule
fn parse_qualified_rule<'i, 't, P, E>(
start: &ParserState,
input: &mut Parser<'i, 't>,
parser: &mut P,
- delimiters: Delimiters,
+ nested: bool,
) -> Result<<P as QualifiedRuleParser<'i>>::QualifiedRule, ParseError<'i, E>>
where
P: QualifiedRuleParser<'i, Error = E>,
{
- let prelude = input.parse_until_before(delimiters, |input| parser.parse_prelude(input));
+ input.skip_whitespace();
+ let prelude = {
+ let state = input.state();
+ if looks_like_a_custom_property(input) {
+ // If nested is true, consume the remnants of a bad declaration from input, with
+ // nested set to true, and return nothing.
+ // If nested is false, consume a block from input, and return nothing.
+ let delimiters = if nested {
+ Delimiter::Semicolon
+ } else {
+ Delimiter::CurlyBracketBlock
+ };
+ let _: Result<(), ParseError<()>> = input.parse_until_after(delimiters, |_| Ok(()));
+ return Err(state
+ .source_location()
+ .new_error(BasicParseErrorKind::QualifiedRuleInvalid));
+ }
+ let delimiters = if nested {
+ Delimiter::Semicolon | Delimiter::CurlyBracketBlock
+ } else {
+ Delimiter::CurlyBracketBlock
+ };
+ input.reset(&state);
+ input.parse_until_before(delimiters, |input| parser.parse_prelude(input))
+ };
+
input.expect_curly_bracket_block()?;
// Do this here so that we consume the `{` even if the prelude is `Err`.
let prelude = prelude?;
- parse_nested_block(input, |input| parser.parse_block(prelude, &start, input))
+ parse_nested_block(input, |input| parser.parse_block(prelude, start, input))
}