Skip to content

Commit

Permalink
Make PresShell::EventHandler::DispatchPrecedingPointerEvent update …
Browse files Browse the repository at this point in the history
…event target after dispatching a pointer event

The reason of the bug is, no `mouseup` event is fired after the `pointerup`
event listener removed the target.  Therefore, `nsIFrame::HandleRelease()` does
not run and nobody cleans up the drag state of the `nsFrameSelection`.

This is caused by that `PresShell::EventHandler::DispatchPrecedingPointerEvent()`
updates only event target frame of the following mouse event target if the
pointer event target was removed from the tree, however, the frame may not be
ready.  In this case, `PresShell::GetCurrentContent()` will clear both current
event target content and frame because its composed document (`nullptr`) never
matches with the document for the `PresShell`.  Therefore, it needs to update
the target too.

This patch makes all developers won't create similar bugs, this encapsulate
`EventTargetData::mContent` and `EventTargetData::mFrame` to make their setters
clean up or automatically check the relation.

Differential Revision: https://phabricator.services.mozilla.com/D201053

bugzilla-url: https://bugzilla.mozilla.org/show_bug.cgi?id=1877815
gecko-commit: 88c50740c90849f41b36a3ebdea5c1182d010b62
gecko-reviewers: smaug
  • Loading branch information
masayuki-nakano authored and marcoscaceres committed Feb 23, 2024
1 parent d83f58e commit f8d30eb
Showing 1 changed file with 96 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>After pointerup target is removed, selection should not be updated by pointer move</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>
"use strict";

/**
* This behavior is not defined in any spec, but even if browser supports
* expanding selection across text nodes with dragging a pointer, it should
* not work after pointerup whose target is removed by a pointerup event
* listener.
*/

addEventListener("load", async () => {
const span1 = document.querySelector("span");
const span2 = span1.nextSibling;
const span3 = span2.nextSibling;
const button = document.querySelector("button");

promise_test(async () => {
const overlay = document.createElement("div");
overlay.className = "overlay";
overlay.addEventListener("pointerup", () => {
overlay.remove();
});
document.body.appendChild(overlay);
overlay.style.display = "block";
await new Promise(resolve => {
requestAnimationFrame(() => requestAnimationFrame(resolve));
});
await new test_driver.Actions()
.pointerMove(10, 10, {origin: span1})
.pointerDown()
.pointerUp()
.pointerMove(10, 10, {origin: span2})
.addTick()
.pointerMove(10, 10, {origin: span3})
.addTick()
.send();
assert_true(getSelection().isCollapsed);
}, "pointermove after pointerup which deletes the overlay should not keep expanding selection");

promise_test(async () => {
const overlay = document.createElement("div");
overlay.className = "overlay";
overlay.addEventListener("pointerup", () => {
button.focus();
overlay.remove();
});
document.body.appendChild(overlay);
overlay.style.display = "block";
await new Promise(resolve => {
requestAnimationFrame(() => requestAnimationFrame(resolve));
});
await new test_driver.Actions()
.pointerMove(10, 10, {origin: span1})
.pointerDown()
.pointerUp()
.pointerMove(10, 10, {origin: span2})
.addTick()
.pointerMove(10, 10, {origin: span3})
.addTick()
.send();
assert_true(getSelection().isCollapsed);
}, "pointermove after pointerup which deletes the overlay and move focus to the button should not keep expanding selection");
}, {once: true});
</script>
<style>
div.overlay {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.5);
display: none;
}
#container {
font-size: 32px;
}
</style>
</head>
<body>
<div id="container">
<span>abc</span><span>def</span><span>ghi</span><br>
<button>button</button>
</div>
</body>
</html>

0 comments on commit f8d30eb

Please sign in to comment.