Skip to content

Restore Vue upload-node file drops and harden media drag/paste handling after #9463#10841

Open
xmarre wants to merge 16 commits intoComfy-Org:mainfrom
xmarre:codex/async-dnd-drop-bridge
Open

Restore Vue upload-node file drops and harden media drag/paste handling after #9463#10841
xmarre wants to merge 16 commits intoComfy-Org:mainfrom
xmarre:codex/async-dnd-drop-bridge

Conversation

@xmarre
Copy link
Copy Markdown

@xmarre xmarre commented Apr 3, 2026

Summary

This fixes the regression introduced in the v1.43.4 -> v1.43.5 window by #9463, where local file drops on Vue-rendered upload nodes (for example Load Image-style nodes) could highlight correctly on dragover but then escape the node path on drop.

The load-bearing failure was the graph/document handoff after Vue-node drop bubbling changed. Once some Vue-node drops were allowed to bubble, the document-level drop handler in app.ts could discard graph-canvas drops too early because they were already defaultPrevented, which prevented the graph/node recovery path from running.

In addition to the handoff fix, this PR also hardens the surrounding media drag/paste paths so they agree on file extraction and media-type detection when browsers expose dragged content through DataTransferItemList or empty MIME types.


Root cause

The broken invariant after #9463 was:

URI-only drops may bubble to the document handler, but real file drops over upload-capable Vue nodes must still be recoverable by the graph/node drop path.

What happened in practice was:

  1. A local file drag hovered a Vue upload node and the node appeared droppable.
  2. The final drop frequently landed on canvas#graph-canvas.
  3. The document-level drop handler in app.ts treated event.defaultPrevented === true as "already fully handled" and returned too early.
  4. That meant the graph/node recovery path never ran:
    • no graph-canvas node resolution from the final drop
    • no dropNode?.onDragDrop?.(event)
    • no upload into the intended node

So the primary regression was not image decoding or MIME handling by itself. The root cause was the post-#9463 routing contract between Vue-node bubbling and the document/canvas drop handler.


What changed

1) Restore the graph/document handoff in app.ts

The document-level drop handler no longer blindly discards graph-canvas drops just because they are already defaultPrevented.

Instead, it preserves the old fast-exit only for drops outside the graph canvas/container, while still processing bubbled graph-canvas drops through the node-resolution path.

This is the actual fix for the regression introduced by #9463.

2) Keep node-level file extraction robust

useNodeDragAndDrop.ts now falls back from dataTransfer.files to dataTransfer.items when needed.

This matters because some browser/drag-source combinations expose usable file payloads through DataTransferItemList even when FileList is empty or incomplete on the relevant path.

3) Keep document-level file extraction consistent

eventUtils.ts now also supports extracting files from dataTransfer.items when dataTransfer.files is empty, so the document fallback path agrees with the node-local path.

4) Harden media-type detection

Media classification now:

  • falls back to filename extension only when the MIME type is empty
  • does not override an explicit non-media MIME with the filename extension

This keeps empty-MIME file drags/pastes working without misclassifying unrelated files.

5) Keep clipboard/media paste behavior aligned

usePaste.ts now uses the same media classification logic as the drag/drop paths, including empty-MIME cases, so the paste path no longer lags behind drag/drop handling.

6) Narrow Vue-node drop ownership to the intended cases

LGraphNode.vue keeps the URI-only carveout while ensuring file-backed drops continue through await node.onDragDrop(event) instead of escaping the node path.


Why no browser_tests/ change was added

I did not add a Playwright/browser test for this regression because the failing behavior depends on a native OS-to-browser external file drag landing on the graph canvas, and the current browser_tests/ harness does not reproduce the browser-provided DataTransfer semantics that caused this bug.

Specifically, the regression depended on details of a real external drag payload such as:

  • the final drop targeting canvas#graph-canvas
  • the event arriving already defaultPrevented
  • browser-populated DataTransfer.items / DataTransfer.files behavior for external explorer drags
  • the handoff from Vue-node bubbling to the document-level drop handler

A synthetic DOM DragEvent in Playwright would not faithfully reproduce that browser/runtime behavior and would not have been a trustworthy regression test for the original failure mode.

Instead, this PR adds boundary-level regression coverage at the actual code paths that were involved:

  • src/renderer/extensions/vueNodes/components/LGraphNode.test.ts
  • src/composables/node/useNodeDragAndDrop.test.ts
  • src/utils/__tests__/eventUtils.test.ts
  • src/composables/usePaste.test.ts
  • src/scripts/app.test.ts

