diff --git a/Userland/Libraries/LibWeb/DOM/ShadowRoot.cpp b/Userland/Libraries/LibWeb/DOM/ShadowRoot.cpp index 237216379b..bf3744c9cc 100644 --- a/Userland/Libraries/LibWeb/DOM/ShadowRoot.cpp +++ b/Userland/Libraries/LibWeb/DOM/ShadowRoot.cpp @@ -26,6 +26,7 @@ #include #include +#include namespace Web::DOM { @@ -46,4 +47,9 @@ EventTarget* ShadowRoot::get_parent(const Event& event) return host(); } +RefPtr ShadowRoot::create_layout_node() +{ + return adopt(*new Layout::BlockBox(document(), this, CSS::ComputedValues {})); +} + } diff --git a/Userland/Libraries/LibWeb/DOM/ShadowRoot.h b/Userland/Libraries/LibWeb/DOM/ShadowRoot.h index 4bee76470d..9e9e026298 100644 --- a/Userland/Libraries/LibWeb/DOM/ShadowRoot.h +++ b/Userland/Libraries/LibWeb/DOM/ShadowRoot.h @@ -49,6 +49,10 @@ public: String mode() const { return m_closed ? "closed" : "open"; } private: + // ^Node + virtual FlyString node_name() const override { return "#shadow-root"; } + virtual RefPtr create_layout_node() override; + // NOTE: The specification doesn't seem to specify a default value for closed. Assuming false for now. bool m_closed { false }; bool m_delegates_focus { false }; diff --git a/Userland/Libraries/LibWeb/Layout/TreeBuilder.cpp b/Userland/Libraries/LibWeb/Layout/TreeBuilder.cpp index 6eeff109ea..23fa3eaf6e 100644 --- a/Userland/Libraries/LibWeb/Layout/TreeBuilder.cpp +++ b/Userland/Libraries/LibWeb/Layout/TreeBuilder.cpp @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include @@ -92,14 +93,14 @@ static Layout::Node& insertion_parent_for_block_node(Layout::Node& layout_parent void TreeBuilder::create_layout_tree(DOM::Node& dom_node) { // If the parent doesn't have a layout node, we don't need one either. - if (dom_node.parent() && !dom_node.parent()->layout_node()) + if (dom_node.parent_or_shadow_host() && !dom_node.parent_or_shadow_host()->layout_node()) return; auto layout_node = dom_node.create_layout_node(); if (!layout_node) return; - if (!dom_node.parent()) { + if (!dom_node.parent_or_shadow_host()) { m_layout_root = layout_node; } else { if (layout_node->is_inline()) { @@ -122,8 +123,12 @@ void TreeBuilder::create_layout_tree(DOM::Node& dom_node) } } - if (dom_node.has_children() && layout_node->can_have_children()) { + auto* shadow_root = is(dom_node) ? downcast(dom_node).shadow_root() : nullptr; + + if ((dom_node.has_children() || shadow_root) && layout_node->can_have_children()) { push_parent(downcast(*layout_node)); + if (shadow_root) + create_layout_tree(*shadow_root); downcast(dom_node).for_each_child([&](auto& dom_child) { create_layout_tree(dom_child); });