Skip to content

Commit c822996

Browse files
committed
[golf] don't fallback to execCommand for clipboard
1 parent 65546d6 commit c822996

File tree

2 files changed

+3
-109
lines changed

2 files changed

+3
-109
lines changed

src/apps/golf/components/PermalinkDisplay.tsx

Lines changed: 3 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -16,32 +16,9 @@ const PermalinkDisplay = ({ label, url, onCopy }: PermalinkDisplayProps) => {
1616
setCopyStatus('copying')
1717

1818
try {
19-
// Try modern Clipboard API first
20-
if (navigator.clipboard && window.isSecureContext) {
21-
await navigator.clipboard.writeText(url)
22-
setCopyStatus('success')
23-
onCopy?.()
24-
} else {
25-
// Fallback method for older browsers or non-secure contexts
26-
const textArea = document.createElement('textarea')
27-
textArea.value = url
28-
textArea.style.position = 'fixed'
29-
textArea.style.left = '-999999px'
30-
textArea.style.top = '-999999px'
31-
document.body.appendChild(textArea)
32-
textArea.focus()
33-
textArea.select()
34-
35-
const successful = document.execCommand('copy')
36-
document.body.removeChild(textArea)
37-
38-
if (successful) {
39-
setCopyStatus('success')
40-
onCopy?.()
41-
} else {
42-
throw new Error('Fallback copy method failed')
43-
}
44-
}
19+
await navigator.clipboard.writeText(url)
20+
setCopyStatus('success')
21+
onCopy?.()
4522
} catch (error) {
4623
console.error('Failed to copy permalink:', error)
4724
setCopyStatus('error')

src/apps/golf/components/__tests__/PermalinkDisplay.test.tsx

Lines changed: 0 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -31,12 +31,6 @@ describe('PermalinkDisplay', () => {
3131
value: true,
3232
writable: true
3333
})
34-
35-
// Mock document.execCommand
36-
Object.defineProperty(document, 'execCommand', {
37-
value: mockExecCommand,
38-
writable: true
39-
})
4034
})
4135

4236
afterEach(() => {
@@ -128,83 +122,6 @@ describe('PermalinkDisplay', () => {
128122
})
129123
})
130124

131-
describe('Copy Functionality - Fallback Method', () => {
132-
it('attempts fallback method when clipboard API is not available', async () => {
133-
// Simulate no clipboard API or insecure context
134-
Object.defineProperty(navigator, 'clipboard', {
135-
value: undefined,
136-
writable: true
137-
})
138-
Object.defineProperty(window, 'isSecureContext', {
139-
value: false,
140-
writable: true
141-
})
142-
143-
mockExecCommand.mockReturnValue(true)
144-
145-
render(<PermalinkDisplay {...defaultProps} />)
146-
147-
const copyButton = screen.getByRole('button', { name: /copy share room/i })
148-
fireEvent.click(copyButton)
149-
150-
// Should attempt to use execCommand
151-
await waitFor(() => {
152-
expect(mockExecCommand).toHaveBeenCalledWith('copy')
153-
})
154-
155-
await waitFor(() => {
156-
expect(copyButton).toHaveTextContent('Copied!')
157-
})
158-
})
159-
160-
it('handles fallback method failure', async () => {
161-
// Simulate no clipboard API or insecure context
162-
Object.defineProperty(navigator, 'clipboard', {
163-
value: undefined,
164-
writable: true
165-
})
166-
Object.defineProperty(window, 'isSecureContext', {
167-
value: false,
168-
writable: true
169-
})
170-
171-
mockExecCommand.mockReturnValue(false)
172-
173-
render(<PermalinkDisplay {...defaultProps} />)
174-
175-
const copyButton = screen.getByRole('button', { name: /copy share room/i })
176-
fireEvent.click(copyButton)
177-
178-
await waitFor(() => {
179-
expect(copyButton).toHaveTextContent('Failed')
180-
})
181-
})
182-
183-
it('calls onCopy callback when fallback succeeds', async () => {
184-
// Simulate no clipboard API or insecure context
185-
Object.defineProperty(navigator, 'clipboard', {
186-
value: undefined,
187-
writable: true
188-
})
189-
Object.defineProperty(window, 'isSecureContext', {
190-
value: false,
191-
writable: true
192-
})
193-
194-
const onCopy = vi.fn()
195-
mockExecCommand.mockReturnValue(true)
196-
197-
render(<PermalinkDisplay {...defaultProps} onCopy={onCopy} />)
198-
199-
const copyButton = screen.getByRole('button', { name: /copy share room/i })
200-
fireEvent.click(copyButton)
201-
202-
await waitFor(() => {
203-
expect(onCopy).toHaveBeenCalled()
204-
})
205-
})
206-
})
207-
208125
describe('Button States and Interactions', () => {
209126
it('disables button while copying', async () => {
210127
mockClipboard.writeText.mockImplementation(() => new Promise(resolve => setTimeout(resolve, 100)))

0 commit comments

Comments
 (0)