[csswg-drafts] [css-conditional-5] Add ability to test for at-rule preludes (#6966)

tabatkins has just created a new issue for https://github.com/w3c/csswg-drafts:

== [css-conditional-5] Add ability to test for at-rule preludes ==
In #2463 we just resolved to add `at-rule(@foo)` and `at-rule(@foo; desc: value)` functions to @supports, to test for whether an at-rule is supported at all, and whether it supports a given `desc: value` declaration.

It was brought up in the call (and deferred for time) that we should be able to test for support of things in an at-rule's prelude as well, as that can sometimes be significant and potentially change over time. (Especially for at-rules that end in a semicolon instead of a block, as they're nothing *but* prelude.)

An important point brought up by @emilio (and supported with historical design context by @dbaron) is that part of the "no special-casing needed, It Just Works" feature of @supports is that we can use it to tell if something is dropped *as a whole* easily, but can't easily test whether some *part* of a construct is dropped (since that information is not currently signaled by the CSS parsers, and even if parsers are instrumented to flag a parse error, it's possible to miss spots and thus have @supports give an incorrect result).

In the case of preludes, this isn't a problem - they're either supported or invalidate the at-rule as a whole. Thus, adding detection support for them is possible. The question is just how precisely to invoke this. 

To avoid any special-casing at all, I suggest we *do* support passing an *entire* at-rule in the function, but we just test whether the at-rule as a whole is dropped or not. That is, `at-rule(@foo bar baz {...})` (or `at-rule(@foo bar baz)` for semicolon-ended rules) is allowed, and just detects whether the rule, when parsed, is dropped or not. We do the parsing as if it was the first content in a stylesheet, so `at-rule(@import "foo")` would return true.

We thus would have three parsing forms for the at-rule function:

1. Just the at-rule name, `at-rule(@foo)`, which returns whether this is a recognized at-rule name *at all*. (This doesn't invoke any parsing, but afaik all existing impls do keep up lists of all their recognized at-rules, so this should still be a no-special-case easy check without the possibility of drifting out of sync.)
2. An entire at-rule, `at-rule(@foo bar {baz: qux})`, which returns whether or not the at-rule as a whole, when parsed as the first and only content in a fresh stylesheet, is valid or dropped. If the at-rule is valid but drops some of its contents as invalid, such as an unknown descriptor, this will still return true.
3. An at-rule name accompanied by a descriptor declaration, `at-rule(@foo; desc: value)`, which returns whether the at-rule is recognized, and the given descriptor successfully parses as part of that at-rule. This should be testable by invoking existing parsing functions in a relatively generic fashion.

Some implications:
* The second form implies that any required descriptors have to be passed as well; `at-rule(@counter-style foo {})` will fail, because @counter-style requires the 'system' descriptors and either 'symbols' or 'additive-symbols', or else the whole rule is dropped.
* Also, naively the first and second forms collide grammar-wise; we tell them apart by always invoking the first form when the only non-WS contents of the function are a single at-keyword token.
* Should a trailing semicolon be allowed for the second form, when it's a semicolon-ended rule? It's not actually grammatically ambiguous with the third form (as the third requires a `desc:value` after it), but allowing it as a valid second-form invocation is a small wrinkle in parsers. I'm fine either way.

Please view or discuss this issue at https://github.com/w3c/csswg-drafts/issues/6966 using your GitHub account


-- 
Sent via github-notify-ml as configured in https://github.com/w3c/github-notify-ml-config

Received on Wednesday, 19 January 2022 18:27:30 UTC