2020-10-02 15:10:00 +00:00
|
|
|
import {get as getBrowserGlobals} from 'app/client/lib/browserGlobals';
|
|
|
|
|
|
|
|
const G = getBrowserGlobals('document', 'window');
|
|
|
|
|
|
|
|
/**
|
2023-04-28 09:20:28 +00:00
|
|
|
* Copy text or data to the clipboard.
|
2020-10-02 15:10:00 +00:00
|
|
|
*/
|
2023-04-28 09:20:28 +00:00
|
|
|
export async function copyToClipboard(data: string | ClipboardItem) {
|
|
|
|
if (typeof data === 'string') {
|
|
|
|
await copyTextToClipboard(data);
|
|
|
|
} else {
|
|
|
|
await copyDataToClipboard(data);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Copy text to the clipboard.
|
|
|
|
*/
|
|
|
|
async function copyTextToClipboard(txt: string) {
|
2020-10-02 15:10:00 +00:00
|
|
|
// If present and we have permission to use it, the navigator.clipboard interface
|
|
|
|
// is convenient. This method works in non-headless tests, and regular chrome
|
|
|
|
// and firefox.
|
|
|
|
if (G.window.navigator && G.window.navigator.clipboard && G.window.navigator.clipboard.writeText) {
|
|
|
|
try {
|
|
|
|
await G.window.navigator.clipboard.writeText(txt);
|
|
|
|
return;
|
|
|
|
} catch (e) {
|
|
|
|
// no joy, try another way.
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// Otherwise fall back on document.execCommand('copy'), which requires text in
|
|
|
|
// the dom to be selected. Implementation here based on:
|
|
|
|
// https://hackernoon.com/copying-text-to-clipboard-with-javascript-df4d4988697f
|
|
|
|
// This fallback takes effect at least in headless tests, and in Safari.
|
|
|
|
const stash = G.document.createElement('textarea');
|
|
|
|
stash.value = txt;
|
|
|
|
stash.setAttribute('readonly', '');
|
|
|
|
stash.style.position = 'absolute';
|
|
|
|
stash.style.left = '-10000px';
|
|
|
|
G.document.body.appendChild(stash);
|
|
|
|
const selection = G.document.getSelection().rangeCount > 0 && G.document.getSelection().getRangeAt(0);
|
|
|
|
stash.select();
|
|
|
|
G.document.execCommand('copy');
|
|
|
|
G.document.body.removeChild(stash);
|
|
|
|
if (selection) {
|
|
|
|
G.document.getSelection().removeAllRanges();
|
|
|
|
G.document.getSelection().addRange(selection);
|
|
|
|
}
|
|
|
|
}
|
2023-04-28 09:20:28 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Copy data to the clipboard.
|
|
|
|
*/
|
|
|
|
async function copyDataToClipboard(data: ClipboardItem) {
|
|
|
|
if (!G.window.navigator?.clipboard?.write) {
|
|
|
|
throw new Error('navigator.clipboard.write is not supported on this browser');
|
|
|
|
}
|
|
|
|
|
|
|
|
await G.window.navigator.clipboard.write([data]);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Read text from the clipboard.
|
|
|
|
*/
|
|
|
|
export function readTextFromClipboard(): Promise<string> {
|
|
|
|
if (!G.window.navigator?.clipboard?.readText) {
|
|
|
|
throw new Error('navigator.clipboard.readText is not supported on this browser');
|
|
|
|
}
|
|
|
|
|
|
|
|
return G.window.navigator.clipboard.readText();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Read data from the clipboard.
|
|
|
|
*/
|
|
|
|
export function readDataFromClipboard(): Promise<ClipboardItem[]> {
|
|
|
|
if (!G.window.navigator?.clipboard?.read) {
|
|
|
|
throw new Error('navigator.clipboard.read is not supported on this browser');
|
|
|
|
}
|
|
|
|
|
|
|
|
return G.window.navigator.clipboard.read();
|
|
|
|
}
|