diff options
author | Andreas Kling <kling@serenityos.org> | 2021-02-10 18:23:52 +0100 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2021-02-10 19:06:20 +0100 |
commit | e562819a7e5649d18de106d4f9e88fa9c4b4a8cb (patch) | |
tree | 4a3c51636adab939f0d408ef5537000c0c6a9b3a | |
parent | 41ff7268db1d7821aaa194d0ba89a1b9fa493714 (diff) | |
download | serenity-e562819a7e5649d18de106d4f9e88fa9c4b4a8cb.zip |
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. :^)
-rw-r--r-- | Userland/Libraries/LibWeb/DOM/ShadowRoot.cpp | 6 | ||||
-rw-r--r-- | Userland/Libraries/LibWeb/DOM/ShadowRoot.h | 4 | ||||
-rw-r--r-- | 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 <LibWeb/DOM/Event.h> #include <LibWeb/DOM/ShadowRoot.h> +#include <LibWeb/Layout/BlockBox.h> namespace Web::DOM { @@ -46,4 +47,9 @@ EventTarget* ShadowRoot::get_parent(const Event& event) return host(); } +RefPtr<Layout::Node> 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<Layout::Node> 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 <LibWeb/DOM/Document.h> #include <LibWeb/DOM/Element.h> #include <LibWeb/DOM/ParentNode.h> +#include <LibWeb/DOM/ShadowRoot.h> #include <LibWeb/Dump.h> #include <LibWeb/Layout/InitialContainingBlockBox.h> #include <LibWeb/Layout/Node.h> @@ -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::Element>(dom_node) ? downcast<DOM::Element>(dom_node).shadow_root() : nullptr; + + if ((dom_node.has_children() || shadow_root) && layout_node->can_have_children()) { push_parent(downcast<NodeWithStyle>(*layout_node)); + if (shadow_root) + create_layout_tree(*shadow_root); downcast<DOM::ParentNode>(dom_node).for_each_child([&](auto& dom_child) { create_layout_tree(dom_child); }); |