LibWeb: Accept TableWrapper as containing block for abspos items

When an element is displayed as table, an anonymous table wrapper box
needs to be created for it. Among others, the position property of the
table element is then applied to the anonymous table wrapper box
instead. If the table happens to be positioned absolutely, the table
wrapper box may become the containing block for absolutely positioned
elements inside the table.

In the original code however, anonymous layout nodes were excluded from
becoming the containing block for an absolutely positioned element.
Because of this, the containing block was calculated to be the first
suitable parent block of the table wrapper box.

This incorrect containing block would result in a crash later on when
trying to size the absolutely positioned element inside the table. To
prevent this crash, the anonymous table wrapper box is now allowed to
become the containing block for absolutely positioned elements inside
a table.

The definition of containing block for an absolutely positioned element
in the spec does not mention anything about skipping anonymous boxes.
Additionally the rules for absolute positioning of tables
(https://www.w3.org/TR/css-tables-3/#abspos-boxes-in-table-root) imply
that a table wrapper box is indeed able to be the containing block for
absolutely positioned elements.
This commit is contained in:
InvalidUsernameException 2025-01-19 14:35:25 +01:00 committed by Alexander Kalenik
parent b64a355a30
commit de71eb9b13
Notes: github-actions[bot] 2025-01-21 14:25:03 +00:00
4 changed files with 48 additions and 2 deletions

View file

@ -118,8 +118,6 @@ Box const* Node::containing_block() const
auto const* ancestor = parent(); auto const* ancestor = parent();
while (ancestor && !ancestor->can_contain_boxes_with_position_absolute()) while (ancestor && !ancestor->can_contain_boxes_with_position_absolute())
ancestor = ancestor->parent(); ancestor = ancestor->parent();
while (ancestor && ancestor->is_anonymous())
ancestor = nearest_ancestor_capable_of_forming_a_containing_block(*ancestor);
return static_cast<Box const*>(ancestor); return static_cast<Box const*>(ancestor);
} }

View file

@ -0,0 +1,35 @@
<!doctype html>
<link rel="author" title="David Grogan" href="mailto:dgrogan@chromium.org">
<link rel="help" href="https://www.w3.org/TR/css-position-3/#def-cb">
<link rel="match" href="../../../../expected/wpt-import/css/reference/ref-filled-green-100px-square-only.html">
<link rel="bookmark" href="https://crbug.com/977507" />
<meta name="assert" content="Abspos table works when it is dynamically added" />
<style>
table {
border-spacing: 0px;
}
td {
padding: 0px;
}
.outerTable {
height: 100px;
width: 100px;
position: relative;
}
.innerTable {
position: absolute;
top: 0px;
width: 100px;
height: 100%;
color: green;
background: green;
}
</style>
<p>Test passes if there is a filled green square.</p>
<table class=outerTable>
<td id=outerCell></td>
</table>
<script>
outerCell.innerHTML = "<table class=innerTable><td>some text</td></table>";
</script>

View file

@ -0,0 +1 @@
PASS (did not crash)

View file

@ -0,0 +1,12 @@
<!DOCTYPE html>
<script src="include.js"></script>
<style>
.outer {
display: table;
position: absolute;
}
.inner {
position: absolute;
}
</style><div class="outer"><div class="inner"></div></div>
<script>test(() => println("PASS (did not crash)"));</script>