From 821d302e1550773e86b1c209161cc1d8bedb741f Mon Sep 17 00:00:00 2001 From: Kenny Ketelaar Date: Wed, 29 Mar 2023 20:01:36 +0200 Subject: [PATCH 1/2] Added copying QR code to clipboard with a menu item and CTRL+C --- src/_locales/en/messages.json | 9 +++++++ src/popup/modules/UserInterface.js | 39 +++++++++++++++++++++++++++++- 2 files changed, 47 insertions(+), 1 deletion(-) diff --git a/src/_locales/en/messages.json b/src/_locales/en/messages.json index 71a1ecd8..0dee2429 100644 --- a/src/_locales/en/messages.json +++ b/src/_locales/en/messages.json @@ -202,6 +202,15 @@ "message": "Save QR code as an &SVG…", "description": "The context menu entry shown for saving SVG images in the popup with an access key." }, + "contextMenuSaveImageClipboard": { + "message": "Save QR code to clipboard…", + "description": "The context menu entry shown for saving PNG images (to the clipboard) in the popup" + }, + "contextMenuSaveImageClipboardAccessKey": { + "message": "Save QR code to &clipboard…", + "description": "The context menu entry shown for saving PNG images (to the clipboard) in the popup with an access key." + }, + // options "someSettingsAreManaged": { diff --git a/src/popup/modules/UserInterface.js b/src/popup/modules/UserInterface.js index 6da4d662..46471c98 100644 --- a/src/popup/modules/UserInterface.js +++ b/src/popup/modules/UserInterface.js @@ -33,6 +33,7 @@ const THROTTLE_SIZE_SAVING_FOR_REMEMBER = 500; // ms const CONTEXT_MENU_SAVE_IMAGE_CANVAS = "save-image-canvas"; const CONTEXT_MENU_SAVE_IMAGE_SVG = "save-image-svg"; +const CONTEXT_MENU_SAVE_IMAGE_CLIPBOARD = "save-image-clipboard"; const DOWNLOAD_PERMISSION = { permissions: ["downloads"] @@ -502,6 +503,10 @@ function menuClicked(event) { }, "image/png"); break; } + case CONTEXT_MENU_SAVE_IMAGE_CLIPBOARD: { + copyToClipboard() + break; + } } } @@ -520,6 +525,8 @@ async function createContextMenu() { // remove menu item if it has been added before browser.menus.remove(CONTEXT_MENU_SAVE_IMAGE_CANVAS); browser.menus.remove(CONTEXT_MENU_SAVE_IMAGE_SVG); + browser.menus.remove(CONTEXT_MENU_SAVE_IMAGE_CLIPBOARD); + // create save menus if needed await createMenu("contextMenuSaveImageSvg", { @@ -538,6 +545,13 @@ async function createContextMenu() { ] } ); + await createMenu("contextMenuSaveImageClipboard", { + id: CONTEXT_MENU_SAVE_IMAGE_CLIPBOARD, + contexts: ["page"], + documentUrlPatterns: [ + document.URL // only apply to own URL = popup + ] + }); browser.menus.onClicked.addListener(menuClicked); return Promise.resolve(); @@ -571,6 +585,27 @@ export function postInitGenerate() { selectAllText({ target: qrCodeText }); } +// TODO: Improve naming of these 2 functions, a bit too similar at the moment +function copyQRCodeToClipboard(event) { + const standardCopyCommand = event.ctrlKey && event.key === "c" + // CMD + C is standard for macOS + const macCopyCommand = event.metaKey && event.key === "c" + + if (standardCopyCommand || macCopyCommand) { + copyToClipboard() + } +} + +function copyToClipboard() { + const canvasElem = QrCreator.getQrCodeCanvasFromLib(); + + canvasElem.toBlob((blob) => { + const clipboardImage = new ClipboardItem({"image/png": blob}) + navigator.clipboard.write([clipboardImage]) + }, "image/png") + +} + /** * Initalises the module. * @@ -589,7 +624,9 @@ export function init() { // add event listeners qrCodeText.addEventListener("input", refreshQrCode); - qrCodeText.addEventListener("focus", selectAllText); + // TODO: Disable event listener below depending on user preference + qrCodeText.addEventListener("keydown", copyQRCodeToClipboard) + // qrCodeText.addEventListener("focus", selectAllText); const applyingMonospaceFont = AddonSettings.get("monospaceFont").then((monospaceFont) => { if (monospaceFont) { From baf70f92ba18f3e4ecb833a21fddabd8ac5914e2 Mon Sep 17 00:00:00 2001 From: Kenny Ketelaar Date: Thu, 30 Mar 2023 14:34:44 +0200 Subject: [PATCH 2/2] Added setting for overriding CTRL+C/CMD+C for copying QR code --- src/_locales/en/messages.json | 5 +++ src/common/modules/data/DefaultSettings.js | 3 +- src/options/options.html | 7 +++++ src/popup/modules/UserInterface.js | 36 +++++++++++++++++----- 4 files changed, 42 insertions(+), 9 deletions(-) diff --git a/src/_locales/en/messages.json b/src/_locales/en/messages.json index 0dee2429..cb60d1ff 100644 --- a/src/_locales/en/messages.json +++ b/src/_locales/en/messages.json @@ -362,6 +362,11 @@ "description": "This is an option shown in the add-on settings." }, + "optionOverrideCopy": { + "message": "CTRL+C/⌘+C to copy QR code", + "description": "This is an option shown in the add-on" + }, + "optionDebugMode": { "message": "Enable debug mode", "description": "This is an option shown in the add-on settings." diff --git a/src/common/modules/data/DefaultSettings.js b/src/common/modules/data/DefaultSettings.js index 03be7613..c16aeb4d 100644 --- a/src/common/modules/data/DefaultSettings.js +++ b/src/common/modules/data/DefaultSettings.js @@ -29,7 +29,8 @@ const defaultSettings = Object.freeze({ qrQuietZone: 1, randomTips: { tips: {} - } + }, + overrideCopy: true }); // freeze the inner objects, this is strongly recommend diff --git a/src/options/options.html b/src/options/options.html index 3169dce3..8a742a65 100644 --- a/src/options/options.html +++ b/src/options/options.html @@ -179,6 +179,13 @@