Those tests cover the routing and extraction invariants that regressed, while manual verification covered the real native external-drag path.


Test coverage added

src/renderer/extensions/vueNodes/components/LGraphNode.test.ts

Covers the Vue boundary cases:

  • file-backed drops stay local to the node
  • URI-only drops bubble
  • async drops still stay local
  • child-element drops still reach the node path

src/composables/node/useNodeDragAndDrop.test.ts

Covers DataTransfer.items fallback when DataTransfer.files is empty.

src/utils/__tests__/eventUtils.test.ts

Covers:

  • extracting files from DataTransfer.items
  • empty-MIME filename fallback
  • precedence of explicit non-media MIME over filename extension

src/composables/usePaste.test.ts

Covers empty-MIME media paste routing by extension.

src/scripts/app.test.ts

Covers app-level empty-MIME media routing behavior.


Manual verification

Verified with the real external file-drag repro that originally failed:

  • v1.43.4: good
  • v1.43.5: broken
  • patched post-v1.43.5 frontend: fixed

Observed broken behavior before the fix:

  • Vue Load Image-style nodes highlighted on dragover
  • final drop landed on canvas#graph-canvas
  • the document-level drop path discarded the event too early
  • the node upload path never ran

Observed behavior after the fix:

  • local file drops over Vue upload nodes now populate the target node correctly
  • URI-only drops still follow the document-level path as intended

Scope note

Although the regression was introduced by #9463 and manifested as a Vue-node drop-routing bug, the full fix necessarily touches the surrounding media drag/paste helpers as well, because the broken runtime path exposed inconsistencies between:

  • node-local drop extraction
  • document-level drop extraction
  • media-type classification
  • clipboard/media paste routing

That is why this PR spans the graph/document handoff plus the related media handling helpers and regression tests.


Notes

The docstring coverage warning is non-blocking for this PR.

I intentionally did not add broad JSDoc/docstring churn across small internal frontend helpers as part of a bug-fix changeset, because that would increase patch size and regression surface without changing runtime behavior. If maintainers want that warning silenced in this PR rather than in a follow-up cleanup, I can add targeted docstrings to the new helper functions.

@xmarre xmarre requested a review from a team April 3, 2026 23:06
@chatgpt-codex-connector
Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.
To continue using code reviews, you can upgrade your account or add credits to your account and enable them for code reviews in your settings.

@dosubot dosubot bot added the size:M This PR changes 30-99 lines, ignoring generated files. label Apr 3, 2026
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Apr 3, 2026

📝 Walkthrough

Walkthrough

Enhanced media type detection for files with empty MIME types by introducing filename-based classification helpers. Updated paste, drag-drop, and widget file-handling to use these utilities instead of simple MIME prefix checks. Refined drop event handling in components with improved state cleanup and validation. Added comprehensive test coverage for empty-MIME-type scenarios.

Changes

Cohort / File(s) Summary
Media Type Detection Utilities
src/utils/eventUtils.ts, src/utils/__tests__/eventUtils.test.ts
Introduced getMediaTypeFromFile helper that uses MIME type when available, otherwise falls back to filename-based classification via getMediaTypeFromFilename. Updated hasImageType, hasAudioType, hasVideoType predicates to accept File parameters and leverage this hybrid approach. Added getFilesFromItems for extracting files from DataTransferItemList. Extended tests to validate empty-MIME-type classification and filename-based fallback behavior.
Paste/Clipboard Handling
src/composables/usePaste.ts, src/composables/usePaste.test.ts
Updated paste item filtering to use new media-type helpers (hasImageType, hasAudioType, hasVideoType) and extract files via getAsFile(). Added unit and integration tests verifying correct handling of files with empty MIME types but recognizable extensions.
Drag-and-Drop Core Logic
src/scripts/app.ts, src/scripts/app.test.ts
Refined document drop handler to better distinguish canvas-area drops from external drops, using node position detection via canvas.graph.getNodeOnPos(). Switched media-type detection from MIME prefix checks to new helper functions. Updated handleFileList gating to use hasImageType. Added test cases for empty-MIME-type image files.
Component Drag-Drop Handling
src/renderer/extensions/vueNodes/components/LGraphNode.vue, src/renderer/extensions/vueNodes/components/LGraphNode.test.ts
Introduced state cleanup helpers (clearDragOverState, isUriOnlyDrop, hasRealFileTransfer) to centralize drag-over state management. Refactored handleDrop to be async with guaranteed cleanup via finally block. Distinguished URI-only drops from file-backed drops. Expanded tests with real DataTransfer objects and new drop scenarios (URI-only, inner child, BMP placeholder).
Node Drag-and-Drop Composable
src/composables/node/useNodeDragAndDrop.ts, src/composables/node/useNodeDragAndDrop.test.ts
Added getFilesFromItems helper for extracting files from transfer items. Updated file validation to prefer dataTransfer.files and fall back to items extraction when files list is empty. Reworked filtering to exclude BMP placeholders before applying user fileFilter. Added tests covering items-based file extraction and BMP placeholder scenarios.
Widget Utilities
src/renderer/extensions/vueNodes/widgets/composables/useImageUploadWidget.ts
Replaced local isVideoFile/isImageFile predicates with imported hasVideoType/hasImageType helpers for consistent file-type detection across the application.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~22 minutes

