clipboard: fix copy/paste on Firefox (#4003)
So, here's what's up: - in Firefox, in version 127 `navigator.clipboard.write` support was added: https://developer.mozilla.org/en-US/docs/Mozilla/Firefox/Releases/127 - previously, Firefox was going down an if/else branch where `navigator.clipboard.write` isn't present, we use `navigator.clipboard.writeText` - Now, that Firefox is using the more common path, it now puts MIME-types on the clipboard, both HTML and plaintext. - _However_, on Firefox, it uses a different sanitization algorithm than the Blink engine does and it ends up scrubbing out the `<tldraw>` fake HTML tag: https://developer.chrome.com/docs/web-platform/unsanitized-html-async-clipboard - And, unfortunately, Firefox doesn't support setting `unsanitized` on the ClipboardItem: https://caniuse.com/?search=unsanitized - see also: https://developer.chrome.com/docs/web-platform/unsanitized-html-async-clipboard - So, the workaround here is to just use `<div data-tldraw>`. I'm not completely happy with it since the ending `</div>` tag assumes there's no nesting but ¯\\_(ツ)_/¯ it's fine in this case. - Plus, I wanted to make sure that in the wild no one was relying on this format being what was on the clipboard. Searching across all of GitHub it seems like it'll be fine. - The longer term, better solution, would be to use custom HTML formats: https://developer.chrome.com/blog/web-custom-formats-for-the-async-clipboard-api - However, of course, Firefox doesn't support that yet either 🙃 https://caniuse.com/?search=web%20custom%20format - see also: https://developer.chrome.com/blog/web-custom-formats-for-the-async-clipboard-api Talked with Alex, and what we could do down the line is copy SVG-in-HTML and then include `data-info` attributes that had data we could extract per shape. Something like that :handwavy: :) I'll hotfix this once it lands. ### Change Type <!-- ❗ Please select a 'Scope' label ❗️ --> - [x] `sdk` — Changes the tldraw SDK - [ ] `dotcom` — Changes the tldraw.com web app - [ ] `docs` — Changes to the documentation, examples, or templates. - [ ] `vs code` — Changes to the vscode plugin - [ ] `internal` — Does not affect user-facing stuff <!-- ❗ Please select a 'Type' label ❗️ --> - [x] `bugfix` — Bug fix - [ ] `feature` — New feature - [ ] `improvement` — Improving existing features - [ ] `chore` — Updating dependencies, other boring stuff - [ ] `galaxy brain` — Architectural changes - [ ] `tests` — Changes to any test code - [ ] `tools` — Changes to infrastructure, CI, internal scripts, debugging tools, etc. - [ ] `dunno` — I don't know ### Release Notes - Clipboard: fix copy/paste in Firefox 127+
This commit is contained in:
parent
2d2a7ea76f
commit
9850ef93e2
1 changed files with 3 additions and 3 deletions
|
@ -323,7 +323,7 @@ async function handleClipboardThings(editor: Editor, things: ClipboardThing[], p
|
||||||
|
|
||||||
thing.source.then((text) => {
|
thing.source.then((text) => {
|
||||||
// first, see if we can find tldraw content, which is JSON inside of an html comment
|
// first, see if we can find tldraw content, which is JSON inside of an html comment
|
||||||
const tldrawHtmlComment = text.match(/<tldraw[^>]*>(.*)<\/tldraw>/)?.[1]
|
const tldrawHtmlComment = text.match(/<div data-tldraw[^>]*>(.*)<\/div>/)?.[1]
|
||||||
|
|
||||||
if (tldrawHtmlComment) {
|
if (tldrawHtmlComment) {
|
||||||
try {
|
try {
|
||||||
|
@ -525,7 +525,7 @@ const handleNativeOrMenuCopy = async (editor: Editor) => {
|
||||||
.filter(isNonNull)
|
.filter(isNonNull)
|
||||||
|
|
||||||
if (navigator.clipboard?.write) {
|
if (navigator.clipboard?.write) {
|
||||||
const htmlBlob = new Blob([`<tldraw>${stringifiedClipboard}</tldraw>`], {
|
const htmlBlob = new Blob([`<div data-tldraw>${stringifiedClipboard}</div>`], {
|
||||||
type: 'text/html',
|
type: 'text/html',
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -546,7 +546,7 @@ const handleNativeOrMenuCopy = async (editor: Editor) => {
|
||||||
}),
|
}),
|
||||||
])
|
])
|
||||||
} else if (navigator.clipboard.writeText) {
|
} else if (navigator.clipboard.writeText) {
|
||||||
navigator.clipboard.writeText(`<tldraw>${stringifiedClipboard}</tldraw>`)
|
navigator.clipboard.writeText(`<div data-tldraw>${stringifiedClipboard}</div data-tldraw>`)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue