Skip to content

Commit e56925d

Browse files
committed
fix: clipboard copy on non-secure context
Signed-off-by: Pedro Lamas <pedrolamas@gmail.com>
1 parent 3f1d1be commit e56925d

File tree

2 files changed

+59
-10
lines changed

2 files changed

+59
-10
lines changed

src/components/ui/AppTextFieldWithCopy.vue

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@
3838

3939
<script lang="ts">
4040
import { Component, VModel, Vue } from 'vue-property-decorator'
41+
import clipboardCopy from '@/util/clipboard-copy'
42+
import sleep from '@/util/sleep'
4143
4244
@Component({
4345
inheritAttrs: false
@@ -47,19 +49,23 @@ export default class AppTextFieldWithCopy extends Vue {
4749
inputValue!: unknown
4850
4951
hasCopied = false
52+
abortController: AbortController | null = null
5053
51-
handleCopy () {
52-
if (
53-
this.inputValue &&
54-
navigator.clipboard
55-
) {
56-
navigator.clipboard.writeText(this.inputValue.toString())
54+
async handleCopy () {
55+
if (this.inputValue) {
56+
if (await clipboardCopy(this.inputValue.toString(), this.$el)) {
57+
this.abortController?.abort()
5758
58-
this.hasCopied = true
59+
this.hasCopied = true
5960
60-
setTimeout(() => {
61-
this.hasCopied = false
62-
}, 2000)
61+
try {
62+
const abortController = this.abortController = new AbortController()
63+
64+
await sleep(2000, abortController.signal)
65+
66+
this.hasCopied = false
67+
} catch {}
68+
}
6369
}
6470
}
6571
}

src/util/clipboard-copy.ts

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import consola from 'consola'
2+
3+
const clipboardCopy = async (text: string, parentElement?: Element): Promise<boolean> => {
4+
if (navigator.clipboard) {
5+
try {
6+
await navigator.clipboard.writeText(text)
7+
8+
return true
9+
} catch (e) {
10+
consola.error('Error while copying text to clipboard', e)
11+
12+
return false
13+
}
14+
}
15+
16+
parentElement ??= document.body
17+
18+
const textarea = document.createElement('textarea')
19+
20+
textarea.value = text
21+
textarea.style.position = 'absolute'
22+
textarea.style.top = '0'
23+
textarea.style.left = '0'
24+
textarea.style.zIndex = '100000'
25+
textarea.style.opacity = '0'
26+
27+
parentElement.appendChild(textarea)
28+
29+
try {
30+
textarea.focus()
31+
textarea.select()
32+
33+
return document.execCommand('copy')
34+
} catch (e) {
35+
consola.error('Error while copying text to clipboard', e)
36+
37+
return false
38+
} finally {
39+
parentElement.removeChild(textarea)
40+
}
41+
}
42+
43+
export default clipboardCopy

0 commit comments

Comments
 (0)