Files
ark-stronghold-protocol/public/js/ui/clipboard.js
T

33 lines
1.4 KiB
JavaScript

// Shared by invite links, loadouts and settings exports, including LAN / insecure contexts.
/** @param {string} text @returns {Promise<boolean>} */
export async function copyText(text) {
try {
if (globalThis.navigator?.clipboard && globalThis.isSecureContext) {
await navigator.clipboard.writeText(text);
return true;
}
} catch { /* use the selected-text fallback */ }
let ta, prev;
try {
prev = document.activeElement;
ta = document.createElement('textarea');
ta.value = text;
ta.setAttribute('readonly', '');
// Keep the temporary selection inside the active focus trap (#433). The 16 px readonly field avoids iOS zoom
// and its keyboard; do not disable the dialog's focus protection or copy a selection redirected to another field.
ta.style.cssText = 'position:fixed;left:-9999px;top:0;opacity:0;font-size:16px';
const host = prev?.closest?.('[role="dialog"][aria-modal="true"], .guide') || document.body;
host.appendChild(ta);
ta.focus({ preventScroll: true });
ta.select();
ta.setSelectionRange(0, ta.value.length); // iOS Safari ignores select() alone
if (document.activeElement !== ta || ta.selectionStart !== 0 || ta.selectionEnd !== ta.value.length) return false;
return !!document.execCommand('copy');
} catch {
return false;
} finally {
ta?.remove();
if (prev?.isConnected) prev.focus?.({ preventScroll: true });
}
}