forked from mirrors/gecko-dev
Bug 1872764 - Screenshots should always get events. r=sfoster,emilio
Differential Revision: https://phabricator.services.mozilla.com/D197802
This commit is contained in:
parent
44523c0504
commit
10e944bf30
6 changed files with 97 additions and 66 deletions
|
|
@ -15,6 +15,15 @@ export class ScreenshotsComponentChild extends JSWindowActorChild {
|
|||
#scrollTask;
|
||||
#overlay;
|
||||
|
||||
static OVERLAY_EVENTS = [
|
||||
"click",
|
||||
"pointerdown",
|
||||
"pointermove",
|
||||
"pointerup",
|
||||
"keyup",
|
||||
"keydown",
|
||||
];
|
||||
|
||||
get overlay() {
|
||||
return this.#overlay;
|
||||
}
|
||||
|
|
@ -41,10 +50,19 @@ export class ScreenshotsComponentChild extends JSWindowActorChild {
|
|||
|
||||
handleEvent(event) {
|
||||
switch (event.type) {
|
||||
case "click":
|
||||
case "pointerdown":
|
||||
case "pointermove":
|
||||
case "pointerup":
|
||||
case "keyup":
|
||||
case "keydown":
|
||||
if (event.key === "Escape") {
|
||||
if (!this.overlay?.initialized) {
|
||||
return;
|
||||
}
|
||||
if (event.type === "keydown" && event.key === "Escape") {
|
||||
this.requestCancelScreenshot("escape");
|
||||
}
|
||||
this.overlay.handleEvent(event);
|
||||
break;
|
||||
case "beforeunload":
|
||||
this.requestCancelScreenshot("navigation");
|
||||
|
|
@ -191,6 +209,13 @@ export class ScreenshotsComponentChild extends JSWindowActorChild {
|
|||
});
|
||||
}
|
||||
|
||||
addOverlayEventListeners() {
|
||||
let chromeEventHandler = this.docShell.chromeEventHandler;
|
||||
for (let event of ScreenshotsComponentChild.OVERLAY_EVENTS) {
|
||||
chromeEventHandler.addEventListener(event, this, true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Wait until the document is ready and then show the screenshots overlay
|
||||
*
|
||||
|
|
@ -208,24 +233,33 @@ export class ScreenshotsComponentChild extends JSWindowActorChild {
|
|||
let overlay =
|
||||
this.overlay ||
|
||||
(this.#overlay = new lazy.ScreenshotsOverlay(this.document));
|
||||
this.document.addEventListener("keydown", this);
|
||||
this.document.ownerGlobal.addEventListener("beforeunload", this);
|
||||
this.contentWindow.addEventListener("resize", this);
|
||||
this.contentWindow.addEventListener("scroll", this);
|
||||
this.contentWindow.addEventListener("visibilitychange", this);
|
||||
this.addOverlayEventListeners();
|
||||
|
||||
overlay.initialize();
|
||||
return true;
|
||||
}
|
||||
|
||||
removeOverlayEventListeners() {
|
||||
let chromeEventHandler = this.docShell.chromeEventHandler;
|
||||
for (let event of ScreenshotsComponentChild.OVERLAY_EVENTS) {
|
||||
chromeEventHandler.removeEventListener(event, this, true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes event listeners and the screenshots overlay.
|
||||
*/
|
||||
endScreenshotsOverlay(options = {}) {
|
||||
this.document.removeEventListener("keydown", this);
|
||||
this.document.ownerGlobal.removeEventListener("beforeunload", this);
|
||||
this.contentWindow.removeEventListener("resize", this);
|
||||
this.contentWindow.removeEventListener("scroll", this);
|
||||
this.contentWindow.removeEventListener("visibilitychange", this);
|
||||
this.removeOverlayEventListeners();
|
||||
|
||||
this.overlay?.tearDown(options);
|
||||
this.#resizeTask?.disarm();
|
||||
this.#scrollTask?.disarm();
|
||||
|
|
|
|||
|
|
@ -229,8 +229,6 @@ export class ScreenshotsOverlay {
|
|||
this.bottomRightMover = this.getElementById("mover-bottomRight");
|
||||
|
||||
this.selectionSize = this.getElementById("selection-size");
|
||||
|
||||
this.addEventListeners();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -238,7 +236,6 @@ export class ScreenshotsOverlay {
|
|||
*/
|
||||
tearDown(options = {}) {
|
||||
if (this.#content) {
|
||||
this.removeEventListeners();
|
||||
if (!(options.doNotResetMethods === true)) {
|
||||
this.resetMethodsUsed();
|
||||
}
|
||||
|
|
@ -253,30 +250,6 @@ export class ScreenshotsOverlay {
|
|||
this.#setState("");
|
||||
}
|
||||
|
||||
/**
|
||||
* Add required event listeners to the overlay
|
||||
*/
|
||||
addEventListeners() {
|
||||
this.screenshotsContainer.addEventListener("click", this);
|
||||
this.screenshotsContainer.addEventListener("pointerdown", this);
|
||||
this.window.addEventListener("pointermove", this);
|
||||
this.window.addEventListener("pointerup", this);
|
||||
this.screenshotsContainer.addEventListener("keydown", this);
|
||||
this.screenshotsContainer.addEventListener("keyup", this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the events listeners from the overlay
|
||||
*/
|
||||
removeEventListeners() {
|
||||
this.screenshotsContainer.removeEventListener("click", this);
|
||||
this.screenshotsContainer.removeEventListener("pointerdown", this);
|
||||
this.window.removeEventListener("pointermove", this);
|
||||
this.window.removeEventListener("pointerup", this);
|
||||
this.screenshotsContainer.removeEventListener("keydown", this);
|
||||
this.screenshotsContainer.removeEventListener("keyup", this);
|
||||
}
|
||||
|
||||
resetMethodsUsed() {
|
||||
this.#methodsUsed = {
|
||||
element: 0,
|
||||
|
|
@ -332,7 +305,7 @@ export class ScreenshotsOverlay {
|
|||
}
|
||||
|
||||
handleClick(event) {
|
||||
switch (event.target.id) {
|
||||
switch (event.originalTarget.id) {
|
||||
case "screenshots-cancel-button":
|
||||
case "cancel":
|
||||
this.#dispatchEvent("Screenshots:Close", { reason: "overlay_cancel" });
|
||||
|
|
@ -357,8 +330,9 @@ export class ScreenshotsOverlay {
|
|||
*/
|
||||
handlePointerDown(event) {
|
||||
if (
|
||||
event.target.id === "screenshots-cancel-button" ||
|
||||
event.target.closest("#buttons-container") === this.buttonsContainer
|
||||
event.originalTarget.id === "screenshots-cancel-button" ||
|
||||
event.originalTarget.closest("#buttons-container") ===
|
||||
this.buttonsContainer
|
||||
) {
|
||||
event.stopPropagation();
|
||||
return;
|
||||
|
|
@ -372,7 +346,7 @@ export class ScreenshotsOverlay {
|
|||
break;
|
||||
}
|
||||
case STATES.SELECTED: {
|
||||
this.selectedDragStart(pageX, pageY, event.target.id);
|
||||
this.selectedDragStart(pageX, pageY, event.originalTarget.id);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -420,7 +394,7 @@ export class ScreenshotsOverlay {
|
|||
break;
|
||||
}
|
||||
case STATES.DRAGGING: {
|
||||
this.draggingDragEnd(pageX, pageY, event.target.id);
|
||||
this.draggingDragEnd(pageX, pageY, event.originalTarget.id);
|
||||
break;
|
||||
}
|
||||
case STATES.RESIZING: {
|
||||
|
|
@ -475,7 +449,7 @@ export class ScreenshotsOverlay {
|
|||
* @param {Event} event The keydown event
|
||||
*/
|
||||
handleArrowLeftKeyDown(event) {
|
||||
switch (event.target.id) {
|
||||
switch (event.originalTarget.id) {
|
||||
case "highlight":
|
||||
if (this.getAccelKey(event)) {
|
||||
let width = this.selectionRegion.width;
|
||||
|
|
@ -505,9 +479,9 @@ export class ScreenshotsOverlay {
|
|||
let left = this.selectionRegion.left;
|
||||
this.selectionRegion.left = this.windowDimensions.scrollX;
|
||||
this.selectionRegion.right = left;
|
||||
if (event.target.id === "mover-topRight") {
|
||||
if (event.originalTarget.id === "mover-topRight") {
|
||||
this.topLeftMover.focus();
|
||||
} else if (event.target.id === "mover-bottomRight") {
|
||||
} else if (event.originalTarget.id === "mover-bottomRight") {
|
||||
this.bottomLeftMover.focus();
|
||||
}
|
||||
break;
|
||||
|
|
@ -516,9 +490,9 @@ export class ScreenshotsOverlay {
|
|||
this.selectionRegion.right -= 10 ** event.shiftKey;
|
||||
if (this.selectionRegion.x1 >= this.selectionRegion.x2) {
|
||||
this.selectionRegion.sortCoords();
|
||||
if (event.target.id === "mover-topRight") {
|
||||
if (event.originalTarget.id === "mover-topRight") {
|
||||
this.topLeftMover.focus();
|
||||
} else if (event.target.id === "mover-bottomRight") {
|
||||
} else if (event.originalTarget.id === "mover-bottomRight") {
|
||||
this.bottomLeftMover.focus();
|
||||
}
|
||||
}
|
||||
|
|
@ -543,7 +517,7 @@ export class ScreenshotsOverlay {
|
|||
* @param {Event} event The keydown event
|
||||
*/
|
||||
handleArrowUpKeyDown(event) {
|
||||
switch (event.target.id) {
|
||||
switch (event.originalTarget.id) {
|
||||
case "highlight":
|
||||
if (this.getAccelKey(event)) {
|
||||
let height = this.selectionRegion.height;
|
||||
|
|
@ -573,9 +547,9 @@ export class ScreenshotsOverlay {
|
|||
let top = this.selectionRegion.top;
|
||||
this.selectionRegion.top = this.windowDimensions.scrollY;
|
||||
this.selectionRegion.bottom = top;
|
||||
if (event.target.id === "mover-bottomLeft") {
|
||||
if (event.originalTarget.id === "mover-bottomLeft") {
|
||||
this.topLeftMover.focus();
|
||||
} else if (event.target.id === "mover-bottomRight") {
|
||||
} else if (event.originalTarget.id === "mover-bottomRight") {
|
||||
this.topRightMover.focus();
|
||||
}
|
||||
break;
|
||||
|
|
@ -584,9 +558,9 @@ export class ScreenshotsOverlay {
|
|||
this.selectionRegion.bottom -= 10 ** event.shiftKey;
|
||||
if (this.selectionRegion.y1 >= this.selectionRegion.y2) {
|
||||
this.selectionRegion.sortCoords();
|
||||
if (event.target.id === "mover-bottomLeft") {
|
||||
if (event.originalTarget.id === "mover-bottomLeft") {
|
||||
this.topLeftMover.focus();
|
||||
} else if (event.target.id === "mover-bottomRight") {
|
||||
} else if (event.originalTarget.id === "mover-bottomRight") {
|
||||
this.topRightMover.focus();
|
||||
}
|
||||
}
|
||||
|
|
@ -611,7 +585,7 @@ export class ScreenshotsOverlay {
|
|||
* @param {Event} event The keydown event
|
||||
*/
|
||||
handleArrowRightKeyDown(event) {
|
||||
switch (event.target.id) {
|
||||
switch (event.originalTarget.id) {
|
||||
case "highlight":
|
||||
if (this.getAccelKey(event)) {
|
||||
let width = this.selectionRegion.width;
|
||||
|
|
@ -644,9 +618,9 @@ export class ScreenshotsOverlay {
|
|||
this.selectionRegion.right =
|
||||
this.windowDimensions.scrollX + this.windowDimensions.clientWidth;
|
||||
this.selectionRegion.left = right;
|
||||
if (event.target.id === "mover-topLeft") {
|
||||
if (event.originalTarget.id === "mover-topLeft") {
|
||||
this.topRightMover.focus();
|
||||
} else if (event.target.id === "mover-bottomLeft") {
|
||||
} else if (event.originalTarget.id === "mover-bottomLeft") {
|
||||
this.bottomRightMover.focus();
|
||||
}
|
||||
break;
|
||||
|
|
@ -655,9 +629,9 @@ export class ScreenshotsOverlay {
|
|||
this.selectionRegion.left += 10 ** event.shiftKey;
|
||||
if (this.selectionRegion.x1 >= this.selectionRegion.x2) {
|
||||
this.selectionRegion.sortCoords();
|
||||
if (event.target.id === "mover-topLeft") {
|
||||
if (event.originalTarget.id === "mover-topLeft") {
|
||||
this.topRightMover.focus();
|
||||
} else if (event.target.id === "mover-bottomLeft") {
|
||||
} else if (event.originalTarget.id === "mover-bottomLeft") {
|
||||
this.bottomRightMover.focus();
|
||||
}
|
||||
}
|
||||
|
|
@ -682,7 +656,7 @@ export class ScreenshotsOverlay {
|
|||
* @param {Event} event The keydown event
|
||||
*/
|
||||
handleArrowDownKeyDown(event) {
|
||||
switch (event.target.id) {
|
||||
switch (event.originalTarget.id) {
|
||||
case "highlight":
|
||||
if (this.getAccelKey(event)) {
|
||||
let height = this.selectionRegion.height;
|
||||
|
|
@ -715,9 +689,9 @@ export class ScreenshotsOverlay {
|
|||
this.selectionRegion.bottom =
|
||||
this.windowDimensions.scrollY + this.windowDimensions.clientHeight;
|
||||
this.selectionRegion.top = bottom;
|
||||
if (event.target.id === "mover-topLeft") {
|
||||
if (event.originalTarget.id === "mover-topLeft") {
|
||||
this.bottomLeftMover.focus();
|
||||
} else if (event.target.id === "mover-topRight") {
|
||||
} else if (event.originalTarget.id === "mover-topRight") {
|
||||
this.bottomRightMover.focus();
|
||||
}
|
||||
break;
|
||||
|
|
@ -726,9 +700,9 @@ export class ScreenshotsOverlay {
|
|||
this.selectionRegion.top += 10 ** event.shiftKey;
|
||||
if (this.selectionRegion.y1 >= this.selectionRegion.y2) {
|
||||
this.selectionRegion.sortCoords();
|
||||
if (event.target.id === "mover-topLeft") {
|
||||
if (event.originalTarget.id === "mover-topLeft") {
|
||||
this.bottomLeftMover.focus();
|
||||
} else if (event.target.id === "mover-topRight") {
|
||||
} else if (event.originalTarget.id === "mover-topRight") {
|
||||
this.bottomRightMover.focus();
|
||||
}
|
||||
}
|
||||
|
|
@ -755,12 +729,18 @@ export class ScreenshotsOverlay {
|
|||
return;
|
||||
}
|
||||
|
||||
if (event.target.id === "highlight" && event.shiftKey) {
|
||||
event.preventDefault();
|
||||
event.preventDefault();
|
||||
if (event.originalTarget.id === "highlight" && event.shiftKey) {
|
||||
this.downloadButton.focus();
|
||||
} else if (event.target.id === "download" && !event.shiftKey) {
|
||||
event.preventDefault();
|
||||
} else if (event.originalTarget.id === "download" && !event.shiftKey) {
|
||||
this.highlightEl.focus();
|
||||
} else {
|
||||
// The content document can listen for keydown events and prevent moving
|
||||
// focus so we manually move focus to the next element here.
|
||||
let direction = event.shiftKey
|
||||
? Services.focus.MOVEFOCUS_BACKWARD
|
||||
: Services.focus.MOVEFOCUS_FORWARD;
|
||||
Services.focus.moveFocus(this.window, null, direction, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -775,7 +755,7 @@ export class ScreenshotsOverlay {
|
|||
case "ArrowUp":
|
||||
case "ArrowRight":
|
||||
case "ArrowDown":
|
||||
switch (event.target.id) {
|
||||
switch (event.originalTarget.id) {
|
||||
case "highlight":
|
||||
case "mover-bottomLeft":
|
||||
case "mover-bottomRight":
|
||||
|
|
|
|||
|
|
@ -12,11 +12,11 @@ add_task(async function test() {
|
|||
await BrowserTestUtils.withNewTab(
|
||||
{
|
||||
gBrowser,
|
||||
url: TEST_PAGE,
|
||||
url: SHORT_TEST_PAGE,
|
||||
},
|
||||
async browser => {
|
||||
await clearAllTelemetryEvents();
|
||||
await SpecialPowers.spawn(browser, [TEST_PAGE], url => {
|
||||
await SpecialPowers.spawn(browser, [SHORT_TEST_PAGE], url => {
|
||||
let a = content.document.createElement("a");
|
||||
a.id = "clickMe";
|
||||
a.href = url;
|
||||
|
|
|
|||
|
|
@ -92,7 +92,7 @@ add_task(async function test_started_and_canceled_events() {
|
|||
await BrowserTestUtils.withNewTab(
|
||||
{
|
||||
gBrowser,
|
||||
url: TEST_PAGE,
|
||||
url: SHORT_TEST_PAGE,
|
||||
},
|
||||
async browser => {
|
||||
await clearAllTelemetryEvents();
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ add_task(async function test() {
|
|||
await BrowserTestUtils.withNewTab(
|
||||
{
|
||||
gBrowser,
|
||||
url: TEST_PAGE,
|
||||
url: SHORT_TEST_PAGE,
|
||||
},
|
||||
async browser => {
|
||||
function awaitExtensionEvent(eventName, id) {
|
||||
|
|
@ -227,7 +227,7 @@ add_task(async function test() {
|
|||
await BrowserTestUtils.withNewTab(
|
||||
{
|
||||
gBrowser,
|
||||
url: TEST_PAGE,
|
||||
url: SHORT_TEST_PAGE,
|
||||
},
|
||||
async browser => {
|
||||
const SCREENSHOTS_PREF = "extensions.screenshots.disabled";
|
||||
|
|
@ -265,7 +265,7 @@ add_task(async function test() {
|
|||
await BrowserTestUtils.withNewTab(
|
||||
{
|
||||
gBrowser,
|
||||
url: TEST_PAGE,
|
||||
url: SHORT_TEST_PAGE,
|
||||
},
|
||||
async browser => {
|
||||
const SCREENSHOTS_PREF = "extensions.screenshots.disabled";
|
||||
|
|
|
|||
|
|
@ -6,5 +6,22 @@
|
|||
</head>
|
||||
<body style="height:4000px; width:4000px; background-repeat: no-repeat; background-size: 4008px 4016px; background-color: rgb(111, 111, 111); background-image:linear-gradient(to right, transparent 50%, rgba(0, 200, 200, 0.5) 50%),linear-gradient(to bottom, transparent 50%, rgba(100, 0, 100, 0.5) 50%);">
|
||||
<div id="testPageElement" style="position:absolute; top:91px; left:93px; width:92px; height:94px; border:solid red;"></div>
|
||||
<script>
|
||||
// Make sure the screenshots overlay anonymous document always receives events
|
||||
// that web content would normally be able to intercept, as that could break the
|
||||
// overlay
|
||||
function disabledEvent(event) {
|
||||
event.preventDefault();
|
||||
event.stopImmediatePropagation();
|
||||
}
|
||||
|
||||
window.addEventListener("click", disabledEvent, true);
|
||||
window.addEventListener("pointerdown", disabledEvent, true);
|
||||
window.addEventListener("pointermove", disabledEvent, true);
|
||||
window.addEventListener("mousemove", disabledEvent, true);
|
||||
window.addEventListener("pointerup", disabledEvent, true);
|
||||
window.addEventListener("keydown", disabledEvent, true);
|
||||
window.addEventListener("keyup", disabledEvent, true);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
|||
Loading…
Reference in a new issue