@@ -50,14 +50,9 @@ pub trait DeclarationParser<'i> {
5050 & mut self ,
5151 name : CowRcStr < ' i > ,
5252 input : & mut Parser < ' i , ' t > ,
53- ) -> Result < Self :: Declaration , ParseError < ' i , Self :: Error > > ;
54-
55- /// Whether to try to parse qualified rules along with declarations. See
56- /// <https://github.com/w3c/csswg-drafts/issues/7961> for the current state of the discussion.
57- /// This is a low effort opt-in to be able to experiment with it, but it's likely to be needed
58- /// when nesting is less experimental as well (e.g., you probably don't want to allow nesting
59- /// in a style attribute anyways).
60- fn enable_nesting ( & self ) -> bool { false }
53+ ) -> Result < Self :: Declaration , ParseError < ' i , Self :: Error > > {
54+ Err ( input. new_error ( BasicParseErrorKind :: UnexpectedToken ( Token :: Ident ( name) ) ) )
55+ }
6156}
6257
6358/// A trait to provide various parsing of at-rules.
@@ -99,8 +94,6 @@ pub trait AtRuleParser<'i> {
9994 name : CowRcStr < ' i > ,
10095 input : & mut Parser < ' i , ' t > ,
10196 ) -> Result < Self :: Prelude , ParseError < ' i , Self :: Error > > {
102- let _ = name;
103- let _ = input;
10497 Err ( input. new_error ( BasicParseErrorKind :: AtRuleInvalid ( name) ) )
10598 }
10699
@@ -140,7 +133,6 @@ pub trait AtRuleParser<'i> {
140133 ) -> Result < Self :: AtRule , ParseError < ' i , Self :: Error > > {
141134 let _ = prelude;
142135 let _ = start;
143- let _ = input;
144136 Err ( input. new_error ( BasicParseErrorKind :: AtRuleBodyInvalid ) )
145137 }
146138}
@@ -178,7 +170,6 @@ pub trait QualifiedRuleParser<'i> {
178170 & mut self ,
179171 input : & mut Parser < ' i , ' t > ,
180172 ) -> Result < Self :: Prelude , ParseError < ' i , Self :: Error > > {
181- let _ = input;
182173 Err ( input. new_error ( BasicParseErrorKind :: QualifiedRuleInvalid ) )
183174 }
184175
@@ -197,24 +188,35 @@ pub trait QualifiedRuleParser<'i> {
197188 ) -> Result < Self :: QualifiedRule , ParseError < ' i , Self :: Error > > {
198189 let _ = prelude;
199190 let _ = start;
200- let _ = input;
201191 Err ( input. new_error ( BasicParseErrorKind :: QualifiedRuleInvalid ) )
202192 }
203193}
204194
205- /// Provides an iterator for declaration list parsing .
206- pub struct DeclarationListParser < ' i , ' t , ' a , P > {
207- /// The input given to `DeclarationListParser::new`
195+ /// Provides an iterator for rule bodies and declaration lists .
196+ pub struct RuleBodyParser < ' i , ' t , ' a , P , I , E > {
197+ /// The input given to the parser.
208198 pub input : & ' a mut Parser < ' i , ' t > ,
209-
210199 /// The parser given to `DeclarationListParser::new`
211- pub parser : P ,
200+ pub parser : & ' a mut P ,
201+
202+ _phantom : std:: marker:: PhantomData < ( I , E ) > ,
212203}
213204
214- impl < ' i , ' t , ' a , I , P , E : ' i > DeclarationListParser < ' i , ' t , ' a , P >
215- where
216- P : DeclarationParser < ' i , Declaration = I , Error = E > + AtRuleParser < ' i , AtRule = I , Error = E > ,
205+ /// A parser for a rule body item.
206+ pub trait RuleBodyItemParser < ' i , DeclOrRule , Error : ' i >
207+ : DeclarationParser < ' i , Declaration = DeclOrRule , Error = Error >
208+ + QualifiedRuleParser < ' i , QualifiedRule = DeclOrRule , Error = Error >
209+ + AtRuleParser < ' i , AtRule = DeclOrRule , Error = Error >
217210{
211+ /// Whether we should attempt to parse declarations. If you know you won't, returning false
212+ /// here is slightly faster.
213+ fn parse_declarations ( & self ) -> bool ;
214+ /// Whether we should attempt to parse qualified rules. If you know you won't, returning false
215+ /// would be slightly faster.
216+ fn parse_qualified ( & self ) -> bool ;
217+ }
218+
219+ impl < ' i , ' t , ' a , P , I , E > RuleBodyParser < ' i , ' t , ' a , P , I , E > {
218220 /// Create a new `DeclarationListParser` for the given `input` and `parser`.
219221 ///
220222 /// Note that all CSS declaration lists can on principle contain at-rules.
@@ -229,29 +231,27 @@ where
229231 /// The return type for finished declarations and at-rules also needs to be the same,
230232 /// since `<DeclarationListParser as Iterator>::next` can return either.
231233 /// It could be a custom enum.
232- pub fn new ( input : & ' a mut Parser < ' i , ' t > , parser : P ) -> Self {
233- DeclarationListParser { input, parser }
234+ pub fn new ( input : & ' a mut Parser < ' i , ' t > , parser : & ' a mut P ) -> Self {
235+ Self { input, parser, _phantom : std :: marker :: PhantomData }
234236 }
235237}
236238
237239/// `DeclarationListParser` is an iterator that yields `Ok(_)` for a valid declaration or at-rule
238240/// or `Err(())` for an invalid one.
239- impl < ' i , ' t , ' a , I , P , E : ' i > Iterator for DeclarationListParser < ' i , ' t , ' a , P >
241+ impl < ' i , ' t , ' a , I , P , E : ' i > Iterator for RuleBodyParser < ' i , ' t , ' a , P , I , E >
240242where
241- P : DeclarationParser < ' i , Declaration = I , Error = E >
242- + AtRuleParser < ' i , AtRule = I , Error = E >
243- + QualifiedRuleParser < ' i , QualifiedRule = I , Error = E > ,
243+ P : RuleBodyItemParser < ' i , I , E > ,
244244{
245245 type Item = Result < I , ( ParseError < ' i , E > , & ' i str ) > ;
246246
247247 fn next ( & mut self ) -> Option < Self :: Item > {
248248 loop {
249249 let start = self . input . state ( ) ;
250- match self . input . next_including_whitespace_and_comments ( ) {
251- Ok ( & Token :: WhiteSpace ( _) ) | Ok ( & Token :: Comment ( _) ) | Ok ( & Token :: Semicolon ) => {
252- continue
250+ match self . input . next_including_whitespace_and_comments ( ) . ok ( ) ? {
251+ Token :: WhiteSpace ( _) | Token :: Comment ( _) | Token :: Semicolon => {
252+ continue ;
253253 }
254- Ok ( & Token :: Ident ( ref name) ) => {
254+ Token :: Ident ( ref name) if self . parser . parse_declarations ( ) => {
255255 let name = name. clone ( ) ;
256256 let mut result = {
257257 let parser = & mut self . parser ;
@@ -261,23 +261,23 @@ where
261261 } )
262262 } ;
263263
264- if result. is_err ( ) && self . parser . enable_nesting ( ) {
264+ if result. is_err ( ) && self . parser . parse_qualified ( ) {
265265 self . input . reset ( & start) ;
266- result = parse_qualified_rule ( & start, self . input , & mut self . parser ) ;
266+ result = parse_qualified_rule ( & start, self . input , & mut * self . parser ) ;
267267 }
268268
269269 return Some ( result. map_err ( |e| ( e, self . input . slice_from ( start. position ( ) ) ) ) ) ;
270270 }
271- Ok ( & Token :: AtKeyword ( ref name) ) => {
271+ Token :: AtKeyword ( ref name) => {
272272 let name = name. clone ( ) ;
273- return Some ( parse_at_rule ( & start, name, self . input , & mut self . parser ) ) ;
273+ return Some ( parse_at_rule ( & start, name, self . input , & mut * self . parser ) ) ;
274274 }
275- Ok ( token) => {
276- let result = if self . parser . enable_nesting ( ) {
275+ token => {
276+ let result = if self . parser . parse_qualified ( ) {
277277 self . input . reset ( & start) ;
278278 // XXX do we need to, if we fail, consume only until the next semicolon,
279279 // rather than until the next `{`?
280- parse_qualified_rule ( & start, self . input , & mut self . parser )
280+ parse_qualified_rule ( & start, self . input , & mut * self . parser )
281281 } else {
282282 let token = token. clone ( ) ;
283283 self . input . parse_until_after ( Delimiter :: Semicolon , |_| {
@@ -286,66 +286,44 @@ where
286286 } ;
287287 return Some ( result. map_err ( |e| ( e, self . input . slice_from ( start. position ( ) ) ) ) ) ;
288288 }
289- Err ( ..) => return None ,
290289 }
291290 }
292291 }
293292}
294293
295- /// Provides an iterator for rule list parsing.
296- pub struct RuleListParser < ' i , ' t , ' a , P > {
297- /// The input given to `RuleListParser::new`
294+ /// Provides an iterator for rule list parsing at the top-level of a stylesheet .
295+ pub struct StyleSheetParser < ' i , ' t , ' a , P > {
296+ /// The input given.
298297 pub input : & ' a mut Parser < ' i , ' t > ,
299298
300- /// The parser given to `RuleListParser::new`
301- pub parser : P ,
299+ /// The parser given.
300+ pub parser : & ' a mut P ,
302301
303- is_stylesheet : bool ,
304302 any_rule_so_far : bool ,
305303}
306304
307- impl < ' i , ' t , ' a , R , P , E : ' i > RuleListParser < ' i , ' t , ' a , P >
305+ impl < ' i , ' t , ' a , R , P , E : ' i > StyleSheetParser < ' i , ' t , ' a , P >
308306where
309307 P : QualifiedRuleParser < ' i , QualifiedRule = R , Error = E >
310308 + AtRuleParser < ' i , AtRule = R , Error = E > ,
311309{
312- /// Create a new `RuleListParser` for the given `input` at the top-level of a stylesheet
313- /// and the given `parser`.
314- ///
315310 /// The given `parser` needs to implement both `QualifiedRuleParser` and `AtRuleParser` traits.
316- /// However, either of them can be an empty `impl`
317- /// since the traits provide default implementations of their methods.
311+ /// However, either of them can be an empty `impl` since the traits provide default
312+ /// implementations of their methods.
318313 ///
319314 /// The return type for finished qualified rules and at-rules also needs to be the same,
320- /// since `<RuleListParser as Iterator>::next` can return either.
321- /// It could be a custom enum.
322- pub fn new_for_stylesheet ( input : & ' a mut Parser < ' i , ' t > , parser : P ) -> Self {
323- RuleListParser {
324- input,
325- parser,
326- is_stylesheet : true ,
327- any_rule_so_far : false ,
328- }
329- }
330-
331- /// Same is `new_for_stylesheet`, but should be used for rule lists inside a block
332- /// such as the body of an `@media` rule.
333- ///
334- /// This differs in that `<!--` and `-->` tokens
335- /// should only be ignored at the stylesheet top-level.
336- /// (This is to deal with legacy workarounds for `<style>` HTML element parsing.)
337- pub fn new_for_nested_rule ( input : & ' a mut Parser < ' i , ' t > , parser : P ) -> Self {
338- RuleListParser {
315+ /// since `<RuleListParser as Iterator>::next` can return either. It could be a custom enum.
316+ pub fn new ( input : & ' a mut Parser < ' i , ' t > , parser : & ' a mut P ) -> Self {
317+ Self {
339318 input,
340319 parser,
341- is_stylesheet : false ,
342320 any_rule_so_far : false ,
343321 }
344322 }
345323}
346324
347325/// `RuleListParser` is an iterator that yields `Ok(_)` for a rule or `Err(())` for an invalid one.
348- impl < ' i , ' t , ' a , R , P , E : ' i > Iterator for RuleListParser < ' i , ' t , ' a , P >
326+ impl < ' i , ' t , ' a , R , P , E : ' i > Iterator for StyleSheetParser < ' i , ' t , ' a , P >
349327where
350328 P : QualifiedRuleParser < ' i , QualifiedRule = R , Error = E >
351329 + AtRuleParser < ' i , AtRule = R , Error = E > ,
@@ -354,13 +332,8 @@ where
354332
355333 fn next ( & mut self ) -> Option < Self :: Item > {
356334 loop {
357- if self . is_stylesheet {
358- self . input . skip_cdc_and_cdo ( )
359- } else {
360- self . input . skip_whitespace ( )
361- }
335+ self . input . skip_cdc_and_cdo ( ) ;
362336 let start = self . input . state ( ) ;
363-
364337 let at_keyword = match self . input . next_byte ( ) ? {
365338 b'@' => match self . input . next_including_whitespace_and_comments ( ) {
366339 Ok ( & Token :: AtKeyword ( ref name) ) => Some ( name. clone ( ) ) ,
@@ -373,7 +346,7 @@ where
373346 } ;
374347
375348 if let Some ( name) = at_keyword {
376- let first_stylesheet_rule = self . is_stylesheet && !self . any_rule_so_far ;
349+ let first_stylesheet_rule = !self . any_rule_so_far ;
377350 self . any_rule_so_far = true ;
378351 if first_stylesheet_rule && name. eq_ignore_ascii_case ( "charset" ) {
379352 let delimiters = Delimiter :: Semicolon | Delimiter :: CurlyBracketBlock ;
@@ -384,13 +357,13 @@ where
384357 & start,
385358 name. clone ( ) ,
386359 self . input ,
387- & mut self . parser ,
388- ) ) ;
360+ & mut * self . parser ,
361+ ) )
389362 }
390363 } else {
391364 self . any_rule_so_far = true ;
392- let result = parse_qualified_rule ( & start, self . input , & mut self . parser ) ;
393- return Some ( result. map_err ( |e| ( e, self . input . slice_from ( start. position ( ) ) ) ) ) ;
365+ let result = parse_qualified_rule ( & start, self . input , & mut * self . parser ) ;
366+ return Some ( result. map_err ( |e| ( e, self . input . slice_from ( start. position ( ) ) ) ) )
394367 }
395368 }
396369 }
0 commit comments