LibWeb: Protect LayoutCheckBox against crashes after event dispatch

After dispatching a "change" event due to the checked state being
modified, we may have been removed from the layout tree.

Make LayoutCheckBox protect itself to prevent this from crashing.

Also, add a little test page for checkboxes. :^)
This commit is contained in:
Andreas Kling 2020-09-11 18:37:18 +02:00
parent 71092226bd
commit b62043dbca
Notes: sideshowbarker 2024-07-19 02:45:45 +09:00
3 changed files with 15 additions and 0 deletions

View file

@ -0,0 +1,11 @@
<html>
<input id=foo type=checkbox> This is a checkbox
<pre id=bar></pre>
<script>
var foo = document.getElementById("foo");
var bar = document.getElementById("bar");
foo.addEventListener("change", function() {
bar.innerHTML += foo.checked + "\n";
});
</script>
</html>

View file

@ -31,6 +31,7 @@ span#ua {
<p>Your user agent is: <b><span id="ua"></span></b></p>
<p>Some small test pages:</p>
<ul>
<li><a href="checkbox.html">checkbox</a></li>
<li><a href="canvas-rotate.html">canvas rotate()</a></li>
<li><a href="margin-collapse-2.html">margin collapsing 2</a></li>
<li><a href="margin-collapse-1.html">margin collapsing 1</a></li>

View file

@ -80,6 +80,9 @@ void LayoutCheckBox::handle_mouseup(Badge<EventHandler>, const Gfx::IntPoint& po
if (!m_tracking_mouse || button != GUI::MouseButton::Left)
return;
// NOTE: Changing the checked state of the DOM node may run arbitrary JS, which could disappear this node.
NonnullRefPtr protect = *this;
bool is_inside = enclosing_int_rect(absolute_rect()).contains(position);
if (is_inside)
node().set_checked(!node().checked());