Skip to content

Commit df94ac5

Browse files
committed
[css-layout-api] Introduce FragmentResult & constructor.
1 parent 520e6b2 commit df94ac5

File tree

1 file changed

+170
-37
lines changed

1 file changed

+170
-37
lines changed

css-layout-api/Overview.bs

+170-37
Original file line numberDiff line numberDiff line change
@@ -682,7 +682,7 @@ When the user agent wants to <dfn>get a layout child</dfn> given |workletGlobalS
682682
properties</a>.
683683

684684
3. Let |layoutChild| be a new {{LayoutChild}} with internal slot(s):
685-
- {{[[box]]}} set to |box|.
685+
- {{LayoutChild/[[box]]}} set to |box|.
686686
- {{[[styleMap]]}} set to a new {{StylePropertyMapReadOnly}} populated with
687687
<em>only</em> the [=computed values=] for properties listed in
688688
|childInputProperties|.
@@ -1441,12 +1441,163 @@ dictionary FragmentResultOptions {
14411441
BreakTokenOptions breakToken = null;
14421442
};
14431443

1444+
[Constructor(FragmentResultOptions)]
1445+
interface FragmentResult {
1446+
readonly attribute double inlineSize;
1447+
readonly attribute double blockSize;
1448+
};
1449+
14441450
dictionary IntrinsicSizesResultOptions {
14451451
double maxContentSize;
14461452
double minContentSize;
14471453
};
14481454
</pre>
14491455

