Bug 1700365 - synthesizeNativeMouseEvent works on mobile viewport. r=masayuki

We have to consider mobile viewport scale to calculate screen position.
And mozInnerScreen isn't valid position if that scale isn't 1 (bug 1701546).

Also, this function won't work on Fission+xorigin with mobile viewport due to
no way to get current mobile viewport scale since window.top isn't same
origin.

Differential Revision: https://phabricator.services.mozilla.com/D110198
This commit is contained in:
Makoto Kato 2021-04-09 09:25:36 +00:00
parent 636f8e1395
commit 3ed8588b5a
2 changed files with 33 additions and 11 deletions

View File

@ -54,11 +54,6 @@ function starttest() {
is(check, true, 'sendMouseEvent should dispatch click event');
await (async function testSynthesizeNativeMouseEvent() {
if (navigator.appVersion.includes("Android")) {
todo(false,
`testSynthesizeNativeMouseEvent: does nothing on Android because its nsIWidget::SynthesizeNativeMouseEvent won't fire "mouseup"`);
return;
}
let events = [];
let listener = event => events.push(event);
let preventDefault = event => event.preventDefault();

View File

@ -1051,6 +1051,13 @@ function synthesizeNativeMouseEvent(aParams, aCallback = null) {
}
const rect = target?.getBoundingClientRect();
let resolution = 1.0;
try {
resolution = _getDOMWindowUtils(win.top).getResolution();
} catch (e) {
// XXX How to get mobile viewport scale on Fission+xorigin since
// window.top access isn't allowed due to cross-origin?
}
const scaleValue = (() => {
if (scale === "inScreenPixels") {
return 1.0;
@ -1063,14 +1070,26 @@ function synthesizeNativeMouseEvent(aParams, aCallback = null) {
}
throw Error(`invalid scale value (${scale}) is specified`);
})();
// XXX mozInnerScreen might be invalid value on mobile viewport (Bug 1701546),
// so use window.top's mozInnerScreen. But this won't work fission+xorigin
// with mobile viewport until mozInnerScreen returns valid value with
// scale.
const x = (() => {
if (screenX != undefined) {
return screenX * scaleValue;
}
let winInnerOffsetX = win.mozInnerScreenX;
try {
winInnerOffsetX =
win.top.mozInnerScreenX +
(win.mozInnerScreenX - win.top.mozInnerScreenX) * resolution;
} catch (e) {
// XXX fission+xorigin test throws permission denied since win.top is
// cross-origin.
}
return (
((atCenter ? rect.width / 2 : offsetX) +
win.mozInnerScreenX +
rect.left) *
(((atCenter ? rect.width / 2 : offsetX) + rect.left) * resolution +
winInnerOffsetX) *
scaleValue
);
})();
@ -1078,10 +1097,18 @@ function synthesizeNativeMouseEvent(aParams, aCallback = null) {
if (screenY != undefined) {
return screenY * scaleValue;
}
let winInnerOffsetY = win.mozInnerScreenY;
try {
winInnerOffsetY =
win.top.mozInnerScreenY +
(win.mozInnerScreenY - win.top.mozInnerScreenY) * resolution;
} catch (e) {
// XXX fission+xorigin test throws permission denied since win.top is
// cross-origin.
}
return (
((atCenter ? rect.height / 2 : offsetY) +
win.mozInnerScreenY +
rect.top) *
(((atCenter ? rect.height / 2 : offsetY) + rect.top) * resolution +
winInnerOffsetY) *
scaleValue
);
})();