Poem

🐰 Files come in, both paste and drag,
With names and types that sometimes lag,
We check the MIME, the extension too,
Now empty types won't trip us through!
State cleanup flows, and drops behave,
A better way our nodes to save.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main changes: restoring Vue upload-node file drops (regression fix) and hardening media drag/paste handling after PR #9463.
Description check ✅ Passed The description is comprehensive and well-structured, covering summary, root cause, detailed changes, testing approach, and rationale. All required template sections are present and substantive.
End-To-End Regression Coverage For Fixes ✅ Passed PR description provides concrete explanation for why Playwright native-drag test was not added, and extensive unit/integration tests plus manual verification demonstrate fix effectiveness.
Adr Compliance For Entity/Litegraph Changes ✅ Passed PR modifies only composables, components, and utilities; no changes to src/lib/litegraph/, src/ecs/, or graph entity class definitions.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions
Copy link
Copy Markdown

github-actions bot commented Apr 3, 2026

🎨 Storybook: loading Building...

@github-actions
Copy link
Copy Markdown

github-actions bot commented Apr 3, 2026

🎭 Playwright: ⏳ Running...

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
src/renderer/extensions/vueNodes/components/LGraphNode.test.ts (1)

346-369: Cover the “promise resolves false still claims event” contract explicitly.

Great regression test. One small gap: it only checks the Promise<true> path. Since this PR intentionally claims the event for async handlers regardless of final resolution, add a mockResolvedValue(false) variant so that behavior is locked in.

Suggested test addition
+    it('should still stop propagation when onDragDrop promise resolves false', async () => {
+      const onDragDrop = vi.fn().mockResolvedValue(false)
+      mockData.mockLgraphNode = {
+        onDragDrop,
+        onDragOver: vi.fn(),
+        isSubgraphNode: () => false
+      }
+
+      const wrapper = mountLGraphNode({ nodeData: mockNodeData })
+      const parentListener = vi.fn()
+      const parent = wrapper.element.parentElement
+      expect(parent).not.toBeNull()
+      parent!.addEventListener('drop', parentListener)
+
+      wrapper.element.dispatchEvent(
+        new Event('drop', { bubbles: true, cancelable: true })
+      )
+
+      await Promise.resolve()
+
+      expect(onDragDrop).toHaveBeenCalled()
+      expect(parentListener).not.toHaveBeenCalled()
+    })
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/renderer/extensions/vueNodes/components/LGraphNode.test.ts` around lines
346 - 369, Add a second test case mirroring the existing "should stop
propagation when onDragDrop returns a promise" scenario but set onDragDrop =
vi.fn().mockResolvedValue(false); mount the node the same way (using
mountLGraphNode with mockNodeData), attach a parent 'drop' listener
(parentListener), dispatch a cancelable bubbling 'drop' event on
wrapper.element, await the promise resolution (e.g., await Promise.resolve()),
and assert that onDragDrop was called and parentListener was not called;
reference the mockData.mockLgraphNode object and the onDragDrop mock to locate
where to inject this new test.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@src/renderer/extensions/vueNodes/components/LGraphNode.test.ts`:
- Around line 346-369: Add a second test case mirroring the existing "should
stop propagation when onDragDrop returns a promise" scenario but set onDragDrop
= vi.fn().mockResolvedValue(false); mount the node the same way (using
mountLGraphNode with mockNodeData), attach a parent 'drop' listener
(parentListener), dispatch a cancelable bubbling 'drop' event on
wrapper.element, await the promise resolution (e.g., await Promise.resolve()),
and assert that onDragDrop was called and parentListener was not called;
reference the mockData.mockLgraphNode object and the onDragDrop mock to locate
where to inject this new test.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 8d532a8e-8dc2-481a-8248-e5d5ebbdd6fb

