Bug 1446130 [wpt PR 10054] - [css-layout-api] Allow LayoutChild(ren) to be laid out., a=testonly
authorIan Kilpatrick <ikilpatrick@chromium.org>
Mon, 09 Apr 2018 18:13:04 +0000
changeset 467185 76971d866c6999ca47afedbc7c428b513b2cbb10
parent 467184 1c178deec30f8b05ed3300f0b0e59efcc31fe240
child 467186 4cfcb3612183d4dd0bfe26a40103525b8d6aa33d
push id9165
push userasasaki@mozilla.com
push dateThu, 26 Apr 2018 21:04:54 +0000
treeherdermozilla-beta@064c3804de2e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerstestonly
bugs1446130, 10054, 726125, 962870, 545845
milestone61.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1446130 [wpt PR 10054] - [css-layout-api] Allow LayoutChild(ren) to be laid out., a=testonly Automatic update from web-platform-tests[css-layout-api] Allow LayoutChild(ren) to be laid out. This allows a LayoutChild to have layout performed on it, which will return a Fragment - with the correct inline and block sizes. These Fragments cannot be positioned yet, (next patch). The LayoutChild will be laid out with an available inline/block size of zero by default, and optionally can accept a fixed-inline/block size, which it must respect. Bug: 726125 Change-Id: Ie4386b8f6cd6ccec3f9e52ff332322101058836d Reviewed-on: https://chromium-review.googlesource.com/962870 Commit-Queue: Ian Kilpatrick <ikilpatrick@chromium.org> Reviewed-by: Kentaro Hara <haraken@chromium.org> Reviewed-by: Emil A Eklund <eae@chromium.org> Reviewed-by: Morten Stenshorne <mstensho@chromium.org> Cr-Commit-Position: refs/heads/master@{#545845} wpt-commits: 7988e1756539bcdf39ec2102b99e0671c44d503c wpt-pr: 10054 wpt-commits: 7988e1756539bcdf39ec2102b99e0671c44d503c wpt-pr: 10054
testing/web-platform/meta/MANIFEST.json
testing/web-platform/tests/common/worklet-reftest.js
testing/web-platform/tests/css/css-layout-api/fallback-layout-invalid-child.https.html
testing/web-platform/tests/css/css-layout-api/fallback-layout-invalid-fragment-request.https.html
testing/web-platform/tests/css/css-layout-api/fallback-layout-invalid-fragment.https.html
testing/web-platform/tests/css/css-layout-api/perform-child-layout-fixed-block-size-vrl.https.html
testing/web-platform/tests/css/css-layout-api/perform-child-layout-fixed-block-size.https.html
testing/web-platform/tests/css/css-layout-api/perform-child-layout-fixed-inline-size-vrl.https.html
testing/web-platform/tests/css/css-layout-api/perform-child-layout-fixed-inline-size.https.html
testing/web-platform/tests/css/css-layout-api/support/layout-child-fixed-sizes-worklet.js
testing/web-platform/tests/css/css-layout-api/support/layout-child-worklet.js
--- a/testing/web-platform/meta/MANIFEST.json
+++ b/testing/web-platform/meta/MANIFEST.json
@@ -117768,16 +117768,52 @@
       [
        "/css/css-layout-api/fallback-ref.html",
        "=="
       ]
      ],
      {}
     ]
    ],
