btcpayserver/BTCPayServer/wwwroot/js/copy-to-clipboard.js
d11n e6c68dc5bc
Checkout: Fix modal iframe clipboard permissions (#4453)
* Checkout: Fix modal iframe clipboard permissions 

WebKit-based browser require a [permissions policy](https://web.dev/async-clipboard/#permissions-policy-integration) to be set on the iframe element. See the discussions [here](https://github.com/btcpayserver/btcpayserver/discussions/4308#discussioncomment-4399342) and [on Mattermost](https://chat.btcpayserver.org/btcpayserver/pl/z7kdgidcjtnd8f5zs5648t1dhe).

* Updates from code review
2022-12-20 22:54:47 +09:00

60 lines
2.4 KiB
JavaScript

function confirmCopy(el, message) {
if (!el.dataset.clipboardInitial) {
el.dataset.clipboardInitial = el.innerHTML;
el.style.minWidth = el.getBoundingClientRect().width + 'px';
}
el.innerHTML = `<span class="text-success">${message}</span>`;
setTimeout(function () {
el.innerHTML = el.dataset.clipboardInitial;
}, 2500);
}
window.copyToClipboard = async function (e, data) {
e.preventDefault();
const item = e.target.closest('[data-clipboard]') || e.target.closest('[data-clipboard-target]') || e.target;
const confirm = item.dataset.clipboardConfirmElement
? document.getElementById(item.dataset.clipboardConfirmElement) || item
: item.querySelector('[data-clipboard-confirm]') || item;
const message = confirm.getAttribute('data-clipboard-confirm') || 'Copied';
// Check compatibility and permissions:
// https://web.dev/async-clipboard/#security-and-permissions
let hasPermission = true;
if (navigator.clipboard && navigator.permissions) {
try {
const permissionStatus = await navigator.permissions.query({ name: 'clipboard-write', allowWithoutGesture: false });
hasPermission = permissionStatus.state === 'granted';
} catch (err) {}
}
if (navigator.clipboard && hasPermission) {
await navigator.clipboard.writeText(data);
confirmCopy(confirm, message);
} else {
const copyEl = document.createElement('textarea');
copyEl.style.position = 'absolute';
copyEl.style.opacity = '0';
copyEl.value = data;
document.body.appendChild(copyEl);
copyEl.select();
document.execCommand('copy');
copyEl.remove();
confirmCopy(confirm, message);
}
item.blur();
}
window.copyUrlToClipboard = function (e) {
window.copyToClipboard(e, window.location)
}
document.addEventListener("DOMContentLoaded", function () {
delegate('click', '[data-clipboard]', function (e) {
const data = e.target.closest('[data-clipboard]').getAttribute('data-clipboard')
window.copyToClipboard(e, data)
})
delegate('click', '[data-clipboard-target]', function (e) {
const selector = e.target.closest('[data-clipboard-target]').getAttribute('data-clipboard-target')
const target = document.querySelector(selector)
const data = target.innerText
window.copyToClipboard(e, data)
})
})