From 030b1a197bec8b0eb0fe974b7f043ca78ad16a61 Mon Sep 17 00:00:00 2001 From: Andi Gallo Date: Wed, 12 Jul 2023 03:03:16 +0000 Subject: [PATCH] LibWeb: Don't use the preferred increment as reference for distribution The specification says we should distribute excess width proportionally to the width of the cell, not to the preferred increment. Doing the latter leads to distributing all excess width to just the cells which demand some increment, even if it's very modest. Moreover, there's code which partially implements the correct criteria just below the one we remove here. --- ...-auto-max-width-table-percentage-width.txt | 10 ++--- ...th-distribution-of-max-width-increment.txt | 38 +++++++++++++++++++ ...auto-max-width-table-percentage-width.html | 0 ...h-distribution-of-max-width-increment.html | 24 ++++++++++++ .../LibWeb/Layout/TableFormattingContext.cpp | 35 ++++++++++++----- 5 files changed, 93 insertions(+), 14 deletions(-) rename Tests/LibWeb/Layout/expected/{ => table}/cell-auto-max-width-table-percentage-width.txt (85%) create mode 100644 Tests/LibWeb/Layout/expected/table/width-distribution-of-max-width-increment.txt rename Tests/LibWeb/Layout/input/{ => table}/cell-auto-max-width-table-percentage-width.html (100%) create mode 100644 Tests/LibWeb/Layout/input/table/width-distribution-of-max-width-increment.html diff --git a/Tests/LibWeb/Layout/expected/cell-auto-max-width-table-percentage-width.txt b/Tests/LibWeb/Layout/expected/table/cell-auto-max-width-table-percentage-width.txt similarity index 85% rename from Tests/LibWeb/Layout/expected/cell-auto-max-width-table-percentage-width.txt rename to Tests/LibWeb/Layout/expected/table/cell-auto-max-width-table-percentage-width.txt index 1d7bad67ce..ac328ce24f 100644 --- a/Tests/LibWeb/Layout/expected/cell-auto-max-width-table-percentage-width.txt +++ b/Tests/LibWeb/Layout/expected/table/cell-auto-max-width-table-percentage-width.txt @@ -14,23 +14,23 @@ Viewport <#document> at (0,0) content-size 800x600 children: not-inline Box at (10,10) content-size 72x19.46875 table-row children: not-inline BlockContainer <(anonymous)> (not painted) children: inline TextNode <#text> - BlockContainer at (11,11) content-size 14.265625x17.46875 table-cell [BFC] children: inline + BlockContainer at (11,11) content-size 17.828571x17.46875 table-cell [BFC] children: inline line 0 width: 14.265625, height: 17.46875, bottom: 17.46875, baseline: 13.53125 frag 0 from TextNode start: 0, length: 1, rect: [11,11 14.265625x17.46875] "A" TextNode <#text> BlockContainer <(anonymous)> (not painted) children: inline TextNode <#text> - BlockContainer at (29.265625,11) content-size 9.34375x17.46875 table-cell [BFC] children: inline + BlockContainer at (32.828571,11) content-size 11.828571x17.46875 table-cell [BFC] children: inline line 0 width: 9.34375, height: 17.46875, bottom: 17.46875, baseline: 13.53125 - frag 0 from TextNode start: 0, length: 1, rect: [29.265625,11 9.34375x17.46875] + frag 0 from TextNode start: 0, length: 1, rect: [32.828571,11 9.34375x17.46875] "B" TextNode <#text> BlockContainer <(anonymous)> (not painted) children: inline TextNode <#text> - BlockContainer at (42.609375,11) content-size 42.390625x17.46875 table-cell [BFC] children: inline + BlockContainer at (48.657142,11) content-size 36.342857x17.46875 table-cell [BFC] children: inline line 0 width: 29.453125, height: 17.46875, bottom: 17.46875, baseline: 13.53125 - frag 0 from TextNode start: 0, length: 3, rect: [42.609375,11 29.453125x17.46875] + frag 0 from TextNode start: 0, length: 3, rect: [48.657142,11 29.453125x17.46875] "C D" TextNode <#text> BlockContainer <(anonymous)> (not painted) children: inline diff --git a/Tests/LibWeb/Layout/expected/table/width-distribution-of-max-width-increment.txt b/Tests/LibWeb/Layout/expected/table/width-distribution-of-max-width-increment.txt new file mode 100644 index 0000000000..15fc58d867 --- /dev/null +++ b/Tests/LibWeb/Layout/expected/table/width-distribution-of-max-width-increment.txt @@ -0,0 +1,38 @@ +Viewport <#document> at (0,0) content-size 800x600 children: not-inline + BlockContainer at (0,0) content-size 800x600 [BFC] children: not-inline + BlockContainer at (8,8) content-size 784x21.46875 children: not-inline + TableWrapper <(anonymous)> at (8,8) content-size 784x21.46875 [BFC] children: not-inline + Box at (8,8) content-size 784x21.46875 table-box [TFC] children: not-inline + BlockContainer <(anonymous)> (not painted) children: inline + TextNode <#text> + Box at (8,8) content-size 784x21.46875 table-row-group children: not-inline + BlockContainer <(anonymous)> (not painted) children: inline + TextNode <#text> + Box at (8,8) content-size 784x21.46875 table-row children: not-inline + BlockContainer <(anonymous)> (not painted) children: inline + TextNode <#text> + BlockContainer
at (10,10) content-size 216.099903x17.46875 table-cell [BFC] children: inline + line 0 width: 14.265625, height: 17.46875, bottom: 17.46875, baseline: 13.53125 + frag 0 from TextNode start: 1, length: 1, rect: [10,10 14.265625x17.46875] + "A" + TextNode <#text> + BlockContainer <(anonymous)> (not painted) children: inline + TextNode <#text> + BlockContainer at (230.099903,10) content-size 156.791546x17.46875 table-cell [BFC] children: inline + line 0 width: 9.34375, height: 17.46875, bottom: 17.46875, baseline: 13.53125 + frag 0 from TextNode start: 1, length: 1, rect: [230.099903,10 9.34375x17.46875] + "B" + TextNode <#text> + BlockContainer <(anonymous)> (not painted) children: inline + TextNode <#text> + BlockContainer at (390.891450,10) content-size 399.108549x17.46875 table-cell [BFC] children: inline + line 0 width: 29.453125, height: 17.46875, bottom: 17.46875, baseline: 13.53125 + frag 0 from TextNode start: 1, length: 3, rect: [390.891450,10 29.453125x17.46875] + "C D" + TextNode <#text> + BlockContainer <(anonymous)> (not painted) children: inline + TextNode <#text> + BlockContainer <(anonymous)> (not painted) children: inline + TextNode <#text> + BlockContainer <(anonymous)> (not painted) children: inline + TextNode <#text> diff --git a/Tests/LibWeb/Layout/input/cell-auto-max-width-table-percentage-width.html b/Tests/LibWeb/Layout/input/table/cell-auto-max-width-table-percentage-width.html similarity index 100% rename from Tests/LibWeb/Layout/input/cell-auto-max-width-table-percentage-width.html rename to Tests/LibWeb/Layout/input/table/cell-auto-max-width-table-percentage-width.html diff --git a/Tests/LibWeb/Layout/input/table/width-distribution-of-max-width-increment.html b/Tests/LibWeb/Layout/input/table/width-distribution-of-max-width-increment.html new file mode 100644 index 0000000000..b49d8f5d39 --- /dev/null +++ b/Tests/LibWeb/Layout/input/table/width-distribution-of-max-width-increment.html @@ -0,0 +1,24 @@ + + + + + + + + + +
+ A + + B + + C D +
\ No newline at end of file diff --git a/Userland/Libraries/LibWeb/Layout/TableFormattingContext.cpp b/Userland/Libraries/LibWeb/Layout/TableFormattingContext.cpp index 7356b78c19..a8e53dc710 100644 --- a/Userland/Libraries/LibWeb/Layout/TableFormattingContext.cpp +++ b/Userland/Libraries/LibWeb/Layout/TableFormattingContext.cpp @@ -532,10 +532,16 @@ void TableFormattingContext::distribute_width_to_columns() expand_columns_to_fill_available_width(column_type); }; + // 1. The min-content sizing-guess is the set of column width assignments where each column is assigned its min-content width. for (auto& column : m_columns) { column.used_width = column.min_size; } + // 2. The min-content-percentage sizing-guess is the set of column width assignments where: + // - each percent-column is assigned the larger of: + // - its intrinsic percentage width times the assignable width and + // - its min-content width. + // - all other columns are assigned their min-content width. for (auto& column : m_columns) { if (column.type == SizeType::Percent) { column.used_width = max(column.min_size, column.percentage_width / 100 * available_width); @@ -547,6 +553,12 @@ void TableFormattingContext::distribute_width_to_columns() return; } + // 3. The min-content-specified sizing-guess is the set of column width assignments where: + // - each percent-column is assigned the larger of: + // - its intrinsic percentage width times the assignable width and + // - its min-content width + // - any other column that is constrained is assigned its max-content width + // - all other columns are assigned their min-content width. for (auto& column : m_columns) { if (column.type == SizeType::Pixel) { column.used_width = column.max_size; @@ -558,20 +570,25 @@ void TableFormattingContext::distribute_width_to_columns() return; } - if (columns_total_used_width() < available_width) { - expand_columns_to_fill_available_width(SizeType::Auto); + // 4. The max-content sizing-guess is the set of column width assignments where: + // - each percent-column is assigned the larger of: + // - its intrinsic percentage width times the assignable width and + // - its min-content width + // - all other columns are assigned their max-content width. + for (auto& column : m_columns) { + if (column.type != SizeType::Percent) { + column.used_width = column.max_size; + } } - if (columns_total_used_width() < available_width) { - expand_columns_to_fill_available_width(SizeType::Pixel); - } + // If the assignable table width is less than or equal to the max-content sizing-guess, the used widths of the columns must be the + // linear combination (with weights adding to 1) of the two consecutive sizing-guesses whose width sums bound the available width. - if (columns_total_used_width() < available_width) { - expand_columns_to_fill_available_width(SizeType::Percent); - } + // Otherwise, the used widths of the columns are the result of starting from the max-content sizing-guess and distributing + // the excess width to the columns of the table according to the rules for distributing excess width to columns (for used width). // Implements steps 1 and 2 of https://www.w3.org/TR/css-tables-3/#distributing-width-to-columns - // FIXME: Implement steps 3-5 as well, which distribute excess width to constrained columns. + // FIXME: Implement steps 3-6 as well, which distribute excess width to constrained columns. if (columns_total_used_width() < available_width) { // NOTE: if all columns got their max width and there is still width to distribute left // it should be assigned to columns proportionally to their max width