+   "css/css-layout-api/fallback-layout-invalid-child.https.html": [
+    [
+     "/css/css-layout-api/fallback-layout-invalid-child.https.html",
+     [
+      [
+       "/css/css-layout-api/fallback-ref.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "css/css-layout-api/fallback-layout-invalid-fragment-request.https.html": [
+    [
+     "/css/css-layout-api/fallback-layout-invalid-fragment-request.https.html",
+     [
+      [
+       "/css/css-layout-api/fallback-ref.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "css/css-layout-api/fallback-layout-invalid-fragment.https.html": [
+    [
+     "/css/css-layout-api/fallback-layout-invalid-fragment.https.html",
+     [
+      [
+       "/css/css-layout-api/fallback-ref.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
    "css/css-layout-api/fallback-layout-return.https.html": [
     [
      "/css/css-layout-api/fallback-layout-return.https.html",
      [
       [
        "/css/css-layout-api/fallback-ref.html",
        "=="
       ]
@@ -117864,16 +117900,64 @@
       [
        "/css/css-layout-api/layout-child-ref.html",
        "=="
       ]
      ],
      {}
     ]
    ],
+   "css/css-layout-api/perform-child-layout-fixed-block-size-vrl.https.html": [
+    [
+     "/css/css-layout-api/perform-child-layout-fixed-block-size-vrl.https.html",
+     [
+      [
+       "/css/css-layout-api/layout-child-ref.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "css/css-layout-api/perform-child-layout-fixed-block-size.https.html": [
+    [
+     "/css/css-layout-api/perform-child-layout-fixed-block-size.https.html",
+     [
+      [
+       "/css/css-layout-api/layout-child-ref.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "css/css-layout-api/perform-child-layout-fixed-inline-size-vrl.https.html": [
+    [
+     "/css/css-layout-api/perform-child-layout-fixed-inline-size-vrl.https.html",
+     [
+      [
+       "/css/css-layout-api/layout-child-ref.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "css/css-layout-api/perform-child-layout-fixed-inline-size.https.html": [
+    [
+     "/css/css-layout-api/perform-child-layout-fixed-inline-size.https.html",
+     [
+      [
+       "/css/css-layout-api/layout-child-ref.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
    "css/css-layout-api/style-map-multi.https.html": [
     [
      "/css/css-layout-api/style-map-multi.https.html",
      [
       [
        "/css/css-layout-api/style-map-multi-ref.html",
        "=="
       ]
@@ -248425,16 +248509,21 @@
      {}
     ]
    ],
    "css/css-layout-api/style-map-ref.html": [
     [
      {}
     ]
    ],
+   "css/css-layout-api/support/layout-child-fixed-sizes-worklet.js": [
+    [
+     {}
+    ]
+   ],
    "css/css-layout-api/support/layout-child-worklet.js": [
     [
      {}
     ]
    ],
    "css/css-lists/OWNERS": [
     [
      {}
@@ -402930,17 +403019,17 @@
    "1d8598ff2c801c54c0f9be1c688b753bb6291c94",
    "support"
   ],
   "common/utils.js.headers": [
    "e3593850f8098d3f3ff82c042deab15f51c66a52",
    "support"
   ],
   "common/worklet-reftest.js": [
-   "29a9c4f2f6187fc64ecd1c77bcccfa1aef278ed8",
+   "11ef28419b58983d473606865c0d7a47be5e4056",
    "support"
   ],
   "compat/OWNERS": [
    "e714708a95e56bc556b64d991cb72f0ccace4f92",
    "support"
   ],
   "compat/green-ref.html": [
    "4b23ea52d785a6dd19785bd4278bf700eb5547f8",
@@ -502877,16 +502966,28 @@
   "css/css-layout-api/fallback-constructor-error.https.html": [
    "fdb9954e12f4628c114499a5e69f257b60377617",
    "reftest"
   ],
   "css/css-layout-api/fallback-layout-error.https.html": [
    "3d279f42a9b8e8ea0f6dc120d36ca0597372ef9b",
    "reftest"
   ],
+  "css/css-layout-api/fallback-layout-invalid-child.https.html": [
+   "f2fa9fefa56073f42a0537fa3140f37ca0c316da",
+   "reftest"
+  ],
+  "css/css-layout-api/fallback-layout-invalid-fragment-request.https.html": [
+   "24aed5d6b0f7ea7095324ce1f59adb0498277bdf",
+   "reftest"
+  ],
+  "css/css-layout-api/fallback-layout-invalid-fragment.https.html": [
+   "991b73a63246ae1d2676df32c3a56028f5a9583b",
+   "reftest"
+  ],
   "css/css-layout-api/fallback-layout-return.https.html": [
    "159662be847f8657d33a0607cb0e6561d57ef4e1",
    "reftest"
   ],
   "css/css-layout-api/fallback-ref.html": [
    "464a929254bba9991b03e2d0d161c0274c7c4b59",
    "support"
   ],
@@ -502921,34 +503022,54 @@
   "css/css-layout-api/layout-child-ref.html": [
    "1688098230f9fb825bc73134dff15dcf5ff9782d",
    "support"
   ],
   "css/css-layout-api/layout-child-text.https.html": [
    "567ff67317cae9906e6d159dc232c41464a4e7c6",
    "reftest"
   ],
+  "css/css-layout-api/perform-child-layout-fixed-block-size-vrl.https.html": [
+   "341711737d74fb068bb3a2e348e47820c236fa49",
+   "reftest"
+  ],
+  "css/css-layout-api/perform-child-layout-fixed-block-size.https.html": [
+   "486fe671afaa9275bc6b32c49ca4c8143290f9be",
+   "reftest"
+  ],
+  "css/css-layout-api/perform-child-layout-fixed-inline-size-vrl.https.html": [
+   "3c3b4c800af40a85eb9ddb588a07fc0d8ceec5cf",
+   "reftest"
+  ],
+  "css/css-layout-api/perform-child-layout-fixed-inline-size.https.html": [
+   "a25a85095781de557edde6dd02b82ee052642bf1",
+   "reftest"
+  ],
   "css/css-layout-api/style-map-multi-ref.html": [
    "d33f700e795484641d3cc7db1c26e09dca952209",
    "support"
   ],
   "css/css-layout-api/style-map-multi.https.html": [
    "646cb60aeb21fe01c899219f273e6c72e5b12ba8",
    "reftest"
   ],
   "css/css-layout-api/style-map-ref.html": [
    "fa11b57c69526a4922b2a5f9aeff2486d11a4fc6",
    "support"
   ],
   "css/css-layout-api/style-map.https.html": [
    "361b3c82c37c0068d23ae23e96d8e9185d3765b0",
    "reftest"
   ],
+  "css/css-layout-api/support/layout-child-fixed-sizes-worklet.js": [
+   "5ddda72e3c9d077508622511e8685249c7803028",
+   "support"
+  ],
   "css/css-layout-api/support/layout-child-worklet.js": [
-   "bea931d2a111e173494ec3bf2adaa9cc42b73a1e",
+   "87af0bfedbe9d4ea23e904edc5b22382a5d5d56c",
    "support"
   ],
   "css/css-layout-api/supports.https.html": [
    "be6b57f5a85f99a64e755da22411ace3fba2992f",
    "testharness"
   ],
   "css/css-lists/OWNERS": [
    "d9c8054b356c9273a054a83abeb9be0626c23921",
--- a/testing/web-platform/tests/common/worklet-reftest.js
+++ b/testing/web-platform/tests/common/worklet-reftest.js
@@ -1,25 +1,33 @@
-// To make sure that we take the snapshot at the right time, we do double
-// requestAnimationFrame. In the second frame, we take a screenshot, that makes
-// sure that we already have a full frame.
-function importWorkletAndTerminateTestAfterAsyncPaint(worklet, code) {
-    if (typeof worklet === 'undefined') {
-        takeScreenshot();
-        return;
-    }
-
+// Imports code into a worklet. E.g.
+//
+// importWorklet(CSS.paintWorklet, {url: 'script.js'});
+// importWorklet(CSS.paintWorklet, '/* javascript string */');
+function importWorklet(worklet, code) {
     let url;
     if (typeof code === 'object') {
       url = code.url;
     } else {
       const blob = new Blob([code], {type: 'text/javascript'});
       url = URL.createObjectURL(blob);
     }
 
-    worklet.addModule(url).then(function() {
+    return worklet.addModule(url);
+}
+
+// To make sure that we take the snapshot at the right time, we do double
+// requestAnimationFrame. In the second frame, we take a screenshot, that makes
+// sure that we already have a full frame.
+async function importWorkletAndTerminateTestAfterAsyncPaint(worklet, code) {
+    if (typeof worklet === 'undefined') {
+        takeScreenshot();
+        return;
+    }
+
+    await importWorklet(worklet, code);
+
+    requestAnimationFrame(function() {
         requestAnimationFrame(function() {
-            requestAnimationFrame(function() {
-                takeScreenshot();
-            });
+            takeScreenshot();
         });
     });
 }
new file mode 100644
--- /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-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']; }
+
+  *intrinsicSizes() {}
+  *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 = yield 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>
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/fallback-layout-invalid-fragment-request.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-ref.html">
+<meta name="assert" content="This test checks that a layout() class performing layout on an invalid fragment request 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']; }
+
+  *intrinsicSizes() {}
+  *layout(children, _, __, styleMap) {
+    if (styleMap.get('--fail').toString() !== 'true') {
+      this.request = children[0].layoutNextFragment({});
+    }
+
+    // Try to perform layout on the child. If its invalid (we skipped the if
+    // statement above) we should fallback to block layout.
+    const childFragments = yield [this.request];
+
+    return {autoBlockSize: 0, childFragments};
+  }
+});
+</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>
new file mode 100644
--- /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-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']; }
+
+  *intrinsicSizes() {}
+  *layout(children, _, __, styleMap) {
+    if (styleMap.get('--fail').toString() !== 'true') {
+      this.fragment = yield 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>
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/perform-child-layout-fixed-block-size-vrl.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-layoutconstraintsoptions-fixedinlinesize">
+<link rel="match" href="layout-child-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;
+  margin: 10px;
+  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-fixed-sizes-worklet.js'});
+</script>
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/perform-child-layout-fixed-block-size.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="layout-child-ref.html">
+<meta name="assert" content="This test checks that fixing the block size of children works as expected." />
+
+<style>
+.test {
+  background: red;
+  margin: 10px;
+  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-fixed-sizes-worklet.js'});
+</script>
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/perform-child-layout-fixed-inline-size-vrl.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-layoutconstraintsoptions-fixedinlinesize">
+<link rel="match" href="layout-child-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;
+  margin: 10px;
+  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-fixed-sizes-worklet.js'});
+</script>
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/perform-child-layout-fixed-inline-size.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="layout-child-ref.html">
+<meta name="assert" content="This test checks that fixing the inline size of children works as expected." />
+
+<style>
+.test {
+  background: red;
+  margin: 10px;
+  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-fixed-sizes-worklet.js'});
+</script>
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/css/css-layout-api/support/layout-child-fixed-sizes-worklet.js
@@ -0,0 +1,52 @@
+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 [
+      '--fixed-inline-size',
+      '--fixed-block-size',
+      '--inline-size-expected',
+      '--block-size-expected'
+    ];
+  }
+
+  *intrinsicSizes() {}
+  *layout(children, edges, constraints, styleMap) {
+    const childFragments = yield children.map((child) => {
+      const childConstraints = {};
+      const fixedInlineSize = parseNumber(child.styleMap.get('--fixed-inline-size'));
+      const fixedBlockSize = parseNumber(child.styleMap.get('--fixed-block-size'));
+      return child.layoutNextFragment({fixedInlineSize, fixedBlockSize});
+    });
+
+    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};
+  }
+});
--- a/testing/web-platform/tests/css/css-layout-api/support/layout-child-worklet.js
+++ b/testing/web-platform/tests/css/css-layout-api/support/layout-child-worklet.js
@@ -11,14 +11,16 @@ registerLayout('test', class {
 
   *intrinsicSizes() {}
   *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 = yield children.map((child) => { return child.layoutNextFragment({}); });
+
     if (!areArraysEqual(expected, actual))
-      return {autoBlockSize: 0};
+      return {autoBlockSize: 0, childFragments};
 
-    return {autoBlockSize: 100};
+    return {autoBlockSize: 100, childFragments};
   }
 });