1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-25 14:27:35 +00:00

LibWeb: Make DOM Nodes keep their Document alive

In addition to being reference-counted, all nodes that are part of a
document must also keep the document alive.

This is achieved by adding a second ref-count to the Document object
and incrementing/decrementing it whenever a node is created/destroyed
in that document.

This brings us much closer to a proper DOM lifetime model, although
the JS bindings still need more work.
This commit is contained in:
Andreas Kling 2020-10-11 21:52:59 +02:00
parent 99acbbe86b
commit f68ed6d25b
5 changed files with 45 additions and 11 deletions

View file

@ -77,6 +77,16 @@ Document::~Document()
{
}
void Document::removed_last_ref()
{
ASSERT(!ref_count());
if (m_referencing_node_count)
return;
delete this;
}
Origin Document::origin() const
{
if (!m_url.is_valid())

View file

@ -177,9 +177,27 @@ public:
const String& ready_state() const { return m_ready_state; }
void set_ready_state(const String&);
void ref_from_node(Badge<Node>)
{
++m_referencing_node_count;
}
void unref_from_node(Badge<Node>)
{
ASSERT(m_referencing_node_count);
--m_referencing_node_count;
if (!m_referencing_node_count && !ref_count()) {
removed_last_ref();
}
}
void removed_last_ref();
private:
virtual RefPtr<LayoutNode> create_layout_node(const CSS::StyleProperties* parent_style) override;
unsigned m_referencing_node_count { 0 };
OwnPtr<CSS::StyleResolver> m_style_resolver;
RefPtr<CSS::StyleSheetList> m_style_sheets;
RefPtr<Node> m_hovered_node;

View file

@ -206,4 +206,13 @@ Bindings::EventTargetWrapper* Node::create_wrapper(JS::GlobalObject& global_obje
return wrap(global_object, *this);
}
void Node::removed_last_ref()
{
if (is<Document>(*this)) {
downcast<Document>(*this).removed_last_ref();
return;
}
delete this;
}
}

View file

@ -65,6 +65,8 @@ public:
virtual ~Node();
void removed_last_ref();
NodeType type() const { return m_type; }
bool is_element() const { return type() == NodeType::ELEMENT_NODE; }
bool is_text() const { return type() == NodeType::TEXT_NODE; }