Bug 1909020 - Make createDragEventObject() in EventUtils.js aware of HiDPI environments r=smaug
`synthesizePlainDragAndDrop()` sends `drop` event [1] via `PresShell` [2]. Then, the `screenX` and `screenY` values are set to `WidgetEvent::mRefPoint` [3]. Then, the `drop` event's position is recorded before dispatch [4]. So, `drop` event is fired on the target but the `mRefPoint` may be outside the target. Finally, synthesized `eMouseMove` after `eDrop` will be fired on the wrong element which is different from `eDrop`'s target. This caused the failures of `test_synthmousemove_after_dnd.html` and `test_dragdrop.html` on Android. Perhaps, we should improve `nsDOMWindowUtils` or something lower layer later. Instead, this patch fixes in `EventUtils.js` level. This makes the `createDragEventObject()`. 1. https://searchfox.org/mozilla-central/rev/6a72a6d20eeb1b20b93862a79166938d6ce794a0/testing/mochitest/tests/SimpleTest/EventUtils.js#3893-3900 2. https://searchfox.org/mozilla-central/rev/6a72a6d20eeb1b20b93862a79166938d6ce794a0/testing/mochitest/tests/SimpleTest/EventUtils.js#376-393,400 3. https://searchfox.org/mozilla-central/rev/6a72a6d20eeb1b20b93862a79166938d6ce794a0/dom/events/MouseEvent.cpp#81-84 4. https://searchfox.org/mozilla-central/rev/6a72a6d20eeb1b20b93862a79166938d6ce794a0/layout/base/PresShell.cpp#8987 Differential Revision: https://phabricator.services.mozilla.com/D251091
This commit is contained in:
committed by
masayuki@d-toybox.com
parent
842f61a7ac
commit
735e6414f0
@@ -939,9 +939,6 @@ async function doTest() {
|
||||
})();
|
||||
|
||||
// -------- Test dragging contenteditable to same contenteditable
|
||||
// Bug 1904272: Android Non-XOrigin incorrectly inserts after the 3rd M
|
||||
// instead of after the 2nd M in some of the following tests.
|
||||
const isAndroidException = AppConstants.platform === "android" && !isXOrigin;
|
||||
|
||||
await (async function test_dragging_from_contenteditable_to_itself() {
|
||||
const description = "dragging text in contenteditable to same contenteditable";
|
||||
@@ -972,16 +969,8 @@ async function doTest() {
|
||||
}
|
||||
)
|
||||
) {
|
||||
const kExpectedOffsets = isAndroidException ? [3,3] : [2,2];
|
||||
if (isAndroidException) {
|
||||
todo_is(contenteditable.innerHTML, "<b>bd</b> <span>MM</span><b>ol</b><span>MM</span>",
|
||||
`${description}: dragged range should be removed from contenteditable`);
|
||||
isnot(contenteditable.innerHTML, "<b>bd</b> <span>MMMM</span><b>ol</b>",
|
||||
`${description}: dragged range should be removed from contenteditable`);
|
||||
} else {
|
||||
is(contenteditable.innerHTML, "<b>bd</b> <span>MM</span><b>ol</b><span>MM</span>",
|
||||
`${description}: dragged range should be removed from contenteditable`);
|
||||
}
|
||||
is(contenteditable.innerHTML, "<b>bd</b> <span>MM</span><b>ol</b><span>MM</span>",
|
||||
`${description}: dragged range should be removed from contenteditable`);
|
||||
is(beforeinputEvents.length, 2,
|
||||
`${description}: 2 "beforeinput" events should be fired on contenteditable`);
|
||||
checkInputEvent(beforeinputEvents[0], contenteditable, "deleteByDrag", null, null,
|
||||
@@ -991,8 +980,8 @@ async function doTest() {
|
||||
checkInputEvent(beforeinputEvents[1], contenteditable, "insertFromDrop", null,
|
||||
[{type: "text/html", data: "<b>ol</b>"},
|
||||
{type: "text/plain", data: "ol"}],
|
||||
[{startContainer: lastTextNode, startOffset: kExpectedOffsets[0],
|
||||
endContainer: lastTextNode, endOffset: kExpectedOffsets[1]}],
|
||||
[{startContainer: lastTextNode, startOffset: 2,
|
||||
endContainer: lastTextNode, endOffset: 2}],
|
||||
description);
|
||||
is(inputEvents.length, 2,
|
||||
`${description}: 2 "input" events should be fired on contenteditable`);
|
||||
@@ -1039,16 +1028,8 @@ async function doTest() {
|
||||
}
|
||||
)
|
||||
) {
|
||||
const kExpectedOffsets = isAndroidException ? [3,3] : [2,2];
|
||||
if (isAndroidException) {
|
||||
todo_is(contenteditable.innerHTML, "<b>bold</b> <span>MM</span><b>ol</b><span>MM</span>",
|
||||
`${description}: dragged range shouldn't be removed from contenteditable`);
|
||||
isnot(contenteditable.innerHTML, "<b>bold</b> <span>MMMM</span><b>ol</b>",
|
||||
`${description}: dragged range shouldn't be removed from contenteditable`);
|
||||
} else {
|
||||
is(contenteditable.innerHTML, "<b>bold</b> <span>MM</span><b>ol</b><span>MM</span>",
|
||||
`${description}: dragged range shouldn't be removed from contenteditable`);
|
||||
}
|
||||
is(contenteditable.innerHTML, "<b>bold</b> <span>MM</span><b>ol</b><span>MM</span>",
|
||||
`${description}: dragged range shouldn't be removed from contenteditable`);
|
||||
is(beforeinputEvents.length, 2,
|
||||
`${description}: 2 "beforeinput" events should be fired on contenteditable`);
|
||||
checkInputEvent(beforeinputEvents[0], contenteditable, "deleteByDrag", null, null,
|
||||
@@ -1058,8 +1039,8 @@ async function doTest() {
|
||||
checkInputEvent(beforeinputEvents[1], contenteditable, "insertFromDrop", null,
|
||||
[{type: "text/html", data: "<b>ol</b>"},
|
||||
{type: "text/plain", data: "ol"}],
|
||||
[{startContainer: lastTextNode, startOffset: kExpectedOffsets[0],
|
||||
endContainer: lastTextNode, endOffset: kExpectedOffsets[1]}],
|
||||
[{startContainer: lastTextNode, startOffset: 2,
|
||||
endContainer: lastTextNode, endOffset: 2}],
|
||||
description);
|
||||
is(inputEvents.length, 1,
|
||||
`${description}: only one "input" event should be fired on contenteditable`);
|
||||
@@ -1114,12 +1095,11 @@ async function doTest() {
|
||||
[{startContainer: selectionContainers[0], startOffset: 1,
|
||||
endContainer: selectionContainers[1], endOffset: 3}],
|
||||
description);
|
||||
const kExpectedOffsets = isAndroidException ? [3,3] : [2,2];
|
||||
checkInputEvent(beforeinputEvents[1], contenteditable, "insertFromDrop", null,
|
||||
[{type: "text/html", data: "<b>ol</b>"},
|
||||
{type: "text/plain", data: "ol"}],
|
||||
[{startContainer: lastTextNode, startOffset: kExpectedOffsets[0],
|
||||
endContainer: lastTextNode, endOffset: kExpectedOffsets[1]}],
|
||||
[{startContainer: lastTextNode, startOffset: 2,
|
||||
endContainer: lastTextNode, endOffset: 2}],
|
||||
description);
|
||||
is(inputEvents.length, 1,
|
||||
`${description}: only one "input" event should be fired on contenteditable`);
|
||||
@@ -1162,23 +1142,15 @@ async function doTest() {
|
||||
}
|
||||
)
|
||||
) {
|
||||
const kExpectedOffsets = isAndroidException ? [3,3] : [2,2];
|
||||
if (isAndroidException) {
|
||||
todo_is(contenteditable.innerHTML, "<b>bold</b> <span>MM</span><b>ol</b><span>MM</span>",
|
||||
`${description}: dragged range shouldn't be removed from contenteditable`);
|
||||
isnot(contenteditable.innerHTML, "<b>bold</b> <span>MMMM</span><b>ol</b>",
|
||||
`${description}: dragged range shouldn't be removed from contenteditable`);
|
||||
} else {
|
||||
is(contenteditable.innerHTML, "<b>bold</b> <span>MM</span><b>ol</b><span>MM</span>",
|
||||
`${description}: dragged range shouldn't be removed from contenteditable`);
|
||||
}
|
||||
is(contenteditable.innerHTML, "<b>bold</b> <span>MM</span><b>ol</b><span>MM</span>",
|
||||
`${description}: dragged range shouldn't be removed from contenteditable`);
|
||||
is(beforeinputEvents.length, 1,
|
||||
`${description}: only 1 "beforeinput" events should be fired on contenteditable`);
|
||||
checkInputEvent(beforeinputEvents[0], contenteditable, "insertFromDrop", null,
|
||||
[{type: "text/html", data: "<b>ol</b>"},
|
||||
{type: "text/plain", data: "ol"}],
|
||||
[{startContainer: lastTextNode, startOffset: kExpectedOffsets[0],
|
||||
endContainer: lastTextNode, endOffset: kExpectedOffsets[1]}],
|
||||
[{startContainer: lastTextNode, startOffset: 2,
|
||||
endContainer: lastTextNode, endOffset: 2}],
|
||||
description);
|
||||
is(inputEvents.length, 1,
|
||||
`${description}: only 1 "input" events should be fired on contenteditable`);
|
||||
@@ -3548,16 +3520,8 @@ async function doTest() {
|
||||
}
|
||||
)
|
||||
) {
|
||||
const kExpectedOffsets = isAndroidException ? [4,4] : [2,2];
|
||||
if (isAndroidException) {
|
||||
todo_is(contenteditable.innerHTML, "!!<span>MM</span>dragme<span>MM</span>",
|
||||
`${description}: dragged range should be moved in inline contenteditable`);
|
||||
is(contenteditable.innerHTML, "!!<span>MMMM</span>dragme",
|
||||
`${description}: dragged range should be moved in inline contenteditable`);
|
||||
} else {
|
||||
is(contenteditable.innerHTML, "!!<span>MM</span>dragme<span>MM</span>",
|
||||
`${description}: dragged range should be moved in inline contenteditable`);
|
||||
}
|
||||
is(contenteditable.innerHTML, "!!<span>MM</span>dragme<span>MM</span>",
|
||||
`${description}: dragged range should be moved in inline contenteditable`);
|
||||
is(beforeinputEvents.length, 2,
|
||||
`${description}: 2 "beforeinput" events should be fired on inline contenteditable`);
|
||||
checkInputEvent(beforeinputEvents[0], contenteditable, "deleteByDrag", null, null,
|
||||
@@ -3567,8 +3531,8 @@ async function doTest() {
|
||||
checkInputEvent(beforeinputEvents[1], contenteditable, "insertFromDrop", null,
|
||||
[{type: "text/html", data: "dragme"},
|
||||
{type: "text/plain", data: "dragme"}],
|
||||
[{startContainer: span.firstChild, startOffset: kExpectedOffsets[0],
|
||||
endContainer: span.firstChild, endOffset: kExpectedOffsets[1]}],
|
||||
[{startContainer: span.firstChild, startOffset: 2,
|
||||
endContainer: span.firstChild, endOffset: 2}],
|
||||
description);
|
||||
is(inputEvents.length, 2,
|
||||
`${description}: 2 "input" events should be fired on inline contenteditable`);
|
||||
@@ -3611,18 +3575,10 @@ async function doTest() {
|
||||
}
|
||||
)
|
||||
) {
|
||||
const kExpectedOffsets = isAndroidException ? [2,2] : [1,1];
|
||||
is(contenteditable.innerHTML, "!!",
|
||||
`${description}: dragged range should be removed from inline contenteditable`);
|
||||
if (isAndroidException) {
|
||||
todo_is(otherContenteditable.innerHTML, "MdragmeM",
|
||||
`${description}: dragged content should be inserted into other inline contenteditable`);
|
||||
is(otherContenteditable.innerHTML, "MMdragme",
|
||||
`${description}: dragged content should be inserted into other inline contenteditable`);
|
||||
} else {
|
||||
is(otherContenteditable.innerHTML, "MdragmeM",
|
||||
`${description}: dragged content should be inserted into other inline contenteditable`);
|
||||
}
|
||||
is(otherContenteditable.innerHTML, "MdragmeM",
|
||||
`${description}: dragged content should be inserted into other inline contenteditable`);
|
||||
is(beforeinputEvents.length, 2,
|
||||
`${description}: 2 "beforeinput" events should be fired on inline contenteditable`);
|
||||
checkInputEvent(beforeinputEvents[0], contenteditable, "deleteByDrag", null, null,
|
||||
@@ -3632,8 +3588,8 @@ async function doTest() {
|
||||
checkInputEvent(beforeinputEvents[1], otherContenteditable, "insertFromDrop", null,
|
||||
[{type: "text/html", data: "dragme"},
|
||||
{type: "text/plain", data: "dragme"}],
|
||||
[{startContainer: otherContenteditable.firstChild, startOffset: kExpectedOffsets[0],
|
||||
endContainer: otherContenteditable.firstChild, endOffset: kExpectedOffsets[1]}],
|
||||
[{startContainer: otherContenteditable.firstChild, startOffset: 1,
|
||||
endContainer: otherContenteditable.firstChild, endOffset: 1}],
|
||||
description);
|
||||
is(inputEvents.length, 2,
|
||||
`${description}: 2 "input" events should be fired on inline contenteditable`);
|
||||
|
||||
Reference in New Issue
Block a user