summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Kling <kling@serenityos.org>2021-02-10 18:23:52 +0100
committerAndreas Kling <kling@serenityos.org>2021-02-10 19:06:20 +0100
commite562819a7e5649d18de106d4f9e88fa9c4b4a8cb (patch)
tree4a3c51636adab939f0d408ef5537000c0c6a9b3a
parent41ff7268db1d7821aaa194d0ba89a1b9fa493714 (diff)
downloadserenity-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.cpp6
-rw-r--r--Userland/Libraries/LibWeb/DOM/ShadowRoot.h4
-rw-r--r--Userland/Libraries/LibWeb/Layout/TreeBuilder.cpp11
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);
});