summaryrefslogtreecommitdiffstats
path: root/browser/components/screenshots/ScreenshotsOverlayChild.sys.mjs
diff options
context:
space:
mode:
Diffstat (limited to 'browser/components/screenshots/ScreenshotsOverlayChild.sys.mjs')
-rw-r--r--browser/components/screenshots/ScreenshotsOverlayChild.sys.mjs491
1 files changed, 376 insertions, 115 deletions
diff --git a/browser/components/screenshots/ScreenshotsOverlayChild.sys.mjs b/browser/components/screenshots/ScreenshotsOverlayChild.sys.mjs
index 3718b6a4e0..aa9dbfdbd3 100644
--- a/browser/components/screenshots/ScreenshotsOverlayChild.sys.mjs
+++ b/browser/components/screenshots/ScreenshotsOverlayChild.sys.mjs
@@ -88,22 +88,18 @@ export class ScreenshotsOverlay {
cancelLabel,
cancelAttributes,
instructions,
- downloadLabel,
downloadAttributes,
- copyLabel,
copyAttributes,
] = lazy.overlayLocalization.formatMessagesSync([
{ id: "screenshots-cancel-button" },
{ id: "screenshots-component-cancel-button" },
{ id: "screenshots-instructions" },
- { id: "screenshots-component-download-button-label" },
{
- id: "screenshots-component-download-button",
+ id: "screenshots-component-download-button-2",
args: { shortcut: downloadShortcut },
},
- { id: "screenshots-component-copy-button-label" },
{
- id: "screenshots-component-copy-button",
+ id: "screenshots-component-copy-button-2",
args: { shortcut: copyShorcut },
},
]);
@@ -137,31 +133,31 @@ export class ScreenshotsOverlay {
<div id="mover-topRight" class="mover-target direction-topRight" tabindex="0">
<div class="mover"></div>
</div>
- <div id="mover-left" class="mover-target direction-left">
- <div class="mover"></div>
- </div>
<div id="mover-right" class="mover-target direction-right">
<div class="mover"></div>
</div>
- <div id="mover-bottomLeft" class="mover-target direction-bottomLeft" tabindex="0">
+ <div id="mover-bottomRight" class="mover-target direction-bottomRight" tabindex="0">
<div class="mover"></div>
</div>
<div id="mover-bottom" class="mover-target direction-bottom">
<div class="mover"></div>
</div>
- <div id="mover-bottomRight" class="mover-target direction-bottomRight" tabindex="0">
+ <div id="mover-bottomLeft" class="mover-target direction-bottomLeft" tabindex="0">
+ <div class="mover"></div>
+ </div>
+ <div id="mover-left" class="mover-target direction-left">
<div class="mover"></div>
</div>
<div id="selection-size-container">
- <span id="selection-size"></span>
+ <span id="selection-size" dir="ltr"></span>
</div>
</div>
</div>
<div id="buttons-container" hidden>
<div class="buttons-wrapper">
<button id="cancel" class="screenshots-button" title="${cancelAttributes.attributes[0].value}" aria-label="${cancelAttributes.attributes[1].value}"><img/></button>
- <button id="copy" class="screenshots-button" title="${copyAttributes.attributes[0].value}" aria-label="${copyAttributes.attributes[1].value}"><img/><label>${copyLabel.value}</label></button>
- <button id="download" class="screenshots-button primary" title="${downloadAttributes.attributes[0].value}" aria-label="${downloadAttributes.attributes[1].value}"><img/><label>${downloadLabel.value}</label></button>
+ <button id="copy" class="screenshots-button" title="${copyAttributes.attributes[0].value}" aria-label="${copyAttributes.attributes[1].value}"><img/><label>${copyAttributes.value}</label></button>
+ <button id="download" class="screenshots-button primary" title="${downloadAttributes.attributes[0].value}" aria-label="${downloadAttributes.attributes[1].value}"><img/><label>${downloadAttributes.value}</label></button>
</div>
</div>
</div>
@@ -240,6 +236,12 @@ export class ScreenshotsOverlay {
this.#setState(STATES.CROSSHAIRS);
+ this.selection = this.window.getSelection();
+ this.ranges = [];
+ for (let i = 0; i < this.selection.rangeCount; i++) {
+ this.ranges.push(this.selection.getRangeAt(i));
+ }
+
this.#initialized = true;
}
@@ -303,6 +305,10 @@ export class ScreenshotsOverlay {
};
}
+ focus() {
+ this.previewCancelButton.focus({ focusVisible: true });
+ }
+
/**
* Returns the x and y coordinates of the event relative to both the
* viewport and the page.
@@ -316,7 +322,9 @@ export class ScreenshotsOverlay {
* }
*/
getCoordinatesFromEvent(event) {
- const { clientX, clientY, pageX, pageY } = event;
+ let { clientX, clientY, pageX, pageY } = event;
+ pageX -= this.windowDimensions.scrollMinX;
+ pageY -= this.windowDimensions.scrollMinY;
return { clientX, clientY, pageX, pageY };
}
@@ -341,6 +349,9 @@ export class ScreenshotsOverlay {
case "keyup":
this.handleKeyUp(event);
break;
+ case "selectionchange":
+ this.handleSelectionChange();
+ break;
}
}
@@ -498,6 +509,127 @@ export class ScreenshotsOverlay {
* @param {Event} event The keydown event
*/
handleKeyDown(event) {
+ if (event.key === "Escape") {
+ this.maybeCancelScreenshots();
+ return;
+ }
+
+ switch (this.#state) {
+ case STATES.CROSSHAIRS:
+ this.crosshairsKeyDown(event);
+ break;
+ case STATES.DRAGGING:
+ this.draggingKeyDown(event);
+ break;
+ case STATES.RESIZING:
+ this.resizingKeyDown(event);
+ break;
+ case STATES.SELECTED:
+ this.selectedKeyDown(event);
+ break;
+ }
+ }
+
+ /**
+ * Handles when a keyup occurs in the screenshots component.
+ * All we need to do on keyup is set the state to selected.
+ * @param {Event} event The keydown event
+ */
+ handleKeyUp(event) {
+ switch (this.#state) {
+ case STATES.RESIZING:
+ switch (event.key) {
+ case "ArrowLeft":
+ case "ArrowUp":
+ case "ArrowRight":
+ case "ArrowDown":
+ switch (event.originalTarget.id) {
+ case "highlight":
+ case "mover-bottomLeft":
+ case "mover-bottomRight":
+ case "mover-topLeft":
+ case "mover-topRight":
+ event.preventDefault();
+ this.#setState(STATES.SELECTED, { doNotMoveFocus: true });
+ break;
+ }
+ break;
+ }
+ break;
+ }
+ }
+
+ /**
+ * Gets the accel key depending on the platform.
+ * metaKey for macOS. ctrlKey for Windows and Linux.
+ * @param {Event} event The keydown event
+ * @returns {Boolean} True if the accel key is pressed, false otherwise.
+ */
+ getAccelKey(event) {
+ if (AppConstants.platform === "macosx") {
+ return event.metaKey;
+ }
+ return event.ctrlKey;
+ }
+
+ crosshairsKeyDown(event) {
+ switch (event.key) {
+ case "ArrowLeft":
+ case "ArrowUp":
+ case "ArrowRight":
+ case "ArrowDown":
+ // Do nothing so we can prevent default below
+ break;
+ case "Tab":
+ this.maybeLockFocus(event);
+ return;
+ case "Enter":
+ if (this.hoverElementRegion.isRegionValid) {
+ event.preventDefault();
+ this.draggingReadyStart();
+ this.draggingReadyDragEnd();
+ return;
+ }
+ // eslint-disable-next-line no-fallthrough
+ case " ": {
+ if (Services.appinfo.isWayland) {
+ return;
+ }
+
+ if (event.originalTarget === this.previewCancelButton) {
+ return;
+ }
+
+ event.preventDefault();
+ // The left and top coordinates from cursorRegion are relative to
+ // the client window so we need to add the scroll offset of the page to
+ // get the correct coordinates.
+ let x = {};
+ let y = {};
+ this.window.windowUtils.getLastOverWindowPointerLocationInCSSPixels(
+ x,
+ y
+ );
+ this.crosshairsDragStart(
+ x.value + this.windowDimensions.scrollX,
+ y.value + this.windowDimensions.scrollY
+ );
+ this.#setState(STATES.DRAGGING);
+ break;
+ }
+ default:
+ return;
+ }
+
+ // Prevent scrolling with arrow keys
+ event.preventDefault();
+ }
+
+ /**
+ * Handles a keydown event for the dragging state.
+ * @param {Event} event The keydown event
+ */
+ draggingKeyDown(event) {
switch (event.key) {
case "ArrowLeft":
this.handleArrowLeftKeyDown(event);
@@ -511,11 +643,71 @@ export class ScreenshotsOverlay {
case "ArrowDown":
this.handleArrowDownKeyDown(event);
break;
+ case "Enter":
+ case " ":
+ event.preventDefault();
+ this.#setState(STATES.SELECTED);
+ return;
+ default:
+ return;
+ }
+
+ this.drawSelectionContainer();
+ }
+
+ /**
+ * Handles a keydown event for the resizing state.
+ * @param {Event} event The keydown event
+ */
+ resizingKeyDown(event) {
+ switch (event.key) {
+ case "ArrowLeft":
+ this.resizingArrowLeftKeyDown(event);
+ break;
+ case "ArrowUp":
+ this.resizingArrowUpKeyDown(event);
+ break;
+ case "ArrowRight":
+ this.resizingArrowRightKeyDown(event);
+ break;
+ case "ArrowDown":
+ this.resizingArrowDownKeyDown(event);
+ break;
+ }
+ }
+
+ selectedKeyDown(event) {
+ let isSelectionElement = event.originalTarget.closest(
+ "#selection-container"
+ );
+ switch (event.key) {
+ case "ArrowLeft":
+ if (isSelectionElement) {
+ this.resizingArrowLeftKeyDown(event);
+ }
+ break;
+ case "ArrowUp":
+ if (isSelectionElement) {
+ this.resizingArrowUpKeyDown(event);
+ }
+ break;
+ case "ArrowRight":
+ if (isSelectionElement) {
+ this.resizingArrowRightKeyDown(event);
+ }
+ break;
+ case "ArrowDown":
+ if (isSelectionElement) {
+ this.resizingArrowDownKeyDown(event);
+ }
+ break;
case "Tab":
this.maybeLockFocus(event);
break;
- case "Escape":
- this.maybeCancelScreenshots();
+ case " ":
+ if (!event.originalTarget.closest("#buttons-container")) {
+ event.preventDefault();
+ }
break;
case this.copyKey.toLowerCase():
if (this.state === "selected" && this.getAccelKey(event)) {
@@ -533,16 +725,20 @@ export class ScreenshotsOverlay {
}
/**
- * Gets the accel key depending on the platform.
- * metaKey for macOS. ctrlKey for Windows and Linux.
+ * Move the region or its left or right side to the left.
+ * Just the arrow key will move the region by 1px.
+ * Arrow key + shift will move the region by 10px.
+ * Arrow key + control/meta will move to the edge of the window.
* @param {Event} event The keydown event
- * @returns {Boolean} True if the accel key is pressed, false otherwise.
*/
- getAccelKey(event) {
- if (AppConstants.platform === "macosx") {
- return event.metaKey;
+ resizingArrowLeftKeyDown(event) {
+ this.handleArrowLeftKeyDown(event);
+
+ if (this.#state !== STATES.RESIZING) {
+ this.#setState(STATES.RESIZING);
}
- return event.ctrlKey;
+
+ this.drawSelectionContainer();
}
/**
@@ -553,6 +749,7 @@ export class ScreenshotsOverlay {
* @param {Event} event The keydown event
*/
handleArrowLeftKeyDown(event) {
+ let exponent = event.shiftKey ? 1 : 0;
switch (event.originalTarget.id) {
case "highlight":
if (this.getAccelKey(event)) {
@@ -562,7 +759,7 @@ export class ScreenshotsOverlay {
break;
}
- this.selectionRegion.right -= 10 ** event.shiftKey;
+ this.selectionRegion.right -= 10 ** exponent;
// eslint-disable-next-line no-fallthrough
case "mover-topLeft":
case "mover-bottomLeft":
@@ -571,7 +768,7 @@ export class ScreenshotsOverlay {
break;
}
- this.selectionRegion.left -= 10 ** event.shiftKey;
+ this.selectionRegion.left -= 10 ** exponent;
this.scrollIfByEdge(
this.selectionRegion.left,
this.windowDimensions.scrollY + this.windowDimensions.clientHeight / 2
@@ -591,7 +788,7 @@ export class ScreenshotsOverlay {
break;
}
- this.selectionRegion.right -= 10 ** event.shiftKey;
+ this.selectionRegion.right -= 10 ** exponent;
if (this.selectionRegion.x1 >= this.selectionRegion.x2) {
this.selectionRegion.sortCoords();
if (event.originalTarget.id === "mover-topRight") {
@@ -605,11 +802,23 @@ export class ScreenshotsOverlay {
return;
}
+ event.preventDefault();
+ }
+
+ /**
+ * Move the region or its top or bottom side upward.
+ * Just the arrow key will move the region by 1px.
+ * Arrow key + shift will move the region by 10px.
+ * Arrow key + control/meta will move to the edge of the window.
+ * @param {Event} event The keydown event
+ */
+ resizingArrowUpKeyDown(event) {
+ this.handleArrowUpKeyDown(event);
+
if (this.#state !== STATES.RESIZING) {
this.#setState(STATES.RESIZING);
}
- event.preventDefault();
this.drawSelectionContainer();
}
@@ -621,6 +830,7 @@ export class ScreenshotsOverlay {
* @param {Event} event The keydown event
*/
handleArrowUpKeyDown(event) {
+ let exponent = event.shiftKey ? 1 : 0;
switch (event.originalTarget.id) {
case "highlight":
if (this.getAccelKey(event)) {
@@ -630,7 +840,7 @@ export class ScreenshotsOverlay {
break;
}
- this.selectionRegion.bottom -= 10 ** event.shiftKey;
+ this.selectionRegion.bottom -= 10 ** exponent;
// eslint-disable-next-line no-fallthrough
case "mover-topLeft":
case "mover-topRight":
@@ -639,7 +849,7 @@ export class ScreenshotsOverlay {
break;
}
- this.selectionRegion.top -= 10 ** event.shiftKey;
+ this.selectionRegion.top -= 10 ** exponent;
this.scrollIfByEdge(
this.windowDimensions.scrollX + this.windowDimensions.clientWidth / 2,
this.selectionRegion.top
@@ -659,7 +869,7 @@ export class ScreenshotsOverlay {
break;
}
- this.selectionRegion.bottom -= 10 ** event.shiftKey;
+ this.selectionRegion.bottom -= 10 ** exponent;
if (this.selectionRegion.y1 >= this.selectionRegion.y2) {
this.selectionRegion.sortCoords();
if (event.originalTarget.id === "mover-bottomLeft") {
@@ -673,11 +883,23 @@ export class ScreenshotsOverlay {
return;
}
+ event.preventDefault();
+ }
+
+ /**
+ * Move the region or its left or right side to the right.
+ * Just the arrow key will move the region by 1px.
+ * Arrow key + shift will move the region by 10px.
+ * Arrow key + control/meta will move to the edge of the window.
+ * @param {Event} event The keydown event
+ */
+ resizingArrowRightKeyDown(event) {
+ this.handleArrowRightKeyDown(event);
+
if (this.#state !== STATES.RESIZING) {
this.#setState(STATES.RESIZING);
}
- event.preventDefault();
this.drawSelectionContainer();
}
@@ -689,6 +911,7 @@ export class ScreenshotsOverlay {
* @param {Event} event The keydown event
*/
handleArrowRightKeyDown(event) {
+ let exponent = event.shiftKey ? 1 : 0;
switch (event.originalTarget.id) {
case "highlight":
if (this.getAccelKey(event)) {
@@ -699,7 +922,7 @@ export class ScreenshotsOverlay {
break;
}
- this.selectionRegion.left += 10 ** event.shiftKey;
+ this.selectionRegion.left += 10 ** exponent;
// eslint-disable-next-line no-fallthrough
case "mover-topRight":
case "mover-bottomRight":
@@ -709,7 +932,7 @@ export class ScreenshotsOverlay {
break;
}
- this.selectionRegion.right += 10 ** event.shiftKey;
+ this.selectionRegion.right += 10 ** exponent;
this.scrollIfByEdge(
this.selectionRegion.right,
this.windowDimensions.scrollY + this.windowDimensions.clientHeight / 2
@@ -730,7 +953,7 @@ export class ScreenshotsOverlay {
break;
}
- this.selectionRegion.left += 10 ** event.shiftKey;
+ this.selectionRegion.left += 10 ** exponent;
if (this.selectionRegion.x1 >= this.selectionRegion.x2) {
this.selectionRegion.sortCoords();
if (event.originalTarget.id === "mover-topLeft") {
@@ -744,12 +967,7 @@ export class ScreenshotsOverlay {
return;
}
- if (this.#state !== STATES.RESIZING) {
- this.#setState(STATES.RESIZING);
- }
-
event.preventDefault();
- this.drawSelectionContainer();
}
/**
@@ -759,7 +977,18 @@ export class ScreenshotsOverlay {
* Arrow key + control/meta will move to the edge of the window.
* @param {Event} event The keydown event
*/
+ resizingArrowDownKeyDown(event) {
+ this.handleArrowDownKeyDown(event);
+
+ if (this.#state !== STATES.RESIZING) {
+ this.#setState(STATES.RESIZING);
+ }
+
+ this.drawSelectionContainer();
+ }
+
handleArrowDownKeyDown(event) {
+ let exponent = event.shiftKey ? 1 : 0;
switch (event.originalTarget.id) {
case "highlight":
if (this.getAccelKey(event)) {
@@ -770,7 +999,7 @@ export class ScreenshotsOverlay {
break;
}
- this.selectionRegion.top += 10 ** event.shiftKey;
+ this.selectionRegion.top += 10 ** exponent;
// eslint-disable-next-line no-fallthrough
case "mover-bottomLeft":
case "mover-bottomRight":
@@ -780,7 +1009,7 @@ export class ScreenshotsOverlay {
break;
}
- this.selectionRegion.bottom += 10 ** event.shiftKey;
+ this.selectionRegion.bottom += 10 ** exponent;
this.scrollIfByEdge(
this.windowDimensions.scrollX + this.windowDimensions.clientWidth / 2,
this.selectionRegion.bottom
@@ -801,7 +1030,7 @@ export class ScreenshotsOverlay {
break;
}
- this.selectionRegion.top += 10 ** event.shiftKey;
+ this.selectionRegion.top += 10 ** exponent;
if (this.selectionRegion.y1 >= this.selectionRegion.y2) {
this.selectionRegion.sortCoords();
if (event.originalTarget.id === "mover-topLeft") {
@@ -815,12 +1044,7 @@ export class ScreenshotsOverlay {
return;
}
- if (this.#state !== STATES.RESIZING) {
- this.#setState(STATES.RESIZING);
- }
-
event.preventDefault();
- this.drawSelectionContainer();
}
/**
@@ -829,27 +1053,39 @@ export class ScreenshotsOverlay {
* @param {Event} event The keydown event
*/
maybeLockFocus(event) {
- if (this.#state !== STATES.SELECTED) {
- return;
- }
-
event.preventDefault();
- if (event.originalTarget.id === "highlight" && event.shiftKey) {
- this.downloadButton.focus({ focusVisible: true });
- } else if (event.originalTarget.id === "download" && !event.shiftKey) {
- this.highlightEl.focus({ focusVisible: true });
- } 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,
- Services.focus.FLAG_BYKEY
- );
+
+ switch (this.#state) {
+ case STATES.CROSSHAIRS:
+ if (event.shiftKey) {
+ this.#dispatchEvent("Screenshots:FocusPanel", {
+ direction: "backward",
+ });
+ } else {
+ this.#dispatchEvent("Screenshots:FocusPanel", {
+ direction: "forward",
+ });
+ }
+ break;
+ case STATES.SELECTED:
+ if (event.originalTarget.id === "highlight" && event.shiftKey) {
+ this.downloadButton.focus({ focusVisible: true });
+ } else if (event.originalTarget.id === "download" && !event.shiftKey) {
+ this.highlightEl.focus({ focusVisible: true });
+ } 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,
+ Services.focus.FLAG_BYKEY
+ );
+ }
+ break;
}
}
@@ -866,27 +1102,15 @@ export class ScreenshotsOverlay {
}
/**
- * Handles when a keydown occurs in the screenshots component.
- * All we need to do on keyup is set the state to selected.
- * @param {Event} event The keydown event
+ * All of the selection ranges were recorded at initialization. The ranges
+ * are removed when focus is set to the buttons so we add the selection
+ * ranges back so a selected region can be captured.
*/
- handleKeyUp(event) {
- switch (event.key) {
- case "ArrowLeft":
- case "ArrowUp":
- case "ArrowRight":
- case "ArrowDown":
- switch (event.originalTarget.id) {
- case "highlight":
- case "mover-bottomLeft":
- case "mover-bottomRight":
- case "mover-topLeft":
- case "mover-topRight":
- event.preventDefault();
- this.#setState(STATES.SELECTED);
- break;
- }
- break;
+ handleSelectionChange() {
+ if (this.ranges.length) {
+ for (let range of this.ranges) {
+ this.selection.addRange(range);
+ }
}
}
@@ -908,8 +1132,9 @@ export class ScreenshotsOverlay {
/**
* Set a new state for the overlay
* @param {String} newState
+ * @param {Object} options (optional) Options for calling start of state method
*/
- #setState(newState) {
+ #setState(newState, options = {}) {
if (this.#state === STATES.SELECTED && newState === STATES.CROSSHAIRS) {
this.#dispatchEvent("Screenshots:RecordEvent", {
eventName: "started",
@@ -918,7 +1143,13 @@ export class ScreenshotsOverlay {
}
if (newState !== this.#state) {
this.#dispatchEvent("Screenshots:OverlaySelection", {
- hasSelection: newState == STATES.SELECTED,
+ hasSelection: [
+ STATES.DRAGGING_READY,
+ STATES.DRAGGING,
+ STATES.RESIZING,
+ STATES.SELECTED,
+ ].includes(newState),
+ overlayState: newState,
});
}
this.#state = newState;
@@ -937,7 +1168,7 @@ export class ScreenshotsOverlay {
break;
}
case STATES.SELECTED: {
- this.selectedStart();
+ this.selectedStart(options);
break;
}
case STATES.RESIZING: {
@@ -997,11 +1228,16 @@ export class ScreenshotsOverlay {
* Hide the preview and hover element containers.
* Draw the selection and buttons containers.
*/
- selectedStart() {
+ selectedStart(options) {
+ this.selectionRegion.sortCoords();
this.hidePreviewContainer();
this.hideHoverElementContainer();
this.drawSelectionContainer();
this.drawButtonsContainer();
+
+ if (!options.doNotMoveFocus) {
+ this.setFocusToActionButton();
+ }
}
/**
@@ -1228,7 +1464,6 @@ export class ScreenshotsOverlay {
if (this.hoverElementRegion.isRegionValid) {
this.selectionRegion.dimensions = this.hoverElementRegion.dimensions;
this.#setState(STATES.SELECTED);
- this.setFocusToActionButton();
this.#dispatchEvent("Screenshots:RecordEvent", {
eventName: "selected",
reason: "element",
@@ -1249,11 +1484,9 @@ export class ScreenshotsOverlay {
right: pageX,
bottom: pageY,
};
- this.selectionRegion.sortCoords();
this.#setState(STATES.SELECTED);
this.maybeRecordRegionSelected();
this.#methodsUsed.region += 1;
- this.setFocusToActionButton();
}
/**
@@ -1264,9 +1497,7 @@ export class ScreenshotsOverlay {
*/
resizingDragEnd(pageX, pageY) {
this.resizingDrag(pageX, pageY);
- this.selectionRegion.sortCoords();
this.#setState(STATES.SELECTED);
- this.setFocusToActionButton();
this.maybeRecordRegionSelected();
if (this.#moverId === "highlight") {
this.#methodsUsed.move += 1;
@@ -1325,8 +1556,9 @@ export class ScreenshotsOverlay {
* Update the screenshots overlay container based on the window dimensions.
*/
updateScreenshotsOverlayContainer() {
- let { scrollWidth, scrollHeight } = this.windowDimensions.dimensions;
- this.screenshotsContainer.style = `width:${scrollWidth}px;height:${scrollHeight}px;`;
+ let { scrollWidth, scrollHeight, scrollMinX } =
+ this.windowDimensions.dimensions;
+ this.screenshotsContainer.style = `left:${scrollMinX};width:${scrollWidth}px;height:${scrollHeight}px;`;
}
showScreenshotsOverlayContainer() {
@@ -1387,7 +1619,7 @@ export class ScreenshotsOverlay {
let [selectionSizeTranslation] =
lazy.overlayLocalization.formatMessagesSync([
{
- id: "screenshots-overlay-selection-region-size-2",
+ id: "screenshots-overlay-selection-region-size-3",
args: {
width: Math.floor(width * zoom),
height: Math.floor(height * zoom),
@@ -1420,16 +1652,13 @@ export class ScreenshotsOverlay {
right: boxRight,
bottom: boxBottom,
} = this.selectionRegion.dimensions;
- let { clientWidth, clientHeight, scrollX, scrollY } =
+
+ let { clientWidth, clientHeight, scrollX, scrollY, scrollWidth } =
this.windowDimensions.dimensions;
- if (
- boxTop > scrollY + clientHeight ||
- boxBottom < scrollY ||
- boxLeft > scrollX + clientWidth ||
- boxRight < scrollX
- ) {
- // The box is offscreen so need to draw the buttons
+ if (!this.windowDimensions.isInViewport(this.selectionRegion.dimensions)) {
+ // The box is entirely offscreen so need to draw the buttons
+
return;
}
@@ -1445,12 +1674,32 @@ export class ScreenshotsOverlay {
}
}
- if (boxRight < 300) {
- this.buttonsContainer.style.left = `${boxLeft}px`;
- this.buttonsContainer.style.right = "";
- } else {
- this.buttonsContainer.style.right = `calc(100% - ${boxRight}px)`;
+ if (!this.buttonsContainerRect) {
+ this.buttonsContainerRect = this.buttonsContainer.getBoundingClientRect();
+ }
+
+ let viewportLeft = scrollX;
+ let viewportRight = scrollX + clientWidth;
+
+ let left, right;
+ let isLTR = !Services.locale.isAppLocaleRTL;
+ if (isLTR) {
+ left = Math.max(
+ Math.min(viewportRight, boxRight),
+ viewportLeft + Math.ceil(this.buttonsContainerRect.width)
+ );
+ right = scrollWidth - left;
+
+ this.buttonsContainer.style.right = `${right}px`;
this.buttonsContainer.style.left = "";
+ } else {
+ left = Math.min(
+ Math.max(viewportLeft, boxLeft),
+ viewportRight - Math.ceil(this.buttonsContainerRect.width)
+ );
+
+ this.buttonsContainer.style.left = `${left}px`;
+ this.buttonsContainer.style.right = "";
}
this.buttonsContainer.style.top = `${top}px`;
@@ -1464,6 +1713,10 @@ export class ScreenshotsOverlay {
this.buttonsContainer.hidden = true;
}
+ updateCursorRegion(left, top) {
+ this.cursorRegion = { left, top, right: left, bottom: top };
+ }
+
/**
* Set the pointer events to none on the screenshots elements so
* elementFromPoint can find the real element at the given point.
@@ -1595,8 +1848,10 @@ export class ScreenshotsOverlay {
* scrollHeight: The height of the entire page
* scrollX: The X scroll offset of the viewport
* scrollY: The Y scroll offest of the viewport
- * scrollMinX: The X mininmun the viewport can scroll to
- * scrollMinY: The Y mininmun the viewport can scroll to
+ * scrollMinX: The X minimum the viewport can scroll to
+ * scrollMinY: The Y minimum the viewport can scroll to
+ * scrollMaxX: The X maximum the viewport can scroll to
+ * scrollMaxY: The Y maximum the viewport can scroll to
* }
*/
getDimensionsFromWindow() {
@@ -1637,6 +1892,8 @@ export class ScreenshotsOverlay {
scrollY,
scrollMinX,
scrollMinY,
+ scrollMaxX,
+ scrollMaxY,
};
}
@@ -1665,6 +1922,8 @@ export class ScreenshotsOverlay {
scrollY,
scrollMinX,
scrollMinY,
+ scrollMaxX,
+ scrollMaxY,
} = this.getDimensionsFromWindow();
this.screenshotsContainer.toggleAttribute("resizing", false);
@@ -1677,6 +1936,8 @@ export class ScreenshotsOverlay {
scrollY,
scrollMinX,
scrollMinY,
+ scrollMaxX,
+ scrollMaxY,
devicePixelRatio: this.window.devicePixelRatio,
};