1456+
The {{FragmentResult}} has internal slot(s):
1457+
1458+
- <dfn attribute for=FragmentResult>\[[box]]</dfn> a CSS [=box=].
1459+
1460+
- <dfn attribute for=FragmentResult>[[inline size]]</dfn> the inline size of the resulting
1461+
fragment.
1462+
1463+
- <dfn attribute for=FragmentResult>[[block size]]</dfn> the block size of the resulting
1464+
fragment.
1465+
1466+
- <dfn attribute for=FragmentResult>[[child fragments]]</dfn> the list of child fragments.
1467+
1468+
- <dfn attribute for=FragmentResult>\[[data]]</dfn> some optional serialized data.
1469+
1470+
- <dfn attribute for=FragmentResult>[[internal break token]]</dfn> an internal representation of
1471+
the break information for this fragment.
1472+
1473+
- <dfn attribute for=FragmentResult>[[unique id]]</dfn> the [=unique id=] of the current
1474+
[=layout api context=]. This slot is used so that a {{FragmentResult}} used outside the
1475+
current layout pass is invalid.
1476+
1477+
<hr>
1478+
1479+
The web developer defined layout method can return either a {{FragmentResultOptions}} or a
1480+
{{FragmentResult}}. The {{FragmentResult}} can be used for determining the final size of the
1481+
fragment or detecting if the provided {{FragmentResultOptions}} would result in triggering a
1482+
fallback to [=flow layout=].
1483+
1484+
<div class="example">
1485+
This example show the web developer using the {{FragmentResult}} instead of just returning the
1486+
{{FragmentResultOptions}} object.
1487+
1488+
<pre class="lang-javascript">
1489+
registerLayout('feature-detection', class {
1490+
async layout(children, edges, constraints, styleMap, breakToken) {
1491+
1492+
let result;
1493+
try {
1494+
result = new FragmentResult({
1495+
childFragments: [],
1496+
autoBlockSize: 100
1497+
});
1498+
} catch (e) {
1499+
// The above call may throw, if the dictionary was just returned, it
1500+
// would fallback to flow layout.
1501+
}
1502+
1503+
// The web developer can test what size the fragment will be.
1504+
result.blockSize;
1505+
1506+
// Instead of returning the dictionary, we can just return this object.
1507+
return result;
1508+
}
1509+
}
1510+
</pre>
1511+
</div>
1512+
1513+
<div algorithm>
1514+
The <dfn attribute for=FragmentResult>inlineSize</dfn>, on getting from a {{FragmentResult}} |this|,
1515+
the user agent must perform the following steps:
1516+
1517+
1. Return |this|' {{FragmentResult/[[inline size]]}} internal slot.
1518+
</div>
1519+
1520+
<div algorithm>
1521+
The <dfn attribute for=FragmentResult>blockSize</dfn>, on getting from a {{FragmentResult}} |this|,
1522+
the user agent must perform the following steps:
1523+
1524+
1. Return |this|' {{FragmentResult/[[block size]]}} internal slot.
1525+
</div>
1526+
1527+
Note: The {{FragmentResult(options)}} constructor performs a series of validation checks (the web
1528+
developer isn't using an object from a previous invocation, and determines the final size of the
1529+
resulting fragment.
1530+
1531+
<div algorithm>
1532+
When the <dfn constructor for=FragmentResult>FragmentResult(options)</dfn> constructor is called,
1533+
the user agent must perform the following stpes:
1534+
1535+
1. Let |context| be the [=current layout's=] [=layout API context=].
1536+
1537+
2. Let |uniqueId| be |context|'s [=unique id=].
1538+
1539+
3. Let |box| be the [=current layout's=] [=box=].
1540+
1541+
4. Let |breakTokenOptions| be |options|'s {{FragmentResultOptions/breakToken}}.
1542+
1543+
5. [=list/For each=] |childFragment| in |options|'s {{FragmentResultOptions/childFragments}},
1544+
perform the following stubsteps:
1545+
1546+
1. If |childFragment|'s {{LayoutFragment/[[unique id]]}} internal slot is not equal to
1547+
|uniqueId|, then [=throw=] a [=TypeError=], and abort all these steps.
1548+
1549+
6. [=list/For each=] |childBreakToken| in |breakTokenOptions|'s
1550+
{{BreakTokenOptions/childBreakTokens}}, perform the following stubsteps:
1551+
1552+
1. If |childBreakToken|'s {{ChildBreakToken/[[unique id]]}} internal slot is not equal to
1553+
|uniqueId|, then [=throw=] a [=TypeError=], and abort all these steps.
1554+
1555+
7. If |sizingMode| is <code>"block-like"</code>:
1556+
1557+
- Then:
1558+
1559+
1. Let |inlineSize| be the result of calculating |box|'s <b>border-box</b> [=inline
1560+
size=] (relative to |box|'s writing mode) exactly like block containers do.
1561+
1562+
2. Let |blockSize| be the result of calculating |box|'s <b>border-box</b>
1563+
[=block size=] (relative to |box|'s writing mode) exactly like block containers do,
1564+
given |fragment|'s {{FragmentResultOptions/autoBlockSize}} as the "intrinsic
1565+
block size".
1566+
1567+
- Otherwise (|sizingMode| is <code>"manual"</code>):
1568+
1569+
1. Let |inlineSize| be |fragment|'s {{FragmentResultOptions/inlineSize}}.
1570+
1571+
2. Let |blockSize| be |fragment|'s {{FragmentResultOptions/blockSize}}.
1572+
1573+
8. Let |clonedData| be the result of invoking [=StructuredSerializeForStorage=] on |options|'s
1574+
{{FragmentResultOptions/data}}.
1575+
1576+
9. Let |clonedBreakTokenData| be the result of invoking [=StructuredSerializeForStorage=] on
1577+
|breakTokenOptions|'s {{BreakTokenOptions/data}}.
1578+
1579+
10. Let |internalBreakToken| be the internal representation of the [=fragmentation break=]
1580+
containing |clonedBreakTokenData|, and |breakTokenOptions|.
1581+
1582+
11. Return a new {{FragmentResult}} with:
1583+
1584+
- {{FragmentResult/[[box]]}} being |box|.
1585+
1586+
- {{FragmentResult/[[inline size]]}} being |inlineSize|.
1587+
1588+
- {{FragmentResult/[[block size]]}} being |blockSize|.
1589+
1590+
- {{FragmentResult/[[child fragments]]}} being |options|'s
1591+
{{FragmentResultOptions/childFragments}}.
1592+
1593+
- {{FragmentResult/[[data]]}} being |clonedData|.
1594+
1595+
- {{FragmentResult/[[internal break token]]}} being |internalBreakToken|.
1596+
1597+
- {{FragmentResult/[[unique id]]}} being |uniqueId|.
1598+
1599+
</div>
1600+
14501601
### Determining Intrinsic Sizes ### {#determining-intrinsic-sizes}
14511602

14521603
The [=determine the intrinsic sizes=] algorithm defines how a user agent is to query the author
@@ -1665,54 +1816,36 @@ following steps:
16651816
If [=run a work queue=] returns failure, let the |box| fallback to the [=flow layout=] and
16661817
abort all these steps.
16671818

1668-
16. Let |fragment| be the result of [=converting=] |fragmentValue| to a
1819+
16. Let |fragmentResultOptions| be the result of [=converting=] |fragmentValue| to a
16691820
{{FragmentResultOptions}}. If an exception is [=thrown=], let |box| fallback to the [=flow
16701821
layout=] and abort all these steps.
16711822

1672-
17. <a for=list>For each</a> |childFragment| in |fragment|'s
1673-
{{FragmentResultOptions/childFragments}}, perform the following stubsteps:
1674-
1675-
1. If |childFragment|'s {{LayoutFragment/[[unique id]]}} internal slot is not equal to
1676-
|context|'s [=unique id=], then let |box| fallback to the [=flow layout=] and abort all
1677-
these steps.
1678-
1679-
18. If |sizingMode| is <code>"block-like"</code>:
1680-
1681-
- Then:
1682-
1683-
1. Let |inlineSize| be |layoutConstraints|' {{LayoutConstraints/fixedInlineSize}}. (This
1684-
value must be set if we are using <code>"block-like"</code> sizing).
1685-
1686-
2. Let |blockSize| be the result of calculating |box|'s <b>border-box</b>
1687-
[=block size=] (relative to |box|'s writing mode) exactly like block containers do,
1688-
given |fragment|'s {{FragmentResultOptions/autoBlockSize}} as the "intrinsic
1689-
height".
1823+
17. Let |fragmentResult| be the result of constructing {{FragmentResult(options)}} given
1824+
|fragmentResultOptions|.
16901825

1691-
- Otherwise (|sizingMode| is <code>"manual"</code>):
1826+
If an exception is [=thrown=] the let |box| fallback to the [=flow layout=] and abort all
1827+
these steps.
16921828

1693-
1. Let |inlineSize| be |fragment|'s {{FragmentResultOptions/inlineSize}}.
1829+
Issue: The above two steps may not be needed as it already might be a {{FragmentResult}}.
16941830

1695-
2. Let |blockSize| be |fragment|'s {{FragmentResultOptions/blockSize}}.
1831+
18. Return an internal representation of a [=fragment=] with:
16961832

1697-
19. Return a [=fragment=] for |box| with:
1833+
- The [=inline size=] set to |fragmentResult|'s {{FragmentResult/[[inline size]]}}.
16981834

1699-
- The [=inline size=] set to |inlineSize|.
1835+
- The [=block size=] set to |fragmentResult|'s {{FragmentResult/[[inline size]]}}.
17001836

1701-
- The [=block size=] set to |blockSize|.
1837+
- The child fragments set to |fragmentResult|'s {{FragmentResult/[[child fragments]]}}.
17021838

1703-
- The child fragments set to |fragment|'s {{FragmentResultOptions/childFragments}}
1704-
[=list=]. The ordering <em>is</em> important as this dictates their paint order
1705-
(described in [[#layout-api-containers]]). Their position relative to the <b>border
1706-
box</b> of the |fragment| should be based off the author specified
1707-
{{LayoutFragment/inlineOffset}} and {{LayoutFragment/blockOffset}}.
1839+
The ordering <em>is</em> important as this dictates their paint order (described in
1840+
[[#layout-api-containers]]). Their position relative to the <b>border box</b> of the
1841+
fragment should be based off the author specified {{LayoutFragment/inlineOffset}} and
1842+
{{LayoutFragment/blockOffset}}.
17081843

1709-
- The [=fragmentation break=] information set to |fragment|'s
1710-
{{FragmentResultOptions/breakToken}}.
1844+
- The [=fragmentation break=] information set to |fragmentResult|'s
1845+
{{FragmentResult/[[internal break token]]}}.
17111846

1712-
- Let |clonedData| be the result of invoking [=StructuredSerializeForStorage=] on
1713-
|fragment|'s {{FragmentResultOptions/data}}.
1847+
- Store |fragmentResult|'s {{FragmentResult/[[data]]}} with the [=fragment=].
17141848

1715-
The user agent must store |clonedData| with the [=fragment=].
17161849
</div>
17171850

17181851
### Utility Algorithms ### {#utility-algorithms}
@@ -1808,7 +1941,7 @@ When the user agent wants to <dfn>run a work queue</dfn> given |promise|, and |w
18081941

18091942
1. Let |layoutChild| be |task|'s [=layout api work task/layout child=].
18101943

1811-
2. Let |box| be |layoutChild|'s [=box=] in the {{[[box]]}} internal slot.
1944+
2. Let |box| be |layoutChild|'s [=box=] in the {{LayoutChild/[[box]]}} internal slot.
18121945

18131946
3. Let |childPromise| be |task|'s [=layout api work task/=promise].
18141947

0 commit comments

Comments
 (0)