mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-12-04 05:20:30 +00:00
parent
4c0816b002
commit
769f11f9ae
Notes:
sideshowbarker
2024-07-18 00:41:35 +09:00
Author: https://github.com/axgallo Commit: https://github.com/SerenityOS/serenity/commit/769f11f9ae Pull-request: https://github.com/SerenityOS/serenity/pull/20675 Issue: https://github.com/SerenityOS/serenity/issues/19936 Reviewed-by: https://github.com/kalenikaliaksandr ✅
8 changed files with 199 additions and 24 deletions
|
@ -0,0 +1,57 @@
|
|||
Viewport <#document> at (0,0) content-size 800x600 children: not-inline
|
||||
BlockContainer <html> at (0,0) content-size 800x600 [BFC] children: not-inline
|
||||
BlockContainer <body> at (8,8) content-size 784x120.40625 children: not-inline
|
||||
Box <div> at (8,8) content-size 784x120.40625 [GFC] children: not-inline
|
||||
TableWrapper <(anonymous)> at (8,8) content-size 100x120.40625 [BFC] children: not-inline
|
||||
Box <table> at (9,9) content-size 98x118.40625 table-box [TFC] children: not-inline
|
||||
Box <tbody> at (9,9) content-size 98x118.40625 table-row-group children: not-inline
|
||||
Box <tr> at (9,9) content-size 98x39.46875 table-row children: not-inline
|
||||
BlockContainer <td> at (20,20) content-size 30.5625x17.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: [20,20 14.265625x17.46875]
|
||||
"A"
|
||||
TextNode <#text>
|
||||
BlockContainer <td> at (72.5625,20) content-size 23.4375x17.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: [72.5625,20 9.34375x17.46875]
|
||||
"B"
|
||||
TextNode <#text>
|
||||
Box <tr> at (9,48.46875) content-size 98x39.46875 table-row children: not-inline
|
||||
BlockContainer <td> at (20,59.46875) content-size 30.5625x17.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: [20,59.46875 14.265625x17.46875]
|
||||
"A"
|
||||
TextNode <#text>
|
||||
BlockContainer <(anonymous)> at (62.5625,68.703125) content-size 21.71875x0 table-cell [BFC] children: not-inline
|
||||
BlockContainer <(anonymous)> at (84.28125,68.203125) content-size 21.71875x0 table-cell [BFC] children: not-inline
|
||||
Box <tr> at (9,87.9375) content-size 98x39.46875 table-row children: not-inline
|
||||
BlockContainer <td> at (20,98.9375) content-size 30.5625x17.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: [20,98.9375 14.265625x17.46875]
|
||||
"A"
|
||||
TextNode <#text>
|
||||
BlockContainer <(anonymous)> at (62.5625,107.171875) content-size 21.71875x0 table-cell [BFC] children: not-inline
|
||||
BlockContainer <(anonymous)> at (84.28125,107.171875) content-size 21.71875x0 table-cell [BFC] children: not-inline
|
||||
|
||||
ViewportPaintable (Viewport<#document>) [0,0 800x600]
|
||||
PaintableWithLines (BlockContainer<HTML>) [0,0 800x600]
|
||||
PaintableWithLines (BlockContainer<BODY>) [8,8 784x120.40625]
|
||||
PaintableBox (Box<DIV>) [8,8 784x120.40625]
|
||||
PaintableWithLines (TableWrapper(anonymous)) [8,8 100x120.40625]
|
||||
PaintableBox (Box<TABLE>) [8,8 100x120.40625]
|
||||
PaintableBox (Box<TBODY>) [9,9 98x118.40625]
|
||||
PaintableBox (Box<TR>) [9,9 98x39.46875]
|
||||
PaintableWithLines (BlockContainer<TD>) [9,9 52.5625x39.46875]
|
||||
TextPaintable (TextNode<#text>)
|
||||
PaintableWithLines (BlockContainer<TD>) [61.5625,9 45.4375x39.46875]
|
||||
TextPaintable (TextNode<#text>)
|
||||
PaintableBox (Box<TR>) [9,48.46875 98x39.46875]
|
||||
PaintableWithLines (BlockContainer<TD>) [9,48.46875 52.5625x39.46875]
|
||||
TextPaintable (TextNode<#text>)
|
||||
PaintableWithLines (BlockContainer(anonymous)) [61.5625,48.46875 22.71875x39.46875]
|
||||
PaintableWithLines (BlockContainer(anonymous)) [84.28125,48.46875 22.71875x39.46875]
|
||||
PaintableBox (Box<TR>) [9,87.9375 98x39.46875]
|
||||
PaintableWithLines (BlockContainer<TD>) [9,87.9375 52.5625x39.46875]
|
||||
TextPaintable (TextNode<#text>)
|
||||
PaintableWithLines (BlockContainer(anonymous)) [61.5625,87.9375 22.71875x39.46875]
|
||||
PaintableWithLines (BlockContainer(anonymous)) [84.28125,87.9375 22.71875x39.46875]
|
53
Tests/LibWeb/Layout/expected/table/missing-cells.txt
Normal file
53
Tests/LibWeb/Layout/expected/table/missing-cells.txt
Normal file
|
@ -0,0 +1,53 @@
|
|||
Viewport <#document> at (0,0) content-size 800x600 children: not-inline
|
||||
BlockContainer <html> at (0,0) content-size 800x600 [BFC] children: not-inline
|
||||
BlockContainer <body> at (8,8) content-size 784x120.40625 children: not-inline
|
||||
Box <div> at (8,8) content-size 784x120.40625 [GFC] children: not-inline
|
||||
TableWrapper <(anonymous)> at (8,8) content-size 100x120.40625 [BFC] children: not-inline
|
||||
Box <table> at (9,9) content-size 98x118.40625 table-box [TFC] children: not-inline
|
||||
Box <tbody> at (9,9) content-size 98x118.40625 table-row-group children: not-inline
|
||||
Box <tr> at (9,9) content-size 98x39.46875 table-row children: not-inline
|
||||
BlockContainer <td> at (20,20) content-size 30.5625x17.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: [20,20 14.265625x17.46875]
|
||||
"A"
|
||||
TextNode <#text>
|
||||
BlockContainer <td> at (72.5625,20) content-size 23.4375x17.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: [72.5625,20 9.34375x17.46875]
|
||||
"B"
|
||||
TextNode <#text>
|
||||
Box <tr> at (9,48.46875) content-size 98x39.46875 table-row children: not-inline
|
||||
BlockContainer <td> at (20,59.46875) content-size 30.5625x17.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: [20,59.46875 14.265625x17.46875]
|
||||
"A"
|
||||
TextNode <#text>
|
||||
BlockContainer <(anonymous)> at (62.5625,68.703125) content-size 43.4375x0 table-cell [BFC] children: not-inline
|
||||
Box <tr> at (9,87.9375) content-size 98x39.46875 table-row children: not-inline
|
||||
BlockContainer <td> at (20,98.9375) content-size 30.5625x17.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: [20,98.9375 14.265625x17.46875]
|
||||
"A"
|
||||
TextNode <#text>
|
||||
BlockContainer <(anonymous)> at (62.5625,107.171875) content-size 43.4375x0 table-cell [BFC] children: not-inline
|
||||
|
||||
ViewportPaintable (Viewport<#document>) [0,0 800x600]
|
||||
PaintableWithLines (BlockContainer<HTML>) [0,0 800x600]
|
||||
PaintableWithLines (BlockContainer<BODY>) [8,8 784x120.40625]
|
||||
PaintableBox (Box<DIV>) [8,8 784x120.40625]
|
||||
PaintableWithLines (TableWrapper(anonymous)) [8,8 100x120.40625]
|
||||
PaintableBox (Box<TABLE>) [8,8 100x120.40625]
|
||||
PaintableBox (Box<TBODY>) [9,9 98x118.40625]
|
||||
PaintableBox (Box<TR>) [9,9 98x39.46875]
|
||||
PaintableWithLines (BlockContainer<TD>) [9,9 52.5625x39.46875]
|
||||
TextPaintable (TextNode<#text>)
|
||||
PaintableWithLines (BlockContainer<TD>) [61.5625,9 45.4375x39.46875]
|
||||
TextPaintable (TextNode<#text>)
|
||||
PaintableBox (Box<TR>) [9,48.46875 98x39.46875]
|
||||
PaintableWithLines (BlockContainer<TD>) [9,48.46875 52.5625x39.46875]
|
||||
TextPaintable (TextNode<#text>)
|
||||
PaintableWithLines (BlockContainer(anonymous)) [61.5625,48.46875 45.4375x39.46875]
|
||||
PaintableBox (Box<TR>) [9,87.9375 98x39.46875]
|
||||
PaintableWithLines (BlockContainer<TD>) [9,87.9375 52.5625x39.46875]
|
||||
TextPaintable (TextNode<#text>)
|
||||
PaintableWithLines (BlockContainer(anonymous)) [61.5625,87.9375 45.4375x39.46875]
|
16
Tests/LibWeb/Layout/input/table/missing-cells-with-span.html
Normal file
16
Tests/LibWeb/Layout/input/table/missing-cells-with-span.html
Normal file
|
@ -0,0 +1,16 @@
|
|||
<style>
|
||||
div {
|
||||
display: grid;
|
||||
}
|
||||
|
||||
table {
|
||||
border: 1px solid black;
|
||||
border-collapse: collapse;
|
||||
width: 100px;
|
||||
}
|
||||
|
||||
td {
|
||||
border: 1px solid black;
|
||||
padding: 10px;
|
||||
}
|
||||
</style><div><table><tr><td>A</td><td colspan="2">B</td></tr><tr><td>A</td></tr><tr><td>A</td></tr></table></div>
|
16
Tests/LibWeb/Layout/input/table/missing-cells.html
Normal file
16
Tests/LibWeb/Layout/input/table/missing-cells.html
Normal file
|
@ -0,0 +1,16 @@
|
|||
<style>
|
||||
div {
|
||||
display: grid;
|
||||
}
|
||||
|
||||
table {
|
||||
border: 1px solid black;
|
||||
border-collapse: collapse;
|
||||
width: 100px;
|
||||
}
|
||||
|
||||
td {
|
||||
border: 1px solid black;
|
||||
padding: 10px;
|
||||
}
|
||||
</style><div><table><tr><td>A</td><td>B</td></tr><tr><td>A</td></tr><tr><td>A</td></tr></table></div>
|
|
@ -12,26 +12,6 @@
|
|||
#include <LibWeb/Layout/InlineFormattingContext.h>
|
||||
#include <LibWeb/Layout/TableFormattingContext.h>
|
||||
|
||||
struct GridPosition {
|
||||
size_t x;
|
||||
size_t y;
|
||||
};
|
||||
|
||||
inline bool operator==(GridPosition const& a, GridPosition const& b)
|
||||
{
|
||||
return a.x == b.x && a.y == b.y;
|
||||
}
|
||||
|
||||
namespace AK {
|
||||
template<>
|
||||
struct Traits<GridPosition> : public GenericTraits<GridPosition> {
|
||||
static unsigned hash(GridPosition const& key)
|
||||
{
|
||||
return pair_int_hash(key.x, key.y);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
namespace Web::Layout {
|
||||
|
||||
TableFormattingContext::TableFormattingContext(LayoutState& state, Box const& root, FormattingContext* parent)
|
||||
|
|
|
@ -38,7 +38,6 @@ public:
|
|||
private:
|
||||
CSSPixels run_caption_layout(LayoutMode, CSS::CaptionSide);
|
||||
CSSPixels compute_capmin();
|
||||
void calculate_row_column_grid(Box const&);
|
||||
void compute_constrainedness();
|
||||
void compute_cell_measures();
|
||||
void compute_outer_content_sizes();
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include <LibWeb/Layout/ListItemMarkerBox.h>
|
||||
#include <LibWeb/Layout/Node.h>
|
||||
#include <LibWeb/Layout/Progress.h>
|
||||
#include <LibWeb/Layout/TableGrid.h>
|
||||
#include <LibWeb/Layout/TableWrapper.h>
|
||||
#include <LibWeb/Layout/TextNode.h>
|
||||
#include <LibWeb/Layout/TreeBuilder.h>
|
||||
|
@ -451,7 +452,8 @@ void TreeBuilder::fixup_tables(NodeWithStyle& root)
|
|||
{
|
||||
remove_irrelevant_boxes(root);
|
||||
generate_missing_child_wrappers(root);
|
||||
generate_missing_parents(root);
|
||||
auto table_root_boxes = generate_missing_parents(root);
|
||||
missing_cells_fixup(table_root_boxes);
|
||||
}
|
||||
|
||||
void TreeBuilder::remove_irrelevant_boxes(NodeWithStyle& root)
|
||||
|
@ -621,7 +623,7 @@ void TreeBuilder::generate_missing_child_wrappers(NodeWithStyle& root)
|
|||
});
|
||||
}
|
||||
|
||||
void TreeBuilder::generate_missing_parents(NodeWithStyle& root)
|
||||
Vector<JS::Handle<Box>> TreeBuilder::generate_missing_parents(NodeWithStyle& root)
|
||||
{
|
||||
Vector<JS::Handle<Box>> table_roots_to_wrap;
|
||||
root.for_each_in_inclusive_subtree_of_type<Box>([&](auto& parent) {
|
||||
|
@ -671,6 +673,57 @@ void TreeBuilder::generate_missing_parents(NodeWithStyle& root)
|
|||
else
|
||||
parent.append_child(*wrapper);
|
||||
}
|
||||
|
||||
return table_roots_to_wrap;
|
||||
}
|
||||
|
||||
template<typename Matcher, typename Callback>
|
||||
static void for_each_child_box_matching(Box& parent, Matcher matcher, Callback callback)
|
||||
{
|
||||
parent.for_each_child_of_type<Box>([&](Box& child_box) {
|
||||
if (matcher(child_box))
|
||||
callback(child_box);
|
||||
});
|
||||
}
|
||||
|
||||
static void fixup_row(Box& row_box, TableGrid const& table_grid, size_t row_index)
|
||||
{
|
||||
bool missing_cells_run_has_started = false;
|
||||
for (size_t column_index = 0; column_index < table_grid.column_count(); ++column_index) {
|
||||
if (table_grid.occupancy_grid().contains({ column_index, row_index })) {
|
||||
VERIFY(!missing_cells_run_has_started);
|
||||
continue;
|
||||
}
|
||||
missing_cells_run_has_started = true;
|
||||
auto row_computed_values = row_box.computed_values().clone_inherited_values();
|
||||
auto& cell_computed_values = static_cast<CSS::MutableComputedValues&>(row_computed_values);
|
||||
cell_computed_values.set_display(Web::CSS::Display { CSS::Display::Internal::TableCell });
|
||||
// Ensure that the cell (with zero content height) will have the same height as the row by setting vertical-align to middle.
|
||||
cell_computed_values.set_vertical_align(CSS::VerticalAlign::Middle);
|
||||
auto cell_box = row_box.heap().template allocate_without_realm<BlockContainer>(row_box.document(), nullptr, cell_computed_values);
|
||||
row_box.append_child(cell_box);
|
||||
}
|
||||
}
|
||||
|
||||
void TreeBuilder::missing_cells_fixup(Vector<JS::Handle<Box>> const& table_root_boxes)
|
||||
{
|
||||
// Implements https://www.w3.org/TR/css-tables-3/#missing-cells-fixup.
|
||||
for (auto& table_box : table_root_boxes) {
|
||||
auto table_grid = TableGrid::calculate_row_column_grid(*table_box);
|
||||
size_t row_index = 0;
|
||||
for_each_child_box_matching(*table_box, TableGrid::is_table_row_group, [&](auto& row_group_box) {
|
||||
for_each_child_box_matching(row_group_box, is_table_row, [&](auto& row_box) {
|
||||
fixup_row(row_box, table_grid, row_index);
|
||||
++row_index;
|
||||
return IterationDecision::Continue;
|
||||
});
|
||||
});
|
||||
|
||||
for_each_child_box_matching(*table_box, is_table_row, [&](auto& row_box) {
|
||||
fixup_row(row_box, table_grid, row_index);
|
||||
++row_index;
|
||||
return IterationDecision::Continue;
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,7 +39,8 @@ private:
|
|||
void fixup_tables(NodeWithStyle& root);
|
||||
void remove_irrelevant_boxes(NodeWithStyle& root);
|
||||
void generate_missing_child_wrappers(NodeWithStyle& root);
|
||||
void generate_missing_parents(NodeWithStyle& root);
|
||||
Vector<JS::Handle<Box>> generate_missing_parents(NodeWithStyle& root);
|
||||
void missing_cells_fixup(Vector<JS::Handle<Box>> const&);
|
||||
|
||||
enum class AppendOrPrepend {
|
||||
Append,
|
||||
|
|
Loading…
Reference in a new issue