diff options
author | Andi Gallo <andigallo@proton.me> | 2023-05-18 03:55:39 +0000 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2023-05-21 14:23:41 +0200 |
commit | e6221117a5f32fedc8d344d6172f06c087b8055d (patch) | |
tree | 4e9a3d19d9fceed5867bce368ad100a7d91dc9b3 /Userland | |
parent | 6cb9d755d90f005b63828df6a66b074c0345d6e2 (diff) | |
download | serenity-e6221117a5f32fedc8d344d6172f06c087b8055d.zip |
LibWeb: Implement table rowspan
Adjust computing the table height and positioning of cells to account
for the rowspan property.
Fixes #18952.
Diffstat (limited to 'Userland')
-rw-r--r-- | Userland/Libraries/LibWeb/Layout/TableFormattingContext.cpp | 35 | ||||
-rw-r--r-- | Userland/Libraries/LibWeb/Layout/TableFormattingContext.h | 2 |
2 files changed, 35 insertions, 2 deletions
diff --git a/Userland/Libraries/LibWeb/Layout/TableFormattingContext.cpp b/Userland/Libraries/LibWeb/Layout/TableFormattingContext.cpp index 0757f30ace..f48e51461c 100644 --- a/Userland/Libraries/LibWeb/Layout/TableFormattingContext.cpp +++ b/Userland/Libraries/LibWeb/Layout/TableFormattingContext.cpp @@ -457,7 +457,11 @@ void TableFormattingContext::compute_table_height(LayoutMode layout_mode) cell.baseline = box_baseline(m_state, cell.box); - row.base_height = max(row.base_height, cell_state.border_box_height()); + // Only cells spanning the current row exclusively are part of computing minimum height of a row, + // as described in https://www.w3.org/TR/css-tables-3/#computing-the-table-height + if (cell.row_span == 1) { + row.base_height = max(row.base_height, cell_state.border_box_height()); + } row.baseline = max(row.baseline, cell.baseline); } @@ -645,7 +649,7 @@ void TableFormattingContext::position_cell_boxes() auto& cell_state = m_state.get_mutable(cell.box); auto& row_state = m_state.get(m_rows[cell.row_index].box); CSSPixels const cell_border_box_height = cell_state.content_height() + cell_state.border_box_top() + cell_state.border_box_bottom(); - CSSPixels const row_content_height = row_state.content_height(); + CSSPixels const row_content_height = compute_row_content_height(cell); auto const& vertical_align = cell.box->computed_values().vertical_align(); if (vertical_align.has<CSS::VerticalAlign>()) { switch (vertical_align.get<CSS::VerticalAlign>()) { @@ -671,6 +675,33 @@ void TableFormattingContext::position_cell_boxes() } } +CSSPixels TableFormattingContext::compute_row_content_height(Cell const& cell) const +{ + auto& row_state = m_state.get(m_rows[cell.row_index].box); + if (cell.row_span == 1) { + return row_state.content_height(); + } + // The height of a cell is the sum of all spanned rows, as described in + // https://www.w3.org/TR/css-tables-3/#bounding-box-assignment + + // When the row span is greater than 1, the borders of inner rows within the span have to be + // included in the content height of the spanning cell. First top and final bottom borders are + // excluded to be consistent with the handling of row span 1 case above, which uses the content + // height (no top and bottom borders) of the row. + CSSPixels span_height = 0; + for (size_t i = 0; i < cell.row_span; ++i) { + auto const& row_state = m_state.get(m_rows[cell.row_index + i].box); + if (i == 0) { + span_height += row_state.content_height() + row_state.border_box_bottom(); + } else if (i == cell.row_span - 1) { + span_height += row_state.border_box_top() + row_state.content_height(); + } else { + span_height += row_state.border_box_height(); + } + } + return span_height; +} + void TableFormattingContext::run(Box const& box, LayoutMode layout_mode, AvailableSpace const& available_space) { m_available_space = available_space; diff --git a/Userland/Libraries/LibWeb/Layout/TableFormattingContext.h b/Userland/Libraries/LibWeb/Layout/TableFormattingContext.h index f8ade2a8e2..0b85bb34ea 100644 --- a/Userland/Libraries/LibWeb/Layout/TableFormattingContext.h +++ b/Userland/Libraries/LibWeb/Layout/TableFormattingContext.h @@ -78,6 +78,8 @@ private: CSSPixels max_width { 0 }; }; + CSSPixels compute_row_content_height(Cell const& cell) const; + Vector<Cell> m_cells; Vector<Column> m_columns; Vector<Row> m_rows; |