diff --git a/Userland/Libraries/LibWeb/Layout/Node.cpp b/Userland/Libraries/LibWeb/Layout/Node.cpp index 0f793cea72..9fae6c4c84 100644 --- a/Userland/Libraries/LibWeb/Layout/Node.cpp +++ b/Userland/Libraries/LibWeb/Layout/Node.cpp @@ -13,6 +13,7 @@ #include #include #include +#include #include #include @@ -666,6 +667,17 @@ JS::NonnullGCPtr NodeWithStyle::create_anonymous_wrapper() const return *wrapper; } +void NodeWithStyle::reset_table_box_computed_values_used_by_wrapper_to_init_values() +{ + VERIFY(is(*this)); + + CSS::MutableComputedValues& mutable_computed_values = static_cast(m_computed_values); + mutable_computed_values.set_position(CSS::Position::Static); + mutable_computed_values.set_float(CSS::Float::None); + mutable_computed_values.set_inset({ CSS::Length::make_auto(), CSS::Length::make_auto(), CSS::Length::make_auto(), CSS::Length::make_auto() }); + mutable_computed_values.set_margin({ CSS::Length::make_px(0), CSS::Length::make_px(0), CSS::Length::make_px(0), CSS::Length::make_px(0) }); +} + void Node::set_paintable(RefPtr paintable) { m_paintable = move(paintable); diff --git a/Userland/Libraries/LibWeb/Layout/Node.h b/Userland/Libraries/LibWeb/Layout/Node.h index 4b7622ca75..baf01d4490 100644 --- a/Userland/Libraries/LibWeb/Layout/Node.h +++ b/Userland/Libraries/LibWeb/Layout/Node.h @@ -183,6 +183,8 @@ public: JS::NonnullGCPtr create_anonymous_wrapper() const; + void reset_table_box_computed_values_used_by_wrapper_to_init_values(); + protected: NodeWithStyle(DOM::Document&, DOM::Node*, NonnullRefPtr); NodeWithStyle(DOM::Document&, DOM::Node*, CSS::ComputedValues); diff --git a/Userland/Libraries/LibWeb/Layout/TreeBuilder.cpp b/Userland/Libraries/LibWeb/Layout/TreeBuilder.cpp index 2baa4e37bb..a89909e88c 100644 --- a/Userland/Libraries/LibWeb/Layout/TreeBuilder.cpp +++ b/Userland/Libraries/LibWeb/Layout/TreeBuilder.cpp @@ -550,6 +550,7 @@ void TreeBuilder::generate_missing_child_wrappers(NodeWithStyle& root) void TreeBuilder::generate_missing_parents(NodeWithStyle& root) { + Vector> table_roots_to_wrap; root.for_each_in_inclusive_subtree_of_type([&](auto& parent) { // An anonymous table-row box must be generated around each sequence of consecutive table-cell boxes whose parent is not a table-row. if (is_not_table_row(parent)) { @@ -572,8 +573,36 @@ void TreeBuilder::generate_missing_parents(NodeWithStyle& root) }); } + // An anonymous table-wrapper box must be generated around each table-root. + if (parent.display().is_table_inside()) { + table_roots_to_wrap.append(static_cast(parent)); + } + return IterationDecision::Continue; }); + + for (auto& table_box : table_roots_to_wrap) { + auto* nearest_sibling = table_box->next_sibling(); + auto& parent = *table_box->parent(); + + CSS::ComputedValues wrapper_computed_values; + // The computed values of properties 'position', 'float', 'margin-*', 'top', 'right', 'bottom', and 'left' on the table element are used on the table wrapper box and not the table box; + // all other values of non-inheritable properties are used on the table box and not the table wrapper box. + // (Where the table element's values are not used on the table and table wrapper boxes, the initial values are used instead.) + auto& mutable_wrapper_computed_values = static_cast(wrapper_computed_values); + mutable_wrapper_computed_values.set_display(CSS::Display(CSS::Display::Outside::Block, CSS::Display::Inside::FlowRoot)); + mutable_wrapper_computed_values.set_position(table_box->computed_values().position()); + mutable_wrapper_computed_values.set_inset(table_box->computed_values().inset()); + mutable_wrapper_computed_values.set_float(table_box->computed_values().float_()); + mutable_wrapper_computed_values.set_margin(table_box->computed_values().margin()); + table_box->reset_table_box_computed_values_used_by_wrapper_to_init_values(); + + auto wrapper = parent.heap().allocate_without_realm(parent.document(), nullptr, move(wrapper_computed_values)); + + parent.remove_child(*table_box); + wrapper->append_child(*table_box); + parent.insert_before(*wrapper, *nearest_sibling); + } } }