e1bf9ecb22
Auto Tag Develop / tag (push) Successful in 7s
navigator.clipboard n'est disponible qu'en secure context (HTTPS/localhost), ce qui cassait la copie en prod HTTP. Ajout d'un utilitaire copyToClipboard avec fallback textarea + execCommand, appliqué au viewer Markdown, au token API du profil et au nom de branche Git.
41 lines
1.4 KiB
TypeScript
41 lines
1.4 KiB
TypeScript
/**
|
|
* Copy text to the clipboard with a fallback for non-secure contexts.
|
|
*
|
|
* `navigator.clipboard` is only available in secure contexts (HTTPS or
|
|
* localhost). On a plain HTTP origin (e.g. an internal/prod server without
|
|
* TLS) the API is missing, so we fall back to the legacy
|
|
* `document.execCommand('copy')` using a temporary off-screen textarea.
|
|
*
|
|
* @returns `true` if the copy succeeded, `false` otherwise.
|
|
*/
|
|
export async function copyToClipboard(text: string): Promise<boolean> {
|
|
// Preferred path: available in secure contexts (HTTPS / localhost).
|
|
if (navigator.clipboard && window.isSecureContext) {
|
|
try {
|
|
await navigator.clipboard.writeText(text)
|
|
return true
|
|
} catch {
|
|
// Fall through to the legacy fallback below.
|
|
}
|
|
}
|
|
|
|
// Legacy fallback: works on plain HTTP origins.
|
|
try {
|
|
const textarea = document.createElement('textarea')
|
|
textarea.value = text
|
|
// Keep it out of view and prevent layout shift / scrolling.
|
|
textarea.style.position = 'fixed'
|
|
textarea.style.top = '-9999px'
|
|
textarea.style.left = '-9999px'
|
|
textarea.setAttribute('readonly', '')
|
|
document.body.appendChild(textarea)
|
|
textarea.select()
|
|
textarea.setSelectionRange(0, text.length)
|
|
const ok = document.execCommand('copy')
|
|
document.body.removeChild(textarea)
|
|
return ok
|
|
} catch {
|
|
return false
|
|
}
|
|
}
|