summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/tests/css/css-layout-api
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 09:22:09 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 09:22:09 +0000
commit43a97878ce14b72f0981164f87f2e35e14151312 (patch)
tree620249daf56c0258faa40cbdcf9cfba06de2a846 /testing/web-platform/tests/css/css-layout-api
parentInitial commit. (diff)
downloadfirefox-43a97878ce14b72f0981164f87f2e35e14151312.tar.xz
firefox-43a97878ce14b72f0981164f87f2e35e14151312.zip
Adding upstream version 110.0.1.upstream/110.0.1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'testing/web-platform/tests/css/css-layout-api')
-rw-r--r--testing/web-platform/tests/css/css-layout-api/META.yml4
-rw-r--r--testing/web-platform/tests/css/css-layout-api/at-supports-rule.https.html23
-rw-r--r--testing/web-platform/tests/css/css-layout-api/auto-block-size/absolute.https.html73
-rw-r--r--testing/web-platform/tests/css/css-layout-api/auto-block-size/auto-block-size-absolute-ref.html27
-rw-r--r--testing/web-platform/tests/css/css-layout-api/auto-block-size/auto-block-size-floats-ref.html26
-rw-r--r--testing/web-platform/tests/css/css-layout-api/auto-block-size/auto-block-size-negative-ref.html11
-rw-r--r--testing/web-platform/tests/css/css-layout-api/auto-block-size/flex-ref.html21
-rw-r--r--testing/web-platform/tests/css/css-layout-api/auto-block-size/flex.https.html61
-rw-r--r--testing/web-platform/tests/css/css-layout-api/auto-block-size/floats.https.html57
-rw-r--r--testing/web-platform/tests/css/css-layout-api/auto-block-size/inflow-ref.html13
-rw-r--r--testing/web-platform/tests/css/css-layout-api/auto-block-size/inflow.https.html63
-rw-r--r--testing/web-platform/tests/css/css-layout-api/auto-block-size/negative.https.html50
-rw-r--r--testing/web-platform/tests/css/css-layout-api/baseline/child-baseline.https.html58
-rw-r--r--testing/web-platform/tests/css/css-layout-api/baseline/flex-baseline.https.html51
-rw-r--r--testing/web-platform/tests/css/css-layout-api/baseline/no-baseline.https.html42
-rw-r--r--testing/web-platform/tests/css/css-layout-api/baseline/orthogonal-baseline.https.html42
-rw-r--r--testing/web-platform/tests/css/css-layout-api/box-tree-registered-ref.html20
-rw-r--r--testing/web-platform/tests/css/css-layout-api/box-tree-registered.https.html66
-rw-r--r--testing/web-platform/tests/css/css-layout-api/box-tree-unregistered-ref.html34
-rw-r--r--testing/web-platform/tests/css/css-layout-api/box-tree-unregistered.https.html62
-rw-r--r--testing/web-platform/tests/css/css-layout-api/child-constraints/available-block-size-htb-vrl.https.html65
-rw-r--r--testing/web-platform/tests/css/css-layout-api/child-constraints/available-block-size-invalid.https.html49
-rw-r--r--testing/web-platform/tests/css/css-layout-api/child-constraints/available-block-size-vrl-htb.https.html65
-rw-r--r--testing/web-platform/tests/css/css-layout-api/child-constraints/available-inline-size-htb-htb.https.html65
-rw-r--r--testing/web-platform/tests/css/css-layout-api/child-constraints/available-inline-size-invalid.https.html49
-rw-r--r--testing/web-platform/tests/css/css-layout-api/child-constraints/available-inline-size-vrl-vrl.https.html65
-rw-r--r--testing/web-platform/tests/css/css-layout-api/child-constraints/available-size-for-percentages-htb-htb.https.html59
-rw-r--r--testing/web-platform/tests/css/css-layout-api/child-constraints/available-size-for-percentages-htb-vrl.https.html59
-rw-r--r--testing/web-platform/tests/css/css-layout-api/child-constraints/available-size-for-percentages-invalid.https.html49
-rw-r--r--testing/web-platform/tests/css/css-layout-api/child-constraints/available-size-for-percentages-vrl-htb.https.html59
-rw-r--r--testing/web-platform/tests/css/css-layout-api/child-constraints/available-size-for-percentages-vrl-vrl.https.html59
-rw-r--r--testing/web-platform/tests/css/css-layout-api/child-constraints/fixed-block-size-vrl.https.html60
-rw-r--r--testing/web-platform/tests/css/css-layout-api/child-constraints/fixed-block-size.https.html59
-rw-r--r--testing/web-platform/tests/css/css-layout-api/child-constraints/fixed-inline-size-vrl.https.html60
-rw-r--r--testing/web-platform/tests/css/css-layout-api/child-constraints/fixed-inline-size.https.html59
-rw-r--r--testing/web-platform/tests/css/css-layout-api/child-constraints/percentage-size-htb-htb.https.html58
-rw-r--r--testing/web-platform/tests/css/css-layout-api/child-constraints/percentage-size-htb-vrl.https.html58
-rw-r--r--testing/web-platform/tests/css/css-layout-api/child-constraints/percentage-size-invalid.https.html47
-rw-r--r--testing/web-platform/tests/css/css-layout-api/child-constraints/percentage-size-quirks-mode.https.html55
-rw-r--r--testing/web-platform/tests/css/css-layout-api/child-constraints/percentage-size-vrl-htb.https.html58
-rw-r--r--testing/web-platform/tests/css/css-layout-api/child-constraints/percentage-size-vrl-vrl.https.html58
-rw-r--r--testing/web-platform/tests/css/css-layout-api/child-constraints/support/layout-child-sizes-worklet.js67
-rw-r--r--testing/web-platform/tests/css/css-layout-api/chrome-bug-1287843-000-crash.https.html12
-rw-r--r--testing/web-platform/tests/css/css-layout-api/chrome-bug-1287843-001-crash.https.html18
-rw-r--r--testing/web-platform/tests/css/css-layout-api/chrome-bug-1291449-crash.https.html11
-rw-r--r--testing/web-platform/tests/css/css-layout-api/chrome-bug-1296664-crash.https.html18
-rw-r--r--testing/web-platform/tests/css/css-layout-api/computed-style-layout-function.https.html50
-rw-r--r--testing/web-platform/tests/css/css-layout-api/constraints-data-function-failure.https.html61
-rw-r--r--testing/web-platform/tests/css/css-layout-api/constraints-data-sab-failure.https.html62
-rw-r--r--testing/web-platform/tests/css/css-layout-api/constraints-data.https.html69
-rw-r--r--testing/web-platform/tests/css/css-layout-api/constraints/fixed-block-size-absolute-left-right-vrl.https.html40
-rw-r--r--testing/web-platform/tests/css/css-layout-api/constraints/fixed-block-size-absolute-none.https.html36
-rw-r--r--testing/web-platform/tests/css/css-layout-api/constraints/fixed-block-size-absolute-top-bottom.https.html39
-rw-r--r--testing/web-platform/tests/css/css-layout-api/constraints/fixed-block-size-block-none-vrl.https.html32
-rw-r--r--testing/web-platform/tests/css/css-layout-api/constraints/fixed-block-size-block-none.https.html32
-rw-r--r--testing/web-platform/tests/css/css-layout-api/constraints/fixed-block-size-fixed-max.https.html34
-rw-r--r--testing/web-platform/tests/css/css-layout-api/constraints/fixed-block-size-fixed-min.https.html34
-rw-r--r--testing/web-platform/tests/css/css-layout-api/constraints/fixed-block-size-fixed-vrl.https.html33
-rw-r--r--testing/web-platform/tests/css/css-layout-api/constraints/fixed-block-size-fixed.https.html33
-rw-r--r--testing/web-platform/tests/css/css-layout-api/constraints/fixed-block-size-flex-basis-vrl.https.html37
-rw-r--r--testing/web-platform/tests/css/css-layout-api/constraints/fixed-block-size-flex-column-basis.https.html38
-rw-r--r--testing/web-platform/tests/css/css-layout-api/constraints/fixed-block-size-flex-column-grow.https.html40
-rw-r--r--testing/web-platform/tests/css/css-layout-api/constraints/fixed-block-size-flex-column-none.https.html37
-rw-r--r--testing/web-platform/tests/css/css-layout-api/constraints/fixed-block-size-flex-column-stretch-vrl.https.html39
-rw-r--r--testing/web-platform/tests/css/css-layout-api/constraints/fixed-block-size-flex-grow-vrl.https.html38
-rw-r--r--testing/web-platform/tests/css/css-layout-api/constraints/fixed-block-size-flex-none.https.html36
-rw-r--r--testing/web-platform/tests/css/css-layout-api/constraints/fixed-block-size-flex-percentage-indefinite.https.html37
-rw-r--r--testing/web-platform/tests/css/css-layout-api/constraints/fixed-block-size-flex-stretch-max.https.html39
-rw-r--r--testing/web-platform/tests/css/css-layout-api/constraints/fixed-block-size-flex-stretch.https.html38
-rw-r--r--testing/web-platform/tests/css/css-layout-api/constraints/fixed-block-size-grid-none.https.html36
-rw-r--r--testing/web-platform/tests/css/css-layout-api/constraints/fixed-block-size-grid-stretch-max.https.html39
-rw-r--r--testing/web-platform/tests/css/css-layout-api/constraints/fixed-block-size-grid-stretch.https.html38
-rw-r--r--testing/web-platform/tests/css/css-layout-api/constraints/fixed-block-size-grid-vrl.https.html38
-rw-r--r--testing/web-platform/tests/css/css-layout-api/constraints/fixed-block-size-percentage-indefinite.https.html33
-rw-r--r--testing/web-platform/tests/css/css-layout-api/constraints/fixed-block-size-percentage-quirks-mode.https.html38
-rw-r--r--testing/web-platform/tests/css/css-layout-api/constraints/fixed-block-size-percentage-vrl.https.html37
-rw-r--r--testing/web-platform/tests/css/css-layout-api/constraints/fixed-block-size-percentage.https.html37
-rw-r--r--testing/web-platform/tests/css/css-layout-api/constraints/fixed-block-size-quirky-body.https.html22
-rw-r--r--testing/web-platform/tests/css/css-layout-api/constraints/fixed-inline-size-absolute-left-right.https.html33
-rw-r--r--testing/web-platform/tests/css/css-layout-api/constraints/fixed-inline-size-absolute-top-bottom-vrl.https.html35
-rw-r--r--testing/web-platform/tests/css/css-layout-api/constraints/fixed-inline-size-block-auto-avoid-floats-vlr.https.html37
-rw-r--r--testing/web-platform/tests/css/css-layout-api/constraints/fixed-inline-size-block-auto-avoid-floats.https.html36
-rw-r--r--testing/web-platform/tests/css/css-layout-api/constraints/fixed-inline-size-block-auto-vlr.https.html31
-rw-r--r--testing/web-platform/tests/css/css-layout-api/constraints/fixed-inline-size-block-auto.https.html30
-rw-r--r--testing/web-platform/tests/css/css-layout-api/constraints/fixed-inline-size-fixed-vrl.https.html27
-rw-r--r--testing/web-platform/tests/css/css-layout-api/constraints/fixed-inline-size-fixed.https.html26
-rw-r--r--testing/web-platform/tests/css/css-layout-api/constraints/fixed-inline-size-flex-grow-column-vrl.https.html33
-rw-r--r--testing/web-platform/tests/css/css-layout-api/constraints/fixed-inline-size-flex-grow.https.html31
-rw-r--r--testing/web-platform/tests/css/css-layout-api/constraints/fixed-inline-size-grid.https.html30
-rw-r--r--testing/web-platform/tests/css/css-layout-api/constraints/fixed-inline-size-percentage-vlr.https.html31
-rw-r--r--testing/web-platform/tests/css/css-layout-api/constraints/fixed-inline-size-percentage.https.html30
-rw-r--r--testing/web-platform/tests/css/css-layout-api/constraints/fixed-inline-size-ref.html10
-rw-r--r--testing/web-platform/tests/css/css-layout-api/constraints/support/constraints-fixed-block-size-quirky-body-iframe.html21
-rw-r--r--testing/web-platform/tests/css/css-layout-api/constraints/support/constraints-fixed-block-size.js22
-rw-r--r--testing/web-platform/tests/css/css-layout-api/constraints/support/constraints-fixed-inline-size.js9
-rw-r--r--testing/web-platform/tests/css/css-layout-api/crash-multicol.https.html28
-rw-r--r--testing/web-platform/tests/css/css-layout-api/edges/all-ref.html161
-rw-r--r--testing/web-platform/tests/css/css-layout-api/edges/all.https.html194
-rw-r--r--testing/web-platform/tests/css/css-layout-api/edges/border-htb-rtl.https.html39
-rw-r--r--testing/web-platform/tests/css/css-layout-api/edges/border-htb.https.html38
-rw-r--r--testing/web-platform/tests/css/css-layout-api/edges/border-vlr-rtl.https.html39
-rw-r--r--testing/web-platform/tests/css/css-layout-api/edges/border-vlr.https.html38
-rw-r--r--testing/web-platform/tests/css/css-layout-api/edges/border-vrl-rtl.https.html39
-rw-r--r--testing/web-platform/tests/css/css-layout-api/edges/border-vrl.https.html38
-rw-r--r--testing/web-platform/tests/css/css-layout-api/edges/padding-htb-rtl.https.html37
-rw-r--r--testing/web-platform/tests/css/css-layout-api/edges/padding-htb.https.html36
-rw-r--r--testing/web-platform/tests/css/css-layout-api/edges/padding-vlr-rtl.https.html37
-rw-r--r--testing/web-platform/tests/css/css-layout-api/edges/padding-vlr.https.html36
-rw-r--r--testing/web-platform/tests/css/css-layout-api/edges/padding-vrl-rtl.https.html37
-rw-r--r--testing/web-platform/tests/css/css-layout-api/edges/padding-vrl.https.html36
-rw-r--r--testing/web-platform/tests/css/css-layout-api/edges/scrollbar-ref.html159
-rw-r--r--testing/web-platform/tests/css/css-layout-api/edges/scrollbar.https.html192
-rw-r--r--testing/web-platform/tests/css/css-layout-api/edges/support/edges.js38
-rw-r--r--testing/web-platform/tests/css/css-layout-api/fallback-intrinsic-sizes/bad-return.https.html49
-rw-r--r--testing/web-platform/tests/css/css-layout-api/fallback-intrinsic-sizes/constructor-error.https.html50
-rw-r--r--testing/web-platform/tests/css/css-layout-api/fallback-intrinsic-sizes/error.https.html49
-rw-r--r--testing/web-platform/tests/css/css-layout-api/fallback-intrinsic-sizes/fallback-ref.html11
-rw-r--r--testing/web-platform/tests/css/css-layout-api/fallback-intrinsic-sizes/invalid-child.https.html84
-rw-r--r--testing/web-platform/tests/css/css-layout-api/fallback-intrinsic-sizes/no-promise.https.html41
-rw-r--r--testing/web-platform/tests/css/css-layout-api/fallback-intrinsic-sizes/unresolved-promise.https.html41
-rw-r--r--testing/web-platform/tests/css/css-layout-api/fallback-layout/bad-return.https.html50
-rw-r--r--testing/web-platform/tests/css/css-layout-api/fallback-layout/constructor-error.https.html51
-rw-r--r--testing/web-platform/tests/css/css-layout-api/fallback-layout/error.https.html50
-rw-r--r--testing/web-platform/tests/css/css-layout-api/fallback-layout/fallback-layout-fallback-ref.html11
-rw-r--r--testing/web-platform/tests/css/css-layout-api/fallback-layout/invalid-child.https.html84
-rw-r--r--testing/web-platform/tests/css/css-layout-api/fallback-layout/invalid-fragment.https.html82
-rw-r--r--testing/web-platform/tests/css/css-layout-api/fallback-layout/no-promise.https.html41
-rw-r--r--testing/web-platform/tests/css/css-layout-api/fallback-layout/unresolved-promise.https.html41
-rw-r--r--testing/web-platform/tests/css/css-layout-api/fragment-data-function-failure.https.html43
-rw-r--r--testing/web-platform/tests/css/css-layout-api/fragment-data-immutable.https.html69
-rw-r--r--testing/web-platform/tests/css/css-layout-api/fragment-data-sab-failure.https.html45
-rw-r--r--testing/web-platform/tests/css/css-layout-api/fragment-data.https.html64
-rw-r--r--testing/web-platform/tests/css/css-layout-api/green-square-ref.html9
-rw-r--r--testing/web-platform/tests/css/css-layout-api/inline-style-layout-function.https.html36
-rw-r--r--testing/web-platform/tests/css/css-layout-api/input-text-crash.https.html4
-rw-r--r--testing/web-platform/tests/css/css-layout-api/inside-multicol-crash.https.html8
-rw-r--r--testing/web-platform/tests/css/css-layout-api/intrinsic-sizes/absolute-ref.html43
-rw-r--r--testing/web-platform/tests/css/css-layout-api/intrinsic-sizes/absolute.https.html73
-rw-r--r--testing/web-platform/tests/css/css-layout-api/intrinsic-sizes/child-replaced-percentage-01.https.html47
-rw-r--r--testing/web-platform/tests/css/css-layout-api/intrinsic-sizes/child-replaced-percentage-02.https.html49
-rw-r--r--testing/web-platform/tests/css/css-layout-api/intrinsic-sizes/child-replaced-percentage-ref.html9
-rw-r--r--testing/web-platform/tests/css/css-layout-api/intrinsic-sizes/child-size-01-ref.html9
-rw-r--r--testing/web-platform/tests/css/css-layout-api/intrinsic-sizes/child-size-01.https.html61
-rw-r--r--testing/web-platform/tests/css/css-layout-api/intrinsic-sizes/child-size-02-ref.html9
-rw-r--r--testing/web-platform/tests/css/css-layout-api/intrinsic-sizes/child-size-02.https.html67
-rw-r--r--testing/web-platform/tests/css/css-layout-api/intrinsic-sizes/child-size-03.https.html67
-rw-r--r--testing/web-platform/tests/css/css-layout-api/intrinsic-sizes/child-size-contribution.https.html49
-rw-r--r--testing/web-platform/tests/css/css-layout-api/intrinsic-sizes/content-size-ref.html11
-rw-r--r--testing/web-platform/tests/css/css-layout-api/intrinsic-sizes/content-size.https.html48
-rw-r--r--testing/web-platform/tests/css/css-layout-api/intrinsic-sizes/floats-ref.html47
-rw-r--r--testing/web-platform/tests/css/css-layout-api/intrinsic-sizes/floats.https.html78
-rw-r--r--testing/web-platform/tests/css/css-layout-api/intrinsic-sizes/invalid-min-max.https.html39
-rw-r--r--testing/web-platform/tests/css/css-layout-api/intrinsic-sizes/invalid-ref.html11
-rw-r--r--testing/web-platform/tests/css/css-layout-api/intrinsic-sizes/negative-max.https.html40
-rw-r--r--testing/web-platform/tests/css/css-layout-api/intrinsic-sizes/negative-min.https.html40
-rw-r--r--testing/web-platform/tests/css/css-layout-api/intrinsic-sizes/negative-ref.html11
-rw-r--r--testing/web-platform/tests/css/css-layout-api/layout-child/absolute.https.html43
-rw-r--r--testing/web-platform/tests/css/css-layout-api/layout-child/before-after.https.html48
-rw-r--r--testing/web-platform/tests/css/css-layout-api/layout-child/fixed.https.html43
-rw-r--r--testing/web-platform/tests/css/css-layout-api/layout-child/float.https.html43
-rw-r--r--testing/web-platform/tests/css/css-layout-api/layout-child/inflow.https.html42
-rw-r--r--testing/web-platform/tests/css/css-layout-api/layout-child/inlines-dynamic.https.html39
-rw-r--r--testing/web-platform/tests/css/css-layout-api/layout-child/inlines.https.html54
-rw-r--r--testing/web-platform/tests/css/css-layout-api/layout-child/support/layout-child-worklet.js26
-rw-r--r--testing/web-platform/tests/css/css-layout-api/layout-child/text-01.https.html51
-rw-r--r--testing/web-platform/tests/css/css-layout-api/layout-child/text-02.https.html44
-rw-r--r--testing/web-platform/tests/css/css-layout-api/list-item-multicol-with-custom-layout-child-crash.https.html6
-rw-r--r--testing/web-platform/tests/css/css-layout-api/multicol-break-before-crash.https.html7
-rw-r--r--testing/web-platform/tests/css/css-layout-api/multicol-child-crash.https.html10
-rw-r--r--testing/web-platform/tests/css/css-layout-api/multicol-details-crash.https.html6
-rw-r--r--testing/web-platform/tests/css/css-layout-api/multicol-fieldset-crash.https.html8
-rw-r--r--testing/web-platform/tests/css/css-layout-api/position-fragment/htb-ltr.https.html54
-rw-r--r--testing/web-platform/tests/css/css-layout-api/position-fragment/htb-rtl.https.html54
-rw-r--r--testing/web-platform/tests/css/css-layout-api/position-fragment/ref.html33
-rw-r--r--testing/web-platform/tests/css/css-layout-api/position-fragment/support/layout-position-child-worklet.js20
-rw-r--r--testing/web-platform/tests/css/css-layout-api/position-fragment/vlr-ltr.https.html54
-rw-r--r--testing/web-platform/tests/css/css-layout-api/position-fragment/vlr-rtl.https.html54
-rw-r--r--testing/web-platform/tests/css/css-layout-api/position-fragment/vrl-ltr.https.html54
-rw-r--r--testing/web-platform/tests/css/css-layout-api/position-fragment/vrl-rtl.https.html54
-rw-r--r--testing/web-platform/tests/css/css-layout-api/style-map-multi-ref.html13
-rw-r--r--testing/web-platform/tests/css/css-layout-api/style-map-multi.https.html70
-rw-r--r--testing/web-platform/tests/css/css-layout-api/style-map-ref.html16
-rw-r--r--testing/web-platform/tests/css/css-layout-api/style-map.https.html71
-rw-r--r--testing/web-platform/tests/css/css-layout-api/supports.https.html11
-rw-r--r--testing/web-platform/tests/css/css-layout-api/sync-layout-microtasks.https.html56
185 files changed, 7996 insertions, 0 deletions
diff --git a/testing/web-platform/tests/css/css-layout-api/META.yml b/testing/web-platform/tests/css/css-layout-api/META.yml
new file mode 100644
index 0000000000..c85c2d4ccc
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/META.yml
@@ -0,0 +1,4 @@
+spec: https://drafts.css-houdini.org/css-layout-api/
+suggested_reviewers:
+ - bfgeek
+ - tabatkins
diff --git a/testing/web-platform/tests/css/css-layout-api/at-supports-rule.https.html b/testing/web-platform/tests/css/css-layout-api/at-supports-rule.https.html
new file mode 100644
index 0000000000..0f23325ce6
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/at-supports-rule.https.html
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#valdef-display-layout">
+<meta name="assert" content="This test checks that a layout() function works correctly with an @supports rule." />
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<style>
+#test {
+ content: 'fail';
+}
+
+@supports (display: layout(foo)) {
+ #test {
+ content: 'pass';
+ }
+}
+</style>
+<div id="test"></div>
+<script>
+test(function() {
+ const element = document.getElementById('test');
+ assert_equals(getComputedStyle(element).content, '"pass"');
+});
+</script>
diff --git a/testing/web-platform/tests/css/css-layout-api/auto-block-size/absolute.https.html b/testing/web-platform/tests/css/css-layout-api/auto-block-size/absolute.https.html
new file mode 100644
index 0000000000..bf81b21a4b
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/auto-block-size/absolute.https.html
@@ -0,0 +1,73 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#interaction-sizing">
+<link rel="match" href="auto-block-size-absolute-ref.html">
+<meta name="assert" content="This test checks that the absolute positioning respects the auto-block-size." />
+
+<style>
+.test {
+ position: absolute;
+ background: red;
+}
+
+@supports (display: layout(block-size-100)) {
+ .test {
+ display: layout(block-size-100);
+ background: green;
+ }
+}
+
+.container {
+ position: relative;
+ margin: 20px 0;
+ width: 200px;
+ height: 200px;
+ border: solid 2px;
+}
+
+.width-100 {
+ width: 100px;
+ writing-mode: horizontal-tb;
+}
+
+.height-100 {
+ height: 100px;
+ writing-mode: vertical-rl;
+}
+</style>
+<script src="/common/reftest-wait.js"></script>
+<script src="/common/worklet-reftest.js"></script>
+
+<!-- 100px x 100px, bottom-left -->
+<div class="container">
+ <div class="test width-100" style="bottom: 0px"></div>
+</div>
+
+<!-- 100px x 200px, left, auto-size is ignored. -->
+<div class="container">
+ <div class="test width-100" style="top: 0px; bottom: 0px"></div>
+</div>
+
+<!-- 100px x 100px, top-left -->
+<div class="container">
+ <div class="test height-100" style="left: 0px;"></div>
+</div>
+
+<!-- 100px x 100px, top, auto-size is ignored. -->
+<div class="container">
+ <div class="test height-100" style="left: 0px; right: 0px;"></div>
+</div>
+
+<script id="code" type="text/worklet">
+registerLayout('block-size-100', class {
+ async intrinsicSizes() {}
+ async layout() {
+ return {autoBlockSize: 100};
+ }
+});
+</script>
+
+<script>
+importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, document.getElementById('code').textContent);
+</script>
+</html>
diff --git a/testing/web-platform/tests/css/css-layout-api/auto-block-size/auto-block-size-absolute-ref.html b/testing/web-platform/tests/css/css-layout-api/auto-block-size/auto-block-size-absolute-ref.html
new file mode 100644
index 0000000000..416d57c43f
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/auto-block-size/auto-block-size-absolute-ref.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<style>
+.container {
+ position: relative;
+ margin: 20px 0;
+ width: 200px;
+ height: 200px;
+ border: solid 2px;
+}
+
+.result {
+ position: absolute;
+ background: green;
+}
+</style>
+<div class="container">
+ <div class="result" style="width: 100px; height: 100px; bottom: 0px;"></div>
+</div>
+<div class="container">
+ <div class="result" style="width: 100px; height: 200px;"></div>
+</div>
+<div class="container">
+ <div class="result" style="width: 100px; height: 100px;"></div>
+</div>
+<div class="container">
+ <div class="result" style="width: 200px; height: 100px;"></div>
+</div>
diff --git a/testing/web-platform/tests/css/css-layout-api/auto-block-size/auto-block-size-floats-ref.html b/testing/web-platform/tests/css/css-layout-api/auto-block-size/auto-block-size-floats-ref.html
new file mode 100644
index 0000000000..368d3d8693
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/auto-block-size/auto-block-size-floats-ref.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<style>
+.container {
+ width: 150px;
+ border: solid 2px;
+}
+
+.left {
+ float: left;
+ background: green;
+ width: 100px;
+ height: 100px;
+}
+
+.right {
+ float: right;
+ background: green;
+ width: 100px;
+ height: 100px;
+}
+</style>
+
+<div class="container">
+ <div class="left"></div>
+ <div class="right"></div>
+</div>
diff --git a/testing/web-platform/tests/css/css-layout-api/auto-block-size/auto-block-size-negative-ref.html b/testing/web-platform/tests/css/css-layout-api/auto-block-size/auto-block-size-negative-ref.html
new file mode 100644
index 0000000000..665b5c6620
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/auto-block-size/auto-block-size-negative-ref.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<style>
+.result {
+ background: green;
+ border: solid 2px;
+ margin: 20px 0;
+}
+</style>
+
+<div class="result" style="width: 100px; height: 0px;"></div>
+<div class="result" style="width: 0px; height: 100px;"></div>
diff --git a/testing/web-platform/tests/css/css-layout-api/auto-block-size/flex-ref.html b/testing/web-platform/tests/css/css-layout-api/auto-block-size/flex-ref.html
new file mode 100644
index 0000000000..e71b104c74
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/auto-block-size/flex-ref.html
@@ -0,0 +1,21 @@
+<!DOCTYPE html>
+<style>
+.container {
+ border: solid 2px;
+ display: flow-root;
+ width: 300px;
+}
+
+.child {
+ background: green;
+ border: solid 2px;
+ box-sizing: border-box;
+ float: left;
+ height: 100px;
+}
+</style>
+
+<div class="container">
+ <div class="child" style="width: 100px;"></div>
+ <div class="child" style="width: 200px;"></div>
+</div>
diff --git a/testing/web-platform/tests/css/css-layout-api/auto-block-size/flex.https.html b/testing/web-platform/tests/css/css-layout-api/auto-block-size/flex.https.html
new file mode 100644
index 0000000000..96fe3c79a9
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/auto-block-size/flex.https.html
@@ -0,0 +1,61 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#interaction-sizing">
+<link rel="match" href="flex-ref.html">
+<meta name="assert" content="This test checks that the flex layout respects the auto-block-size." />
+
+<style>
+.flex {
+ width: 300px;
+ display: flex;
+ border: solid 2px;
+}
+
+.custom {
+ background: red;
+ box-sizing: border-box;
+ border: solid 2px;
+ height: 100px;
+ writing-mode: vertical-rl;
+}
+
+@supports (display: layout(block-size-100)) {
+ .custom-100 {
+ display: layout(block-size-100);
+ background: green;
+ }
+ .custom-50 {
+ display: layout(block-size-50);
+ background: green;
+ flex: 1;
+ }
+}
+</style>
+<script src="/common/reftest-wait.js"></script>
+<script src="/common/worklet-reftest.js"></script>
+
+<!-- Tests that floats using an auto block size get positioned correctly. -->
+<div class="flex">
+ <div class="custom custom-100"></div>
+ <div class="custom custom-50"></div>
+</div>
+
+<script id="code" type="text/worklet">
+registerLayout('block-size-100', class {
+ async intrinsicSizes() {}
+ async layout() {
+ return {autoBlockSize: 100};
+ }
+});
+registerLayout('block-size-50', class {
+ async intrinsicSizes() {}
+ async layout() {
+ return {autoBlockSize: 50};
+ }
+});
+</script>
+
+<script>
+importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, document.getElementById('code').textContent);
+</script>
+</html>
diff --git a/testing/web-platform/tests/css/css-layout-api/auto-block-size/floats.https.html b/testing/web-platform/tests/css/css-layout-api/auto-block-size/floats.https.html
new file mode 100644
index 0000000000..342c57b530
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/auto-block-size/floats.https.html
@@ -0,0 +1,57 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#interaction-sizing">
+<link rel="match" href="auto-block-size-floats-ref.html">
+<meta name="assert" content="This test checks that if the layout() is a float, the flow layout respects the auto-block-size." />
+
+<style>
+.test {
+ background: red;
+}
+
+@supports (display: layout(block-size-100)) {
+ .test {
+ display: layout(block-size-100);
+ background: green;
+ }
+}
+
+.container {
+ width: 150px;
+ border: solid 2px;
+}
+
+.left {
+ float: left;
+ width: 100px;
+ writing-mode: horizontal-tb;
+}
+
+.right {
+ float: right;
+ height: 100px;
+ writing-mode: vertical-rl;
+}
+</style>
+<script src="/common/reftest-wait.js"></script>
+<script src="/common/worklet-reftest.js"></script>
+
+<!-- Tests that floats using an auto block size get positioned correctly. -->
+<div class="container">
+ <div class="left test"></div>
+ <div class="right test"></div>
+</div>
+
+<script id="code" type="text/worklet">
+registerLayout('block-size-100', class {
+ async intrinsicSizes() {}
+ async layout() {
+ return {autoBlockSize: 100};
+ }
+});
+</script>
+
+<script>
+importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, document.getElementById('code').textContent);
+</script>
+</html>
diff --git a/testing/web-platform/tests/css/css-layout-api/auto-block-size/inflow-ref.html b/testing/web-platform/tests/css/css-layout-api/auto-block-size/inflow-ref.html
new file mode 100644
index 0000000000..73f84811b1
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/auto-block-size/inflow-ref.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<style>
+.result {
+ margin: 20px 0;
+ background: green;
+}
+</style>
+<div class="result" style="width: 100px; height: 100px;"></div>
+<div class="result" style="width: 100px; height: 150px;"></div>
+<div class="result" style="width: 100px; height: 50px;"></div>
+<div class="result" style="width: 100px; height: 100px;"></div>
+<div class="result" style="width: 150px; height: 100px;"></div>
+<div class="result" style="width: 50px; height: 100px;"></div>
diff --git a/testing/web-platform/tests/css/css-layout-api/auto-block-size/inflow.https.html b/testing/web-platform/tests/css/css-layout-api/auto-block-size/inflow.https.html
new file mode 100644
index 0000000000..2239b27894
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/auto-block-size/inflow.https.html
@@ -0,0 +1,63 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#interaction-sizing">
+<link rel="match" href="inflow-ref.html">
+<meta name="assert" content="This test checks that min/max-block-size constraints are applied correctly to a layout()." />
+
+<style>
+.test {
+ margin: 20px 0;
+ background: red;
+}
+
+@supports (display: layout(block-size-100)) {
+ .test {
+ display: layout(block-size-100);
+ background: green;
+ }
+}
+
+.width-100 {
+ width: 100px;
+ writing-mode: horizontal-tb;
+}
+
+.height-100 {
+ height: 100px;
+ writing-mode: vertical-rl;
+}
+</style>
+<script src="/common/reftest-wait.js"></script>
+<script src="/common/worklet-reftest.js"></script>
+
+<!-- 100px x 100px -->
+<div class="test width-100"></div>
+
+<!-- 100px x 150px -->
+<div class="test width-100" style="min-height: 150px"></div>
+
+<!-- 100px x 50px -->
+<div class="test width-100" style="max-height: 50px"></div>
+
+<!-- 100px x 100px -->
+<div class="test height-100"></div>
+
+<!-- 150px x 100px -->
+<div class="test height-100" style="min-width: 150px"></div>
+
+<!-- 50px x 100px -->
+<div class="test height-100" style="max-width: 50px"></div>
+
+<script id="code" type="text/worklet">
+registerLayout('block-size-100', class {
+ async intrinsicSizes() {}
+ async layout() {
+ return {autoBlockSize: 100};
+ }
+});
+</script>
+
+<script>
+importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, document.getElementById('code').textContent);
+</script>
+</html>
diff --git a/testing/web-platform/tests/css/css-layout-api/auto-block-size/negative.https.html b/testing/web-platform/tests/css/css-layout-api/auto-block-size/negative.https.html
new file mode 100644
index 0000000000..d321f03002
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/auto-block-size/negative.https.html
@@ -0,0 +1,50 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#interaction-sizing">
+<link rel="match" href="auto-block-size-negative-ref.html">
+<meta name="assert" content="This test checks that auto-block-size is correctly clamped to zero." />
+
+<style>
+
+.test {
+ background: red;
+ border: solid 2px;
+ margin: 20px 0;
+}
+
+.width-100 {
+ width: 100px;
+ writing-mode: horizontal-tb;
+}
+
+.height-100 {
+ height: 100px;
+ writing-mode: vertical-rl;
+}
+
+@supports (display: layout(block-size-negative)) {
+ .test {
+ display: layout(block-size-negative);
+ background: green;
+ }
+}
+</style>
+<script src="/common/reftest-wait.js"></script>
+<script src="/common/worklet-reftest.js"></script>
+
+<div class="test width-100"></div>
+<div class="test height-100"></div>
+
+<script id="code" type="text/worklet">
+registerLayout('block-size-negative', class {
+ async intrinsicSizes() {}
+ async layout() {
+ return {autoBlockSize: -100};
+ }
+});
+</script>
+
+<script>
+importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, document.getElementById('code').textContent);
+</script>
+</html>
diff --git a/testing/web-platform/tests/css/css-layout-api/baseline/child-baseline.https.html b/testing/web-platform/tests/css/css-layout-api/baseline/child-baseline.https.html
new file mode 100644
index 0000000000..a871d69011
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/baseline/child-baseline.https.html
@@ -0,0 +1,58 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#interaction-alignment">
+<link rel="match" href="../green-square-ref.html">
+<meta name="assert" content="This test checks that passing child baseline to a parent works correctly." />
+<style>
+.test {
+ background: green;
+ padding: 0 10px;
+ width: 80px;
+}
+
+@supports (display: layout(parent)) {
+ .test {
+ display: layout(parent);
+ background: green;
+ }
+
+ .child {
+ display: layout(child);
+ }
+}
+</style>
+<script src="/common/reftest-wait.js"></script>
+<script src="/common/worklet-reftest.js"></script>
+
+<div class="test">
+ <div class="child"></div>
+</div>
+
+<script id="code" type="text/worklet">
+const BASELINE = 10;
+
+registerLayout('parent', class {
+ async intrinsicSizes() {}
+ async layout(children) {
+ const childFragments = await Promise.all(children.map(child => child.layoutNextFragment({})));
+
+ if (childFragments[0].baseline != BASELINE)
+ return {autoBlockSize: 0, childFragments};
+
+ return {autoBlockSize: 100, childFragments};
+ }
+});
+
+registerLayout('child', class {
+ async intrinsicSizes() {}
+ async layout(children) {
+ const childFragments = await Promise.all(children.map(child => child.layoutNextFragment({})));
+ return { childFragments, baseline: BASELINE }
+ }
+});
+</script>
+
+<script>
+importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, document.getElementById('code').textContent);
+</script>
+</html>
diff --git a/testing/web-platform/tests/css/css-layout-api/baseline/flex-baseline.https.html b/testing/web-platform/tests/css/css-layout-api/baseline/flex-baseline.https.html
new file mode 100644
index 0000000000..ce869bee37
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/baseline/flex-baseline.https.html
@@ -0,0 +1,51 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#interaction-alignment">
+<link rel="match" href="../green-square-ref.html">
+<meta name="assert" content="This test checks that a baseline aligned element uses the baseline set in layout()."/>
+<style>
+.parent {
+ background: red;
+ display: flex;
+ padding: 0 10px;
+ width: 80px;
+ height: 100px;
+ align-items: baseline;
+}
+
+.child {
+ color: red;
+}
+
+@supports (display: layout(parent)) {
+ .parent {
+ background: green;
+ }
+ .child {
+ display: layout(child);
+ }
+}
+</style>
+<script src="/common/reftest-wait.js"></script>
+<script src="/common/worklet-reftest.js"></script>
+
+<div class="parent">
+ <div style="position: absolute; top: 50px; width: 50px; height: 25px; background: green;"></div>
+ <div></div>
+ <div class="child">text</div>
+</div>
+
+<script id="code" type="text/worklet">
+registerLayout('child', class {
+ async intrinsicSizes() {}
+ async layout(children) {
+ const childFragments = await Promise.all(children.map(child => child.layoutNextFragment({})));
+ return {childFragments, baseline: -50};
+ }
+});
+</script>
+
+<script>
+importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, document.getElementById('code').textContent);
+</script>
+</html>
diff --git a/testing/web-platform/tests/css/css-layout-api/baseline/no-baseline.https.html b/testing/web-platform/tests/css/css-layout-api/baseline/no-baseline.https.html
new file mode 100644
index 0000000000..0bc08552bc
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/baseline/no-baseline.https.html
@@ -0,0 +1,42 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#interaction-alignment">
+<link rel="match" href="../green-square-ref.html">
+<meta name="assert" content="This test checks that an element with no baseline is handled correctly."/>
+<style>
+.test {
+ background: green;
+ padding: 0 10px;
+ width: 80px;
+}
+
+@supports (display: layout(parent)) {
+ .test {
+ display: layout(parent);
+ background: green;
+ }
+}
+</style>
+<script src="/common/reftest-wait.js"></script>
+<script src="/common/worklet-reftest.js"></script>
+
+<div class="test">
+ <div></div>
+</div>
+
+<script id="code" type="text/worklet">
+registerLayout('parent', class {
+ async intrinsicSizes() {}
+ async layout(children) {
+ const childFragments = await Promise.all(children.map(child => child.layoutNextFragment({})));
+ if (childFragments[0].baseline)
+ return {autoBlockSize: 0, childFragments};
+ return {autoBlockSize: 100, childFragments};
+ }
+});
+</script>
+
+<script>
+importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, document.getElementById('code').textContent);
+</script>
+</html>
diff --git a/testing/web-platform/tests/css/css-layout-api/baseline/orthogonal-baseline.https.html b/testing/web-platform/tests/css/css-layout-api/baseline/orthogonal-baseline.https.html
new file mode 100644
index 0000000000..c83560b57e
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/baseline/orthogonal-baseline.https.html
@@ -0,0 +1,42 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#interaction-alignment">
+<link rel="match" href="../green-square-ref.html">
+<meta name="assert" content="This test checks that orthogonal children do not produce baselines."/>
+<style>
+.test {
+ background: green;
+ padding: 0 10px;
+ width: 80px;
+}
+
+@supports (display: layout(test)) {
+ .test {
+ display: layout(test);
+ background: green;
+ }
+}
+</style>
+<script src="/common/reftest-wait.js"></script>
+<script src="/common/worklet-reftest.js"></script>
+
+<div class="test">
+ <div style="writing-mode: vertical-rl; color: green;">text</div>
+</div>
+
+<script id="code" type="text/worklet">
+registerLayout('test', class {
+ async intrinsicSizes() {}
+ async layout(children) {
+ const childFragments = await Promise.all(children.map(child => child.layoutNextFragment({})));
+ if (childFragments[0].baseline)
+ return {autoBlockSize: 0, childFragments};
+ return {autoBlockSize: 100, childFragments};
+ }
+});
+</script>
+
+<script>
+importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, document.getElementById('code').textContent);
+</script>
+</html>
diff --git a/testing/web-platform/tests/css/css-layout-api/box-tree-registered-ref.html b/testing/web-platform/tests/css/css-layout-api/box-tree-registered-ref.html
new file mode 100644
index 0000000000..0ba9862015
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/box-tree-registered-ref.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<style>
+.container {
+ margin: 20px 0;
+ border: solid 2px;
+ width: 100px;
+}
+
+.pink {
+ background: hotpink;
+}
+</style>
+
+<div class="container">
+ <div class="pink" style="width: 50px; height: 100px;"></div>
+</div>
+
+<div class="container">
+ <div class="pink" style="width: 100px; height: 100px;"></div>
+</div>
diff --git a/testing/web-platform/tests/css/css-layout-api/box-tree-registered.https.html b/testing/web-platform/tests/css/css-layout-api/box-tree-registered.https.html
new file mode 100644
index 0000000000..c3024f9f3a
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/box-tree-registered.https.html
@@ -0,0 +1,66 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#layout-api-box-tree">
+<link rel="match" href="box-tree-registered-ref.html">
+<meta name="assert" content="This test checks that a registered layout() has children which are blockified and new formatting contexts." />
+<style>
+@supports (display: layout(registered)) {
+ .test {
+ display: layout(registered);
+ }
+}
+
+.container {
+ margin: 20px 0;
+ border: solid 2px;
+ width: 100px;
+}
+
+.float {
+ float: left;
+ width: 50%;
+ height: 50px;
+}
+
+.pink {
+ background: hotpink;
+}
+</style>
+<script src="/common/reftest-wait.js"></script>
+<script src="/common/worklet-reftest.js"></script>
+
+<div class="container">
+ <!-- This tests that the "layout()" grandchildren floats within the don't interact with each other. -->
+ <div class="test">
+ <div class="inflow">
+ <div class="float pink"></div>
+ </div>
+ <div class="inflow">
+ <div class="float pink"></div>
+ </div>
+ </div>
+</div>
+
+<div class="container">
+ <!-- This tests that the "layout()" children margins interact as if they are new formatting contexts. -->
+ <div class="test">
+ <div class="inflow pink">
+ <div style="margin-bottom: 50px;"></div>
+ </div>
+ <div class="inflow pink">
+ <div style="margin-top: 50px;"></div>
+ </div>
+ </div>
+</div>
+
+<script id="code" type="text/worklet">
+registerLayout('registered', class {
+ async intrinsicSizes() {}
+ async layout() { throw Error(); }
+});
+</script>
+
+<script>
+importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, document.getElementById('code').textContent);
+</script>
+</html>
diff --git a/testing/web-platform/tests/css/css-layout-api/box-tree-unregistered-ref.html b/testing/web-platform/tests/css/css-layout-api/box-tree-unregistered-ref.html
new file mode 100644
index 0000000000..20312cff8f
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/box-tree-unregistered-ref.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<style>
+.container {
+ float: left;
+ margin: 20px 0;
+ border: solid 2px;
+ width: 100px;
+}
+
+.inflow {
+ height: 40px;
+}
+</style>
+
+<div class="container">
+ <div class="inflow"></div>
+ <div class="inflow" style="background: hotpink"></div>
+ <div class="inflow"></div>
+</div>
+
+<div class="container">
+ <div class="inflow"></div>
+ <div class="inflow" style="background: hotpink"></div>
+ <div class="inflow"></div>
+</div>
+
+<div class="container">
+ <div class="inflow" style="background: hotpink"></div>
+ <div class="inflow" style="background: green"></div>
+</div>
+
+<div class="container">
+ <div style="height:100px; background:green;"></div>
+</div>
diff --git a/testing/web-platform/tests/css/css-layout-api/box-tree-unregistered.https.html b/testing/web-platform/tests/css/css-layout-api/box-tree-unregistered.https.html
new file mode 100644
index 0000000000..25fe602d1c
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/box-tree-unregistered.https.html
@@ -0,0 +1,62 @@
+<!DOCTYPE html>
+<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#layout-api-box-tree">
+<link rel="match" href="box-tree-unregistered-ref.html">
+<meta name="assert" content="This test checks that an unregistered layout() works the same as a normal flow-root." />
+<style>
+@supports (display: layout(unregistered)) {
+ .test {
+ display: layout(unregistered);
+ }
+}
+
+.container {
+ float: left;
+ margin: 20px 0;
+ border: solid 2px;
+ width: 100px;
+}
+
+.float {
+ float: left;
+ width: 100%;
+ height: 40px;
+ background: hotpink;
+}
+
+.inflow {
+ height: 40px;
+ background: hotpink;
+}
+</style>
+
+<div class="container">
+ <!-- This tests that the "layout()" margins don't collapse with its children. -->
+ <div class="test" style="margin: 20px 0">
+ <div class="inflow" style="margin: 20px 0"></div>
+ </div>
+</div>
+
+<div class="container">
+ <!-- This tests that the "layout()" grows to fit child floats. -->
+ <div class="test">
+ <div class="float" style="margin: 40px 0"></div>
+ </div>
+</div>
+
+<div class="container">
+ <!-- This tests that a float does not intrude into "layout()" box. -->
+ <div class="float"></div>
+ <div class="test" style="width: 100%; height: 40px; background: green;"></div>
+</div>
+
+<div class="container">
+ <!-- This tests that margins in two "layout()" box children collapse as normally. -->
+ <div class="test" style="background: green;">
+ <div style="margin:100px 0;">
+ <div style="margin:100px 0;"></div>
+ </div>
+ <div style="margin:100px 0;">
+ <div style="margin:100px 0;"></div>
+ </div>
+ </div>
+</div>
diff --git a/testing/web-platform/tests/css/css-layout-api/child-constraints/available-block-size-htb-vrl.https.html b/testing/web-platform/tests/css/css-layout-api/child-constraints/available-block-size-htb-vrl.https.html
new file mode 100644
index 0000000000..6ec8e4062f
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/child-constraints/available-block-size-htb-vrl.https.html
@@ -0,0 +1,65 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#dom-layoutconstraintsoptions-availableblocksize">
+<link rel="match" href="../green-square-ref.html">
+<meta name="assert" content="This test checks that setting the available block-size of children works as expected." />
+
+<style>
+.test {
+ writing-mode: horizontal-tb;
+ background: red;
+ width: 100px;
+}
+
+.child {
+ writing-mode: vertical-rl;
+ visibility: hidden;
+ line-height: 0;
+
+ --available-block-size: 20;
+}
+
+.inline {
+ display: inline-block;
+ width: 8px;
+}
+
+.inline-size-10 { height: 10px; }
+.inline-size-30 { height: 30px; }
+
+@supports (display: layout(test)) {
+ .test {
+ background: green;
+ display: layout(test);
+ }
+}
+</style>
+<script src="/common/reftest-wait.js"></script>
+<script src="/common/worklet-reftest.js"></script>
+
+<div class="test">
+ <!-- As the inlines don't fit within 20px, we'll end up with two lines. -->
+ <div class="child" style="--block-size-expected: 30; --inline-size-expected: 16;">
+ <span class="inline inline-size-10"></span>
+ <span class="inline inline-size-30"></span>
+ </div>
+
+ <!-- The single inline doesn't take up the whole 20px, so will be shrink fitted. -->
+ <div class="child" style="--block-size-expected: 10; --inline-size-expected: 8;">
+ <span class="inline inline-size-10"></span>
+ </div>
+
+ <!-- Make sure the max-height property clamps the size. -->
+ <div class="child" style="max-height: 25px; --block-size-expected: 25; --inline-size-expected: 8;">
+ <span class="inline inline-size-30"></span>
+ </div>
+
+ <!-- Make sure the min-height property clamps the size. -->
+ <div class="child" style="min-height: 25px; --block-size-expected: 25; --inline-size-expected: 8;">
+ <span class="inline inline-size-10"></span>
+ </div>
+</div>
+
+<script>
+importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, {url: 'support/layout-child-sizes-worklet.js'});
+</script>
diff --git a/testing/web-platform/tests/css/css-layout-api/child-constraints/available-block-size-invalid.https.html b/testing/web-platform/tests/css/css-layout-api/child-constraints/available-block-size-invalid.https.html
new file mode 100644
index 0000000000..32a0f11a4e
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/child-constraints/available-block-size-invalid.https.html
@@ -0,0 +1,49 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#dom-layoutconstraintsoptions-availableblocksize">
+<link rel="match" href="../green-square-ref.html">
+<meta name="assert" content="This test checks that setting an invalid available block-size works as expected." />
+
+<style>
+.test {
+ writing-mode: horizontal-tb;
+ background: red;
+ width: 100px;
+}
+
+.child {
+ writing-mode: vertical-rl;
+ visibility: hidden;
+ line-height: 0;
+
+ --available-block-size: -20;
+}
+
+.inline {
+ display: inline-block;
+ width: 8px;
+}
+
+.inline-size-10 { height: 10px; }
+
+@supports (display: layout(test)) {
+ .test {
+ background: green;
+ display: layout(test);
+ }
+}
+</style>
+<script src="/common/reftest-wait.js"></script>
+<script src="/common/worklet-reftest.js"></script>
+
+<div class="test">
+ <!-- The invalid available block-size should be clamped to zero. -->
+ <div class="child" style="--block-size-expected: 10; --inline-size-expected: 16;">
+ <span class="inline inline-size-10"></span>
+ <span class="inline inline-size-10"></span>
+ </div>
+</div>
+
+<script>
+importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, {url: 'support/layout-child-sizes-worklet.js'});
+</script>
diff --git a/testing/web-platform/tests/css/css-layout-api/child-constraints/available-block-size-vrl-htb.https.html b/testing/web-platform/tests/css/css-layout-api/child-constraints/available-block-size-vrl-htb.https.html
new file mode 100644
index 0000000000..536af3b5a4
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/child-constraints/available-block-size-vrl-htb.https.html
@@ -0,0 +1,65 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#dom-layoutconstraintsoptions-availableblocksize">
+<link rel="match" href="../green-square-ref.html">
+<meta name="assert" content="This test checks that setting the available block-size of children works as expected." />
+
+<style>
+.test {
+ writing-mode: vertical-rl;
+ background: red;
+ height: 100px;
+}
+
+.child {
+ writing-mode: horizontal-tb;
+ visibility: hidden;
+ line-height: 0;
+
+ --available-block-size: 20;
+}
+
+.inline {
+ display: inline-block;
+ height: 8px;
+}
+
+.inline-size-10 { width: 10px; }
+.inline-size-30 { width: 30px; }
+
+@supports (display: layout(test)) {
+ .test {
+ background: green;
+ display: layout(test);
+ }
+}
+</style>
+<script src="/common/reftest-wait.js"></script>
+<script src="/common/worklet-reftest.js"></script>
+
+<div class="test">
+ <!-- As the inlines don't fit within 20px, we'll end up with two lines. -->
+ <div class="child" style="--block-size-expected: 30; --inline-size-expected: 16;">
+ <span class="inline inline-size-10"></span>
+ <span class="inline inline-size-30"></span>
+ </div>
+
+ <!-- The single inline doesn't take up the whole 20px, so will be shrink fitted. -->
+ <div class="child" style="--block-size-expected: 10; --inline-size-expected: 8;">
+ <span class="inline inline-size-10"></span>
+ </div>
+
+ <!-- Make sure the max-width property clamps the size. -->
+ <div class="child" style="max-width: 25px; --block-size-expected: 25; --inline-size-expected: 8;">
+ <span class="inline inline-size-30"></span>
+ </div>
+
+ <!-- Make sure the min-width property clamps the size. -->
+ <div class="child" style="min-width: 25px; --block-size-expected: 25; --inline-size-expected: 8;">
+ <span class="inline inline-size-10"></span>
+ </div>
+</div>
+
+<script>
+importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, {url: 'support/layout-child-sizes-worklet.js'});
+</script>
diff --git a/testing/web-platform/tests/css/css-layout-api/child-constraints/available-inline-size-htb-htb.https.html b/testing/web-platform/tests/css/css-layout-api/child-constraints/available-inline-size-htb-htb.https.html
new file mode 100644
index 0000000000..6205c01d10
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/child-constraints/available-inline-size-htb-htb.https.html
@@ -0,0 +1,65 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#dom-layoutconstraintsoptions-availableinlinesize">
+<link rel="match" href="../green-square-ref.html">
+<meta name="assert" content="This test checks that setting the available inline-size of children works as expected." />
+
+<style>
+.test {
+ writing-mode: horizontal-tb;
+ background: red;
+ width: 100px;
+}
+
+.child {
+ writing-mode: horizontal-tb;
+ visibility: hidden;
+ line-height: 0;
+
+ --available-inline-size: 20;
+}
+
+.inline {
+ display: inline-block;
+ height: 8px;
+}
+
+.inline-size-10 { width: 10px; }
+.inline-size-30 { width: 30px; }
+
+@supports (display: layout(test)) {
+ .test {
+ background: green;
+ display: layout(test);
+ }
+}
+</style>
+<script src="/common/reftest-wait.js"></script>
+<script src="/common/worklet-reftest.js"></script>
+
+<div class="test">
+ <!-- As the inlines don't fit within 20px, we'll end up with two lines. -->
+ <div class="child" style="--inline-size-expected: 30; --block-size-expected: 16;">
+ <span class="inline inline-size-10"></span>
+ <span class="inline inline-size-30"></span>
+ </div>
+
+ <!-- The single inline doesn't take up the whole 20px, so will be shrink fitted. -->
+ <div class="child" style="--inline-size-expected: 10; --block-size-expected: 8;">
+ <span class="inline inline-size-10"></span>
+ </div>
+
+ <!-- Make sure the max-width property clamps the size. -->
+ <div class="child" style="max-width: 25px; --inline-size-expected: 25; --block-size-expected: 8;">
+ <span class="inline inline-size-30"></span>
+ </div>
+
+ <!-- Make sure the min-width property clamps the size. -->
+ <div class="child" style="min-width: 25px; --inline-size-expected: 25; --block-size-expected: 8;">
+ <span class="inline inline-size-10"></span>
+ </div>
+</div>
+
+<script>
+importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, {url: 'support/layout-child-sizes-worklet.js'});
+</script>
diff --git a/testing/web-platform/tests/css/css-layout-api/child-constraints/available-inline-size-invalid.https.html b/testing/web-platform/tests/css/css-layout-api/child-constraints/available-inline-size-invalid.https.html
new file mode 100644
index 0000000000..8bb18aaa4b
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/child-constraints/available-inline-size-invalid.https.html
@@ -0,0 +1,49 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#dom-layoutconstraintsoptions-availableinlinesize">
+<link rel="match" href="../green-square-ref.html">
+<meta name="assert" content="This test checks that setting an invalid available inline-size works as expected." />
+
+<style>
+.test {
+ writing-mode: horizontal-tb;
+ background: red;
+ width: 100px;
+}
+
+.child {
+ writing-mode: horizontal-tb;
+ visibility: hidden;
+ line-height: 0;
+
+ --available-inline-size: -20;
+}
+
+.inline {
+ display: inline-block;
+ height: 8px;
+}
+
+.inline-size-10 { width: 10px; }
+
+@supports (display: layout(test)) {
+ .test {
+ background: green;
+ display: layout(test);
+ }
+}
+</style>
+<script src="/common/reftest-wait.js"></script>
+<script src="/common/worklet-reftest.js"></script>
+
+<div class="test">
+ <!-- The invalid available inline-size should be clamped to zero. -->
+ <div class="child" style="--inline-size-expected: 10; --block-size-expected: 16;">
+ <span class="inline inline-size-10"></span>
+ <span class="inline inline-size-10"></span>
+ </div>
+</div>
+
+<script>
+importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, {url: 'support/layout-child-sizes-worklet.js'});
+</script>
diff --git a/testing/web-platform/tests/css/css-layout-api/child-constraints/available-inline-size-vrl-vrl.https.html b/testing/web-platform/tests/css/css-layout-api/child-constraints/available-inline-size-vrl-vrl.https.html
new file mode 100644
index 0000000000..1b8d01f024
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/child-constraints/available-inline-size-vrl-vrl.https.html
@@ -0,0 +1,65 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#dom-layoutconstraintsoptions-availableinlinesize">
+<link rel="match" href="../green-square-ref.html">
+<meta name="assert" content="This test checks that setting the available inline-size of children works as expected." />
+
+<style>
+.test {
+ writing-mode: vertical-rl;
+ background: red;
+ height: 100px;
+}
+
+.child {
+ writing-mode: vertical-rl;
+ visibility: hidden;
+ line-height: 0;
+
+ --available-inline-size: 20;
+}
+
+.inline {
+ display: inline-block;
+ width: 8px;
+}
+
+.inline-size-10 { height: 10px; }
+.inline-size-30 { height: 30px; }
+
+@supports (display: layout(test)) {
+ .test {
+ background: green;
+ display: layout(test);
+ }
+}
+</style>
+<script src="/common/reftest-wait.js"></script>
+<script src="/common/worklet-reftest.js"></script>
+
+<div class="test">
+ <!-- As the inlines don't fit within 20px, we'll end up with two lines. -->
+ <div class="child" style="--inline-size-expected: 30; --block-size-expected: 16;">
+ <span class="inline inline-size-10"></span>
+ <span class="inline inline-size-30"></span>
+ </div>
+
+ <!-- The single inline doesn't take up the whole 20px, so will be shrink fitted. -->
+ <div class="child" style="--inline-size-expected: 10; --block-size-expected: 8;">
+ <span class="inline inline-size-10"></span>
+ </div>
+
+ <!-- Make sure the max-height property clamps the size. -->
+ <div class="child" style="max-height: 25px; --inline-size-expected: 25; --block-size-expected: 8;">
+ <span class="inline inline-size-30"></span>
+ </div>
+
+ <!-- Make sure the min-height property clamps the size. -->
+ <div class="child" style="min-height: 25px; --inline-size-expected: 25; --block-size-expected: 8;">
+ <span class="inline inline-size-10"></span>
+ </div>
+</div>
+
+<script>
+importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, {url: 'support/layout-child-sizes-worklet.js'});
+</script>
diff --git a/testing/web-platform/tests/css/css-layout-api/child-constraints/available-size-for-percentages-htb-htb.https.html b/testing/web-platform/tests/css/css-layout-api/child-constraints/available-size-for-percentages-htb-htb.https.html
new file mode 100644
index 0000000000..9bf4d40ad6
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/child-constraints/available-size-for-percentages-htb-htb.https.html
@@ -0,0 +1,59 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#dom-layoutconstraintsoptions-availableinlinesize">
+<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#dom-layoutconstraintsoptions-availableblocksize">
+<link rel="match" href="../green-square-ref.html">
+<meta name="assert" content="This test checks that resolving percentages against the available size works as expected." />
+
+<style>
+.test {
+ writing-mode: horizontal-tb;
+ background: red;
+ width: 100px;
+}
+
+.child {
+ writing-mode: horizontal-tb;
+ visibility: hidden;
+
+ --available-inline-size: 50;
+ --available-block-size: 20;
+
+ --inline-size-expected: 10px;
+ --block-size-expected: 10px;
+}
+
+@supports (display: layout(test)) {
+ .test {
+ background: green;
+ display: layout(test);
+ }
+}
+</style>
+<script src="/common/reftest-wait.js"></script>
+<script src="/common/worklet-reftest.js"></script>
+
+<div class="test">
+ <!-- A fixed width/height shouldn't be affected by the available size. -->
+ <div class="child" style="width: 10px; height: 10px;"></div>
+
+ <!-- A percentage width/height should resolve itself against the available size. -->
+ <div class="child" style="width: 20%; height: 50%;"></div>
+
+ <!-- A percentage max-width/max-height should resolve itself against the available size. -->
+ <div class="child" style="width: 15px; max-width: 20%; height: 15px; max-height: 50%;"></div>
+
+ <!-- A percentage min-width/min-height should resolve itself against the available size. -->
+ <div class="child" style="width: 5px; min-width: 20%; height: 5px; min-height: 50%;"></div>
+
+ <!-- A replaced percentage width/height should resolve itself against the available size. -->
+ <img class="child" style="width: 20%; height: 50%;" />
+
+ <!-- A replaced percentage max-width/max-height should resolve itself against the available size. -->
+ <img class="child" style="width: 15px; max-width: 20%; height: 15px; max-height: 50%;" />
+
+ <!-- A replaced percentage min-width/min-height should resolve itself against the available size. -->
+ <img class="child" style="width: 5px; min-width: 20%; height: 5px; min-height: 50%;" />
+<script>
+importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, {url: 'support/layout-child-sizes-worklet.js'});
+</script>
diff --git a/testing/web-platform/tests/css/css-layout-api/child-constraints/available-size-for-percentages-htb-vrl.https.html b/testing/web-platform/tests/css/css-layout-api/child-constraints/available-size-for-percentages-htb-vrl.https.html
new file mode 100644
index 0000000000..eb104a180d
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/child-constraints/available-size-for-percentages-htb-vrl.https.html
@@ -0,0 +1,59 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#dom-layoutconstraintsoptions-availableinlinesize">
+<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#dom-layoutconstraintsoptions-availableblocksize">
+<link rel="match" href="../green-square-ref.html">
+<meta name="assert" content="This test checks that resolving percentages against the available size works as expected." />
+
+<style>
+.test {
+ writing-mode: horizontal-tb;
+ background: red;
+ width: 100px;
+}
+
+.child {
+ writing-mode: vertical-rl;
+ visibility: hidden;
+
+ --available-inline-size: 50;
+ --available-block-size: 20;
+
+ --inline-size-expected: 10px;
+ --block-size-expected: 10px;
+}
+
+@supports (display: layout(test)) {
+ .test {
+ background: green;
+ display: layout(test);
+ }
+}
+</style>
+<script src="/common/reftest-wait.js"></script>
+<script src="/common/worklet-reftest.js"></script>
+
+<div class="test">
+ <!-- A fixed width/height shouldn't be affected by the available size. -->
+ <div class="child" style="width: 10px; height: 10px;"></div>
+
+ <!-- A percentage width/height should resolve itself against the available size. -->
+ <div class="child" style="width: 20%; height: 50%;"></div>
+
+ <!-- A percentage max-width/max-height should resolve itself against the available size. -->
+ <div class="child" style="width: 15px; max-width: 20%; height: 15px; max-height: 50%;"></div>
+
+ <!-- A percentage min-width/min-height should resolve itself against the available size. -->
+ <div class="child" style="width: 5px; min-width: 20%; height: 5px; min-height: 50%;"></div>
+
+ <!-- A replaced percentage width/height should resolve itself against the available size. -->
+ <img class="child" style="width: 20%; height: 50%;" />
+
+ <!-- A replaced percentage max-width/max-height should resolve itself against the available size. -->
+ <img class="child" style="width: 15px; max-width: 20%; height: 15px; max-height: 50%;" />
+
+ <!-- A replaced percentage min-width/min-height should resolve itself against the available size. -->
+ <img class="child" style="width: 5px; min-width: 20%; height: 5px; min-height: 50%;" />
+<script>
+importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, {url: 'support/layout-child-sizes-worklet.js'});
+</script>
diff --git a/testing/web-platform/tests/css/css-layout-api/child-constraints/available-size-for-percentages-invalid.https.html b/testing/web-platform/tests/css/css-layout-api/child-constraints/available-size-for-percentages-invalid.https.html
new file mode 100644
index 0000000000..8bd969271e
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/child-constraints/available-size-for-percentages-invalid.https.html
@@ -0,0 +1,49 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#dom-layoutconstraintsoptions-availableinlinesize">
+<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#dom-layoutconstraintsoptions-availableblocksize">
+<link rel="match" href="../green-square-ref.html">
+<meta name="assert" content="This test checks that resolving percentages against an invalid available size works as expected." />
+
+<style>
+.test {
+ background: red;
+ width: 100px;
+}
+
+.child {
+ visibility: hidden;
+ width: 10px;
+ line-height: 0;
+
+ --available-inline-size: -20;
+ --available-block-size: -10;
+}
+
+.inline {
+ display: inline-block;
+ width: 10px;
+ height: 10px;
+}
+
+@supports (display: layout(test)) {
+ .test {
+ background: green;
+ display: layout(test);
+ }
+}
+</style>
+<script src="/common/reftest-wait.js"></script>
+<script src="/common/worklet-reftest.js"></script>
+
+<div class="test">
+ <!-- The available inline-size gets clamped to zero, and the available block-size gets treated as indefinite. -->
+ <div class="child" style="--inline-size-expected: 0px; --block-size-expected: 10px; width: 100%; height: 100%;">
+ <div class="inline"></div>
+ </div>
+
+ <!-- For replaced elements, both axis should be resolved to 0px. -->
+ <img class="child" style="--inline-size-expected: 0px; --block-size-expected: 0px; width: 100%; height: 100%;" />
+<script>
+importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, {url: 'support/layout-child-sizes-worklet.js'});
+</script>
diff --git a/testing/web-platform/tests/css/css-layout-api/child-constraints/available-size-for-percentages-vrl-htb.https.html b/testing/web-platform/tests/css/css-layout-api/child-constraints/available-size-for-percentages-vrl-htb.https.html
new file mode 100644
index 0000000000..ce8ff95dd0
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/child-constraints/available-size-for-percentages-vrl-htb.https.html
@@ -0,0 +1,59 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#dom-layoutconstraintsoptions-availableinlinesize">
+<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#dom-layoutconstraintsoptions-availableblocksize">
+<link rel="match" href="../green-square-ref.html">
+<meta name="assert" content="This test checks that resolving percentages against the available size works as expected." />
+
+<style>
+.test {
+ writing-mode: vertical-rl;
+ background: red;
+ height: 100px;
+}
+
+.child {
+ writing-mode: horizontal-tb;
+ visibility: hidden;
+
+ --available-inline-size: 20;
+ --available-block-size: 50;
+
+ --inline-size-expected: 10px;
+ --block-size-expected: 10px;
+}
+
+@supports (display: layout(test)) {
+ .test {
+ background: green;
+ display: layout(test);
+ }
+}
+</style>
+<script src="/common/reftest-wait.js"></script>
+<script src="/common/worklet-reftest.js"></script>
+
+<div class="test">
+ <!-- A fixed width/height shouldn't be affected by the available size. -->
+ <div class="child" style="width: 10px; height: 10px;"></div>
+
+ <!-- A percentage width/height should resolve itself against the available size. -->
+ <div class="child" style="width: 20%; height: 50%;"></div>
+
+ <!-- A percentage max-width/max-height should resolve itself against the available size. -->
+ <div class="child" style="width: 15px; max-width: 20%; height: 15px; max-height: 50%;"></div>
+
+ <!-- A percentage min-width/min-height should resolve itself against the available size. -->
+ <div class="child" style="width: 5px; min-width: 20%; height: 5px; min-height: 50%;"></div>
+
+ <!-- A replaced percentage width/height should resolve itself against the available size. -->
+ <img class="child" style="width: 20%; height: 50%;" />
+
+ <!-- A replaced percentage max-width/max-height should resolve itself against the available size. -->
+ <img class="child" style="width: 15px; max-width: 20%; height: 15px; max-height: 50%;" />
+
+ <!-- A replaced percentage min-width/min-height should resolve itself against the available size. -->
+ <img class="child" style="width: 5px; min-width: 20%; height: 5px; min-height: 50%;" />
+<script>
+importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, {url: 'support/layout-child-sizes-worklet.js'});
+</script>
diff --git a/testing/web-platform/tests/css/css-layout-api/child-constraints/available-size-for-percentages-vrl-vrl.https.html b/testing/web-platform/tests/css/css-layout-api/child-constraints/available-size-for-percentages-vrl-vrl.https.html
new file mode 100644
index 0000000000..71c7355b9c
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/child-constraints/available-size-for-percentages-vrl-vrl.https.html
@@ -0,0 +1,59 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#dom-layoutconstraintsoptions-availableinlinesize">
+<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#dom-layoutconstraintsoptions-availableblocksize">
+<link rel="match" href="../green-square-ref.html">
+<meta name="assert" content="This test checks that resolving percentages against the available size works as expected." />
+
+<style>
+.test {
+ writing-mode: vertical-rl;
+ background: red;
+ height: 100px;
+}
+
+.child {
+ writing-mode: vertical-rl;
+ visibility: hidden;
+
+ --available-inline-size: 20;
+ --available-block-size: 50;
+
+ --inline-size-expected: 10px;
+ --block-size-expected: 10px;
+}
+
+@supports (display: layout(test)) {
+ .test {
+ background: green;
+ display: layout(test);
+ }
+}
+</style>
+<script src="/common/reftest-wait.js"></script>
+<script src="/common/worklet-reftest.js"></script>
+
+<div class="test">
+ <!-- A fixed width/height shouldn't be affected by the available size. -->
+ <div class="child" style="width: 10px; height: 10px;"></div>
+
+ <!-- A percentage width/height should resolve itself against the available size. -->
+ <div class="child" style="width: 20%; height: 50%;"></div>
+
+ <!-- A percentage max-width/max-height should resolve itself against the available size. -->
+ <div class="child" style="width: 15px; max-width: 20%; height: 15px; max-height: 50%;"></div>
+
+ <!-- A percentage min-width/min-height should resolve itself against the available size. -->
+ <div class="child" style="width: 5px; min-width: 20%; height: 5px; min-height: 50%;"></div>
+
+ <!-- A replaced percentage width/height should resolve itself against the available size. -->
+ <img class="child" style="width: 20%; height: 50%;" />
+
+ <!-- A replaced percentage max-width/max-height should resolve itself against the available size. -->
+ <img class="child" style="width: 15px; max-width: 20%; height: 15px; max-height: 50%;" />
+
+ <!-- A replaced percentage min-width/min-height should resolve itself against the available size. -->
+ <img class="child" style="width: 5px; min-width: 20%; height: 5px; min-height: 50%;" />
+<script>
+importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, {url: 'support/layout-child-sizes-worklet.js'});
+</script>
diff --git a/testing/web-platform/tests/css/css-layout-api/child-constraints/fixed-block-size-vrl.https.html b/testing/web-platform/tests/css/css-layout-api/child-constraints/fixed-block-size-vrl.https.html
new file mode 100644
index 0000000000..631c5f8281
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/child-constraints/fixed-block-size-vrl.https.html
@@ -0,0 +1,60 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#dom-layoutconstraintsoptions-fixedblocksize">
+<link rel="match" href="../green-square-ref.html">
+<meta name="assert" content="This test checks that fixing the block size of children works as expected." />
+
+<style>
+.test {
+ writing-mode: vertical-rl;
+ background: red;
+ height: 100px;
+}
+
+.htb {
+ writing-mode: horizontal-tb;
+ visibility: hidden;
+ width: 3px;
+ height: 2px;
+
+ --fixed-block-size: 10;
+
+ --inline-size-expected: 2;
+ --block-size-expected: 10;
+}
+
+.vrl {
+ writing-mode: vertical-rl;
+ visibility: hidden;
+ width: 3px;
+ height: 2px;
+
+ --fixed-block-size: 10;
+
+ --inline-size-expected: 2;
+ --block-size-expected: 10;
+}
+
+@supports (display: layout(test)) {
+ .test {
+ background: green;
+ display: layout(test);
+ }
+}
+</style>
+<script src="/common/reftest-wait.js"></script>
+<script src="/common/worklet-reftest.js"></script>
+
+<div class="test">
+ <div class="htb"></div>
+ <div class="vrl"></div>
+ <!-- min/max-width should have no effect, fixedBlockSize wins. -->
+ <div class="htb" style="max-width: 5px;"></div>
+ <div class="vrl" style="max-width: 5px;"></div>
+ <div class="htb" style="min-width: 15px;"></div>
+ <div class="vrl" style="min-width: 15px;"></div>
+</div>
+
+<script>
+importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, {url: 'support/layout-child-sizes-worklet.js'});
+</script>
diff --git a/testing/web-platform/tests/css/css-layout-api/child-constraints/fixed-block-size.https.html b/testing/web-platform/tests/css/css-layout-api/child-constraints/fixed-block-size.https.html
new file mode 100644
index 0000000000..737cc4da75
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/child-constraints/fixed-block-size.https.html
@@ -0,0 +1,59 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#dom-layoutconstraintsoptions-fixedblocksize">
+<link rel="match" href="../green-square-ref.html">
+<meta name="assert" content="This test checks that fixing the block size of children works as expected." />
+
+<style>
+.test {
+ background: red;
+ width: 100px;
+}
+
+.htb {
+ writing-mode: horizontal-tb;
+ visibility: hidden;
+ width: 3px;
+ height: 2px;
+
+ --fixed-block-size: 10;
+
+ --inline-size-expected: 3;
+ --block-size-expected: 10;
+}
+
+.vrl {
+ writing-mode: vertical-rl;
+ visibility: hidden;
+ width: 3px;
+ height: 2px;
+
+ --fixed-block-size: 10;
+
+ --inline-size-expected: 3;
+ --block-size-expected: 10;
+}
+
+@supports (display: layout(test)) {
+ .test {
+ background: green;
+ display: layout(test);
+ }
+}
+</style>
+<script src="/common/reftest-wait.js"></script>
+<script src="/common/worklet-reftest.js"></script>
+
+<div class="test">
+ <div class="htb"></div>
+ <div class="vrl"></div>
+ <!-- min/max-height should have no effect, fixedBlockSize wins. -->
+ <div class="htb" style="max-height: 5px;"></div>
+ <div class="vrl" style="max-height: 5px;"></div>
+ <div class="htb" style="min-height: 15px;"></div>
+ <div class="vrl" style="min-height: 15px;"></div>
+</div>
+
+<script>
+importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, {url: 'support/layout-child-sizes-worklet.js'});
+</script>
diff --git a/testing/web-platform/tests/css/css-layout-api/child-constraints/fixed-inline-size-vrl.https.html b/testing/web-platform/tests/css/css-layout-api/child-constraints/fixed-inline-size-vrl.https.html
new file mode 100644
index 0000000000..4fc3c2e77d
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/child-constraints/fixed-inline-size-vrl.https.html
@@ -0,0 +1,60 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#dom-layoutconstraintsoptions-fixedinlinesize">
+<link rel="match" href="../green-square-ref.html">
+<meta name="assert" content="This test checks that fixing the inline size of children works as expected." />
+
+<style>
+.test {
+ writing-mode: vertical-rl;
+ background: red;
+ height: 100px;
+}
+
+.htb {
+ writing-mode: horizontal-tb;
+ visibility: hidden;
+ width: 3px;
+ height: 2px;
+
+ --fixed-inline-size: 10;
+
+ --inline-size-expected: 10;
+ --block-size-expected: 3;
+}
+
+.vrl {
+ writing-mode: vertical-rl;
+ visibility: hidden;
+ width: 3px;
+ height: 2px;
+
+ --fixed-inline-size: 10;
+
+ --inline-size-expected: 10;
+ --block-size-expected: 3;
+}
+
+@supports (display: layout(test)) {
+ .test {
+ background: green;
+ display: layout(test);
+ }
+}
+</style>
+<script src="/common/reftest-wait.js"></script>
+<script src="/common/worklet-reftest.js"></script>
+
+<div class="test">
+ <div class="htb"></div>
+ <div class="vrl"></div>
+ <!-- min/max-height should have no effect, fixedInlineSize wins. -->
+ <div class="htb" style="max-height: 5px;"></div>
+ <div class="vrl" style="max-height: 5px;"></div>
+ <div class="htb" style="min-height: 15px;"></div>
+ <div class="vrl" style="min-height: 15px;"></div>
+</div>
+
+<script>
+importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, {url: 'support/layout-child-sizes-worklet.js'});
+</script>
diff --git a/testing/web-platform/tests/css/css-layout-api/child-constraints/fixed-inline-size.https.html b/testing/web-platform/tests/css/css-layout-api/child-constraints/fixed-inline-size.https.html
new file mode 100644
index 0000000000..0fdf4aca3a
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/child-constraints/fixed-inline-size.https.html
@@ -0,0 +1,59 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#dom-layoutconstraintsoptions-fixedinlinesize">
+<link rel="match" href="../green-square-ref.html">
+<meta name="assert" content="This test checks that fixing the inline size of children works as expected." />
+
+<style>
+.test {
+ background: red;
+ width: 100px;
+}
+
+.htb {
+ writing-mode: horizontal-tb;
+ visibility: hidden;
+ width: 3px;
+ height: 2px;
+
+ --fixed-inline-size: 10;
+
+ --inline-size-expected: 10;
+ --block-size-expected: 2;
+}
+
+.vrl {
+ writing-mode: vertical-rl;
+ visibility: hidden;
+ width: 3px;
+ height: 2px;
+
+ --fixed-inline-size: 10;
+
+ --inline-size-expected: 10;
+ --block-size-expected: 2;
+}
+
+@supports (display: layout(test)) {
+ .test {
+ background: green;
+ display: layout(test);
+ }
+}
+</style>
+<script src="/common/reftest-wait.js"></script>
+<script src="/common/worklet-reftest.js"></script>
+
+<div class="test">
+ <div class="htb"></div>
+ <div class="vrl"></div>
+ <!-- min/max-width should have no effect, fixedInlineSize wins. -->
+ <div class="htb" style="max-width: 5px;"></div>
+ <div class="vrl" style="max-width: 5px;"></div>
+ <div class="htb" style="min-width: 15px;"></div>
+ <div class="vrl" style="min-width: 15px;"></div>
+</div>
+
+<script>
+importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, {url: 'support/layout-child-sizes-worklet.js'});
+</script>
diff --git a/testing/web-platform/tests/css/css-layout-api/child-constraints/percentage-size-htb-htb.https.html b/testing/web-platform/tests/css/css-layout-api/child-constraints/percentage-size-htb-htb.https.html
new file mode 100644
index 0000000000..84bda1ddf5
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/child-constraints/percentage-size-htb-htb.https.html
@@ -0,0 +1,58 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#dom-layoutconstraintsoptions-percentageblocksize">
+<link rel="match" href="../green-square-ref.html">
+<meta name="assert" content="This test checks that setting the percentage block-size of children works as expected." />
+
+<style>
+.test {
+ writing-mode: horizontal-tb;
+ background: red;
+ width: 100px;
+}
+
+.child {
+ writing-mode: horizontal-tb;
+ visibility: hidden;
+ width: 10px;
+
+ --percentage-block-size: 20;
+
+ --inline-size-expected: 10px;
+ --block-size-expected: 10px;
+}
+
+@supports (display: layout(test)) {
+ .test {
+ background: green;
+ display: layout(test);
+ }
+}
+</style>
+<script src="/common/reftest-wait.js"></script>
+<script src="/common/worklet-reftest.js"></script>
+
+<div class="test">
+ <!-- A fixed height shouldn't be affected by the percentage size. -->
+ <div class="child" style="height: 10px;"></div>
+
+ <!-- A percentage height should resolve itself against the percentageBlockSize. -->
+ <div class="child" style="height: 50%;"></div>
+
+ <!-- A percentage max-height should resolve itself against the percentageBlockSize. -->
+ <div class="child" style="height: 15px; max-height: 50%;"></div>
+
+ <!-- A percentage min-height should resolve itself against the percentageBlockSize. -->
+ <div class="child" style="height: 5px; min-height: 50%;"></div>
+
+ <!-- A replaced percentage height should resolve itself against the percentageBlockSize. -->
+ <img class="child" style="height: 50%;" />
+
+ <!-- A replaced percentage max-height should resolve itself against the percentageBlockSize. -->
+ <img class="child" style="height: 15px; max-height: 50%;" />
+
+ <!-- A replaced percentage min-height should resolve itself against the percentageBlockSize. -->
+ <img class="child" style="height: 5px; min-height: 50%;" />
+<script>
+importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, {url: 'support/layout-child-sizes-worklet.js'});
+</script>
diff --git a/testing/web-platform/tests/css/css-layout-api/child-constraints/percentage-size-htb-vrl.https.html b/testing/web-platform/tests/css/css-layout-api/child-constraints/percentage-size-htb-vrl.https.html
new file mode 100644
index 0000000000..98d285b015
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/child-constraints/percentage-size-htb-vrl.https.html
@@ -0,0 +1,58 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#dom-layoutconstraintsoptions-percentageinlinesize">
+<link rel="match" href="../green-square-ref.html">
+<meta name="assert" content="This test checks that setting the percentage inline-size of children works as expected." />
+
+<style>
+.test {
+ writing-mode: horizontal-tb;
+ background: red;
+ width: 100px;
+}
+
+.child {
+ writing-mode: vertical-rl;
+ visibility: hidden;
+ height: 10px;
+
+ --percentage-inline-size: 20;
+
+ --inline-size-expected: 10px;
+ --block-size-expected: 10px;
+}
+
+@supports (display: layout(test)) {
+ .test {
+ background: green;
+ display: layout(test);
+ }
+}
+</style>
+<script src="/common/reftest-wait.js"></script>
+<script src="/common/worklet-reftest.js"></script>
+
+<div class="test">
+ <!-- A fixed width shouldn't be affected by the percentage size. -->
+ <div class="child" style="width: 10px;"></div>
+
+ <!-- A percentage width should resolve itself against the percentageInlineSize. -->
+ <div class="child" style="width: 50%;"></div>
+
+ <!-- A percentage max-width should resolve itself against the percentageInlineSize. -->
+ <div class="child" style="width: 15px; max-width: 50%;"></div>
+
+ <!-- A percentage min-width should resolve itself against the percentageInlineSize. -->
+ <div class="child" style="width: 5px; min-width: 50%;"></div>
+
+ <!-- A replaced percentage width should resolve itself against the percentageInlineSize. -->
+ <img class="child" style="width: 50%;" />
+
+ <!-- A replaced percentage max-width should resolve itself against the percentageInlineSize. -->
+ <img class="child" style="width: 15px; max-width: 50%;" />
+
+ <!-- A replaced percentage min-width should resolve itself against the percentageInlineSize. -->
+ <img class="child" style="width: 5px; min-width: 50%;" />
+<script>
+importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, {url: 'support/layout-child-sizes-worklet.js'});
+</script>
diff --git a/testing/web-platform/tests/css/css-layout-api/child-constraints/percentage-size-invalid.https.html b/testing/web-platform/tests/css/css-layout-api/child-constraints/percentage-size-invalid.https.html
new file mode 100644
index 0000000000..0435535552
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/child-constraints/percentage-size-invalid.https.html
@@ -0,0 +1,47 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#dom-layoutconstraintsoptions-percentageblocksize">
+<link rel="match" href="../green-square-ref.html">
+<meta name="assert" content="This test checks that setting an invalid percentage block-size of children works as expected." />
+
+<style>
+.test {
+ background: red;
+ width: 100px;
+}
+
+.child {
+ visibility: hidden;
+ width: 10px;
+ line-height: 0;
+
+ --percentage-block-size: -10;
+}
+
+.inline {
+ display: inline-block;
+ width: 10px;
+ height: 10px;
+}
+
+@supports (display: layout(test)) {
+ .test {
+ background: green;
+ display: layout(test);
+ }
+}
+</style>
+<script src="/common/reftest-wait.js"></script>
+<script src="/common/worklet-reftest.js"></script>
+
+<div class="test">
+ <!-- A percentage shouldn't be resolved against an invalid percentageBlockSize. -->
+ <div class="child" style="--inline-size-expected: 10px; --block-size-expected: 10px; height: 100%;">
+ <div class="inline"></div>
+ </div>
+
+ <!-- A percentage shouldn't be resolved against an invalid percentageBlockSize. -->
+ <img class="child" style="--inline-size-expected: 10px; --block-size-expected: 0px; height: 100%;" />
+<script>
+importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, {url: 'support/layout-child-sizes-worklet.js'});
+</script>
diff --git a/testing/web-platform/tests/css/css-layout-api/child-constraints/percentage-size-quirks-mode.https.html b/testing/web-platform/tests/css/css-layout-api/child-constraints/percentage-size-quirks-mode.https.html
new file mode 100644
index 0000000000..527149b67a
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/child-constraints/percentage-size-quirks-mode.https.html
@@ -0,0 +1,55 @@
+<html class=reftest-wait>
+<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#dom-layoutconstraintsoptions-percentageblocksize">
+<link rel="match" href="../green-square-ref.html">
+<meta name="assert" content="This test checks that setting a percentage block-size works correctly in quirks mode." />
+
+<style>
+.container {
+ height: 200px;
+}
+
+.test {
+ background: red;
+ width: 100px;
+}
+
+.child {
+ visibility: hidden;
+ width: 10px;
+ line-height: 0;
+}
+
+.inline {
+ display: inline-block;
+ width: 10px;
+ height: 10px;
+}
+
+@supports (display: layout(test)) {
+ .test {
+ background: green;
+ display: layout(test);
+ }
+}
+</style>
+<script src="/common/reftest-wait.js"></script>
+<script src="/common/worklet-reftest.js"></script>
+
+<div class="container">
+ <div class="test">
+ <!-- TODO explain. -->
+ <div class="child" style="--percentage-block-size: 50px; --inline-size-expected: 10px; --block-size-expected: 10px;">
+ <div style="height: 20%"></div>
+ </div>
+
+ <!-- TODO explain. -->
+ <div class="child" style="--inline-size-expected: 10px; --block-size-expected: 10px;">
+ <div style="height: 100%">
+ <div class="inline"></div>
+ </div>
+ </div>
+ </div>
+</div>
+<script>
+importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, {url: 'support/layout-child-sizes-worklet.js'});
+</script>
diff --git a/testing/web-platform/tests/css/css-layout-api/child-constraints/percentage-size-vrl-htb.https.html b/testing/web-platform/tests/css/css-layout-api/child-constraints/percentage-size-vrl-htb.https.html
new file mode 100644
index 0000000000..2d3d496fa5
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/child-constraints/percentage-size-vrl-htb.https.html
@@ -0,0 +1,58 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#dom-layoutconstraintsoptions-percentageinlinesize">
+<link rel="match" href="../green-square-ref.html">
+<meta name="assert" content="This test checks that setting the percentage inline-size of children works as expected." />
+
+<style>
+.test {
+ writing-mode: vertical-rl;
+ background: red;
+ height: 100px;
+}
+
+.child {
+ writing-mode: horizontal-tb;
+ visibility: hidden;
+ width: 10px;
+
+ --percentage-inline-size: 20;
+
+ --inline-size-expected: 10px;
+ --block-size-expected: 10px;
+}
+
+@supports (display: layout(test)) {
+ .test {
+ background: green;
+ display: layout(test);
+ }
+}
+</style>
+<script src="/common/reftest-wait.js"></script>
+<script src="/common/worklet-reftest.js"></script>
+
+<div class="test">
+ <!-- A fixed height shouldn't be affected by the percentage size. -->
+ <div class="child" style="height: 10px;"></div>
+
+ <!-- A percentage height should resolve itself against the percentageInlineSize. -->
+ <div class="child" style="height: 50%;"></div>
+
+ <!-- A percentage max-height should resolve itself against the percentageInlineSize. -->
+ <div class="child" style="height: 15px; max-height: 50%;"></div>
+
+ <!-- A percentage min-height should resolve itself against the percentageInlineSize. -->
+ <div class="child" style="height: 5px; min-height: 50%;"></div>
+
+ <!-- A replaced percentage height should resolve itself against the percentageInlineSize. -->
+ <img class="child" style="height: 50%;" />
+
+ <!-- A replaced percentage max-height should resolve itself against the percentageInlineSize. -->
+ <img class="child" style="height: 15px; max-height: 50%;" />
+
+ <!-- A replaced percentage min-height should resolve itself against the percentageInlineSize. -->
+ <img class="child" style="height: 5px; min-height: 50%;" />
+<script>
+importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, {url: 'support/layout-child-sizes-worklet.js'});
+</script>
diff --git a/testing/web-platform/tests/css/css-layout-api/child-constraints/percentage-size-vrl-vrl.https.html b/testing/web-platform/tests/css/css-layout-api/child-constraints/percentage-size-vrl-vrl.https.html
new file mode 100644
index 0000000000..577b98ad98
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/child-constraints/percentage-size-vrl-vrl.https.html
@@ -0,0 +1,58 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#dom-layoutconstraintsoptions-percentageblocksize">
+<link rel="match" href="../green-square-ref.html">
+<meta name="assert" content="This test checks that setting the percentage block-size of children works as expected." />
+
+<style>
+.test {
+ writing-mode: vertical-rl;
+ background: red;
+ height: 100px;
+}
+
+.child {
+ writing-mode: vertical-rl;
+ visibility: hidden;
+ height: 10px;
+
+ --percentage-block-size: 20;
+
+ --inline-size-expected: 10px;
+ --block-size-expected: 10px;
+}
+
+@supports (display: layout(test)) {
+ .test {
+ background: green;
+ display: layout(test);
+ }
+}
+</style>
+<script src="/common/reftest-wait.js"></script>
+<script src="/common/worklet-reftest.js"></script>
+
+<div class="test">
+ <!-- A fixed width shouldn't be affected by the percentage size. -->
+ <div class="child" style="width: 10px;"></div>
+
+ <!-- A percentage width should resolve itself against the percentageBlockSize. -->
+ <div class="child" style="width: 50%;"></div>
+
+ <!-- A percentage max-width should resolve itself against the percentageBlockSize. -->
+ <div class="child" style="width: 15px; max-width: 50%;"></div>
+
+ <!-- A percentage min-width should resolve itself against the percentageBlockSize. -->
+ <div class="child" style="width: 5px; min-width: 50%;"></div>
+
+ <!-- A replaced percentage width should resolve itself against the percentageBlockSize. -->
+ <img class="child" style="width: 50%;" />
+
+ <!-- A replaced percentage max-width should resolve itself against the percentageBlockSize. -->
+ <img class="child" style="width: 15px; max-width: 50%;" />
+
+ <!-- A replaced percentage min-width should resolve itself against the percentageBlockSize. -->
+ <img class="child" style="width: 5px; min-width: 50%;" />
+<script>
+importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, {url: 'support/layout-child-sizes-worklet.js'});
+</script>
diff --git a/testing/web-platform/tests/css/css-layout-api/child-constraints/support/layout-child-sizes-worklet.js b/testing/web-platform/tests/css/css-layout-api/child-constraints/support/layout-child-sizes-worklet.js
new file mode 100644
index 0000000000..5956c9a70c
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/child-constraints/support/layout-child-sizes-worklet.js
@@ -0,0 +1,67 @@
+import {areArraysEqual} from '/common/arrays.js';
+
+function parseNumber(value) {
+ const num = parseInt(value.toString());
+ if (isNaN(num)) return undefined;
+ return num;
+}
+
+registerLayout('test', class {
+ static get childInputProperties() {
+ return [
+ '--available-inline-size',
+ '--available-block-size',
+ '--fixed-inline-size',
+ '--fixed-block-size',
+ '--percentage-inline-size',
+ '--percentage-block-size',
+ '--inline-size-expected',
+ '--block-size-expected'
+ ];
+ }
+
+ async intrinsicSizes() {}
+ async layout(children, edges, constraints, styleMap) {
+ const childFragments = await Promise.all(children.map((child) => {
+ const childConstraints = {};
+ const availableInlineSize = parseNumber(child.styleMap.get('--available-inline-size'));
+ const availableBlockSize = parseNumber(child.styleMap.get('--available-block-size'));
+ const fixedInlineSize = parseNumber(child.styleMap.get('--fixed-inline-size'));
+ const fixedBlockSize = parseNumber(child.styleMap.get('--fixed-block-size'));
+ const percentageInlineSize = parseNumber(child.styleMap.get('--percentage-inline-size'));
+ const percentageBlockSize = parseNumber(child.styleMap.get('--percentage-block-size'));
+ return child.layoutNextFragment({
+ availableInlineSize,
+ availableBlockSize,
+ fixedInlineSize,
+ fixedBlockSize,
+ percentageInlineSize,
+ percentageBlockSize,
+ });
+ }));
+
+ const actual = childFragments.map((childFragment) => {
+ return {
+ inlineSize: childFragment.inlineSize,
+ blockSize: childFragment.blockSize,
+ };
+ });
+
+ const expected = children.map((child) => {
+ return {
+ inlineSize: parseInt(child.styleMap.get('--inline-size-expected').toString()),
+ blockSize: parseInt(child.styleMap.get('--block-size-expected').toString()),
+ };
+ });
+
+ const equalityFunc = (a, b) => {
+ return a.inlineSize == b.inlineSize && a.blockSize == b.blockSize;
+ };
+
+ if (!areArraysEqual(expected, actual, equalityFunc)) {
+ return {autoBlockSize: 0, childFragments};
+ }
+
+ return {autoBlockSize: 100, childFragments};
+ }
+});
diff --git a/testing/web-platform/tests/css/css-layout-api/chrome-bug-1287843-000-crash.https.html b/testing/web-platform/tests/css/css-layout-api/chrome-bug-1287843-000-crash.https.html
new file mode 100644
index 0000000000..6137eba6dc
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/chrome-bug-1287843-000-crash.https.html
@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org">
+<link rel="help" href="https://bugs.chromium.org/p/chromium/issues/detail?id=1287843">
+<div style="columns:2;">
+ <div style="display:layout(foo);">
+ <div>
+ <div style="display:inline-table;">
+ <div style="display:table-row;"></div>
+ </div>
+ </div>
+ </div>
+</div>
diff --git a/testing/web-platform/tests/css/css-layout-api/chrome-bug-1287843-001-crash.https.html b/testing/web-platform/tests/css/css-layout-api/chrome-bug-1287843-001-crash.https.html
new file mode 100644
index 0000000000..ac8c6ecf1a
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/chrome-bug-1287843-001-crash.https.html
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org">
+<link rel="help" href="https://bugs.chromium.org/p/chromium/issues/detail?id=1287843">
+<div style="columns:2;">
+ <div style="display:layout(foo);">
+ <div>
+ <div style="display:inline-table;">
+ <div style="display:table-row;">
+ <div style="columns:2;">
+ <div style="display:inline-table;">
+ <div style="display:table-row;"></div>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+</div>
diff --git a/testing/web-platform/tests/css/css-layout-api/chrome-bug-1291449-crash.https.html b/testing/web-platform/tests/css/css-layout-api/chrome-bug-1291449-crash.https.html
new file mode 100644
index 0000000000..d13fed0179
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/chrome-bug-1291449-crash.https.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org">
+<link rel="help" href="https://bugs.chromium.org/p/chromium/issues/detail?id=1291449">
+<div style="columns:2;">
+ <div style="display:flex;"></div>
+ <div style="display:grid;"></div>
+ <div style="display:table;"></div>
+ <div style="display:layout(foo);">
+ <div style="columns:2;"></div>
+ </div>
+</div>
diff --git a/testing/web-platform/tests/css/css-layout-api/chrome-bug-1296664-crash.https.html b/testing/web-platform/tests/css/css-layout-api/chrome-bug-1296664-crash.https.html
new file mode 100644
index 0000000000..9e523fb181
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/chrome-bug-1296664-crash.https.html
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org">
+<link rel="help" href="https://bugs.chromium.org/p/chromium/issues/detail?id=1296664">
+<div id="container">
+ <div style="position:relative; margin-top:8px;">
+ <div style="display:layout(foo); position:absolute; width:100px; height:100px;"></div>
+ <div style="column-span:all;"></div>
+ </div>
+ <span style="columns:1;">
+ <div style="display:flex;"></div>
+ <div style="display:grid;"></div>
+ <div style="display:table;"></div>
+ </span>
+</div>
+<script>
+ document.body.offsetTop;
+ container.style.columns = "1";
+</script>
diff --git a/testing/web-platform/tests/css/css-layout-api/computed-style-layout-function.https.html b/testing/web-platform/tests/css/css-layout-api/computed-style-layout-function.https.html
new file mode 100644
index 0000000000..d115009c6c
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/computed-style-layout-function.https.html
@@ -0,0 +1,50 @@
+<!DOCTYPE html>
+<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#valdef-display-layout">
+<meta name="assert" content="This test checks that a layout() function parses correctly and serializes correctly from computed style." />
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<style>
+#test1 { display: layout(test1); }
+#test2 { display: layout(); }
+#test3 { display: layout(test3, invalid); }
+#test4 { --display: layout(test4); display: var(--display); }
+</style>
+
+<div id=test1></div>
+<div id=test2></div>
+<div id=test3></div>
+<div id=test4></div>
+<div id=test5></div>
+<script>
+test(function() {
+ const test1 = document.getElementById('test1');
+ assert_equals(getComputedStyle(test1).display, 'layout(test1)');
+});
+
+test(function() {
+ // layout() should fail to parse.
+ const test2 = document.getElementById('test2');
+ assert_equals(getComputedStyle(test2).display, 'block');
+});
+
+test(function() {
+ // layout(test3, invalid) should fail to parse.
+ const test3 = document.getElementById('test3');
+ assert_equals(getComputedStyle(test3).display, 'block');
+});
+
+test(function() {
+ // Setting via a custom property should work.
+ const test4 = document.getElementById('test4');
+ assert_equals(getComputedStyle(test4).display, 'layout(test4)');
+});
+
+test(function() {
+ // Setting the inline style should reflect in the computed style.
+ const test5 = document.getElementById('test5');
+ assert_equals(getComputedStyle(test5).display, 'block');
+
+ test5.style.display = 'layout(test5)';
+ assert_equals(getComputedStyle(test5).display, 'layout(test5)');
+});
+</script>
diff --git a/testing/web-platform/tests/css/css-layout-api/constraints-data-function-failure.https.html b/testing/web-platform/tests/css/css-layout-api/constraints-data-function-failure.https.html
new file mode 100644
index 0000000000..2d5e5240d7
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/constraints-data-function-failure.https.html
@@ -0,0 +1,61 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#dom-layoutconstraints-data">
+<link rel="match" href="green-square-ref.html">
+<meta name="assert" content="This test checks that a function can't be passed to a child layout." />
+<style>
+.test {
+ background: red;
+ width: 100px;
+}
+
+@supports (display: layout(parent)) {
+ .test {
+ display: layout(parent);
+ background: green;
+ }
+
+ .child {
+ display: layout(child);
+ }
+}
+</style>
+<script src="/common/reftest-wait.js"></script>
+<script src="/common/worklet-reftest.js"></script>
+
+<div class="test">
+ <div class="child"></div>
+</div>
+
+<script id="code" type="text/worklet">
+registerLayout('parent', class {
+ async intrinsicSizes() {}
+ async layout([child], edges, constraints, styleMap) {
+ let childFragment = null;
+
+ try {
+ childFragment = await child.layoutNextFragment({
+ data: { fn: function() {} }
+ });
+ } catch(e) {
+ // Success! The structured cloning algorithm should have thrown an error.
+ childFragment = await child.layoutNextFragment({});
+ return {autoBlockSize: 100, childFragments: [childFragment]};
+ }
+
+ return {autoBlockSize: 0, childFragments: [childFragment]};
+ }
+});
+
+registerLayout('child', class {
+ async intrinsicSizes() {}
+ async layout() {
+ return {autoBlockSize: 0};
+ }
+});
+</script>
+
+<script>
+importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, document.getElementById('code').textContent);
+</script>
+</html>
diff --git a/testing/web-platform/tests/css/css-layout-api/constraints-data-sab-failure.https.html b/testing/web-platform/tests/css/css-layout-api/constraints-data-sab-failure.https.html
new file mode 100644
index 0000000000..b8df61c73d
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/constraints-data-sab-failure.https.html
@@ -0,0 +1,62 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#dom-layoutconstraints-data">
+<link rel="match" href="green-square-ref.html">
+<meta name="assert" content="This test checks that a SharedArrayBuffer can't be passed to a child layout." />
+<style>
+.test {
+ background: red;
+ width: 100px;
+}
+
+@supports (display: layout(parent)) {
+ .test {
+ display: layout(parent);
+ background: green;
+ }
+
+ .child {
+ display: layout(child);
+ }
+}
+</style>
+<script src="/common/reftest-wait.js"></script>
+<script src="/common/worklet-reftest.js"></script>
+
+<div class="test">
+ <div class="child"></div>
+</div>
+
+<script id="code" type="text/worklet">
+registerLayout('parent', class {
+ async intrinsicSizes() {}
+ async layout([child], edges, constraints, styleMap) {
+ let childFragment = null;
+
+ try {
+ childFragment = await child.layoutNextFragment({
+ // See https://github.com/whatwg/html/issues/5380 for why not `new SharedArrayBuffer()`
+ data: { sab: new WebAssembly.Memory({ shared:true, initial:1, maximum:1 }).buffer }
+ });
+ } catch(e) {
+ // Success! The structured cloning algorithm should have thrown an error.
+ childFragment = await child.layoutNextFragment({});
+ return {autoBlockSize: 100, childFragments: [childFragment]};
+ }
+
+ return {autoBlockSize: 0, childFragments: [childFragment]};
+ }
+});
+
+registerLayout('child', class {
+ async intrinsicSizes() {}
+ async layout() {
+ return {autoBlockSize: 0};
+ }
+});
+</script>
+
+<script>
+importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, document.getElementById('code').textContent);
+</script>
+</html>
diff --git a/testing/web-platform/tests/css/css-layout-api/constraints-data.https.html b/testing/web-platform/tests/css/css-layout-api/constraints-data.https.html
new file mode 100644
index 0000000000..4bea061917
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/constraints-data.https.html
@@ -0,0 +1,69 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#dom-layoutconstraints-data">
+<link rel="match" href="green-square-ref.html">
+<meta name="assert" content="This test checks that passing data to a child layout works correctly." />
+<style>
+.test {
+ background: red;
+ width: 100px;
+}
+
+@supports (display: layout(parent)) {
+ .test {
+ display: layout(parent);
+ background: green;
+ }
+
+ .child {
+ display: layout(child);
+ }
+}
+</style>
+<script src="/common/reftest-wait.js"></script>
+<script src="/common/worklet-reftest.js"></script>
+
+<div class="test">
+ <div class="child"></div>
+</div>
+
+<script id="code" type="text/worklet">
+const DATA = {
+ str: 'hello',
+ num: 42,
+ obj: {str2: 'world'},
+};
+
+registerLayout('parent', class {
+ async intrinsicSizes() {}
+ async layout([child], edges, constraints, styleMap) {
+
+ const childFragment = await child.layoutNextFragment({data: DATA});
+
+ // If the child's block-size is 100 the structured cloning worked.
+ if (childFragment.blockSize === 100) {
+ return {autoBlockSize: 100, childFragments: [childFragment]};
+ }
+
+ return {autoBlockSize: 0, childFragments: [childFragment]};
+ }
+});
+
+registerLayout('child', class {
+ async intrinsicSizes() {}
+ async layout(children, edges, constraints, styleMap) {
+ // Use JSON.stringify to make sure the structured cloning worked.
+ if (constraints.data !== DATA &&
+ JSON.stringify(constraints.data) === JSON.stringify(DATA)) {
+ return {autoBlockSize: 100};
+ }
+
+ return {autoBlockSize: 0};
+ }
+});
+</script>
+
+<script>
+importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, document.getElementById('code').textContent);
+</script>
+</html>
diff --git a/testing/web-platform/tests/css/css-layout-api/constraints/fixed-block-size-absolute-left-right-vrl.https.html b/testing/web-platform/tests/css/css-layout-api/constraints/fixed-block-size-absolute-left-right-vrl.https.html
new file mode 100644
index 0000000000..8e177dbf33
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/constraints/fixed-block-size-absolute-left-right-vrl.https.html
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#dom-layoutconstraints-fixedblocksize">
+<link rel="match" href="../green-square-ref.html">
+<meta name="assert" content="This test checks that LayoutConstraints#fixedBlockSize is passed into the layout function correctly." />
+<style>
+body {
+ position: relative;
+ width: 120px;
+}
+
+.test {
+ writing-mode: vertical-rl;
+ background: red;
+ position: absolute;
+ left: 0px;
+ right: 20px;
+ --expected-block-size: 100;
+}
+
+.child {
+ background: green;
+}
+
+@supports (display: layout(test)) {
+ .test {
+ display: layout(test);
+ }
+}
+</style>
+<script src="/common/reftest-wait.js"></script>
+<script src="/common/worklet-reftest.js"></script>
+
+<div class="test">
+ <div class="child"></div>
+</div>
+
+<script>
+importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, {url: 'support/constraints-fixed-block-size.js'});
+</script>
diff --git a/testing/web-platform/tests/css/css-layout-api/constraints/fixed-block-size-absolute-none.https.html b/testing/web-platform/tests/css/css-layout-api/constraints/fixed-block-size-absolute-none.https.html
new file mode 100644
index 0000000000..7b10f11d7d
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/constraints/fixed-block-size-absolute-none.https.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#dom-layoutconstraints-fixedblocksize">
+<link rel="match" href="../green-square-ref.html">
+<meta name="assert" content="This test checks that LayoutConstraints#fixedBlockSize is passed into the layout function correctly." />
+<style>
+body {
+ position: relative;
+}
+
+.test {
+ background: red;
+ position: absolute;
+ --expected-block-size: null;
+}
+
+.child {
+ background: green;
+}
+
+@supports (display: layout(test)) {
+ .test {
+ display: layout(test);
+ }
+}
+</style>
+<script src="/common/reftest-wait.js"></script>
+<script src="/common/worklet-reftest.js"></script>
+
+<div class="test">
+ <div class="child"></div>
+</div>
+
+<script>
+importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, {url: 'support/constraints-fixed-block-size.js'});
+</script>
diff --git a/testing/web-platform/tests/css/css-layout-api/constraints/fixed-block-size-absolute-top-bottom.https.html b/testing/web-platform/tests/css/css-layout-api/constraints/fixed-block-size-absolute-top-bottom.https.html
new file mode 100644
index 0000000000..73c29000cf
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/constraints/fixed-block-size-absolute-top-bottom.https.html
@@ -0,0 +1,39 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#dom-layoutconstraints-fixedblocksize">
+<link rel="match" href="../green-square-ref.html">
+<meta name="assert" content="This test checks that LayoutConstraints#fixedBlockSize is passed into the layout function correctly." />
+<style>
+body {
+ position: relative;
+ height: 120px;
+}
+
+.test {
+ background: red;
+ position: absolute;
+ top: 0px;
+ bottom: 20px;
+ --expected-block-size: 100;
+}
+
+.child {
+ background: green;
+}
+
+@supports (display: layout(test)) {
+ .test {
+ display: layout(test);
+ }
+}
+</style>
+<script src="/common/reftest-wait.js"></script>
+<script src="/common/worklet-reftest.js"></script>
+
+<div class="test">
+ <div class="child"></div>
+</div>
+
+<script>
+importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, {url: 'support/constraints-fixed-block-size.js'});
+</script>
diff --git a/testing/web-platform/tests/css/css-layout-api/constraints/fixed-block-size-block-none-vrl.https.html b/testing/web-platform/tests/css/css-layout-api/constraints/fixed-block-size-block-none-vrl.https.html
new file mode 100644
index 0000000000..704b66d64a
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/constraints/fixed-block-size-block-none-vrl.https.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#dom-layoutconstraints-fixedblocksize">
+<link rel="match" href="../green-square-ref.html">
+<meta name="assert" content="This test checks that LayoutConstraints#fixedBlockSize is passed into the layout function correctly." />
+<style>
+.test {
+ writing-mode: vertical-lr;
+ background: red;
+ --expected-block-size: null;
+}
+
+.child {
+ background: green;
+}
+
+@supports (display: layout(test)) {
+ .test {
+ display: layout(test);
+ }
+}
+</style>
+<script src="/common/reftest-wait.js"></script>
+<script src="/common/worklet-reftest.js"></script>
+
+<div class="test">
+ <div class="child"></div>
+</div>
+
+<script>
+importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, {url: 'support/constraints-fixed-block-size.js'});
+</script>
diff --git a/testing/web-platform/tests/css/css-layout-api/constraints/fixed-block-size-block-none.https.html b/testing/web-platform/tests/css/css-layout-api/constraints/fixed-block-size-block-none.https.html
new file mode 100644
index 0000000000..6c023f5162
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/constraints/fixed-block-size-block-none.https.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#dom-layoutconstraints-fixedblocksize">
+<link rel="match" href="../green-square-ref.html">
+<meta name="assert" content="This test checks that LayoutConstraints#fixedBlockSize is passed into the layout function correctly." />
+<style>
+.test {
+ background: red;
+ --expected-block-size: null;
+ width: 100px;
+}
+
+.child {
+ background: green;
+}
+
+@supports (display: layout(test)) {
+ .test {
+ display: layout(test);
+ }
+}
+</style>
+<script src="/common/reftest-wait.js"></script>
+<script src="/common/worklet-reftest.js"></script>
+
+<div class="test">
+ <div class="child"></div>
+</div>
+
+<script>
+importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, {url: 'support/constraints-fixed-block-size.js'});
+</script>
diff --git a/testing/web-platform/tests/css/css-layout-api/constraints/fixed-block-size-fixed-max.https.html b/testing/web-platform/tests/css/css-layout-api/constraints/fixed-block-size-fixed-max.https.html
new file mode 100644
index 0000000000..8af6afde26
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/constraints/fixed-block-size-fixed-max.https.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#dom-layoutconstraints-fixedblocksize">
+<link rel="match" href="../green-square-ref.html">
+<meta name="assert" content="This test checks that LayoutConstraints#fixedBlockSize is passed into the layout function correctly." />
+<style>
+.test {
+ background: red;
+ --expected-block-size: 30;
+ width: 100px;
+ height: 60px;
+ max-height: 30px;
+}
+
+.child {
+ background: green;
+}
+
+@supports (display: layout(test)) {
+ .test {
+ display: layout(test);
+ }
+}
+</style>
+<script src="/common/reftest-wait.js"></script>
+<script src="/common/worklet-reftest.js"></script>
+
+<div class="test">
+ <div class="child"></div>
+</div>
+
+<script>
+importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, {url: 'support/constraints-fixed-block-size.js'});
+</script>
diff --git a/testing/web-platform/tests/css/css-layout-api/constraints/fixed-block-size-fixed-min.https.html b/testing/web-platform/tests/css/css-layout-api/constraints/fixed-block-size-fixed-min.https.html
new file mode 100644
index 0000000000..4d76ed9785
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/constraints/fixed-block-size-fixed-min.https.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#dom-layoutconstraints-fixedblocksize">
+<link rel="match" href="../green-square-ref.html">
+<meta name="assert" content="This test checks that LayoutConstraints#fixedBlockSize is passed into the layout function correctly." />
+<style>
+.test {
+ background: red;
+ --expected-block-size: 70;
+ width: 100px;
+ height: 60px;
+ min-height: 70px;
+}
+
+.child {
+ background: green;
+}
+
+@supports (display: layout(test)) {
+ .test {
+ display: layout(test);
+ }
+}
+</style>
+<script src="/common/reftest-wait.js"></script>
+<script src="/common/worklet-reftest.js"></script>
+
+<div class="test">
+ <div class="child"></div>
+</div>
+
+<script>
+importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, {url: 'support/constraints-fixed-block-size.js'});
+</script>
diff --git a/testing/web-platform/tests/css/css-layout-api/constraints/fixed-block-size-fixed-vrl.https.html b/testing/web-platform/tests/css/css-layout-api/constraints/fixed-block-size-fixed-vrl.https.html
new file mode 100644
index 0000000000..bbc0a2fde8
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/constraints/fixed-block-size-fixed-vrl.https.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#dom-layoutconstraints-fixedblocksize">
+<link rel="match" href="../green-square-ref.html">
+<meta name="assert" content="This test checks that LayoutConstraints#fixedBlockSize is passed into the layout function correctly." />
+<style>
+.test {
+ writing-mode: vertical-rl;
+ background: red;
+ --expected-block-size: 100;
+ width: 100px;
+}
+
+.child {
+ background: green;
+}
+
+@supports (display: layout(test)) {
+ .test {
+ display: layout(test);
+ }
+}
+</style>
+<script src="/common/reftest-wait.js"></script>
+<script src="/common/worklet-reftest.js"></script>
+
+<div class="test">
+ <div class="child"></div>
+</div>
+
+<script>
+importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, {url: 'support/constraints-fixed-block-size.js'});
+</script>
diff --git a/testing/web-platform/tests/css/css-layout-api/constraints/fixed-block-size-fixed.https.html b/testing/web-platform/tests/css/css-layout-api/constraints/fixed-block-size-fixed.https.html
new file mode 100644
index 0000000000..45376ac295
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/constraints/fixed-block-size-fixed.https.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#dom-layoutconstraints-fixedblocksize">
+<link rel="match" href="../green-square-ref.html">
+<meta name="assert" content="This test checks that LayoutConstraints#fixedBlockSize is passed into the layout function correctly." />
+<style>
+.test {
+ background: red;
+ --expected-block-size: 60;
+ width: 100px;
+ height: 60px;
+}
+
+.child {
+ background: green;
+}
+
+@supports (display: layout(test)) {
+ .test {
+ display: layout(test);
+ }
+}
+</style>
+<script src="/common/reftest-wait.js"></script>
+<script src="/common/worklet-reftest.js"></script>
+
+<div class="test">
+ <div class="child"></div>
+</div>
+
+<script>
+importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, {url: 'support/constraints-fixed-block-size.js'});
+</script>
diff --git a/testing/web-platform/tests/css/css-layout-api/constraints/fixed-block-size-flex-basis-vrl.https.html b/testing/web-platform/tests/css/css-layout-api/constraints/fixed-block-size-flex-basis-vrl.https.html
new file mode 100644
index 0000000000..25fc685a67
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/constraints/fixed-block-size-flex-basis-vrl.https.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#dom-layoutconstraints-fixedblocksize">
+<link rel="match" href="../green-square-ref.html">
+<meta name="assert" content="This test checks that LayoutConstraints#fixedBlockSize is passed into the layout function correctly." />
+<style>
+body {
+ display: flex;
+}
+
+.test {
+ writing-mode: vertical-rl;
+ background: red;
+ --expected-block-size: 100;
+ flex-basis: 100px;
+}
+
+.child {
+ background: green;
+}
+
+@supports (display: layout(test)) {
+ .test {
+ display: layout(test);
+ }
+}
+</style>
+<script src="/common/reftest-wait.js"></script>
+<script src="/common/worklet-reftest.js"></script>
+
+<div class="test">
+ <div class="child"></div>
+</div>
+
+<script>
+importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, {url: 'support/constraints-fixed-block-size.js'});
+</script>
diff --git a/testing/web-platform/tests/css/css-layout-api/constraints/fixed-block-size-flex-column-basis.https.html b/testing/web-platform/tests/css/css-layout-api/constraints/fixed-block-size-flex-column-basis.https.html
new file mode 100644
index 0000000000..8df99ee835
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/constraints/fixed-block-size-flex-column-basis.https.html
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#dom-layoutconstraints-fixedblocksize">
+<link rel="match" href="../green-square-ref.html">
+<meta name="assert" content="This test checks that LayoutConstraints#fixedBlockSize is passed into the layout function correctly." />
+<style>
+body {
+ display: flex;
+ flex-direction: column;
+ width: 100px;
+}
+
+.test {
+ background: red;
+ --expected-block-size: 60;
+ flex-basis: 60px;
+}
+
+.child {
+ background: green;
+}
+
+@supports (display: layout(test)) {
+ .test {
+ display: layout(test);
+ }
+}
+</style>
+<script src="/common/reftest-wait.js"></script>
+<script src="/common/worklet-reftest.js"></script>
+
+<div class="test">
+ <div class="child"></div>
+</div>
+
+<script>
+importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, {url: 'support/constraints-fixed-block-size.js'});
+</script>
diff --git a/testing/web-platform/tests/css/css-layout-api/constraints/fixed-block-size-flex-column-grow.https.html b/testing/web-platform/tests/css/css-layout-api/constraints/fixed-block-size-flex-column-grow.https.html
new file mode 100644
index 0000000000..da53fa86ad
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/constraints/fixed-block-size-flex-column-grow.https.html
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#dom-layoutconstraints-fixedblocksize">
+<link rel="match" href="../green-square-ref.html">
+<meta name="assert" content="This test checks that LayoutConstraints#fixedBlockSize is passed into the layout function correctly." />
+<style>
+body {
+ display: flex;
+ flex-direction: column;
+ width: 100px;
+ height: 60px;
+}
+
+.test {
+ background: red;
+ --expected-block-size: 50;
+ margin-bottom: 10px;
+ flex-grow: 1;
+}
+
+.child {
+ background: green;
+}
+
+@supports (display: layout(test)) {
+ .test {
+ display: layout(test);
+ }
+}
+</style>
+<script src="/common/reftest-wait.js"></script>
+<script src="/common/worklet-reftest.js"></script>
+
+<div class="test">
+ <div class="child"></div>
+</div>
+
+<script>
+importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, {url: 'support/constraints-fixed-block-size.js'});
+</script>
diff --git a/testing/web-platform/tests/css/css-layout-api/constraints/fixed-block-size-flex-column-none.https.html b/testing/web-platform/tests/css/css-layout-api/constraints/fixed-block-size-flex-column-none.https.html
new file mode 100644
index 0000000000..1d4249e925
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/constraints/fixed-block-size-flex-column-none.https.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#dom-layoutconstraints-fixedblocksize">
+<link rel="match" href="../green-square-ref.html">
+<meta name="assert" content="This test checks that LayoutConstraints#fixedBlockSize is passed into the layout function correctly." />
+<style>
+body {
+ display: flex;
+ flex-direction: column;
+ width: 100px;
+}
+
+.test {
+ background: red;
+ --expected-block-size: null;
+}
+
+.child {
+ background: green;
+}
+
+@supports (display: layout(test)) {
+ .test {
+ display: layout(test);
+ }
+}
+</style>
+<script src="/common/reftest-wait.js"></script>
+<script src="/common/worklet-reftest.js"></script>
+
+<div class="test">
+ <div class="child"></div>
+</div>
+
+<script>
+importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, {url: 'support/constraints-fixed-block-size.js'});
+</script>
diff --git a/testing/web-platform/tests/css/css-layout-api/constraints/fixed-block-size-flex-column-stretch-vrl.https.html b/testing/web-platform/tests/css/css-layout-api/constraints/fixed-block-size-flex-column-stretch-vrl.https.html
new file mode 100644
index 0000000000..c71e202b0c
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/constraints/fixed-block-size-flex-column-stretch-vrl.https.html
@@ -0,0 +1,39 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#dom-layoutconstraints-fixedblocksize">
+<link rel="match" href="../green-square-ref.html">
+<meta name="assert" content="This test checks that LayoutConstraints#fixedBlockSize is passed into the layout function correctly." />
+<style>
+body {
+ display: flex;
+ flex-direction: column;
+ width: 100px;
+}
+
+.test {
+ writing-mode: vertical-rl;
+ background: red;
+ --expected-block-size: 90; /* flex-item should stretch to (100 - 10)px */
+ margin-left: 10px;
+}
+
+.child {
+ background: green;
+}
+
+@supports (display: layout(test)) {
+ .test {
+ display: layout(test);
+ }
+}
+</style>
+<script src="/common/reftest-wait.js"></script>
+<script src="/common/worklet-reftest.js"></script>
+
+<div class="test">
+ <div class="child"></div>
+</div>
+
+<script>
+importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, {url: 'support/constraints-fixed-block-size.js'});
+</script>
diff --git a/testing/web-platform/tests/css/css-layout-api/constraints/fixed-block-size-flex-grow-vrl.https.html b/testing/web-platform/tests/css/css-layout-api/constraints/fixed-block-size-flex-grow-vrl.https.html
new file mode 100644
index 0000000000..f77b84910a
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/constraints/fixed-block-size-flex-grow-vrl.https.html
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#dom-layoutconstraints-fixedblocksize">
+<link rel="match" href="../green-square-ref.html">
+<meta name="assert" content="This test checks that LayoutConstraints#fixedBlockSize is passed into the layout function correctly." />
+<style>
+body {
+ display: flex;
+ width: 100px;
+}
+
+.test {
+ writing-mode: vertical-rl;
+ background: red;
+ --expected-block-size: 100;
+ flex-grow: 1;
+}
+
+.child {
+ background: green;
+}
+
+@supports (display: layout(test)) {
+ .test {
+ display: layout(test);
+ }
+}
+</style>
+<script src="/common/reftest-wait.js"></script>
+<script src="/common/worklet-reftest.js"></script>
+
+<div class="test">
+ <div class="child"></div>
+</div>
+
+<script>
+importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, {url: 'support/constraints-fixed-block-size.js'});
+</script>
diff --git a/testing/web-platform/tests/css/css-layout-api/constraints/fixed-block-size-flex-none.https.html b/testing/web-platform/tests/css/css-layout-api/constraints/fixed-block-size-flex-none.https.html
new file mode 100644
index 0000000000..9ef11daccf
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/constraints/fixed-block-size-flex-none.https.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#dom-layoutconstraints-fixedblocksize">
+<link rel="match" href="../green-square-ref.html">
+<meta name="assert" content="This test checks that LayoutConstraints#fixedBlockSize is passed into the layout function correctly." />
+<style>
+body {
+ display: flex;
+}
+
+.test {
+ background: red;
+ --expected-block-size: null;
+ width: 100px;
+}
+
+.child {
+ background: green;
+}
+
+@supports (display: layout(test)) {
+ .test {
+ display: layout(test);
+ }
+}
+</style>
+<script src="/common/reftest-wait.js"></script>
+<script src="/common/worklet-reftest.js"></script>
+
+<div class="test">
+ <div class="child"></div>
+</div>
+
+<script>
+importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, {url: 'support/constraints-fixed-block-size.js'});
+</script>
diff --git a/testing/web-platform/tests/css/css-layout-api/constraints/fixed-block-size-flex-percentage-indefinite.https.html b/testing/web-platform/tests/css/css-layout-api/constraints/fixed-block-size-flex-percentage-indefinite.https.html
new file mode 100644
index 0000000000..111120673e
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/constraints/fixed-block-size-flex-percentage-indefinite.https.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#dom-layoutconstraints-fixedblocksize">
+<link rel="match" href="../green-square-ref.html">
+<meta name="assert" content="This test checks that LayoutConstraints#fixedBlockSize is passed into the layout function correctly." />
+<style>
+body {
+ display: flex;
+}
+
+.test {
+ background: red;
+ --expected-block-size: null; /* Percentage which we are resolving height against is indefinite. */
+ width: 100px;
+ height: 50%;
+}
+
+.child {
+ background: green;
+}
+
+@supports (display: layout(test)) {
+ .test {
+ display: layout(test);
+ }
+}
+</style>
+<script src="/common/reftest-wait.js"></script>
+<script src="/common/worklet-reftest.js"></script>
+
+<div class="test">
+ <div class="child"></div>
+</div>
+
+<script>
+importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, {url: 'support/constraints-fixed-block-size.js'});
+</script>
diff --git a/testing/web-platform/tests/css/css-layout-api/constraints/fixed-block-size-flex-stretch-max.https.html b/testing/web-platform/tests/css/css-layout-api/constraints/fixed-block-size-flex-stretch-max.https.html
new file mode 100644
index 0000000000..c72ed3e04d
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/constraints/fixed-block-size-flex-stretch-max.https.html
@@ -0,0 +1,39 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#dom-layoutconstraints-fixedblocksize">
+<link rel="match" href="../green-square-ref.html">
+<meta name="assert" content="This test checks that LayoutConstraints#fixedBlockSize is passed into the layout function correctly." />
+<style>
+body {
+ display: flex;
+ height: 50px;
+}
+
+.test {
+ background: red;
+ --expected-block-size: 30; /* flex-item should respect the max constraint */
+ max-height: 30px;
+ width: 100px;
+ margin-bottom: 10px;
+}
+
+.child {
+ background: green;
+}
+
+@supports (display: layout(test)) {
+ .test {
+ display: layout(test);
+ }
+}
+</style>
+<script src="/common/reftest-wait.js"></script>
+<script src="/common/worklet-reftest.js"></script>
+
+<div class="test">
+ <div class="child"></div>
+</div>
+
+<script>
+importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, {url: 'support/constraints-fixed-block-size.js'});
+</script>
diff --git a/testing/web-platform/tests/css/css-layout-api/constraints/fixed-block-size-flex-stretch.https.html b/testing/web-platform/tests/css/css-layout-api/constraints/fixed-block-size-flex-stretch.https.html
new file mode 100644
index 0000000000..cfaf38295f
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/constraints/fixed-block-size-flex-stretch.https.html
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#dom-layoutconstraints-fixedblocksize">
+<link rel="match" href="../green-square-ref.html">
+<meta name="assert" content="This test checks that LayoutConstraints#fixedBlockSize is passed into the layout function correctly." />
+<style>
+body {
+ display: flex;
+ height: 50px;
+}
+
+.test {
+ background: red;
+ --expected-block-size: 40; /* flex-item should stretch to (50 - 10)px */
+ width: 100px;
+ margin-bottom: 10px;
+}
+
+.child {
+ background: green;
+}
+
+@supports (display: layout(test)) {
+ .test {
+ display: layout(test);
+ }
+}
+</style>
+<script src="/common/reftest-wait.js"></script>
+<script src="/common/worklet-reftest.js"></script>
+
+<div class="test">
+ <div class="child"></div>
+</div>
+
+<script>
+importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, {url: 'support/constraints-fixed-block-size.js'});
+</script>
diff --git a/testing/web-platform/tests/css/css-layout-api/constraints/fixed-block-size-grid-none.https.html b/testing/web-platform/tests/css/css-layout-api/constraints/fixed-block-size-grid-none.https.html
new file mode 100644
index 0000000000..5c7381523e
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/constraints/fixed-block-size-grid-none.https.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#dom-layoutconstraints-fixedblocksize">
+<link rel="match" href="../green-square-ref.html">
+<meta name="assert" content="This test checks that LayoutConstraints#fixedBlockSize is passed into the layout function correctly." />
+<style>
+body {
+ display: grid;
+}
+
+.test {
+ background: red;
+ --expected-block-size: null;
+ width: 100px;
+}
+
+.child {
+ background: green;
+}
+
+@supports (display: layout(test)) {
+ .test {
+ display: layout(test);
+ }
+}
+</style>
+<script src="/common/reftest-wait.js"></script>
+<script src="/common/worklet-reftest.js"></script>
+
+<div class="test">
+ <div class="child"></div>
+</div>
+
+<script>
+importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, {url: 'support/constraints-fixed-block-size.js'});
+</script>
diff --git a/testing/web-platform/tests/css/css-layout-api/constraints/fixed-block-size-grid-stretch-max.https.html b/testing/web-platform/tests/css/css-layout-api/constraints/fixed-block-size-grid-stretch-max.https.html
new file mode 100644
index 0000000000..c738ad546d
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/constraints/fixed-block-size-grid-stretch-max.https.html
@@ -0,0 +1,39 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#dom-layoutconstraints-fixedblocksize">
+<link rel="match" href="../green-square-ref.html">
+<meta name="assert" content="This test checks that LayoutConstraints#fixedBlockSize is passed into the layout function correctly." />
+<style>
+body {
+ display: grid;
+ grid: 50px / auto-flow;
+}
+
+.test {
+ background: red;
+ --expected-block-size: 30; /* grid-item should respect the max constraint */
+ max-height: 30px;
+ width: 100px;
+ margin-bottom: 10px;
+}
+
+.child {
+ background: green;
+}
+
+@supports (display: layout(test)) {
+ .test {
+ display: layout(test);
+ }
+}
+</style>
+<script src="/common/reftest-wait.js"></script>
+<script src="/common/worklet-reftest.js"></script>
+
+<div class="test">
+ <div class="child"></div>
+</div>
+
+<script>
+importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, {url: 'support/constraints-fixed-block-size.js'});
+</script>
diff --git a/testing/web-platform/tests/css/css-layout-api/constraints/fixed-block-size-grid-stretch.https.html b/testing/web-platform/tests/css/css-layout-api/constraints/fixed-block-size-grid-stretch.https.html
new file mode 100644
index 0000000000..2e83f42c86
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/constraints/fixed-block-size-grid-stretch.https.html
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#dom-layoutconstraints-fixedblocksize">
+<link rel="match" href="../green-square-ref.html">
+<meta name="assert" content="This test checks that LayoutConstraints#fixedBlockSize is passed into the layout function correctly." />
+<style>
+body {
+ display: grid;
+ grid: 50px / auto-flow;
+}
+
+.test {
+ background: red;
+ --expected-block-size: 40; /* grid-item should stretch to (50 - 10)px */
+ width: 100px;
+ margin-bottom: 10px;
+}
+
+.child {
+ background: green;
+}
+
+@supports (display: layout(test)) {
+ .test {
+ display: layout(test);
+ }
+}
+</style>
+<script src="/common/reftest-wait.js"></script>
+<script src="/common/worklet-reftest.js"></script>
+
+<div class="test">
+ <div class="child"></div>
+</div>
+
+<script>
+importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, {url: 'support/constraints-fixed-block-size.js'});
+</script>
diff --git a/testing/web-platform/tests/css/css-layout-api/constraints/fixed-block-size-grid-vrl.https.html b/testing/web-platform/tests/css/css-layout-api/constraints/fixed-block-size-grid-vrl.https.html
new file mode 100644
index 0000000000..2c004cd916
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/constraints/fixed-block-size-grid-vrl.https.html
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#dom-layoutconstraints-fixedblocksize">
+<link rel="match" href="../green-square-ref.html">
+<meta name="assert" content="This test checks that LayoutConstraints#fixedBlockSize is passed into the layout function correctly." />
+<style>
+body {
+ display: grid;
+ grid: auto-flow / 100px;
+}
+
+.test {
+ writing-mode: vertical-rl;
+ background: red;
+ --expected-block-size: 100;
+ width: 100px;
+}
+
+.child {
+ background: green;
+}
+
+@supports (display: layout(test)) {
+ .test {
+ display: layout(test);
+ }
+}
+</style>
+<script src="/common/reftest-wait.js"></script>
+<script src="/common/worklet-reftest.js"></script>
+
+<div class="test">
+ <div class="child"></div>
+</div>
+
+<script>
+importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, {url: 'support/constraints-fixed-block-size.js'});
+</script>
diff --git a/testing/web-platform/tests/css/css-layout-api/constraints/fixed-block-size-percentage-indefinite.https.html b/testing/web-platform/tests/css/css-layout-api/constraints/fixed-block-size-percentage-indefinite.https.html
new file mode 100644
index 0000000000..ab02cb4b03
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/constraints/fixed-block-size-percentage-indefinite.https.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#dom-layoutconstraints-fixedblocksize">
+<link rel="match" href="../green-square-ref.html">
+<meta name="assert" content="This test checks that LayoutConstraints#fixedBlockSize is passed into the layout function correctly." />
+<style>
+.test {
+ background: red;
+ --expected-block-size: null; /* Percentage which we are resolving height against is indefinite. */
+ width: 100px;
+ height: 50%;
+}
+
+.child {
+ background: green;
+}
+
+@supports (display: layout(test)) {
+ .test {
+ display: layout(test);
+ }
+}
+</style>
+<script src="/common/reftest-wait.js"></script>
+<script src="/common/worklet-reftest.js"></script>
+
+<div class="test">
+ <div class="child"></div>
+</div>
+
+<script>
+importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, {url: 'support/constraints-fixed-block-size.js'});
+</script>
diff --git a/testing/web-platform/tests/css/css-layout-api/constraints/fixed-block-size-percentage-quirks-mode.https.html b/testing/web-platform/tests/css/css-layout-api/constraints/fixed-block-size-percentage-quirks-mode.https.html
new file mode 100644
index 0000000000..285ce941b2
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/constraints/fixed-block-size-percentage-quirks-mode.https.html
@@ -0,0 +1,38 @@
+<html class=reftest-wait>
+<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#dom-layoutconstraints-fixedblocksize">
+<link rel="match" href="../green-square-ref.html">
+<meta name="assert" content="This test checks that LayoutConstraints#fixedBlockSize is passed into the layout function correctly." />
+<style>
+body {
+ height: 100px;
+}
+
+.test {
+ background: red;
+ --expected-block-size: 50; /* In quirks mode we should get 100px * 50% */
+ width: 100px;
+ height: 50%;
+}
+
+.child {
+ background: green;
+}
+
+@supports (display: layout(test)) {
+ .test {
+ display: layout(test);
+ }
+}
+</style>
+<script src="/common/reftest-wait.js"></script>
+<script src="/common/worklet-reftest.js"></script>
+
+<div class="container">
+ <div class="test">
+ <div class="child"></div>
+ </div>
+</div>
+
+<script>
+importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, {url: 'support/constraints-fixed-block-size.js'});
+</script>
diff --git a/testing/web-platform/tests/css/css-layout-api/constraints/fixed-block-size-percentage-vrl.https.html b/testing/web-platform/tests/css/css-layout-api/constraints/fixed-block-size-percentage-vrl.https.html
new file mode 100644
index 0000000000..870bc526f8
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/constraints/fixed-block-size-percentage-vrl.https.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#dom-layoutconstraints-fixedblocksize">
+<link rel="match" href="../green-square-ref.html">
+<meta name="assert" content="This test checks that LayoutConstraints#fixedBlockSize is passed into the layout function correctly." />
+<style>
+body {
+ width: 200px;
+}
+
+.test {
+ writing-mode: vertical-rl;
+ background: red;
+ --expected-block-size: 100;
+ width: 50%;
+}
+
+.child {
+ background: green;
+}
+
+@supports (display: layout(test)) {
+ .test {
+ display: layout(test);
+ }
+}
+</style>
+<script src="/common/reftest-wait.js"></script>
+<script src="/common/worklet-reftest.js"></script>
+
+<div class="test">
+ <div class="child"></div>
+</div>
+
+<script>
+importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, {url: 'support/constraints-fixed-block-size.js'});
+</script>
diff --git a/testing/web-platform/tests/css/css-layout-api/constraints/fixed-block-size-percentage.https.html b/testing/web-platform/tests/css/css-layout-api/constraints/fixed-block-size-percentage.https.html
new file mode 100644
index 0000000000..335556550d
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/constraints/fixed-block-size-percentage.https.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#dom-layoutconstraints-fixedblocksize">
+<link rel="match" href="../green-square-ref.html">
+<meta name="assert" content="This test checks that LayoutConstraints#fixedBlockSize is passed into the layout function correctly." />
+<style>
+body {
+ height: 200px;
+}
+
+.test {
+ background: red;
+ --expected-block-size: 100;
+ width: 100px;
+ height: 50%;
+}
+
+.child {
+ background: green;
+}
+
+@supports (display: layout(test)) {
+ .test {
+ display: layout(test);
+ }
+}
+</style>
+<script src="/common/reftest-wait.js"></script>
+<script src="/common/worklet-reftest.js"></script>
+
+<div class="test">
+ <div class="child"></div>
+</div>
+
+<script>
+importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, {url: 'support/constraints-fixed-block-size.js'});
+</script>
diff --git a/testing/web-platform/tests/css/css-layout-api/constraints/fixed-block-size-quirky-body.https.html b/testing/web-platform/tests/css/css-layout-api/constraints/fixed-block-size-quirky-body.https.html
new file mode 100644
index 0000000000..150426d45c
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/constraints/fixed-block-size-quirky-body.https.html
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#dom-layoutconstraints-fixedblocksize">
+<link rel="match" href="../green-square-ref.html">
+<meta name="assert" content="This test checks that LayoutConstraints#fixedBlockSize is passed into the layout function correctly." />
+<style>
+iframe { border: none; width: 200px; height: 200px; }
+</style>
+<script src="/common/reftest-wait.js"></script>
+<script src="/common/worklet-reftest.js"></script>
+<body>
+<script>
+// For this test we load a quirky iframe with the test file.
+// We can control the auto size of the iframe body element by setting the iframe height.
+const iframe = document.createElement('iframe');
+document.body.appendChild(iframe);
+iframe.addEventListener('load', () => {
+ importWorkletAndTerminateTestAfterAsyncPaint(
+ iframe.contentWindow.CSS.layoutWorklet, {url: 'constraints-fixed-block-size.js'});
+});
+iframe.src = 'support/constraints-fixed-block-size-quirky-body-iframe.html';
+</script>
diff --git a/testing/web-platform/tests/css/css-layout-api/constraints/fixed-inline-size-absolute-left-right.https.html b/testing/web-platform/tests/css/css-layout-api/constraints/fixed-inline-size-absolute-left-right.https.html
new file mode 100644
index 0000000000..3b81c4d13d
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/constraints/fixed-inline-size-absolute-left-right.https.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#dom-layoutconstraints-fixedinlinesize">
+<link rel="match" href="fixed-inline-size-ref.html">
+<meta name="assert" content="This test checks that LayoutConstraints#fixedInlineSize is passed into the layout function correctly." />
+<style>
+body {
+ position: relative;
+ width: 120px;
+}
+
+.test {
+ background: red;
+ position: absolute;
+ left: 0px;
+ right: 20px;
+}
+
+@supports (display: layout(test)) {
+ .test {
+ background: green;
+ display: layout(test);
+ }
+}
+</style>
+<script src="/common/reftest-wait.js"></script>
+<script src="/common/worklet-reftest.js"></script>
+
+<div class="test"></div>
+
+<script>
+importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, {url: 'support/constraints-fixed-inline-size.js'});
+</script>
diff --git a/testing/web-platform/tests/css/css-layout-api/constraints/fixed-inline-size-absolute-top-bottom-vrl.https.html b/testing/web-platform/tests/css/css-layout-api/constraints/fixed-inline-size-absolute-top-bottom-vrl.https.html
new file mode 100644
index 0000000000..ec94e59a17
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/constraints/fixed-inline-size-absolute-top-bottom-vrl.https.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#dom-layoutconstraints-fixedinlinesize">
+<link rel="match" href="fixed-inline-size-ref.html">
+<meta name="assert" content="This test checks that LayoutConstraints#fixedInlineSize is passed into the layout function correctly." />
+<style>
+body {
+ position: relative;
+ height: 120px;
+}
+
+.test {
+ background: red;
+ position: absolute;
+ left: 0px;
+ top: 0px;
+ bottom: 20px;
+ writing-mode: vertical-rl;
+}
+
+@supports (display: layout(test)) {
+ .test {
+ background: green;
+ display: layout(test);
+ }
+}
+</style>
+<script src="/common/reftest-wait.js"></script>
+<script src="/common/worklet-reftest.js"></script>
+
+<div class="test"></div>
+
+<script>
+importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, {url: 'support/constraints-fixed-inline-size.js'});
+</script>
diff --git a/testing/web-platform/tests/css/css-layout-api/constraints/fixed-inline-size-block-auto-avoid-floats-vlr.https.html b/testing/web-platform/tests/css/css-layout-api/constraints/fixed-inline-size-block-auto-avoid-floats-vlr.https.html
new file mode 100644
index 0000000000..2758462bd3
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/constraints/fixed-inline-size-block-auto-avoid-floats-vlr.https.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#dom-layoutconstraints-fixedinlinesize">
+<link rel="match" href="fixed-inline-size-ref.html">
+<meta name="assert" content="This test checks that LayoutConstraints#fixedInlineSize is passed into the layout function correctly." />
+<style>
+body {
+ height: 200px;
+ writing-mode: vertical-lr;
+}
+
+.float {
+ float: right;
+ width: 20px;
+ height: 100px;
+}
+
+.test {
+ background: red;
+}
+
+@supports (display: layout(test)) {
+ .test {
+ background: green;
+ display: layout(test);
+ }
+}
+</style>
+<script src="/common/reftest-wait.js"></script>
+<script src="/common/worklet-reftest.js"></script>
+
+<div class="float"></div>
+<div class="test"></div>
+
+<script>
+importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, {url: 'support/constraints-fixed-inline-size.js'});
+</script>
diff --git a/testing/web-platform/tests/css/css-layout-api/constraints/fixed-inline-size-block-auto-avoid-floats.https.html b/testing/web-platform/tests/css/css-layout-api/constraints/fixed-inline-size-block-auto-avoid-floats.https.html
new file mode 100644
index 0000000000..862b9ad3b2
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/constraints/fixed-inline-size-block-auto-avoid-floats.https.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#dom-layoutconstraints-fixedinlinesize">
+<link rel="match" href="fixed-inline-size-ref.html">
+<meta name="assert" content="This test checks that LayoutConstraints#fixedInlineSize is passed into the layout function correctly." />
+<style>
+body {
+ width: 200px;
+}
+
+.float {
+ float: right;
+ width: 100px;
+ height: 20px;
+}
+
+.test {
+ background: red;
+}
+
+@supports (display: layout(test)) {
+ .test {
+ background: green;
+ display: layout(test);
+ }
+}
+</style>
+<script src="/common/reftest-wait.js"></script>
+<script src="/common/worklet-reftest.js"></script>
+
+<div class="float"></div>
+<div class="test"></div>
+
+<script>
+importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, {url: 'support/constraints-fixed-inline-size.js'});
+</script>
diff --git a/testing/web-platform/tests/css/css-layout-api/constraints/fixed-inline-size-block-auto-vlr.https.html b/testing/web-platform/tests/css/css-layout-api/constraints/fixed-inline-size-block-auto-vlr.https.html
new file mode 100644
index 0000000000..0c15fd12ee
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/constraints/fixed-inline-size-block-auto-vlr.https.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#dom-layoutconstraints-fixedinlinesize">
+<link rel="match" href="fixed-inline-size-ref.html">
+<meta name="assert" content="This test checks that LayoutConstraints#fixedInlineSize is passed into the layout function correctly." />
+<style>
+body {
+ height: 120px;
+ writing-mode: vertical-lr;
+}
+
+.test {
+ margin-bottom: 20px;
+ background: red;
+}
+
+@supports (display: layout(test)) {
+ .test {
+ background: green;
+ display: layout(test);
+ }
+}
+</style>
+<script src="/common/reftest-wait.js"></script>
+<script src="/common/worklet-reftest.js"></script>
+
+<div class="test"></div>
+
+<script>
+importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, {url: 'support/constraints-fixed-inline-size.js'});
+</script>
diff --git a/testing/web-platform/tests/css/css-layout-api/constraints/fixed-inline-size-block-auto.https.html b/testing/web-platform/tests/css/css-layout-api/constraints/fixed-inline-size-block-auto.https.html
new file mode 100644
index 0000000000..c513c3d844
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/constraints/fixed-inline-size-block-auto.https.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#dom-layoutconstraints-fixedinlinesize">
+<link rel="match" href="fixed-inline-size-ref.html">
+<meta name="assert" content="This test checks that LayoutConstraints#fixedInlineSize is passed into the layout function correctly." />
+<style>
+body {
+ width: 120px;
+}
+
+.test {
+ margin-right: 20px;
+ background: red;
+}
+
+@supports (display: layout(test)) {
+ .test {
+ background: green;
+ display: layout(test);
+ }
+}
+</style>
+<script src="/common/reftest-wait.js"></script>
+<script src="/common/worklet-reftest.js"></script>
+
+<div class="test"></div>
+
+<script>
+importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, {url: 'support/constraints-fixed-inline-size.js'});
+</script>
diff --git a/testing/web-platform/tests/css/css-layout-api/constraints/fixed-inline-size-fixed-vrl.https.html b/testing/web-platform/tests/css/css-layout-api/constraints/fixed-inline-size-fixed-vrl.https.html
new file mode 100644
index 0000000000..93b0c110d9
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/constraints/fixed-inline-size-fixed-vrl.https.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#dom-layoutconstraints-fixedinlinesize">
+<link rel="match" href="fixed-inline-size-ref.html">
+<meta name="assert" content="This test checks that LayoutConstraints#fixedInlineSize is passed into the layout function correctly." />
+<style>
+.test {
+ background: red;
+ height: 100px;
+ writing-mode: vertical-rl;
+}
+
+@supports (display: layout(test)) {
+ .test {
+ background: green;
+ display: layout(test);
+ }
+}
+</style>
+<script src="/common/reftest-wait.js"></script>
+<script src="/common/worklet-reftest.js"></script>
+
+<div class="test"></div>
+
+<script>
+importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, {url: 'support/constraints-fixed-inline-size.js'});
+</script>
diff --git a/testing/web-platform/tests/css/css-layout-api/constraints/fixed-inline-size-fixed.https.html b/testing/web-platform/tests/css/css-layout-api/constraints/fixed-inline-size-fixed.https.html
new file mode 100644
index 0000000000..d8e8062f83
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/constraints/fixed-inline-size-fixed.https.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#dom-layoutconstraints-fixedinlinesize">
+<link rel="match" href="fixed-inline-size-ref.html">
+<meta name="assert" content="This test checks that LayoutConstraints#fixedInlineSize is passed into the layout function correctly." />
+<style>
+.test {
+ background: red;
+ width: 100px;
+}
+
+@supports (display: layout(test)) {
+ .test {
+ background: green;
+ display: layout(test);
+ }
+}
+</style>
+<script src="/common/reftest-wait.js"></script>
+<script src="/common/worklet-reftest.js"></script>
+
+<div class="test"></div>
+
+<script>
+importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, {url: 'support/constraints-fixed-inline-size.js'});
+</script>
diff --git a/testing/web-platform/tests/css/css-layout-api/constraints/fixed-inline-size-flex-grow-column-vrl.https.html b/testing/web-platform/tests/css/css-layout-api/constraints/fixed-inline-size-flex-grow-column-vrl.https.html
new file mode 100644
index 0000000000..b9159965a0
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/constraints/fixed-inline-size-flex-grow-column-vrl.https.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#dom-layoutconstraints-fixedinlinesize">
+<link rel="match" href="fixed-inline-size-ref.html">
+<meta name="assert" content="This test checks that LayoutConstraints#fixedInlineSize is passed into the layout function correctly." />
+<style>
+body {
+ display: flex;
+ flex-flow: column;
+ width: 100px;
+ height: 100px;
+}
+
+.test {
+ background: red;
+ flex-grow: 1;
+}
+
+@supports (display: layout(test)) {
+ .test {
+ background: green;
+ display: layout(test);
+ }
+}
+</style>
+<script src="/common/reftest-wait.js"></script>
+<script src="/common/worklet-reftest.js"></script>
+
+<div class="test"></div>
+
+<script>
+importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, {url: 'support/constraints-fixed-inline-size.js'});
+</script>
diff --git a/testing/web-platform/tests/css/css-layout-api/constraints/fixed-inline-size-flex-grow.https.html b/testing/web-platform/tests/css/css-layout-api/constraints/fixed-inline-size-flex-grow.https.html
new file mode 100644
index 0000000000..c2532c1460
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/constraints/fixed-inline-size-flex-grow.https.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#dom-layoutconstraints-fixedinlinesize">
+<link rel="match" href="fixed-inline-size-ref.html">
+<meta name="assert" content="This test checks that LayoutConstraints#fixedInlineSize is passed into the layout function correctly." />
+<style>
+body {
+ display: flex;
+ width: 100px;
+}
+
+.test {
+ background: red;
+ flex-grow: 1;
+}
+
+@supports (display: layout(test)) {
+ .test {
+ background: green;
+ display: layout(test);
+ }
+}
+</style>
+<script src="/common/reftest-wait.js"></script>
+<script src="/common/worklet-reftest.js"></script>
+
+<div class="test"></div>
+
+<script>
+importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, {url: 'support/constraints-fixed-inline-size.js'});
+</script>
diff --git a/testing/web-platform/tests/css/css-layout-api/constraints/fixed-inline-size-grid.https.html b/testing/web-platform/tests/css/css-layout-api/constraints/fixed-inline-size-grid.https.html
new file mode 100644
index 0000000000..45f9f491e7
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/constraints/fixed-inline-size-grid.https.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#dom-layoutconstraints-fixedinlinesize">
+<link rel="match" href="fixed-inline-size-ref.html">
+<meta name="assert" content="This test checks that LayoutConstraints#fixedInlineSize is passed into the layout function correctly." />
+<style>
+body {
+ display: grid;
+ grid: auto-flow / 100px;
+}
+
+.test {
+ background: red;
+}
+
+@supports (display: layout(test)) {
+ .test {
+ background: green;
+ display: layout(test);
+ }
+}
+</style>
+<script src="/common/reftest-wait.js"></script>
+<script src="/common/worklet-reftest.js"></script>
+
+<div class="test"></div>
+
+<script>
+importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, {url: 'support/constraints-fixed-inline-size.js'});
+</script>
diff --git a/testing/web-platform/tests/css/css-layout-api/constraints/fixed-inline-size-percentage-vlr.https.html b/testing/web-platform/tests/css/css-layout-api/constraints/fixed-inline-size-percentage-vlr.https.html
new file mode 100644
index 0000000000..2e35043777
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/constraints/fixed-inline-size-percentage-vlr.https.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#dom-layoutconstraints-fixedinlinesize">
+<link rel="match" href="fixed-inline-size-ref.html">
+<meta name="assert" content="This test checks that LayoutConstraints#fixedInlineSize is passed into the layout function correctly." />
+<style>
+body {
+ height: 200px;
+ writing-mode: vertical-lr;
+}
+
+.test {
+ background: red;
+ height: 50%;
+}
+
+@supports (display: layout(test)) {
+ .test {
+ background: green;
+ display: layout(test);
+ }
+}
+</style>
+<script src="/common/reftest-wait.js"></script>
+<script src="/common/worklet-reftest.js"></script>
+
+<div class="test"></div>
+
+<script>
+importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, {url: 'support/constraints-fixed-inline-size.js'});
+</script>
diff --git a/testing/web-platform/tests/css/css-layout-api/constraints/fixed-inline-size-percentage.https.html b/testing/web-platform/tests/css/css-layout-api/constraints/fixed-inline-size-percentage.https.html
new file mode 100644
index 0000000000..c9041cf0ea
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/constraints/fixed-inline-size-percentage.https.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#dom-layoutconstraints-fixedinlinesize">
+<link rel="match" href="fixed-inline-size-ref.html">
+<meta name="assert" content="This test checks that LayoutConstraints#fixedInlineSize is passed into the layout function correctly." />
+<style>
+body {
+ width: 200px;
+}
+
+.test {
+ background: red;
+ width: 50%;
+}
+
+@supports (display: layout(test)) {
+ .test {
+ background: green;
+ display: layout(test);
+ }
+}
+</style>
+<script src="/common/reftest-wait.js"></script>
+<script src="/common/worklet-reftest.js"></script>
+
+<div class="test"></div>
+
+<script>
+importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, {url: 'support/constraints-fixed-inline-size.js'});
+</script>
diff --git a/testing/web-platform/tests/css/css-layout-api/constraints/fixed-inline-size-ref.html b/testing/web-platform/tests/css/css-layout-api/constraints/fixed-inline-size-ref.html
new file mode 100644
index 0000000000..e5727c0e2d
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/constraints/fixed-inline-size-ref.html
@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+<style>
+.result {
+ background: green;
+ height: 100px;
+ width: 100px;
+}
+</style>
+
+<div class="result"></div>
diff --git a/testing/web-platform/tests/css/css-layout-api/constraints/support/constraints-fixed-block-size-quirky-body-iframe.html b/testing/web-platform/tests/css/css-layout-api/constraints/support/constraints-fixed-block-size-quirky-body-iframe.html
new file mode 100644
index 0000000000..da770e6caf
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/constraints/support/constraints-fixed-block-size-quirky-body-iframe.html
@@ -0,0 +1,21 @@
+<style>
+body {
+ margin: 0;
+ --expected-block-size: 200;
+}
+
+.child {
+ background: green;
+}
+
+@supports (display: layout(test)) {
+ body {
+ display: layout(test);
+ }
+}
+</style>
+
+<!-- In Quirks mode, we should stretch to 100% of the inital containing block. -->
+<body>
+<div class="child"></div>
+</body>
diff --git a/testing/web-platform/tests/css/css-layout-api/constraints/support/constraints-fixed-block-size.js b/testing/web-platform/tests/css/css-layout-api/constraints/support/constraints-fixed-block-size.js
new file mode 100644
index 0000000000..25d73ef615
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/constraints/support/constraints-fixed-block-size.js
@@ -0,0 +1,22 @@
+registerLayout('test', class {
+ static get inputProperties() {
+ return ['--expected-block-size'];
+ }
+
+ async intrinsicSizes() {}
+ async layout([child], edges, constraints, styleMap) {
+ let childFixedInlineSize = 0;
+ let childFixedBlockSize = 0;
+ if (constraints.fixedBlockSize === JSON.parse(styleMap.get('--expected-block-size'))) {
+ childFixedInlineSize = 100;
+ childFixedBlockSize = 100;
+ }
+
+ const childFragments = [await child.layoutNextFragment({
+ fixedInlineSize: childFixedInlineSize,
+ fixedBlockSize: childFixedBlockSize,
+ })];
+
+ return {childFragments};
+ }
+});
diff --git a/testing/web-platform/tests/css/css-layout-api/constraints/support/constraints-fixed-inline-size.js b/testing/web-platform/tests/css/css-layout-api/constraints/support/constraints-fixed-inline-size.js
new file mode 100644
index 0000000000..3636f36654
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/constraints/support/constraints-fixed-inline-size.js
@@ -0,0 +1,9 @@
+registerLayout('test', class {
+ async intrinsicSizes() {}
+ async layout(children, edges, constraints, styleMap) {
+ if (constraints.fixedInlineSize !== 100)
+ return {autoBlockSize: 0};
+
+ return {autoBlockSize: 100};
+ }
+});
diff --git a/testing/web-platform/tests/css/css-layout-api/crash-multicol.https.html b/testing/web-platform/tests/css/css-layout-api/crash-multicol.https.html
new file mode 100644
index 0000000000..5f175100e5
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/crash-multicol.https.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/">
+<meta name="assert" content="This test checks that browser doesn't crash when the layout() function is used with multicol." />
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/worklet-reftest.js"></script>
+
+<style>
+#test {
+ display: layout('test');
+ columns: 2;
+}
+</style>
+
+<div id="test"></div>
+
+<script id="code" type="text/worklet">
+registerLayout('test', class {
+ async intrinsicSizes() {}
+ async layout() {}
+});
+</script>
+
+<script>
+promise_test(async function() {
+ await importWorklet(CSS.layoutWorklet, document.getElementById('code').textContent);
+});
+</script>
diff --git a/testing/web-platform/tests/css/css-layout-api/edges/all-ref.html b/testing/web-platform/tests/css/css-layout-api/edges/all-ref.html
new file mode 100644
index 0000000000..2a04f96e73
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/edges/all-ref.html
@@ -0,0 +1,161 @@
+<!DOCTYPE html>
+<style>
+td { text-align: center; }
+
+.parent {
+ box-sizing: border-box;
+ width: 60px;
+ height: 60px;
+ border: solid;
+ border-width: 1px 2px 3px 4px;
+ padding: 0px 4px 8px 12px;
+ position: relative;
+}
+
+.child {
+ position: absolute;
+ width: 10px;
+ height: 10px;
+ background: green;
+}
+
+.top-left {
+ top: 0;
+ left: 12px;
+}
+
+.top-right {
+ top: 0;
+ right: 4px;
+}
+
+.bottom-left {
+ bottom: 8px;
+ left: 12px;
+}
+
+.bottom-right {
+ bottom: 8px;
+ right: 4px;
+}
+</style>
+
+<table>
+ <tr>
+ <td></td>
+ <td colspan=2>LTR</td>
+ <td colspan=2>RTL</td>
+ </tr>
+ <tr>
+ <td></td>
+ <td>Y</td>
+ <td>X</td>
+ <td>Y</td>
+ <td>X</td>
+ </tr>
+ <tr>
+ <td>HTB</td>
+ <td>
+ <div class="parent" style="writing-mode: horizontal-tb; direction: ltr; overflow-y: scroll;">
+ <div class="child top-left"></div>
+ <div class="child top-right"></div>
+ <div class="child bottom-left"></div>
+ <div class="child bottom-right"></div>
+ </div>
+ </td>
+ <td>
+ <div class="parent" style="writing-mode: horizontal-tb; direction: ltr; overflow-x: scroll;">
+ <div class="child top-left"></div>
+ <div class="child top-right"></div>
+ <div class="child bottom-left"></div>
+ <div class="child bottom-right"></div>
+ </div>
+ </td>
+ <td>
+ <div class="parent" style="writing-mode: horizontal-tb; direction: rtl; overflow-y: scroll;">
+ <div class="child top-left"></div>
+ <div class="child top-right"></div>
+ <div class="child bottom-left"></div>
+ <div class="child bottom-right"></div>
+ </div>
+ </td>
+ <td>
+ <div class="parent" style="writing-mode: horizontal-tb; direction: rtl; overflow-x: scroll;">
+ <div class="child top-left"></div>
+ <div class="child top-right"></div>
+ <div class="child bottom-left"></div>
+ <div class="child bottom-right"></div>
+ </div>
+ </td>
+ </tr>
+ <tr>
+ <td>VRL</td>
+ <td>
+ <div class="parent" style="writing-mode: vertical-rl; direction: ltr; overflow-y: scroll;">
+ <div class="child top-left"></div>
+ <div class="child top-right"></div>
+ <div class="child bottom-left"></div>
+ <div class="child bottom-right"></div>
+ </div>
+ </td>
+ <td>
+ <div class="parent" style="writing-mode: vertical-rl; direction: ltr; overflow-x: scroll;">
+ <div class="child top-left"></div>
+ <div class="child top-right"></div>
+ <div class="child bottom-left"></div>
+ <div class="child bottom-right"></div>
+ </div>
+ </td>
+ <td>
+ <div class="parent" style="writing-mode: vertical-rl; direction: rtl; overflow-y: scroll;">
+ <div class="child top-left"></div>
+ <div class="child top-right"></div>
+ <div class="child bottom-left"></div>
+ <div class="child bottom-right"></div>
+ </div>
+ </td>
+ <td>
+ <div class="parent" style="writing-mode: vertical-rl; direction: rtl; overflow-x: scroll;">
+ <div class="child top-left"></div>
+ <div class="child top-right"></div>
+ <div class="child bottom-left"></div>
+ <div class="child bottom-right"></div>
+ </div>
+ </td>
+ </tr>
+ <tr>
+ <td>VLR</td>
+ <td>
+ <div class="parent" style="writing-mode: vertical-lr; direction: ltr; overflow-y: scroll;">
+ <div class="child top-left"></div>
+ <div class="child top-right"></div>
+ <div class="child bottom-left"></div>
+ <div class="child bottom-right"></div>
+ </div>
+ </td>
+ <td>
+ <div class="parent" style="writing-mode: vertical-lr; direction: ltr; overflow-x: scroll;">
+ <div class="child top-left"></div>
+ <div class="child top-right"></div>
+ <div class="child bottom-left"></div>
+ <div class="child bottom-right"></div>
+ </div>
+ </td>
+ <td>
+ <div class="parent" style="writing-mode: vertical-lr; direction: rtl; overflow-y: scroll;">
+ <div class="child top-left"></div>
+ <div class="child top-right"></div>
+ <div class="child bottom-left"></div>
+ <div class="child bottom-right"></div>
+ </div>
+ </td>
+ <td>
+ <div class="parent" style="writing-mode: vertical-lr; direction: rtl; overflow-x: scroll;">
+ <div class="child top-left"></div>
+ <div class="child top-right"></div>
+ <div class="child bottom-left"></div>
+ <div class="child bottom-right"></div>
+ </div>
+ </td>
+ </tr>
+</table>
diff --git a/testing/web-platform/tests/css/css-layout-api/edges/all.https.html b/testing/web-platform/tests/css/css-layout-api/edges/all.https.html
new file mode 100644
index 0000000000..e38d3666b8
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/edges/all.https.html
@@ -0,0 +1,194 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#dom-layoutedges">
+<link rel="match" href="all-ref.html">
+<meta name="assert" content="This test checks that 'all' sizes are passed to the layout correctly." />
+<style>
+td { text-align: center; }
+
+.parent {
+ box-sizing: border-box;
+ width: 60px;
+ height: 60px;
+ border: solid;
+ border-width: 1px 2px 3px 4px;
+ padding: 0px 4px 8px 12px;
+ position: relative;
+ background: red;
+}
+
+@supports (display: layout(test)) {
+ .parent {
+ display: layout(test);
+ background: initial;
+ }
+}
+
+.child {
+ width: 10px;
+ height: 10px;
+ background: green;
+}
+</style>
+<!--
+ This test works by placing four children in each corner of the layout using the edges.
+ The reference to this test uses absolute positioning to achieve the same effect.
+-->
+<table>
+ <tr>
+ <td></td>
+ <td colspan=2>LTR</td>
+ <td colspan=2>RTL</td>
+ </tr>
+ <tr>
+ <td></td>
+ <td>Y</td>
+ <td>X</td>
+ <td>Y</td>
+ <td>X</td>
+ </tr>
+ <tr>
+ <td>HTB</td>
+ <td>
+ <div class="parent" style="writing-mode: horizontal-tb; direction: ltr; overflow-y: scroll;">
+ <div class="child"></div>
+ <div class="child"></div>
+ <div class="child"></div>
+ <div class="child"></div>
+ </div>
+ </td>
+ <td>
+ <div class="parent" style="writing-mode: horizontal-tb; direction: ltr; overflow-x: scroll;">
+ <div class="child"></div>
+ <div class="child"></div>
+ <div class="child"></div>
+ <div class="child"></div>
+ </div>
+ </td>
+ <td>
+ <div class="parent" style="writing-mode: horizontal-tb; direction: rtl; overflow-y: scroll;">
+ <div class="child"></div>
+ <div class="child"></div>
+ <div class="child"></div>
+ <div class="child"></div>
+ </div>
+ </td>
+ <td>
+ <div class="parent" style="writing-mode: horizontal-tb; direction: rtl; overflow-x: scroll;">
+ <div class="child"></div>
+ <div class="child"></div>
+ <div class="child"></div>
+ <div class="child"></div>
+ </div>
+ </td>
+ </tr>
+ <tr>
+ <td>VRL</td>
+ <td>
+ <div class="parent" style="writing-mode: vertical-rl; direction: ltr; overflow-y: scroll;">
+ <div class="child"></div>
+ <div class="child"></div>
+ <div class="child"></div>
+ <div class="child"></div>
+ </div>
+ </td>
+ <td>
+ <div class="parent" style="writing-mode: vertical-rl; direction: ltr; overflow-x: scroll;">
+ <div class="child"></div>
+ <div class="child"></div>
+ <div class="child"></div>
+ <div class="child"></div>
+ </div>
+ </td>
+ <td>
+ <div class="parent" style="writing-mode: vertical-rl; direction: rtl; overflow-y: scroll;">
+ <div class="child"></div>
+ <div class="child"></div>
+ <div class="child"></div>
+ <div class="child"></div>
+ </div>
+ </td>
+ <td>
+ <div class="parent" style="writing-mode: vertical-rl; direction: rtl; overflow-x: scroll;">
+ <div class="child"></div>
+ <div class="child"></div>
+ <div class="child"></div>
+ <div class="child"></div>
+ </div>
+ </td>
+ </tr>
+ <tr>
+ <td>VLR</td>
+ <td>
+ <div class="parent" style="writing-mode: vertical-lr; direction: ltr; overflow-y: scroll;">
+ <div class="child"></div>
+ <div class="child"></div>
+ <div class="child"></div>
+ <div class="child"></div>
+ </div>
+ </td>
+ <td>
+ <div class="parent" style="writing-mode: vertical-lr; direction: ltr; overflow-x: scroll;">
+ <div class="child"></div>
+ <div class="child"></div>
+ <div class="child"></div>
+ <div class="child"></div>
+ </div>
+ </td>
+ <td>
+ <div class="parent" style="writing-mode: vertical-lr; direction: rtl; overflow-y: scroll;">
+ <div class="child"></div>
+ <div class="child"></div>
+ <div class="child"></div>
+ <div class="child"></div>
+ </div>
+ </td>
+ <td>
+ <div class="parent" style="writing-mode: vertical-lr; direction: rtl; overflow-x: scroll;">
+ <div class="child"></div>
+ <div class="child"></div>
+ <div class="child"></div>
+ <div class="child"></div>
+ </div>
+ </td>
+ </tr>
+</table>
+<script src="/common/reftest-wait.js"></script>
+<script src="/common/worklet-reftest.js"></script>
+<script id="code" type="text/worklet">
+registerLayout('test', class {
+ async intrinsicSizes() {}
+ async layout(children, edges, constraints) {
+ const topLeftFragment = await children[0].layoutNextFragment();
+ const topRightFragment = await children[1].layoutNextFragment();
+ const bottomLeftFragment = await children[2].layoutNextFragment();
+ const bottomRightFragment = await children[3].layoutNextFragment();
+
+ topLeftFragment.inlineOffset = edges.inlineStart;
+ topLeftFragment.blockOffset = edges.blockStart;
+
+ topRightFragment.inlineOffset =
+ constraints.fixedInlineSize - topRightFragment.inlineSize - edges.inlineEnd;
+ topRightFragment.blockOffset = edges.blockStart;
+
+ bottomLeftFragment.inlineOffset = edges.inlineStart;
+ bottomLeftFragment.blockOffset =
+ constraints.fixedBlockSize - bottomLeftFragment.blockSize - edges.blockEnd;
+
+ bottomRightFragment.inlineOffset =
+ constraints.fixedInlineSize - bottomRightFragment.inlineSize - edges.inlineEnd;
+ bottomRightFragment.blockOffset =
+ constraints.fixedBlockSize - bottomRightFragment.blockSize - edges.blockEnd;
+
+ return {childFragments: [
+ topLeftFragment,
+ topRightFragment,
+ bottomLeftFragment,
+ bottomRightFragment
+ ]};
+ }
+});
+</script>
+<script>
+importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, document.getElementById('code').textContent);
+</script>
diff --git a/testing/web-platform/tests/css/css-layout-api/edges/border-htb-rtl.https.html b/testing/web-platform/tests/css/css-layout-api/edges/border-htb-rtl.https.html
new file mode 100644
index 0000000000..cb200a7675
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/edges/border-htb-rtl.https.html
@@ -0,0 +1,39 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#dom-layoutedges">
+<link rel="match" href="../green-square-ref.html">
+<meta name="assert" content="This test checks that border sizes are passed to the layout correctly." />
+<style>
+.test {
+ writing-mode: horizontal-tb;
+ direction: rtl;
+ background: red;
+ box-sizing: border-box;
+ width: 100px;
+
+ --edges-inline-start-expected: 8;
+ --edges-inline-end-expected: 20;
+ --edges-block-start-expected: 10;
+ --edges-block-end-expected: 0;
+
+ font-size: 8px;
+
+ border-color: transparent;
+ border-style: solid;
+ border-width: 10px 1em 0 20px;
+}
+
+@supports (display: layout(test)) {
+ .test {
+ display: layout(test);
+ background: green;
+ }
+}
+</style>
+<script src="/common/reftest-wait.js"></script>
+<script src="/common/worklet-reftest.js"></script>
+
+<div class="test"></div>
+<script>
+importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, {url: 'support/edges.js'});
+</script>
diff --git a/testing/web-platform/tests/css/css-layout-api/edges/border-htb.https.html b/testing/web-platform/tests/css/css-layout-api/edges/border-htb.https.html
new file mode 100644
index 0000000000..67a3858830
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/edges/border-htb.https.html
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#dom-layoutedges">
+<link rel="match" href="../green-square-ref.html">
+<meta name="assert" content="This test checks that border sizes are passed to the layout correctly." />
+<style>
+.test {
+ writing-mode: horizontal-tb;
+ background: red;
+ box-sizing: border-box;
+ width: 100px;
+
+ --edges-inline-start-expected: 20;
+ --edges-inline-end-expected: 8;
+ --edges-block-start-expected: 10;
+ --edges-block-end-expected: 0;
+
+ font-size: 8px;
+
+ border-color: transparent;
+ border-style: solid;
+ border-width: 10px 1em 0 20px;
+}
+
+@supports (display: layout(test)) {
+ .test {
+ display: layout(test);
+ background: green;
+ }
+}
+</style>
+<script src="/common/reftest-wait.js"></script>
+<script src="/common/worklet-reftest.js"></script>
+
+<div class="test"></div>
+<script>
+importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, {url: 'support/edges.js'});
+</script>
diff --git a/testing/web-platform/tests/css/css-layout-api/edges/border-vlr-rtl.https.html b/testing/web-platform/tests/css/css-layout-api/edges/border-vlr-rtl.https.html
new file mode 100644
index 0000000000..8da84e9acc
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/edges/border-vlr-rtl.https.html
@@ -0,0 +1,39 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#dom-layoutedges">
+<link rel="match" href="../green-square-ref.html">
+<meta name="assert" content="This test checks that border sizes are passed to the layout correctly." />
+<style>
+.test {
+ writing-mode: vertical-lr;
+ direction: rtl;
+ background: red;
+ box-sizing: border-box;
+ height: 100px;
+
+ --edges-inline-start-expected: 0;
+ --edges-inline-end-expected: 10;
+ --edges-block-start-expected: 20;
+ --edges-block-end-expected: 8;
+
+ font-size: 8px;
+
+ border-color: transparent;
+ border-style: solid;
+ border-width: 10px 1em 0 20px;
+}
+
+@supports (display: layout(test)) {
+ .test {
+ display: layout(test);
+ background: green;
+ }
+}
+</style>
+<script src="/common/reftest-wait.js"></script>
+<script src="/common/worklet-reftest.js"></script>
+
+<div class="test"></div>
+<script>
+importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, {url: 'support/edges.js'});
+</script>
diff --git a/testing/web-platform/tests/css/css-layout-api/edges/border-vlr.https.html b/testing/web-platform/tests/css/css-layout-api/edges/border-vlr.https.html
new file mode 100644
index 0000000000..b514b2f22f
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/edges/border-vlr.https.html
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#dom-layoutedges">
+<link rel="match" href="../green-square-ref.html">
+<meta name="assert" content="This test checks that border sizes are passed to the layout correctly." />
+<style>
+.test {
+ writing-mode: vertical-lr;
+ background: red;
+ box-sizing: border-box;
+ height: 100px;
+
+ --edges-inline-start-expected: 10;
+ --edges-inline-end-expected: 0;
+ --edges-block-start-expected: 20;
+ --edges-block-end-expected: 8;
+
+ font-size: 8px;
+
+ border-color: transparent;
+ border-style: solid;
+ border-width: 10px 1em 0 20px;
+}
+
+@supports (display: layout(test)) {
+ .test {
+ display: layout(test);
+ background: green;
+ }
+}
+</style>
+<script src="/common/reftest-wait.js"></script>
+<script src="/common/worklet-reftest.js"></script>
+
+<div class="test"></div>
+<script>
+importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, {url: 'support/edges.js'});
+</script>
diff --git a/testing/web-platform/tests/css/css-layout-api/edges/border-vrl-rtl.https.html b/testing/web-platform/tests/css/css-layout-api/edges/border-vrl-rtl.https.html
new file mode 100644
index 0000000000..38c8c3f046
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/edges/border-vrl-rtl.https.html
@@ -0,0 +1,39 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#dom-layoutedges">
+<link rel="match" href="../green-square-ref.html">
+<meta name="assert" content="This test checks that border sizes are passed to the layout correctly." />
+<style>
+.test {
+ writing-mode: vertical-rl;
+ direction: rtl;
+ background: red;
+ box-sizing: border-box;
+ height: 100px;
+
+ --edges-inline-start-expected: 0;
+ --edges-inline-end-expected: 10;
+ --edges-block-start-expected: 8;
+ --edges-block-end-expected: 20;
+
+ font-size: 8px;
+
+ border-color: transparent;
+ border-style: solid;
+ border-width: 10px 1em 0 20px;
+}
+
+@supports (display: layout(test)) {
+ .test {
+ display: layout(test);
+ background: green;
+ }
+}
+</style>
+<script src="/common/reftest-wait.js"></script>
+<script src="/common/worklet-reftest.js"></script>
+
+<div class="test"></div>
+<script>
+importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, {url: 'support/edges.js'});
+</script>
diff --git a/testing/web-platform/tests/css/css-layout-api/edges/border-vrl.https.html b/testing/web-platform/tests/css/css-layout-api/edges/border-vrl.https.html
new file mode 100644
index 0000000000..94c5353eb9
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/edges/border-vrl.https.html
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#dom-layoutedges">
+<link rel="match" href="../green-square-ref.html">
+<meta name="assert" content="This test checks that border sizes are passed to the layout correctly." />
+<style>
+.test {
+ writing-mode: vertical-rl;
+ background: red;
+ box-sizing: border-box;
+ height: 100px;
+
+ --edges-inline-start-expected: 10;
+ --edges-inline-end-expected: 0;
+ --edges-block-start-expected: 8;
+ --edges-block-end-expected: 20;
+
+ font-size: 8px;
+
+ border-color: transparent;
+ border-style: solid;
+ border-width: 10px 1em 0 20px;
+}
+
+@supports (display: layout(test)) {
+ .test {
+ display: layout(test);
+ background: green;
+ }
+}
+</style>
+<script src="/common/reftest-wait.js"></script>
+<script src="/common/worklet-reftest.js"></script>
+
+<div class="test"></div>
+<script>
+importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, {url: 'support/edges.js'});
+</script>
diff --git a/testing/web-platform/tests/css/css-layout-api/edges/padding-htb-rtl.https.html b/testing/web-platform/tests/css/css-layout-api/edges/padding-htb-rtl.https.html
new file mode 100644
index 0000000000..dfbf2bc099
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/edges/padding-htb-rtl.https.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#dom-layoutedges">
+<link rel="match" href="../green-square-ref.html">
+<meta name="assert" content="This test checks that padding sizes are passed to the layout correctly." />
+<style>
+.test {
+ writing-mode: horizontal-tb;
+ direction: rtl;
+ background: red;
+ box-sizing: border-box;
+ width: 100px;
+
+ --edges-inline-start-expected: 8;
+ --edges-inline-end-expected: 20;
+ --edges-block-start-expected: 10;
+ --edges-block-end-expected: 0;
+
+ font-size: 8px;
+
+ padding: 10px 1em 0 20px;
+}
+
+@supports (display: layout(test)) {
+ .test {
+ display: layout(test);
+ background: green;
+ }
+}
+</style>
+<script src="/common/reftest-wait.js"></script>
+<script src="/common/worklet-reftest.js"></script>
+
+<div class="test"></div>
+<script>
+importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, {url: 'support/edges.js'});
+</script>
diff --git a/testing/web-platform/tests/css/css-layout-api/edges/padding-htb.https.html b/testing/web-platform/tests/css/css-layout-api/edges/padding-htb.https.html
new file mode 100644
index 0000000000..ebad66594c
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/edges/padding-htb.https.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#dom-layoutedges">
+<link rel="match" href="../green-square-ref.html">
+<meta name="assert" content="This test checks that padding sizes are passed to the layout correctly." />
+<style>
+.test {
+ writing-mode: horizontal-tb;
+ background: red;
+ box-sizing: border-box;
+ width: 100px;
+
+ --edges-inline-start-expected: 20;
+ --edges-inline-end-expected: 8;
+ --edges-block-start-expected: 10;
+ --edges-block-end-expected: 0;
+
+ font-size: 8px;
+
+ padding: 10px 1em 0 20px;
+}
+
+@supports (display: layout(test)) {
+ .test {
+ display: layout(test);
+ background: green;
+ }
+}
+</style>
+<script src="/common/reftest-wait.js"></script>
+<script src="/common/worklet-reftest.js"></script>
+
+<div class="test"></div>
+<script>
+importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, {url: 'support/edges.js'});
+</script>
diff --git a/testing/web-platform/tests/css/css-layout-api/edges/padding-vlr-rtl.https.html b/testing/web-platform/tests/css/css-layout-api/edges/padding-vlr-rtl.https.html
new file mode 100644
index 0000000000..86b0ca5425
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/edges/padding-vlr-rtl.https.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#dom-layoutedges">
+<link rel="match" href="../green-square-ref.html">
+<meta name="assert" content="This test checks that padding sizes are passed to the layout correctly." />
+<style>
+.test {
+ writing-mode: vertical-lr;
+ direction: rtl;
+ background: red;
+ box-sizing: border-box;
+ height: 100px;
+
+ --edges-inline-start-expected: 0;
+ --edges-inline-end-expected: 10;
+ --edges-block-start-expected: 20;
+ --edges-block-end-expected: 8;
+
+ font-size: 8px;
+
+ padding: 10px 1em 0 20px;
+}
+
+@supports (display: layout(test)) {
+ .test {
+ display: layout(test);
+ background: green;
+ }
+}
+</style>
+<script src="/common/reftest-wait.js"></script>
+<script src="/common/worklet-reftest.js"></script>
+
+<div class="test"></div>
+<script>
+importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, {url: 'support/edges.js'});
+</script>
diff --git a/testing/web-platform/tests/css/css-layout-api/edges/padding-vlr.https.html b/testing/web-platform/tests/css/css-layout-api/edges/padding-vlr.https.html
new file mode 100644
index 0000000000..563884ade3
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/edges/padding-vlr.https.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#dom-layoutedges">
+<link rel="match" href="../green-square-ref.html">
+<meta name="assert" content="This test checks that padding sizes are passed to the layout correctly." />
+<style>
+.test {
+ writing-mode: vertical-lr;
+ background: red;
+ box-sizing: border-box;
+ height: 100px;
+
+ --edges-inline-start-expected: 10;
+ --edges-inline-end-expected: 0;
+ --edges-block-start-expected: 20;
+ --edges-block-end-expected: 8;
+
+ font-size: 8px;
+
+ padding: 10px 1em 0 20px;
+}
+
+@supports (display: layout(test)) {
+ .test {
+ display: layout(test);
+ background: green;
+ }
+}
+</style>
+<script src="/common/reftest-wait.js"></script>
+<script src="/common/worklet-reftest.js"></script>
+
+<div class="test"></div>
+<script>
+importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, {url: 'support/edges.js'});
+</script>
diff --git a/testing/web-platform/tests/css/css-layout-api/edges/padding-vrl-rtl.https.html b/testing/web-platform/tests/css/css-layout-api/edges/padding-vrl-rtl.https.html
new file mode 100644
index 0000000000..bda0a21144
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/edges/padding-vrl-rtl.https.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#dom-layoutedges">
+<link rel="match" href="../green-square-ref.html">
+<meta name="assert" content="This test checks that padding sizes are passed to the layout correctly." />
+<style>
+.test {
+ writing-mode: vertical-rl;
+ direction: rtl;
+ background: red;
+ box-sizing: border-box;
+ height: 100px;
+
+ --edges-inline-start-expected: 0;
+ --edges-inline-end-expected: 10;
+ --edges-block-start-expected: 8;
+ --edges-block-end-expected: 20;
+
+ font-size: 8px;
+
+ padding: 10px 1em 0 20px;
+}
+
+@supports (display: layout(test)) {
+ .test {
+ display: layout(test);
+ background: green;
+ }
+}
+</style>
+<script src="/common/reftest-wait.js"></script>
+<script src="/common/worklet-reftest.js"></script>
+
+<div class="test"></div>
+<script>
+importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, {url: 'support/edges.js'});
+</script>
diff --git a/testing/web-platform/tests/css/css-layout-api/edges/padding-vrl.https.html b/testing/web-platform/tests/css/css-layout-api/edges/padding-vrl.https.html
new file mode 100644
index 0000000000..a65ecad311
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/edges/padding-vrl.https.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#dom-layoutedges">
+<link rel="match" href="../green-square-ref.html">
+<meta name="assert" content="This test checks that padding sizes are passed to the layout correctly." />
+<style>
+.test {
+ writing-mode: vertical-rl;
+ background: red;
+ box-sizing: border-box;
+ height: 100px;
+
+ --edges-inline-start-expected: 10;
+ --edges-inline-end-expected: 0;
+ --edges-block-start-expected: 8;
+ --edges-block-end-expected: 20;
+
+ font-size: 8px;
+
+ padding: 10px 1em 0 20px;
+}
+
+@supports (display: layout(test)) {
+ .test {
+ display: layout(test);
+ background: green;
+ }
+}
+</style>
+<script src="/common/reftest-wait.js"></script>
+<script src="/common/worklet-reftest.js"></script>
+
+<div class="test"></div>
+<script>
+importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, {url: 'support/edges.js'});
+</script>
diff --git a/testing/web-platform/tests/css/css-layout-api/edges/scrollbar-ref.html b/testing/web-platform/tests/css/css-layout-api/edges/scrollbar-ref.html
new file mode 100644
index 0000000000..cc41754c08
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/edges/scrollbar-ref.html
@@ -0,0 +1,159 @@
+<!DOCTYPE html>
+<style>
+td { text-align: center; }
+
+.parent {
+ box-sizing: border-box;
+ width: 50px;
+ height: 50px;
+ border: solid;
+ position: relative;
+}
+
+.child {
+ position: absolute;
+ width: 10px;
+ height: 10px;
+ background: green;
+}
+
+.top-left {
+ top: 0;
+ left: 0;
+}
+
+.top-right {
+ top: 0;
+ right: 0;
+}
+
+.bottom-left {
+ bottom: 0;
+ left: 0;
+}
+
+.bottom-right {
+ bottom: 0;
+ right: 0;
+}
+</style>
+
+<table>
+ <tr>
+ <td></td>
+ <td colspan=2>LTR</td>
+ <td colspan=2>RTL</td>
+ </tr>
+ <tr>
+ <td></td>
+ <td>Y</td>
+ <td>X</td>
+ <td>Y</td>
+ <td>X</td>
+ </tr>
+ <tr>
+ <td>HTB</td>
+ <td>
+ <div class="parent" style="writing-mode: horizontal-tb; direction: ltr; overflow-y: scroll;">
+ <div class="child top-left"></div>
+ <div class="child top-right"></div>
+ <div class="child bottom-left"></div>
+ <div class="child bottom-right"></div>
+ </div>
+ </td>
+ <td>
+ <div class="parent" style="writing-mode: horizontal-tb; direction: ltr; overflow-x: scroll;">
+ <div class="child top-left"></div>
+ <div class="child top-right"></div>
+ <div class="child bottom-left"></div>
+ <div class="child bottom-right"></div>
+ </div>
+ </td>
+ <td>
+ <div class="parent" style="writing-mode: horizontal-tb; direction: rtl; overflow-y: scroll;">
+ <div class="child top-left"></div>
+ <div class="child top-right"></div>
+ <div class="child bottom-left"></div>
+ <div class="child bottom-right"></div>
+ </div>
+ </td>
+ <td>
+ <div class="parent" style="writing-mode: horizontal-tb; direction: rtl; overflow-x: scroll;">
+ <div class="child top-left"></div>
+ <div class="child top-right"></div>
+ <div class="child bottom-left"></div>
+ <div class="child bottom-right"></div>
+ </div>
+ </td>
+ </tr>
+ <tr>
+ <td>VRL</td>
+ <td>
+ <div class="parent" style="writing-mode: vertical-rl; direction: ltr; overflow-y: scroll;">
+ <div class="child top-left"></div>
+ <div class="child top-right"></div>
+ <div class="child bottom-left"></div>
+ <div class="child bottom-right"></div>
+ </div>
+ </td>
+ <td>
+ <div class="parent" style="writing-mode: vertical-rl; direction: ltr; overflow-x: scroll;">
+ <div class="child top-left"></div>
+ <div class="child top-right"></div>
+ <div class="child bottom-left"></div>
+ <div class="child bottom-right"></div>
+ </div>
+ </td>
+ <td>
+ <div class="parent" style="writing-mode: vertical-rl; direction: rtl; overflow-y: scroll;">
+ <div class="child top-left"></div>
+ <div class="child top-right"></div>
+ <div class="child bottom-left"></div>
+ <div class="child bottom-right"></div>
+ </div>
+ </td>
+ <td>
+ <div class="parent" style="writing-mode: vertical-rl; direction: rtl; overflow-x: scroll;">
+ <div class="child top-left"></div>
+ <div class="child top-right"></div>
+ <div class="child bottom-left"></div>
+ <div class="child bottom-right"></div>
+ </div>
+ </td>
+ </tr>
+ <tr>
+ <td>VLR</td>
+ <td>
+ <div class="parent" style="writing-mode: vertical-lr; direction: ltr; overflow-y: scroll;">
+ <div class="child top-left"></div>
+ <div class="child top-right"></div>
+ <div class="child bottom-left"></div>
+ <div class="child bottom-right"></div>
+ </div>
+ </td>
+ <td>
+ <div class="parent" style="writing-mode: vertical-lr; direction: ltr; overflow-x: scroll;">
+ <div class="child top-left"></div>
+ <div class="child top-right"></div>
+ <div class="child bottom-left"></div>
+ <div class="child bottom-right"></div>
+ </div>
+ </td>
+ <td>
+ <div class="parent" style="writing-mode: vertical-lr; direction: rtl; overflow-y: scroll;">
+ <div class="child top-left"></div>
+ <div class="child top-right"></div>
+ <div class="child bottom-left"></div>
+ <div class="child bottom-right"></div>
+ </div>
+ </td>
+ <td>
+ <div class="parent" style="writing-mode: vertical-lr; direction: rtl; overflow-x: scroll;">
+ <div class="child top-left"></div>
+ <div class="child top-right"></div>
+ <div class="child bottom-left"></div>
+ <div class="child bottom-right"></div>
+ </div>
+ </td>
+ </tr>
+</table>
diff --git a/testing/web-platform/tests/css/css-layout-api/edges/scrollbar.https.html b/testing/web-platform/tests/css/css-layout-api/edges/scrollbar.https.html
new file mode 100644
index 0000000000..76bbd4dccd
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/edges/scrollbar.https.html
@@ -0,0 +1,192 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#dom-layoutedges">
+<link rel="match" href="scrollbar-ref.html">
+<meta name="assert" content="This test checks that scrollbar sizes are passed to the layout correctly." />
+<style>
+td { text-align: center; }
+
+.parent {
+ box-sizing: border-box;
+ width: 50px;
+ height: 50px;
+ border: solid;
+ position: relative;
+ background: red;
+}
+
+@supports (display: layout(test)) {
+ .parent {
+ display: layout(test);
+ background: initial;
+ }
+}
+
+.child {
+ width: 10px;
+ height: 10px;
+ background: green;
+}
+</style>
+<!--
+ This test works by placing four children in each corner of the layout using the edges.
+ The reference to this test uses absolute positioning to achieve the same effect.
+-->
+<table>
+ <tr>
+ <td></td>
+ <td colspan=2>LTR</td>
+ <td colspan=2>RTL</td>
+ </tr>
+ <tr>
+ <td></td>
+ <td>Y</td>
+ <td>X</td>
+ <td>Y</td>
+ <td>X</td>
+ </tr>
+ <tr>
+ <td>HTB</td>
+ <td>
+ <div class="parent" style="writing-mode: horizontal-tb; direction: ltr; overflow-y: scroll;">
+ <div class="child"></div>
+ <div class="child"></div>
+ <div class="child"></div>
+ <div class="child"></div>
+ </div>
+ </td>
+ <td>
+ <div class="parent" style="writing-mode: horizontal-tb; direction: ltr; overflow-x: scroll;">
+ <div class="child"></div>
+ <div class="child"></div>
+ <div class="child"></div>
+ <div class="child"></div>
+ </div>
+ </td>
+ <td>
+ <div class="parent" style="writing-mode: horizontal-tb; direction: rtl; overflow-y: scroll;">
+ <div class="child"></div>
+ <div class="child"></div>
+ <div class="child"></div>
+ <div class="child"></div>
+ </div>
+ </td>
+ <td>
+ <div class="parent" style="writing-mode: horizontal-tb; direction: rtl; overflow-x: scroll;">
+ <div class="child"></div>
+ <div class="child"></div>
+ <div class="child"></div>
+ <div class="child"></div>
+ </div>
+ </td>
+ </tr>
+ <tr>
+ <td>VRL</td>
+ <td>
+ <div class="parent" style="writing-mode: vertical-rl; direction: ltr; overflow-y: scroll;">
+ <div class="child"></div>
+ <div class="child"></div>
+ <div class="child"></div>
+ <div class="child"></div>
+ </div>
+ </td>
+ <td>
+ <div class="parent" style="writing-mode: vertical-rl; direction: ltr; overflow-x: scroll;">
+ <div class="child"></div>
+ <div class="child"></div>
+ <div class="child"></div>
+ <div class="child"></div>
+ </div>
+ </td>
+ <td>
+ <div class="parent" style="writing-mode: vertical-rl; direction: rtl; overflow-y: scroll;">
+ <div class="child"></div>
+ <div class="child"></div>
+ <div class="child"></div>
+ <div class="child"></div>
+ </div>
+ </td>
+ <td>
+ <div class="parent" style="writing-mode: vertical-rl; direction: rtl; overflow-x: scroll;">
+ <div class="child"></div>
+ <div class="child"></div>
+ <div class="child"></div>
+ <div class="child"></div>
+ </div>
+ </td>
+ </tr>
+ <tr>
+ <td>VLR</td>
+ <td>
+ <div class="parent" style="writing-mode: vertical-lr; direction: ltr; overflow-y: scroll;">
+ <div class="child"></div>
+ <div class="child"></div>
+ <div class="child"></div>
+ <div class="child"></div>
+ </div>
+ </td>
+ <td>
+ <div class="parent" style="writing-mode: vertical-lr; direction: ltr; overflow-x: scroll;">
+ <div class="child"></div>
+ <div class="child"></div>
+ <div class="child"></div>
+ <div class="child"></div>
+ </div>
+ </td>
+ <td>
+ <div class="parent" style="writing-mode: vertical-lr; direction: rtl; overflow-y: scroll;">
+ <div class="child"></div>
+ <div class="child"></div>
+ <div class="child"></div>
+ <div class="child"></div>
+ </div>
+ </td>
+ <td>
+ <div class="parent" style="writing-mode: vertical-lr; direction: rtl; overflow-x: scroll;">
+ <div class="child"></div>
+ <div class="child"></div>
+ <div class="child"></div>
+ <div class="child"></div>
+ </div>
+ </td>
+ </tr>
+</table>
+<script src="/common/reftest-wait.js"></script>
+<script src="/common/worklet-reftest.js"></script>
+<script id="code" type="text/worklet">
+registerLayout('test', class {
+ async intrinsicSizes() {}
+ async layout(children, edges, constraints) {
+ const topLeftFragment = await children[0].layoutNextFragment();
+ const topRightFragment = await children[1].layoutNextFragment();
+ const bottomLeftFragment = await children[2].layoutNextFragment();
+ const bottomRightFragment = await children[3].layoutNextFragment();
+
+ topLeftFragment.inlineOffset = edges.inlineStart;
+ topLeftFragment.blockOffset = edges.blockStart;
+
+ topRightFragment.inlineOffset =
+ constraints.fixedInlineSize - topRightFragment.inlineSize - edges.inlineEnd;
+ topRightFragment.blockOffset = edges.blockStart;
+
+ bottomLeftFragment.inlineOffset = edges.inlineStart;
+ bottomLeftFragment.blockOffset =
+ constraints.fixedBlockSize - bottomLeftFragment.blockSize - edges.blockEnd;
+
+ bottomRightFragment.inlineOffset =
+ constraints.fixedInlineSize - bottomRightFragment.inlineSize - edges.inlineEnd;
+ bottomRightFragment.blockOffset =
+ constraints.fixedBlockSize - bottomRightFragment.blockSize - edges.blockEnd;
+
+ return {childFragments: [
+ topLeftFragment,
+ topRightFragment,
+ bottomLeftFragment,
+ bottomRightFragment
+ ]};
+ }
+});
+</script>
+<script>
+importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, document.getElementById('code').textContent);
+</script>
diff --git a/testing/web-platform/tests/css/css-layout-api/edges/support/edges.js b/testing/web-platform/tests/css/css-layout-api/edges/support/edges.js
new file mode 100644
index 0000000000..b70a42f398
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/edges/support/edges.js
@@ -0,0 +1,38 @@
+import {areArraysEqual} from '/common/arrays.js';
+
+function parseNumber(value) {
+ const num = parseInt(value.toString());
+ if (isNaN(num)) return 0;
+ return num;
+}
+
+registerLayout('test', class {
+ static get inputProperties() {
+ return [
+ '--edges-inline-start-expected',
+ '--edges-inline-end-expected',
+ '--edges-block-start-expected',
+ '--edges-block-end-expected',
+ ];
+ }
+
+ async intrinsicSizes() {}
+ async layout(children, edges, constraints, styleMap) {
+ const actual = this.constructor.inputProperties.map(
+ prop => parseNumber(styleMap.get(prop))
+ );
+
+ const expected = [
+ edges.inlineStart,
+ edges.inlineEnd,
+ edges.blockStart,
+ edges.blockEnd,
+ ];
+
+ if (!areArraysEqual(expected, actual)) {
+ return {autoBlockSize: 0, childFragments: []};
+ }
+
+ return {autoBlockSize: 100, childFragment: []};
+ }
+});
diff --git a/testing/web-platform/tests/css/css-layout-api/fallback-intrinsic-sizes/bad-return.https.html b/testing/web-platform/tests/css/css-layout-api/fallback-intrinsic-sizes/bad-return.https.html
new file mode 100644
index 0000000000..7ea0e93b86
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/fallback-intrinsic-sizes/bad-return.https.html
@@ -0,0 +1,49 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#invoke-an-intrinsic-sizes-callback">
+<link rel="match" href="fallback-ref.html">
+<meta name="assert" content="This test checks that a layout() class with the intrinsicSizes function returning a bad value will fallback to block layout." />
+<style>
+.test {
+ background: red;
+ border: solid 2px;
+ width: min-content;
+}
+
+.float {
+ float: left;
+ height: 100px;
+ width: 50%;
+}
+
+.fc {
+ display: flow-root;
+ height: 100px;
+}
+
+@supports (display: layout(bad-return)) {
+ .test {
+ display: layout(bad-return);
+ background: green;
+ }
+}
+</style>
+<script src="/common/reftest-wait.js"></script>
+<script src="/common/worklet-reftest.js"></script>
+
+<div class="test">
+ <div class="float"></div>
+ <div class="fc"></div>
+</div>
+
+<script id="code" type="text/worklet">
+registerLayout('bad-return', class {
+ async intrinsicSizes() { return 42; }
+ async layout() {}
+});
+</script>
+
+<script>
+importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, document.getElementById('code').textContent);
+</script>
+</html>
diff --git a/testing/web-platform/tests/css/css-layout-api/fallback-intrinsic-sizes/constructor-error.https.html b/testing/web-platform/tests/css/css-layout-api/fallback-intrinsic-sizes/constructor-error.https.html
new file mode 100644
index 0000000000..2078a49cda
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/fallback-intrinsic-sizes/constructor-error.https.html
@@ -0,0 +1,50 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#get-a-layout-class-instance">
+<link rel="match" href="fallback-ref.html">
+<meta name="assert" content="This test checks that a layout() class with a throwing constructor will fallback to block layout." />
+<style>
+.test {
+ background: red;
+ border: solid 2px;
+ width: min-content;
+}
+
+.float {
+ float: left;
+ width: 50%;
+ height: 100px;
+}
+
+.fc {
+ display: flow-root;
+ height: 100px;
+}
+
+@supports (display: layout(throwing-ctor)) {
+ .test {
+ display: layout(throwing-ctor);
+ background: green;
+ }
+}
+</style>
+<script src="/common/reftest-wait.js"></script>
+<script src="/common/worklet-reftest.js"></script>
+
+<div class="test">
+ <div class="float"></div>
+ <div class="fc"></div>
+</div>
+
+<script id="code" type="text/worklet">
+registerLayout('throwing-ctor', class {
+ constructor() { throw Error('fail!'); }
+ async intrinsicSizes() {}
+ async layout() {}
+});
+</script>
+
+<script>
+importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, document.getElementById('code').textContent);
+</script>
+</html>
diff --git a/testing/web-platform/tests/css/css-layout-api/fallback-intrinsic-sizes/error.https.html b/testing/web-platform/tests/css/css-layout-api/fallback-intrinsic-sizes/error.https.html
new file mode 100644
index 0000000000..3a6665d8aa
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/fallback-intrinsic-sizes/error.https.html
@@ -0,0 +1,49 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#invoke-an-intrinsic-sizes-callback">
+<link rel="match" href="fallback-ref.html">
+<meta name="assert" content="This test checks that a layout() class with a throwing intrinsicSizes function will fallback to block layout." />
+<style>
+.test {
+ background: red;
+ border: solid 2px;
+ width: min-content;
+}
+
+.float {
+ float: left;
+ height: 100px;
+ width: 50%;
+}
+
+.fc {
+ display: flow-root;
+ height: 100px;
+}
+
+@supports (display: layout(throwing-intrinsic-sizes)) {
+ .test {
+ display: layout(throwing-intrinsic-sizes);
+ background: green;
+ }
+}
+</style>
+<script src="/common/reftest-wait.js"></script>
+<script src="/common/worklet-reftest.js"></script>
+
+<div class="test">
+ <div class="float"></div>
+ <div class="fc"></div>
+</div>
+
+<script id="code" type="text/worklet">
+registerLayout('throwing-intrinsic-sizes', class {
+ async intrinsicSizes() { throw Error('fail!'); }
+ async layout() {}
+});
+</script>
+
+<script>
+importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, document.getElementById('code').textContent);
+</script>
+</html>
diff --git a/testing/web-platform/tests/css/css-layout-api/fallback-intrinsic-sizes/fallback-ref.html b/testing/web-platform/tests/css/css-layout-api/fallback-intrinsic-sizes/fallback-ref.html
new file mode 100644
index 0000000000..6808e14eb6
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/fallback-intrinsic-sizes/fallback-ref.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<style>
+.result {
+ background: green;
+ border: solid 2px;
+ height: 100px;
+ width: min-content;
+}
+</style>
+
+<div class="result"></div>
diff --git a/testing/web-platform/tests/css/css-layout-api/fallback-intrinsic-sizes/invalid-child.https.html b/testing/web-platform/tests/css/css-layout-api/fallback-intrinsic-sizes/invalid-child.https.html
new file mode 100644
index 0000000000..c21d1577e4
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/fallback-intrinsic-sizes/invalid-child.https.html
@@ -0,0 +1,84 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#invoke-an-intrinsic-sizes-callback">
+<link rel="match" href="fallback-ref.html">
+<meta name="assert" content="This test checks that a layout() class performing intrinsicSizes on an invalid child will fallback to block layout." />
+<style>
+.test {
+ background: red;
+ border: solid 2px;
+ width: min-content;
+}
+
+.test > div {
+ height: 100px;
+}
+
+@supports (display: layout(bad-child-layout)) {
+ .test {
+ display: layout(bad-child-layout);
+ background: green;
+ }
+}
+</style>
+<script src="/common/reftest-wait.js"></script>
+<script src="/common/worklet-reftest.js"></script>
+
+<div class="test">
+ <div></div>
+</div>
+
+<script id="code" type="text/worklet">
+registerLayout('bad-child-layout', class {
+ static get inputProperties() { return ['--fail']; }
+
+ async intrinsicSizes(children, _, styleMap) {
+ if (styleMap.get('--fail').toString() !== 'true') {
+ this.child = children[0];
+ }
+
+ // Try to perform layout on the child. If its invalid (we skipped the if
+ // statement above) we should fallback to block layout.
+ const childIntrinsicSize = await this.child.intrinsicSizes();
+
+ return { maxContentSize: 100, minContentSize: 100 };
+ }
+ async layout() {}
+});
+</script>
+
+<script>
+function raf() {
+ return new Promise((resolve) => {
+ requestAnimationFrame(() => {
+ resolve();
+ });
+ });
+}
+
+(async function() {
+ if (typeof CSS.layoutWorklet === 'undefined') {
+ takeScreenshot();
+ return;
+ }
+
+ await importWorklet(CSS.layoutWorklet, document.getElementById('code').textContent);
+
+ // Ensure that all instances have a child to perform an invalid intrinsic size upon.
+ const test = document.getElementsByClassName('test')[0];
+ for (let i = 0; i < 100; i++) {
+ test.innerHTML = '<div><div>';
+ await raf();
+ }
+
+ // The next layout should mean that we will fallback to block.
+ test.innerHTML = '<div></div>';
+ test.style.setProperty('--fail', 'true');
+
+ // Finish up the test.
+ await raf();
+ await raf();
+ takeScreenshot();
+})();
+</script>
+</html>
diff --git a/testing/web-platform/tests/css/css-layout-api/fallback-intrinsic-sizes/no-promise.https.html b/testing/web-platform/tests/css/css-layout-api/fallback-intrinsic-sizes/no-promise.https.html
new file mode 100644
index 0000000000..c5ec721b54
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/fallback-intrinsic-sizes/no-promise.https.html
@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#invoke-an-intrinsic-sizes-callback">
+<link rel="match" href="fallback-ref.html">
+<meta name="assert" content="This test checks that a layout() class with an intrinsicSizes function that doesn't return a promise will fallback to block layout." />
+<style>
+.test {
+ background: red;
+ border: solid 2px;
+ width: min-content;
+}
+
+.child {
+ height: 100px;
+}
+
+@supports (display: layout(no-promise)) {
+ .test {
+ display: layout(no-promise);
+ background: green;
+ }
+}
+</style>
+<script src="/common/reftest-wait.js"></script>
+<script src="/common/worklet-reftest.js"></script>
+
+<div class="test">
+ <div class="child"></div>
+</div>
+
+<script id="code" type="text/worklet">
+registerLayout('no-promise', class {
+ intrinsicSizes() { return { minContentSize: 100 }; }
+ async layout() {}
+});
+</script>
+
+<script>
+importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, document.getElementById('code').textContent);
+</script>
+</html>
diff --git a/testing/web-platform/tests/css/css-layout-api/fallback-intrinsic-sizes/unresolved-promise.https.html b/testing/web-platform/tests/css/css-layout-api/fallback-intrinsic-sizes/unresolved-promise.https.html
new file mode 100644
index 0000000000..f56e331a5a
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/fallback-intrinsic-sizes/unresolved-promise.https.html
@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#invoke-an-intrinsic-sizes-callback">
+<link rel="match" href="fallback-ref.html">
+<meta name="assert" content="This test checks that a layout() class with an intrinsicSizes function that doesn't return a promise will fallback to block layout." />
+<style>
+.test {
+ background: red;
+ border: solid 2px;
+ width: min-content;
+}
+
+.child {
+ height: 100px;
+}
+
+@supports (display: layout(unresolved-promise)) {
+ .test {
+ display: layout(unresolved-promise);
+ background: green;
+ }
+}
+</style>
+<script src="/common/reftest-wait.js"></script>
+<script src="/common/worklet-reftest.js"></script>
+
+<div class="test">
+ <div class="child"></div>
+</div>
+
+<script id="code" type="text/worklet">
+registerLayout('unresolved-promise', class {
+ intrinsicSizes() { return new Promise(() => { /* never resolves */ }); }
+ async layout() {}
+});
+</script>
+
+<script>
+importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, document.getElementById('code').textContent);
+</script>
+</html>
diff --git a/testing/web-platform/tests/css/css-layout-api/fallback-layout/bad-return.https.html b/testing/web-platform/tests/css/css-layout-api/fallback-layout/bad-return.https.html
new file mode 100644
index 0000000000..3e671537c9
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/fallback-layout/bad-return.https.html
@@ -0,0 +1,50 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#invoke-a-layout-callback">
+<link rel="match" href="fallback-layout-fallback-ref.html">
+<meta name="assert" content="This test checks that a layout() class with the layout function returning a bad value will fallback to block layout." />
+<style>
+.test {
+ background: red;
+ border: solid 2px;
+ width: 100px;
+}
+
+.float {
+ float: left;
+ width: 50%;
+ height: 100px;
+}
+
+.fc {
+ display: flow-root;
+ height: 100px;
+}
+
+@supports (display: layout(bad-return)) {
+ .test {
+ display: layout(bad-return);
+ background: green;
+ }
+}
+</style>
+<script src="/common/reftest-wait.js"></script>
+<script src="/common/worklet-reftest.js"></script>
+
+<!-- This tests that when the "layout()" layout function returns a bad value, it will fallback to block layout. -->
+<div class="test">
+ <div class="float"></div>
+ <div class="fc"></div>
+</div>
+
+<script id="code" type="text/worklet">
+registerLayout('bad-return', class {
+ async intrinsicSizes() {}
+ async layout() { return 42; }
+});
+</script>
+
+<script>
+importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, document.getElementById('code').textContent);
+</script>
+</html>
diff --git a/testing/web-platform/tests/css/css-layout-api/fallback-layout/constructor-error.https.html b/testing/web-platform/tests/css/css-layout-api/fallback-layout/constructor-error.https.html
new file mode 100644
index 0000000000..9ce791ab5b
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/fallback-layout/constructor-error.https.html
@@ -0,0 +1,51 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#get-a-layout-class-instance">
+<link rel="match" href="fallback-layout-fallback-ref.html">
+<meta name="assert" content="This test checks that a layout() class with a throwing constructor will fallback to block layout." />
+<style>
+.test {
+ background: red;
+ border: solid 2px;
+ width: 100px;
+}
+
+.float {
+ float: left;
+ width: 50%;
+ height: 100px;
+}
+
+.fc {
+ display: flow-root;
+ height: 100px;
+}
+
+@supports (display: layout(throwing-ctor)) {
+ .test {
+ display: layout(throwing-ctor);
+ background: green;
+ }
+}
+</style>
+<script src="/common/reftest-wait.js"></script>
+<script src="/common/worklet-reftest.js"></script>
+
+<!-- This tests that when the "layout()" constructor fails, it will fallback to block layout. -->
+<div class="test">
+ <div class="float"></div>
+ <div class="fc"></div>
+</div>
+
+<script id="code" type="text/worklet">
+registerLayout('throwing-ctor', class {
+ constructor() { throw Error('fail!'); }
+ async intrinsicSizes() {}
+ async layout() {}
+});
+</script>
+
+<script>
+importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, document.getElementById('code').textContent);
+</script>
+</html>
diff --git a/testing/web-platform/tests/css/css-layout-api/fallback-layout/error.https.html b/testing/web-platform/tests/css/css-layout-api/fallback-layout/error.https.html
new file mode 100644
index 0000000000..0631193e1f
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/fallback-layout/error.https.html
@@ -0,0 +1,50 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#invoke-a-layout-callback">
+<link rel="match" href="fallback-layout-fallback-ref.html">
+<meta name="assert" content="This test checks that a layout() class with a throwing layout function will fallback to block layout." />
+<style>
+.test {
+ background: red;
+ border: solid 2px;
+ width: 100px;
+}
+
+.float {
+ float: left;
+ width: 50%;
+ height: 100px;
+}
+
+.fc {
+ display: flow-root;
+ height: 100px;
+}
+
+@supports (display: layout(throwing-layout)) {
+ .test {
+ display: layout(throwing-layout);
+ background: green;
+ }
+}
+</style>
+<script src="/common/reftest-wait.js"></script>
+<script src="/common/worklet-reftest.js"></script>
+
+<!-- This tests that when the "layout()" layout function fails, it will fallback to block layout. -->
+<div class="test">
+ <div class="float"></div>
+ <div class="fc"></div>
+</div>
+
+<script id="code" type="text/worklet">
+registerLayout('throwing-layout', class {
+ async intrinsicSizes() {}
+ async layout() { throw Error('fail!'); }
+});
+</script>
+
+<script>
+importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, document.getElementById('code').textContent);
+</script>
+</html>
diff --git a/testing/web-platform/tests/css/css-layout-api/fallback-layout/fallback-layout-fallback-ref.html b/testing/web-platform/tests/css/css-layout-api/fallback-layout/fallback-layout-fallback-ref.html
new file mode 100644
index 0000000000..63bb91e90c
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/fallback-layout/fallback-layout-fallback-ref.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<style>
+.result {
+ background: green;
+ border: solid 2px;
+ height: 100px;
+ width: 100px;
+}
+</style>
+
+<div class="result"></div>
diff --git a/testing/web-platform/tests/css/css-layout-api/fallback-layout/invalid-child.https.html b/testing/web-platform/tests/css/css-layout-api/fallback-layout/invalid-child.https.html
new file mode 100644
index 0000000000..fb48ac7602
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/fallback-layout/invalid-child.https.html
@@ -0,0 +1,84 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#invoke-a-layout-callback">
+<link rel="match" href="fallback-layout-fallback-ref.html">
+<meta name="assert" content="This test checks that a layout() class performing layout on an invalid child will fallback to block layout." />
+<style>
+.test {
+ background: red;
+ border: solid 2px;
+ width: 100px;
+}
+
+.test > div {
+ height: 100px;
+}
+
+@supports (display: layout(bad-child-layout)) {
+ .test {
+ display: layout(bad-child-layout);
+ background: green;
+ }
+}
+</style>
+<script src="/common/reftest-wait.js"></script>
+<script src="/common/worklet-reftest.js"></script>
+
+<div class="test">
+ <div></div>
+</div>
+
+<script id="code" type="text/worklet">
+registerLayout('bad-child-layout', class {
+ static get inputProperties() { return ['--fail']; }
+
+ async intrinsicSizes() {}
+ async layout(children, _, __, styleMap) {
+ if (styleMap.get('--fail').toString() !== 'true') {
+ this.child = children[0];
+ }
+
+ // Try to perform layout on the child. If its invalid (we skipped the if
+ // statement above) we should fallback to block layout.
+ const fragment = await this.child.layoutNextFragment({});
+
+ return {autoBlockSize: 0, childFragments: [fragment]};
+ }
+});
+</script>
+
+<script>
+function raf() {
+ return new Promise((resolve) => {
+ requestAnimationFrame(() => {
+ resolve();
+ });
+ });
+}
+
+(async function() {
+ if (typeof CSS.layoutWorklet === 'undefined') {
+ takeScreenshot();
+ return;
+ }
+
+ await importWorklet(CSS.layoutWorklet, document.getElementById('code').textContent);
+
+ // Ensure that all instances have a child to perform an invalid layout upon.
+ const test = document.getElementsByClassName('test')[0];
+ for (let i = 0; i < 100; i++) {
+ test.innerHTML = '<div><div>';
+ await raf();
+ }
+
+ // The next layout should mean that we will fallback to block.
+ test.innerHTML = '<div></div>';
+ test.style.setProperty('--fail', 'true');
+
+ // Finish up the test.
+ await raf();
+ await raf();
+ takeScreenshot();
+})();
+</script>
+</html>
diff --git a/testing/web-platform/tests/css/css-layout-api/fallback-layout/invalid-fragment.https.html b/testing/web-platform/tests/css/css-layout-api/fallback-layout/invalid-fragment.https.html
new file mode 100644
index 0000000000..d954f44ba3
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/fallback-layout/invalid-fragment.https.html
@@ -0,0 +1,82 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#invoke-a-layout-callback">
+<link rel="match" href="fallback-layout-fallback-ref.html">
+<meta name="assert" content="This test checks that a layout() class returning an invalid fragment will fallback to block layout." />
+<style>
+.test {
+ background: red;
+ border: solid 2px;
+ width: 100px;
+}
+
+.test > div {
+ height: 100px;
+}
+
+@supports (display: layout(bad-request)) {
+ .test {
+ display: layout(bad-request);
+ background: green;
+ }
+}
+</style>
+<script src="/common/reftest-wait.js"></script>
+<script src="/common/worklet-reftest.js"></script>
+
+<div class="test">
+ <div></div>
+</div>
+
+<script id="code" type="text/worklet">
+registerLayout('bad-request', class {
+ static get inputProperties() { return ['--fail']; }
+
+ async intrinsicSizes() {}
+ async layout(children, _, __, styleMap) {
+ if (styleMap.get('--fail').toString() !== 'true') {
+ this.fragment = await children[0].layoutNextFragment({});
+ }
+
+ // Return, if the fragment is invalid (we skipped the if statement above)
+ // we should fallback to block layout.
+ return {autoBlockSize: 0, childFragments: [this.fragment]};
+ }
+});
+</script>
+
+<script>
+function raf() {
+ return new Promise((resolve) => {
+ requestAnimationFrame(() => {
+ resolve();
+ });
+ });
+}
+
+(async function() {
+ if (typeof CSS.layoutWorklet === 'undefined') {
+ takeScreenshot();
+ return;
+ }
+
+ await importWorklet(CSS.layoutWorklet, document.getElementById('code').textContent);
+
+ // Ensure that all instances have a child to perform an invalid layout upon.
+ const test = document.getElementsByClassName('test')[0];
+ for (let i = 0; i < 100; i++) {
+ test.innerHTML = '<div><div>';
+ await raf();
+ }
+
+ // The next layout should mean that we will fallback to block.
+ test.innerHTML = '<div></div>';
+ test.style.setProperty('--fail', 'true');
+
+ // Finish up the test.
+ await raf();
+ await raf();
+ takeScreenshot();
+})();
+</script>
+</html>
diff --git a/testing/web-platform/tests/css/css-layout-api/fallback-layout/no-promise.https.html b/testing/web-platform/tests/css/css-layout-api/fallback-layout/no-promise.https.html
new file mode 100644
index 0000000000..00670f7bbe
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/fallback-layout/no-promise.https.html
@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#invoke-a-layout-callback">
+<link rel="match" href="fallback-layout-fallback-ref.html">
+<meta name="assert" content="This test checks that a layout() class with a layout function that doesn't return a promise will fallback to block layout." />
+<style>
+.test {
+ background: red;
+ border: solid 2px;
+ width: 100px;
+}
+
+.child {
+ height: 100px;
+}
+
+@supports (display: layout(no-promise)) {
+ .test {
+ display: layout(no-promise);
+ background: green;
+ }
+}
+</style>
+<script src="/common/reftest-wait.js"></script>
+<script src="/common/worklet-reftest.js"></script>
+
+<div class="test">
+ <div class="child"></div>
+</div>
+
+<script id="code" type="text/worklet">
+registerLayout('no-promise', class {
+ async intrinsicSizes() {}
+ layout() { return {autoBlockSize: 50}; }
+});
+</script>
+
+<script>
+importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, document.getElementById('code').textContent);
+</script>
+</html>
diff --git a/testing/web-platform/tests/css/css-layout-api/fallback-layout/unresolved-promise.https.html b/testing/web-platform/tests/css/css-layout-api/fallback-layout/unresolved-promise.https.html
new file mode 100644
index 0000000000..72ce549acf
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/fallback-layout/unresolved-promise.https.html
@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#invoke-a-layout-callback">
+<link rel="match" href="fallback-layout-fallback-ref.html">
+<meta name="assert" content="This test checks that a layout() class with a layout function that doesn't return a promise will fallback to block layout." />
+<style>
+.test {
+ background: red;
+ border: solid 2px;
+ width: 100px;
+}
+
+.child {
+ height: 100px;
+}
+
+@supports (display: layout(unresolved-promise)) {
+ .test {
+ display: layout(unresolved-promise);
+ background: green;
+ }
+}
+</style>
+<script src="/common/reftest-wait.js"></script>
+<script src="/common/worklet-reftest.js"></script>
+
+<div class="test">
+ <div class="child"></div>
+</div>
+
+<script id="code" type="text/worklet">
+registerLayout('unresolved-promise', class {
+ async intrinsicSizes() {}
+ layout() { return new Promise(() => { /* never resolves */ }); }
+});
+</script>
+
+<script>
+importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, document.getElementById('code').textContent);
+</script>
+</html>
diff --git a/testing/web-platform/tests/css/css-layout-api/fragment-data-function-failure.https.html b/testing/web-platform/tests/css/css-layout-api/fragment-data-function-failure.https.html
new file mode 100644
index 0000000000..8496967be0
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/fragment-data-function-failure.https.html
@@ -0,0 +1,43 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#dom-layoutfragment-data">
+<link rel="match" href="green-square-ref.html">
+<meta name="assert" content="This test checks that passing something that can't be serialized to the parent triggers a fallback to block layout." />
+<style>
+.test {
+ background: red;
+ width: 100px;
+}
+
+.child {
+ height: 100px;
+}
+
+@supports (display: layout(fallback-fn)) {
+ .test {
+ display: layout(fallback-fn);
+ background: green;
+ }
+}
+</style>
+<script src="/common/reftest-wait.js"></script>
+<script src="/common/worklet-reftest.js"></script>
+
+<div class="test">
+ <div class="child"></div>
+</div>
+
+<script id="code" type="text/worklet">
+registerLayout('fallback-fn', class {
+ async intrinsicSizes() {}
+ async layout(children, edges, constraints, styleMap) {
+ const childFragments = await children.map(child => child.layoutNextFragment());
+ return {autoBlockSize: 0, childFragments, data: {fn: function() {}}};
+ }
+});
+</script>
+
+<script>
+importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, document.getElementById('code').textContent);
+</script>
+</html>
diff --git a/testing/web-platform/tests/css/css-layout-api/fragment-data-immutable.https.html b/testing/web-platform/tests/css/css-layout-api/fragment-data-immutable.https.html
new file mode 100644
index 0000000000..e33a6ff0ee
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/fragment-data-immutable.https.html
@@ -0,0 +1,69 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#dom-layoutfragment-data">
+<link rel="match" href="green-square-ref.html">
+<meta name="assert" content="This test checks that LayoutFragment#data is immutable between child layout passes." />
+<style>
+.test {
+ background: red;
+ width: 100px;
+}
+
+@supports (display: layout(parent)) {
+ .test {
+ display: layout(parent);
+ background: green;
+ }
+
+ .child {
+ display: layout(child);
+ }
+}
+</style>
+<script src="/common/reftest-wait.js"></script>
+<script src="/common/worklet-reftest.js"></script>
+
+<div class="test">
+ <div class="child"></div>
+</div>
+
+<script id="code" type="text/worklet">
+registerLayout('parent', class {
+ async intrinsicSizes() {}
+ async layout([child], edges, constraints, styleMap) {
+
+ const childFragment10 = await child.layoutNextFragment({fixedInlineSize: 10});
+
+ // First layout data should be "10".
+ if (childFragment10.data.size !== 10) {
+ return {autoBlockSize: 0, childFragments: [childFragment10]};
+ }
+
+ const childFragment20 = await child.layoutNextFragment({fixedInlineSize: 20});
+
+ // Second layout data should be "20".
+ if (childFragment20.data.size !== 20) {
+ return {autoBlockSize: 0, childFragments: [childFragment10]};
+ }
+
+ // First layout data should still be "10".
+ if (childFragment10.data.size !== 10) {
+ return {autoBlockSize: 0, childFragments: [childFragment10]};
+ }
+
+ return {autoBlockSize: 100, childFragments: [childFragment20]};
+ }
+});
+
+registerLayout('child', class {
+ async intrinsicSizes() {}
+ async layout(children, edges, constraints, styleMap) {
+ return {autoBlockSize: 10, data: {size: constraints.fixedInlineSize}};
+ }
+});
+</script>
+
+<script>
+importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, document.getElementById('code').textContent);
+</script>
+</html>
diff --git a/testing/web-platform/tests/css/css-layout-api/fragment-data-sab-failure.https.html b/testing/web-platform/tests/css/css-layout-api/fragment-data-sab-failure.https.html
new file mode 100644
index 0000000000..681de5b543
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/fragment-data-sab-failure.https.html
@@ -0,0 +1,45 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#dom-layoutfragment-data">
+<link rel="match" href="green-square-ref.html">
+<meta name="assert" content="This test checks that a SharedArrayBuffer can't be passed to the parent layout." />
+<style>
+.test {
+ background: red;
+ width: 100px;
+}
+
+.child {
+ height: 100px;
+}
+
+@supports (display: layout(fallback-sab)) {
+ .test {
+ display: layout(fallback-sab);
+ background: green;
+ }
+}
+</style>
+<script src="/common/reftest-wait.js"></script>
+<script src="/common/worklet-reftest.js"></script>
+
+<div class="test">
+ <div class="child"></div>
+</div>
+
+<script id="code" type="text/worklet">
+registerLayout('fallback-sab', class {
+ async intrinsicSizes() {}
+ async layout(children, edges, constraints, styleMap) {
+ const childFragments = await Promise.all(children.map(child => child.layoutNextFragment()));
+
+ // See https://github.com/whatwg/html/issues/5380 for why not `new SharedArrayBuffer()`
+ return {autoBlockSize: 0, childFragments, data: {sab: new WebAssembly.Memory({ shared:true, initial:1, maximum:1 }).buffer }};
+ }
+});
+</script>
+
+<script>
+importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, document.getElementById('code').textContent);
+</script>
+</html>
diff --git a/testing/web-platform/tests/css/css-layout-api/fragment-data.https.html b/testing/web-platform/tests/css/css-layout-api/fragment-data.https.html
new file mode 100644
index 0000000000..ffc360ab35
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/fragment-data.https.html
@@ -0,0 +1,64 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#dom-layoutfragment-data">
+<link rel="match" href="green-square-ref.html">
+<meta name="assert" content="This test checks that passing data to a parent layout works correctly." />
+<style>
+.test {
+ background: red;
+ width: 100px;
+}
+
+@supports (display: layout(parent)) {
+ .test {
+ display: layout(parent);
+ background: green;
+ }
+
+ .child {
+ display: layout(child);
+ }
+}
+</style>
+<script src="/common/reftest-wait.js"></script>
+<script src="/common/worklet-reftest.js"></script>
+
+<div class="test">
+ <div class="child"></div>
+</div>
+
+<script id="code" type="text/worklet">
+const DATA = {
+ str: 'hello',
+ num: 42,
+ obj: {str2: 'world'},
+};
+
+registerLayout('parent', class {
+ async intrinsicSizes() {}
+ async layout([child], edges, constraints, styleMap) {
+
+ const childFragment = await child.layoutNextFragment();
+
+ // Use JSON.stringify to make sure the structured cloning worked.
+ if (childFragment.data !== DATA &&
+ JSON.stringify(childFragment.data) === JSON.stringify(DATA)) {
+ return {autoBlockSize: 100, childFragments: [childFragment]};
+ }
+
+ return {autoBlockSize: 0, childFragments: [childFragment]};
+ }
+});
+
+registerLayout('child', class {
+ async intrinsicSizes() {}
+ async layout(children, edges, constraints, styleMap) {
+ return {autoBlockSize: 10, data: DATA};
+ }
+});
+</script>
+
+<script>
+importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, document.getElementById('code').textContent);
+</script>
+</html>
diff --git a/testing/web-platform/tests/css/css-layout-api/green-square-ref.html b/testing/web-platform/tests/css/css-layout-api/green-square-ref.html
new file mode 100644
index 0000000000..a28e43be4a
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/green-square-ref.html
@@ -0,0 +1,9 @@
+<!DOCTYPE html>
+<style>
+.result {
+ background: green;
+ height: 100px;
+ width: 100px;
+}
+</style>
+<div class="result"></div>
diff --git a/testing/web-platform/tests/css/css-layout-api/inline-style-layout-function.https.html b/testing/web-platform/tests/css/css-layout-api/inline-style-layout-function.https.html
new file mode 100644
index 0000000000..f11405b8e8
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/inline-style-layout-function.https.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#valdef-display-layout">
+<meta name="assert" content="This test checks that a layout() function is parses and serializes correctly from inline style." />
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+
+<div id=test1></div>
+<div id=test2></div>
+<div id=test3></div>
+<script>
+test(function() {
+ const test1 = document.getElementById('test1');
+ assert_equals(test1.style.display, '');
+
+ test1.style.display = 'layout(test1)';
+ assert_equals(test1.style.display, 'layout(test1)');
+});
+
+test(function() {
+ const test2 = document.getElementById('test2');
+ assert_equals(test2.style.display, '');
+
+ // layout() should fail to parse.
+ test2.style.display = 'layout()';
+ assert_equals(test2.style.display, '');
+});
+
+test(function() {
+ const test3 = document.getElementById('test3');
+ assert_equals(test3.style.display, '');
+
+ // layout(test3, invalid) should fail to parse.
+ test3.style.display = 'layout(test3, invalid)';
+ assert_equals(test3.style.display, '');
+});
+</script>
diff --git a/testing/web-platform/tests/css/css-layout-api/input-text-crash.https.html b/testing/web-platform/tests/css/css-layout-api/input-text-crash.https.html
new file mode 100644
index 0000000000..2d32609040
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/input-text-crash.https.html
@@ -0,0 +1,4 @@
+<!DOCTYPE html>
+<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org">
+<link rel="help" href="https://bugs.chromium.org/p/chromium/issues/detail?id=1181687">
+<input style="display:layout(success);">
diff --git a/testing/web-platform/tests/css/css-layout-api/inside-multicol-crash.https.html b/testing/web-platform/tests/css/css-layout-api/inside-multicol-crash.https.html
new file mode 100644
index 0000000000..61223bfcdc
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/inside-multicol-crash.https.html
@@ -0,0 +1,8 @@
+<!DOCTYPE html>
+<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org">
+<link rel="help" href="https://bugs.chromium.org/p/chromium/issues/detail?id=1127112#c7">
+<div style="columns:16;">
+ <div style="display:layout(child-layout);">
+ <div></div>
+ </div>
+</div>
diff --git a/testing/web-platform/tests/css/css-layout-api/intrinsic-sizes/absolute-ref.html b/testing/web-platform/tests/css/css-layout-api/intrinsic-sizes/absolute-ref.html
new file mode 100644
index 0000000000..2f23f68b60
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/intrinsic-sizes/absolute-ref.html
@@ -0,0 +1,43 @@
+<!DOCTYPE html>
+<style>
+.test {
+ background: green;
+ position: absolute;
+}
+
+.container-1 {
+ border: solid 2px;
+ position: relative;
+ height: 200px;
+ width: 300px;
+}
+
+.container-2 {
+ border: solid 2px;
+ position: relative;
+ height: 25px;
+ width: 25px;
+}
+
+.horizontal {
+ writing-mode: horizontal-tb;
+}
+
+.vertical {
+ writing-mode: vertical-rl;
+}
+
+</style>
+
+<div class="container-1">
+ <div class="horizontal test" style="height: 100px; width: 100px; bottom: 0px;"></div>
+ <div class="vertical test" style="height: 100px; width: 100px; right: 0px;"></div>
+</div>
+
+<div class="container-2">
+ <div class="horizontal test" style="height: 25px; width: 50px; bottom: 0px;"></div>
+</div>
+
+<div class="container-2">
+ <div class="vertical test" style="height: 50px; width: 25px; right: 0px;"></div>
+</div>
diff --git a/testing/web-platform/tests/css/css-layout-api/intrinsic-sizes/absolute.https.html b/testing/web-platform/tests/css/css-layout-api/intrinsic-sizes/absolute.https.html
new file mode 100644
index 0000000000..be654ecbc7
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/intrinsic-sizes/absolute.https.html
@@ -0,0 +1,73 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#interaction-sizing">
+<link rel="match" href="absolute-ref.html">
+<meta name="assert" content="This test checks that the absolute positioning respects the intrinsicSizes function." />
+
+<style>
+.test {
+ background: red;
+ position: absolute;
+}
+
+@supports (display: layout(test-layout)) {
+ .test {
+ display: layout(test-layout);
+ background: green;
+ }
+}
+
+.container-1 {
+ border: solid 2px;
+ position: relative;
+ height: 200px;
+ width: 300px;
+}
+
+.container-2 {
+ border: solid 2px;
+ position: relative;
+ height: 25px;
+ width: 25px;
+}
+
+.horizontal {
+ writing-mode: horizontal-tb;
+}
+
+.vertical {
+ writing-mode: vertical-rl;
+}
+
+</style>
+<script src="/common/reftest-wait.js"></script>
+<script src="/common/worklet-reftest.js"></script>
+
+
+<div class="container-1">
+ <div class="horizontal test" style="height: 100px; bottom: 0px;"></div>
+ <div class="vertical test" style="width: 100px; right: 0px;"></div>
+</div>
+
+<div class="container-2">
+ <div class="horizontal test" style="height: 25px; bottom: 0px;"></div>
+</div>
+
+<div class="container-2">
+ <div class="vertical test" style="width: 25px; right: 0px;"></div>
+</div>
+
+
+<script id="code" type="text/worklet">
+registerLayout('test-layout', class {
+ async intrinsicSizes() {
+ return { maxContentSize: 100, minContentSize: 50 };
+ }
+ async layout() {}
+});
+</script>
+
+<script>
+importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, document.getElementById('code').textContent);
+</script>
+</html>
diff --git a/testing/web-platform/tests/css/css-layout-api/intrinsic-sizes/child-replaced-percentage-01.https.html b/testing/web-platform/tests/css/css-layout-api/intrinsic-sizes/child-replaced-percentage-01.https.html
new file mode 100644
index 0000000000..058428601d
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/intrinsic-sizes/child-replaced-percentage-01.https.html
@@ -0,0 +1,47 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#intrinsic-sizes">
+<link rel="match" href="child-replaced-percentage-ref.html">
+<meta name="assert" content="This test checks that intrinsicSizes is calculated correctly for a replaced child element with a percentage height." />
+<style>
+.test {
+ background: red;
+ height: 50px;
+ width: min-content;
+}
+
+@supports (display: layout(parent)) {
+ .test {
+ display: layout(parent);
+ background: green;
+ }
+}
+</style>
+<script src="/common/reftest-wait.js"></script>
+<script src="/common/worklet-reftest.js"></script>
+
+<div class="test">
+ <canvas width=100 height=100 style="height: 100%;"></canvas>
+</div>
+
+<script id="code" type="text/worklet">
+registerLayout('parent', class {
+ async intrinsicSizes(children, edges, styleMap) {
+ const childrenSizes = await Promise.all(children.map((child) => {
+ return child.intrinsicSizes();
+ }));
+
+ if (childrenSizes[0].minContentSize == 50 &&
+ childrenSizes[0].maxContentSize == 50) {
+ return { maxContentSize: 100, minContentSize: 50 };
+ }
+ return { maxContentSize: 0, minContentSize: 0 };
+ }
+ async layout() {}
+});
+</script>
+
+<script>
+importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, document.getElementById('code').textContent);
+</script>
+</html>
diff --git a/testing/web-platform/tests/css/css-layout-api/intrinsic-sizes/child-replaced-percentage-02.https.html b/testing/web-platform/tests/css/css-layout-api/intrinsic-sizes/child-replaced-percentage-02.https.html
new file mode 100644
index 0000000000..42e8207b5b
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/intrinsic-sizes/child-replaced-percentage-02.https.html
@@ -0,0 +1,49 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#intrinsic-sizes">
+<link rel="match" href="child-replaced-percentage-ref.html">
+<meta name="assert" content="This test checks that intrinsicSizes is calculated correctly for a replaced child element with a percentage height." />
+<style>
+.test {
+ background: red;
+ height: 50px;
+ width: min-content;
+}
+
+@supports (display: layout(parent)) {
+ .test {
+ display: layout(parent);
+ background: green;
+ }
+}
+</style>
+<script src="/common/reftest-wait.js"></script>
+<script src="/common/worklet-reftest.js"></script>
+
+<div class="test">
+ <div style="height: 50%">
+ <canvas width=100 height=100 style="height: 100%;"></canvas>
+ </div>
+</div>
+
+<script id="code" type="text/worklet">
+registerLayout('parent', class {
+ async intrinsicSizes(children, edges, styleMap) {
+ const childrenSizes = await Promise.all(children.map((child) => {
+ return child.intrinsicSizes();
+ }));
+
+ if (childrenSizes[0].minContentSize == 25 &&
+ childrenSizes[0].maxContentSize == 25) {
+ return { maxContentSize: 100, minContentSize: 50 };
+ }
+ return { maxContentSize: 0, minContentSize: 0 };
+ }
+ async layout() {}
+});
+</script>
+
+<script>
+importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, document.getElementById('code').textContent);
+</script>
+</html>
diff --git a/testing/web-platform/tests/css/css-layout-api/intrinsic-sizes/child-replaced-percentage-ref.html b/testing/web-platform/tests/css/css-layout-api/intrinsic-sizes/child-replaced-percentage-ref.html
new file mode 100644
index 0000000000..762740ffee
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/intrinsic-sizes/child-replaced-percentage-ref.html
@@ -0,0 +1,9 @@
+<!DOCTYPE html>
+<style>
+.result {
+ background: green;
+ height: 50px;
+ width: 50px;
+}
+</style>
+<div class="result"></div>
diff --git a/testing/web-platform/tests/css/css-layout-api/intrinsic-sizes/child-size-01-ref.html b/testing/web-platform/tests/css/css-layout-api/intrinsic-sizes/child-size-01-ref.html
new file mode 100644
index 0000000000..3702d72080
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/intrinsic-sizes/child-size-01-ref.html
@@ -0,0 +1,9 @@
+<!DOCTYPE html>
+<style>
+.result {
+ background: green;
+ height: 100px;
+ width: 50px;
+}
+</style>
+<div class="result"></div>
diff --git a/testing/web-platform/tests/css/css-layout-api/intrinsic-sizes/child-size-01.https.html b/testing/web-platform/tests/css/css-layout-api/intrinsic-sizes/child-size-01.https.html
new file mode 100644
index 0000000000..c0a00e28bb
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/intrinsic-sizes/child-size-01.https.html
@@ -0,0 +1,61 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#intrinsic-sizes">
+<link rel="match" href="child-size-01-ref.html">
+<meta name="assert" content="This test checks that passing child intrinsicSizes to a parent works correctly." />
+<style>
+.test {
+ background: red;
+ height: 100px;
+ width: min-content;
+}
+
+@supports (display: layout(parent)) {
+ .test {
+ display: layout(parent);
+ background: green;
+ }
+
+ .child {
+ display: layout(child);
+ }
+}
+</style>
+<script src="/common/reftest-wait.js"></script>
+<script src="/common/worklet-reftest.js"></script>
+
+<div class="test">
+ <div class="child"></div>
+</div>
+
+<script id="code" type="text/worklet">
+const MAX_CONTENT_SIZE = 100;
+const MIN_CONTENT_SIZE = 50;
+
+registerLayout('parent', class {
+ async intrinsicSizes(children, edges, styleMap) {
+ const childrenSizes = await Promise.all(children.map((child) => {
+ return child.intrinsicSizes();
+ }));
+
+ if (childrenSizes[0].minContentSize == MIN_CONTENT_SIZE &&
+ childrenSizes[0].maxContentSize == MAX_CONTENT_SIZE) {
+ return { maxContentSize: MAX_CONTENT_SIZE, minContentSize: MIN_CONTENT_SIZE };
+ }
+ return { maxContentSize: 0, minContentSize: 0 };
+ }
+ async layout() {}
+});
+
+registerLayout('child', class {
+ async intrinsicSizes() {
+ return { maxContentSize: MAX_CONTENT_SIZE, minContentSize: MIN_CONTENT_SIZE };
+ }
+ async layout() {}
+});
+</script>
+
+<script>
+importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, document.getElementById('code').textContent);
+</script>
+</html>
diff --git a/testing/web-platform/tests/css/css-layout-api/intrinsic-sizes/child-size-02-ref.html b/testing/web-platform/tests/css/css-layout-api/intrinsic-sizes/child-size-02-ref.html
new file mode 100644
index 0000000000..76c885e182
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/intrinsic-sizes/child-size-02-ref.html
@@ -0,0 +1,9 @@
+<!DOCTYPE html>
+<style>
+.result {
+ background: green;
+ height: 100px;
+ width: 75px;
+}
+</style>
+<div class="result"></div>
diff --git a/testing/web-platform/tests/css/css-layout-api/intrinsic-sizes/child-size-02.https.html b/testing/web-platform/tests/css/css-layout-api/intrinsic-sizes/child-size-02.https.html
new file mode 100644
index 0000000000..030ecfccdc
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/intrinsic-sizes/child-size-02.https.html
@@ -0,0 +1,67 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#intrinsic-sizes">
+<link rel="match" href="child-size-02-ref.html">
+<meta name="assert" content="This test checks that setting a child's intrinsicSizes does not override its min-width." />
+<style>
+.test {
+ background: red;
+ height: 100px;
+ width: min-content;
+}
+
+.child {
+ min-width: 75px;
+}
+
+@supports (display: layout(parent)) {
+ .test {
+ display: layout(parent);
+ background: green;
+ }
+
+ .child {
+ display: layout(child);
+ }
+}
+</style>
+<script src="/common/reftest-wait.js"></script>
+<script src="/common/worklet-reftest.js"></script>
+
+<div class="test">
+ <div class="child"></div>
+</div>
+
+<script id="code" type="text/worklet">
+const MAX_CONTENT_SIZE = 100;
+const MIN_CONTENT_SIZE = 50;
+
+registerLayout('parent', class {
+ static get childInputProperties() { return ['min-width']; }
+
+ async intrinsicSizes(children, edges, styleMap) {
+ const childrenSizes = await Promise.all(children.map((child) => {
+ return child.intrinsicSizes();
+ }));
+
+ if (childrenSizes[0].minContentSize == child.styleMap.get('min-width').value &&
+ childrenSizes[0].maxContentSize == MAX_CONTENT_SIZE) {
+ return { maxContentSize: MAX_CONTENT_SIZE, minContentSize: MIN_CONTENT_SIZE };
+ }
+ return { maxContentSize: 0, minContentSize: 0 };
+ }
+ async layout() {}
+});
+
+registerLayout('child', class {
+ async intrinsicSizes() {
+ return { maxContentSize: MAX_CONTENT_SIZE, minContentSize: MIN_CONTENT_SIZE };
+ }
+ async layout() {}
+});
+</script>
+
+<script>
+importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, document.getElementById('code').textContent);
+</script>
+</html>
diff --git a/testing/web-platform/tests/css/css-layout-api/intrinsic-sizes/child-size-03.https.html b/testing/web-platform/tests/css/css-layout-api/intrinsic-sizes/child-size-03.https.html
new file mode 100644
index 0000000000..8b540cf959
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/intrinsic-sizes/child-size-03.https.html
@@ -0,0 +1,67 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#intrinsic-sizes">
+<link rel="match" href="child-size-02-ref.html">
+<meta name="assert" content="This test checks that setting a child's intrinsicSizes does not override its max-width." />
+<style>
+.test {
+ background: red;
+ height: 100px;
+ width: max-content;
+}
+
+.child {
+ max-width: 75px;
+}
+
+@supports (display: layout(parent)) {
+ .test {
+ display: layout(parent);
+ background: green;
+ }
+
+ .child {
+ display: layout(child);
+ }
+}
+</style>
+<script src="/common/reftest-wait.js"></script>
+<script src="/common/worklet-reftest.js"></script>
+
+<div class="test">
+ <div class="child"></div>
+</div>
+
+<script id="code" type="text/worklet">
+const MAX_CONTENT_SIZE = 100;
+const MIN_CONTENT_SIZE = 50;
+
+registerLayout('parent', class {
+ static get childInputProperties() { return ['max-width']; }
+
+ async intrinsicSizes(children, edges, styleMap) {
+ const childrenSizes = await Promise.all(children.map((child) => {
+ return child.intrinsicSizes();
+ }));
+
+ if (childrenSizes[0].minContentSize == MIN_CONTENT_SIZE &&
+ childrenSizes[0].maxContentSize == child.styleMap.get('max-width').value) {
+ return { maxContentSize: MAX_CONTENT_SIZE, minContentSize: MIN_CONTENT_SIZE };
+ }
+ return { maxContentSize: 0, minContentSize: 0 };
+ }
+ async layout() {}
+});
+
+registerLayout('child', class {
+ async intrinsicSizes() {
+ return { maxContentSize: MAX_CONTENT_SIZE, minContentSize: MIN_CONTENT_SIZE };
+ }
+ async layout() {}
+});
+</script>
+
+<script>
+importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, document.getElementById('code').textContent);
+</script>
+</html>
diff --git a/testing/web-platform/tests/css/css-layout-api/intrinsic-sizes/child-size-contribution.https.html b/testing/web-platform/tests/css/css-layout-api/intrinsic-sizes/child-size-contribution.https.html
new file mode 100644
index 0000000000..e21085c9f6
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/intrinsic-sizes/child-size-contribution.https.html
@@ -0,0 +1,49 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#intrinsic-sizes">
+<link rel="match" href="child-size-01-ref.html">
+<meta name="assert" content="This test checks that the child intrinsicSizes returns the min/max size contributions." />
+<style>
+.test {
+ background: red;
+ height: 100px;
+ width: min-content;
+}
+
+@supports (display: layout(parent)) {
+ .test {
+ display: layout(parent);
+ background: green;
+ }
+}
+</style>
+<script src="/common/reftest-wait.js"></script>
+<script src="/common/worklet-reftest.js"></script>
+
+<div class="test">
+ <div style="width: 100px;">
+ <div style="width: 200px;"></div>
+ </div>
+</div>
+
+<script id="code" type="text/worklet">
+registerLayout('parent', class {
+ async intrinsicSizes(children, edges, styleMap) {
+ const childrenSizes = await Promise.all(children.map((child) => {
+ return child.intrinsicSizes();
+ }));
+
+ if (childrenSizes[0].minContentSize == 100 &&
+ childrenSizes[0].maxContentSize == 100) {
+ return { maxContentSize: 100, minContentSize: 50 };
+ }
+ return { maxContentSize: 0, minContentSize: 0 };
+ }
+ async layout() {}
+});
+</script>
+
+<script>
+importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, document.getElementById('code').textContent);
+</script>
+</html>
diff --git a/testing/web-platform/tests/css/css-layout-api/intrinsic-sizes/content-size-ref.html b/testing/web-platform/tests/css/css-layout-api/intrinsic-sizes/content-size-ref.html
new file mode 100644
index 0000000000..6bccf070a9
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/intrinsic-sizes/content-size-ref.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<style>
+.test {
+ background: green;
+ border: solid 2px;
+ height: 100px;
+}
+</style>
+
+<div class="test" style="width: 96px"></div>
+<div class="test" style="width: 46px"></div>
diff --git a/testing/web-platform/tests/css/css-layout-api/intrinsic-sizes/content-size.https.html b/testing/web-platform/tests/css/css-layout-api/intrinsic-sizes/content-size.https.html
new file mode 100644
index 0000000000..ed87dd5065
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/intrinsic-sizes/content-size.https.html
@@ -0,0 +1,48 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#interaction-sizing">
+<link rel="match" href="content-size-ref.html">
+<meta name="assert" content="This test checks that the min-content and max-content sizes respect the values returned from the intrinsicSizes function." />
+
+<style>
+.test {
+ background: red;
+ border: solid 2px;
+ height: 100px;
+}
+
+.test-1 {
+ width: max-content;
+}
+
+.test-2 {
+ width: min-content;
+}
+
+@supports (display: layout(test-layout)) {
+ .test {
+ display: layout(test-layout);
+ background: green;
+ }
+}
+</style>
+<script src="/common/reftest-wait.js"></script>
+<script src="/common/worklet-reftest.js"></script>
+
+
+<div class="test test-1"></div>
+<div class="test test-2"></div>
+
+<script id="code" type="text/worklet">
+registerLayout('test-layout', class {
+ async intrinsicSizes() {
+ return { maxContentSize: 100, minContentSize: 50 };
+ }
+ async layout() {}
+});
+</script>
+
+<script>
+importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, document.getElementById('code').textContent);
+</script>
+</html>
diff --git a/testing/web-platform/tests/css/css-layout-api/intrinsic-sizes/floats-ref.html b/testing/web-platform/tests/css/css-layout-api/intrinsic-sizes/floats-ref.html
new file mode 100644
index 0000000000..11cdb055eb
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/intrinsic-sizes/floats-ref.html
@@ -0,0 +1,47 @@
+<!DOCTYPE html>
+<style>
+.test {
+ background: green;
+ border: solid 2px;
+}
+
+.container-1 {
+ height: 100px;
+ width: 300px;
+}
+
+.container-2 {
+ height: 50px;
+ width: 50px;
+}
+
+.container-3 {
+ height: 80px;
+ width: 80px;
+}
+
+.left {
+ float: left;
+ writing-mode: horizontal-tb;
+}
+
+.right {
+ float: right;
+ writing-mode: vertical-rl;
+}
+</style>
+
+<div class="container-1">
+ <div class="left test" style="height: 100px; width: 96px;"></div>
+ <div class="right test" style="height: 96px; width: 100px;"></div>
+</div>
+
+<div class="container-2">
+ <div class="left test" style="height: 25px; width: 46px;"></div>
+ <div class="right test" style="height: 46px; width: 25px;"></div>
+</div>
+
+<div class="container-3">
+ <div class="left test" style="height: 25px; width: 76px;"></div>
+ <div class="right test" style="height: 76px; width: 25px;"></div>
+</div>
diff --git a/testing/web-platform/tests/css/css-layout-api/intrinsic-sizes/floats.https.html b/testing/web-platform/tests/css/css-layout-api/intrinsic-sizes/floats.https.html
new file mode 100644
index 0000000000..5079b193fe
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/intrinsic-sizes/floats.https.html
@@ -0,0 +1,78 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#interaction-sizing">
+<link rel="match" href="floats-ref.html">
+<meta name="assert" content="This test checks that if the layout() is a float, the flow layout respects the intrinsicSizes function." />
+
+<style>
+.test {
+ background: red;
+ border: solid 2px;
+}
+
+@supports (display: layout(test-layout)) {
+ .test {
+ display: layout(test-layout);
+ background: green;
+ }
+}
+
+.container-1 {
+ height: 100px;
+ width: 300px;
+}
+
+.container-2 {
+ height: 50px;
+ width: 50px;
+}
+
+.container-3 {
+ height: 80px;
+ width: 80px;
+}
+
+.left {
+ float: left;
+ writing-mode: horizontal-tb;
+}
+
+.right {
+ float: right;
+ writing-mode: vertical-rl;
+}
+
+</style>
+<script src="/common/reftest-wait.js"></script>
+<script src="/common/worklet-reftest.js"></script>
+
+
+<div class="container-1">
+ <div class="left test" style="height: 100px"></div>
+ <div class="right test" style="width: 100px"></div>
+</div>
+
+<div class="container-2">
+ <div class="left test" style="height: 25px"></div>
+ <div class="right test" style="width: 25px"></div>
+</div>
+
+<div class="container-3">
+ <div class="left test" style="height: 25px"></div>
+ <div class="right test" style="width: 25px"></div>
+</div>
+
+
+<script id="code" type="text/worklet">
+registerLayout('test-layout', class {
+ async intrinsicSizes() {
+ return { maxContentSize: 100, minContentSize: 50 };
+ }
+ async layout() {}
+});
+</script>
+
+<script>
+importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, document.getElementById('code').textContent);
+</script>
+</html>
diff --git a/testing/web-platform/tests/css/css-layout-api/intrinsic-sizes/invalid-min-max.https.html b/testing/web-platform/tests/css/css-layout-api/intrinsic-sizes/invalid-min-max.https.html
new file mode 100644
index 0000000000..2b2d8ca76e
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/intrinsic-sizes/invalid-min-max.https.html
@@ -0,0 +1,39 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#interaction-sizing">
+<link rel="match" href="invalid-ref.html">
+<meta name="assert" content="This test checks that min-content-size greater than max-content-size is correctly clamped to max-content-size." />
+
+<style>
+.test {
+ background: red;
+ border: solid 2px;
+ height: 100px;
+ width: max-content;
+}
+
+@supports (display: layout(invalid-sizes)) {
+ .test {
+ display: layout(invalid-sizes);
+ background: green;
+ }
+}
+</style>
+<script src="/common/reftest-wait.js"></script>
+<script src="/common/worklet-reftest.js"></script>
+
+<div class="test"></div>
+
+<script id="code" type="text/worklet">
+registerLayout('invalid-sizes', class {
+ async intrinsicSizes() {
+ return { maxContentSize: 10, minContentSize: 200 };
+ }
+ async layout() {}
+});
+</script>
+
+<script>
+importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, document.getElementById('code').textContent);
+</script>
+</html>
diff --git a/testing/web-platform/tests/css/css-layout-api/intrinsic-sizes/invalid-ref.html b/testing/web-platform/tests/css/css-layout-api/intrinsic-sizes/invalid-ref.html
new file mode 100644
index 0000000000..4159356047
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/intrinsic-sizes/invalid-ref.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<style>
+.result {
+ background: green;
+ border: solid 2px;
+ height: 100px;
+ width: 6px;
+}
+</style>
+
+<div class="result"></div>
diff --git a/testing/web-platform/tests/css/css-layout-api/intrinsic-sizes/negative-max.https.html b/testing/web-platform/tests/css/css-layout-api/intrinsic-sizes/negative-max.https.html
new file mode 100644
index 0000000000..578803767e
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/intrinsic-sizes/negative-max.https.html
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#interaction-sizing">
+<link rel="match" href="negative-ref.html">
+<meta name="assert" content="This test checks that max-content-size is correctly clamped to zero." />
+
+<style>
+
+.test {
+ background: red;
+ border: solid 2px;
+ height: 100px;
+ width: max-content;
+}
+
+@supports (display: layout(max-content-size-negative)) {
+ .test {
+ display: layout(max-content-size-negative);
+ background: green;
+ }
+}
+</style>
+<script src="/common/reftest-wait.js"></script>
+<script src="/common/worklet-reftest.js"></script>
+
+<div class="test"></div>
+
+<script id="code" type="text/worklet">
+registerLayout('max-content-size-negative', class {
+ async intrinsicSizes() {
+ return { maxContentSize: -100 };
+ }
+ async layout() {}
+});
+</script>
+
+<script>
+importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, document.getElementById('code').textContent);
+</script>
+</html>
diff --git a/testing/web-platform/tests/css/css-layout-api/intrinsic-sizes/negative-min.https.html b/testing/web-platform/tests/css/css-layout-api/intrinsic-sizes/negative-min.https.html
new file mode 100644
index 0000000000..c614a2fb12
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/intrinsic-sizes/negative-min.https.html
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#interaction-sizing">
+<link rel="match" href="negative-ref.html">
+<meta name="assert" content="This test checks that min-content-size is correctly clamped to zero." />
+
+<style>
+
+.test {
+ background: red;
+ border: solid 2px;
+ height: 100px;
+ width: min-content;
+}
+
+@supports (display: layout(min-content-size-negative)) {
+ .test {
+ display: layout(min-content-size-negative);
+ background: green;
+ }
+}
+</style>
+<script src="/common/reftest-wait.js"></script>
+<script src="/common/worklet-reftest.js"></script>
+
+<div class="test"></div>
+
+<script id="code" type="text/worklet">
+registerLayout('min-content-size-negative', class {
+ async intrinsicSizes() {
+ return { minContentSize: -100 };
+ }
+ async layout() {}
+});
+</script>
+
+<script>
+importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, document.getElementById('code').textContent);
+</script>
+</html>
diff --git a/testing/web-platform/tests/css/css-layout-api/intrinsic-sizes/negative-ref.html b/testing/web-platform/tests/css/css-layout-api/intrinsic-sizes/negative-ref.html
new file mode 100644
index 0000000000..6808e14eb6
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/intrinsic-sizes/negative-ref.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<style>
+.result {
+ background: green;
+ border: solid 2px;
+ height: 100px;
+ width: min-content;
+}
+</style>
+
+<div class="result"></div>
diff --git a/testing/web-platform/tests/css/css-layout-api/layout-child/absolute.https.html b/testing/web-platform/tests/css/css-layout-api/layout-child/absolute.https.html
new file mode 100644
index 0000000000..7c47e38e7a
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/layout-child/absolute.https.html
@@ -0,0 +1,43 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#layout-children">
+<link rel="match" href="../green-square-ref.html">
+<meta name="assert" content="This test checks that absolute children don't appear in the children array." />
+
+<style>
+.test {
+ --child-expected: ["2"];
+
+ background: red;
+ width: 100px;
+}
+
+.absolute {
+ position: absolute;
+ visibility: hidden;
+ --child: 1;
+}
+
+.inflow {
+ visibility: hidden;
+ --child: 2;
+}
+
+@supports (display: layout(test)) {
+ .test {
+ background: green;
+ display: layout(test);
+ }
+}
+</style>
+<script src="/common/reftest-wait.js"></script>
+<script src="/common/worklet-reftest.js"></script>
+
+<div class="test">
+ <div class="absolute"></div>
+ <div class="inflow"></div>
+</div>
+
+<script>
+importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, {url: 'support/layout-child-worklet.js'});
+</script>
diff --git a/testing/web-platform/tests/css/css-layout-api/layout-child/before-after.https.html b/testing/web-platform/tests/css/css-layout-api/layout-child/before-after.https.html
new file mode 100644
index 0000000000..373392ddfd
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/layout-child/before-after.https.html
@@ -0,0 +1,48 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#layout-children">
+<link rel="match" href="../green-square-ref.html">
+<meta name="assert" content="This test checks that boxes created by ::before/::after appear as children." />
+
+<style>
+.test {
+ --child-expected: ["1", "2", "3"];
+
+ background: red;
+ width: 100px;
+}
+
+.test::before {
+ visibility: hidden;
+ content: 'before';
+ --child: 1;
+}
+
+.inflow {
+ visibility: hidden;
+ --child: 2;
+}
+
+.test::after {
+ visibility: hidden;
+ content: 'after';
+ --child: 3;
+}
+
+@supports (display: layout(test)) {
+ .test {
+ background: green;
+ display: layout(test);
+ }
+}
+</style>
+<script src="/common/reftest-wait.js"></script>
+<script src="/common/worklet-reftest.js"></script>
+
+<div class="test">
+ <div class="inflow"></div>
+</div>
+
+<script>
+importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, {url: 'support/layout-child-worklet.js'});
+</script>
diff --git a/testing/web-platform/tests/css/css-layout-api/layout-child/fixed.https.html b/testing/web-platform/tests/css/css-layout-api/layout-child/fixed.https.html
new file mode 100644
index 0000000000..95d8852b7d
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/layout-child/fixed.https.html
@@ -0,0 +1,43 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#layout-children">
+<link rel="match" href="../green-square-ref.html">
+<meta name="assert" content="This test checks that fixed children don't appear in the children array." />
+
+<style>
+.test {
+ --child-expected: ["2"];
+
+ background: red;
+ width: 100px;
+}
+
+.fixed {
+ position: fixed;
+ visibility: hidden;
+ --child: 1;
+}
+
+.inflow {
+ visibility: hidden;
+ --child: 2;
+}
+
+@supports (display: layout(test)) {
+ .test {
+ background: green;
+ display: layout(test);
+ }
+}
+</style>
+<script src="/common/reftest-wait.js"></script>
+<script src="/common/worklet-reftest.js"></script>
+
+<div class="test">
+ <div class="fixed"></div>
+ <div class="inflow"></div>
+</div>
+
+<script>
+importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, {url: 'support/layout-child-worklet.js'});
+</script>
diff --git a/testing/web-platform/tests/css/css-layout-api/layout-child/float.https.html b/testing/web-platform/tests/css/css-layout-api/layout-child/float.https.html
new file mode 100644
index 0000000000..e8db261774
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/layout-child/float.https.html
@@ -0,0 +1,43 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#layout-children">
+<link rel="match" href="../green-square-ref.html">
+<meta name="assert" content="This test checks that float children appear in the children array." />
+
+<style>
+.test {
+ --child-expected: ["1", "2"];
+
+ background: red;
+ width: 100px;
+}
+
+.float {
+ float: right;
+ visibility: hidden;
+ --child: 1;
+}
+
+.inflow {
+ visibility: hidden;
+ --child: 2;
+}
+
+@supports (display: layout(test)) {
+ .test {
+ background: green;
+ display: layout(test);
+ }
+}
+</style>
+<script src="/common/reftest-wait.js"></script>
+<script src="/common/worklet-reftest.js"></script>
+
+<div class="test">
+ <div class="float"></div>
+ <div class="inflow"></div>
+</div>
+
+<script>
+importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, {url: 'support/layout-child-worklet.js'});
+</script>
diff --git a/testing/web-platform/tests/css/css-layout-api/layout-child/inflow.https.html b/testing/web-platform/tests/css/css-layout-api/layout-child/inflow.https.html
new file mode 100644
index 0000000000..b43f1a7fac
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/layout-child/inflow.https.html
@@ -0,0 +1,42 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#layout-children">
+<link rel="match" href="../green-square-ref.html">
+<meta name="assert" content="This test checks that regular inflow children appear as children." />
+
+<style>
+.test {
+ --child-expected: ["1", "2"];
+
+ background: red;
+ width: 100px;
+}
+
+.inflow-1 {
+ visibility: hidden;
+ --child: 1;
+}
+
+.inflow-2 {
+ visibility: hidden;
+ --child: 2;
+}
+
+@supports (display: layout(test)) {
+ .test {
+ background: green;
+ display: layout(test);
+ }
+}
+</style>
+<script src="/common/reftest-wait.js"></script>
+<script src="/common/worklet-reftest.js"></script>
+
+<div class="test">
+ <div class="inflow-1"></div>
+ <div class="inflow-2"></div>
+</div>
+
+<script>
+importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, {url: 'support/layout-child-worklet.js'});
+</script>
diff --git a/testing/web-platform/tests/css/css-layout-api/layout-child/inlines-dynamic.https.html b/testing/web-platform/tests/css/css-layout-api/layout-child/inlines-dynamic.https.html
new file mode 100644
index 0000000000..50052087f4
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/layout-child/inlines-dynamic.https.html
@@ -0,0 +1,39 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Layout API: Dynamic blockification of inline children</title>
+<link rel="author" href="mailto:obrufau@igalia.com" title="Oriol Brufau">
+<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#layout-children" title="4.1. Layout Children">
+<meta name="assert" content="This test checks that inline children are correctly blockified or unblockified when the display of the parent changes dynamically." />
+
+<style>
+#wrapper {
+ display: layout(foo);
+}
+#test {
+ display: inline;
+}
+</style>
+
+<div id="wrapper">
+ <div id="test">Lorem ipsum</div>
+</div>
+
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/worklet-reftest.js"></script>
+<script>
+promise_test(async function() {
+ await importWorklet(CSS.layoutWorklet, {url: 'support/layout-child-worklet.js'});
+
+ const wrapper = document.getElementById("wrapper");
+ const test = document.getElementById("test");
+
+ assert_equals(getComputedStyle(test).display, "block", "The child should have been blockified by the custom layout");
+
+ wrapper.style.display = "block";
+ assert_equals(getComputedStyle(test).display, "inline", "The child should no longer be blockified in block layout");
+
+ wrapper.style.display = "";
+ assert_equals(getComputedStyle(test).display, "block", "The child should have been blockified again");
+});
+</script>
diff --git a/testing/web-platform/tests/css/css-layout-api/layout-child/inlines.https.html b/testing/web-platform/tests/css/css-layout-api/layout-child/inlines.https.html
new file mode 100644
index 0000000000..dac7e0b26b
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/layout-child/inlines.https.html
@@ -0,0 +1,54 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#layout-children">
+<link rel="match" href="../green-square-ref.html">
+<meta name="assert" content="This test checks that inline children are correctly blockified or wrapped in anonymous boxes." />
+
+<style>
+/* We have a wrapper in this test to ensure that any text that is positioned
+ * slightly outside the "test" box doesn't affect the rendering.
+ * This wrapper has a 10px inline padding which does the trick. */
+.wrapper {
+ background: green;
+ padding: 0 10px;
+ width: 80px;
+}
+
+.test {
+ --child-expected: ["1", "default", "3", "4", "5"];
+
+ background: red;
+ color: green;
+ width: 80px;
+ --child: default;
+}
+
+.inflow {
+ visibility: hidden;
+ --child: 3;
+}
+
+@supports (display: layout(test)) {
+ .test {
+ background: green;
+ display: layout(test);
+ }
+}
+</style>
+<script src="/common/reftest-wait.js"></script>
+<script src="/common/worklet-reftest.js"></script>
+
+<div class="wrapper">
+ <div class="test">
+ <span style="--child: 1;">Text,</span> more text
+ <div class="inflow"></div>
+ <span style="--child: 4;">Text,
+ <div>block!</div>
+ </span>
+ <span style="--child: 5;">Other text</span>
+ </div>
+</div>
+
+<script>
+importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, {url: 'support/layout-child-worklet.js'});
+</script>
diff --git a/testing/web-platform/tests/css/css-layout-api/layout-child/support/layout-child-worklet.js b/testing/web-platform/tests/css/css-layout-api/layout-child/support/layout-child-worklet.js
new file mode 100644
index 0000000000..70d1b7e457
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/layout-child/support/layout-child-worklet.js
@@ -0,0 +1,26 @@
+import {areArraysEqual} from '/common/arrays.js';
+
+registerLayout('test', class {
+ static get inputProperties() {
+ return [ '--child-expected'];
+ }
+
+ static get childInputProperties() {
+ return [ '--child' ];
+ }
+
+ async intrinsicSizes() {}
+ async layout(children, edges, constraints, styleMap) {
+ const expected = JSON.parse(styleMap.get('--child-expected').toString());
+ const actual = children.map((child) => {
+ return child.styleMap.get('--child').toString().trim();
+ });
+
+ const childFragments = await Promise.all(children.map(child => child.layoutNextFragment({})));
+
+ if (!areArraysEqual(expected, actual))
+ return {autoBlockSize: 0, childFragments};
+
+ return {autoBlockSize: 100, childFragments};
+ }
+});
diff --git a/testing/web-platform/tests/css/css-layout-api/layout-child/text-01.https.html b/testing/web-platform/tests/css/css-layout-api/layout-child/text-01.https.html
new file mode 100644
index 0000000000..090034fc18
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/layout-child/text-01.https.html
@@ -0,0 +1,51 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#layout-children">
+<link rel="match" href="../green-square-ref.html">
+<meta name="assert" content="This test checks that text children are correctly blockified." />
+
+<style>
+/* We have a wrapper in this test to ensure that any text that is positioned
+ * slightly outside the "test" box doesn't affect the rendering.
+ * This wrapper has a 10px inline padding which does the trick. */
+.wrapper {
+ background: green;
+ padding: 0 10px;
+ width: 80px;
+}
+
+.test {
+ --child-expected: ["default", "2", "default"];
+
+ background: red;
+ color: green;
+ width: 80px;
+ --child: default;
+}
+
+.inflow {
+ visibility: hidden;
+ --child: 2;
+}
+
+@supports (display: layout(test)) {
+ .test {
+ background: green;
+ display: layout(test);
+ }
+}
+</style>
+<script src="/common/reftest-wait.js"></script>
+<script src="/common/worklet-reftest.js"></script>
+
+<div class="wrapper">
+ <div class="test">
+ Text text text
+ <div class="inflow"></div>
+ Text text text
+ </div>
+</div>
+
+<script>
+importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, {url: 'support/layout-child-worklet.js'});
+</script>
diff --git a/testing/web-platform/tests/css/css-layout-api/layout-child/text-02.https.html b/testing/web-platform/tests/css/css-layout-api/layout-child/text-02.https.html
new file mode 100644
index 0000000000..0df7498668
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/layout-child/text-02.https.html
@@ -0,0 +1,44 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#layout-children">
+<link rel="match" href="../green-square-ref.html">
+<meta name="assert" content="This test checks that text children are correctly blockified when no other children exist." />
+
+<style>
+/* We have a wrapper in this test to ensure that any text that is positioned
+ * slightly outside the "test" box doesn't affect the rendering.
+ * This wrapper has a 10px inline padding which does the trick. */
+.wrapper {
+ background: green;
+ padding: 0 10px;
+ width: 80px;
+}
+
+.test {
+ --child-expected: ["default"];
+
+ background: red;
+ color: green;
+ width: 80px;
+ --child: default;
+}
+
+@supports (display: layout(test)) {
+ .test {
+ background: green;
+ display: layout(test);
+ }
+}
+</style>
+<script src="/common/reftest-wait.js"></script>
+<script src="/common/worklet-reftest.js"></script>
+
+<div class="wrapper">
+ <div class="test">
+ Text text text
+ </div>
+</div>
+
+<script>
+importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, {url: 'support/layout-child-worklet.js'});
+</script>
diff --git a/testing/web-platform/tests/css/css-layout-api/list-item-multicol-with-custom-layout-child-crash.https.html b/testing/web-platform/tests/css/css-layout-api/list-item-multicol-with-custom-layout-child-crash.https.html
new file mode 100644
index 0000000000..be91346c54
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/list-item-multicol-with-custom-layout-child-crash.https.html
@@ -0,0 +1,6 @@
+<!DOCTYPE html>
+<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org">
+<link rel="help" href="https://bugs.chromium.org/p/chromium/issues/detail?id=1127112#c8">
+<div style="display:list-item; columns:2;">
+ <div style="display:layout(child-layout);">Do not crash.</div>
+</div>
diff --git a/testing/web-platform/tests/css/css-layout-api/multicol-break-before-crash.https.html b/testing/web-platform/tests/css/css-layout-api/multicol-break-before-crash.https.html
new file mode 100644
index 0000000000..c2a33802e5
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/multicol-break-before-crash.https.html
@@ -0,0 +1,7 @@
+<!DOCTYPE html>
+<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org">
+<link rel="help" href="https://www.w3.org/TR/css-layout-api-1/#breaking-and-fragmentation">
+<div style="columns:3; column-fill:auto; height:100px;">
+ <div style="height:1px;"></div>
+ <div style="display:layout(child-layout); break-before:column; height:200px;"></div>
+</div>
diff --git a/testing/web-platform/tests/css/css-layout-api/multicol-child-crash.https.html b/testing/web-platform/tests/css/css-layout-api/multicol-child-crash.https.html
new file mode 100644
index 0000000000..e16532f772
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/multicol-child-crash.https.html
@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org">
+<link rel="help" href="https://bugs.chromium.org/p/chromium/issues/detail?id=1127112#c9">
+<div style="columns:2;">
+ <div style="display:layout(child-layout);">
+ line1<br>
+ line2<br>
+ line3<br>
+ </div>
+</div>
diff --git a/testing/web-platform/tests/css/css-layout-api/multicol-details-crash.https.html b/testing/web-platform/tests/css/css-layout-api/multicol-details-crash.https.html
new file mode 100644
index 0000000000..8c45190cec
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/multicol-details-crash.https.html
@@ -0,0 +1,6 @@
+<!DOCTYPE html>
+<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org">
+<link rel="help" href="https://bugs.chromium.org/p/chromium/issues/detail?id=1219874">
+<div style="columns:2;">
+ <details style="display:layout(foo); columns:2;"></details>
+</div>
diff --git a/testing/web-platform/tests/css/css-layout-api/multicol-fieldset-crash.https.html b/testing/web-platform/tests/css/css-layout-api/multicol-fieldset-crash.https.html
new file mode 100644
index 0000000000..a267a6d42b
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/multicol-fieldset-crash.https.html
@@ -0,0 +1,8 @@
+<!DOCTYPE html>
+<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org">
+<link rel="help" href="https://bugs.chromium.org/p/chromium/issues/detail?id=1221885">
+<div style="columns:2;">
+ <fieldset style="display:layout(child-layout); columns:2;">
+ BOO!
+ </fieldset>
+</div>
diff --git a/testing/web-platform/tests/css/css-layout-api/position-fragment/htb-ltr.https.html b/testing/web-platform/tests/css/css-layout-api/position-fragment/htb-ltr.https.html
new file mode 100644
index 0000000000..f60109ca57
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/position-fragment/htb-ltr.https.html
@@ -0,0 +1,54 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#layoutfragment">
+<link rel="match" href="ref.html">
+<meta name="assert" content="This test checks that child fragments get positioned correctly." />
+<style>
+.test {
+ background: red;
+ width: 100px;
+ height: 100px;
+}
+
+.test {
+ writing-mode: horizontal-tb;
+ direction: ltr;
+}
+
+.child-1 {
+ background: rebeccapurple;
+ width: 10px;
+ height: 20px;
+
+ --inline-offset: 5;
+ --block-offset: 25;
+}
+
+.child-2 {
+ writing-mode: vertical-rl;
+ background: rebeccapurple;
+ width: 15px;
+ height: 25px;
+
+ --inline-offset: 50;
+ --block-offset: 60;
+}
+
+@supports (display: layout(test)) {
+ .test {
+ background: green;
+ display: layout(test);
+ }
+}
+</style>
+<script src="/common/reftest-wait.js"></script>
+<script src="/common/worklet-reftest.js"></script>
+
+<div class="test">
+ <div class="child-1"></div>
+ <div class="child-2"></div>
+</div>
+
+<script>
+importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, {url: 'support/layout-position-child-worklet.js'});
+</script>
diff --git a/testing/web-platform/tests/css/css-layout-api/position-fragment/htb-rtl.https.html b/testing/web-platform/tests/css/css-layout-api/position-fragment/htb-rtl.https.html
new file mode 100644
index 0000000000..980a3cdc25
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/position-fragment/htb-rtl.https.html
@@ -0,0 +1,54 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#layoutfragment">
+<link rel="match" href="ref.html">
+<meta name="assert" content="This test checks that child fragments get positioned correctly." />
+<style>
+.test {
+ background: red;
+ width: 100px;
+ height: 100px;
+}
+
+.test {
+ writing-mode: horizontal-tb;
+ direction: rtl;
+}
+
+.child-1 {
+ background: rebeccapurple;
+ width: 10px;
+ height: 20px;
+
+ --inline-offset: 85;
+ --block-offset: 25;
+}
+
+.child-2 {
+ writing-mode: vertical-rl;
+ background: rebeccapurple;
+ width: 15px;
+ height: 25px;
+
+ --inline-offset: 35;
+ --block-offset: 60;
+}
+
+@supports (display: layout(test)) {
+ .test {
+ background: green;
+ display: layout(test);
+ }
+}
+</style>
+<script src="/common/reftest-wait.js"></script>
+<script src="/common/worklet-reftest.js"></script>
+
+<div class="test">
+ <div class="child-1"></div>
+ <div class="child-2"></div>
+</div>
+
+<script>
+importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, {url: 'support/layout-position-child-worklet.js'});
+</script>
diff --git a/testing/web-platform/tests/css/css-layout-api/position-fragment/ref.html b/testing/web-platform/tests/css/css-layout-api/position-fragment/ref.html
new file mode 100644
index 0000000000..4ce0a6e39d
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/position-fragment/ref.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<style>
+.result {
+ position: relative;
+ background: green;
+ width: 100px;
+ height: 100px;
+}
+
+.result-child-1 {
+ background: rebeccapurple;
+ width: 10px;
+ height: 20px;
+
+ position: absolute;
+ top: 25px;
+ left: 5px;
+}
+
+.result-child-2 {
+ background: rebeccapurple;
+ width: 15px;
+ height: 25px;
+
+ position: absolute;
+ top: 60px;
+ left: 50px;
+}
+</style>
+<div class="result">
+ <div class="result-child-1"></div>
+ <div class="result-child-2"></div>
+</div>
diff --git a/testing/web-platform/tests/css/css-layout-api/position-fragment/support/layout-position-child-worklet.js b/testing/web-platform/tests/css/css-layout-api/position-fragment/support/layout-position-child-worklet.js
new file mode 100644
index 0000000000..7d5c494952
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/position-fragment/support/layout-position-child-worklet.js
@@ -0,0 +1,20 @@
+registerLayout('test', class {
+ static get childInputProperties() {
+ return [
+ '--inline-offset',
+ '--block-offset',
+ ];
+ }
+
+ async intrinsicSizes() {}
+ async layout(children, edges, constraints, styleMap) {
+ const childFragments = await Promise.all(children.map((child) => child.layoutNextFragment({})));
+
+ for (let i = 0; i < children.length; i++) {
+ childFragments[i].inlineOffset = parseInt(children[i].styleMap.get('--inline-offset').toString());
+ childFragments[i].blockOffset = parseInt(children[i].styleMap.get('--block-offset').toString());
+ }
+
+ return {autoBlockSize: 0, childFragments};
+ }
+});
diff --git a/testing/web-platform/tests/css/css-layout-api/position-fragment/vlr-ltr.https.html b/testing/web-platform/tests/css/css-layout-api/position-fragment/vlr-ltr.https.html
new file mode 100644
index 0000000000..d75a4af639
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/position-fragment/vlr-ltr.https.html
@@ -0,0 +1,54 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#layoutfragment">
+<link rel="match" href="ref.html">
+<meta name="assert" content="This test checks that child fragments get positioned correctly." />
+<style>
+.test {
+ background: red;
+ width: 100px;
+ height: 100px;
+}
+
+.test {
+ writing-mode: vertical-lr;
+ direction: ltr;
+}
+
+.child-1 {
+ background: rebeccapurple;
+ width: 10px;
+ height: 20px;
+
+ --inline-offset: 25;
+ --block-offset: 5;
+}
+
+.child-2 {
+ writing-mode: vertical-rl;
+ background: rebeccapurple;
+ width: 15px;
+ height: 25px;
+
+ --inline-offset: 60;
+ --block-offset: 50;
+}
+
+@supports (display: layout(test)) {
+ .test {
+ background: green;
+ display: layout(test);
+ }
+}
+</style>
+<script src="/common/reftest-wait.js"></script>
+<script src="/common/worklet-reftest.js"></script>
+
+<div class="test">
+ <div class="child-1"></div>
+ <div class="child-2"></div>
+</div>
+
+<script>
+importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, {url: 'support/layout-position-child-worklet.js'});
+</script>
diff --git a/testing/web-platform/tests/css/css-layout-api/position-fragment/vlr-rtl.https.html b/testing/web-platform/tests/css/css-layout-api/position-fragment/vlr-rtl.https.html
new file mode 100644
index 0000000000..a8ef6c699c
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/position-fragment/vlr-rtl.https.html
@@ -0,0 +1,54 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#layoutfragment">
+<link rel="match" href="ref.html">
+<meta name="assert" content="This test checks that child fragments get positioned correctly." />
+<style>
+.test {
+ background: red;
+ width: 100px;
+ height: 100px;
+}
+
+.test {
+ writing-mode: vertical-lr;
+ direction: rtl;
+}
+
+.child-1 {
+ background: rebeccapurple;
+ width: 10px;
+ height: 20px;
+
+ --inline-offset: 55;
+ --block-offset: 5;
+}
+
+.child-2 {
+ writing-mode: vertical-rl;
+ background: rebeccapurple;
+ width: 15px;
+ height: 25px;
+
+ --inline-offset: 15;
+ --block-offset: 50;
+}
+
+@supports (display: layout(test)) {
+ .test {
+ background: green;
+ display: layout(test);
+ }
+}
+</style>
+<script src="/common/reftest-wait.js"></script>
+<script src="/common/worklet-reftest.js"></script>
+
+<div class="test">
+ <div class="child-1"></div>
+ <div class="child-2"></div>
+</div>
+
+<script>
+importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, {url: 'support/layout-position-child-worklet.js'});
+</script>
diff --git a/testing/web-platform/tests/css/css-layout-api/position-fragment/vrl-ltr.https.html b/testing/web-platform/tests/css/css-layout-api/position-fragment/vrl-ltr.https.html
new file mode 100644
index 0000000000..21c9ce54d6
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/position-fragment/vrl-ltr.https.html
@@ -0,0 +1,54 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#layoutfragment">
+<link rel="match" href="ref.html">
+<meta name="assert" content="This test checks that child fragments get positioned correctly." />
+<style>
+.test {
+ background: red;
+ width: 100px;
+ height: 100px;
+}
+
+.test {
+ writing-mode: vertical-rl;
+ direction: ltr;
+}
+
+.child-1 {
+ background: rebeccapurple;
+ width: 10px;
+ height: 20px;
+
+ --inline-offset: 25;
+ --block-offset: 85;
+}
+
+.child-2 {
+ writing-mode: vertical-rl;
+ background: rebeccapurple;
+ width: 15px;
+ height: 25px;
+
+ --inline-offset: 60;
+ --block-offset: 35;
+}
+
+@supports (display: layout(test)) {
+ .test {
+ background: green;
+ display: layout(test);
+ }
+}
+</style>
+<script src="/common/reftest-wait.js"></script>
+<script src="/common/worklet-reftest.js"></script>
+
+<div class="test">
+ <div class="child-1"></div>
+ <div class="child-2"></div>
+</div>
+
+<script>
+importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, {url: 'support/layout-position-child-worklet.js'});
+</script>
diff --git a/testing/web-platform/tests/css/css-layout-api/position-fragment/vrl-rtl.https.html b/testing/web-platform/tests/css/css-layout-api/position-fragment/vrl-rtl.https.html
new file mode 100644
index 0000000000..777e725da9
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/position-fragment/vrl-rtl.https.html
@@ -0,0 +1,54 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#layoutfragment">
+<link rel="match" href="ref.html">
+<meta name="assert" content="This test checks that child fragments get positioned correctly." />
+<style>
+.test {
+ background: red;
+ width: 100px;
+ height: 100px;
+}
+
+.test {
+ writing-mode: vertical-rl;
+ direction: rtl;
+}
+
+.child-1 {
+ background: rebeccapurple;
+ width: 10px;
+ height: 20px;
+
+ --inline-offset: 55;
+ --block-offset: 85;
+}
+
+.child-2 {
+ writing-mode: vertical-rl;
+ background: rebeccapurple;
+ width: 15px;
+ height: 25px;
+
+ --inline-offset: 15;
+ --block-offset: 35;
+}
+
+@supports (display: layout(test)) {
+ .test {
+ background: green;
+ display: layout(test);
+ }
+}
+</style>
+<script src="/common/reftest-wait.js"></script>
+<script src="/common/worklet-reftest.js"></script>
+
+<div class="test">
+ <div class="child-1"></div>
+ <div class="child-2"></div>
+</div>
+
+<script>
+importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, {url: 'support/layout-position-child-worklet.js'});
+</script>
diff --git a/testing/web-platform/tests/css/css-layout-api/style-map-multi-ref.html b/testing/web-platform/tests/css/css-layout-api/style-map-multi-ref.html
new file mode 100644
index 0000000000..fc54068418
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/style-map-multi-ref.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<style>
+.result {
+ background: green;
+ margin: 10px;
+ margin-left: 2px;
+
+ width: 100px;
+ height: 100px;
+}
+</style>
+
+<div class="result"></div>
diff --git a/testing/web-platform/tests/css/css-layout-api/style-map-multi.https.html b/testing/web-platform/tests/css/css-layout-api/style-map-multi.https.html
new file mode 100644
index 0000000000..9c49d0f928
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/style-map-multi.https.html
@@ -0,0 +1,70 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#layout-invalidation">
+<link rel="match" href="style-map-multi-ref.html">
+<meta name="assert" content="This test checks that properties are correctly given to the layout function." />
+
+<style>
+.test {
+ background: red;
+ margin: 10px;
+ width: 100px;
+
+ /* Properties under test. */
+ --foo: bar;
+ margin-left: 2px;
+}
+
+@supports (display: layout(test)) {
+ .test {
+ background: green;
+ display: layout(test);
+ }
+}
+</style>
+<script src="/common/reftest-wait.js"></script>
+<script src="/common/worklet-reftest.js"></script>
+
+<div class="test"></div>
+
+<script id="code" type="text/worklet">
+registerLayout('test', class {
+ static get inputProperties() {
+ return [ '--bar', '--foo', 'empty-cells', 'margin-left'];
+ }
+
+ async intrinsicSizes() {}
+ async layout(children, edges, constraints, styleMap) {
+ const expected = [
+ {property: '--bar', value: '[CSSUnparsedValue=]'},
+ {property: '--foo', value: '[CSSUnparsedValue= bar]'},
+ {property: 'empty-cells', value: '[CSSKeywordValue=show]'},
+ {property: 'margin-left', value: '[CSSUnitValue=2px]'},
+ ];
+
+ const actual = Array.from(styleMap.keys()).sort().map((property) => {
+ const valueObject = styleMap.get(property);
+ const value = '[' + valueObject.constructor.name + '=' + valueObject.toString() + ']';
+ return {property, value};
+ });
+
+ if (expected.length != actual.length)
+ return {autoBlockSize: 0};
+
+ for (let i = 0; i < expected.length; i++) {
+ if (expected[i].property != actual[i].property)
+ return {autoBlockSize: 0};
+
+ if (expected[i].value != actual[i].value)
+ return {autoBlockSize: 0};
+ }
+
+ return {autoBlockSize: 100};
+ }
+});
+</script>
+
+<script>
+importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, document.getElementById('code').textContent);
+</script>
+</html>
diff --git a/testing/web-platform/tests/css/css-layout-api/style-map-ref.html b/testing/web-platform/tests/css/css-layout-api/style-map-ref.html
new file mode 100644
index 0000000000..c24e3949ee
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/style-map-ref.html
@@ -0,0 +1,16 @@
+<!DOCTYPE html>
+<style>
+.result {
+ background: green;
+ margin: 10px;
+ margin-left: 2px;
+
+ width: 100px;
+ height: 100px;
+}
+</style>
+
+<div class="result"></div>
+<div class="result"></div>
+<div class="result"></div>
+<div class="result"></div>
diff --git a/testing/web-platform/tests/css/css-layout-api/style-map.https.html b/testing/web-platform/tests/css/css-layout-api/style-map.https.html
new file mode 100644
index 0000000000..0300b8dfb4
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/style-map.https.html
@@ -0,0 +1,71 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#layout-invalidation">
+<link rel="match" href="style-map-ref.html">
+<meta name="assert" content="This test checks that properties are correctly given to the layout function." />
+
+<style>
+.test {
+ background: red;
+ margin: 10px;
+ width: 100px;
+
+ /* Properties under test. */
+ --foo: bar;
+ margin-left: 2px;
+}
+
+@supports (display: layout(test)) {
+ .test {
+ background: green;
+ }
+
+ .test-0 { display: layout(test-0); }
+ .test-1 { display: layout(test-1); }
+ .test-2 { display: layout(test-2); }
+ .test-3 { display: layout(test-3); }
+}
+</style>
+<script src="/common/reftest-wait.js"></script>
+<script src="/common/worklet-reftest.js"></script>
+
+<div class="test test-0"></div>
+<div class="test test-1"></div>
+<div class="test test-2"></div>
+<div class="test test-3"></div>
+
+<script>
+const tmpl = (test, idx) => {
+ return `
+ registerLayout('test-${idx}', class {
+ static get inputProperties() { return ['${test.property}']; }
+
+ async intrinsicSizes() {}
+ async layout(children, edges, constraints, styleMap) {
+ const value = styleMap.get('${test.property}');
+ const result = '[' + value.constructor.name + '=' + value.toString() + ']';
+ if (result != '${test.expected}')
+ return {autoBlockSize: 0};
+
+ const size = Array.from(styleMap.keys()).length;
+ if (size != 1)
+ return {autoBlockSize: 0};
+
+ return {autoBlockSize: 100};
+ }
+ });
+ `;
+}
+
+const tests = [
+ {property: '--bar', expected: '[CSSUnparsedValue=]'},
+ {property: '--foo', expected: '[CSSUnparsedValue= bar]'},
+ {property: 'empty-cells', expected: '[CSSKeywordValue=show]'},
+ {property: 'margin-left', expected: '[CSSUnitValue=2px]'},
+];
+
+const workletSource = tests.map(tmpl).join('\n');
+
+importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, workletSource);
+</script>
+</html>
diff --git a/testing/web-platform/tests/css/css-layout-api/supports.https.html b/testing/web-platform/tests/css/css-layout-api/supports.https.html
new file mode 100644
index 0000000000..e269b29214
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/supports.https.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#valdef-display-layout">
+<meta name="assert" content="This test checks that a layout() function works correctly with CSS.supports()." />
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+
+<script>
+test(function() {
+ assert_true(CSS.supports('display', 'layout(foo)'));
+});
+</script>
diff --git a/testing/web-platform/tests/css/css-layout-api/sync-layout-microtasks.https.html b/testing/web-platform/tests/css/css-layout-api/sync-layout-microtasks.https.html
new file mode 100644
index 0000000000..84457c0c9d
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/sync-layout-microtasks.https.html
@@ -0,0 +1,56 @@
+<!DOCTYPE html>
+<html>
+<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#invoke-a-layout-callback">
+<meta name="assert" content="This test checks running the microtask queue for a layout() class won't run the main world's microtask queue." />
+<style>
+#test {
+ display: layout(child-layout);
+ width: 100px;
+}
+
+#test > div {
+ height: 100px;
+}
+</style>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/worklet-reftest.js"></script>
+
+<div id="test">
+ <div></div>
+</div>
+
+<script id="code" type="text/worklet">
+registerLayout('child-layout', class {
+ async intrinsicSizes() {}
+ async layout([child]) {
+ const fragment = await child.layoutNextFragment();
+ return {autoBlockSize: 50, childFragments: [fragment]};
+ }
+});
+</script>
+
+<script>
+promise_test(async t => {
+ if (typeof CSS.layoutWorklet === 'undefined') {
+ throw Error('CSS Layout API not supported.');
+ }
+
+ await importWorklet(CSS.layoutWorklet, document.getElementById('code').textContent);
+
+ let resolved = false;
+ let p = Promise.resolve().then(() => {
+ resolved = true;
+ });
+ assert_false(resolved);
+
+ // Running the layout-worklet's microtask queue shouldn't trigger the main
+ // world's microtask queue.
+ assert_equals(document.getElementById('test').clientHeight, 50);
+ assert_false(resolved);
+
+ await p;
+ assert_true(resolved);
+});
+</script>
+</html>