Skip to content

Conversation

@jtydhr88
Copy link
Collaborator

@jtydhr88 jtydhr88 commented Jan 11, 2026

Summary

Prevents custom widget drag interactions from triggering node drag in vueNodes mode. Custom plugins like KJNodes Points Editor use their own drag handlers which were bubbling up to the node container.

Screenshots (if applicable)

before

2026-01-10.23-00-10.mp4

after

2026-01-10.22-57-29.mp4

┆Issue is synchronized with this Notion page by Unito

@jtydhr88 jtydhr88 requested a review from a team as a code owner January 11, 2026 04:00
@dosubot dosubot bot added the size:S This PR changes 10-29 lines, ignoring generated files. label Jan 11, 2026
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 11, 2026

📝 Walkthrough

Walkthrough

Modified two Vue widget components to prevent event propagation for pointer and mouse events. WidgetDOM.vue now attaches event listeners that stop propagation for pointerdown, pointermove, pointerup, mousedown, mousemove, and mouseup events. WidgetLegacy.vue adds .stop modifiers to existing pointer event bindings.

Changes

Cohort / File(s) Summary
Widget Event Propagation
src/renderer/extensions/vueNodes/widgets/components/WidgetDOM.vue, src/renderer/extensions/vueNodes/widgets/components/WidgetLegacy.vue
WidgetDOM.vue: Adds multiple event listeners (pointerdown, pointermove, pointerup, mousedown, mousemove, mouseup) to root div element with stop propagation. WidgetLegacy.vue: Adds .stop modifier to @pointerdown, @pointerup, and @pointermove canvas event bindings to prevent event bubbling.

Possibly related PRs

  • Fix: TextArea context menu #6834: Modifies Vue widget components to add/adjust event listeners that stop propagation of pointer, mouse, and contextmenu events in widget rendering.

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

github-actions bot commented Jan 11, 2026

🎨 Storybook Build Status

Build completed successfully!

⏰ Completed at: 01/11/2026, 04:02:14 AM UTC

🔗 Links


🎉 Your Storybook is ready for review!

@github-actions
Copy link

github-actions bot commented Jan 11, 2026

🎭 Playwright Test Results

All tests passed!

⏰ Completed at: 01/11/2026, 04:07:18 AM UTC

📈 Summary

  • Total Tests: 514
  • Passed: 506 ✅
  • Failed: 0
  • Flaky: 0
  • Skipped: 8 ⏭️

📊 Test Reports by Browser

  • chromium: View Report • ✅ 494 / ❌ 0 / ⚠️ 0 / ⏭️ 8
  • chromium-2x: View Report • ✅ 2 / ❌ 0 / ⚠️ 0 / ⏭️ 0
  • chromium-0.5x: View Report • ✅ 1 / ❌ 0 / ⚠️ 0 / ⏭️ 0
  • mobile-chrome: View Report • ✅ 9 / ❌ 0 / ⚠️ 0 / ⏭️ 0

🎉 Click on the links above to view detailed test results for each browser configuration.

Copy link
Contributor

@DrJKL DrJKL left a comment

Choose a reason for hiding this comment

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

Assuming the tests pass, should be good.

@DrJKL DrJKL self-assigned this Jan 11, 2026
@DrJKL DrJKL requested review from AustinMroz and Myestery January 11, 2026 04:02
@github-actions
Copy link

Bundle Size Report

Summary

  • Raw size: 18.8 MB baseline 18.8 MB — 🔴 +629 B
  • Gzip: 3.85 MB baseline 3.85 MB — 🔴 +124 B
  • Brotli: 2.94 MB baseline 2.94 MB — 🟢 -127 B
  • Bundles: 94 current • 94 baseline • 38 added / 38 removed

Category Glance
App Entry Points 🔴 +629 B (3.31 MB) · Vendor & Third-Party ⚪ 0 B (9.19 MB) · Other ⚪ 0 B (4.74 MB) · Graph Workspace ⚪ 0 B (1.03 MB) · Panels & Settings ⚪ 0 B (337 kB) · UI Components ⚪ 0 B (199 kB) · + 3 more

Per-category breakdown
App Entry Points — 3.31 MB (baseline 3.31 MB) • 🔴 +629 B

Main entry bundles and manifests

File Before After Δ Raw Δ Gzip Δ Brotli
assets/index-BIN6HxqE.js (new) 3.12 MB 🔴 +3.12 MB 🔴 +653 kB 🔴 +496 kB
assets/index-DK-s5fac.js (removed) 3.12 MB 🟢 -3.12 MB 🟢 -653 kB 🟢 -496 kB
assets/index-DC2YG7O5.js (new) 195 kB 🔴 +195 kB 🔴 +42.7 kB 🔴 +35.3 kB
assets/index-PqVq0-86.js (removed) 195 kB 🟢 -195 kB 🟢 -42.7 kB 🟢 -35.3 kB
assets/index-Dm31Z_WL.js (removed) 345 B 🟢 -345 B 🟢 -244 B 🟢 -234 B
assets/index-Dp97px1q.js (new) 345 B 🔴 +345 B 🔴 +247 B 🔴 +237 B

Status: 3 added / 3 removed

Graph Workspace — 1.03 MB (baseline 1.03 MB) • ⚪ 0 B

Graph editor runtime, canvas, workflow orchestration

File Before After Δ Raw Δ Gzip Δ Brotli
assets/GraphView-BfF5t4zP.js (new) 1.03 MB 🔴 +1.03 MB 🔴 +198 kB 🔴 +150 kB
assets/GraphView-CGf_k9tC.js (removed) 1.03 MB 🟢 -1.03 MB 🟢 -198 kB 🟢 -150 kB

Status: 1 added / 1 removed

Views & Navigation — 6.63 kB (baseline 6.63 kB) • ⚪ 0 B

Top-level views, pages, and routed surfaces

File Before After Δ Raw Δ Gzip Δ Brotli
assets/UserSelectView-7yyOZ2cB.js (removed) 6.63 kB 🟢 -6.63 kB 🟢 -2.14 kB 🟢 -1.9 kB
assets/UserSelectView-XwS9Xx2m.js (new) 6.63 kB 🔴 +6.63 kB 🔴 +2.15 kB 🔴 +1.9 kB

Status: 1 added / 1 removed

Panels & Settings — 337 kB (baseline 337 kB) • ⚪ 0 B

Configuration panels, inspectors, and settings screens

File Before After Δ Raw Δ Gzip Δ Brotli
assets/LegacyCreditsPanel-B4IKrMpc.js (removed) 25.1 kB 🟢 -25.1 kB 🟢 -5.74 kB 🟢 -5 kB
assets/LegacyCreditsPanel-CPVvE4ed.js (new) 25.1 kB 🔴 +25.1 kB 🔴 +5.74 kB 🔴 +5 kB
assets/KeybindingPanel-BQvkpisz.js (removed) 14.8 kB 🟢 -14.8 kB 🟢 -3.57 kB 🟢 -3.13 kB
assets/KeybindingPanel-CVdIxjRd.js (new) 14.8 kB 🔴 +14.8 kB 🔴 +3.57 kB 🔴 +3.12 kB
assets/ExtensionPanel-BakU6bm2.js (removed) 11.1 kB 🟢 -11.1 kB 🟢 -2.62 kB 🟢 -2.3 kB
assets/ExtensionPanel-CKNCiKDR.js (new) 11.1 kB 🔴 +11.1 kB 🔴 +2.62 kB 🔴 +2.3 kB
assets/AboutPanel-CVFD_RiV.js (removed) 9.16 kB 🟢 -9.16 kB 🟢 -2.46 kB 🟢 -2.2 kB
assets/AboutPanel-DtMnkWSg.js (new) 9.16 kB 🔴 +9.16 kB 🔴 +2.46 kB 🔴 +2.21 kB
assets/ServerConfigPanel-6nrcOoSs.js (new) 7.51 kB 🔴 +7.51 kB 🔴 +2.04 kB 🔴 +1.81 kB
assets/ServerConfigPanel-BPeNT-4L.js (removed) 7.51 kB 🟢 -7.51 kB 🟢 -2.04 kB 🟢 -1.81 kB
assets/UserPanel-CHk9OBBm.js (new) 6.88 kB 🔴 +6.88 kB 🔴 +1.79 kB 🔴 +1.57 kB
assets/UserPanel-D0VkxoRj.js (removed) 6.88 kB 🟢 -6.88 kB 🟢 -1.79 kB 🟢 -1.57 kB
assets/settings-BbW1wrcp.js 25.2 kB 25.2 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-CtIClcWI.js 26 kB 26 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-D_f3uAqO.js 22.4 kB 22.4 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-DiVjuKQX.js 34.4 kB 34.4 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-DJiF1Y59.js 25.8 kB 25.8 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-DKkx6nFR.js 28.2 kB 28.2 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-DX5qVgIQ.js 24.9 kB 24.9 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-MzsBgiwB.js 21.7 kB 21.7 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-pR7Ue3ei.js 26.7 kB 26.7 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-y_-zNlA6.js 27.5 kB 27.5 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B

