Quellcode durchsuchen

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.
Aliaksandr Kalenik vor 1 Jahr
Ursprung
Commit
91ec1d6f95

+ 21 - 0
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<void(CSS::CSSStyleSheet&)>&& ca
     }
 }
 
+void Document::register_shadow_root(Badge<DOM::ShadowRoot>, DOM::ShadowRoot& shadow_root)
+{
+    m_shadow_roots.append(shadow_root);
+}
+
+void Document::unregister_shadow_root(Badge<DOM::ShadowRoot>, DOM::ShadowRoot& shadow_root)
+{
+    m_shadow_roots.remove_all_matching([&](auto& item) {
+        return item.ptr() == &shadow_root;
+    });
+}
+
+void Document::for_each_shadow_root(Function<void(DOM::ShadowRoot&)>&& callback)
+{
+    for (auto& shadow_root : m_shadow_roots)
+        callback(shadow_root);
+}
+
 }

+ 6 - 0
Userland/Libraries/LibWeb/DOM/Document.h

@@ -604,6 +604,10 @@ public:
     JS::NonnullGCPtr<WebIDL::ObservableArray> adopted_style_sheets() const;
     WebIDL::ExceptionOr<void> set_adopted_style_sheets(JS::Value);
 
+    void register_shadow_root(Badge<DOM::ShadowRoot>, DOM::ShadowRoot&);
+    void unregister_shadow_root(Badge<DOM::ShadowRoot>, DOM::ShadowRoot&);
+    void for_each_shadow_root(Function<void(DOM::ShadowRoot&)>&& 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<WebIDL::ObservableArray> m_adopted_style_sheets;
+
+    Vector<JS::NonnullGCPtr<DOM::ShadowRoot>> m_shadow_roots;
 };
 
 template<>

+ 7 - 0
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);

+ 2 - 0
Userland/Libraries/LibWeb/DOM/ShadowRoot.h

@@ -42,6 +42,8 @@ public:
     JS::NonnullGCPtr<WebIDL::ObservableArray> adopted_style_sheets() const;
     WebIDL::ExceptionOr<void> set_adopted_style_sheets(JS::Value);
 
+    virtual void finalize() override;
+
 protected:
     virtual void visit_edges(Cell::Visitor&) override;