LibWeb: Fix table width algorithm when available space is a constraint

Handle available space more carefully when computing a table width, in
order to avoid creating a definite infinite width when available space
width is max-content, as it's the case in calculate_max_content_width.
The constraint is thus correctly propagated by the time we cache the
computed value, which was previously rejected by the hash function due
to being definite but infinite instead of max-content.
This commit is contained in:
Andi Gallo 2023-06-11 12:04:01 +00:00 committed by Andreas Kling
parent b86ca27692
commit 75e87c32f2
Notes: sideshowbarker 2024-07-17 03:35:24 +09:00
4 changed files with 27 additions and 1 deletions

View file

@ -11,6 +11,7 @@ namespace Web::Layout {
AvailableSize AvailableSize::make_definite(CSSPixels value)
{
VERIFY(isfinite(value.value()));
return AvailableSize { Type::Definite, value };
}

View file

@ -415,7 +415,14 @@ CSSPixels BlockFormattingContext::compute_table_box_width_inside_table_wrapper(B
auto available_width = width_of_containing_block - margin_left.to_px(box) - margin_right.to_px(box);
LayoutState throwaway_state(&m_state);
throwaway_state.get_mutable(box).set_content_width(available_width);
if (available_space.width.is_definite())
throwaway_state.get_mutable(box).set_content_width(available_width);
else if (available_space.width.is_min_content())
throwaway_state.get_mutable(box).set_min_content_width();
else {
VERIFY(available_space.width.is_max_content());
throwaway_state.get_mutable(box).set_max_content_width();
}
auto context = create_independent_formatting_context_if_needed(throwaway_state, box);
VERIFY(context);
context->run(box, LayoutMode::IntrinsicSizing, m_state.get(box).available_inner_space_or_constraints_from(available_space));

View file

@ -297,6 +297,7 @@ void LayoutState::UsedValues::set_node(NodeWithStyleAndBoxModelMetrics& node, Us
void LayoutState::UsedValues::set_content_width(CSSPixels width)
{
VERIFY(isfinite(width.value()));
if (width < 0) {
// Negative widths are not allowed in CSS. We have a bug somewhere! Clamp to 0 to avoid doing too much damage.
dbgln_if(LIBWEB_CSS_DEBUG, "FIXME: Layout calculated a negative width for {}: {}", m_node->debug_description(), width);
@ -308,6 +309,7 @@ void LayoutState::UsedValues::set_content_width(CSSPixels width)
void LayoutState::UsedValues::set_content_height(CSSPixels height)
{
VERIFY(isfinite(height.value()));
if (height < 0) {
// Negative heights are not allowed in CSS. We have a bug somewhere! Clamp to 0 to avoid doing too much damage.
dbgln_if(LIBWEB_CSS_DEBUG, "FIXME: Layout calculated a negative height for {}: {}", m_node->debug_description(), height);
@ -387,4 +389,18 @@ void LayoutState::UsedValues::set_indefinite_content_height()
m_has_definite_height = false;
}
void LayoutState::UsedValues::set_min_content_width()
{
width_constraint = SizeConstraint::MinContent;
m_content_width = 0;
m_has_definite_height = false;
}
void LayoutState::UsedValues::set_max_content_width()
{
width_constraint = SizeConstraint::MaxContent;
m_content_width = INFINITY;
m_has_definite_height = false;
}
}

View file

@ -51,6 +51,8 @@ struct LayoutState {
void set_indefinite_content_width();
void set_indefinite_content_height();
void set_min_content_width();
void set_max_content_width();
// NOTE: These are used by FlexFormattingContext to assign a temporary main size to items
// early on, so that descendants have something to resolve percentages against.