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 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); });