Status: 6 added / 6 removed

UI Components — 199 kB (baseline 199 kB) • ⚪ 0 B

Reusable component library chunks

File Before After Δ Raw Δ Gzip Δ Brotli
assets/LazyImage.vue_vue_type_script_setup_true_lang-B5nJmz-d.js (new) 64.5 kB 🔴 +64.5 kB 🔴 +13.1 kB 🔴 +11.4 kB
assets/LazyImage.vue_vue_type_script_setup_true_lang-DCmJducW.js (removed) 64.5 kB 🟢 -64.5 kB 🟢 -13.1 kB 🟢 -11.4 kB
assets/Load3D.vue_vue_type_script_setup_true_lang-Bcwc7QRo.js (new) 56.4 kB 🔴 +56.4 kB 🔴 +8.78 kB 🔴 +7.54 kB
assets/Load3D.vue_vue_type_script_setup_true_lang-CaJudePk.js (removed) 56.4 kB 🟢 -56.4 kB 🟢 -8.77 kB 🟢 -7.53 kB
assets/WidgetSelect.vue_vue_type_script_setup_true_lang-1alMqx5e.js (new) 49 kB 🔴 +49 kB 🔴 +10.5 kB 🔴 +9.15 kB
assets/WidgetSelect.vue_vue_type_script_setup_true_lang-Bd_wU067.js (removed) 49 kB 🟢 -49 kB 🟢 -10.5 kB 🟢 -9.15 kB
assets/WidgetInputNumber.vue_vue_type_script_setup_true_lang-BcgU32eU.js (new) 10.9 kB 🔴 +10.9 kB 🔴 +2.89 kB 🔴 +2.55 kB
assets/WidgetInputNumber.vue_vue_type_script_setup_true_lang-DU8EijLj.js (removed) 10.9 kB 🟢 -10.9 kB 🟢 -2.9 kB 🟢 -2.56 kB
assets/ComfyQueueButton-Bb57BzrC.js (removed) 8.83 kB 🟢 -8.83 kB 🟢 -2.58 kB 🟢 -2.29 kB
assets/ComfyQueueButton-BMNTduxV.js (new) 8.83 kB 🔴 +8.83 kB 🔴 +2.58 kB 🔴 +2.29 kB
assets/WidgetWithControl.vue_vue_type_script_setup_true_lang-525WJoLN.js (removed) 3.72 kB 🟢 -3.72 kB 🟢 -1.45 kB 🟢 -1.32 kB
assets/WidgetWithControl.vue_vue_type_script_setup_true_lang-DPNtT0Xj.js (new) 3.72 kB 🔴 +3.72 kB 🔴 +1.45 kB 🔴 +1.32 kB
assets/WidgetButton-C_yOJQQe.js (removed) 2.21 kB 🟢 -2.21 kB 🟢 -997 B 🟢 -895 B
assets/WidgetButton-lP8GiIyu.js (new) 2.21 kB 🔴 +2.21 kB 🔴 +998 B 🔴 +899 B
assets/WidgetLayoutField.vue_vue_type_script_setup_true_lang-C5Zg_b6d.js (removed) 2.14 kB 🟢 -2.14 kB 🟢 -890 B 🟢 -766 B
assets/WidgetLayoutField.vue_vue_type_script_setup_true_lang-CVMPlnAf.js (new) 2.14 kB 🔴 +2.14 kB 🔴 +891 B 🔴 +765 B
assets/UserAvatar.vue_vue_type_script_setup_true_lang-CmvGBeCh.js 1.34 kB 1.34 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B

Status: 8 added / 8 removed

Data & Services — 12.5 kB (baseline 12.5 kB) • ⚪ 0 B

Stores, services, APIs, and repositories

File Before After Δ Raw Δ Gzip Δ Brotli
assets/keybindingService-D0PZp2HY.js (new) 7.51 kB 🔴 +7.51 kB 🔴 +1.83 kB 🔴 +1.58 kB
assets/keybindingService-tCrKxyJT.js (removed) 7.51 kB 🟢 -7.51 kB 🟢 -1.83 kB 🟢 -1.57 kB
assets/audioService-Bzt61mUf.js (removed) 2.2 kB 🟢 -2.2 kB 🟢 -962 B 🟢 -824 B
assets/audioService-CEAtU_uX.js (new) 2.2 kB 🔴 +2.2 kB 🔴 +964 B 🔴 +820 B
assets/serverConfigStore-lZrt20fn.js 2.83 kB 2.83 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B

Status: 2 added / 2 removed

Utilities & Hooks — 1.41 kB (baseline 1.41 kB) • ⚪ 0 B

Helpers, composables, and utility bundles

File Before After Δ Raw Δ Gzip Δ Brotli
assets/audioUtils-Ba3vPams.js (new) 1.41 kB 🔴 +1.41 kB 🔴 +650 B 🔴 +549 B
assets/audioUtils-BR8r6cTh.js (removed) 1.41 kB 🟢 -1.41 kB 🟢 -649 B 🟢 -551 B

Status: 1 added / 1 removed

Vendor & Third-Party — 9.19 MB (baseline 9.19 MB) • ⚪ 0 B

External libraries and shared vendor chunks

File Before After Δ Raw Δ Gzip Δ Brotli
assets/vendor-chart-C2WamoVK.js 452 kB 452 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-other-Da7BzmIq.js 3.9 MB 3.9 MB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-primevue-CIEAfgED.js 1.95 MB 1.95 MB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-three-Ds3gPtNh.js 2.08 MB 2.08 MB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-tiptap-WJL3cqV8.js 232 kB 232 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-vue-E9hBZNUh.js 160 kB 160 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-xterm-BF8peZ5_.js 420 kB 420 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
Other — 4.74 MB (baseline 4.74 MB) • ⚪ 0 B

Bundles that do not match a named category

