Selaa lähdekoodia

LibWeb: Use a WeakPtr for DocumentFragment's "host" field

We had a reference cycle between fragments and their hosts.
Andreas Kling 3 vuotta sitten
vanhempi
commit
fdb647c097

+ 4 - 3
Userland/Libraries/LibWeb/DOM/DocumentFragment.h

@@ -26,13 +26,14 @@ public:
 
     virtual FlyString node_name() const override { return "#document-fragment"; }
 
-    RefPtr<Element> host() { return m_host; }
-    const RefPtr<Element> host() const { return m_host; }
+    Element* host() { return m_host; }
+    Element const* host() const { return m_host; }
 
     void set_host(Element& host) { m_host = host; }
 
 private:
-    RefPtr<Element> m_host;
+    // https://dom.spec.whatwg.org/#concept-documentfragment-host
+    WeakPtr<Element> m_host;
 };
 
 }

+ 8 - 1
Userland/Libraries/LibWeb/DOM/Node.cpp

@@ -701,7 +701,14 @@ u16 Node::compare_document_position(RefPtr<Node> other)
 // https://dom.spec.whatwg.org/#concept-tree-host-including-inclusive-ancestor
 bool Node::is_host_including_inclusive_ancestor_of(const Node& other) const
 {
-    return is_inclusive_ancestor_of(other) || (is<DocumentFragment>(other.root()) && verify_cast<DocumentFragment>(other.root()).host() && is_inclusive_ancestor_of(*verify_cast<DocumentFragment>(other.root()).host().ptr()));
+    if (is_inclusive_ancestor_of(other))
+        return true;
+    if (is<DocumentFragment>(other.root())
+        && static_cast<DocumentFragment const&>(other.root()).host()
+        && is_inclusive_ancestor_of(*static_cast<DocumentFragment const&>(other.root()).host())) {
+        return true;
+    }
+    return false;
 }
 
 // https://dom.spec.whatwg.org/#dom-node-ownerdocument