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="/mixed/js/object-property-accessor.js"></script>
|
||||||
|
|
||||||
<script src="/bg/js/background-main.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>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
@ -64,11 +64,10 @@ class Backend {
|
|||||||
});
|
});
|
||||||
this._templateRenderer = new TemplateRenderer();
|
this._templateRenderer = new TemplateRenderer();
|
||||||
|
|
||||||
this._clipboardPasteTarget = (
|
this._clipboardPasteTarget = null;
|
||||||
typeof document === 'object' && document !== null ?
|
this._clipboardPasteTargetInitialized = false;
|
||||||
document.querySelector('#clipboard-paste-target') :
|
this._clipboardImagePasteTarget = null;
|
||||||
null
|
this._clipboardImagePasteTargetInitialized = false;
|
||||||
);
|
|
||||||
|
|
||||||
this._searchPopupTabId = null;
|
this._searchPopupTabId = null;
|
||||||
this._searchPopupTabCreatePromise = null;
|
this._searchPopupTabCreatePromise = null;
|
||||||
@ -108,6 +107,7 @@ class Backend {
|
|||||||
['getStylesheetContent', {async: true, contentScript: true, handler: this._onApiGetStylesheetContent.bind(this)}],
|
['getStylesheetContent', {async: true, contentScript: true, handler: this._onApiGetStylesheetContent.bind(this)}],
|
||||||
['getEnvironmentInfo', {async: false, contentScript: true, handler: this._onApiGetEnvironmentInfo.bind(this)}],
|
['getEnvironmentInfo', {async: false, contentScript: true, handler: this._onApiGetEnvironmentInfo.bind(this)}],
|
||||||
['clipboardGet', {async: true, contentScript: true, handler: this._onApiClipboardGet.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)}],
|
['getDisplayTemplatesHtml', {async: true, contentScript: true, handler: this._onApiGetDisplayTemplatesHtml.bind(this)}],
|
||||||
['getQueryParserTemplatesHtml', {async: true, contentScript: true, handler: this._onApiGetQueryParserTemplatesHtml.bind(this)}],
|
['getQueryParserTemplatesHtml', {async: true, contentScript: true, handler: this._onApiGetQueryParserTemplatesHtml.bind(this)}],
|
||||||
['getZoom', {async: true, contentScript: true, handler: this._onApiGetZoom.bind(this)}],
|
['getZoom', {async: true, contentScript: true, handler: this._onApiGetZoom.bind(this)}],
|
||||||
@ -645,18 +645,63 @@ class Backend {
|
|||||||
const {browser} = this._environment.getInfo();
|
const {browser} = this._environment.getInfo();
|
||||||
if (browser === 'firefox' || browser === 'firefox-mobile') {
|
if (browser === 'firefox' || browser === 'firefox-mobile') {
|
||||||
return await navigator.clipboard.readText();
|
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() {
|
async _onApiGetDisplayTemplatesHtml() {
|
||||||
@ -1539,4 +1584,21 @@ class Backend {
|
|||||||
const isValidTab = urlPredicate(url);
|
const isValidTab = urlPredicate(url);
|
||||||
return isValidTab ? tab : null;
|
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');
|
return this._invoke('clipboardGet');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
clipboardGetImage() {
|
||||||
|
return this._invoke('clipboardGetImage');
|
||||||
|
}
|
||||||
|
|
||||||
getDisplayTemplatesHtml() {
|
getDisplayTemplatesHtml() {
|
||||||
return this._invoke('getDisplayTemplatesHtml');
|
return this._invoke('getDisplayTemplatesHtml');
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user