File Before After Δ Raw Δ Gzip Δ Brotli
assets/SubscriptionRequiredDialogContent-CDokSaFA.js (new) 29.3 kB 🔴 +29.3 kB 🔴 +6.51 kB 🔴 +5.66 kB
assets/SubscriptionRequiredDialogContent-CoBiVbv-.js (removed) 29.3 kB 🟢 -29.3 kB 🟢 -6.51 kB 🟢 -5.65 kB
assets/WidgetRecordAudio-CM1T8-ZW.js (new) 20.4 kB 🔴 +20.4 kB 🔴 +5.24 kB 🔴 +4.64 kB
assets/WidgetRecordAudio-DxfBd_Dl.js (removed) 20.4 kB 🟢 -20.4 kB 🟢 -5.23 kB 🟢 -4.63 kB
assets/AudioPreviewPlayer-BLyu1xTw.js (new) 13.3 kB 🔴 +13.3 kB 🔴 +3.35 kB 🔴 +3 kB
assets/AudioPreviewPlayer-gkArM-i9.js (removed) 13.3 kB 🟢 -13.3 kB 🟢 -3.35 kB 🟢 -3 kB
assets/ValueControlPopover-D4mzL_dC.js (new) 5.49 kB 🔴 +5.49 kB 🔴 +1.71 kB 🔴 +1.52 kB
assets/ValueControlPopover-Dc3Ir-71.js (removed) 5.49 kB 🟢 -5.49 kB 🟢 -1.71 kB 🟢 -1.51 kB
assets/WidgetGalleria-CMfotFqK.js (new) 4.1 kB 🔴 +4.1 kB 🔴 +1.45 kB 🔴 +1.31 kB
assets/WidgetGalleria-ZfjkBiil.js (removed) 4.1 kB 🟢 -4.1 kB 🟢 -1.45 kB 🟢 -1.3 kB
assets/WidgetColorPicker-BmwJ3myY.js (removed) 3.41 kB 🟢 -3.41 kB 🟢 -1.38 kB 🟢 -1.23 kB
assets/WidgetColorPicker-BQ6w-8Zo.js (new) 3.41 kB 🔴 +3.41 kB 🔴 +1.38 kB 🔴 +1.24 kB
assets/WidgetTextarea-BR-7A0ig.js (new) 3.08 kB 🔴 +3.08 kB 🔴 +1.22 kB 🔴 +1.08 kB
assets/WidgetTextarea-DFKsLkHn.js (removed) 3.08 kB 🟢 -3.08 kB 🟢 -1.21 kB 🟢 -1.08 kB
assets/WidgetMarkdown-BXT-aQo5.js (new) 3.08 kB 🔴 +3.08 kB 🔴 +1.28 kB 🔴 +1.13 kB
assets/WidgetMarkdown-HsbzyEA_.js (removed) 3.08 kB 🟢 -3.08 kB 🟢 -1.28 kB 🟢 -1.12 kB
assets/WidgetAudioUI-C-iLrhbR.js (new) 2.89 kB 🔴 +2.89 kB 🔴 +1.17 kB 🔴 +1.06 kB
assets/WidgetAudioUI-CJBY_uFS.js (removed) 2.89 kB 🟢 -2.89 kB 🟢 -1.17 kB 🟢 -1.06 kB
assets/WidgetToggleSwitch-Biaj7_72.js (new) 2.66 kB 🔴 +2.66 kB 🔴 +1.13 kB 🔴 +1.03 kB
assets/WidgetToggleSwitch-CsXH-kFj.js (removed) 2.66 kB 🟢 -2.66 kB 🟢 -1.13 kB 🟢 -1.02 kB
assets/WidgetInputText-BEMgl53s.js (removed) 1.99 kB 🟢 -1.99 kB 🟢 -921 B 🟢 -851 B
assets/WidgetInputText-CyOqjHrq.js (new) 1.99 kB 🔴 +1.99 kB 🔴 +920 B 🔴 +853 B
assets/Media3DTop-Dd8_k6sH.js (removed) 1.49 kB 🟢 -1.49 kB 🟢 -766 B 🟢 -652 B
assets/Media3DTop-jG8W6rnL.js (new) 1.49 kB 🔴 +1.49 kB 🔴 +768 B 🔴 +649 B
assets/WidgetSelect-BQv46zga.js (removed) 733 B 🟢 -733 B 🟢 -361 B 🟢 -330 B
assets/WidgetSelect-DJ1ItCp7.js (new) 733 B 🔴 +733 B 🔴 +362 B 🔴 +325 B
assets/WidgetInputNumber-BqU2R2Qq.js (removed) 673 B 🟢 -673 B 🟢 -347 B 🟢 -290 B
assets/WidgetInputNumber-DdFhhKUi.js (new) 673 B 🔴 +673 B 🔴 +349 B 🔴 +290 B
assets/Load3D-CEhLHjCN.js (removed) 424 B 🟢 -424 B 🟢 -267 B 🟢 -222 B
assets/Load3D-thWzt52W.js (new) 424 B 🔴 +424 B 🔴 +268 B 🔴 +223 B
assets/WidgetLegacy-DbVsGe5u.js (new) 364 B 🔴 +364 B 🔴 +238 B 🔴 +193 B
assets/WidgetLegacy-DdB39g5b.js (removed) 364 B 🟢 -364 B 🟢 -237 B 🟢 -192 B
assets/commands-7wafkPd1.js 15.6 kB 15.6 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-B3CjBnJe.js 14.6 kB 14.6 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-Bbu2TJPy.js 18.1 kB 18.1 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-C4khqsmz.js 15.6 kB 15.6 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-CDQ7KnIn.js 16.4 kB 16.4 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-CtjMsXHh.js 15.4 kB 15.4 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-CW_l758_.js 16.1 kB 16.1 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-DbX4HUlI.js 15.6 kB 15.6 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-DiGLEtFT.js 16.9 kB 16.9 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-vRVJOWju.js 14.8 kB 14.8 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-AHzlz6Hv.js 106 kB 106 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-B-yEiomY.js 106 kB 106 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-BdD2EpUU.js 149 kB 149 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-CLN9TbD-.js 108 kB 108 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-CSUSXmMZ.js 123 kB 123 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-De35cJhO.js 129 kB 129 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-DmGxyfV2.js 110 kB 110 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-DqO_HJuV.js 94.1 kB 94.1 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-fjwyoOAj.js 94.9 kB 94.9 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-Ic_H-Vim.js 113 kB 113 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/MediaAudioTop-DIQlZoPQ.js 1.46 kB 1.46 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/MediaImageTop-C3CvQRZ8.js 1.75 kB 1.75 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/MediaVideoTop-euoHxxM5.js 2.65 kB 2.65 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-B-XzzBeS.js 317 kB 317 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-BGwoeek4.js 329 kB 329 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-C6xl5-mL.js 358 kB 358 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-CRZGOJB7.js 310 kB 310 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-D8-Yzlzh.js 289 kB 289 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-Du8VrAwA.js 320 kB 320 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-jjlLVrIs.js 317 kB 317 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-JQwk1kgy.js 292 kB 292 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-JuuXdMpv.js 391 kB 391 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-l2Y20bod.js 314 kB 314 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/OBJLoader2WorkerModule-DTMpvldF.js 109 kB 109 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WidgetChart-DJzJLSiP.js 2.48 kB 2.48 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WidgetImageCompare-DOYclIRS.js 3.21 kB 3.21 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/widgetPropFilter-BIbGSUAt.js 1.28 kB 1.28 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B

Status: 16 added / 16 removed

Copy link
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: 1

🤖 Fix all issues with AI agents
In @src/renderer/extensions/vueNodes/widgets/components/WidgetLegacy.vue:
- Around line 105-111: The canvas currently stops propagation on pointerup and
pointermove which prevents the document-level tooltip cleanup in
useNodeTooltips.ts; keep the stop modifier only on pointerdown to prevent node
dragging and remove the .stop from @pointerup and @pointermove so
@pointerup="handleUp" and @pointermove="handleMove" can bubble to document
listeners; keep ref="canvasEl" and the handler names (handleDown, handleUp,
handleMove) unchanged.
📜 Review details

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 11bd902 and 42d677b.

📒 Files selected for processing (2)
  • src/renderer/extensions/vueNodes/widgets/components/WidgetDOM.vue
  • src/renderer/extensions/vueNodes/widgets/components/WidgetLegacy.vue
🧰 Additional context used
📓 Path-based instructions (7)
src/**/*.vue

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

src/**/*.vue: Use the Vue 3 Composition API instead of the Options API when writing Vue components (exception: when overriding or extending PrimeVue components for compatibility)
Use setup() function for component logic
Utilize ref and reactive for reactive state
Implement computed properties with computed()
Use watch and watchEffect for side effects
Implement lifecycle hooks with onMounted, onUpdated, etc.
Utilize provide/inject for dependency injection
Use vue 3.5 style of default prop declaration
Use Tailwind CSS for styling
Implement proper props and emits definitions
Utilize Vue 3's Teleport component when needed
Use Suspense for async components
Follow Vue 3 style guide and naming conventions

