git-ents.gitmain
⌘K
foforge
commit aa01840
fix: fall back to execCommand and report failure in copy.js

navigator.clipboard.writeText was called unconditionally with no .catch(), so a rejected promise silently did nothing, and navigator.clipboard is undefined outside a secure context (plain HTTP), throwing instead of copying at all. copyText now falls back to a hidden-textarea execCommand("copy") when the Clipboard API is unavailable, and both button handlers show Copy failed on rejection instead of leaving the click looking like it did nothing.

Assisted-by: Claude:claude-sonnet-5

Joseph D. Carpinelli · 1 month ago

Reviews

No reviews of this commit yet — record a verdict below.

Start a review

verdict

crates/git-ents-server/src/web/copy.js @@ -1,9 +1,41 @@ +function copyText(text) { + if (navigator.clipboard && navigator.clipboard.writeText) { + return navigator.clipboard.writeText(text); + } + return new Promise((resolve, reject) => { + const textarea = document.createElement('textarea'); + textarea.value = text; + textarea.style.position = 'fixed'; + textarea.style.opacity = '0'; + document.body.appendChild(textarea); + textarea.focus(); + textarea.select(); + try { + const ok = document.execCommand('copy'); + document.body.removeChild(textarea); + if (ok) { + resolve(); + } else { + reject(new Error('execCommand copy failed')); + } + } catch (err) { + document.body.removeChild(textarea); + reject(err); + } + }); +} + document.querySelectorAll('[data-copy]').forEach((btn) => { btn.addEventListener('click', () => { - navigator.clipboard.writeText(btn.dataset.copy).then(() => { - const label = btn.textContent; - btn.textContent = 'Copied'; - setTimeout(() => { btn.textContent = label; }, 1200); - }); + const label = btn.textContent; + copyText(btn.dataset.copy) + .then(() => { + btn.textContent = 'Copied'; + setTimeout(() => { btn.textContent = label; }, 1200); + }) + .catch(() => { + btn.textContent = 'Copy failed'; + setTimeout(() => { btn.textContent = label; }, 1200); + }); }); });