Add api.clipboardGetImage (#778)
* Rename clipboardPasteTarget to just target * Remove else block * Add helper functions * Defer assignment of clipboard paste target * Add api.clipboardGetImage
This commit is contained in:
parent
b28241dbf2
commit
115afb63b9
@ -46,5 +46,12 @@
|
||||
<script src="/mixed/js/object-property-accessor.js"></script>
|
||||
|
||||
<script src="/bg/js/background-main.js"></script>
|
||||
|
||||
<!--
|
||||
Due to a Firefox bug, this next element is purposefully terminated incorrectly.
|
||||
This element must appear directly inside the <body> element, and it must not be closed properly.
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=1603985
|
||||
-->
|
||||
<div id="clipboard-image-paste-target" contenteditable="true">
|
||||
</body>
|
||||
</html>
|
||||
|
@ -64,11 +64,10 @@ class Backend {
|
||||
});
|
||||
this._templateRenderer = new TemplateRenderer();
|
||||
|
||||
this._clipboardPasteTarget = (
|
||||
typeof document === 'object' && document !== null ?
|
||||
document.querySelector('#clipboard-paste-target') :
|
||||
null
|
||||
);
|
||||
this._clipboardPasteTarget = null;
|
||||
this._clipboardPasteTargetInitialized = false;
|
||||
this._clipboardImagePasteTarget = null;
|
||||
this._clipboardImagePasteTargetInitialized = false;
|
||||
|
||||
this._searchPopupTabId = null;
|
||||
this._searchPopupTabCreatePromise = null;
|
||||
@ -108,6 +107,7 @@ class Backend {
|
||||
['getStylesheetContent', {async: true, contentScript: true, handler: this._onApiGetStylesheetContent.bind(this)}],
|
||||
['getEnvironmentInfo', {async: false, contentScript: true, handler: this._onApiGetEnvironmentInfo.bind(this)}],
|
||||
['clipboardGet', {async: true, contentScript: true, handler: this._onApiClipboardGet.bind(this)}],
|
||||
['clipboardGetImage', {async: true, contentScript: true, handler: this._onApiClipboardImageGet.bind(this)}],
|
||||
['getDisplayTemplatesHtml', {async: true, contentScript: true, handler: this._onApiGetDisplayTemplatesHtml.bind(this)}],
|
||||
['getQueryParserTemplatesHtml', {async: true, contentScript: true, handler: this._onApiGetQueryParserTemplatesHtml.bind(this)}],
|
||||
['getZoom', {async: true, contentScript: true, handler: this._onApiGetZoom.bind(this)}],
|
||||
@ -645,18 +645,63 @@ class Backend {
|
||||
const {browser} = this._environment.getInfo();
|
||||
if (browser === 'firefox' || browser === 'firefox-mobile') {
|
||||
return await navigator.clipboard.readText();
|
||||
} else {
|
||||
const clipboardPasteTarget = this._clipboardPasteTarget;
|
||||
if (clipboardPasteTarget === null) {
|
||||
throw new Error('Reading the clipboard is not supported in this context');
|
||||
}
|
||||
clipboardPasteTarget.value = '';
|
||||
clipboardPasteTarget.focus();
|
||||
document.execCommand('paste');
|
||||
const result = clipboardPasteTarget.value;
|
||||
clipboardPasteTarget.value = '';
|
||||
return result;
|
||||
}
|
||||
|
||||
if (!this._environmentHasDocument()) {
|
||||
throw new Error('Reading the clipboard is not supported in this context');
|
||||
}
|
||||
|
||||
if (!this._clipboardPasteTargetInitialized) {
|
||||
this._clipboardPasteTarget = document.querySelector('#clipboard-paste-target');
|
||||
this._clipboardPasteTargetInitialized = true;
|
||||
}
|
||||
|
||||
const target = this._clipboardPasteTarget;
|
||||
if (target === null) {
|
||||
throw new Error('Clipboard paste target does not exist');
|
||||
}
|
||||
|
||||
target.value = '';
|
||||
target.focus();
|
||||
this._executePasteCommand();
|
||||
const result = target.value;
|
||||
target.value = '';
|
||||
return result;
|
||||
}
|
||||
|
||||
async _onApiClipboardImageGet() {
|
||||
// See browser-specific notes in _onApiClipboardGet
|
||||
const {browser} = this._environment.getInfo();
|
||||
if (browser === 'firefox' || browser === 'firefox-mobile') {
|
||||
if (typeof navigator.clipboard !== 'undefined' && typeof navigator.clipboard.read === 'function') {
|
||||
// This function is behind the flag: dom.events.asyncClipboard.dataTransfer
|
||||
const {files} = await navigator.clipboard.read();
|
||||
if (files.length === 0) { return null; }
|
||||
const result = await this._readFileAsDataURL(files[0]);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
if (!this._environmentHasDocument()) {
|
||||
throw new Error('Reading the clipboard is not supported in this context');
|
||||
}
|
||||
|
||||
if (!this._clipboardImagePasteTargetInitialized) {
|
||||
this._clipboardImagePasteTarget = document.querySelector('#clipboard-image-paste-target');
|
||||
this._clipboardImagePasteTargetInitialized = true;
|
||||
}
|
||||
|
||||
const target = this._clipboardImagePasteTarget;
|
||||
if (target === null) {
|
||||
throw new Error('Clipboard paste target does not exist');
|
||||
}
|
||||
|
||||
target.focus();
|
||||
this._executePasteCommand();
|
||||
const image = target.querySelector('img[src^="data:"]');
|
||||
const result = (image !== null ? image.getAttribute('src') : null);
|
||||
target.textContent = '';
|
||||
return result;
|
||||
}
|
||||
|
||||
async _onApiGetDisplayTemplatesHtml() {
|
||||
@ -1539,4 +1584,21 @@ class Backend {
|
||||
const isValidTab = urlPredicate(url);
|
||||
return isValidTab ? tab : null;
|
||||
}
|
||||
|
||||
_environmentHasDocument() {
|
||||
return (typeof document === 'object' && document !== null);
|
||||
}
|
||||
|
||||
_executePasteCommand() {
|
||||
document.execCommand('paste');
|
||||
}
|
||||
|
||||
_readFileAsDataURL(file) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const reader = new FileReader();
|
||||
reader.onload = () => resolve(reader.result);
|
||||
reader.onerror = () => reject(reader.error);
|
||||
reader.readAsDataURL(file);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -133,6 +133,10 @@ const api = (() => {
|
||||
return this._invoke('clipboardGet');
|
||||
}
|
||||
|
||||
clipboardGetImage() {
|
||||
return this._invoke('clipboardGetImage');
|
||||
}
|
||||
|
||||
getDisplayTemplatesHtml() {
|
||||
return this._invoke('getDisplayTemplatesHtml');
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user