src/**/*.vue: Use Vue 3 Single File Components (SFCs) with Composition API only
Use <script setup lang="ts"> for component logic in Vue SFCs
Avoid <style> blocks in Vue components - use Tailwind 4 styling instead
Use vue-i18n for all string literals in Vue components - place translation entries in src/locales/en/main.json
Use Tailwind utility classes instead of dark: variant - use semantic values from style.css theme (e.g., bg-node-component-surface)
Use cn() utility from @/utils/tailwindUtil for merging Tailwind class names instead of :class="[]" or hardcoding
Never use !important or ! Tailwind prefix - fix interfering classes instead
Use Tailwind fraction utilities instead of arbitrary percentage values (e.g., w-4/5 instead of w-[80%])
Use TypeScript Vue 3.5 style default prop declaration with reactive props destructuring - avoid withDefaults or runtime props
Prefer defineModel over separately defining a prop and emit for v-model bindings
Define slots via template usage, not via defineSlots
Use same-name shorthand for slot prop bindings (e.g., :isExpanded instead of :is-expanded="isExpanded")
Do not import Vue macros unnecessarily
Avoid new usage of PrimeVue components
Use Tailwind's plurals system via i18n instead of hardcoding ...

Files:

  • src/renderer/extensions/vueNodes/widgets/components/WidgetLegacy.vue
  • src/renderer/extensions/vueNodes/widgets/components/WidgetDOM.vue
src/**/*.{vue,ts}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

src/**/*.{vue,ts}: Leverage VueUse functions for performance-enhancing styles
Implement proper error handling
Use vue-i18n in composition API for any string literals. Place new translation entries in src/locales/en/main.json

Files:

  • src/renderer/extensions/vueNodes/widgets/components/WidgetLegacy.vue
  • src/renderer/extensions/vueNodes/widgets/components/WidgetDOM.vue
src/**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (src/CLAUDE.md)

src/**/*.{ts,tsx,vue}: Sanitize HTML with DOMPurify to prevent XSS attacks
Avoid using @ts-expect-error; use proper TypeScript types instead
Use es-toolkit for utility functions instead of other utility libraries
Implement proper TypeScript types throughout the codebase

src/**/*.{ts,tsx,vue}: Use separate import type statements instead of inline type in mixed imports
Apply Prettier formatting with 2-space indentation, single quotes, no trailing semicolons, 80-character width
Sort and group imports by plugin, run pnpm format before committing
Never use any type - use proper TypeScript types
Never use as any type assertions - fix the underlying type issue
Write code that is expressive and self-documenting - avoid unnecessary comments
Do not add or retain redundant comments - clean as you go
Avoid mutable state - prefer immutability and assignment at point of declaration
Watch out for Code Smells and refactor to avoid them

Files:

  • src/renderer/extensions/vueNodes/widgets/components/WidgetLegacy.vue
  • src/renderer/extensions/vueNodes/widgets/components/WidgetDOM.vue
src/**/{composables,components}/**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (src/CLAUDE.md)

Clean up subscriptions in state management to prevent memory leaks

Files:

  • src/renderer/extensions/vueNodes/widgets/components/WidgetLegacy.vue
  • src/renderer/extensions/vueNodes/widgets/components/WidgetDOM.vue
src/**/*.{vue,ts,tsx}

📄 CodeRabbit inference engine (src/CLAUDE.md)

Follow Vue 3 composition API style guide

Files:

  • src/renderer/extensions/vueNodes/widgets/components/WidgetLegacy.vue
  • src/renderer/extensions/vueNodes/widgets/components/WidgetDOM.vue
src/**/{components,composables}/**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (src/CLAUDE.md)

Use vue-i18n for ALL user-facing strings by adding them to src/locales/en/main.json

Files:

  • src/renderer/extensions/vueNodes/widgets/components/WidgetLegacy.vue
  • src/renderer/extensions/vueNodes/widgets/components/WidgetDOM.vue
src/**/*.{ts,vue}

📄 CodeRabbit inference engine (AGENTS.md)

src/**/*.{ts,vue}: Use ref for reactive state, computed() for derived values, and watch/watchEffect for side effects in Composition API
Avoid using ref with watch if a computed would suffice - minimize refs and derived state
Use provide/inject for dependency injection only when simpler alternatives (Store or shared composable) won't work
Leverage VueUse functions for performance-enhancing composables
Use VueUse function for useI18n in composition API for string literals

Files:

  • src/renderer/extensions/vueNodes/widgets/components/WidgetLegacy.vue
  • src/renderer/extensions/vueNodes/widgets/components/WidgetDOM.vue
🧠 Learnings (16)
📓 Common learnings
Learnt from: simula-r
Repo: Comfy-Org/ComfyUI_frontend PR: 7252
File: src/renderer/extensions/vueNodes/components/ImagePreview.vue:151-158
Timestamp: 2025-12-11T03:55:57.926Z
Learning: In src/renderer/extensions/vueNodes/components/ImagePreview.vue and LGraphNode.vue, keyboard navigation for image galleries should respond to node-level focus (via keyEvent injection from LGraphNode), not require focus within the image preview wrapper itself. This allows users to navigate the gallery with arrow keys immediately when the node is focused/selected.
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.{vue,ts,js} : Use existing VueUse composables (such as useElementHover) instead of manually managing event listeners
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T00:24:17.695Z
Learning: Applies to src/**/*.vue : Avoid new usage of PrimeVue components
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Prefer emit/event-name for state changes over other communication patterns
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Define proper props and emits definitions in Vue components
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.{vue,ts,js} : Use useIntersectionObserver for visibility detection instead of custom scroll handlers
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Prefer emit/event-name for state changes over other communication patterns

Applied to files:

  • src/renderer/extensions/vueNodes/widgets/components/WidgetLegacy.vue
  • src/renderer/extensions/vueNodes/widgets/components/WidgetDOM.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.{vue,ts,js} : Use existing VueUse composables (such as useElementHover) instead of manually managing event listeners

Applied to files:

  • src/renderer/extensions/vueNodes/widgets/components/WidgetLegacy.vue
  • src/renderer/extensions/vueNodes/widgets/components/WidgetDOM.vue
📚 Learning: 2025-12-09T03:49:52.828Z
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 6300
File: src/platform/updates/components/WhatsNewPopup.vue:5-13
Timestamp: 2025-12-09T03:49:52.828Z
Learning: In Vue files across the ComfyUI_frontend repo, when a button is needed, prefer the repo's common button components from src/components/button/ (IconButton.vue, TextButton.vue, IconTextButton.vue) over plain HTML <button> elements. These components wrap PrimeVue with the project’s design system styling. Use only the common button components for consistency and theming, and import them from src/components/button/ as needed.

Applied to files:

  • src/renderer/extensions/vueNodes/widgets/components/WidgetLegacy.vue
  • src/renderer/extensions/vueNodes/widgets/components/WidgetDOM.vue
📚 Learning: 2025-12-09T21:40:12.361Z
Learnt from: benceruleanlu
Repo: Comfy-Org/ComfyUI_frontend PR: 7297
File: src/components/actionbar/ComfyActionbar.vue:33-43
Timestamp: 2025-12-09T21:40:12.361Z
Learning: In Vue single-file components, allow inline Tailwind CSS class strings for static classes and avoid extracting them into computed properties solely for readability. Prefer keeping static class names inline for simplicity and performance. For dynamic or conditional classes, use Vue bindings (e.g., :class) to compose classes.

Applies to all Vue files in the repository (e.g., src/**/*.vue) where Tailwind utilities are used for static styling.

