mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-02-03 22:59:14 +00:00
## Summary Use TextEncoder/TextDecoder for UTF-8 safe base64 encoding/decoding When copying nodes containing non-Latin1 characters (e.g., Chinese characters in localized_name field), btoa() throws an error: InvalidCharacterError: Failed to execute 'btoa' on 'Window': The string to be encoded contains characters outside of the Latin1 range. The copy operation saved data to localStorage successfully, but failed to write to the browser clipboard. On paste, the browser clipboard still contained old data, causing the wrong node to be pasted. <!-- Fixes #ISSUE_NUMBER --> https://github.com/Comfy-Org/ComfyUI_frontend/issues/6993 https://github.com/Comfy-Org/ComfyUI_frontend/issues/5449 https://github.com/comfyanonymous/ComfyUI/issues/8481 ## Screenshots (if applicable) before https://github.com/user-attachments/assets/8abd9049-91bb-4200-8853-e26753376007 after https://github.com/user-attachments/assets/7d969f32-bb0f-4c7a-baa2-65d576a4eba2 ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-7103-fix-handle-Unicode-characters-in-clipboard-copy-paste-and-add-Paste-menu-option-2bd6d73d365081f39c40e7e7f832b97c) by [Unito](https://www.unito.io) --------- Co-authored-by: github-actions <github-actions@github.com>
43 lines
1.2 KiB
TypeScript
43 lines
1.2 KiB
TypeScript
import { useEventListener } from '@vueuse/core'
|
|
|
|
import { useCanvasStore } from '@/renderer/core/canvas/canvasStore'
|
|
import { shouldIgnoreCopyPaste } from '@/workbench/eventHelpers'
|
|
|
|
const clipboardHTMLWrapper = [
|
|
'<meta charset="utf-8"><div><span data-metadata="',
|
|
'"></span></div><span style="white-space:pre-wrap;">Text</span>'
|
|
]
|
|
|
|
/**
|
|
* Adds a handler on copy that serializes selected nodes to JSON
|
|
*/
|
|
export const useCopy = () => {
|
|
const canvasStore = useCanvasStore()
|
|
|
|
useEventListener(document, 'copy', (e) => {
|
|
if (shouldIgnoreCopyPaste(e.target)) {
|
|
// Default system copy
|
|
return
|
|
}
|
|
// copy nodes and clear clipboard
|
|
const canvas = canvasStore.canvas
|
|
if (canvas?.selectedItems) {
|
|
const serializedData = canvas.copyToClipboard()
|
|
// Use TextEncoder to handle Unicode characters properly
|
|
const base64Data = btoa(
|
|
String.fromCharCode(
|
|
...Array.from(new TextEncoder().encode(serializedData))
|
|
)
|
|
)
|
|
// clearData doesn't remove images from clipboard
|
|
e.clipboardData?.setData(
|
|
'text/html',
|
|
clipboardHTMLWrapper.join(base64Data)
|
|
)
|
|
e.preventDefault()
|
|
e.stopImmediatePropagation()
|
|
return false
|
|
}
|
|
})
|
|
}
|