Skip to content

Commit 66d00e0

Browse files
committed
[css-layout-api] Define algorithm to register a layout.
1 parent 6c58a23 commit 66d00e0

File tree

1 file changed

+143
-22
lines changed

1 file changed

+143
-22
lines changed

css-layout-api/Overview.bs

Lines changed: 143 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,28 @@ spec:css-display-3; type:value; for:display; text:none
2121
spec:dom; type:dfn; text:element
2222
</pre>
2323

24+
<pre class="anchors">
25+
urlPrefix: https://heycam.github.io/webidl/; type: dfn;
26+
text: NotSupportedError
27+
urlPrefix: #dfn-;
28+
text: callback this value
29+
text: exception
30+
text: throw
31+
url: throw; text: thrown
32+
url: es-invoking-callback-functions; text: Invoke
33+
urlPrefix: https://tc39.github.io/ecma262/#sec-; type: dfn;
34+
text: constructor
35+
text: Construct
36+
text: IsArray
37+
text: IsCallable
38+
text: IsConstructor
39+
text: HasProperty
40+
url: get-o-p; text: Get
41+
url: terms-and-definitions-function; text: function
42+
urlPrefix: native-error-types-used-in-this-standard-
43+
text: TypeError
44+
</pre>
45+
2446
Introduction {#intro}
2547
=====================
2648

@@ -494,10 +516,10 @@ name to child input properties map</dfn>. Initialy these maps are empty and are
494516
Each <a>box</a> has an associated <dfn>layout valid flag</dfn>. It may be either
495517
<dfn>layout-valid</dfn> or <dfn>layout-invalid</dfn>. It is initially set to <a>layout-invalid</a>.
496518

497-
When the computed style for a |box| changes, the user agent must run the following steps:
519+
When the <a>computed style</a> for a |box| changes, the user agent must run the following steps:
498520
1. Let |layoutFunction| be the <<layout()>> or <<inline-layout()>> function of the 'display'
499-
property on the computed style if it exists. If it is a different type of value (e.g.
500-
''grid'') then abort all these steps.
521+
property on the <a>computed style</a> for the |box| if it exists. If it is a different type
522+
of value (e.g. ''grid'') then abort all these steps.
501523

502524
2. Let |name| be the first argument of the |layoutFunction|.
503525

@@ -538,7 +560,7 @@ interface FragmentRequestToken {
538560
</pre>
539561

540562
The layout method on the author supplied layout class is a generator function instead of a regular
541-
javascript function. This is for user-agents to be able to support asyncronous and parallel layout
563+
javascript function. This is for user-agents to be able to support asynchronous and parallel layout
542564
engines.
543565

544566
When an author invokes the {{LayoutChild/doLayout()}} method on a {{LayoutChild}} the user-agent
@@ -602,33 +624,132 @@ class LayoutEngine {
602624

603625
TODO explain parallel layout + {{FragmentRequestToken}}, etc.
604626

605-
Registering A Layout {#registering-a-layout}
606-
============================================
627+
Layout Worklet {#layout-worklet}
628+
================================
629+
630+
The {{layoutWorklet}} attribute allows access to the {{Worklet}} responsible for all the classes
631+
which are related to layout.
632+
633+
The {{layoutWorklet}}'s <a>worklet global scope type</a> is {{LayoutWorkletGlobalScope}}.
634+
635+
<pre class='idl'>
636+
partial interface CSS {
637+
[SameObject] readonly attribute Worklet layoutWorklet;
638+
};
639+
</pre>
640+
641+
The {{LayoutWorkletGlobalScope}} is the global execution context of the {{layoutWorklet}}.
607642

608643
<pre class='idl'>
609-
partial interface LayoutWorkletGlobalScope {
644+
[Global=(Worklet,LayoutWorklet),Exposed=LayoutWorklet]
645+
interface LayoutWorkletGlobalScope : WorkletGlobalScope {
610646
void registerLayout(DOMString name, VoidFunction layoutCtor);
611647
};
612648
</pre>
613649

614-
The {{LayoutWorkletGlobalScope}} has a map of <b>name to layout constructor map</b>. Initially this
615-
map is empty; it is populated when {{registerLayout(name, layoutCtor)}} is called.
650+
Registering A Layout {#registering-layout}
651+
==========================================
652+
653+
A <dfn>layout definition</dfn> describes an author defined layout which can be referenced by the
654+
<<layout()>> or <<inline-layout()>> functions. It consists of:
655+
656+
- A <dfn>layout name</dfn>.
657+
658+
- A <dfn>layout class constructor</dfn> which is the class <a>constructor</a>.
659+
660+
- A <dfn>layout generator function</dfn> which is the layout <a>generator function</a> callback.
661+
662+
- A <dfn>layout class constructor valid flag</dfn>.
663+
664+
The {{LayoutWorkletGlobalScope}} has a map of <b>layout name to layout definition map</b>. Initially
665+
this map is empty; it is populated when {{registerLayout(name, layoutCtor)}} is called.
666+
667+
When the <dfn method for=LayoutWorkletGlobalScope>registerLayout(|name|, |layoutCtor|)</dfn> method
668+
is called, the user agent <em>must</em> run the following steps:
669+
1. If the |name| exists as a key in the <a>layout name to layout definition map</dfn>,
670+
<a>throw</a> a <a>NotSupportedError</a> and abort all these steps.
671+
672+
2. If the |name| is an empty string, <a>throw</a> a <a>TypeError</a> and abort all these steps.
673+
674+
3. Let |inputProperties| be the result of <a>Get</a>(|layoutCtor|,
675+
<code>"inputProperties"</code>).
676+
677+
4. If |inputProperties| is not undefined, and the result of <a>IsArray</a>(|inputProperties|) is
678+
false, <a>throw</a> a <a>TypeError</a> and abort all these steps.
679+
680+
If |inputProperties| is undefined, let |inputProperties| be a new empty array.
681+
682+
5. For each |item| in |inputProperties| perform the following substeps:
683+
684+
1. If the result of <a>Type</a>(|item|) is not String, <a>throw</a> a <a>TypeError</a> and
685+
abort all these steps.
616686

617-
Issue: Write full register algorithm, and checks required.
687+
6. Let |childInputProperties| be the result of <a>Get</a>(|layoutCtor|,
688+
<code>"childInputProperties"</code>).
689+
690+
7. If |childInputProperties| is not undefined, and the result of
691+
<a>IsArray</a>(|childInputProperties|) is false, <a>throw</a> a <a>TypeError</a> and abort
692+
all these steps.
693+
694+
If |childInputProperties| is undefined, let |childInputProperties| be a new empty array.
695+
696+
8. For each |item| in |childInputProperties| perform the following substeps:
697+
698+
1. If the result of <a>Type</a>(|item|) is not String, <a>throw</a> a <a>TypeError</a> and
699+
abort these steps.
700+
701+
Note: The list of CSS properties provided by "inputProperties" or "childInputProperties" can
702+
either by custom or native CSS properties.
703+
704+
Note: The list of CSS properties may contain shorthands.
705+
706+
Note: In order for a layout class to be forwards compatible, the list of CSS properties can also
707+
contain currently invalid properties for the user agent. For example
708+
<code>margin-bikeshed-property</code>.
709+
710+
9. Let |prototype| be the result of <a>Get</a>(|layoutCtor|, <code>"prototype"</code>).
711+
712+
10. If the result of <a>Type</a>(|prototype|) is not Object, <a>throw</a> a <a>TypeError</a> and
713+
abort all these steps.
714+
715+
11. Let |layout| be the result of <a>Get</a>(|prototype|, <code>"layout"</code>).
716+
717+
12. If the result of <a>IsCallable</a>(|layout|) is false, <a>throw</a> a <a>TypeError</a> and
718+
abort all these steps.
719+
720+
13. If |layout|'s <code>\[[FunctionKind]]</code> internal slot is not <code>"generator"</code>,
721+
<a>throw</a> a <a>TypeError</a> and abort all these steps.
722+
723+
14. Let |definition| be a new <a>layout definition</a> with:
724+
725+
- <a>layout name</a> being |name|.
726+
727+
- <a>layout class constructor</a> being |layoutCtor|.
728+
729+
- <a>layout generator function</a> being |layout|.
730+
731+
- <a>layout class constructor valid flag</a> being true
732+
733+
15. Add the key-value pair (|name| - |inputProperties|) to the <a>layout name to input
734+
properties map</a> of the associated <a>document</a>.
735+
736+
16. Add the key-value pair (|name| - |childInputProperties|) to the <a>layout name to child
737+
input properties map</a> of the associated <a>document</a>.
738+
739+
17. Add the key-value pair (|name| - |definition|) to the <a>layout name to layout definition
740+
map</a> of the associated <a>document</a>.
618741

619742
<div class='note'>
620-
This is what the shape of the class should be:
621-
<pre class='idl'>
622-
callback interface LayoutClass {
623-
readonly attribute sequence&lt;DOMString> inputProperties;
624-
readonly attribute sequence&lt;DOMString> childInputProperties;
625-
626-
LayoutResult layout(
627-
ConstraintSpace space,
628-
sequence&lt;Box> children,
629-
StylePropertyMap styleMap,
630-
BreakToken break);
631-
};
743+
The shape of the class should be:
744+
<pre class='lang-javascript'>
745+
class MyLayout {
746+
static get inputProperties() { return ['--foo'] }
747+
static get childrenInputProperties() { return ['--bar'] }
748+
749+
*layout(constraintSpace, children, styleMap, breakToken) {
750+
// Etc.
751+
}
752+
}
632753
</pre>
633754
</div>
634755

0 commit comments

Comments
 (0)