|
83 | 83 | .btn-clear.confirm:hover { |
84 | 84 | background-color: var(--vscode-button-destructiveHoverBackground); |
85 | 85 | } |
| 86 | + .btn-copy { |
| 87 | + background: none; |
| 88 | + border: none; |
| 89 | + cursor: pointer; |
| 90 | + color: var(--vscode-button-foreground); |
| 91 | + background-color: var(--vscode-button-secondaryBackground); |
| 92 | + padding: 2px 6px; |
| 93 | + border-radius: 2px; |
| 94 | + font-size: 11px; |
| 95 | + display: flex; |
| 96 | + align-items: center; |
| 97 | + gap: 4px; |
| 98 | + } |
| 99 | + .btn-copy:hover { |
| 100 | + background-color: var(--vscode-button-secondaryHoverBackground); |
| 101 | + } |
| 102 | + .btn-copy:focus { |
| 103 | + outline: 1px solid var(--vscode-focusBorder); |
| 104 | + outline-offset: 1px; |
| 105 | + } |
| 106 | + .btn-copy.success { |
| 107 | + background-color: var(--vscode-charts-green); |
| 108 | + color: white; |
| 109 | + } |
86 | 110 | </style> |
87 | 111 | </head> |
88 | 112 | <body> |
|
95 | 119 | <div class="footer"> |
96 | 120 | <span id="char-count" class="char-count" aria-live="polite">0 chars</span> |
97 | 121 | <div class="actions"> |
| 122 | + <button id="btn-copy" class="btn-copy" aria-label="Copy to Clipboard" title="Copy content"> |
| 123 | + Copy |
| 124 | + </button> |
98 | 125 | <button id="btn-clear" class="btn-clear" aria-label="Clear Scratchpad" title="Clear all content"> |
99 | 126 | Clear |
100 | 127 | </button> |
|
105 | 132 | const textarea = document.getElementById('scratchpad'); |
106 | 133 | const charCount = document.getElementById('char-count'); |
107 | 134 | const btnClear = document.getElementById('btn-clear'); |
| 135 | + const btnCopy = document.getElementById('btn-copy'); |
108 | 136 | let clearTimeoutId; |
109 | 137 |
|
110 | 138 | // Debounce function |
|
169 | 197 |
|
170 | 198 | textarea.addEventListener('focus', resetClearButton); |
171 | 199 |
|
| 200 | + btnCopy.addEventListener('click', async () => { |
| 201 | + const content = textarea.value; |
| 202 | + if (!content) return; |
| 203 | + |
| 204 | + try { |
| 205 | + await navigator.clipboard.writeText(content); |
| 206 | + const originalText = btnCopy.textContent; |
| 207 | + btnCopy.textContent = 'Copied!'; |
| 208 | + btnCopy.classList.add('success'); |
| 209 | + btnCopy.setAttribute('aria-label', 'Content copied successfully'); |
| 210 | + |
| 211 | + setTimeout(() => { |
| 212 | + btnCopy.textContent = originalText; |
| 213 | + btnCopy.classList.remove('success'); |
| 214 | + btnCopy.setAttribute('aria-label', 'Copy to Clipboard'); |
| 215 | + }, 2000); |
| 216 | + } catch (err) { |
| 217 | + console.error('Failed to copy:', err); |
| 218 | + const originalText = btnCopy.textContent; |
| 219 | + btnCopy.textContent = 'Error'; |
| 220 | + setTimeout(() => { |
| 221 | + btnCopy.textContent = originalText; |
| 222 | + }, 2000); |
| 223 | + } |
| 224 | + }); |
| 225 | + |
172 | 226 | // 接收来自扩展的消息 |
173 | 227 | window.addEventListener('message', (event) => { |
174 | 228 | const message = event.data; |
|
0 commit comments