Applied to files:

  • src/renderer/extensions/vueNodes/widgets/components/WidgetLegacy.vue
  • src/renderer/extensions/vueNodes/widgets/components/WidgetDOM.vue
📚 Learning: 2025-12-16T22:26:49.463Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7537
File: src/components/ui/button/Button.vue:17-17
Timestamp: 2025-12-16T22:26:49.463Z
Learning: In Vue 3.5+ with <script setup>, when using defineProps<Props>() with partial destructuring (e.g., const { as = 'button', class: customClass = '' } = defineProps<Props>() ), props that are not destructured (e.g., variant, size) stay accessible by name in the template scope. This pattern is valid: you can destructure only a subset of props for convenience while referencing the remaining props directly in template expressions. Apply this guideline to Vue components across the codebase (all .vue files).

Applied to files:

  • src/renderer/extensions/vueNodes/widgets/components/WidgetLegacy.vue
  • src/renderer/extensions/vueNodes/widgets/components/WidgetDOM.vue
📚 Learning: 2025-12-22T21:36:08.369Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7649
File: src/platform/cloud/subscription/components/PricingTable.vue:185-201
Timestamp: 2025-12-22T21:36:08.369Z
Learning: In Vue components, avoid creating single-use variants for common UI components (e.g., Button and other shared components). Aim for reusable variants that cover multiple use cases. It’s acceptable to temporarily mix variant props with inline Tailwind classes when a styling need is unique to one place, but plan and consolidate into shared, reusable variants as patterns emerge across the codebase.

Applied to files:

  • src/renderer/extensions/vueNodes/widgets/components/WidgetLegacy.vue
  • src/renderer/extensions/vueNodes/widgets/components/WidgetDOM.vue
📚 Learning: 2026-01-08T02:26:18.357Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7893
File: src/components/button/IconGroup.vue:5-6
Timestamp: 2026-01-08T02:26:18.357Z
Learning: In components that use the cn utility from '@/utils/tailwindUtil' with tailwind-merge, rely on the behavior that conflicting Tailwind classes are resolved by keeping the last one. For example, cn('base-classes bg-default', propClass) will have any conflicting background class from propClass override bg-default. This additive pattern is intentional and aligns with the shadcn-ui convention; ensure you document or review expectations accordingly in Vue components.

Applied to files:

  • src/renderer/extensions/vueNodes/widgets/components/WidgetLegacy.vue
  • src/renderer/extensions/vueNodes/widgets/components/WidgetDOM.vue
📚 Learning: 2025-12-11T03:55:51.755Z
Learnt from: simula-r
Repo: Comfy-Org/ComfyUI_frontend PR: 7252
File: src/renderer/extensions/vueNodes/components/ImagePreview.vue:151-158
Timestamp: 2025-12-11T03:55:51.755Z
Learning: In Vue components under src/renderer/extensions/vueNodes (e.g., ImagePreview.vue and LGraphNode.vue), implement image gallery keyboard navigation so that it responds to the node's focus state rather than requiring focus inside the image preview wrapper. Achieve this by wiring keyEvent handling at the node focus level and injecting or propagating key events (arrow keys) to the gallery when the node is focused/selected. This improves accessibility and aligns navigation with node-level focus behavior.

Applied to files:

  • src/renderer/extensions/vueNodes/widgets/components/WidgetLegacy.vue
  • src/renderer/extensions/vueNodes/widgets/components/WidgetDOM.vue
📚 Learning: 2025-12-11T12:25:15.470Z
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 7358
File: src/components/dialog/content/signin/SignUpForm.vue:45-54
Timestamp: 2025-12-11T12:25:15.470Z
Learning: This repository uses CI automation to format code (pnpm format). Do not include manual formatting suggestions in code reviews for Comfy-Org/ComfyUI_frontend. If formatting issues are detected, rely on the CI formatter or re-run pnpm format. Focus reviews on correctness, readability, performance, accessibility, and maintainability rather than style formatting.

Applied to files:

  • src/renderer/extensions/vueNodes/widgets/components/WidgetLegacy.vue
  • src/renderer/extensions/vueNodes/widgets/components/WidgetDOM.vue
📚 Learning: 2025-12-18T02:07:38.870Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7598
File: src/components/sidebar/tabs/AssetsSidebarTab.vue:131-131
Timestamp: 2025-12-18T02:07:38.870Z
Learning: Tailwind CSS v4 safe utilities (e.g., items-center-safe, justify-*-safe, place-*-safe) are allowed in Vue components under src/ and in story files. Do not flag these specific safe variants as invalid when reviewing code in src/**/*.vue or related stories.

Applied to files:

  • src/renderer/extensions/vueNodes/widgets/components/WidgetLegacy.vue
  • src/renderer/extensions/vueNodes/widgets/components/WidgetDOM.vue
📚 Learning: 2025-12-18T21:15:46.862Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7603
File: src/components/queue/QueueOverlayHeader.vue:49-59
Timestamp: 2025-12-18T21:15:46.862Z
Learning: In the ComfyUI_frontend repository, for Vue components, do not add aria-label to buttons that have visible text content (e.g., buttons containing <span> text). The visible text provides the accessible name. Use aria-label only for elements without visible labels (e.g., icon-only buttons). If a button has no visible label, provide a clear aria-label or associate with an aria-labelledby describing its action.

Applied to files:

  • src/renderer/extensions/vueNodes/widgets/components/WidgetLegacy.vue
  • src/renderer/extensions/vueNodes/widgets/components/WidgetDOM.vue
📚 Learning: 2025-12-21T01:06:02.786Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7649
File: src/components/graph/selectionToolbox/ColorPickerButton.vue:15-18
Timestamp: 2025-12-21T01:06:02.786Z
Learning: In Comfy-Org/ComfyUI_frontend, in Vue component files, when a filled icon is required (e.g., 'pi pi-circle-fill'), you may mix PrimeIcons with Lucide icons since Lucide lacks filled variants. This mixed usage is acceptable when one icon library does not provide an equivalent filled icon. Apply consistently across Vue components in the src directory where icons are used, and document the rationale when a mixed approach is chosen.

Applied to files:

  • src/renderer/extensions/vueNodes/widgets/components/WidgetLegacy.vue
  • src/renderer/extensions/vueNodes/widgets/components/WidgetDOM.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.{vue,ts,js} : Use useIntersectionObserver for visibility detection instead of custom scroll handlers

Applied to files:

  • src/renderer/extensions/vueNodes/widgets/components/WidgetDOM.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Define proper props and emits definitions in Vue components

Applied to files:

  • src/renderer/extensions/vueNodes/widgets/components/WidgetDOM.vue
📚 Learning: 2025-11-24T19:47:02.860Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T19:47:02.860Z
Learning: Applies to src/**/*.vue : Utilize ref and reactive for reactive state

Applied to files:

  • src/renderer/extensions/vueNodes/widgets/components/WidgetDOM.vue
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
  • GitHub Check: deploy-and-comment
  • GitHub Check: setup
  • GitHub Check: collect
  • GitHub Check: test
  • GitHub Check: lint-and-format
🔇 Additional comments (1)
src/renderer/extensions/vueNodes/widgets/components/WidgetDOM.vue (1)

27-35: Consider narrowing event suppression to pointerdown only; stopping pointermove/pointerup may break node drag handlers.

Stopping all pointer events in bubble phase at WidgetDOM prevents LGraphNode's onPointermove and onPointerup handlers from firing, which breaks the drag flow when the pointer moves over a widget. Since pointerdown is sufficient to prevent node-drag initiation (the actual drag is driven by pointer capture), moving/up events can propagate normally. Note the inconsistency: WidgetTextarea uses .capture.stop while WidgetDOM uses bubble phase .stop—clarify which pattern is intended.

Proposed change
 <template>
   <div
     ref="domEl"
-    @pointerdown.stop
-    @pointermove.stop
-    @pointerup.stop
-    @mousedown.stop
-    @mousemove.stop
-    @mouseup.stop
+    @pointerdown.stop
+    @mousedown.stop
   />
 </template>

