- From: Simon Sapin <simon.sapin@exyr.org>
- Date: Mon, 22 Apr 2013 08:12:15 +0200
- To: John Daggett <jdaggett@mozilla.com>
- CC: www-style list <www-style@w3.org>, "Tab Atkins Jr." <jackalmage@gmail.com>
Le 22/04/2013 07:07, John Daggett a écrit :
> This might be unrelated, but I noticed that there's an interesting
> pattern involving the handling of the semi-colon*between* @-rules in
> most CSS parsers:
>
> @bongo /* no {} block */
>
> @font-face {
> font-family: test1;
> src: url(...);
> }
>
> @bongo ; /* no {} block but semi-colon */
>
> @font-face {
> font-family: test2;
> src: url(...);
> }
>
> For the two cases above, all browsers that I tested didn't parse the
> test1 font rule but*did* parse the test2 rule. This behavior is
> consistent but I don't see how this follows from the 2.1 grammar
> definition.
In this case, browsers have the expected behavior both per 2.1 and
Syntax 3. This is the "malformed statement" error handling rule:
> User agents must handle unexpected tokens encountered while parsing a
> statement by reading until the end of the statement, while observing
> the rules for matching pairs of (), [], {}, "", and '', and correctly
> handling escapes.
By definition, an at-rule ends with either a semicolon or a {} block:
> at-rule : ATKEYWORD S* any* [ block | ';' S* ];
(Syntax 3 clarifies that EOF or the end of a parent block also ends an
at-rule like a semicolon.)
Another way to view this (or even to implement it) as that the
Syntax-level parser starts an at-rule when finding an at-keyword, keeps
adding tokens/component values to the "prelude" of the rule until it
finds a semicolon or a {} block, and consumes the content of any {}
block as the body of the rule. Only then, a more specific higher-level
parser is triggered based on the value of the at-keyword. (eg.
@font-face expects an empty or whitespace-only prelude, and a body block
containing declarations.)
In your example above, you get one at-rule whose at-keyword is @bongo,
whose prelude is WS COMMENT WS AT-KEYWORD WS, and which has a {} block
body. Then a second @bongo rule whose prelude is just WS and has no
body, then an @font-face rule.
But these @bongo rules are only invalid because no spec defines @bongo.
Nothing’s wrong with the syntax itself. Or at least in Syntax 3, I think
2.1 did not allow at-keywords in at-rule preludes but the error recovery
stays the same.
> Because of the recent syntax change to the @font-feature-values rule,
> this behavior also affects cases like the one below:
>
> @font-feature-values fantastic font, crappy font {
> @bongo
> @styleset { crossed-w: 3; }
> }
>
> Does the syntax error in the line containing '@bongo' cause the
> definition of 'crossed-w' to get eaten as part of the error handling?
Yes. Just like above, inside this @font-feature-values rule you have one
at-rule whose prelude happens to contain an at-keyword.
> Would that change if the first line was '@bongo ;' instead?
Yes. A semicolon would end the @bongo rule and leave @styleset be its
own rule.
Cheers,
--
Simon Sapin
Received on Monday, 22 April 2013 06:12:38 UTC