diff --git a/Libraries/LibWeb/Layout/Node.cpp b/Libraries/LibWeb/Layout/Node.cpp index 0d9a896d686..2875a9295eb 100644 --- a/Libraries/LibWeb/Layout/Node.cpp +++ b/Libraries/LibWeb/Layout/Node.cpp @@ -30,6 +30,7 @@ #include #include #include +#include namespace Web::Layout { @@ -1210,6 +1211,30 @@ CSS::UserSelect Node::user_select_used_value() const return computed_value; } +bool NodeWithStyleAndBoxModelMetrics::should_create_inline_continuation() const +{ + // This node must have an inline parent. + if (!parent()) + return false; + auto const& parent_display = parent()->display(); + if (!parent_display.is_inline_outside() || !parent_display.is_flow_inside()) + return false; + + // This node must not be inline itself or out of flow (which gets handled separately). + if (display().is_inline_outside() || is_out_of_flow()) + return false; + + // This node must not have `display: contents`; inline continuation gets handled by its children. + if (display().is_contents()) + return false; + + // Parent element must not be + if (is(parent()->dom_node())) + return false; + + return true; +} + void NodeWithStyleAndBoxModelMetrics::propagate_style_along_continuation(CSS::ComputedProperties const& computed_style) const { auto continuation = continuation_of_node(); diff --git a/Libraries/LibWeb/Layout/Node.h b/Libraries/LibWeb/Layout/Node.h index 36f43a87252..b250844ddd4 100644 --- a/Libraries/LibWeb/Layout/Node.h +++ b/Libraries/LibWeb/Layout/Node.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2018-2023, Andreas Kling + * Copyright (c) 2025, Jelle Raaijmakers * * SPDX-License-Identifier: BSD-2-Clause */ @@ -265,6 +266,8 @@ public: GC::Ptr continuation_of_node() const { return m_continuation_of_node; } void set_continuation_of_node(Badge, GC::Ptr node) { m_continuation_of_node = node; } + bool should_create_inline_continuation() const; + void propagate_style_along_continuation(CSS::ComputedProperties const&) const; virtual void visit_edges(Cell::Visitor& visitor) override; diff --git a/Libraries/LibWeb/Layout/TreeBuilder.cpp b/Libraries/LibWeb/Layout/TreeBuilder.cpp index 94ef21171d5..cbb5627979f 100644 --- a/Libraries/LibWeb/Layout/TreeBuilder.cpp +++ b/Libraries/LibWeb/Layout/TreeBuilder.cpp @@ -32,7 +32,6 @@ #include #include #include -#include namespace Web::Layout { @@ -609,11 +608,9 @@ void TreeBuilder::update_layout_tree(DOM::Node& dom_node, TreeBuilder::Context& // If we completely finished inserting a block level element into an inline parent, we need to fix up the tree so // that we can maintain the invariant that all children are either inline or non-inline. We can't do this earlier, // because the restructuring adds new children after this node that become part of the ancestor stack. - auto* layout_parent = layout_node->parent(); - if (layout_parent && layout_parent->display().is_inline_outside() && !display.is_contents() - && !is(layout_parent->dom_node()) - && !display.is_inline_outside() && layout_parent->display().is_flow_inside() && !layout_node->is_out_of_flow()) - restructure_block_node_in_inline_parent(static_cast(*layout_node)); + if (auto node_with_metrics = as_if(*layout_node); + node_with_metrics && node_with_metrics->should_create_inline_continuation()) + restructure_block_node_in_inline_parent(*node_with_metrics); } // https://www.w3.org/TR/css-contain-2/#containment-style