4
4
5
5
// https://drafts.csswg.org/css-syntax/#parsing
6
6
7
- use super :: { BasicParseError , BasicParseErrorKind , Delimiter , Delimiters , ParseError , Parser , Token } ;
7
+ use super :: {
8
+ BasicParseError , BasicParseErrorKind , Delimiter , Delimiters , ParseError , Parser , Token ,
9
+ } ;
8
10
use crate :: cow_rc_str:: CowRcStr ;
9
11
use crate :: parser:: { parse_nested_block, parse_until_after, parse_until_before, ParserState } ;
10
12
@@ -239,8 +241,7 @@ impl<'i, 't, 'a, P, I, E> RuleBodyParser<'i, 't, 'a, P, I, E> {
239
241
}
240
242
}
241
243
242
- /// `DeclarationListParser` is an iterator that yields `Ok(_)` for a valid declaration or at-rule
243
- /// or `Err(())` for an invalid one.
244
+ /// https://drafts.csswg.org/css-syntax/#consume-a-blocks-contents
244
245
impl < ' i , ' t , ' a , I , P , E : ' i > Iterator for RuleBodyParser < ' i , ' t , ' a , P , I , E >
245
246
where
246
247
P : RuleBodyItemParser < ' i , I , E > ,
@@ -252,47 +253,51 @@ where
252
253
self . input . skip_whitespace ( ) ;
253
254
let start = self . input . state ( ) ;
254
255
match self . input . next_including_whitespace_and_comments ( ) . ok ( ) ? {
256
+ Token :: CloseCurlyBracket |
257
+ Token :: WhiteSpace ( ..) |
258
+ Token :: Semicolon |
255
259
Token :: Comment ( ..) => continue ,
256
- Token :: Semicolon if self . parser . parse_declarations ( ) => continue ,
260
+ Token :: AtKeyword ( ref name) => {
261
+ let name = name. clone ( ) ;
262
+ return Some ( parse_at_rule ( & start, name, self . input , & mut * self . parser ) ) ;
263
+ }
264
+ // https://drafts.csswg.org/css-syntax/#consume-a-declaration bails out just to
265
+ // keep parsing as a qualified rule if the token is not an ident, so we implement
266
+ // that in a slightly more straight-forward way
257
267
Token :: Ident ( ref name) if self . parser . parse_declarations ( ) => {
258
268
let name = name. clone ( ) ;
259
- let parse_qualified = self . parser . parse_qualified ( ) ;
260
- let delimiters = if parse_qualified {
261
- Delimiter :: Semicolon | Delimiter :: CurlyBracketBlock
262
- } else {
263
- Delimiter :: Semicolon
264
- } ;
265
- let mut result = {
269
+ let result = {
266
270
let parser = & mut self . parser ;
267
- parse_until_after ( self . input , delimiters , |input| {
271
+ parse_until_after ( self . input , Delimiter :: Semicolon , |input| {
268
272
input. expect_colon ( ) ?;
269
273
parser. parse_value ( name, input)
270
274
} )
271
275
} ;
272
-
273
- if result. is_err ( ) && parse_qualified {
276
+ if result. is_err ( ) && self . parser . parse_qualified ( ) {
274
277
self . input . reset ( & start) ;
275
- result =
276
- parse_qualified_rule ( & start, self . input , & mut * self . parser , delimiters) ;
278
+ // We ignore the resulting error here. The property declaration parse error
279
+ // is likely to be more relevant.
280
+ if let Ok ( qual) = parse_qualified_rule (
281
+ & start,
282
+ self . input ,
283
+ & mut * self . parser ,
284
+ Delimiter :: Semicolon | Delimiter :: CurlyBracketBlock ,
285
+ ) {
286
+ return Some ( Ok ( qual) )
287
+ }
277
288
}
278
289
279
290
return Some ( result. map_err ( |e| ( e, self . input . slice_from ( start. position ( ) ) ) ) ) ;
280
291
}
281
- Token :: AtKeyword ( ref name) => {
282
- let name = name. clone ( ) ;
283
- return Some ( parse_at_rule ( & start, name, self . input , & mut * self . parser ) ) ;
284
- }
285
292
token => {
286
293
let result = if self . parser . parse_qualified ( ) {
287
294
self . input . reset ( & start) ;
288
- // TODO(emilio, nesting): do we need to, if we fail, consume only until the
289
- // next semicolon, rather than until the next `{`?
290
- parse_qualified_rule (
291
- & start,
292
- self . input ,
293
- & mut * self . parser ,
294
- Delimiter :: CurlyBracketBlock ,
295
- )
295
+ let delimiters = if self . parser . parse_declarations ( ) {
296
+ Delimiter :: Semicolon | Delimiter :: CurlyBracketBlock
297
+ } else {
298
+ Delimiter :: CurlyBracketBlock
299
+ } ;
300
+ parse_qualified_rule ( & start, self . input , & mut * self . parser , delimiters)
296
301
} else {
297
302
let token = token. clone ( ) ;
298
303
self . input . parse_until_after ( Delimiter :: Semicolon , |_| {
0 commit comments