Browse Source

LibWeb: Make Node.childNodes vend the same NodeList every time

Andreas Kling 2 years ago
parent
commit
a5bb30d2ba
2 changed files with 9 additions and 5 deletions
  1. 7 5
      Userland/Libraries/LibWeb/DOM/Node.cpp
  2. 2 0
      Userland/Libraries/LibWeb/DOM/Node.h

+ 7 - 5
Userland/Libraries/LibWeb/DOM/Node.cpp

@@ -90,6 +90,7 @@ void Node::visit_edges(Cell::Visitor& visitor)
     visitor.visit(m_last_child.ptr());
     visitor.visit(m_next_sibling.ptr());
     visitor.visit(m_previous_sibling.ptr());
+    visitor.visit(m_child_nodes);
 
     for (auto& registered_observer : m_registered_observer_list)
         visitor.visit(registered_observer);
@@ -861,11 +862,12 @@ ParentNode* Node::parent_or_shadow_host()
 
 JS::NonnullGCPtr<NodeList> Node::child_nodes()
 {
-    // FIXME: This should return the same LiveNodeList object every time,
-    //        but that would cause a reference cycle since NodeList refs the root.
-    return LiveNodeList::create(window(), *this, [this](auto& node) {
-        return is_parent_of(node);
-    });
+    if (!m_child_nodes) {
+        m_child_nodes = LiveNodeList::create(window(), *this, [this](auto& node) {
+            return is_parent_of(node);
+        });
+    }
+    return *m_child_nodes;
 }
 
 Vector<JS::Handle<Node>> Node::children_as_vector() const

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

@@ -648,6 +648,8 @@ private:
     JS::GCPtr<Node> m_last_child;
     JS::GCPtr<Node> m_next_sibling;
     JS::GCPtr<Node> m_previous_sibling;
+
+    JS::GCPtr<NodeList> m_child_nodes;
 };
 
 }