@@ -27,18 +27,20 @@ urlPrefix: https://html.spec.whatwg.org/multipage/scripting.html; type: dfn;
2727 text: scratch bitmap
2828 text: set bitmap dimensions
2929urlPrefix: http://www.ecma-international.org/ecma-262/6.0/#sec-; type: dfn;
30+ text: constructor
3031 text: Construct
3132 text: IsArray
3233 text: IsCallable
3334 text: IsConstructor
3435 text: HasProperty
3536 url: get-o-p; text: Get
37+ url: terms-and-definitions-function; text: function
3638</pre>
3739
3840Introduction {#intro}
3941=====================
4042
41- The paint stage of CSS is responsible for painting the background, content and highlight of an
43+ The paint stage of CSS is responsible for painting the background, content and highlight of a
4244box based on that box's geometry (as generated by the layout stage) and computed style.
4345
4446This specification describes an API which allows developers to paint a part of an box in
@@ -113,11 +115,25 @@ interface PaintWorkletGlobalScope : WorkletGlobalScope {
113115 </pre>
114116</div>
115117
118+ Concepts {#concepts}
119+ ====================
120+
121+ A <dfn>paint image definition</dfn> describes an author defined <<image>> which can be referenced by
122+ the <<paint()>> function. It consists of:
123+
124+ - A <dfn>paint image name</dfn>
125+
126+ - A <dfn>class constructor</dfn> which is the class <a>constructor</a>
127+
128+ - A <dfn>paint function</dfn> which is the paint <a>function</a> callback
129+
130+ - A <dfn>class constructor valid flag</dfn>
131+
116132Registering Custom Paint {#registering-custom-paint}
117133====================================================
118134
119- The {{PaintWorkletGlobalScope}} has a <dfn>paint name to constructor map</dfn> . Initially this map
120- is empty; it is populated when {{registerPaint(name, paintCtor)}} is called.
135+ The {{PaintWorkletGlobalScope}} has a <dfn>paint name to paint image definition map</dfn> . Initially
136+ this map is empty; it is populated when {{registerPaint(name, paintCtor)}} is called.
121137
122138The {{PaintWorkletGlobalScope}} has a <dfn>paint name to instance map</dfn> . Initially this map is
123139empty; it is populated when <a>draw a paint image</a> is invoked by the user agent.
@@ -131,25 +147,56 @@ called, the user agent <em>must</em> run the following steps:
131147 1. If the |name| is not a valid <<ident>> , <a>throw</a> a <a>TypeError</a> and abort all these
132148 steps.
133149
134- 2. If the |name| exists as a key in the <a>paint name to constructor map</a> , <a>throw</a> a
135- <a>NotSupportedError</a> and abort all these steps.
150+ 2. If the |name| exists as a key in the <a>paint name to paint image definition map</a> ,
151+ <a>throw</a> a <a>NotSupportedError</a> and abort all these steps.
152+
153+ 3. Let |inputProperties| be the result of <a>Get</a> (O=|paintCtor|, P="inputProperties").
154+
155+ 4. If |inputProperties| is not undefined, and the result of <a>IsArray</a> (argument=
156+ |inputProperties|) is false, <a>throw</a> a <a>TypeError</a> and abort all these steps.
157+
158+ 1. Let |len| be the result of <a>ToLength</a> (<a>Get</a> (O=|inputProperties|, P="length")).
159+
160+ 2. Let |idx| be 0.
161+
162+ 3. Repeat while |idx| < |len|
163+
164+ 1. Let |item| be the result of <a>Get</a> (O=|inputProperties|, |idx|).
136165
137- 3. If the result of <a>IsConstructor</a> (argument=|paintCtor|) is false, <a>throw</a> a
166+ 2. If the result of <a>Type</a> (|item|) is not String, <a>throw</a> a <a>TypeError</a>
167+ and abort all these steps.
168+
169+ 3. TODO prefixed behaviour
170+
171+ If |inputProperties| is undefined, let |inputProperties| be a new empty array.
172+
173+ 5. If the result of <a>IsConstructor</a> (argument=|paintCtor|) is false, <a>throw</a> a
138174 <a>TypeError</a> and abort all these steps.
139175
140- 4 . Let |prototype| be the result of <a>Get</a> (O=|paintCtor|, P="prototype").
176+ 6 . Let |prototype| be the result of <a>Get</a> (O=|paintCtor|, P="prototype").
141177
142- 5. If the result of <a>IsCallable</a> (argument=<a>Get</a> (O=|prototype|, P="paint")) is false,
178+ 7. If the result of <a>Type</a> (argument=|prototype|) is not Object, <a>throw</a> a
179+ <a>TypeError</a> and abort all these steps.
180+
181+ 8. If the result of <a>IsCallable</a> (argument=<a>Get</a> (O=|prototype|, P="paint")) is false,
143182 <a>throw</a> a <a>TypeError</a> and abort all these steps.
144183
145- 6 . Let |inputProperties | be the result of <a>Get </a> (O=|paintCtor|, P="inputProperties").
184+ 9 . Let |definition | be a new <a>paint image definition </a> with:
146185
147- 7. If |inputProperties| is not undefined, and the result of <a>IsArray</a> (argument=
148- |inputProperties|) is false, <a>throw</a> a <a>TypeError</a> and abort all these steps.
186+ - <a>paint image name</a> being |name|
187+
188+ - <a>class constructor</a> being |constructor|
189+
190+ - <a>paint function</a> being |paint|
149191
150- 8. Add the key-value pair (|name| - |inputProperties|) to the <a>paint name to input properties
192+ - <a>class constructor valid flag</a> being true
193+
194+ 10. Add the key-value pair (|name| - |inputProperties|) to the <a>paint name to input properties
151195 map</a> of the associated <a>document</a> .
152196
197+ 11. Add the key-value pair (|name| - |definition|) to the <a>paint name to paint image
198+ definition map</a> of the associated <a>document</a> .
199+
153200Note: The list of CSS properties provided by the input properties getter can either be custom or
154201 native CSS properties.
155202
@@ -298,25 +345,34 @@ following steps:
298345 select or create. It may use a single {{PaintWorkletGlobalScope}} or multiple and
299346 randomly assign between them.
300347
301- 5. If no paint constructor exists on |workletGlobalScope|'s <a>paint name to constructor map</a>
302- with key |name|, the resulting image output will be an <a>invalid image</a> and the user
303- agent must abort all these steps.
348+ 5. Let |definition| be the result of looking up |name| on the |workletGlobalScope|'s <a>paint
349+ name to paint image definition map</a> .
350+
351+ If |definition| does not exist, let the image output be an <a>invalid image</a> and abort
352+ all these steps.
304353
305354 6. Let |paintInstance| be the result of looking up |name| on |workletGlobalScope|'s <a>paint
306355 name to instance map</a> . If |paintInstance| is null run the following substeps:
307- 1. Let |paintCtor| be the result of looking up |name| on <a>paint name to constructor
308- map</a> .
309356
310- 2. Let |paintInstance| be the result of <a>Construct</a> (|paintCtor|).
357+ 1. If the <a>class constructor valid flag</a> on |definition| is false, let the image output
358+ be an <a>invalid image</a> and abort all these steps.
359+
360+ 2. Let |paintCtor| be the <a>class constructor</a> on |definition|.
311361
312- 3. Add the key-value pair (|name| - |paintInstance|) to the <a>paint name to instance
362+ 3. Let |paintInstance| be the result of <a>Construct</a> (|paintCtor|).
363+
364+ If <a>Construct</a> throws an exception, set the |definition|'s <a>constructor valid
365+ flag</a> to false, let the image output be an <a>invalid image</a> and abort all these
366+ steps.
367+
368+ 4. Add the key-value pair (|name| - |paintInstance|) to the <a>paint name to instance
313369 map</a> of the |workletGlobalScope|.
314370
315371 7. Let |inputProperties| be the result of looking up |name| on the associated <a>document</a> 's
316372 <a>paint name to input properties map</a> .
317373
318- 8. Let |styleMap| be a new {{StylePropertyMap }} populated with <em> only</em> the <a>computed
319- value</a> 's for properties listed in |inputProperties|.
374+ 8. Let |styleMap| be a new {{StylePropertyMapReadOnly }} populated with <em> only</em> the
375+ <a>computed value</a> 's for properties listed in |inputProperties|.
320376
321377 9. Let |renderingContext| be the result of <a>create a PaintRenderingContext2D object</a> given:
322378 - "width" - The width given by |concreteObjectSize|.
@@ -340,7 +396,7 @@ following steps:
340396
341397 12. The image output is to be produced from the |renderingContext| given to the method.
342398
343- If an exception is <a>thrown</a> the resulting image output will be an <a>invalid image</a> .
399+ If an exception is <a>thrown</a> the let the image output be an <a>invalid image</a> .
344400
345401 13. Set the <a>paint valid flag</a> for the |paintFunction| to <a>paint-valid</a> .
346402
@@ -423,17 +479,22 @@ document.registerProperty({
423479registerPaint('circle' , class {
424480 static get inputProperties() { return ['--image'] ; }
425481 paint(ctx, geom, properties) {
426- // This relies on a TypedOM image object which doesn't exist yet.
427482 const img = properties.get('--image' );
428- if (img.loaded) {
429- // The image is loaded! Draw the image.
430- ctx.drawImage(img.data, 0, 0, geom.width, geom.height);
431- } else if (img.invalid) {
432- // The image is invalid (e.g. it didn't load), draw a sad face.
433- drawSadFace(ctx);
434- } else {
435- // The image is loading, draw some mountains.
436- drawMountains(ctx);
483+
484+ switch (img.state) {
485+ case 'ready' :
486+ // The image is loaded! Draw the image.
487+ ctx.drawImage(img, 0, 0, geom.width, geom.height);
488+ break;
489+ case 'pending' :
490+ // The image is loading, draw some mountains.
491+ drawMountains(ctx);
492+ break;
493+ case 'invalid' :
494+ default:
495+ // The image is invalid (e.g. it didn't load), draw a sad face.
496+ drawSadFace(ctx);
497+ break;
437498 }
438499 }
439500});
@@ -442,7 +503,7 @@ registerPaint('circle', class {
442503Example 3: Conic-gradient {#example-3}
443504--------------------------------------
444505
445- Issue: Add conic-gradient as a use case.
506+ Issue: Add conic-gradient as a use case once we have function arguments .
446507
447508Example 4: Different color based on geometry {#example-4}
448509---------------------------------------------------------
0 commit comments