@@ -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+
14441450dictionary 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
14521603The [=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