commit fe94eb63d22766c55f6d5441da83b2592c638799
parent af07ef454030c6410244a1c3470fee76a78a3949
Author: Daniel Holbert <dholbert@cs.stanford.edu>
Date: Wed, 19 Nov 2025 17:26:05 +0000
Bug 1989368: Handle 'stretch'-like sizes in ReflowInput::InitConstraints. r=layout-reviewers,emilio
This is needed for certain cases with table layout that happen to bypass our
codepaths that would otherwise resolve 'stretch' closer to the point-of-use.
So, this patch makes us resolve 'stretch' a bit more eagerly here.
I'm including a testcase (expanded from the testcase in the bug report)
that has 'stretch' applied to various table parts, to give us code-coverage
for these scenarioos.
The correctness checks in the testcase are kinda trivial (and would generally
pass whether or not the 'stertch' keyword is supported), since table layout
already forces table-parts to stretch, generally. So, the point of the test is
mostly to give us some basic code coverage to ensure that we behave reasonably
when this keyword (and its aliases like -webkit-fill-available) are used in
this context.
Differential Revision: https://phabricator.services.mozilla.com/D272732
Diffstat:
2 files changed, 140 insertions(+), 1 deletion(-)
diff --git a/layout/generic/ReflowInput.cpp b/layout/generic/ReflowInput.cpp
@@ -2219,8 +2219,23 @@ void ReflowInput::InitConstraints(
mComputeSizeFlags, aBorder, aPadding, mStyleDisplay);
// For calculating the size of this box, we use its own writing mode
- const auto blockSize =
+ auto blockSize =
mStylePosition->BSize(wm, AnchorPosResolutionParams::From(this));
+ if (blockSize->BehavesLikeStretchOnBlockAxis()) {
+ // Resolve 'stretch' to either 'auto' or the stretched bsize, depending
+ // on whether our containing block has a definite bsize.
+ // TODO(dholbert): remove this in bug 2000035.
+ if (NS_UNCONSTRAINEDSIZE == cbSize.BSize(wm)) {
+ blockSize = AnchorResolvedSizeHelper::Auto();
+ } else {
+ nscoord stretchBSize = nsLayoutUtils::ComputeStretchBSize(
+ cbSize.BSize(wm), ComputedLogicalMargin(wm).BStartEnd(wm),
+ ComputedLogicalBorderPadding(wm).BStartEnd(wm),
+ mStylePosition->mBoxSizing);
+ blockSize = AnchorResolvedSizeHelper::LengthPercentage(
+ StyleLengthPercentage::FromAppUnits(stretchBSize));
+ }
+ }
bool isAutoBSize = blockSize->BehavesLikeInitialValueOnBlockAxis();
// Check for a percentage based block size and a containing block
diff --git a/testing/web-platform/tests/css/css-sizing/stretch/stretch-table-001.html b/testing/web-platform/tests/css/css-sizing/stretch/stretch-table-001.html
@@ -0,0 +1,124 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<link rel="help"
+ href="https://drafts.csswg.org/css-sizing-4/#stretch-fit-sizing">
+<link rel="author" title="Daniel Holbert" href="mailto:dholbert@mozilla.com">
+<script src='/resources/testharness.js'></script>
+<script src='/resources/testharnessreport.js'></script>
+<script src="/resources/check-layout-th.js"></script>
+<meta name="assert"
+ content="The stretch keyword should work as a block-size for table parts">
+<style>
+table {
+ border-spacing: 0;
+ margin-bottom: 3px;
+}
+td {
+ border: 0;
+ padding: 0;
+}
+.stretch {
+ height: -webkit-fill-available;
+ height: stretch;
+}
+.spacer {
+ height: 10px;
+ width: 20px;
+ background: tan;
+}
+</style>
+<body onload="checkLayout('.stretch')">
+ <!-- 'stretch' on a table: -->
+ <table class="stretch"
+ data-expected-width="40"
+ data-expected-height="10">
+ <tbody>
+ <tr>
+ <td><div class="spacer"></div></td>
+ <td><div class="spacer"></div></td>
+ </tr>
+ </tbody>
+ </table>
+
+ <!-- 'stretch' on a table in a fixed-height div: -->
+ <div style="height: 30px">
+ <table class="stretch"
+ data-expected-width="40"
+ data-expected-height="30">
+ <tbody>
+ <tr>
+ <td><div class="spacer"></div></td>
+ <td><div class="spacer"></div></td>
+ </tr>
+ </tbody>
+ </table>
+ </div>
+
+ <!-- 'stretch' on a tbody: -->
+ <table>
+ <tbody class="stretch"
+ data-expected-width="40"
+ data-expected-height="10">
+ <tr>
+ <td><div class="spacer"></div></td>
+ <td><div class="spacer"></div></td>
+ </tr>
+ </tbody>
+ </table>
+
+ <!-- 'stretch' on a table row: -->
+ <table>
+ <tbody>
+ <tr class="stretch"
+ data-expected-width="40"
+ data-expected-height="10">
+ <td><div class="spacer"></div></td>
+ <td><div class="spacer"></div></td>
+ </tr>
+ </tbody>
+ </table>
+
+ <!-- 'stretch' on a table cell: -->
+ <table>
+ <tbody>
+ <tr>
+ <td class="stretch"
+ data-expected-width="20"
+ data-expected-height="10">
+ <div class="spacer"></div>
+ </td>
+ <td><div class="spacer"></div></td>
+ </tr>
+ </tbody>
+ </table>
+
+ <!-- 'stretch' on a row-spanning table cell: -->
+ <table>
+ <tbody>
+ <tr>
+ <td><div class="spacer"></div></td>
+ <td class="stretch"
+ data-expected-width="20"
+ data-expected-height="20" rowspan="2">
+ <div class="spacer"></div>
+ </td>
+ </tr>
+ <tr><td><div class="spacer"></div></td></tr>
+ </tbody>
+ </table>
+
+ <!-- 'stretch' on a caption: -->
+ <table>
+ <caption class="stretch"
+ data-expected-width="40"
+ data-expected-height="10">
+ <div class="spacer"></div>
+ </caption>
+ <tbody>
+ <tr>
+ <td><div class="spacer"></div></td>
+ <td><div class="spacer"></div></td>
+ </tr>
+ </tbody>
+ </table>
+</body>