-
Notifications
You must be signed in to change notification settings - Fork 757
Description
from https://lists.w3.org/Archives/Public/www-style/2013Apr/0040.html by @heycam
[All double-quoted strings in this email are to be interpreted as JS
strings.]
I think the spec needs to be clearer about when the assignment of a
string to CSSSupportsRule.conditionText should be successful and when
the assignment should be ignored. Currently the spec says:
If the given value matches the grammar of the appropriate condition
production for the given rule, replace the associated CSS condition
with the given value.
Is this matching done strictly according to the grammar, or should the
normal CSS parsing rules be applied? For example with:
supportsRule.conditionText = "(color: green";
the string does not strictly match the grammar, but if we think of it as
passing the string to the CSS parser, we could invoke the special EOF
handling behaviour that would imply the closing ")".
My interpretation of CSS.supports() is that it does invoke this
behaviour, since it talks about the string being "parsed and evaluated
as a supports_condition".
It might be strange if the conditionText attribute and CSS.supports()
parsed condition expressions differently.
Assuming that CSS parser EOF behaviour is meant to be invoked for
conditionText, then we have to be careful that if we serialize the rule
as a whole with CSSSupportsRule.cssText that you can then reparse the
string and get the same condition. If you do:
supportsRule.conditionText = "(color: green) /*";
then you don't want supportsRule.cssText to be:
"@supports (color: green) /* {\n}"
so you might need to require that the conditionText be augmented with
whatever characters are required to have it parse the same -- in this
case, by appending "*/".
You'd need to do similar things for unclosed strings, unclosed url
tokens, and for a trailing backslash that is not inside a string or url
token.
More difficult is what to do with a bad-string or bad-url token that is
bad because of a trailing backslash. For example:
supportsRule.conditionText = "(color: green) or (before: '\";
IIUC this should be the following sequence of tokens:
( ident "color" colon whitespace ident "green" ) whitespace ident "or" whitespace ( ident "before" colon whitespace bad-string
I don't think there's actually a way to preserve that exact sequence of
tokens in the cssText of the rule. The only way to create a bad-string
without creating another token after it is to use EOF.
What we could do is distinguish between the "parse error" cases and the
"valid because it's at the EOF" cases. An unclosed comment is a parse
error according to css-syntax, so doing
supportsRule.conditionText = "(color: green) /*";
would be ignored. But an unclosed string would be OK. (Maybe that is
already the intent of the spec text.)
So overall I think there are two sane options:
- Have CSS.supports() and CSSSupportsRule.conditionText require strict
matching against the grammar, and thus reject for example "(color: green".
- Have CSS.supports() and CSSSupportsRule.conditionText allow the usual
EOF handling, including closing strings, balancing brackets, etc. Any
parse error causes the condition expression to fail to parse, making
CSS.supports() return false and the assignment to conditionText be
ignored. The spec would require the conditionText assignment to be
augmented with any characters implied by the EOF that would result in it
parsing the same when in the context of the rule's cssText. I think
this involves first looking at the tokenizer's state to determine how to
properly finish the token:
double-quote-string add "\"" single-quote-string add "'" URL-double-quote add "\")" URL-single-quote add "')" URL-end add ")" URL-unquoted add ")"
and then to add as many ")"s as needed to balance supports_condition.
Also, and I'm not sure if this a problem, the first step of the
conditionText assignment says to strip white space from the string, and
that this can cause a change of meaning with:
supportsRule.conditionText = "(counter-increment: a\ ";
if we assume that we go with option 2 above. If we strip the white
space, this is a parse error, as we'll encounter "\" in the ident
state, switch to the data state since it's followed by EOF, then flag it
as a parse error. If we don't strip the white space, we'll have a valid
ident whose value is "a\".