diff options
Diffstat (limited to 'ext/js')
-rw-r--r-- | ext/js/background/backend.js | 6 | ||||
-rw-r--r-- | ext/js/comm/clipboard-monitor.js | 2 | ||||
-rw-r--r-- | ext/js/comm/clipboard-reader.js | 83 |
3 files changed, 53 insertions, 38 deletions
diff --git a/ext/js/background/backend.js b/ext/js/background/backend.js index 197734b1..2154b32a 100644 --- a/ext/js/background/backend.js +++ b/ext/js/background/backend.js @@ -53,7 +53,7 @@ class Backend { // eslint-disable-next-line no-undef document: (typeof document === 'object' && document !== null ? document : null), pasteTargetSelector: '#clipboard-paste-target', - imagePasteTargetSelector: '#clipboard-image-paste-target' + richContentPasteTargetSelector: '#clipboard-rich-content-paste-target' }); this._clipboardMonitor = new ClipboardMonitor({ japaneseUtil: this._japaneseUtil, @@ -596,7 +596,7 @@ class Backend { } async _onApiClipboardGet() { - return this._clipboardReader.getText(); + return this._clipboardReader.getText(false); } async _onApiGetDisplayTemplatesHtml() { @@ -1773,7 +1773,7 @@ class Backend { try { if (clipboardDetails !== null && clipboardDetails.text) { - clipboardText = await this._clipboardReader.getText(); + clipboardText = await this._clipboardReader.getText(false); } } catch (e) { errors.push(serializeError(e)); diff --git a/ext/js/comm/clipboard-monitor.js b/ext/js/comm/clipboard-monitor.js index 7a678461..f5be04e7 100644 --- a/ext/js/comm/clipboard-monitor.js +++ b/ext/js/comm/clipboard-monitor.js @@ -39,7 +39,7 @@ class ClipboardMonitor extends EventDispatcher { let text = null; try { - text = await this._clipboardReader.getText(); + text = await this._clipboardReader.getText(false); } catch (e) { // NOP } diff --git a/ext/js/comm/clipboard-reader.js b/ext/js/comm/clipboard-reader.js index aaf4dcd8..9e9a6116 100644 --- a/ext/js/comm/clipboard-reader.js +++ b/ext/js/comm/clipboard-reader.js @@ -28,15 +28,15 @@ class ClipboardReader { * @param {object} details Details about how to set up the instance. * @param {?Document} details.document The Document object to be used, or null for no support. * @param {?string} details.pasteTargetSelector The selector for the paste target element. - * @param {?string} details.imagePasteTargetSelector The selector for the image paste target element. + * @param {?string} details.richContentPasteTargetSelector The selector for the rich content paste target element. */ - constructor({document=null, pasteTargetSelector=null, imagePasteTargetSelector=null}) { + constructor({document=null, pasteTargetSelector=null, richContentPasteTargetSelector=null}) { this._document = document; this._browser = null; this._pasteTarget = null; this._pasteTargetSelector = pasteTargetSelector; - this._imagePasteTarget = null; - this._imagePasteTargetSelector = imagePasteTargetSelector; + this._richContentPasteTarget = null; + this._richContentPasteTargetSelector = richContentPasteTargetSelector; } /** @@ -56,13 +56,14 @@ class ClipboardReader { /** * Gets the text in the clipboard. + * @param {boolean} useRichText Whether or not to use rich text for pasting, when possible. * @returns {string} A string containing the clipboard text. * @throws {Error} Error if not supported. */ - async getText() { + async getText(useRichText) { /* Notes: - document.execCommand('paste') doesn't work on Firefox. + document.execCommand('paste') sometimes doesn't work on Firefox. See: https://bugzilla.mozilla.org/show_bug.cgi?id=1603985 Therefore, navigator.clipboard.readText() is used on Firefox. @@ -72,7 +73,7 @@ class ClipboardReader { being an extension with clipboard permissions. It effectively asks for the non-extension permission for clipboard access. */ - if (this._isFirefox()) { + if (this._isFirefox() && !useRichText) { try { return await navigator.clipboard.readText(); } catch (e) { @@ -86,21 +87,22 @@ class ClipboardReader { throw new Error('Clipboard reading not supported in this context'); } - let target = this._pasteTarget; - if (target === null) { - target = document.querySelector(this._pasteTargetSelector); - if (target === null) { - throw new Error('Clipboard paste target does not exist'); - } - this._pasteTarget = target; + if (useRichText) { + const target = this._getRichContentPasteTarget(); + target.focus(); + document.execCommand('paste'); + const result = target.textContent; + this._clearRichContent(target); + return result; + } else { + const target = this._getPasteTarget(); + target.value = ''; + target.focus(); + document.execCommand('paste'); + const result = target.value; + target.value = ''; + return (typeof result === 'string' ? result : ''); } - - target.value = ''; - target.focus(); - document.execCommand('paste'); - const result = target.value; - target.value = ''; - return (typeof result === 'string' ? result : ''); } /** @@ -143,23 +145,12 @@ class ClipboardReader { throw new Error('Clipboard reading not supported in this context'); } - let target = this._imagePasteTarget; - if (target === null) { - target = document.querySelector(this._imagePasteTargetSelector); - if (target === null) { - throw new Error('Clipboard paste target does not exist'); - } - this._imagePasteTarget = target; - } - + const target = this._getRichContentPasteTarget(); target.focus(); document.execCommand('paste'); const image = target.querySelector('img[src^="data:"]'); const result = (image !== null ? image.getAttribute('src') : null); - for (const image2 of target.querySelectorAll('img')) { - image2.removeAttribute('src'); - } - target.textContent = ''; + this._clearRichContent(target); return result; } @@ -177,4 +168,28 @@ class ClipboardReader { reader.readAsDataURL(file); }); } + + _getPasteTarget() { + if (this._pasteTarget === null) { this._pasteTarget = this._findPasteTarget(this._pasteTargetSelector); } + return this._pasteTarget; + } + + _getRichContentPasteTarget() { + if (this._richContentPasteTarget === null) { this._richContentPasteTarget = this._findPasteTarget(this._richContentPasteTargetSelector); } + return this._richContentPasteTarget; + } + + _findPasteTarget(selector) { + const target = this._document.querySelector(selector); + if (target === null) { throw new Error('Clipboard paste target does not exist'); } + return target; + } + + _clearRichContent(element) { + for (const image of element.querySelectorAll('img')) { + image.removeAttribute('src'); + image.removeAttribute('srcset'); + } + element.textContent = ''; + } } |