From e562819a7e5649d18de106d4f9e88fa9c4b4a8cb Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Wed, 10 Feb 2021 18:23:52 +0100 Subject: [PATCH] LibWeb: Generate layout nodes for shadow subtrees Elements with shadow roots will now recurse into those shadow trees while building the layout tree. This is the first step towards basic Shadow DOM support. :^) --- Userland/Libraries/LibWeb/DOM/ShadowRoot.cpp | 6 ++++++ Userland/Libraries/LibWeb/DOM/ShadowRoot.h | 4 ++++ Userland/Libraries/LibWeb/Layout/TreeBuilder.cpp | 11 ++++++++--- 3 files changed, 18 insertions(+), 3 deletions(-) diff --git a/Userland/Libraries/LibWeb/DOM/ShadowRoot.cpp b/Userland/Libraries/LibWeb/DOM/ShadowRoot.cpp index 237216379be..bf3744c9cc4 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 4bee76470de..9e9e0262988 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 6eeff109ead..23fa3eaf6ea 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); });