Backed out changeset cc14c4f9f46e (bug 1890721) for causing bc failures @ browser/components/screenshots/tests/browser/browser_screenshots_page_unload.js CLOSED TREE

This commit is contained in:
Sandor Molnar 2024-05-15 21:03:34 +03:00
parent 5f747ddda4
commit 907f5bc3c9
6 changed files with 19 additions and 250 deletions

View File

@ -10,14 +10,10 @@ ChromeUtils.defineESModuleGetters(lazy, {
ScreenshotsOverlay: "resource:///modules/ScreenshotsOverlayChild.sys.mjs", ScreenshotsOverlay: "resource:///modules/ScreenshotsOverlayChild.sys.mjs",
}); });
const SCREENSHOTS_PREVENT_CONTENT_EVENTS_PREF =
"screenshots.browser.component.preventContentEvents";
export class ScreenshotsComponentChild extends JSWindowActorChild { export class ScreenshotsComponentChild extends JSWindowActorChild {
#resizeTask; #resizeTask;
#scrollTask; #scrollTask;
#overlay; #overlay;
#preventableEventsAdded = false;
static OVERLAY_EVENTS = [ static OVERLAY_EVENTS = [
"click", "click",
@ -28,21 +24,6 @@ export class ScreenshotsComponentChild extends JSWindowActorChild {
"keydown", "keydown",
]; ];
// The following events are only listened to so we can prevent them from
// reaching the content page. The events in OVERLAY_EVENTS are also prevented.
static PREVENTABLE_EVENTS = [
"mousemove",
"mousedown",
"mouseup",
"touchstart",
"touchmove",
"touchend",
"dblclick",
"auxclick",
"keypress",
"contextmenu",
];
get overlay() { get overlay() {
return this.#overlay; return this.#overlay;
} }
@ -81,28 +62,19 @@ export class ScreenshotsComponentChild extends JSWindowActorChild {
return; return;
} }
// Handle overlay events here
if (
ScreenshotsComponentChild.OVERLAY_EVENTS.includes(event.type) ||
ScreenshotsComponentChild.PREVENTABLE_EVENTS.includes(event.type)
) {
if (!this.overlay?.initialized) {
return;
}
// Preventing a pointerdown event throws an error in debug builds.
// See https://searchfox.org/mozilla-central/rev/b41bb321fe4bd7d03926083698ac498ebec0accf/widget/WidgetEventImpl.cpp#566-572
// Don't prevent the default context menu.
if (!["contextmenu", "pointerdown"].includes(event.type)) {
event.preventDefault();
}
event.stopImmediatePropagation();
this.overlay.handleEvent(event);
return;
}
switch (event.type) { switch (event.type) {
case "click":
case "pointerdown":
case "pointermove":
case "pointerup":
case "keyup":
case "keydown":
case "selectionchange":
if (!this.overlay?.initialized) {
return;
}
this.overlay.handleEvent(event);
break;
case "beforeunload": case "beforeunload":
this.requestCancelScreenshot("navigation"); this.requestCancelScreenshot("navigation");
break; break;
@ -254,16 +226,7 @@ export class ScreenshotsComponentChild extends JSWindowActorChild {
for (let event of ScreenshotsComponentChild.OVERLAY_EVENTS) { for (let event of ScreenshotsComponentChild.OVERLAY_EVENTS) {
chromeEventHandler.addEventListener(event, this, true); chromeEventHandler.addEventListener(event, this, true);
} }
this.document.addEventListener("selectionchange", this); this.document.addEventListener("selectionchange", this);
if (Services.prefs.getBoolPref(SCREENSHOTS_PREVENT_CONTENT_EVENTS_PREF)) {
for (let event of ScreenshotsComponentChild.PREVENTABLE_EVENTS) {
chromeEventHandler.addEventListener(event, this, true);
}
this.#preventableEventsAdded = true;
}
} }
/** /**
@ -301,16 +264,7 @@ export class ScreenshotsComponentChild extends JSWindowActorChild {
for (let event of ScreenshotsComponentChild.OVERLAY_EVENTS) { for (let event of ScreenshotsComponentChild.OVERLAY_EVENTS) {
chromeEventHandler.removeEventListener(event, this, true); chromeEventHandler.removeEventListener(event, this, true);
} }
this.document.removeEventListener("selectionchange", this); this.document.removeEventListener("selectionchange", this);
if (this.#preventableEventsAdded) {
for (let event of ScreenshotsComponentChild.PREVENTABLE_EVENTS) {
chromeEventHandler.removeEventListener(event, this, true);
}
}
this.#preventableEventsAdded = false;
} }
/** /**

View File

@ -2441,9 +2441,6 @@ pref("screenshots.browser.component.enabled", true);
// Preference that determines what button to focus // Preference that determines what button to focus
pref("screenshots.browser.component.last-saved-method", "download"); pref("screenshots.browser.component.last-saved-method", "download");
// Preference that prevents events from reaching the content page.
pref("screenshots.browser.component.preventContentEvents", true);
// DoH Rollout: whether to clear the mode value at shutdown. // DoH Rollout: whether to clear the mode value at shutdown.
pref("doh-rollout.clearModeOnShutdown", false); pref("doh-rollout.clearModeOnShutdown", false);

View File

@ -74,8 +74,6 @@ skip-if = ["!crashreporter"]
["browser_test_moving_tab_to_new_window.js"] ["browser_test_moving_tab_to_new_window.js"]
["browser_test_prevent_events.js"]
["browser_test_resize.js"] ["browser_test_resize.js"]
["browser_test_selection_size_text.js"] ["browser_test_selection_size_text.js"]

View File

@ -1,84 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
https://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
add_task(async function test_events_prevented() {
await BrowserTestUtils.withNewTab(
{
gBrowser,
url: SHORT_TEST_PAGE,
},
async browser => {
let helper = new ScreenshotsHelper(browser);
await ContentTask.spawn(browser, null, async () => {
let { ScreenshotsComponentChild } = ChromeUtils.importESModule(
"resource:///actors/ScreenshotsComponentChild.sys.mjs"
);
let allOverlayEvents = ScreenshotsComponentChild.OVERLAY_EVENTS.concat(
ScreenshotsComponentChild.PREVENTABLE_EVENTS
);
content.eventsReceived = [];
function eventListener(event) {
content.window.eventsReceived.push(event.type);
}
for (let eventName of [...allOverlayEvents, "wheel"]) {
content.addEventListener(eventName, eventListener, true);
}
});
helper.triggerUIFromToolbar();
await helper.waitForOverlay();
// key events
await key.down("s");
await key.up("s");
await key.press("s");
// touch events
await touch.start(10, 10);
await touch.move(20, 20);
await touch.end(20, 20);
// pointermove/mousemove, pointerdown/mousedown, pointerup/mouseup events
await helper.clickTestPageElement();
// click events and contextmenu
await mouse.dblclick(100, 100);
await mouse.auxclick(100, 100, { button: 1 });
await mouse.click(100, 100);
await mouse.contextmenu(100, 100);
let wheelEventPromise = helper.waitForContentEventOnce("wheel");
await ContentTask.spawn(browser, null, () => {
content.dispatchEvent(new content.WheelEvent("wheel"));
});
await wheelEventPromise;
let contentEventsReceived = await ContentTask.spawn(
browser,
null,
async () => {
return content.eventsReceived;
}
);
// Events are synchronous so if we only have 1 wheel at the end,
// we did not receive any other events
is(
contentEventsReceived.length,
1,
"Only 1 wheel event should reach the content document because everything else was prevent and stopped propagation"
);
is(
contentEventsReceived[0],
"wheel",
"Only 1 wheel event should reach the content document because everything else was prevent and stopped propagation"
);
}
);
});

View File

@ -34,31 +34,16 @@ const gScreenshotUISelectors = {
copyButton: "button.#copy", copyButton: "button.#copy",
}; };
// AnonymousContentEvents is for the mouse, keyboard, and touch events on the Anonymous content // MouseEvents is for the mouse events on the Anonymous content
const AnonymousContentEvents = { const MouseEvents = {
mouse: new Proxy( mouse: new Proxy(
{}, {},
{ {
get: (target, name) => get: (target, name) =>
async function (x, y, options = {}, browser) { async function (x, y, options = {}, browser) {
if (name.includes("click")) { if (name === "click") {
this.down(x, y, options, browser); this.down(x, y, options, browser);
this.up(x, y, options, browser); this.up(x, y, options, browser);
if (name.includes("dbl")) {
this.down(x, y, options, browser);
this.up(x, y, options, browser);
}
} else if (name === "contextmenu") {
await safeSynthesizeMouseEventInContentPage(
":root",
x,
y,
{
type: name,
...options,
},
browser
);
} else { } else {
await safeSynthesizeMouseEventInContentPage( await safeSynthesizeMouseEventInContentPage(
":root", ":root",
@ -74,40 +59,9 @@ const AnonymousContentEvents = {
}, },
} }
), ),
key: new Proxy(
{},
{
get: (target, name) =>
async function (key, options = {}, browser) {
await safeSynthesizeKeyEventInContentPage(
key,
{ type: "key" + name, ...options },
browser
);
},
}
),
touch: new Proxy(
{},
{
get: (target, name) =>
async function (x, y, options = {}, browser) {
await safeSynthesizeTouchEventInContentPage(
":root",
x,
y,
{
type: "touch" + name,
...options,
},
browser
);
},
}
),
}; };
const { mouse, key, touch } = AnonymousContentEvents; const { mouse } = MouseEvents;
class ScreenshotsHelper { class ScreenshotsHelper {
constructor(browser) { constructor(browser) {
@ -867,14 +821,6 @@ class ScreenshotsHelper {
}); });
} }
waitForContentEventOnce(event) {
return ContentTask.spawn(this.browser, event, eventType => {
return new Promise(resolve => {
content.addEventListener(eventType, resolve, { once: true });
});
});
}
/** /**
* Copied from screenshots extension * Copied from screenshots extension
* A helper that returns the size of the image that was just put into the clipboard by the * A helper that returns the size of the image that was just put into the clipboard by the
@ -1009,7 +955,7 @@ function getRawClipboardData(flavor) {
} }
/** /**
* Synthesize a mouse event on an element * Synthesize a mouse event on an element, after ensuring that it is visible
* in the viewport. * in the viewport.
* *
* @param {String} selector: The node selector to get the node target for the event. * @param {String} selector: The node selector to get the node target for the event.
@ -1030,49 +976,7 @@ async function safeSynthesizeMouseEventInContentPage(
} else { } else {
context = browser.browsingContext; context = browser.browsingContext;
} }
await BrowserTestUtils.synthesizeMouse(selector, x, y, options, context); BrowserTestUtils.synthesizeMouse(selector, x, y, options, context);
}
/**
* Synthesize a key event on an element
* in the viewport.
*
* @param {string} key The key
* @param {object} options: Options that will be passed to BrowserTestUtils.synthesizeKey
*/
async function safeSynthesizeKeyEventInContentPage(aKey, options, browser) {
let context;
if (!browser) {
context = gBrowser.selectedBrowser.browsingContext;
} else {
context = browser.browsingContext;
}
await BrowserTestUtils.synthesizeKey(aKey, options, context);
}
/**
* Synthesize a touch event on an element
* in the viewport.
*
* @param {String} selector: The node selector to get the node target for the event.
* @param {number} x
* @param {number} y
* @param {object} options: Options that will be passed to BrowserTestUtils.synthesizeTouch
*/
async function safeSynthesizeTouchEventInContentPage(
selector,
x,
y,
options = {},
browser
) {
let context;
if (!browser) {
context = gBrowser.selectedBrowser.browsingContext;
} else {
context = browser.browsingContext;
}
await BrowserTestUtils.synthesizeTouch(selector, x, y, options, context);
} }
add_setup(async () => { add_setup(async () => {

View File

@ -3,6 +3,6 @@
<title>Screenshots</title> <title>Screenshots</title>
</head> </head>
<body> <body>
<div id="testPageElement" style="height:500px; width:500px; background-color: blue;"></div> <div style="height:500px; width:500px; background-color: blue;"></div>
</body> </body>
</html> </html>