Bug 1911423 - add a desktop-only JS intervention for Power BI maps to fix touchpad zooming; r=denschub,webcompat-reviewers
Differential Revision: https://phabricator.services.mozilla.com/D249886
This commit is contained in:
committed by
twisniewski@mozilla.com
parent
90fec2e1ca
commit
a9c1c3eef1
@@ -3099,12 +3099,23 @@
|
|||||||
"1944518": {
|
"1944518": {
|
||||||
"issue": "broken-scrolling",
|
"issue": "broken-scrolling",
|
||||||
"matches": ["*://app.powerbi.com/view*"]
|
"matches": ["*://app.powerbi.com/view*"]
|
||||||
|
},
|
||||||
|
"1919263": {
|
||||||
|
"issue": "broken-zooming",
|
||||||
|
"matches": ["*://app.powerbi.com/view*"]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"interventions": [
|
"interventions": [
|
||||||
{
|
{
|
||||||
"platforms": ["mac"],
|
"platforms": ["mac"],
|
||||||
"ua_string": ["add_Chrome"]
|
"ua_string": ["add_Chrome"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"platforms": ["desktop"],
|
||||||
|
"content_scripts": {
|
||||||
|
"all_frames": true,
|
||||||
|
"js": ["bug1911423-app.powerbi.com-emulate-mousewheel-events.js"]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -0,0 +1,38 @@
|
|||||||
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
/* globals exportFunction */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Bug 1911423 - app.powerbi.com - zooming is broken on maps
|
||||||
|
*
|
||||||
|
* They listen for non-standard mousewheel events, rather than wheel,
|
||||||
|
* which breaks zooming. This emulates mousewheel events for them.
|
||||||
|
*/
|
||||||
|
|
||||||
|
console.info(
|
||||||
|
"Emulating mousewheel events for compatibility reasons. See https://bugzilla.mozilla.org/show_bug.cgi?id=1911423 for details."
|
||||||
|
);
|
||||||
|
|
||||||
|
(function () {
|
||||||
|
const { prototype } = window.wrappedJSObject.WheelEvent;
|
||||||
|
Object.defineProperty(prototype, "type", {
|
||||||
|
configurable: true,
|
||||||
|
get: exportFunction(() => "mousewheel", window),
|
||||||
|
set: exportFunction(() => {}, window),
|
||||||
|
});
|
||||||
|
})();
|
||||||
|
|
||||||
|
(function () {
|
||||||
|
const { prototype } = window.wrappedJSObject.EventTarget;
|
||||||
|
const { addEventListener } = prototype;
|
||||||
|
prototype.addEventListener = exportFunction(function (type, fn, c, d) {
|
||||||
|
if (type === "mousewheel") {
|
||||||
|
type = "wheel";
|
||||||
|
}
|
||||||
|
return addEventListener.call(this, type, fn, c, d);
|
||||||
|
}, window);
|
||||||
|
})();
|
||||||
@@ -74,6 +74,52 @@ class Client:
|
|||||||
element,
|
element,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
async def send_apz_scroll_gesture(
|
||||||
|
self, units, element=None, offset=None, coords=None
|
||||||
|
):
|
||||||
|
if coords is None:
|
||||||
|
if element is None:
|
||||||
|
raise ValueError("require coords and/or element")
|
||||||
|
coords = self.get_element_screen_position(element)
|
||||||
|
if offset is not None:
|
||||||
|
coords[0] += offset[0]
|
||||||
|
coords[1] += offset[1]
|
||||||
|
with self.using_context("chrome"):
|
||||||
|
return self.execute_async_script(
|
||||||
|
"""
|
||||||
|
const [units, coords, done] = arguments;
|
||||||
|
const { devicePixelRatio, windowUtils } = window;
|
||||||
|
const resolution = windowUtils.getResolution();
|
||||||
|
const toScreenCoords = x => x * devicePixelRatio * resolution;
|
||||||
|
|
||||||
|
// based on nativeVerticalWheelEventMsg()
|
||||||
|
let msg = 4; // linux default
|
||||||
|
switch (Services.appinfo.OS) {
|
||||||
|
case "WINNT":
|
||||||
|
msg = 0x0115; // WM_VSCROLL
|
||||||
|
break;
|
||||||
|
case "Darwin":
|
||||||
|
msg = 1; // use a gesture; don't synthesize a wheel scroll
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
windowUtils.sendNativeMouseScrollEvent(
|
||||||
|
toScreenCoords(coords[0]),
|
||||||
|
toScreenCoords(coords[1]),
|
||||||
|
msg,
|
||||||
|
0,
|
||||||
|
units,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
document.documentElement,
|
||||||
|
() => { done(); },
|
||||||
|
);
|
||||||
|
""",
|
||||||
|
units,
|
||||||
|
coords,
|
||||||
|
)
|
||||||
|
|
||||||
async def send_apz_mouse_event(
|
async def send_apz_mouse_event(
|
||||||
self, event_type, coords=None, element=None, button=0
|
self, event_type, coords=None, element=None, button=0
|
||||||
):
|
):
|
||||||
|
|||||||
@@ -0,0 +1,50 @@
|
|||||||
|
import asyncio
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
URL = "https://lmiamap.ca/"
|
||||||
|
|
||||||
|
FRAME_CSS = "iframe[src*=powerbi]"
|
||||||
|
MAP_CSS = ".MicrosoftMap"
|
||||||
|
CANVAS_CSS = "[id='Microsoft.Maps.Imagery.RoadSceneWithoutLabels']"
|
||||||
|
HERO_CSS = "svg .mapBubbles:not(:empty)"
|
||||||
|
|
||||||
|
|
||||||
|
async def can_zoom_maps(client):
|
||||||
|
await client.navigate(URL, wait="none")
|
||||||
|
client.switch_frame(client.await_css(FRAME_CSS, is_displayed=True))
|
||||||
|
map = client.await_css(MAP_CSS, is_displayed=True)
|
||||||
|
canvas = client.await_css(CANVAS_CSS, is_displayed=True)
|
||||||
|
|
||||||
|
# wait for the map to load and settle down (it zooms in and adds SVG annotations)
|
||||||
|
client.await_css(HERO_CSS, is_displayed=True)
|
||||||
|
await asyncio.sleep(2)
|
||||||
|
|
||||||
|
# now we scroll and see if the canvas' transform changes (it snaps back to its original transform afterward)
|
||||||
|
pre = client.execute_script("return arguments[0].style.transform", canvas)
|
||||||
|
for i in range(30):
|
||||||
|
await client.send_apz_scroll_gesture(4, element=map, offset=[40, 40])
|
||||||
|
await asyncio.sleep(0.05)
|
||||||
|
if pre != client.execute_script(
|
||||||
|
"return arguments[0].style.transform",
|
||||||
|
canvas,
|
||||||
|
):
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
# Android is unaffected; Linux may be, but testing scroll gestures doesn't seem to work.
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.skip_platforms("android", "linux")
|
||||||
|
@pytest.mark.asyncio
|
||||||
|
@pytest.mark.with_interventions
|
||||||
|
async def test_enabled(client):
|
||||||
|
assert await can_zoom_maps(client)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.skip_platforms("android", "linux")
|
||||||
|
@pytest.mark.asyncio
|
||||||
|
@pytest.mark.without_interventions
|
||||||
|
async def test_disabled(client):
|
||||||
|
assert not await can_zoom_maps(client)
|
||||||
Reference in New Issue
Block a user