forked from QuantumNous/new-api
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcopy-to-clipboard.ts
More file actions
103 lines (91 loc) 路 3.02 KB
/
Copy pathcopy-to-clipboard.ts
File metadata and controls
103 lines (91 loc) 路 3.02 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
/*
Copyright (C) 2023-2026 QuantumNous
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
For commercial licensing, please contact support@quantumnous.com
*/
/**
* Fallback copy method using document.execCommand (works in HTTP)
*/
function fallbackCopyToClipboard(text: string): boolean {
const textArea = document.createElement('textarea')
textArea.value = text
// Make the textarea out of viewport
textArea.style.position = 'fixed'
textArea.style.left = '-999999px'
textArea.style.top = '-999999px'
textArea.style.opacity = '0'
textArea.setAttribute('readonly', '')
document.body.appendChild(textArea)
try {
// Select the text
textArea.focus()
textArea.select()
// For iOS devices
const range = document.createRange()
range.selectNodeContents(textArea)
const selection = window.getSelection()
if (selection) {
selection.removeAllRanges()
selection.addRange(range)
}
textArea.setSelectionRange(0, text.length)
// Execute copy command
const successful = document.execCommand('copy')
document.body.removeChild(textArea)
// Clear selection ranges for better UX
const selectionAfter = window.getSelection()
if (selectionAfter) {
selectionAfter.removeAllRanges()
}
return successful
} catch (err) {
// eslint-disable-next-line no-console
console.error('Fallback copy failed:', err)
document.body.removeChild(textArea)
return false
}
}
/**
* Copy text to clipboard with fallback support for HTTP environments
*
* @param text - The text to copy
* @returns Promise that resolves to true if successful, false otherwise
*
* @example
* ```ts
* const success = await copyToClipboard('Hello, World!')
* if (success) {
* console.log('Copied successfully')
* }
* ```
*/
export async function copyToClipboard(text: string): Promise<boolean> {
// Guard for SSR / non-browser environments
if (typeof window === 'undefined' || typeof document === 'undefined') {
return false
}
// Try modern clipboard API first (HTTPS required)
if (navigator?.clipboard?.writeText) {
try {
await navigator.clipboard.writeText(text)
return true
} catch (error) {
// eslint-disable-next-line no-console
console.warn('Clipboard API failed, trying fallback method:', error)
// Try fallback method
return fallbackCopyToClipboard(text)
}
} else {
// Use fallback method directly
return fallbackCopyToClipboard(text)
}
}