diff --git a/Userland/Libraries/LibWeb/DOM/Document.cpp b/Userland/Libraries/LibWeb/DOM/Document.cpp index f072283a75..46dd53bba0 100644 --- a/Userland/Libraries/LibWeb/DOM/Document.cpp +++ b/Userland/Libraries/LibWeb/DOM/Document.cpp @@ -1116,8 +1116,7 @@ void Document::adopt_node(Node& node) node.remove(); if (&old_document != this) { - // FIXME: This should be shadow-including. - node.for_each_in_inclusive_subtree([&](auto& inclusive_descendant) { + node.for_each_shadow_including_descendant([&](auto& inclusive_descendant) { inclusive_descendant.set_document({}, *this); // FIXME: If inclusiveDescendant is an element, then set the node document of each attribute in inclusiveDescendant’s attribute list to document. return IterationDecision::Continue; @@ -1127,8 +1126,7 @@ void Document::adopt_node(Node& node) // enqueue a custom element callback reaction with inclusiveDescendant, callback name "adoptedCallback", // and an argument list containing oldDocument and document. - // FIXME: This should be shadow-including. - node.for_each_in_inclusive_subtree([&](auto& inclusive_descendant) { + node.for_each_shadow_including_descendant([&](auto& inclusive_descendant) { inclusive_descendant.adopted_from(old_document); return IterationDecision::Continue; }); diff --git a/Userland/Libraries/LibWeb/DOM/Node.h b/Userland/Libraries/LibWeb/DOM/Node.h index d30275ef5c..8cd3ffb2c9 100644 --- a/Userland/Libraries/LibWeb/DOM/Node.h +++ b/Userland/Libraries/LibWeb/DOM/Node.h @@ -231,6 +231,10 @@ public: void queue_mutation_record(FlyString const& type, String attribute_name, String attribute_namespace, String old_value, NonnullRefPtr added_nodes, NonnullRefPtr removed_nodes, Node* previous_sibling, Node* next_sibling); + // https://dom.spec.whatwg.org/#concept-shadow-including-descendant + template + IterationDecision for_each_shadow_including_descendant(Callback); + protected: Node(Document&, NodeType); diff --git a/Userland/Libraries/LibWeb/DOM/ShadowRoot.h b/Userland/Libraries/LibWeb/DOM/ShadowRoot.h index b4306c4461..ea561e7b4c 100644 --- a/Userland/Libraries/LibWeb/DOM/ShadowRoot.h +++ b/Userland/Libraries/LibWeb/DOM/ShadowRoot.h @@ -45,4 +45,22 @@ private: template<> inline bool Node::fast_is() const { return is_shadow_root(); } +template +inline IterationDecision Node::for_each_shadow_including_descendant(Callback callback) +{ + if (callback(*this) == IterationDecision::Break) + return IterationDecision::Break; + for (auto* child = first_child(); child; child = child->next_sibling()) { + if (child->is_element()) { + if (RefPtr shadow_root = static_cast(child)->shadow_root()) { + if (shadow_root->for_each_shadow_including_descendant(callback) == IterationDecision::Break) + return IterationDecision::Break; + } + } + if (child->for_each_shadow_including_descendant(callback) == IterationDecision::Break) + return IterationDecision::Break; + } + return IterationDecision::Continue; +} + }