Addon behavior

+
  • +
    + + +
    +
  • +
  • diff --git a/src/popup/modules/UserInterface.js b/src/popup/modules/UserInterface.js index 46471c98..3d5e6b2e 100644 --- a/src/popup/modules/UserInterface.js +++ b/src/popup/modules/UserInterface.js @@ -504,7 +504,7 @@ function menuClicked(event) { break; } case CONTEXT_MENU_SAVE_IMAGE_CLIPBOARD: { - copyToClipboard() + writeQRToClipboard() break; } } @@ -585,20 +585,36 @@ export function postInitGenerate() { selectAllText({ target: qrCodeText }); } -// TODO: Improve naming of these 2 functions, a bit too similar at the moment +/** + * Listens for the default copy commands CTRL+C (Windows/Linux) and CMD+C (macOS) + * and subsequently writes the current QR code to the clipboard + * + * @function + * @private + * @param {event} event + * @returns {void} + */ function copyQRCodeToClipboard(event) { const standardCopyCommand = event.ctrlKey && event.key === "c" // CMD + C is standard for macOS const macCopyCommand = event.metaKey && event.key === "c" if (standardCopyCommand || macCopyCommand) { - copyToClipboard() + writeQRToClipboard() } } -function copyToClipboard() { +/** + * Writes the current QR code to the clipboard using the Clipboard API + * + * @function + * @private + * @returns {void} + */ +function writeQRToClipboard() { const canvasElem = QrCreator.getQrCodeCanvasFromLib(); + // Only works when you set dom.events.asyncClipboard.clipboardItem to True canvasElem.toBlob((blob) => { const clipboardImage = new ClipboardItem({"image/png": blob}) navigator.clipboard.write([clipboardImage]) @@ -624,9 +640,13 @@ export function init() { // add event listeners qrCodeText.addEventListener("input", refreshQrCode); - // TODO: Disable event listener below depending on user preference - qrCodeText.addEventListener("keydown", copyQRCodeToClipboard) - // qrCodeText.addEventListener("focus", selectAllText); + qrCodeText.addEventListener("focus", selectAllText); + + const applyingCopyListener = AddonSettings.get("overrideCopy").then((overrideCopy) => { + if (overrideCopy) { + window.addEventListener("keydown", copyQRCodeToClipboard) + } + }) const applyingMonospaceFont = AddonSettings.get("monospaceFont").then((monospaceFont) => { if (monospaceFont) { @@ -683,5 +703,5 @@ export function init() { const initQrTypespecificSettings = createContextMenu(); // return Promise chain - return Promise.all([applyingMonospaceFont, applyingQrSize, applyingQrColor, initQrTypespecificSettings]); + return Promise.all([applyingCopyListener, applyingMonospaceFont, applyingQrSize, applyingQrColor, initQrTypespecificSettings]); }