@@ -63,6 +63,10 @@ urlPrefix: https://tc39.github.io/ecma262/#sec-; type: dfn;
6363 url: terms-and-definitions-function; text: function
6464 urlPrefix: native-error-types-used-in-this-standard-
6565 text: TypeError
66+ urlPrefix: https://drafts.csswg.org/css-display-3/#; type: dfn
67+ text: flow layout
68+ urlPrefix: https://drafts.csswg.org/css-sizing/#; type: dfn
69+ text: intrinsic sizes
6670</pre>
6771
6872Introduction {#intro}
@@ -733,6 +737,9 @@ name to child input properties map</dfn>. Initially these maps are empty and are
733737Each <a>box</a> has an associated <dfn>layout valid flag</dfn> . It may be either
734738<dfn>layout-valid</dfn> or <dfn>layout-invalid</dfn> . It is initially set to <a>layout-invalid</a> .
735739
740+ TODO comments. <dfn>content size valid flag</dfn> . <dfn>content-size-valid</dfn> .
741+ <dfn>content-size-invalid</dfn> .
742+
736743Issue: The above flag is too restrictive on user agents, change.
737744
738745When the computed style for a |box| changes, the user agent must run the following steps:
@@ -846,7 +853,8 @@ The {{LayoutWorkletGlobalScope}} has a <a>map</a> of <dfn>layout definitions</df
846853map is empty; it is populated when {{registerLayout(name, layoutCtor)}} is called.
847854
848855The {{LayoutWorkletGlobalScope}} has a <a>map</a> of <dfn>layout class instances</dfn> . Initially
849- this map is empty; it is populated when {{registerLayout(name, layoutCtor)}} is called.
856+ this map is empty; it is populated when the user agent calls either <a>determine the content
857+ size</a> or <a>generate a fragment</a> for a <a>box</a> .
850858
851859<div algorithm>
852860When the <dfn method for=LayoutWorkletGlobalScope>registerLayout(|name|, |layoutCtor|)</dfn> method
@@ -1089,13 +1097,211 @@ dictionary ContentSizeResultOptions {
10891097 double maxContentSize;
10901098 double minContentSize;
10911099};
1100+
1101+ interface ContentSize {
1102+ readonly attribute double minContentSize;
1103+ readonly attribute double maxContentSize;
1104+ };
10921105</pre>
10931106
10941107Issue: Specify how we do min/max content contributions.
10951108
10961109Issue: Need to specify that the {{LayoutChild}} objects should remain the same between layouts so
10971110 the author can store information? Not sure.
10981111
1112+ <div algorithm="determine the content size">
1113+ When the user agent wants to <dfn>determine the content size</dfn> of a <a>layout API formatting
1114+ context</a> for a given |box|, |childBoxes| it <em> must</em> run the following steps:
1115+
1116+ 1. Let |layoutFunction| be the <<layout()>> for the <a>computed value</a> of <<display-inside>>
1117+ for |box|.
1118+
1119+ 2. If the <a>content size valid flag</a> for the |layoutFunction| is <a>content-size-valid</a>
1120+ the user agent <em> may</em> use the content size from the previous invocation. If so it
1121+ <em> may</em> abort all these steps and use the previous value for the content sizes.
1122+
1123+ 3. Set the <a>content size valid flag</a> for the |layoutFunction| to <a>content-size-valid</a> .
1124+
1125+ 4. Let |name| be the first argument of the |layoutFunction|.
1126+
1127+ 5. Let |documentLayoutDefinitionMap| be the associated <a>document's</a> <a>document layout
1128+ definitions</a> map.
1129+
1130+ 6. If |documentLayoutDefinitionMap|[|name|] does not <a for=map>exist</a> , let the |box|
1131+ fallback to the <a>flow layout</a> and abort all these steps.
1132+
1133+ 7. Let |documentDefinition| be the result of <a for=map>get</a>
1134+ |documentLayoutDefinitionMap|[|name|] .
1135+
1136+ 8. If |documentDefinition| is <code> "invalid"</code> , let the |box| fallback to the <a>flow
1137+ layout</a> and abort all these steps.
1138+
1139+ 9. Let |workletGlobalScope| be a {{LayoutWorkletGlobalScope}} from the list of <a>worklet's
1140+ WorkletGlobalScopes</a> fomr the layout {{Worklet}} .
1141+
1142+ The user agent <em> must</em> have, and select from at least two
1143+ {{LayoutWorkletGlobalScope}} s in the <a>worklet's WorkletGlobalScopes</a> <a>list</a> ,
1144+ unless the user agent is under memory constraints.
1145+
1146+ Note: This is to ensure that authers do not rely on being able to store state on the global
1147+ object or non-regeneratable state on the class.
1148+
1149+ The user agent <em> may</em> also <a>create a WorkletGlobalScope</a> at this time, given the
1150+ layout {{Worklet}} .
1151+
1152+ 10. Run <a>invoke a content size callback</a> given |name|, |box|, |childBoxes|, and
1153+ |workletGlobalScope| optionally <a>in parallel</a> .
1154+
1155+ Note: If the user agent runs <a>invoke a content size callback</a> on a thread <a>in
1156+ parallel</a> , it should select a layout worklet global scope which can be used on that
1157+ thread.
1158+ </div>
1159+
1160+ <div algorithm="invoke a content size callback">
1161+ When the user agent wants to <dfn>invoke a content size callback</dfn> given |name|, |box|,
1162+ |childBoxes|, and |workletGlobalScope|, it <em> must</em> run the following steps:
1163+
1164+ 1. Let |definition| be the result of <a>get a layout definition</a> given |name|, and
1165+ |workletGlobalScope|.
1166+
1167+ If |definition| is <code> "null"</code> , (i.e. <a>get a layout definition</a> failed), let
1168+ the |box| fallback to the <a>flow layout</a> and abort all these steps.
1169+
1170+ 2. Let |layoutInstance| be the result of <a>get a layout class instance</a> given |name|, |box|,
1171+ |definition|, |workletGlobalScope|.
1172+
1173+ If |layoutInstance| is <code> "null"</code> , (i.e. <a>get a layout class instance</a> failed),
1174+ let |box| fallback to the <a>flow layout</a> and abort all these steps.
1175+
1176+ 3. Let |inputProperties| be |definition|'s <a for="layout definition">input properties</a> .
1177+
1178+ 4. Let |childInputProperties| be |definition|'s <a for="layout definition">child input
1179+ properties</a> .
1180+
1181+ 5. Let |styleMap| be a new {{StylePropertyMapReadOnly}} populated with <em> only</em> the
1182+ <a>computed value</a> 's for properties listed in |inputProperties| for |box|.
1183+
1184+ 6. Let |children| be a new <a>list</a> populated with new {{LayoutChild}} objects which
1185+ represent |childBoxes|.
1186+
1187+ The {{LayoutChild/styleMap}} on each {{LayoutChild}} should be a new
1188+ {{StylePropertyMapReadOnly}} populated with <em> only</em> the <a>computed value</a> 's for
1189+ properties listed in |childInputProperties|.
1190+
1191+ 7. Let |contentSizeGeneratorFunction| be |definition|'s <a>content size generator function</a> .
1192+
1193+ 8. Let |contentSizeGenerator| be the result of <a>Invoke</a> (|contentSizeGeneratorFunction|,
1194+ |layoutInstance|, «|styleMap|, |children|»).
1195+
1196+ If an exception is <a>thrown</a> the let |box| fallback to the <a>flow layout</a> and abort
1197+ all these steps.
1198+
1199+ 9. Let |nextResult| be the result of calling <a>Invoke</a> (<code> next</code> ,
1200+ |contentSizeGenerator|).
1201+
1202+ If an exception is <a>thrown</a> the let |box| fallback to the <a>flow layout</a> and abort
1203+ all these steps.
1204+
1205+ 10. Perform the following substeps until the result of <a>Get</a> (|nextResult|,
1206+ <code> "done"</code> ) is <code> true</code> .
1207+
1208+ 1. Let |childContentSizeRequests| be the result of <a>Get</a> (|nextResult|,
1209+ <code> "value"</code> ).
1210+
1211+ 2. Let |childContentSizes| be an <a for=list>empty</a> <a>list</a> .
1212+
1213+ 3. <a for=list>For each</a> |childRequest| in |childContentSizeRequests| perform the
1214+ following substeps:
1215+
1216+ 1. If |childRequest| is not a {{ContentSizeRequest}} then let |box| fallback to the
1217+ <a>flow layout</a> and abort all these steps.
1218+
1219+ 2. Let |layoutChild| be result of looking up the internal slot
1220+ <code> \[[layoutChild]] </code> on |childRequest|.
1221+
1222+ 3. Let |childContentSize| be a new {{ContentSize}} with:
1223+
1224+ - {{ContentSize/minContentSize}} being |layoutChild|'s <a>min-content size</a> .
1225+
1226+ - {{ContentSize/maxContentSize}} being |layoutChild|'s <a>max-content size</a> .
1227+
1228+ 4. <a for=list>Append</a> |childContentSize| to |childContentSizes|.
1229+
1230+ The user agent may perform this loop out of order, and <a>in parallel</a> . The ordering
1231+ for |childContentSizes| and |childContentSizeRequests| <em> must</em> be consistent.
1232+
1233+ 4. Let |nextResult| be the result of calling <a>Invoke</a> (<code> next</code> ,
1234+ |contentSizeGenerator|, |childContentSizes|).
1235+
1236+ If an exception is <a>thrown</a> then let |box| fallback to the <a>flow layout</a> and
1237+ abort all these steps.
1238+
1239+ 11. Let |contentSizeValue| be the result of calling <a>Get</a> (|nextResult|,
1240+ <code> "value"</code> ).
1241+
1242+ 12. Let |contentSize| be the result of <a>converting</a> |contentSizeValue| to a
1243+ {{ContentSizeResultOptions}} . If an exception is <a>thrown</a> , let |box| fallback to the
1244+ <a>flow layout</a> and abort all these steps.
1245+
1246+ 13. Set the <a>intrinsic sizes</a> of |box|:
1247+
1248+ - Let |contentSize|'s {{ContentSizeResultOptions/minContentSize}} be the <a>min-content
1249+ size</a> of |box|.
1250+
1251+ - Let |contentSize|'s {{ContentSizeResultOptions/maxContentSize}} be the <a>max-content
1252+ size</a> of |box|.
1253+ </div>
1254+
1255+ <div algorithm="get a layout definition">
1256+ When the user agent wants to <dfn>get a layout definition</dfn> given |name|, and
1257+ |workletGlobalScope|, it <em> must</em> run the following steps:
1258+
1259+ 1. Let |layoutDefinitionMap| be |workletGlobalScope|'s <a>layout definitions</a> map.
1260+
1261+ 2. If |layoutDefinitionMap|[|name|] does not <a for=map>exist</a> , run the following steps:
1262+
1263+ 1. <a>Queue a task</a> to run the following steps:
1264+
1265+ 1. Let |documentLayoutDefinitionMap| be the associated <a>document</a> 's <a>document
1266+ layout definition</a> map.
1267+
1268+ 2. <a for=map>Set</a> |documentLayoutDefinitionMap|[|name|] to <code> "invalid"</code> .
1269+
1270+ 3. The user agent <em> should</em> log an error to the debugging console stating that a
1271+ class wasn't registered in all {{LayoutWorkletGlobalScope}} s.
1272+
1273+ 2. Return <code> "null"</code> , and abort all these steps.
1274+
1275+ 3. Return the result of <a>get</a> |layoutDefinitionMap|[|name|] .
1276+ </div>
1277+
1278+ <div algorithm="get a layout class instance">
1279+ When the user agent wants to <dfn>get a layout class instance</dfn> given |name|, |box|,
1280+ |definition|, and |workletGlobalScope|, it <em> must</em> run the following steps:
1281+
1282+ 1. Let |layoutClassInstanceMap| be |workletGlobalScope|'s <a>layout class instances</a> map.
1283+
1284+ 2. Let |key| be a stable <a for=map>key</a> which is unique to |box| and |name|.
1285+
1286+ 3. Let |layoutInstance| be the result of <a>get</a> |layoutClassInstanceMap|[|key|] . If
1287+ |layoutInstance| is null, run the following steps:
1288+
1289+ 1. If the <a>constructor valid flag</a> on |definition| is false, let |box| fallback to the
1290+ <a>flow layout</a> and a abort all these steps.
1291+
1292+ 2. Let |layoutCtor| be the <a>class constructor</a> on |definition|.
1293+
1294+ 3. Let |layoutInstance| be the result of <a>Construct</a> (|layoutCtor|).
1295+
1296+ If <a>construct</a> throws an exception, set the |definition|'s <a>constructor valid
1297+ flag</a> to false, then return <code> "null"</code> and abort all these steps.
1298+
1299+ 4. <a for=map>Set</a> |layoutClassInstanceMap|[|key|] to |layoutInstance|.
1300+
1301+ 4. Return |layoutInstance|.
1302+ </div>
1303+
1304+ <div algorithm="generate a fragment">
10991305When the user agent wants to <dfn>generate a fragment</dfn> of a <a>layout API formatting
11001306context</a> for a given |box|, |constraintSpace|, |children| and an optional |breakToken| it
11011307<em> must</em> run the following steps:
@@ -1229,3 +1435,4 @@ context</a> for a given |box|, |constraintSpace|, |children| and an optional |br
12291435 - The {{FragmentResultOptions/blockSize}} of the fragment.
12301436
12311437 15. Return |fragment|.
1438+ </div>
0 commit comments