📥 Commits

Reviewing files that changed from the base of the PR and between 17d2870 and c5b37f4.

📒 Files selected for processing (2)
  • src/renderer/extensions/vueNodes/components/LGraphNode.test.ts
  • src/renderer/extensions/vueNodes/components/LGraphNode.vue

@dosubot dosubot bot added size:L This PR changes 100-499 lines, ignoring generated files. and removed size:M This PR changes 30-99 lines, ignoring generated files. labels Apr 3, 2026
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/composables/usePaste.ts`:
- Around line 72-83: The initial paste dispatch in usePaste() currently checks
item.type.startsWith(...) and therefore ignores clipboard File items with empty
MIME; update that dispatch loop to detect files by item.kind === 'file', call
item.getAsFile(), and use
hasImageType(file)/hasAudioType(file)/hasVideoType(file) to decide whether to
call pasteImageNode(), pasteAudioNode(), or pasteVideoNode(); ensure this
mirrors pasteItemsOnNode() behavior and add a regression test for usePaste()
that pastes a File with type === '' and verifies it routes to the appropriate
paste*Node handler.

In `@src/utils/eventUtils.ts`:
- Around line 36-46: The function getMediaTypeFromFile currently falls back to
getMediaTypeFromFilename even when File.type is non-empty; change
getMediaTypeFromFile to only call getMediaTypeFromFilename when type is empty
(e.g., type === ''), and if type is non-empty and doesn't start with
image|audio|video return null immediately; update the function's control flow
around the existing type.startsWith checks and the filename fallback, and add a
regression test that asserts a mismatched non-empty MIME (e.g., name
"report.jpg" with type "application/pdf") returns null to ensure precedence is
enforced.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 7e865afd-ab9e-460d-9288-9c1d49c68649

📥 Commits

Reviewing files that changed from the base of the PR and between c5b37f4 and 9762961.

📒 Files selected for processing (7)
  • src/composables/usePaste.test.ts
  • src/composables/usePaste.ts
  • src/renderer/extensions/vueNodes/widgets/composables/useImageUploadWidget.ts
  • src/scripts/app.test.ts
  • src/scripts/app.ts
  • src/utils/__tests__/eventUtils.test.ts
  • src/utils/eventUtils.ts

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
src/renderer/extensions/vueNodes/components/LGraphNode.test.ts (1)

347-353: Add a concrete id to the async mockLgraphNode.

At Line 349, the drop cleanup path is keyed by node.id; this mock currently omits it, so the guard is exercised via undefined rather than realistic IDs.

Suggested test tweak
     const onDragDrop = vi.fn().mockResolvedValue(true)
     mockData.mockLgraphNode = {
+      id: 123,
       onDragDrop,
       onDragOver: vi.fn(() => true),
       isSubgraphNode: () => false
     }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/renderer/extensions/vueNodes/components/LGraphNode.test.ts` around lines
