LibWeb: Assign static position for abspos boxes nested into TFC

TFC is not aware of how to correctly calculate a static position for
abspos boxes, but assigning (0, 0) is better than crashing during abspos
item layout.

Fixes https://github.com/LadybirdBrowser/ladybird/issues/1382
This commit is contained in:
Aliaksandr Kalenik 2024-09-13 22:42:43 +02:00 committed by Andreas Kling
commit 9621439db0
Notes: github-actions[bot] 2024-09-14 13:04:58 +00:00
5 changed files with 70 additions and 1 deletions

View file

@ -0,0 +1,18 @@
Viewport <#document> at (0,0) content-size 800x600 children: not-inline
BlockContainer <html> at (0,0) content-size 800x20 [BFC] children: not-inline
BlockContainer <body> at (8,8) content-size 784x4 children: not-inline
TableWrapper <(anonymous)> at (8,8) content-size 784x4 [BFC] children: not-inline
Box <table> at (8,8) content-size 784x4 table-box [TFC] children: not-inline
Box <thead> at (8,8) content-size 0x0 table-header-group children: not-inline
Box <tr> at (10,10) content-size 0x0 table-row children: not-inline
BlockContainer <(anonymous)> at (0,590) content-size 800x10 positioned [BFC] children: inline
TextNode <#text>
ViewportPaintable (Viewport<#document>) [0,0 800x600]
PaintableWithLines (BlockContainer<HTML>) [0,0 800x20] overflow: [0,0 800x600]
PaintableWithLines (BlockContainer<BODY>) [8,8 784x4] overflow: [0,8 800x592]
PaintableWithLines (TableWrapper(anonymous)) [8,8 784x4] overflow: [0,8 800x592]
PaintableBox (Box<TABLE>) [8,8 784x4] overflow: [0,8 800x592]
PaintableBox (Box<THEAD>) [8,8 0x0] overflow: [0,10 800x590]
PaintableBox (Box<TR>) [10,10 0x0] overflow: [0,590 800x10]
PaintableWithLines (BlockContainer(anonymous)) [0,590 800x10]

View file

@ -0,0 +1,21 @@
<!DOCTYPE html><style>
table {
width: 100%;
}
th, td {
border: 1px solid #ccc;
padding: 8px;
text-align: left;
}
tr::before {
content: '';
position: absolute;
bottom: 0;
left: 0;
width: 100%;
height: 10px;
background-color: red;
}
</style><table><thead><tr></tr></thead></table>

View file

@ -152,7 +152,6 @@ Optional<FormattingContext::Type> FormattingContext::formatting_context_type_cre
// FIXME: We need this for <math> elements
return Type::InternalDummy;
}
return {};
}

View file

@ -1607,6 +1607,35 @@ void TableFormattingContext::run_until_width_calculation(AvailableSpace const& a
compute_table_width();
}
void TableFormattingContext::parent_context_did_dimension_child_root_box()
{
if (m_layout_mode != LayoutMode::Normal)
return;
context_box().for_each_in_subtree_of_type<Box const>([&](Layout::Box const& box) {
if (box.is_absolutely_positioned()) {
// FIXME: calculate_static_position_rect() is not aware of how to correctly calculate static position for
// a box nested inside a table, but we need to set some value, so layout_absolutely_positioned_element()
// won't crash trying to access it.
m_state.get_mutable(box).set_static_position_rect(calculate_static_position_rect(box));
}
if (formatting_context_type_created_by_box(box).has_value()) {
return TraversalDecision::SkipChildrenAndContinue;
}
return TraversalDecision::Continue;
});
for (auto& child : context_box().contained_abspos_children()) {
auto& box = verify_cast<Box>(*child);
auto& cb_state = m_state.get(*box.containing_block());
auto available_width = AvailableSize::make_definite(cb_state.content_width() + cb_state.padding_left + cb_state.padding_right);
auto available_height = AvailableSize::make_definite(cb_state.content_height() + cb_state.padding_top + cb_state.padding_bottom);
layout_absolutely_positioned_element(box, AvailableSpace(available_width, available_height));
}
}
void TableFormattingContext::run(AvailableSpace const& available_space)
{
m_available_space = available_space;

View file

@ -37,6 +37,8 @@ public:
static bool border_is_less_specific(const CSS::BorderData& a, const CSS::BorderData& b);
virtual void parent_context_did_dimension_child_root_box() override;
private:
CSSPixels run_caption_layout(CSS::CaptionSide);
CSSPixels compute_capmin();