From 3372a691da501918aa28d46d92e2d279ee35c5a2 Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Thu, 6 Jul 2023 08:47:29 +0200 Subject: [PATCH] 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. --- ...ith-svg-item-that-only-has-natural-aspect-ratio.txt | 5 +++++ ...th-svg-item-that-only-has-natural-aspect-ratio.html | 10 ++++++++++ .../Libraries/LibWeb/Layout/FlexFormattingContext.cpp | 8 ++++++-- 3 files changed, 21 insertions(+), 2 deletions(-) create mode 100644 Tests/LibWeb/Layout/expected/flex/intrinsic-height-of-flex-container-with-svg-item-that-only-has-natural-aspect-ratio.txt create mode 100644 Tests/LibWeb/Layout/input/flex/intrinsic-height-of-flex-container-with-svg-item-that-only-has-natural-aspect-ratio.html diff --git a/Tests/LibWeb/Layout/expected/flex/intrinsic-height-of-flex-container-with-svg-item-that-only-has-natural-aspect-ratio.txt b/Tests/LibWeb/Layout/expected/flex/intrinsic-height-of-flex-container-with-svg-item-that-only-has-natural-aspect-ratio.txt new file mode 100644 index 0000000000..b13cfe7d13 --- /dev/null +++ b/Tests/LibWeb/Layout/expected/flex/intrinsic-height-of-flex-container-with-svg-item-that-only-has-natural-aspect-ratio.txt @@ -0,0 +1,5 @@ +Viewport <#document> at (0,0) content-size 800x600 children: not-inline + BlockContainer at (0,0) content-size 800x16 [BFC] children: not-inline + Box at (8,8) content-size 784x0 flex-container(column) [FFC] children: not-inline + SVGSVGBox at (400,8) content-size 0x0 flex-item [SVG] children: not-inline + SVGGeometryBox at (400,8) content-size 0x0 children: not-inline diff --git a/Tests/LibWeb/Layout/input/flex/intrinsic-height-of-flex-container-with-svg-item-that-only-has-natural-aspect-ratio.html b/Tests/LibWeb/Layout/input/flex/intrinsic-height-of-flex-container-with-svg-item-that-only-has-natural-aspect-ratio.html new file mode 100644 index 0000000000..58b134715d --- /dev/null +++ b/Tests/LibWeb/Layout/input/flex/intrinsic-height-of-flex-container-with-svg-item-that-only-has-natural-aspect-ratio.html @@ -0,0 +1,10 @@ + \ No newline at end of file diff --git a/Userland/Libraries/LibWeb/Layout/FlexFormattingContext.cpp b/Userland/Libraries/LibWeb/Layout/FlexFormattingContext.cpp index 4694a5184d..960f4b6b18 100644 --- a/Userland/Libraries/LibWeb/Layout/FlexFormattingContext.cpp +++ b/Userland/Libraries/LibWeb/Layout/FlexFormattingContext.cpp @@ -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 item’s 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 item’s 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); } } }