-
Notifications
You must be signed in to change notification settings - Fork 661
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[css-syntax] Dashed-ident rules and error recovery #9336
Comments
Yup, this looks like just a mistake; I didn't mean for this hungry behavior to apply at the top-level. The intention of the hungry behavior is that it's already very difficult for custom properties to actually ever be invalid, so an "ambiguous rule" like But since custom props (or any props at all) can't exist on the top level of a stylesheet, there's no reason to worry about it. That is, So yeah, I propose that we do indeed guard against this. Specifically, in https://drafts.csswg.org/css-syntax/#consume-a-qualified-rule, in the This maintains the constant I want to maintain about where Agenda+ to confirm this with the WG. |
The CSS Working Group just discussed
The full IRC log of that discussion<TabAtkins> scribe+ TabAtkins<fantasai> TabAtkins: We resolved the fundamental grammar ambiguity between properties and declarations in nesting by deciding we would start by parsing as a declaration, and if it was invalid, go backand parse as a rule <fantasai> TabAtkins: recently tweaked to make more efficient <fantasai> TabAtkins: works pretty fine, but a wrinkle about custom properties <fantasai> TabAtkins: custom properties are very hard to make invalid <fantasai> TabAtkins: anything you write in a custom property will always be valid <fantasai> TabAtkins: so if you write --foo: [anything] that's a valid custom property <fantasai> TabAtkins: in order to avoid a behavior change for authors <fantasai> TabAtkins: if it looks like custom property, we treat it as a custom property during rule parsing <fantasai> TabAtkins: if you have 'display:hover', can quickly tell it's not a valid display <fantasai> TabAtkins: issue is that I didn't condition that check on being in a nested context <fantasai> TabAtkins: so as written, if you have a top-level style rule starting with --foo:whatever, it will try to consume a custom property declaration <fantasai> TabAtkins: it will eat everything up to the next top-level semicolon <fantasai> TabAtkins: lose the rest of the stylesheet from that point forward <fantasai> TabAtkins: I didn't think about this case, so proposal is to condition that check for "does this look like a custom property" to check whether in a nested context or not <fantasai> TabAtkins: if not nested context, we let it parse as a rule <fantasai> TabAtkins: but will do rule-parsing and end at next curly brace <fantasai> TabAtkins: this means that behavior-wise, this brings us back to how this case would have acted before my recent change to allow nesting to work <fantasai> TabAtkins: i.e. if you write a style rule --foo:whatever, it will only eat one style rule <fantasai> TabAtkins: I've checked this with Emilio during TPAC <astearns> q+ <astearns> ack fantasai <TabAtkins> fantasai: so what this means is that parsing behavior for style rules with a custom ident is different in top level vs nested <TabAtkins> fantasai: so if we have custom idents at beginnign of selector, will we be int rouble? <fantasai> TabAtkins: In both cases, if you try to write a rule with --foo:something, you would end up with something invalid <fantasai> TabAtkins: if it wasn't a valid custom property, you won't get a rule <fantasai> TabAtkins: The difference in parsing behavior is, if it's nested it'll consume as a declaration <fantasai> TabAtkins: whereas at top level it'll consume as a rule <fantasai> TabAtkins: in both cases, can't be a rule <fantasai> TabAtkins: we took as an implicit restriction on ourselves that if you have a style rule that wants to start with a dashed type selector, you have to spell it differently e.g. wrap in :is() <fantasai> TabAtkins: considered that to be fine because that's not a valid custom element name in HTML or XML (I think?) <fantasai> TabAtkins: very difficult to have a type selector that looks like that, can work around <fantasai> TabAtkins: error recovery is different in both cases, but either way the rule is invalid and won't work <fantasai> TabAtkins: and I think that's enough consistency <fantasai> ok, sgtm <fantasai> astearns: My qeustion is, defining it as working normally in nested context vs defining it as doing different thing in top-level <fantasai> astearns: would that be exactly the same? I'm worried nested context are about CSS nesting, not a regular declaration block... <fantasai> TabAtkins: the switch used in Syntax is "is it mixed with declarations" <fantasai> astearns: ok, and nested context is that type of context <fantasai> TabAtkins: yeah <fantasai> TabAtkins: flag is called "nested" but in practice used for mixed cases <fantasai> astearns: might want a different term <fantasai> TabAtkins: I'll look into it <fantasai> ACTION: TabAtkins to look into using a more generic term than 'nested' for the flag for mixed declaration+rule contexts <fantasai> TabAtkins: Proposal is, at top level, if you see a rule that looks like a custom property, we consume as a rule and throw it away as invalid <fantasai> RESOLVED: at top level, if you see a rule that looks like a custom property, we consume as a rule and throw it away as invalid |
…lookalike behavior if you're not in a context that allows properties in the first place. #9336
I do not see in which nested context So I do not understand why checking (I'm trying to guess from here, if that helps explain to me what I am missing.) From the note titled What's this check for? below the consume a qualified rule algo (and also in the previous comment):
Does it mean that this is consistently an invalid rule everywhere?
Do you mean that 2.2 Error Handling says that the grammar must be checked after each construct is parsed, but it is non-normative and it seems inefficient to retry parsing a declaration as a rule because its value was invalid according to the grammar. Maybe I misunderstood #8834 (comment), ie. what it means to check that a declaration or rule is valid in the context (which I think is not required anymore, btw). |
In a nested context, a At the top level, properties aren't allowed; if you've written
Correct. That's step 9 of "consume a declaration"
Sure, it would be inefficient. But you don't actually have to try, you just have to act identically to an impl that did try. The vast majority of the time you can just quit immediately, or at least very quickly. See the impl notes at the end of "consume a block's contents", which offers guidance about this exact topic. |
Closing the loop on this action: Most of the "consume" algorithms use the "nested" flag. In almost all cases it really does mean "am I nested in a {} block", because it's used to determine whether a The only exception is in "consume a qualified rule": in addition to the above-described usage, it's also used to decide how to handle a custom property. In theory this is referencing the "mixed declarations and rules, or just rules" decision, but in practice it's to make a custom property showing up at the top level of a stylesheet work better (so it doesn't consume the entire rest of the stylesheet), so it's actually caring about nesting too. So, I'm concluding that "nested" is still an appropriate name for this flag, and this action needs no further change. |
Enlightening, thanks. |
https://bugs.webkit.org/show_bug.cgi?id=276302 rdar://131274469 Reviewed by NOBODY (OOPS!). w3c/csswg-drafts#9336 (comment) * LayoutTests/imported/w3c/web-platform-tests/css/css-syntax/custom-property-rule-ambiguity-expected.txt: * LayoutTests/imported/w3c/web-platform-tests/css/css-syntax/custom-property-rule-ambiguity.html: * Source/WebCore/css/parser/CSSParserImpl.cpp: (WebCore::CSSParserImpl::consumeQualifiedRule):
After a recent edit in relation to relaxed nesting, css-syntax now says this:
Unless I'm mistaken, this means that encountering this situation top-level means we'll treat the entire rest of the stylesheet as a "bad declaration".
That is probably a bit extreme, and makes the change a bit hard to ship, since it could affects existing sites (drastically).
Perhaps we can limit the behavior to when
nested
istrue
? Or something else? @tabatkinsThe text was updated successfully, but these errors were encountered: