@@ -13,197 +13,7 @@ Abstract: for parsing arbitrary CSS-like languages into a mildly typed represent
1313Introduction {#intro}
1414=====================
1515
16- Common data-interchange / parsing formats are very valuable
17- for reducing the learning curve of new languages,
18- as users get to lean on their existing knowledge of the format when authoring
19- and only have to newly learn the specifics of the language.
20- This is why generic parsing formats like XML or JSON have become so popular.
21-
22- The CSS language could benefit from this same treatment;
23- a number of languages and tools rely on CSS-like syntax to express themselves,
24- but they usually rely on ad-hoc parsing
25- (often regex-based)
26- which can be relatively fragile,
27- and might break with CSS practices in interesting syntax corner cases.
28- Similarly, CSS syntax is increasingly used in places like attribute values
29- (such as the <{img/sizes}> attribute,
30- or most of the SVG presentation attributes),
31- and custom elements wanting to do the same thing
32- similarly have to rely on ad-hoc parsing right now.
33-
34- To help with these sorts of cases,
35- this spec exposes the [[!css-syntax-3]] parsing algorithms,
36- and represents their results in a mildly-typed representation,
37- simpler and more abstract than what [[css-typed-om-1]] does for CSS properties.
38-
39- Parsing API {#parsing-api}
40- ==========================
41-
42- <pre class=idl>
43- partial interface CSS {
44- Promise<sequence<CSSParserRule>> parseStylesheet(DOMString css, optional CSSParserOptions options);
45- Promise<sequence<CSSParserRule>> parseRuleList(DOMString css, optional CSSParserOptions options);
46- Promise<CSSParserRule> parseRule(DOMString css, optional CSSParserOptions options);
47- Promise<sequence<CSSParserRule>> parseDeclarationList(DOMString css, optional CSSParserOptions options);
48- CSSParserDeclaration parseDeclaration(DOMString css, optional CSSParserOptions options);
49- CSSParserValue parseValue(DOMString css);
50- sequence<CSSParserValue> parseValueList(DOMString css);
51- sequence<sequence<CSSParserValue>> parseCommaValueList(DOMString css);
52- };
53-
54- dictionary CSSParserOptions {
55- object atRules;
56- /* dict of at-rule name => at-rule type
57- (contains decls or contains qualified rules) */
58- };
59- </pre>
60-
61- Issue: {{parseCommaValueList()}} is in Syntax, and thus here,
62- because it's actually a very common operation.
63- It's trivial to do yourself
64- (just call {{parseValueList()}} and then split into an array on top-level commas),
65- but comma-separated lists are so common
66- that it was worthwhile to improve spec ergonomics
67- by providing a shortcut for that functionality.
68- Is it worth it to provide this to JS as well?
69-
70- Issue: Do we handle comments?
71- Currently I don't;
72- Syntax by default just drops comments,
73- but allows an impl to preserve information about them if they want.
74- Maybe add an option to preserve comments?
75- If so, they can appear *anywhere*,
76- in any API that returns a sequence.
77-
78- Issue: What do we do if an unknown at-rule
79- (not appearing in the {{atRules}} option)
80- shows up in the results?
81- Default to decls or rules?
82- Or treat it more simply as just a token sequence?
83-
84- Issue: Parsing stylesheets/rule lists should definitely be async,
85- because stylesheets can be quite large.
86- Parsing individual properties/value lists should definitely be sync,
87- because they're small and it would be really annoying.
88- Parsing a single rule, tho, is unclear--
89- is it large enough to be worth making async,
90- or is it too annoying to be worth it?
91-
92- Parser Values {#parser-values}
93- ==============================
94-
95- <pre class=idl>
96- interface CSSParserRule {
97- /* Just a superclass. */
98- };
99-
100- [Constructor(DOMString name, sequence<CSSParserValue> prelude, optional sequence<CSSParserRule>? body)]
101- interface CSSParserAtRule : CSSParserRule {
102- readonly attribute DOMString name;
103- readonly attribute FrozenArray<CSSParserValue> prelude;
104- readonly attribute FrozenArray<CSSParserRule>? body;
105- /* nullable to handle at-statements */
106- stringifier;
107- };
108-
109- [Constructor(sequence<CSSParserValue> prelude, optional sequence<CSSParserRule>? body)]
110- interface CSSParserQualifiedRule : CSSParserRule {
111- readonly attribute FrozenArray<CSSParserValue> prelude;
112- readonly attribute FrozenArray<CSSParserRule> body;
113- stringifier;
114- };
115-
116- [Constructor(DOMString name, optional sequence<CSSParserRule> body)]
117- interface CSSParserDeclaration : CSSParserRule {
118- readonly attribute DOMString name;
119- readonly attribute FrozenArray<CSSParserValue> body;
120- stringifier;
121- };
122-
123- interface CSSParserValue {
124- /* Just a superclass. */
125- };
126-
127- [Constructor(DOMString name, sequence<CSSParserValue> body)]
128- interface CSSParserBlock : CSSParserValue {
129- readonly attribute DOMString name; /* "[]", "{}", or "()" */
130- readonly attribute FrozenArray<CSSParserValue> body;
131- stringifier;
132- };
133-
134- [Constructor(DOMString name, sequence<sequence<CSSParserValue>> args)]
135- interface CSSParserFunction : CSSParserValue {
136- readonly attribute DOMString name;
137- readonly attribute FrozenArray<FrozenArray<CSSParserValue>> args;
138- stringifier;
139- };
140-
141- [Constructor(DOMString value)]
142- interface CSSParserIdent : CSSParserValue {
143- readonly attribute DOMString value;
144- stringifier;
145- };
146-
147- [Constructor(double value),
148- Constructor(DOMString css)]
149- interface CSSParserNumber : CSSParserValue {
150- readonly attribute double value;
151- stringifier;
152- };
153-
154- [Constructor(double value),
155- Constructor(DOMString css)]
156- interface CSSParserPercentage : CSSParserValue {
157- readonly attribute double value;
158- stringifier;
159- };
160-
161- [Constructor(double value, DOMString type),
162- Constructor(DOMString css)]
163- interface CSSParserDimension : CSSParserValue {
164- readonly attribute double value;
165- readonly attribute DOMString type;
166- stringifier;
167- };
168-
169- [Constructor(DOMString value)]
170- interface CSSParserAtKeyword : CSSParserValue {
171- readonly attribute DOMString value;
172- stringifier;
173- };
174-
175- [Constructor(DOMString value)]
176- interface CSSParserHash : CSSParserValue {
177- readonly attribute DOMString value;
178- /* expose an "is ident" boolean? */
179- stringifier;
180- };
181-
182- [Constructor(DOMString value)]
183- interface CSSParserString : CSSParserValue {
184- readonly attribute DOMString value;
185- stringifier;
186- };
187-
188- [Constructor(DOMString value)]
189- interface CSSParserChar : CSSParserValue {
190- readonly attribute DOMString value;
191- /* for all delims, whitespace, and the
192- weird Selectors-based tokens
193- (split up into the individual chars) */
194- stringifier;
195- };
196- </pre>
197-
198- Issue: Some of the CSSParserValue subtypes correspond closely to Typed OM types;
199- in particular, {{CSSParserIdent}} and {{CSSKeywordValue}} are basically the same thing,
200- as are {{CSSParserNumber}} and {{CSSNumberValue}} .
201- Is it worthwhile to transplant this hierarchy underneath the {{CSSStyleValue}} superclass,
202- and reuse the ones that are reasonable?
203-
204- Issue: Trying to be as useful as possible,
205- without exposing so many details that we're unable to change tokenization in the future.
206- In particular, whitespace, delims, and the weird Selectors tokens
207- all get serialized as individual {{CSSParserChar}} "tokens",
208- which should allow us to change the set of Selectors tokens in the future safely.
209- Am I succeeding at this goal?
16+ This spec is intentionally left blank,
17+ as it is currently being developed in the WICG
18+ at <a href="https://github.com/wicg/css-parser-api/">https://github.com/wicg/css-parser-api/</a>
19+ (<a href="https://wicg.github.io/CSS-Parser-API/">live spec</a> ).
0 commit comments