Skip to content

Commit 71fa14f

Browse files
authored
fix: resolve clipboard.writeText failure under HTTP protocol (#12936)
1 parent 8dd1873 commit 71fa14f

File tree

2 files changed

+37
-1
lines changed

2 files changed

+37
-1
lines changed

web/app/components/develop/code.tsx

+2-1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import {
1010
import { Tab } from '@headlessui/react'
1111
import { Tag } from './tag'
1212
import classNames from '@/utils/classnames'
13+
import { writeTextToClipboard } from '@/utils/clipboard'
1314

1415
const languageNames = {
1516
js: 'JavaScript',
@@ -71,7 +72,7 @@ function CopyButton({ code }: { code: string }) {
7172
: 'bg-white/5 hover:bg-white/7.5 dark:bg-white/2.5 dark:hover:bg-white/5',
7273
)}
7374
onClick={() => {
74-
window.navigator.clipboard.writeText(code).then(() => {
75+
writeTextToClipboard(code).then(() => {
7576
setCopyCount(count => count + 1)
7677
})
7778
}}

web/utils/clipboard.ts

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
export async function writeTextToClipboard(text: string): Promise<void> {
2+
if (navigator.clipboard && navigator.clipboard.writeText)
3+
return navigator.clipboard.writeText(text)
4+
5+
return fallbackCopyTextToClipboard(text)
6+
}
7+
8+
async function fallbackCopyTextToClipboard(text: string): Promise<void> {
9+
const textArea = document.createElement('textarea')
10+
textArea.value = text
11+
textArea.style.position = 'fixed' // Avoid scrolling to bottom
12+
document.body.appendChild(textArea)
13+
textArea.focus()
14+
textArea.select()
15+
try {
16+
const successful = document.execCommand('copy')
17+
if (successful)
18+
return Promise.resolve()
19+
20+
return Promise.reject(new Error('document.execCommand failed'))
21+
}
22+
catch (err) {
23+
return Promise.reject(convertAnyToError(err))
24+
}
25+
finally {
26+
document.body.removeChild(textArea)
27+
}
28+
}
29+
30+
function convertAnyToError(err: any): Error {
31+
if (err instanceof Error)
32+
return err
33+
34+
return new Error(`Caught: ${String(err)}`)
35+
}

0 commit comments

Comments
 (0)