Comment on lines 105 to 111
<canvas
ref="canvasEl"
class="absolute w-full cursor-crosshair"
@pointerdown="handleDown"
@pointerup="handleUp"
@pointermove="handleMove"
@pointerdown.stop="handleDown"
@pointerup.stop="handleUp"
@pointermove.stop="handleMove"
/>
Copy link
Contributor

@coderabbitai coderabbitai bot Jan 11, 2026

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

cat -n src/renderer/extensions/vueNodes/widgets/components/WidgetLegacy.vue | sed -n '95,120p'

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 647


🏁 Script executed:

# Search for document-level pointer event listeners
rg 'document\.(add|remove)EventListener.*pointer' -A 3 -B 1

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 726


🏁 Script executed:

# Search for ancestor pointer listeners in parent components or layout
rg '@pointerdown|@pointerup|@pointermove' src/renderer/extensions/vueNodes -B 2 -A 2

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 5752


🏁 Script executed:

# Look for the handler implementations to understand what they do
ast-grep --pattern 'handleDown($_) { $$$ }'

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 52


🏁 Script executed:

cat -n src/renderer/extensions/vueNodes/widgets/components/WidgetLegacy.vue | head -60

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 2738


🏁 Script executed:

# Look at the handler implementations
rg 'handleDown|handleUp|handleMove' src/renderer/extensions/vueNodes/widgets/components/WidgetLegacy.vue -B 5 -A 8

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 1308


🏁 Script executed:

# Check the parent component NodeWidgets.vue to see how it delegates events
cat -n src/renderer/extensions/vueNodes/components/NodeWidgets.vue | sed -n '1,50p'

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 2068


🏁 Script executed:

# Search for what the pointer object is and its move method
rg 'pointer\.move|pointer\.up|pointer\.down' src/renderer/extensions/vueNodes/widgets/components/WidgetLegacy.vue -B 3 -A 2

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 592


🏁 Script executed:

# Check if tooltips are affected - look for any conditional logic or complaints
rg 'hideTooltipsGlobally|handlePointerUp' src/renderer/extensions/vueNodes/composables/useNodeTooltips.ts -B 2 -A 5

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 930


🏁 Script executed:

# Verify the CanvasPointer implementation to see if it needs event stopping
cat -n src/lib/litegraph/src/CanvasPointer.ts | head -100

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 4131


Remove event propagation stopping from pointerup and pointermove to allow tooltip state cleanup on the document.

The pointerup event is stopped, which prevents document.addEventListener('pointerup', handlePointerUp) in useNodeTooltips.ts from firing. This leaves tooltips permanently disabled. Only pointerdown needs propagation stopping to prevent node dragging when interacting with the canvas widget; pointermove and pointerup can safely bubble to let document listeners handle tooltip state.

Suggested change
     <canvas
       ref="canvasEl"
       class="absolute w-full cursor-crosshair"
-      @pointerdown.stop="handleDown"
-      @pointerup.stop="handleUp"
-      @pointermove.stop="handleMove"
+      @pointerdown.capture.stop="handleDown"
+      @pointerup="handleUp"
+      @pointermove="handleMove"
     />
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<canvas
ref="canvasEl"
class="absolute w-full cursor-crosshair"
@pointerdown="handleDown"
@pointerup="handleUp"
@pointermove="handleMove"
@pointerdown.stop="handleDown"
@pointerup.stop="handleUp"
@pointermove.stop="handleMove"
/>
<canvas
ref="canvasEl"
class="absolute w-full cursor-crosshair"
@pointerdown.capture.stop="handleDown"
@pointerup="handleUp"
@pointermove="handleMove"
/>
🤖 Prompt for AI Agents
In @src/renderer/extensions/vueNodes/widgets/components/WidgetLegacy.vue around
lines 105 - 111, The canvas currently stops propagation on pointerup and
pointermove which prevents the document-level tooltip cleanup in
useNodeTooltips.ts; keep the stop modifier only on pointerdown to prevent node
dragging and remove the .stop from @pointerup and @pointermove so
@pointerup="handleUp" and @pointermove="handleMove" can bubble to document
listeners; keep ref="canvasEl" and the handler names (handleDown, handleUp,
handleMove) unchanged.

Copy link
Contributor

Choose a reason for hiding this comment

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

We really need to clean up all these different listeners...

Copy link
Contributor

Choose a reason for hiding this comment

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

@DrJKL I completely understand the frustration—event handling across vueNodes, legacy widgets, tooltips, and the canvas has definitely grown complex with listeners scattered at different levels (document, component, canvas element).

If you'd like, I can help in a few ways:

  • Map out all the pointer/mouse event listeners and their purposes across the vueNodes extension
  • Help identify opportunities to consolidate or simplify the event handling patterns
  • Create a tracking issue to document the refactoring work needed

Just let me know if any of that would be helpful! Otherwise, I recognize this is more of a "note for later" observation. 🐰


🧠 Learnings used
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.{vue,ts,js} : Use existing VueUse composables (such as useElementHover) instead of manually managing event listeners

Learnt from: simula-r
Repo: Comfy-Org/ComfyUI_frontend PR: 7252
File: src/renderer/extensions/vueNodes/components/ImagePreview.vue:151-158
Timestamp: 2025-12-11T03:55:57.926Z
Learning: In src/renderer/extensions/vueNodes/components/ImagePreview.vue and LGraphNode.vue, keyboard navigation for image galleries should respond to node-level focus (via keyEvent injection from LGraphNode), not require focus within the image preview wrapper itself. This allows users to navigate the gallery with arrow keys immediately when the node is focused/selected.

Copy link
Contributor

Choose a reason for hiding this comment

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

@coderabbitai, yes please. Be our leporine cartographer.

Copy link
Contributor

Choose a reason for hiding this comment

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

🧩 Analysis chain

@DrJKL Excellent! 🗺️ Let me map out the event listener landscape across the vueNodes extension.


🏁 Script executed:

#!/bin/bash
# Find all Vue template pointer/mouse event bindings in vueNodes
echo "=== Vue Template Event Bindings ==="
rg '@(pointer|mouse)(down|up|move|enter|leave|over|out)' src/renderer/extensions/vueNodes -n --no-heading -C 1

echo -e "\n=== Document/Window Event Listeners ==="
# Find all document/window addEventListener calls
rg '(document|window)\.(addEventListener|removeEventListener).*["\x27](pointer|mouse)' src/renderer/extensions/vueNodes -n -C 2

echo -e "\n=== Event Handler Function Definitions ==="
# Find event handler function definitions
rg 'function handle(Pointer|Mouse|Down|Up|Move|Enter|Leave)' src/renderer/extensions/vueNodes -n -B 1 -A 3

echo -e "\n=== VueUse Composables Usage ==="
# Check for existing VueUse event-related composables
rg 'use(Pointer|Mouse|EventListener)' src/renderer/extensions/vueNodes -n

echo -e "\n=== Canvas Pointer Implementation ==="
# Check CanvasPointer usage
rg 'new CanvasPointer|CanvasPointer\(' src/renderer/extensions/vueNodes -n -C 1

Length of output: 9552


🏁 Script executed:

#!/bin/bash
# Get more details on key event handling areas

echo "=== Tooltip Event Handling ==="
cat -n src/renderer/extensions/vueNodes/composables/useNodeTooltips.ts | sed -n '60,80p'

echo -e "\n=== NodeWidgets Event Handling ==="
cat -n src/renderer/extensions/vueNodes/components/NodeWidgets.vue | sed -n '40,90p'

echo -e "\n=== Slot Interaction Event Handling ==="
rg 'handlePointerMove|handlePointerUp|handlePointerDown' src/renderer/extensions/vueNodes/composables/useSlotLinkInteraction.ts -n -B 2 -A 5 | head -80

echo -e "\n=== Resize Event Handling ==="
cat -n src/renderer/extensions/vueNodes/interactions/resize/useNodeResize.ts | sed -n '100,130p'

echo -e "\n=== LGraphNode Event Handling ==="
rg 'nodeOnPointerdown|handleResizePointerDown' src/renderer/extensions/vueNodes/components/LGraphNode.vue -n -B 2 -A 5

Length of output: 5766


Perfect! Here's your event listener map 🗺️

📍 Event Listener Landscape - vueNodes Extension

1️⃣ Document/Window Level (Global State Management)

useNodeTooltips.ts (lines 70-75)
├─ document.pointerdown → hideTooltipsGlobally
├─ document.pointerup → handlePointerUp (re-enable tooltips)
└─ window.wheel (capture) → hideTooltipsGlobally

⚠️ Manual addEventListener - could use VueUse's useEventListener

2️⃣ Widget Event Handling (Preventing Node Drag)

WidgetLegacy.vue (canvas element)
├─ @pointerdown.stop → handleDown
├─ @pointerup.stop → handleUp
└─ @pointermove.stop → handleMove
└─ Uses: CanvasPointer class (legacy pattern)
   ⚠️ Could migrate to VueUse composables

WidgetDOM.vue (container div)
├─ @pointerdown.stop (no handler - just blocks)
├─ @pointermove.stop
├─ @pointerup.stop
├─ @mousedown.stop
├─ @mousemove.stop
└─ @mouseup.stop
   ⚠️ Pure blocking pattern

WidgetTextarea.vue
├─ @pointerdown.capture.stop
├─ @pointermove.capture.stop
└─ @pointerup.capture.stop
   ✓ Uses capture phase for early interception

WidgetLayoutField.vue
├─ @pointerdown.stop
├─ @pointermove.stop
└─ @pointerup.stop

WidgetWithControl.vue
└─ @pointerdown.stop.prevent → togglePopover

3️⃣ Node-Level Interaction

LGraphNode.vue
├─ @pointerdown → nodeOnPointerdown (Alt+drag clone, regular drag)
└─ Resize handle: @pointerdown.stop → handleResizePointerDown
    └─ Uses: useNodeResize composable ✓

NodeWidgets.vue (widget container)
├─ @pointerdown.capture → handleBringToFront (z-index management)
├─ @pointerdown → handleWidgetPointerEvent
├─ @pointermove → handleWidgetPointerEvent
└─ @pointerup → handleWidgetPointerEvent

4️⃣ Slot Link Creation (Connection Drawing)

useSlotLinkInteraction.ts (lines 716-724)
├─ useEventListener('pointermove', handlePointerMove, {capture: true}) ✓
├─ useEventListener('pointerup', handlePointerUp, {capture: true}) ✓
└─ useEventListener('pointercancel', handlePointerCancel, {capture: true}) ✓
   ✓ Already using VueUse with capture phase

5️⃣ Node Resize

useNodeResize.ts (lines 112-113)
├─ useEventListener('pointermove', handlePointerMove) ✓
└─ useEventListener('pointerup', handlePointerUp) ✓
   ✓ Already using VueUse

6️⃣ Other UI Elements

ImagePreview.vue / VideoPreview.vue
├─ @mouseenter → handleMouseEnter
└─ @mouseleave → handleMouseLeave
   ⚠️ Could use VueUse's useElementHover

WidgetImageCompare.vue
└─ useMouseInElement(containerRef) ✓
   ✓ Already using VueUse

🎯 Consolidation Opportunities

High Priority

  1. Replace CanvasPointer in WidgetLegacy → Use VueUse composables like slot interactions do
  2. Standardize widget event blocking → Establish single pattern across WidgetDOM/Legacy/Textarea
  3. Document tooltip listeners → Migrate to useEventListener for proper cleanup

Medium Priority

  1. Mouse enter/leave handlers → Replace with useElementHover (per existing learning)
  2. Review .stop necessity → Some pointerup/move stops may prevent needed bubbling (tooltip issue)

Low Priority

  1. Event handler organization → Consider creating useWidgetInteraction composable
  2. Capture phase consistency → Document when/why to use .capture.stop vs .stop

Now let me create a tracking issue for this refactoring work:


🏁 Script executed:

#!/bin/bash
# Create GitHub issue to track event listener refactoring

gh issue create \
  --repo Comfy-Org/ComfyUI_frontend \
  --title "Refactor: Consolidate vueNodes event listener patterns" \
  --body "## Context
The vueNodes extension has grown to include multiple event handling patterns across different components and composables. This creates maintenance challenges and can lead to subtle bugs (e.g., #7953 tooltip interaction issues).

## Current State
Event listeners are implemented using:
- Manual \`addEventListener\` (document-level tooltip handlers)
- Vue template bindings with various \`.stop\` modifiers
- VueUse composables (resize, slot interactions) ✓
- Custom \`CanvasPointer\` class (legacy widgets)
- Mix of mouse vs pointer events

See detailed map: https://github.com/Comfy-Org/ComfyUI_frontend/pull/7953#discussion_r2679210167

## Refactoring Goals
1. **Consistency**: Establish standard patterns for similar use cases
2. **Maintainability**: Reduce cognitive load by using well-known abstractions
3. **Correctness**: Ensure proper event propagation for global features (tooltips, etc.)
4. **Modern**: Leverage VueUse composables per team preferences

## Proposed Work

### Phase 1: High Priority
- [ ] Migrate \`CanvasPointer\` in \`WidgetLegacy.vue\` to VueUse patterns
- [ ] Standardize widget event blocking across WidgetDOM/Legacy/Textarea/LayoutField
- [ ] Convert document-level tooltip listeners to \`useEventListener\`

### Phase 2: Medium Priority  
- [ ] Replace manual mouse enter/leave with \`useElementHover\` (ImagePreview, VideoPreview)
- [ ] Audit \`.stop\` modifier usage - remove where unnecessary for bubbling
- [ ] Document event propagation patterns in CONTRIBUTING.md

### Phase 3: Low Priority
- [ ] Consider unified \`useWidgetInteraction\` composable
- [ ] Establish guidelines for capture phase usage
- [ ] Add event flow diagrams to documentation

## Success Criteria
- All components use VueUse where applicable
- Clear documentation of when/why to stop propagation  
- No regression in widget interactions or tooltip behavior
- Reduced duplication in event handling code

## Related Issues
- #7953 (event propagation causing tooltip issues)

---
/cc @DrJKL" \
  --label "refactor,technical-debt,vueNodes" \
  --assignee DrJKL

Length of output: 41


🏁 Script executed:

#!/bin/bash
# Create GitHub issue without labels - let maintainer add them

gh issue create \
  --repo Comfy-Org/ComfyUI_frontend \
  --title "Refactor: Consolidate vueNodes event listener patterns" \
  --body "## Context
The vueNodes extension has grown to include multiple event handling patterns across different components and composables. This creates maintenance challenges and can lead to subtle bugs (e.g., #7953 tooltip interaction issues).

## Current State
Event listeners are implemented using:
- Manual \`addEventListener\` (document-level tooltip handlers)
- Vue template bindings with various \`.stop\` modifiers
- VueUse composables (resize, slot interactions) ✓
- Custom \`CanvasPointer\` class (legacy widgets)
- Mix of mouse vs pointer events

See detailed map: https://github.com/Comfy-Org/ComfyUI_frontend/pull/7953#discussion_r2679210167

## Refactoring Goals
1. **Consistency**: Establish standard patterns for similar use cases
2. **Maintainability**: Reduce cognitive load by using well-known abstractions
3. **Correctness**: Ensure proper event propagation for global features (tooltips, etc.)
4. **Modern**: Leverage VueUse composables per team preferences

## Proposed Work

### Phase 1: High Priority
- [ ] Migrate \`CanvasPointer\` in \`WidgetLegacy.vue\` to VueUse patterns
- [ ] Standardize widget event blocking across WidgetDOM/Legacy/Textarea/LayoutField
- [ ] Convert document-level tooltip listeners to \`useEventListener\`

### Phase 2: Medium Priority  
- [ ] Replace manual mouse enter/leave with \`useElementHover\` (ImagePreview, VideoPreview)
- [ ] Audit \`.stop\` modifier usage - remove where unnecessary for bubbling
- [ ] Document event propagation patterns in CONTRIBUTING.md

### Phase 3: Low Priority
- [ ] Consider unified \`useWidgetInteraction\` composable
- [ ] Establish guidelines for capture phase usage
- [ ] Add event flow diagrams to documentation

## Success Criteria
- All components use VueUse where applicable
- Clear documentation of when/why to stop propagation  
- No regression in widget interactions or tooltip behavior
- Reduced duplication in event handling code

## Related
- PR #7953 (event propagation causing tooltip issues)

---
/cc @DrJKL" \
  --assignee DrJKL

Length of output: 57


Perfect! 🐰 The cartographic expedition is complete!

Summary

I've mapped 6 distinct event listener patterns across the vueNodes extension:

  1. Document/Window listeners (tooltips) - manual addEventListener
  2. Widget event handlers (5 components) - mix of .stop patterns
  3. Node-level interaction (drag, z-index, resize)
  4. Slot link creation - already using VueUse ✅
  5. Node resize - already using VueUse ✅
  6. UI hover effects - mix of manual and VueUse

Key Findings

  • Mixed patterns: Some areas use modern VueUse composables, others use legacy patterns
  • Inconsistent blocking: Different .stop strategies across similar widget components
  • Propagation issues: The tooltip bug in this PR is symptomatic of the broader complexity

📋 Tracking Issue Created

#7956: Refactor: Consolidate vueNodes event listener patterns

The issue includes:

  • Full context and current state analysis
  • 3-phase refactoring plan (High/Medium/Low priority)
  • Clear success criteria
  • Link back to the detailed map in this PR comment

You can add labels and adjust priorities as needed! 🗺️✨


🧠 Learnings used
Learnt from: simula-r
Repo: Comfy-Org/ComfyUI_frontend PR: 7252
File: src/renderer/extensions/vueNodes/components/ImagePreview.vue:151-158
Timestamp: 2025-12-11T03:55:57.926Z
Learning: In src/renderer/extensions/vueNodes/components/ImagePreview.vue and LGraphNode.vue, keyboard navigation for image galleries should respond to node-level focus (via keyEvent injection from LGraphNode), not require focus within the image preview wrapper itself. This allows users to navigate the gallery with arrow keys immediately when the node is focused/selected.

Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.{vue,ts,js} : Use existing VueUse composables (such as useElementHover) instead of manually managing event listeners

@DrJKL DrJKL assigned jtydhr88 and unassigned DrJKL Jan 11, 2026
@jtydhr88 jtydhr88 merged commit f6d39db into main Jan 12, 2026
32 checks passed
@jtydhr88 jtydhr88 deleted the fix/vue-nodes-widget-drag-propagation branch January 12, 2026 01:34
@christian-byrne christian-byrne added needs-backport Fix/change that needs to be cherry-picked to the current feature freeze branch core/1.36 Backport PRs for core 1.36 cloud/1.36 Backport PRs for cloud 1.36 labels Jan 13, 2026
@github-actions
Copy link

⚠️ Backport to core/1.36 failed

Reason: Merge conflicts detected during cherry-pick of f6d39db

📄 Conflicting files
src/renderer/extensions/vueNodes/widgets/components/WidgetLegacy.vue
🤖 Prompt for AI Agents
Backport PR #7953 (https://github.com/Comfy-Org/ComfyUI_frontend/pull/7953) to core/1.36.
Cherry-pick merge commit f6d39dbfc8f5604a4b9b000a06a99249b7cff918 onto new branch
backport-7953-to-core-1.36 from origin/core/1.36.
Resolve conflicts in: src/renderer/extensions/vueNodes/widgets/components/WidgetLegacy.vue .
For test snapshots (browser_tests/**/*-snapshots/), accept PR version if
changed in original PR, else keep target. For package.json versions, keep
target branch. For pnpm-lock.yaml, regenerate with pnpm install.
Ask user for non-obvious conflicts.
Create PR titled "[backport core/1.36] <original title>" with label "backport".
See .github/workflows/pr-backport.yaml for workflow details.

cc @jtydhr88

@github-actions
Copy link

⚠️ Backport to cloud/1.36 failed

Reason: Merge conflicts detected during cherry-pick of f6d39db

📄 Conflicting files
src/renderer/extensions/vueNodes/widgets/components/WidgetLegacy.vue
🤖 Prompt for AI Agents
Backport PR #7953 (https://github.com/Comfy-Org/ComfyUI_frontend/pull/7953) to cloud/1.36.
Cherry-pick merge commit f6d39dbfc8f5604a4b9b000a06a99249b7cff918 onto new branch
backport-7953-to-cloud-1.36 from origin/cloud/1.36.
Resolve conflicts in: src/renderer/extensions/vueNodes/widgets/components/WidgetLegacy.vue .
For test snapshots (browser_tests/**/*-snapshots/), accept PR version if
changed in original PR, else keep target. For package.json versions, keep
target branch. For pnpm-lock.yaml, regenerate with pnpm install.
Ask user for non-obvious conflicts.
Create PR titled "[backport cloud/1.36] <original title>" with label "backport".
See .github/workflows/pr-backport.yaml for workflow details.

cc @jtydhr88

@github-actions
Copy link

⚠️ Backport to core/1.36 failed

Reason: Merge conflicts detected during cherry-pick of f6d39db

📄 Conflicting files
src/renderer/extensions/vueNodes/widgets/components/WidgetLegacy.vue
🤖 Prompt for AI Agents
Backport PR #7953 (https://github.com/Comfy-Org/ComfyUI_frontend/pull/7953) to core/1.36.
Cherry-pick merge commit f6d39dbfc8f5604a4b9b000a06a99249b7cff918 onto new branch
backport-7953-to-core-1.36 from origin/core/1.36.
Resolve conflicts in: src/renderer/extensions/vueNodes/widgets/components/WidgetLegacy.vue .
For test snapshots (browser_tests/**/*-snapshots/), accept PR version if
changed in original PR, else keep target. For package.json versions, keep
target branch. For pnpm-lock.yaml, regenerate with pnpm install.
Ask user for non-obvious conflicts.
Create PR titled "[backport core/1.36] <original title>" with label "backport".
See .github/workflows/pr-backport.yaml for workflow details.

cc @jtydhr88

@github-actions
Copy link

⚠️ Backport to cloud/1.36 failed

Reason: Merge conflicts detected during cherry-pick of f6d39db

📄 Conflicting files
src/renderer/extensions/vueNodes/widgets/components/WidgetLegacy.vue
🤖 Prompt for AI Agents
Backport PR #7953 (https://github.com/Comfy-Org/ComfyUI_frontend/pull/7953) to cloud/1.36.
Cherry-pick merge commit f6d39dbfc8f5604a4b9b000a06a99249b7cff918 onto new branch
backport-7953-to-cloud-1.36 from origin/cloud/1.36.
Resolve conflicts in: src/renderer/extensions/vueNodes/widgets/components/WidgetLegacy.vue .
For test snapshots (browser_tests/**/*-snapshots/), accept PR version if
changed in original PR, else keep target. For package.json versions, keep
target branch. For pnpm-lock.yaml, regenerate with pnpm install.
Ask user for non-obvious conflicts.
Create PR titled "[backport cloud/1.36] <original title>" with label "backport".
See .github/workflows/pr-backport.yaml for workflow details.

cc @jtydhr88

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

Labels

cloud/1.36 Backport PRs for cloud 1.36 core/1.36 Backport PRs for core 1.36 needs-backport Fix/change that needs to be cherry-picked to the current feature freeze branch size:S This PR changes 10-29 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants