From 036cd9b2ddde20520fd89df5b726be16dbdc767a Mon Sep 17 00:00:00 2001 From: Aliaksandr Kalenik Date: Mon, 19 Feb 2024 02:22:15 +0100 Subject: [PATCH] LibWeb: Null layout and paintable pointers of removed DOM::Node When a node is removed from the DOM tree, its paintable needs to be removed to ensure that it is not used to obtain sizes that are no longer valid. This change enables the ResizeObserver to send a notification if a node is removed, as it should, because a removed node now has a size of zero It should be okay to nullify pointers without concerning parent/sibling/child relationships because the layout and paintable trees will be rebuilt following any DOM mutation anyway. --- .../notify-if-node-is-removed.txt | 2 + .../notify-if-parent-is-removed.txt | 2 + .../notify-if-node-is-removed.html | 46 +++++++++++++++++++ .../notify-if-parent-is-removed.html | 46 +++++++++++++++++++ Userland/Libraries/LibWeb/DOM/Node.cpp | 6 +++ Userland/Libraries/LibWeb/DOM/Node.h | 2 +- 6 files changed, 103 insertions(+), 1 deletion(-) create mode 100644 Tests/LibWeb/Text/expected/ResizeObserver/notify-if-node-is-removed.txt create mode 100644 Tests/LibWeb/Text/expected/ResizeObserver/notify-if-parent-is-removed.txt create mode 100644 Tests/LibWeb/Text/input/ResizeObserver/notify-if-node-is-removed.html create mode 100644 Tests/LibWeb/Text/input/ResizeObserver/notify-if-parent-is-removed.html diff --git a/Tests/LibWeb/Text/expected/ResizeObserver/notify-if-node-is-removed.txt b/Tests/LibWeb/Text/expected/ResizeObserver/notify-if-node-is-removed.txt new file mode 100644 index 0000000000..573125003a --- /dev/null +++ b/Tests/LibWeb/Text/expected/ResizeObserver/notify-if-node-is-removed.txt @@ -0,0 +1,2 @@ + Size changed: 200px x 200px +Size changed: 0px x 0px diff --git a/Tests/LibWeb/Text/expected/ResizeObserver/notify-if-parent-is-removed.txt b/Tests/LibWeb/Text/expected/ResizeObserver/notify-if-parent-is-removed.txt new file mode 100644 index 0000000000..573125003a --- /dev/null +++ b/Tests/LibWeb/Text/expected/ResizeObserver/notify-if-parent-is-removed.txt @@ -0,0 +1,2 @@ + Size changed: 200px x 200px +Size changed: 0px x 0px diff --git a/Tests/LibWeb/Text/input/ResizeObserver/notify-if-node-is-removed.html b/Tests/LibWeb/Text/input/ResizeObserver/notify-if-node-is-removed.html new file mode 100644 index 0000000000..f34246e8ad --- /dev/null +++ b/Tests/LibWeb/Text/input/ResizeObserver/notify-if-node-is-removed.html @@ -0,0 +1,46 @@ + + + + + +
+ + + diff --git a/Tests/LibWeb/Text/input/ResizeObserver/notify-if-parent-is-removed.html b/Tests/LibWeb/Text/input/ResizeObserver/notify-if-parent-is-removed.html new file mode 100644 index 0000000000..928288d02e --- /dev/null +++ b/Tests/LibWeb/Text/input/ResizeObserver/notify-if-parent-is-removed.html @@ -0,0 +1,46 @@ + + + + + +
+ + + diff --git a/Userland/Libraries/LibWeb/DOM/Node.cpp b/Userland/Libraries/LibWeb/DOM/Node.cpp index 00e7762e66..9c6bfc6493 100644 --- a/Userland/Libraries/LibWeb/DOM/Node.cpp +++ b/Userland/Libraries/LibWeb/DOM/Node.cpp @@ -974,6 +974,12 @@ void Node::inserted() set_needs_style_update(true); } +void Node::removed_from(Node*) +{ + m_layout_node = nullptr; + m_paintable = nullptr; +} + ParentNode* Node::parent_or_shadow_host() { if (is(*this)) diff --git a/Userland/Libraries/LibWeb/DOM/Node.h b/Userland/Libraries/LibWeb/DOM/Node.h index b83ce38bb9..85b3f65b44 100644 --- a/Userland/Libraries/LibWeb/DOM/Node.h +++ b/Userland/Libraries/LibWeb/DOM/Node.h @@ -187,7 +187,7 @@ public: Element const* parent_element() const; virtual void inserted(); - virtual void removed_from(Node*) { } + virtual void removed_from(Node*); virtual void children_changed() { } virtual void adopted_from(Document&) { } virtual void cloned(Node&, bool) {};