LibWeb: Don't let items flex to infinite size in column layout

When sizing under a max-content constraint, we allow flex lines to have
an infinite amount of "remaining space", but we shouldn't let infinity
leak into the geometry of items. So treat it as zero in arithmetic.

This fixes an issue where inline SVGs with natural aspect ratio (from
viewBox) but no natural width or height could get an infinite size as
flex items.
This commit is contained in:
Andreas Kling 2023-07-06 08:47:29 +02:00
parent 00d8e221f3
commit 3372a691da
Notes: sideshowbarker 2024-07-17 22:09:47 +09:00
3 changed files with 21 additions and 2 deletions

View file

@ -0,0 +1,5 @@
Viewport <#document> at (0,0) content-size 800x600 children: not-inline
BlockContainer <html> at (0,0) content-size 800x16 [BFC] children: not-inline
Box <body> at (8,8) content-size 784x0 flex-container(column) [FFC] children: not-inline
SVGSVGBox <svg> at (400,8) content-size 0x0 flex-item [SVG] children: not-inline
SVGGeometryBox <rect> at (400,8) content-size 0x0 children: not-inline

View file

@ -0,0 +1,10 @@
<!DOCTYPE html><style>
body {
display: flex;
flex-direction: column;
align-items: center;
}
svg {
flex-grow: 1;
}
</style><body><svg viewBox="0 0 24 24"><rect x=0 y=0 width=12 height=12></svg>

View file

@ -1004,6 +1004,10 @@ void FlexFormattingContext::resolve_flexible_lengths_for_line(FlexLine& line)
line.remaining_free_space = value;
}
// AD-HOC: We allow the remaining free space to be infinite, but we can't let infinity
// leak into the layout geometry, so we treat infinity as zero when used in arithmetic.
auto remaining_free_space_or_zero_if_infinite = isfinite(line.remaining_free_space.to_double()) ? line.remaining_free_space : 0;
// c. If the remaining free space is non-zero, distribute it proportional to the flex factors:
if (line.remaining_free_space != 0) {
// If using the flex grow factor
@ -1016,7 +1020,7 @@ void FlexFormattingContext::resolve_flexible_lengths_for_line(FlexLine& line)
continue;
double ratio = item.flex_factor.value() / sum_of_flex_factor_of_unfrozen_items;
// Set the items target main size to its flex base size plus a fraction of the remaining free space proportional to the ratio.
item.target_main_size = item.flex_base_size + (line.remaining_free_space * ratio);
item.target_main_size = item.flex_base_size + (remaining_free_space_or_zero_if_infinite * ratio);
}
}
// If using the flex shrink factor
@ -1038,7 +1042,7 @@ void FlexFormattingContext::resolve_flexible_lengths_for_line(FlexLine& line)
// Set the items target main size to its flex base size minus a fraction of the absolute value of the remaining free space proportional to the ratio.
// (Note this may result in a negative inner main size; it will be corrected in the next step.)
item.target_main_size = item.flex_base_size - (abs(line.remaining_free_space) * ratio);
item.target_main_size = item.flex_base_size - (abs(remaining_free_space_or_zero_if_infinite) * ratio);
}
}
}