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": {
|
||||
"issue": "broken-scrolling",
|
||||
"matches": ["*://app.powerbi.com/view*"]
|
||||
},
|
||||
"1919263": {
|
||||
"issue": "broken-zooming",
|
||||
"matches": ["*://app.powerbi.com/view*"]
|
||||
}
|
||||
},
|
||||
"interventions": [
|
||||
{
|
||||
"platforms": ["mac"],
|
||||
"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,
|
||||
)
|
||||
|
||||
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(
|
||||
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