mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-03-13 09:00:16 +00:00
fix: skip node metadata paste when media node is selected (#9773)
## Summary - When a media node (LoadImage/LoadAudio/LoadVideo) is selected and the clipboard contains stale node metadata from a prior Ctrl+C, pasting skips the node-metadata deserialization so that the paste falls through to litegraph's default handler instead of incorrectly pasting the old copied node. - Fixes Comfy-Org/ComfyUI#12896 ## Root Cause The paste handler in `usePaste.ts` checks clipboard `text/html` for `data-metadata` (serialized node data) **before** falling through to litegraph's default paste. When a user copies a node, then copies a web image, the browser clipboard may retain the old `data-metadata` in `text/html` while the image data is not available as a `DataTransferItem` file. This causes the stale node to be pasted instead of the image. ## Fix Skip `pasteClipboardItems()` when a media node is selected, allowing the paste to fall through to litegraph's default handler which can handle the clipboard content appropriately. ## Test plan - [x] Added unit test verifying node metadata paste is skipped when media node is selected - [x] Manual: Copy a node → copy a web image → select LoadImage node → Ctrl+V → verify image is pasted, not the node ## AS IS https://github.com/user-attachments/assets/210d77d3-5c49-4e38-91b7-b9d9ea0e7ca0 ## TO BE https://github.com/user-attachments/assets/b68e4582-0c57-48b8-9ed9-0b3243bb1554 🤖 Generated with [Claude Code](https://claude.com/claude-code) ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-9773-fix-skip-node-metadata-paste-when-media-node-is-selected-3216d73d3650814d92dadcd0c0ec79c7) by [Unito](https://www.unito.io) --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> Co-authored-by: GitHub Action <action@github.com>
This commit is contained in:
@@ -595,6 +595,34 @@ describe('usePaste', () => {
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
it('should skip node metadata paste when a media node is selected', async () => {
|
||||
const mockNode = createMockLGraphNode({
|
||||
is_selected: true,
|
||||
pasteFile: vi.fn(),
|
||||
pasteFiles: vi.fn()
|
||||
})
|
||||
mockCanvas.current_node = mockNode
|
||||
vi.mocked(isImageNode).mockReturnValue(true)
|
||||
|
||||
usePaste()
|
||||
|
||||
const nodeData = { nodes: [{ type: 'KSampler' }] }
|
||||
const encoded = btoa(JSON.stringify(nodeData))
|
||||
const html = `<div data-metadata="${encoded}"></div>`
|
||||
|
||||
const dataTransfer = new DataTransfer()
|
||||
dataTransfer.setData('text/html', html)
|
||||
dataTransfer.setData('text/plain', 'some text')
|
||||
|
||||
const event = new ClipboardEvent('paste', { clipboardData: dataTransfer })
|
||||
document.dispatchEvent(event)
|
||||
|
||||
await vi.waitFor(() => {
|
||||
expect(mockCanvas._deserializeItems).not.toHaveBeenCalled()
|
||||
expect(mockCanvas.pasteFromClipboard).toHaveBeenCalled()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('cloneDataTransfer', () => {
|
||||
|
||||
@@ -229,7 +229,10 @@ export const usePaste = () => {
|
||||
return
|
||||
}
|
||||
}
|
||||
if (pasteClipboardItems(data)) return
|
||||
|
||||
const isMediaNodeSelected =
|
||||
isImageNodeSelected || isVideoNodeSelected || isAudioNodeSelected
|
||||
if (!isMediaNodeSelected && pasteClipboardItems(data)) return
|
||||
|
||||
// No image found. Look for node data
|
||||
data = data.getData('text/plain')
|
||||
|
||||
Reference in New Issue
Block a user