@@ -2673,41 +2673,54 @@ Consume a qualified rule</h4>
2673
2673
If the first two non-<<whitespace-token>> values
2674
2674
of |rule|'s prelude are
2675
2675
an <<ident-token>> whose value starts with "--"
2676
- followed by a <<colon-token>> ,
2677
- [=consume the remnants of a bad declaration=] from |input|,
2678
- with |nested|,
2679
- and return nothing.
2676
+ followed by a <<colon-token>> , then:
2677
+
2678
+ * If |nested| is true,
2679
+ [=consume the remnants of a bad declaration=] from |input|,
2680
+ with |nested| set to true,
2681
+ and return nothing.
2682
+ * If |nested| is false,
2683
+ [=consume a block=] from |input|,
2684
+ and return nothing.
2680
2685
2681
2686
<details class=note>
2682
2687
<summary> What's this check for?</summary>
2683
2688
2684
2689
[=Declarations=] and [=qualified rules=]
2685
- overlap in their generic syntax;
2686
- <code> foo:bar {};</code>
2687
- could be a <css> foo</css> property
2688
- with a value of <css> bar {}</css> ,
2689
- or a qualified rule
2690
- with a <css> foo:bar</css> prelude
2691
- and an empty block.
2692
-
2693
- Validity checking ensures that they're parsed correctly,
2694
- but this still allows an <em> invalid</em> declaration
2695
- to get parsed as a rule.
2696
- This isn't generally a problem--
2697
- the CSSWG has not yet defined any declarations
2698
- with {}-blocks in their values,
2699
- so [=consume a qualified rule=] will hit the semicolon and stop,
2700
- consuming the same amount of tokens as the declaration would have.
2701
- (And if we do define such a declaration,
2702
- we'll take care to preserve this aspect.)
2690
+ don't <em> generally</em> overlap in their allowed syntax.
2691
+ No currently-defined CSS property allows {}-blocks in its value,
2692
+ so <code> foo:bar {};</code> is definitely a rule,
2693
+ and <code> foo: bar;</code> is definitely a property.
2694
+ Even if a future CSS property allows {}-blocks in its value,
2695
+ the allowed syntax is restricted to the {}-block being the whole value,
2696
+ such as <code> foo: {...};</code> ,
2697
+ which is guaranteed to not be a valid rule,
2698
+ since the '':'' doesn't have an ident or function following it
2699
+ to mark it as a pseudo-class.
2700
+
2701
+ This allows us to mix declarations and rules in the same context:
2702
+ we first try to parse something as a declaration,
2703
+ and if that doesn't result in a valid declaration,
2704
+ we reparse it as a rule instead.
2705
+ An accidentally-invalid declaration will parse as a rule instead,
2706
+ but that's fine:
2707
+ the parser will stop at the declaration's ending semicolon
2708
+ and consider it an invalid rule.
2709
+ (Or in the case of a property containing a {}-block,
2710
+ will stop just *before* the semicolon,
2711
+ still considering it an invalid rule,
2712
+ and then the next attempt to parse something
2713
+ will throw out the lone semicolon as invalid.)
2714
+ So the total amount of tokens consumed is the same regardless.
2703
2715
2704
2716
[=Custom properties=] , however, don't have the CSSWG
2705
2717
carefully vetting their syntax.
2706
2718
Authors <em> can</em> write a custom property
2707
- that takes a {}-block in its value;
2719
+ that takes a {}-block in its value,
2720
+ even combined with other thing;
2708
2721
if that custom property is then invalid
2709
2722
(due to an invalidly-written ''var()'' function, for example),
2710
- when it's parsed by [=consume a qualified rule=]
2723
+ when it's reparsed as a rule
2711
2724
it will stop early, at the {}-block.
2712
2725
The remaining tokens of the custom property's value
2713
2726
will then get parsed as a fresh construct,
@@ -2717,9 +2730,20 @@ Consume a qualified rule</h4>
2717
2730
To avoid this (admittedly very niche) corner-case,
2718
2731
we subtract the syntax of a [=custom property=]
2719
2732
from that of a [=qualified rule=] ;
2720
- if you somehow end up parsing a rule
2733
+ if you're in a context that allows properties and rules to be mixed,
2734
+ and you somehow end up parsing a rule
2721
2735
that looks like a [=custom property=] ,
2722
- you've messed up and need to treat it like an (invalid) property.
2736
+ you've messed up,
2737
+ and need to instead consume an entire custom property
2738
+ (all the way to the ending semicolon).
2739
+
2740
+ (If we're in a context that doesn't allow properties,
2741
+ we just throw away the rule
2742
+ if it looks like a custom property.
2743
+ This ensures that <code> --foo:hover { color: blue; }</code>
2744
+ is consistently invalid everywhere,
2745
+ without potentially consuming a ton of a stylesheet
2746
+ looking for the non-existent ending semicolon.)
2723
2747
</details>
2724
2748
2725
2749
Otherwise, [=consume a block=] from |input|,
0 commit comments