Open cdoublev opened 3 weeks ago
Somewhat related... Sometimes specs:
'<'
, <type-name>
, and '>'
<complex-selector-unit>
s if the <combinator>
between them is omittedBut it is not explicitly required after using
in using ( <dependency-list> )
. Obviously there would be a function if the whitespace was omitted, so this may not be worth clarifying. (Please tell me if I should open a separate issue.)
An omitted whitespace between two symbols, eg. <foo><bar>
, does not mean that a whitespace in the input is disallowed. My point is that if whitespaces were defined to be disallowed between an expression defining a function's name and (
, a syntax like <function-name>(<declaration-value>#)
for <dashed-function>
would be unambiguous.
Fwiw, I think this would be confusing and error-prone. A simpler solution is to rewrite with using <dependency-block>
.
Also note that disallowing a whitespace before a multiplier or '>'
, or after '<'
, sets a precedent whereas <foo> +
, while a bit confusing, is unambiguous to parse since multipliers are not allowed to appear unquoted in a value definition.
In my humble experience, spec authors often omit whitespace in various cases:
a| b
<a><b>
[a b ]
fn( a b)
They can all be parsed fine. I expect CSS authors to also omit whitespaces. This may be relaxed later, but perhaps they would appreciate some forgiving syntax. I think functions are the only ambiguous case.
Re: your whitespace comment, there's a bit more, too. Here's the syntax, currently:
<@function> = @function <<function-name>> [ ( <<parameter-list>> ) ]?
[ using ( <<dependency-list>> ) ]?
[ returns <<type>> ]?
{
<<declaration-rule-list>>
}
In addition to the using
detail (using ()
is allowed, using()
is illegal), the main parameters are also separate and optional, so @function --foo ()
is allowed, but @function --foo()
is illegal.
This seems odd; in JS, function foo() {...}
is, I think, the most common syntactic form (even tho function foo () {...}
is allowed in JS, too). I think we should probably at minimum switch to that; possibly we can allow both forms, if useful. This is a novel syntactic form, so even tho it's kinda unprecedented, that might still be acceptable.
@andruud , did you intend to write both of these locations with that whitespace, or was it unintended?
@cdoublev Thanks for reviewing this spec.
--*() = --*( <declaration-value># )
Yeah, I had no idea how to express the thing that needed expressing here. This was inspired by --* from css-variables-1. <dashed-function> = --*( <declaration-value># )
looks better.
What does it mean to mark it informative
, and how do I do that?
@andruud , did you intend to write both of these locations with that whitespace, or was it unintended?
Not exactly intentional. I based this on Miriam's explainer, and then forgot to think about whitespace while copying that grammar.
I agree that @function --foo()
should work. And probably it should be the only valid form?
Not sure if that means we should require using(
as well. Although really I'm hoping we can find an alternatively way to represent the dependencies which avoids the issue.
Tab already marked it as non-normative with the informative
class. Now w3c/reffy
no longer extracts it from the spec.
If I am not mistaken, <dashed-function>
will never be included in other value definitions, like other substitution functions. So this issue may therefore be considered fixed.
But since it must be syntactically validated, it would be nice to define its syntax using a normative value definition.
Fwiw, I like Tab's idea. This requires disallowing function names like not
, and
, or
, right? This would fix #7016 by replacing <function-token> <any-value> <)-token>
with <ident> (<any-value>)
.
First, I think it should be
<dashed-function> = --*( <declaration-value># )
.Second, the CSS Value definition syntax does not allow using
*
as a wildcard in a function's name.Solutions I am thinking of:
informative
<function-name> <declaration-value># ')'
I prefer solution 1 because the syntax of solution 2 represents a list of tokens, whereas productions always represent a list of component values, because all entry points of the CSS parser consume component values from the input list of tokens: you do not match the input against
<function-name>
, then<declaration-value>#
, then<)-token>
, but against a function component value. Related: #7016.