diff --git a/Userland/Libraries/LibWeb/HTML/HTMLTableSectionElement.cpp b/Userland/Libraries/LibWeb/HTML/HTMLTableSectionElement.cpp
index dfa40a6dd4..9c2a669692 100644
--- a/Userland/Libraries/LibWeb/HTML/HTMLTableSectionElement.cpp
+++ b/Userland/Libraries/LibWeb/HTML/HTMLTableSectionElement.cpp
@@ -22,17 +22,24 @@ HTMLTableSectionElement::HTMLTableSectionElement(DOM::Document& document, DOM::Q
HTMLTableSectionElement::~HTMLTableSectionElement() = default;
+void HTMLTableSectionElement::visit_edges(Cell::Visitor& visitor)
+{
+ Base::visit_edges(visitor);
+ visitor.visit(m_rows);
+}
+
// https://html.spec.whatwg.org/multipage/tables.html#dom-tbody-rows
JS::NonnullGCPtr HTMLTableSectionElement::rows() const
{
// The rows attribute must return an HTMLCollection rooted at this element,
// whose filter matches only tr elements that are children of this element.
- // FIXME: This should return the same HTMLCollection object every time,
- // but that would cause a reference cycle since HTMLCollection refs the root.
- return DOM::HTMLCollection::create(const_cast(*this), [this](Element const& element) {
- return element.parent() == this
- && is(element);
- });
+ if (!m_rows) {
+ m_rows = DOM::HTMLCollection::create(const_cast(*this), [this](Element const& element) {
+ return element.parent() == this
+ && is(element);
+ });
+ }
+ return *m_rows;
}
// https://html.spec.whatwg.org/multipage/tables.html#dom-tbody-insertrow
diff --git a/Userland/Libraries/LibWeb/HTML/HTMLTableSectionElement.h b/Userland/Libraries/LibWeb/HTML/HTMLTableSectionElement.h
index 0965cdef89..76b9bbed1e 100644
--- a/Userland/Libraries/LibWeb/HTML/HTMLTableSectionElement.h
+++ b/Userland/Libraries/LibWeb/HTML/HTMLTableSectionElement.h
@@ -23,6 +23,10 @@ public:
private:
HTMLTableSectionElement(DOM::Document&, DOM::QualifiedName);
+
+ virtual void visit_edges(Cell::Visitor&) override;
+
+ JS::GCPtr mutable m_rows;
};
}