@@ -37,6 +37,7 @@ Repository: w3c/css-houdini-drafts
37
37
<pre class='link-defaults'>
38
38
spec:css-transforms-1; type:type; text:<transform-function>
39
39
spec:cssom-1; type:interface; text:CSS
40
+ spec:css-color-4; type:property; text:color
40
41
</pre>
41
42
42
43
Introduction {#intro}
@@ -74,6 +75,9 @@ partial interface CSS {
74
75
};
75
76
</pre>
76
77
78
+ Additional, the {{Window}} object gains a new <dfn attribute for=Window>\[[registeredPropertySet]]</dfn> private slot,
79
+ which is a set of records that describe registered custom properties.
80
+
77
81
The {{PropertyDescriptor}} dictionary {#the-propertydescriptor-dictionary}
78
82
--------------------------------------------------------------------------
79
83
@@ -93,97 +97,185 @@ following members:
93
97
: <dfn dict-member for=PropertyDescriptor>initialValue</dfn>
94
98
:: The initial value of this custom property.
95
99
96
- The {{registerProperty()}} function {#the-registerproperty-function}
97
- --------------------------------------------------------------------
100
+ The {{registerProperty()}} and {{unregisterProperty()}} functions {#the-registerproperty-function}
101
+ --------------------------------------------------------------------------------------------------
98
102
99
103
The <dfn method for=CSS>registerProperty(PropertyDescriptor descriptor)</dfn> method
100
- registers a custom property according the to configuration options provided in
104
+ registers a custom property according to the configuration options provided in
101
105
<code> descriptor</code> .
106
+ When it is called,
107
+ it executes the <a>register a custom property</a> algorithm,
108
+ passing the options in its <code> descriptor</code> argument
109
+ as arguments of the same names.
110
+
111
+ <div algorithm>
112
+ To <dfn>register a custom property</dfn>
113
+ with |name| being a string,
114
+ and optionally
115
+ |syntax| being a string,
116
+ |inherits| being a boolean,
117
+ and |initialValue| being a string,
118
+ execute these steps:
119
+
120
+ 1. Attempt to parse |name|
121
+ as a <<custom-property-name>> .
122
+ If this fails,
123
+ <a>throw</a> a {{SyntaxError}}
124
+ and exit this algorithm.
125
+
126
+ Otherwise,
127
+ let |parsed name| be the parsed value.
128
+
129
+ If the window's {{[[registeredPropertySet]]}} slot
130
+ already contains an entry with |parsed name| as its property name
131
+ (compared codepoint-wise),
132
+ <a>throw</a> an {{InvalidModificationError}}
133
+ and exit this algorithm.
134
+
135
+ 2. If |syntax| is not present,
136
+ or is equal to <code> "*"</code> (U+002A ASTERISK),
137
+ let |parsed syntax| be undefined,
138
+ and skip to the next step of this algorithm.
139
+
140
+ Otherwise, attempt to parse |syntax|
141
+ according to the rules in [[#supported-syntax-strings]] .
142
+ If it does not parse successfully,
143
+ <a>throw</a> a {{SyntaxError}} .
144
+ Otherwise,
145
+ let |parsed syntax| be the parsed syntax.
146
+
147
+ Note: For example, a valid syntax string is something like <code> "<length>"</code> ,
148
+ or <code> "<number>+"</code> ;
149
+ the allowed syntax is a subset of [[css-values-3#value-defs]] .
150
+ Future levels of this specification are expected to expand the complexity of allowed syntax strings,
151
+ allowing custom properties that more closely resemble the full breadth of what CSS properties allow.
152
+
153
+ 3. If |parsed syntax| is undefined,
154
+ and |initialValue| is not present,
155
+ let |parsed initial value| be empty.
156
+ This must be treated identically to the "default" initial value of custom properties,
157
+ as defined in [[!css-variables]] .
158
+ Skip to the next step of this algorithm.
159
+
160
+ Otherwise,
161
+ if |parsed syntax| is undefined,
162
+ parse |initialValue| as a <<declaration-value>> .
163
+ If this fails,
164
+ <a>throw</a> a {{SyntaxError}}
165
+ and exit this algorithm.
166
+ Otherwise,
167
+ let |parsed initial value| be the parsed result.
168
+ Skip to the next step of this algorithm.
169
+
170
+ Otherwise, if |initialValue| is not present,
171
+ <a>throw</a> a {{SyntaxError}}
172
+ and exit this algorithm.
173
+
174
+ Otherwise,
175
+ parse {{PropertyDescriptor/initialValue}}
176
+ according to |parsed syntax|.
177
+ If this fails,
178
+ <a>throw</a> a {{SyntaxError}}
179
+ and exit this algorithm.
180
+
181
+ Otherwise, let |parsed initial value| be the parsed result.
182
+ If |parsed initial value| is not <a>computationally idempotent</a> ,
183
+ <a>throw</a> a {{SyntaxError}}
184
+ and exit this algorithm.
185
+
186
+ 4. If |inherits| is present,
187
+ set |inherit flag| to its value.
188
+ Otherwise, set |inherit flag| to false.
189
+
190
+ 5. Let |registered property| be a record
191
+ with a property name of |parsed name|,
192
+ a syntax of |parsed syntax|,
193
+ an initial value of |parsed initial value|,
194
+ and an inherit flag of |inherit flag|.
195
+ Add |registered property|
196
+ to the window's {{[[registeredPropertySet]]}} .
197
+ </div>
102
198
103
- Attempting to register properties with a {{PropertyDescriptor/name}} that doesn't
104
- correspond to the <<custom-property-name>> production must cause {{registerProperty()}}
105
- to throw a {{SyntaxError}} .
106
-
107
- The list of types supported in the {{PropertyDescriptor/syntax}} member are listed
108
- in <a section href="#supported-syntax-strings"></a> . Currently, only simple
109
- type references are supported. Attempting to register properties with a
110
- {{PropertyDescriptor/syntax}} that is not supported must cause {{registerProperty()}}
111
- to throw a {{SyntaxError}} .
112
-
113
- Note: for example, the syntax string could be "<length>" or "<number>".
114
-
115
- Note: in future levels we anticipate supporting more sophisticated parse strings, e.g.
116
- "<length> || <number>"
117
-
118
- Attempting to call {{registerProperty()}} with an {{PropertyDescriptor/initialValue}} that is
119
- not parseable using the provided {{PropertyDescriptor/syntax}} must cause it to
120
- throw a {{SyntaxError}} . If no {{PropertyDescriptor/initialValue}} is provided and the
121
- {{PropertyDescriptor/syntax}} is '*' , then a special initial value is used. This initial
122
- value must be considered parseable by {{registerProperty()}} but invalid at computed
123
- value time. Initial values that are not computationally idempotent must also cause
124
- {{registerProperty()}} to throw a {{SyntaxError}} .
199
+ A property value is <dfn export>computationally idempotent</dfn>
200
+ if it can be converted into a computed value
201
+ using only the value of the property on the element,
202
+ and "global" information that cannot be changed by CSS.
125
203
126
204
<div class='example'>
127
- For example, "3cm" is a computationally idempotent length, and hence valid as an initial value.
128
- However, "3em" is not (depending on the environment, 3em could compute to
129
- multiple different values). Additionally, "var(--foo)" is not computationally idempotent.
205
+ For example, ''5px'' is <a>computationally idempotent</a> ,
206
+ as converting it into a computed value doesn't change it at all.
207
+ Similarly, ''1in'' is <a>computationally idempotent</a> ,
208
+ as converting it into a computed value
209
+ relies only on the "global knowledge" that ''1in'' is ''96px'' ,
210
+ which can't be altered or adjusted by anything in CSS.
211
+
212
+ On the other hand, ''3em'' is not <a>computationally idempotent</a> ,
213
+ because it relies on the value of 'font-size' on the element
214
+ (or the element's parent).
215
+ Neither is a value with a ''var()'' function,
216
+ because it relies on the value of a <a>custom property</a> .
130
217
</div>
131
218
132
- Issue(282): define computational idempotency.
133
-
134
- Issue(121): Is computational idempotency the right thing to do here? We could also just
135
- resolve any relative values once (against all the other initial values) and use
136
- that. OR! We could allow specified values and just fix our engines...
137
-
138
- When a custom property is registered with a given type, the process via which specified
139
- values for that property are turned into computed values is defined
140
- fully by the type selected, as described in
141
- <a section href="#calculation-of-computed-values"></a> .
142
-
143
- If {{registerProperty()}} is called with a descriptor name that matches an already registered property,
144
- then an {{InvalidModificationError}} is thrown and the re-registration fails.
219
+ When a custom property is registered with a given type,
220
+ the process via which specified values for that property are turned into computed values
221
+ is defined fully by the type selected,
222
+ as described in [[#calculation-of-computed-values]] .
145
223
146
224
Properties can be unregistered using
147
225
<dfn method for=CSS>unregisterProperty(DOMString name)</dfn> .
148
- If this function is called with a name that doesn't match an existing property
149
- then a {{NotFoundError}} is thrown.
226
+ When it is called,
227
+ it executes the <a>unregister a custom property</a> algorithm,
228
+ with a <code> name</code> set to its sole argument.
150
229
151
- Successful calls to both {{registerProperty()}} and {{unregisterProperty()}}
152
- change the set of registered properties. When the set of registered properties
153
- changes, previously syntactically invalid property values can become valid and vice versa.
154
- This can change the set of <a>declared values</a> which requires the <a>cascade</a> to
155
- be recomputed.
230
+ <div algorithm>
231
+ To <dfn>unregister a custom property</dfn> with the name |name|:
156
232
157
- <div class='example'>
158
- By default, all custom property declarations that can be parsed as a sequence of tokens
159
- are valid. Hence, the result of this stylesheet:
160
-
161
- <pre class='lang-css'>
162
- .thing {
163
- --my-color: green;
164
- --my-color: url("not-a-color");
165
- color: var(--my-color);
166
- }
167
- </pre>
168
-
169
- is to set the color property of elements of class "thing" to "inherit".
170
- The second --my-color declaration overrides the first at parse time (both are valid),
171
- and the var reference in the color property is found to be invalid at computation time
172
- (because <code> url("not-a-color")</code> is not a color). At computation time the only
173
- available fallback is the default value, which in the case of color is "inherit".
233
+ 1. If the window's {{[[registeredPropertySet]]}}
234
+ contains a record with a property name matching |name|
235
+ (compared codepoint-wise),
236
+ remove the record from the set.
174
237
175
- if we call:
176
-
177
- <pre class='lang-javascript'>
178
- registerProperty({
179
- name: "--my-color",
180
- syntax: "<color>"
181
- });
182
- </pre>
238
+ Otherwise,
239
+ <a>throw</a> a {{NotFoundError}} .
240
+ </div>
183
241
184
- then the second --my-color declaration becomes syntactically invalid, which means that
185
- the cascade uses the first declaration. The color therefore switches to green.
242
+ When the window's {{[[registeredPropertySet]]}} changes,
243
+ previously syntactically invalid property values can become valid and vice versa.
244
+ This can change the set of <a>declared values</a> which requires the <a>cascade</a> to be recomputed.
186
245
246
+ <div class='example'>
247
+ By default, all custom property declarations that can be parsed as a sequence of tokens
248
+ are valid. Hence, the result of this stylesheet:
249
+
250
+ <pre class='lang-css'>
251
+ .thing {
252
+ --my-color: green;
253
+ --my-color: url("not-a-color");
254
+ color: var(--my-color);
255
+ }
256
+ </pre>
257
+
258
+ is to set the 'color' property of elements of class "thing" to ''inherit'' .
259
+ The second '--my-color' declaration overrides the first at parse time (both are valid),
260
+ and the ''var()'' reference in the 'color' property is found to be <a spec=css-variables>invalid at computed-value time</a>
261
+ (because ''url("not-a-color")'' is not a color).
262
+ At computed-value time the only available fallback is the default value,
263
+ which in the case of color is ''inherit'' .
264
+
265
+ if we call:
266
+
267
+ <pre class='lang-javascript'>
268
+ CSS.registerProperty({
269
+ name: "--my-color",
270
+ syntax: "<color>",
271
+ initialValue: "black"
272
+ });
273
+ </pre>
274
+
275
+ then the second '--my-color' declaration becomes syntactically invalid at parse time,
276
+ and is ignored.
277
+ The first '--my-color' is the only valid declaration left for the property,
278
+ so 'color' is set to the value ''green'' .
187
279
</div>
188
280
189
281
Supported syntax strings {#supported-syntax-strings}
0 commit comments