Implement copy for non-standard browsers. Fix flaky embed copy

This commit is contained in:
James Grugett 2022-03-21 16:44:11 -05:00
parent cf2b54ab8d
commit 033ff3e150
2 changed files with 46 additions and 6 deletions

View File

@ -4,6 +4,7 @@ import { Menu, Transition } from '@headlessui/react'
import { Contract } from '../../common/contract'
import { contractPath } from '../lib/firebase/contracts'
import { DOMAIN } from '../../common/envs/constants'
import { copyToClipboard } from '../lib/util/copy'
export function ShareEmbedButton(props: { contract: Contract }) {
const { contract } = props
@ -14,15 +15,16 @@ export function ShareEmbedButton(props: { contract: Contract }) {
const embedCode = `<iframe width="560" height="405" src="${src}" title="${title}" frameborder="0"></iframe>`
if (navigator.clipboard) navigator.clipboard.writeText(embedCode)
copyToClipboard(embedCode)
}
return (
<Menu as="div" className="relative z-40 flex-shrink-0" onClick={copyEmbed}>
<Menu.Button
className="btn btn-xs btn-outline normal-case hover:bg-white hover:text-neutral"
onClick={copyEmbed}
>
<Menu
as="div"
className="relative z-40 flex-shrink-0"
onMouseUp={copyEmbed}
>
<Menu.Button className="btn btn-xs btn-outline normal-case hover:bg-white hover:text-neutral">
<CodeIcon className="w-4 h-4 text-gray-500 mr-1.5" aria-hidden="true" />
Embed
</Menu.Button>

38
web/lib/util/copy.ts Normal file
View File

@ -0,0 +1,38 @@
// From: https://stackoverflow.com/a/33928558/1592933
// Copies a string to the clipboard. Must be called from within an
// event handler such as click. May return false if it failed, but
// this is not always possible. Browser support for Chrome 43+,
// Firefox 42+, Safari 10+, Edge and Internet Explorer 10+.
// Internet Explorer: The clipboard feature may be disabled by
// an administrator. By default a prompt is shown the first
// time the clipboard is used (per session).
export function copyToClipboard(text: string) {
if (navigator.clipboard) {
navigator.clipboard.writeText(text)
} else if (
(window as any).clipboardData &&
(window as any).clipboardData.setData
) {
console.log('copy 2')
// Internet Explorer-specific code path to prevent textarea being shown while dialog is visible.
return (window as any).clipboardData.setData('Text', text)
} else if (
document.queryCommandSupported &&
document.queryCommandSupported('copy')
) {
console.log('copy 3')
var textarea = document.createElement('textarea')
textarea.textContent = text
textarea.style.position = 'fixed' // Prevent scrolling to bottom of page in Microsoft Edge.
document.body.appendChild(textarea)
textarea.select()
try {
return document.execCommand('copy') // Security exception may be thrown by some browsers.
} catch (ex) {
console.warn('Copy to clipboard failed.', ex)
return prompt('Copy to clipboard: Ctrl+C, Enter', text)
} finally {
document.body.removeChild(textarea)
}
}
}