tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

commit a2466e87b00d1617782a9112c7088607589b3f55
parent 300f5338b9b3dd094f1411f40268f02015f55b45
Author: Mustaq Ahmed <mustaq@google.com>
Date:   Fri,  7 Nov 2025 08:47:09 +0000

Bug 1998030 [wpt PR 55837] - Fix PointerEventManager's element tracker on content removal, a=testonly

Automatic update from web-platform-tests
Fix PointerEventManager's element tracker on content removal

This CL hooks up PointerEventManager's element-under-pointer tracker
to Document::NodeChildrenWillBeRemoved, as already done in
MouseEventManager.  Before this change, when JS "overwrites" an
element's innerHTML, PEM used to wrongly retain references to deleted
nodes and even send events to those nodes.

Bug: 41487938
Change-Id: I7090f29061594a06e8b8a52c0654707a7657efb9
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/7081517
Commit-Queue: Mustaq Ahmed <mustaq@chromium.org>
Reviewed-by: Robert Flack <flackr@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1540035}

--

wpt-commits: bb1eecc43d30bd3f67b79d90101aa60e7436c9bf
wpt-pr: 55837

Diffstat:
Atesting/web-platform/tests/pointerevents/pointer_boundary_events_after_removing_last_over_element_through_innerhtml.html | 102+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 102 insertions(+), 0 deletions(-)

diff --git a/testing/web-platform/tests/pointerevents/pointer_boundary_events_after_removing_last_over_element_through_innerhtml.html b/testing/web-platform/tests/pointerevents/pointer_boundary_events_after_removing_last_over_element_through_innerhtml.html @@ -0,0 +1,102 @@ +<!doctype html> +<meta charset="utf-8"> +<title>Boundary events fired after an innerHTML change removes the element under + pointer</title> +<script src=/resources/testharness.js></script> +<script src=/resources/testharnessreport.js></script> +<script src=/resources/testdriver.js></script> +<script src=/resources/testdriver-actions.js></script> +<script src=/resources/testdriver-vendor.js></script> +<script src=pointerevent_support.js></script> + +<style> + div { + width: 80px; + height: 80px; + } +</style> + +<div id="div1"> + <div id="div2"> + <div id="div3"> + <div id="div4"></div> + </div> + </div> +</div> +<div id="done"></div> + +<script> +"use strict"; + +let event_log = []; +let logged_event_prefix = ""; + +function eventLogger(event) { + if (event.type.startsWith(logged_event_prefix) && + event.eventPhase == event.AT_TARGET) { + event_log.push(`${event.type}@${event.target.id}`); + } +} + +addEventListener("load", () => { + const div1 = document.getElementById("div1"); + const div2 = document.getElementById("div2"); + const div3 = document.getElementById("div3"); + const div4 = document.getElementById("div4"); + const done = document.getElementById("done"); + + for (const div of [div1, div2, div3, div4]) { + for (const event_suffix of ["enter", "leave", "over", "out", "move"]) { + div.addEventListener("pointer" + event_suffix, eventLogger); + div.addEventListener("mouse" + event_suffix, eventLogger); + } + } + + div4.addEventListener("click", event => { + div2.innerHTML = ""; + event_log.push("(empty-div2)"); + }); + + function makePromiseTest(prefix) { + promise_test(async test => { + event_log = []; + logged_event_prefix = prefix; + + test.add_cleanup(() => { + div2.appendChild(div3); + }); + + let done_click_promise = getEvent("click", done, test); + + await new test_driver.Actions() + .pointerMove(0, 0, {origin: div4}) + .pointerDown() + .pointerUp() // This sends a click that makes div2 empty. + .pointerMove(0, 0, {origin: done}) + .pointerDown() + .pointerUp() + .send(); + + await done_click_promise; + + const expected_events = [ + "Eover@div4", + "Eenter@div1", + "Eenter@div2", + "Eenter@div3", + "Eenter@div4", + "Emove@div4", + "(empty-div2)", + "Eover@div2", + "Eout@div2", + "Eleave@div2", + "Eleave@div1" + ].map(s => s.replace("E", prefix)); + assert_equals(event_log.toString(), expected_events.toString()); + }, prefix + " boundary events fired"); + } + + makePromiseTest("pointer"); + makePromiseTest("mouse"); +}, {once: true}); +</script>