From 91ec1d6f950e28bcc638bd4cb512c7099fed8a6e Mon Sep 17 00:00:00 2001 From: Aliaksandr Kalenik Date: Sat, 9 Mar 2024 00:19:05 +0100 Subject: [PATCH] LibWeb: Maintain list of allocated shadow roots in Document Doing that will allow us to get a list of style sheets for each shadow root from StyleComputer without having to traverse the entire tree in upcoming changes. --- Userland/Libraries/LibWeb/DOM/Document.cpp | 21 ++++++++++++++++++++ Userland/Libraries/LibWeb/DOM/Document.h | 6 ++++++ Userland/Libraries/LibWeb/DOM/ShadowRoot.cpp | 7 +++++++ Userland/Libraries/LibWeb/DOM/ShadowRoot.h | 2 ++ 4 files changed, 36 insertions(+) diff --git a/Userland/Libraries/LibWeb/DOM/Document.cpp b/Userland/Libraries/LibWeb/DOM/Document.cpp index 485c3768e2..34ff642720 100644 --- a/Userland/Libraries/LibWeb/DOM/Document.cpp +++ b/Userland/Libraries/LibWeb/DOM/Document.cpp @@ -486,6 +486,9 @@ void Document::visit_edges(Cell::Visitor& visitor) } visitor.visit(m_adopted_style_sheets); + + for (auto& shadow_root : m_shadow_roots) + visitor.visit(shadow_root); } // https://w3c.github.io/selection-api/#dom-document-getselection @@ -4601,4 +4604,22 @@ void Document::for_each_css_style_sheet(Function&& ca } } +void Document::register_shadow_root(Badge, DOM::ShadowRoot& shadow_root) +{ + m_shadow_roots.append(shadow_root); +} + +void Document::unregister_shadow_root(Badge, DOM::ShadowRoot& shadow_root) +{ + m_shadow_roots.remove_all_matching([&](auto& item) { + return item.ptr() == &shadow_root; + }); +} + +void Document::for_each_shadow_root(Function&& callback) +{ + for (auto& shadow_root : m_shadow_roots) + callback(shadow_root); +} + } diff --git a/Userland/Libraries/LibWeb/DOM/Document.h b/Userland/Libraries/LibWeb/DOM/Document.h index b5f9c14041..d6c62b7b2a 100644 --- a/Userland/Libraries/LibWeb/DOM/Document.h +++ b/Userland/Libraries/LibWeb/DOM/Document.h @@ -604,6 +604,10 @@ public: JS::NonnullGCPtr adopted_style_sheets() const; WebIDL::ExceptionOr set_adopted_style_sheets(JS::Value); + void register_shadow_root(Badge, DOM::ShadowRoot&); + void unregister_shadow_root(Badge, DOM::ShadowRoot&); + void for_each_shadow_root(Function&& callback); + protected: virtual void initialize(JS::Realm&) override; virtual void visit_edges(Cell::Visitor&) override; @@ -840,6 +844,8 @@ private: bool m_needs_to_resolve_paint_only_properties { true }; mutable JS::GCPtr m_adopted_style_sheets; + + Vector> m_shadow_roots; }; template<> diff --git a/Userland/Libraries/LibWeb/DOM/ShadowRoot.cpp b/Userland/Libraries/LibWeb/DOM/ShadowRoot.cpp index 8b7c255c95..48323f990d 100644 --- a/Userland/Libraries/LibWeb/DOM/ShadowRoot.cpp +++ b/Userland/Libraries/LibWeb/DOM/ShadowRoot.cpp @@ -19,9 +19,16 @@ ShadowRoot::ShadowRoot(Document& document, Element& host, Bindings::ShadowRootMo : DocumentFragment(document) , m_mode(mode) { + document.register_shadow_root({}, *this); set_host(&host); } +void ShadowRoot::finalize() +{ + Base::finalize(); + document().unregister_shadow_root({}, *this); +} + void ShadowRoot::initialize(JS::Realm& realm) { Base::initialize(realm); diff --git a/Userland/Libraries/LibWeb/DOM/ShadowRoot.h b/Userland/Libraries/LibWeb/DOM/ShadowRoot.h index 8aa0aa5706..532f99985b 100644 --- a/Userland/Libraries/LibWeb/DOM/ShadowRoot.h +++ b/Userland/Libraries/LibWeb/DOM/ShadowRoot.h @@ -42,6 +42,8 @@ public: JS::NonnullGCPtr adopted_style_sheets() const; WebIDL::ExceptionOr set_adopted_style_sheets(JS::Value); + virtual void finalize() override; + protected: virtual void visit_edges(Cell::Visitor&) override;