fix: resolve clipboard.writeText failure under HTTP protocol (#12936)

This commit is contained in:
le0zh 2025-01-22 15:18:23 +08:00 committed by GitHub
parent 8dd1873e76
commit 71fa14f791
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 37 additions and 1 deletions

View File

@ -10,6 +10,7 @@ import {
import { Tab } from '@headlessui/react'
import { Tag } from './tag'
import classNames from '@/utils/classnames'
import { writeTextToClipboard } from '@/utils/clipboard'
const languageNames = {
js: 'JavaScript',
@ -71,7 +72,7 @@ function CopyButton({ code }: { code: string }) {
: 'bg-white/5 hover:bg-white/7.5 dark:bg-white/2.5 dark:hover:bg-white/5',
)}
onClick={() => {
window.navigator.clipboard.writeText(code).then(() => {
writeTextToClipboard(code).then(() => {
setCopyCount(count => count + 1)
})
}}

35
web/utils/clipboard.ts Normal file
View File

@ -0,0 +1,35 @@
export async function writeTextToClipboard(text: string): Promise<void> {
if (navigator.clipboard && navigator.clipboard.writeText)
return navigator.clipboard.writeText(text)
return fallbackCopyTextToClipboard(text)
}
async function fallbackCopyTextToClipboard(text: string): Promise<void> {
const textArea = document.createElement('textarea')
textArea.value = text
textArea.style.position = 'fixed' // Avoid scrolling to bottom
document.body.appendChild(textArea)
textArea.focus()
textArea.select()
try {
const successful = document.execCommand('copy')
if (successful)
return Promise.resolve()
return Promise.reject(new Error('document.execCommand failed'))
}
catch (err) {
return Promise.reject(convertAnyToError(err))
}
finally {
document.body.removeChild(textArea)
}
}
function convertAnyToError(err: any): Error {
if (err instanceof Error)
return err
return new Error(`Caught: ${String(err)}`)
}