347 - 353, The test's mockLgraphNode lacks a concrete id which causes the
drop-cleanup guard (keyed by node.id) to run with undefined; update the
mockLgraphNode in the "should stop propagation when onDragDrop returns a
promise" test to include a realistic id (e.g., id: 'node-1') so the cleanup path
is exercised with a proper identifier; modify the mock object that contains
onDragDrop, onDragOver and isSubgraphNode to also include this id.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@src/renderer/extensions/vueNodes/components/LGraphNode.test.ts`:
- Around line 347-353: The test's mockLgraphNode lacks a concrete id which
causes the drop-cleanup guard (keyed by node.id) to run with undefined; update
the mockLgraphNode in the "should stop propagation when onDragDrop returns a
promise" test to include a realistic id (e.g., id: 'node-1') so the cleanup path
is exercised with a proper identifier; modify the mock object that contains
onDragDrop, onDragOver and isSubgraphNode to also include this id.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: e2586fa1-3836-4d05-b2c0-cd8bb9a55823

📥 Commits

Reviewing files that changed from the base of the PR and between 9762961 and 55f385e.

📒 Files selected for processing (2)
  • src/renderer/extensions/vueNodes/components/LGraphNode.test.ts
  • src/renderer/extensions/vueNodes/components/LGraphNode.vue

@dosubot dosubot bot added size:XL This PR changes 500-999 lines, ignoring generated files. and removed size:L This PR changes 100-499 lines, ignoring generated files. labels Apr 4, 2026
@dosubot dosubot bot added size:L This PR changes 100-499 lines, ignoring generated files. and removed size:XL This PR changes 500-999 lines, ignoring generated files. labels Apr 4, 2026
@dosubot dosubot bot added size:XL This PR changes 500-999 lines, ignoring generated files. and removed size:L This PR changes 100-499 lines, ignoring generated files. labels Apr 4, 2026
@xmarre xmarre changed the title Fix async Vue node drag-drop propagation Fix local file drops on Vue upload nodes after #9463 Apr 4, 2026
@xmarre
Copy link
Copy Markdown
Author

xmarre commented Apr 4, 2026

@coderabbitai resume

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Apr 4, 2026

✅ Actions performed

Reviews resumed.

@xmarre xmarre changed the title Fix local file drops on Vue upload nodes after #9463 Restore Vue upload-node file drops and harden media drag/paste handling after #9463 Apr 4, 2026
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/renderer/extensions/vueNodes/components/LGraphNode.test.ts (1)

325-445: ⚠️ Potential issue | 🟠 Major

This bug fix still needs a browser-level regression or an explicit exemption.

These component tests cover the Vue boundary, but the reported failure only reproduced when the browser delivered the final drop to canvas#graph-canvas. The PR metadata still shows no browser_tests/ change and no explanation for skipping one, so the fix does not satisfy the repo’s bug-fix regression requirement yet.

Based on learnings, "End-to-end regression coverage for fixes: For PRs that include bug-fix language in the title or commit subjects (fix, fixed, fixes, fixing, bugfix, hotfix), ensure at least one of the following: (1) files are changed under browser_tests/, or (2) the PR description includes a concrete, non-placeholder explanation of why an end-to-end regression test was not added."

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/renderer/extensions/vueNodes/components/LGraphNode.test.ts` around lines
325 - 445, The PR adds unit tests around Vue handling in LGraphNode.test.ts but
lacks the required browser-level regression for the bug that reproduced only
when the browser delivered the final drop to canvas#graph-canvas; either add an
end-to-end browser test under browser_tests/ that reproduces the failing drop
behavior (exercise the real DOM drop to canvas#graph-canvas and assert
propagation/handling matches the fix), or update the PR description to include a
concrete explanation why an E2E test is not applicable; reference the related
test/spec file LGraphNode.test.ts and the DOM target canvas#graph-canvas when
adding the browser test or documenting the exemption.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/composables/node/useNodeDragAndDrop.ts`:
- Around line 33-37: The Drag-and-Drop flow incorrectly treats Chrome→Firefox
BMP placeholders as real files; update the file-filtering so that any File with
type 'image/bmp' is removed before branching on "file-backed" length checks.
Concretely, change filterFiles and filterItemFiles (and the other spots
referenced near the other ranges) to filter out files with file.type ===
'image/bmp' (in addition to the existing fileFilter) and ensure any logic that
decides "is file-backed" uses the filtered array returned by getFilesFromItems /
filterFiles rather than the raw dataTransfer.files or raw File[]; keep using
getFilesFromItems for items but apply the BMP exclusion first so
extractFilesFromDragEvent receives a true URI-only path when appropriate.

In `@src/renderer/extensions/vueNodes/components/LGraphNode.vue`:
- Around line 827-845: hasFileTransfer currently treats any file item or
FileList entry as a file drop, which misclassifies Chrome→Firefox URI drags that
include a synthetic "image/bmp" placeholder; update hasFileTransfer to ignore
placeholder BMP entries (or otherwise mirror extractFilesFromDragEvent's filter)
by only returning true for file items/entries whose MIME type is not 'image/bmp'
(or not in the list extractFilesFromDragEvent ignores), so isUriOnlyDrop
correctly recognizes URI-only drops; apply the same logic where file-list checks
occur so both hasFileTransfer and isUriOnlyDrop behave consistently with
extractFilesFromDragEvent.

In `@src/scripts/app.ts`:
- Around line 610-627: Remove the drop tracing console.log added in the
app.documentDrop handler in src/scripts/app.ts: delete the entire
console.log('app.documentDrop', {...}) block (and any similar drag/upload
tracing added in this PR) so filenames, item file names, and the text/uri-list
payload are not logged; if lightweight telemetry is required instead, replace it
with a non-sensitive log that only records safe booleans or counts (e.g.,
whether a drop occurred and number of items) without including file names,
types, or URI contents.

---

Outside diff comments:
In `@src/renderer/extensions/vueNodes/components/LGraphNode.test.ts`:
- Around line 325-445: The PR adds unit tests around Vue handling in
LGraphNode.test.ts but lacks the required browser-level regression for the bug
that reproduced only when the browser delivered the final drop to
canvas#graph-canvas; either add an end-to-end browser test under browser_tests/
that reproduces the failing drop behavior (exercise the real DOM drop to
canvas#graph-canvas and assert propagation/handling matches the fix), or update
the PR description to include a concrete explanation why an E2E test is not
applicable; reference the related test/spec file LGraphNode.test.ts and the DOM
target canvas#graph-canvas when adding the browser test or documenting the
exemption.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 48b9157e-c849-42e1-b597-5bfd50f33319

📥 Commits

Reviewing files that changed from the base of the PR and between 99e50d6 and c9a867b.

📒 Files selected for processing (8)
  • src/composables/node/useNodeDragAndDrop.test.ts
  • src/composables/node/useNodeDragAndDrop.ts
  • src/composables/node/useNodeImageUpload.ts
  • src/renderer/extensions/vueNodes/components/LGraphNode.test.ts
  • src/renderer/extensions/vueNodes/components/LGraphNode.vue
  • src/scripts/app.ts
  • src/utils/__tests__/eventUtils.test.ts
  • src/utils/eventUtils.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/utils/tests/eventUtils.test.ts

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Apr 4, 2026

✅ Actions performed

Reviews resumed.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
src/renderer/extensions/vueNodes/components/LGraphNode.vue (1)

873-880: Minor: Consider consistent cleanup pattern for early return.

This early return path clears app.dragOverNode unconditionally if it exists, unlike clearDragOverState(node.id) which checks the id. This is functionally fine since a node without onDragDrop shouldn't have been set as dragOverNode, but for consistency you could use:

 if (!node?.onDragDrop) {
-  isDraggingOver.value = false
-  if (app.dragOverNode) {
-    app.dragOverNode = null
-    app.canvas.setDirty(false, true)
-  }
+  clearDragOverState(node?.id)
   return
 }

With node?.id being undefined, clearDragOverState would only clear isDraggingOver.value (as intended). However, the current code explicitly clears app.dragOverNode which may be intentional for edge cases—no functional bug here.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/renderer/extensions/vueNodes/components/LGraphNode.vue` around lines 873
- 880, The early-return block that handles nodes without onDragDrop currently
sets isDraggingOver.value = false and unconditionally clears app.dragOverNode
and calls app.canvas.setDirty, which is inconsistent with the elsewhere-used
clearDragOverState behavior; replace the manual cleanup with a call to
clearDragOverState(node?.id) so the same id-check and cleanup logic is reused
(this will clear isDraggingOver.value and only clear app.dragOverNode when the
ids match) while preserving the canvas dirty handling.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@src/renderer/extensions/vueNodes/components/LGraphNode.vue`:
- Around line 873-880: The early-return block that handles nodes without
onDragDrop currently sets isDraggingOver.value = false and unconditionally
clears app.dragOverNode and calls app.canvas.setDirty, which is inconsistent
with the elsewhere-used clearDragOverState behavior; replace the manual cleanup
with a call to clearDragOverState(node?.id) so the same id-check and cleanup
logic is reused (this will clear isDraggingOver.value and only clear
app.dragOverNode when the ids match) while preserving the canvas dirty handling.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: f435411b-482a-45c4-8987-270dbcfa600f

📥 Commits

Reviewing files that changed from the base of the PR and between c9a867b and d274885.

📒 Files selected for processing (5)
  • src/composables/node/useNodeDragAndDrop.test.ts
  • src/composables/node/useNodeDragAndDrop.ts
  • src/renderer/extensions/vueNodes/components/LGraphNode.test.ts
  • src/renderer/extensions/vueNodes/components/LGraphNode.vue
  • src/scripts/app.ts
🚧 Files skipped from review as they are similar to previous changes (3)
  • src/composables/node/useNodeDragAndDrop.test.ts
  • src/renderer/extensions/vueNodes/components/LGraphNode.test.ts
  • src/composables/node/useNodeDragAndDrop.ts

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XL This PR changes 500-999 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant