65 lines
2.3 KiB
JavaScript
65 lines
2.3 KiB
JavaScript
export function clipboard(node, args) {
|
|
if (!window.isSecureContext) {
|
|
console.error('Clipboard action failed: app not running in secure context, see: https://developer.mozilla.org/en-US/docs/Web/API/Clipboard');
|
|
return;
|
|
}
|
|
const fireCopyCompleteEvent = () => {
|
|
node.dispatchEvent(new CustomEvent('copyComplete'));
|
|
};
|
|
const onClick = () => {
|
|
// Handle `data-clipboard` target based on object key
|
|
if (typeof args === 'object') {
|
|
// Element Inner HTML
|
|
if ('element' in args) {
|
|
const element = document.querySelector(`[data-clipboard="${args.element}"]`);
|
|
if (!element)
|
|
throw new Error(`Missing HTMLElement with an attribute of [data-clipboard="${args.element}"]`);
|
|
copyToClipboard(element.innerHTML, 'text/html').then(fireCopyCompleteEvent);
|
|
return;
|
|
}
|
|
// Form Input Value
|
|
if ('input' in args) {
|
|
const input = document.querySelector(`[data-clipboard="${args.input}"]`);
|
|
if (!input)
|
|
throw new Error(`Missing HTMLInputElement with an attribute of [data-clipboard="${args.input}"]`);
|
|
copyToClipboard(input.value).then(fireCopyCompleteEvent);
|
|
return;
|
|
}
|
|
}
|
|
// Handle everything else.
|
|
copyToClipboard(args).then(fireCopyCompleteEvent);
|
|
};
|
|
// Event Listener
|
|
node.addEventListener('click', onClick);
|
|
// Lifecycle
|
|
return {
|
|
update(newArgs) {
|
|
args = newArgs;
|
|
},
|
|
destroy() {
|
|
node.removeEventListener('click', onClick);
|
|
}
|
|
};
|
|
}
|
|
// Shared copy method
|
|
async function copyToClipboard(data, mimeType = 'text/plain') {
|
|
if (navigator.clipboard.write) {
|
|
await navigator.clipboard.write([
|
|
new ClipboardItem({
|
|
[mimeType]: new Blob([data], {
|
|
type: mimeType
|
|
}),
|
|
['text/plain']: new Blob([data], {
|
|
type: 'text/plain'
|
|
})
|
|
})
|
|
]);
|
|
}
|
|
else {
|
|
// fallback since .writeText has wider browser support
|
|
await new Promise((resolve) => {
|
|
resolve(navigator.clipboard.writeText(String(data)));
|
|
});
|
|
}
|
|
}
|