Skip to content

Conversation

@Myestery
Copy link
Collaborator

@Myestery Myestery commented Dec 8, 2025

Summary

  • Fix slot link drag and snap/attraction not working on mobile browsers in Vue Nodes 2.0 mode
  • Use document.elementFromPoint() to get the actual element under the pointer instead of relying on event.target

Root Cause

On touch/mobile devices, pointer events have "implicit pointer capture" - when you touch an element, all subsequent pointer events (pointermove, pointerup) for that touch are sent to the same element where the touch started, regardless of where the pointer moves.

The code was using event.target to find slots under the pointer for snap/attraction. On touch devices, this always returned the original slot element (where the drag started), not the element currently under the touch point. This caused:

  • No snap/attraction when dragging links over other slots
  • Connections failing when dropping on target slots

Before

C4E6F7D3-933A-48D6-82DF-093C103F4226.MP4

After

F78736BB-9237-4D02-AABB-F09B844B5B4C.MP4

Test plan

  • Enable Vue Nodes 2.0 mode in settings
  • Test on mobile browser or Chrome DevTools mobile simulation
  • Drag a link from one node's output slot to another node's input slot
  • Verify the link snaps/attracts to compatible slots during drag
  • Verify the connection is made successfully on drop

Fixes #7224

On touch/mobile devices, pointer events have implicit pointer capture,
meaning event.target always stays as the element where the touch started,
not the element currently under the pointer. This caused the slot link
snap/attraction feature to fail on mobile because the code couldn't detect
when the pointer moved over other slots.

Fix by using document.elementFromPoint() to get the actual element under
the pointer position during drag and drop operations.

Fixes #7224
@Myestery Myestery requested a review from a team as a code owner December 8, 2025 21:59
@dosubot dosubot bot added the size:S This PR changes 10-29 lines, ignoring generated files. label Dec 8, 2025
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 8, 2025

📝 Walkthrough

Walkthrough

Added and exported resolvePointerTarget(clientX, clientY, fallback) that uses document.elementFromPoint to determine the element under pointer coordinates; pointer-move and finish/drag-end logic were updated to use it. Added tests validating resolution behavior, fallback, and integration with slot/node detection.

Changes

Cohort / File(s) Change Summary
Pointer target resolution
src/renderer/extensions/vueNodes/composables/useSlotLinkInteraction.ts
Added and exported `resolvePointerTarget(clientX: number, clientY: number, fallback: EventTarget
Tests for pointer resolution
src/renderer/extensions/vueNodes/composables/useSlotLinkInteraction.test.ts
Added Vitest suite that mocks document.elementFromPoint and verifies: element preference, fallback to provided target when null, null result when both absent, touch/pointer-capture scenarios, and ability to locate slot/node via closest() while preserving data attributes.

Possibly related PRs

Pre-merge checks and finishing touches

✅ Passed checks (2 passed)
Check name Status Explanation
Linked Issues check ✅ Passed The pull request implements resolvePointerTarget() to fix mobile/touch pointer capture issues, directly addressing issue #7224's requirement to restore Nodes 2.0 functionality on mobile browsers.
Out of Scope Changes check ✅ Passed All changes are scoped to fixing mobile slot link drag functionality. New helper function, implementation updates, and comprehensive tests are all directly related to addressing pointer target resolution on touch devices.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/mobile-touch-slot-link-drag

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f46fbf9 and 91011e5.

📒 Files selected for processing (1)
  • src/renderer/extensions/vueNodes/composables/useSlotLinkInteraction.test.ts (1 hunks)
🧰 Additional context used
📓 Path-based instructions (12)
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/composables/useSlotLinkInteraction.test.ts
src/**/*.ts

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

src/**/*.ts: Use es-toolkit for utility functions
Use TypeScript for type safety

Files:

  • src/renderer/extensions/vueNodes/composables/useSlotLinkInteraction.test.ts
src/**/{services,composables}/**/*.{ts,tsx}

📄 CodeRabbit inference engine (src/CLAUDE.md)

src/**/{services,composables}/**/*.{ts,tsx}: Use api.apiURL() for backend endpoints instead of constructing URLs directly
Use api.fileURL() for static file access instead of constructing URLs directly

Files:

  • src/renderer/extensions/vueNodes/composables/useSlotLinkInteraction.test.ts
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

Files:

  • src/renderer/extensions/vueNodes/composables/useSlotLinkInteraction.test.ts
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/composables/useSlotLinkInteraction.test.ts
src/**/*.{vue,ts,tsx}

📄 CodeRabbit inference engine (src/CLAUDE.md)

Follow Vue 3 composition API style guide

Files:

  • src/renderer/extensions/vueNodes/composables/useSlotLinkInteraction.test.ts
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/composables/useSlotLinkInteraction.test.ts
**/*.ts

📄 CodeRabbit inference engine (AGENTS.md)

Use TypeScript exclusively; no new JavaScript code

Files:

  • src/renderer/extensions/vueNodes/composables/useSlotLinkInteraction.test.ts
**/*.{ts,vue}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,vue}: Use camelCase for variable and function names
Indent with 2 spaces (see .prettierrc)
Use single quotes for strings (see .prettierrc)
No trailing semicolons (see .prettierrc)
Maximum line width of 80 characters (see .prettierrc)
Sort and group imports by plugin (run pnpm format before committing)
Never use any type; use proper TypeScript types instead
Never use as any type assertions; fix the underlying type issue instead
Avoid code comments unless absolutely necessary; write expressive, self-documenting code instead
When writing new code, ask if there is a simpler way to introduce the same functionality; if yes, choose the simpler approach
Use refactoring to make complex code simpler
Use es-toolkit for utility functions
Use Vite for fast development and building
Implement proper error handling
Write tests for all changes, especially bug fixes to catch future regressions

Files:

  • src/renderer/extensions/vueNodes/composables/useSlotLinkInteraction.test.ts
**/composables/**/use*.ts

📄 CodeRabbit inference engine (AGENTS.md)

Name composables with useXyz.ts pattern

Files:

  • src/renderer/extensions/vueNodes/composables/useSlotLinkInteraction.test.ts
src/**/*.test.ts

📄 CodeRabbit inference engine (AGENTS.md)

Write unit and component tests with Vitest using happy-dom

Files:

  • src/renderer/extensions/vueNodes/composables/useSlotLinkInteraction.test.ts
**/*.test.ts

📄 CodeRabbit inference engine (AGENTS.md)

**/*.test.ts: Avoid writing change detector tests that just assert default values
Avoid writing tests dependent on non-behavioral features like utility classes or styles
Avoid writing redundant tests

Files:

  • src/renderer/extensions/vueNodes/composables/useSlotLinkInteraction.test.ts
🧠 Learnings (13)
📚 Learning: 2025-11-24T19:48:03.270Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: tests-ui/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:48:03.270Z
Learning: Applies to tests-ui/**/*.test.{js,ts,jsx,tsx} : Write tests for new features

Applied to files:

  • src/renderer/extensions/vueNodes/composables/useSlotLinkInteraction.test.ts
📚 Learning: 2025-12-06T00:52:35.750Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-06T00:52:35.750Z
Learning: Applies to src/**/*.test.ts : Write unit and component tests with Vitest using happy-dom

Applied to files:

  • src/renderer/extensions/vueNodes/composables/useSlotLinkInteraction.test.ts
📚 Learning: 2025-12-06T00:52:35.750Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-06T00:52:35.750Z
Learning: Applies to **/*.{ts,vue} : Write tests for all changes, especially bug fixes to catch future regressions

Applied to files:

  • src/renderer/extensions/vueNodes/composables/useSlotLinkInteraction.test.ts
📚 Learning: 2025-11-24T19:47:56.371Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/lib/litegraph/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:56.371Z
Learning: Applies to src/lib/litegraph/**/*.{test,spec}.{js,ts,jsx,tsx} : When adding features, always write vitest unit tests using cursor rules in @.cursor

Applied to files:

  • src/renderer/extensions/vueNodes/composables/useSlotLinkInteraction.test.ts
📚 Learning: 2025-11-24T19:48:03.270Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: tests-ui/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:48:03.270Z
Learning: Applies to tests-ui/**/*.test.{js,ts,jsx,tsx} : Always prefer vitest mock functions over writing verbose manual mocks

Applied to files:

  • src/renderer/extensions/vueNodes/composables/useSlotLinkInteraction.test.ts
📚 Learning: 2025-11-24T19:48:03.270Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: tests-ui/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:48:03.270Z
Learning: Applies to tests-ui/**/*.test.{js,ts,jsx,tsx} : Follow existing test patterns in the codebase

Applied to files:

  • src/renderer/extensions/vueNodes/composables/useSlotLinkInteraction.test.ts
📚 Learning: 2025-11-24T19:48:03.270Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: tests-ui/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:48:03.270Z
Learning: Applies to tests-ui/**/*.test.{js,ts,jsx,tsx} : Use existing test utilities rather than writing custom utilities

Applied to files:

  • src/renderer/extensions/vueNodes/composables/useSlotLinkInteraction.test.ts
📚 Learning: 2025-11-24T19:47:56.371Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/lib/litegraph/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:56.371Z
Learning: Applies to src/lib/litegraph/**/*.{test,spec}.{ts,tsx} : Use provided test helpers `createTestSubgraph` and `createTestSubgraphNode` from `./fixtures/subgraphHelpers` for consistent subgraph test setup

Applied to files:

  • src/renderer/extensions/vueNodes/composables/useSlotLinkInteraction.test.ts
📚 Learning: 2025-11-24T19:47:22.909Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: browser_tests/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:22.909Z
Learning: Applies to browser_tests/**/*.{e2e,spec}.{ts,tsx,js,jsx} : Test across multiple viewports

Applied to files:

  • src/renderer/extensions/vueNodes/composables/useSlotLinkInteraction.test.ts
📚 Learning: 2025-11-24T19:47:22.909Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: browser_tests/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:22.909Z
Learning: Applies to browser_tests/**/*.{e2e,spec}.{ts,tsx,js,jsx} : Prefer specific selectors in browser tests

Applied to files:

  • src/renderer/extensions/vueNodes/composables/useSlotLinkInteraction.test.ts
📚 Learning: 2025-11-24T19:48:09.318Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .cursor/rules/unit-test.mdc:0-0
Timestamp: 2025-11-24T19:48:09.318Z
Learning: Applies to test/**/*.{test,spec}.{js,ts,jsx,tsx} : Use `vitest` for unit testing in this project

Applied to files:

  • src/renderer/extensions/vueNodes/composables/useSlotLinkInteraction.test.ts
📚 Learning: 2025-11-24T19:48:03.270Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: tests-ui/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:48:03.270Z
Learning: Applies to tests-ui/**/*.test.{js,ts,jsx,tsx} : Mock external dependencies in tests

Applied to files:

  • src/renderer/extensions/vueNodes/composables/useSlotLinkInteraction.test.ts
📚 Learning: 2025-11-24T19:48:09.318Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .cursor/rules/unit-test.mdc:0-0
Timestamp: 2025-11-24T19:48:09.318Z
Learning: Applies to test/**/*.{test,spec}.{js,ts,jsx,tsx} : Mocks should be cleanly written and easy to understand, with reusable mocks where possible

Applied to files:

  • src/renderer/extensions/vueNodes/composables/useSlotLinkInteraction.test.ts
🧬 Code graph analysis (1)
src/renderer/extensions/vueNodes/composables/useSlotLinkInteraction.test.ts (1)
src/renderer/extensions/vueNodes/composables/useSlotLinkInteraction.ts (1)
  • resolvePointerTarget (102-108)
⏰ 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). (4)
  • GitHub Check: setup
  • GitHub Check: collect
  • GitHub Check: lint-and-format
  • GitHub Check: test
🔇 Additional comments (5)
src/renderer/extensions/vueNodes/composables/useSlotLinkInteraction.test.ts (5)

1-8: Test structure and mocking approach are solid. Proper use of Vitest's vi.spyOn() (addressing prior feedback) with consistent afterEach cleanup using vi.restoreAllMocks(). Imports are correctly ordered.


10-43: Basic behavior tests are comprehensive. Lines 10–43 cover the three main cases: happy path, null fallback, and both null. Each test is well-named and verifies both the spy call and return value. Good edge-case handling with null checks.


45-85: Touch/mobile pointer capture scenario tests directly validate the bug fix. Lines 45–85 simulate the core issue: implicit pointer capture on touch devices keeping event.target at the initial element while elementFromPoint() correctly returns the element under the pointer. Tests verify (1) resolution to the actual target when dragging over different elements, and (2) fallback to original target when pointer moves outside viewport. This comprehensive coverage ensures the mobile regression is caught.


87-115: Integration test validates real DOM interaction patterns. Lines 87–115 create a realistic nested DOM structure and verify that the returned element works with closest() for traversing to parent slot and node containers, and preserves data-slot-key attributes. This ensures the function integrates correctly with the slot-detection logic that depends on it.


109-113: Type assertion pattern is appropriate. The instanceof check on line 109 followed by as HTMLElement assertion on line 110 is the correct way to narrow types at runtime before using HTMLElement-specific methods (e.g., closest()). This satisfies type safety without circumventing the type system.


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 Dec 8, 2025

🎭 Playwright Test Results

⚠️ Tests passed with flaky tests

⏰ Completed at: 12/08/2025, 11:49:10 PM UTC

📈 Summary

  • Total Tests: 496
  • Passed: 483 ✅
  • Failed: 0
  • Flaky: 3 ⚠️
  • Skipped: 10 ⏭️

📊 Test Reports by Browser

  • chromium: View Report • ✅ 474 / ❌ 0 / ⚠️ 3 / ⏭️ 10
  • chromium-2x: View Report • ✅ 2 / ❌ 0 / ⚠️ 0 / ⏭️ 0
  • chromium-0.5x: View Report • ✅ 1 / ❌ 0 / ⚠️ 0 / ⏭️ 0
  • mobile-chrome: View Report • ✅ 6 / ❌ 0 / ⚠️ 0 / ⏭️ 0

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

@github-actions
Copy link

github-actions bot commented Dec 8, 2025

🎨 Storybook Build Status

Build completed successfully!

⏰ Completed at: 12/08/2025, 11:40:24 PM UTC

🔗 Links


🎉 Your Storybook is ready for review!

@github-actions
Copy link

github-actions bot commented Dec 8, 2025

Bundle Size Report

Summary

  • Raw size: 17.1 MB baseline 17.1 MB — 🔴 +341 B
  • Gzip: 3.38 MB baseline 3.38 MB — 🔴 +82 B
  • Brotli: 2.59 MB baseline 2.59 MB — 🟢 -35 B
  • Bundles: 97 current • 97 baseline • 37 added / 37 removed

Category Glance
App Entry Points 🔴 +341 B (3.21 MB) · Vendor & Third-Party ⚪ 0 B (8.56 MB) · Other ⚪ 0 B (3.81 MB) · Graph Workspace ⚪ 0 B (978 kB) · Panels & Settings ⚪ 0 B (298 kB) · UI Components ⚪ 0 B (177 kB) · + 3 more

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

Main entry bundles and manifests

File Before After Δ Raw Δ Gzip Δ Brotli
assets/index-PAkbE-vy.js (new) 2.98 MB 🔴 +2.98 MB 🔴 +620 kB 🔴 +471 kB
assets/index-BO46-EbG.js (removed) 2.98 MB 🟢 -2.98 MB 🟢 -620 kB 🟢 -471 kB
assets/index-CP7o22Lp.js (removed) 223 kB 🟢 -223 kB 🟢 -47.6 kB 🟢 -39.2 kB
assets/index-DxnRBVJz.js (new) 223 kB 🔴 +223 kB 🔴 +47.6 kB 🔴 +39.3 kB
assets/index-B4EaAnQ3.js (removed) 345 B 🟢 -345 B 🟢 -245 B 🟢 -235 B
assets/index-qql-OkN6.js (new) 345 B 🔴 +345 B 🔴 +246 B 🔴 +233 B

Status: 3 added / 3 removed

Graph Workspace — 978 kB (baseline 978 kB) • ⚪ 0 B

Graph editor runtime, canvas, workflow orchestration

File Before After Δ Raw Δ Gzip Δ Brotli
assets/GraphView-2Jx_JSA0.js (removed) 978 kB 🟢 -978 kB 🟢 -189 kB 🟢 -144 kB
assets/GraphView-CrqK_CDo.js (new) 978 kB 🔴 +978 kB 🔴 +189 kB 🔴 +144 kB

Status: 1 added / 1 removed

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

Top-level views, pages, and routed surfaces

File Before After Δ Raw Δ Gzip Δ Brotli
assets/UserSelectView-7FrDnEjr.js (removed) 6.54 kB 🟢 -6.54 kB 🟢 -2.14 kB 🟢 -1.9 kB
assets/UserSelectView-CqU_kyLz.js (new) 6.54 kB 🔴 +6.54 kB 🔴 +2.14 kB 🔴 +1.9 kB

Status: 1 added / 1 removed

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

Configuration panels, inspectors, and settings screens

File Before After Δ Raw Δ Gzip Δ Brotli
assets/CreditsPanel-BMkqp6I6.js (removed) 21.4 kB 🟢 -21.4 kB 🟢 -5.15 kB 🟢 -4.5 kB
assets/CreditsPanel-C8kJuwj8.js (new) 21.4 kB 🔴 +21.4 kB 🔴 +5.15 kB 🔴 +4.5 kB
assets/KeybindingPanel-CYjVNHQ_.js (new) 13.6 kB 🔴 +13.6 kB 🔴 +3.42 kB 🔴 +3.02 kB
assets/KeybindingPanel-DBI_xB0R.js (removed) 13.6 kB 🟢 -13.6 kB 🟢 -3.42 kB 🟢 -3.01 kB
assets/ExtensionPanel-BiMQv_dY.js (removed) 10.8 kB 🟢 -10.8 kB 🟢 -2.58 kB 🟢 -2.26 kB
assets/ExtensionPanel-Bm-2cADs.js (new) 10.8 kB 🔴 +10.8 kB 🔴 +2.57 kB 🔴 +2.26 kB
assets/AboutPanel-6tOiwIVw.js (removed) 9.16 kB 🟢 -9.16 kB 🟢 -2.46 kB 🟢 -2.21 kB
assets/AboutPanel-CDOTWjGi.js (new) 9.16 kB 🔴 +9.16 kB 🔴 +2.46 kB 🔴 +2.21 kB
assets/ServerConfigPanel-6YJO4YmL.js (removed) 6.56 kB 🟢 -6.56 kB 🟢 -1.83 kB 🟢 -1.63 kB
assets/ServerConfigPanel-BvBXvV4q.js (new) 6.56 kB 🔴 +6.56 kB 🔴 +1.83 kB 🔴 +1.63 kB
assets/UserPanel-C7sl_ZW-.js (new) 6.23 kB 🔴 +6.23 kB 🔴 +1.72 kB 🔴 +1.5 kB
assets/UserPanel-CoV6pL8X.js (removed) 6.23 kB 🟢 -6.23 kB 🟢 -1.72 kB 🟢 -1.5 kB
assets/settings-BhbWhsRg.js 101 B 101 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-BXTtSH4O.js 33.3 kB 33.3 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-C9Pzn-NG.js 25.2 kB 25.2 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-CCy2fA_h.js 27.3 kB 27.3 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-CQpqEFfl.js 26.6 kB 26.6 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-DHcnxypw.js 21.7 kB 21.7 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-DhFTK9fY.js 25.1 kB 25.1 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-DlT4t_ui.js 25.9 kB 25.9 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-DRgSrIdD.js 24.2 kB 24.2 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-tjkeqiZq.js 21.1 kB 21.1 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B

Status: 6 added / 6 removed

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

Reusable component library chunks

File Before After Δ Raw Δ Gzip Δ Brotli
assets/Load3D.vue_vue_type_script_setup_true_lang-CvCAx_JD.js (removed) 53.9 kB 🟢 -53.9 kB 🟢 -8.52 kB 🟢 -7.32 kB
assets/Load3D.vue_vue_type_script_setup_true_lang-DwArE8MQ.js (new) 53.9 kB 🔴 +53.9 kB 🔴 +8.52 kB 🔴 +7.32 kB
assets/WidgetSelect.vue_vue_type_script_setup_true_lang-Cng-_Z_T.js (new) 48 kB 🔴 +48 kB 🔴 +10.3 kB 🔴 +8.97 kB
assets/WidgetSelect.vue_vue_type_script_setup_true_lang-DFahnEKk.js (removed) 48 kB 🟢 -48 kB 🟢 -10.3 kB 🟢 -8.97 kB
assets/LazyImage.vue_vue_type_script_setup_true_lang-G3jUuCsU.js (removed) 46.9 kB 🟢 -46.9 kB 🟢 -10.5 kB 🟢 -9.16 kB
assets/LazyImage.vue_vue_type_script_setup_true_lang-IAMwE01d.js (new) 46.9 kB 🔴 +46.9 kB 🔴 +10.5 kB 🔴 +9.17 kB
assets/WidgetInputNumber.vue_vue_type_script_setup_true_lang-Cd7jNUsL.js (removed) 12.9 kB 🟢 -12.9 kB 🟢 -3.37 kB 🟢 -2.98 kB
assets/WidgetInputNumber.vue_vue_type_script_setup_true_lang-KigfqOAl.js (new) 12.9 kB 🔴 +12.9 kB 🔴 +3.37 kB 🔴 +2.96 kB
assets/ComfyQueueButton-DYXMua3W.js (new) 8.44 kB 🔴 +8.44 kB 🔴 +2.48 kB 🔴 +2.22 kB
assets/ComfyQueueButton-Y2ySGkeH.js (removed) 8.44 kB 🟢 -8.44 kB 🟢 -2.48 kB 🟢 -2.21 kB
assets/MediaTitle.vue_vue_type_script_setup_true_lang-B_DOBMyl.js (removed) 897 B 🟢 -897 B 🟢 -503 B 🟢 -439 B
assets/MediaTitle.vue_vue_type_script_setup_true_lang-iQNQBkeL.js (new) 897 B 🔴 +897 B 🔴 +502 B 🔴 +441 B
assets/UserAvatar.vue_vue_type_script_setup_true_lang-BPGmgVoN.js 1.34 kB 1.34 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WidgetButton-CFWrwaAG.js 2.04 kB 2.04 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WidgetLayoutField.vue_vue_type_script_setup_true_lang-6ZIklFyS.js 2.26 kB 2.26 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B

Status: 6 added / 6 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-BCcDQJrO.js (new) 7.51 kB 🔴 +7.51 kB 🔴 +1.83 kB 🔴 +1.57 kB
assets/keybindingService-CSE105pK.js (removed) 7.51 kB 🟢 -7.51 kB 🟢 -1.84 kB 🟢 -1.58 kB
assets/audioService-CUMvpfPe.js (new) 2.2 kB 🔴 +2.2 kB 🔴 +959 B 🔴 +823 B
assets/audioService-GfT-1gT0.js (removed) 2.2 kB 🟢 -2.2 kB 🟢 -962 B 🟢 -830 B
assets/serverConfigStore-L3qzi_1Z.js 2.83 kB 2.83 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B

Status: 2 added / 2 removed

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

Helpers, composables, and utility bundles

File Before After Δ Raw Δ Gzip Δ Brotli
assets/audioUtils-8XZGxYwx.js (new) 1.41 kB 🔴 +1.41 kB 🔴 +653 B 🔴 +548 B
assets/audioUtils-Ddw4jr50.js (removed) 1.41 kB 🟢 -1.41 kB 🟢 -650 B 🟢 -547 B
assets/mathUtil-CTARWQ-l.js 1.07 kB 1.07 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeFilterUtil-CXKCRJ-m.js 460 B 460 B ⚪ 0 B ⚪ 0 B ⚪ 0 B

Status: 1 added / 1 removed

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

External libraries and shared vendor chunks

File Before After Δ Raw Δ Gzip Δ Brotli
assets/vendor-chart-DJFoH6N_.js 452 kB 452 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-other-BZV8aGUB.js 3.98 MB 3.98 MB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-primevue-DUTcKlCc.js 1.96 MB 1.96 MB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-three-aR6ntw5X.js 1.37 MB 1.37 MB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-tiptap-Cmu0_BY4.js 232 kB 232 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-vue-Bz22sFex.js 160 kB 160 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-xterm-BZLod3g9.js 407 kB 407 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
Other — 3.81 MB (baseline 3.81 MB) • ⚪ 0 B

Bundles that do not match a named category

File Before After Δ Raw Δ Gzip Δ Brotli
assets/WidgetRecordAudio-DjpQwSG7.js (new) 20.4 kB 🔴 +20.4 kB 🔴 +5.24 kB 🔴 +4.64 kB
assets/WidgetRecordAudio-MyxhzeB5.js (removed) 20.4 kB 🟢 -20.4 kB 🟢 -5.23 kB 🟢 -4.63 kB
assets/AudioPreviewPlayer-DdCA09vu.js (new) 13.5 kB 🔴 +13.5 kB 🔴 +3.4 kB 🔴 +3.04 kB
assets/AudioPreviewPlayer-DTdBW3G3.js (removed) 13.5 kB 🟢 -13.5 kB 🟢 -3.4 kB 🟢 -3.04 kB
assets/WidgetGalleria-B_XyhiBH.js (new) 4.1 kB 🔴 +4.1 kB 🔴 +1.45 kB 🔴 +1.3 kB
assets/WidgetGalleria-d5LKR7tk.js (removed) 4.1 kB 🟢 -4.1 kB 🟢 -1.45 kB 🟢 -1.3 kB
assets/WidgetColorPicker-BN5WBkYw.js (new) 3.41 kB 🔴 +3.41 kB 🔴 +1.38 kB 🔴 +1.23 kB
assets/WidgetColorPicker-Y-T374J8.js (removed) 3.41 kB 🟢 -3.41 kB 🟢 -1.38 kB 🟢 -1.23 kB
assets/WidgetMarkdown-Bk1JSRyk.js (removed) 3.08 kB 🟢 -3.08 kB 🟢 -1.28 kB 🟢 -1.12 kB
assets/WidgetMarkdown-jWqtTZAK.js (new) 3.08 kB 🔴 +3.08 kB 🔴 +1.28 kB 🔴 +1.13 kB
assets/WidgetTextarea-CFNuAzSX.js (removed) 2.93 kB 🟢 -2.93 kB 🟢 -1.17 kB 🟢 -1.03 kB
assets/WidgetTextarea-ZRy7bNUK.js (new) 2.93 kB 🔴 +2.93 kB 🔴 +1.17 kB 🔴 +1.03 kB
assets/WidgetAudioUI-C6dob_mZ.js (removed) 2.85 kB 🟢 -2.85 kB 🟢 -1.16 kB 🟢 -1.06 kB
assets/WidgetAudioUI-DczAqbXt.js (new) 2.85 kB 🔴 +2.85 kB 🔴 +1.16 kB 🔴 +1.05 kB
assets/WidgetInputText-DyXbkLNC.js (new) 1.99 kB 🔴 +1.99 kB 🔴 +917 B 🔴 +848 B
assets/WidgetInputText-j8BqmRTP.js (removed) 1.99 kB 🟢 -1.99 kB 🟢 -916 B 🟢 -849 B
assets/MediaImageBottom-BZ_3xGhD.js (removed) 1.57 kB 🟢 -1.57 kB 🟢 -742 B 🟢 -649 B
assets/MediaImageBottom-C6CmkN7M.js (new) 1.57 kB 🔴 +1.57 kB 🔴 +743 B 🔴 +647 B
assets/MediaAudioBottom-CgnRFVHS.js (removed) 1.52 kB 🟢 -1.52 kB 🟢 -743 B 🟢 -658 B
assets/MediaAudioBottom-CytdoAjQ.js (new) 1.52 kB 🔴 +1.52 kB 🔴 +741 B 🔴 +656 B
assets/MediaVideoBottom-CtXP2K5A.js (new) 1.52 kB 🔴 +1.52 kB 🔴 +740 B 🔴 +654 B
assets/MediaVideoBottom-DSLr16nk.js (removed) 1.52 kB 🟢 -1.52 kB 🟢 -741 B 🟢 -658 B
assets/Media3DBottom-BnyiJzuX.js (new) 1.5 kB 🔴 +1.5 kB 🔴 +730 B 🔴 +650 B
assets/Media3DBottom-DkacTWec.js (removed) 1.5 kB 🟢 -1.5 kB 🟢 -730 B 🟢 -652 B
assets/Media3DTop-C0nqQL3i.js (new) 1.49 kB 🔴 +1.49 kB 🔴 +766 B 🔴 +653 B
assets/Media3DTop-ilM-knDF.js (removed) 1.49 kB 🟢 -1.49 kB 🟢 -764 B 🟢 -651 B
assets/WidgetSelect-CLh0ETaG.js (removed) 655 B 🟢 -655 B 🟢 -342 B 🟢 -292 B
assets/WidgetSelect-kBMtcFr_.js (new) 655 B 🔴 +655 B 🔴 +344 B 🔴 +291 B
assets/WidgetInputNumber-BDVfLdIE.js (new) 595 B 🔴 +595 B 🔴 +331 B 🔴 +273 B
assets/WidgetInputNumber-BT2z0bqv.js (removed) 595 B 🟢 -595 B 🟢 -330 B 🟢 -277 B
assets/Load3D-C4k-Elh-.js (removed) 424 B 🟢 -424 B 🟢 -268 B 🟢 -222 B
assets/Load3D-CNWiSLqx.js (new) 424 B 🔴 +424 B 🔴 +269 B 🔴 +223 B
assets/WidgetLegacy-BcvVVzSq.js (removed) 364 B 🟢 -364 B 🟢 -237 B 🟢 -194 B
assets/WidgetLegacy-CWWkhTvn.js (new) 364 B 🔴 +364 B 🔴 +238 B 🔴 +194 B
assets/commands-_s-RvhJR.js 13.6 kB 13.6 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-BuUILW6P.js 13 kB 13 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-BV4R6fLx.js 14.9 kB 14.9 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-BWp4HdfU.js 101 B 101 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-CLwPdnT6.js 14.2 kB 14.2 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-CWMchBmd.js 15.9 kB 15.9 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-DazTQhtc.js 12.9 kB 12.9 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-DmWrOe93.js 13.7 kB 13.7 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-DwiH7Kr6.js 13.8 kB 13.8 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-mS3LCNPn.js 14.5 kB 14.5 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-B1JflQcI.js 72.2 kB 72.2 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-B2lyXe48.js 114 kB 114 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-B9XEQ-pc.js 94 kB 94 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-BErKFzc-.js 73.1 kB 73.1 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-Bf7Tze-u.js 83.4 kB 83.4 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-BhGMcO4Q.js 84.3 kB 84.3 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-CPZUloNQ.js 99 kB 99 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-Cw9RZWRY.js 89 B 89 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-Dva0z-T2.js 86.5 kB 86.5 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-un0K9wDS.js 81.8 kB 81.8 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/MediaAudioTop-BPDWO8-i.js 1.46 kB 1.46 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/MediaImageTop-BtY1hGDO.js 1.75 kB 1.75 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/MediaVideoTop-ehTZdDBw.js 2.76 kB 2.76 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-BC3OlaIn.js 342 kB 342 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-BsqN8-W1.js 285 kB 285 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-Bw_Jitw_.js 101 B 101 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-CK2saYDx.js 307 kB 307 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-Cm5kR4Hi.js 306 kB 306 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-CMrh-uxB.js 310 kB 310 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-DlUIOit1.js 369 kB 369 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-DNu_xoP2.js 282 kB 282 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-DpcvlpZe.js 303 kB 303 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-IyjOYIl-.js 317 kB 317 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WidgetChart-j6EYUdOM.js 2.48 kB 2.48 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WidgetImageCompare-D5bj5c8l.js 2.21 kB 2.21 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/widgetPropFilter-BIbGSUAt.js 1.28 kB 1.28 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WidgetToggleSwitch-DPJMnc2A.js 1.58 kB 1.58 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B

Status: 17 added / 17 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

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 248929c and 95c4224.

📒 Files selected for processing (1)
  • src/renderer/extensions/vueNodes/composables/useSlotLinkInteraction.ts (2 hunks)
🧰 Additional context used
📓 Path-based instructions (10)
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/composables/useSlotLinkInteraction.ts
src/**/*.ts

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

src/**/*.ts: Use es-toolkit for utility functions
Use TypeScript for type safety

Files:

  • src/renderer/extensions/vueNodes/composables/useSlotLinkInteraction.ts
src/**/{services,composables}/**/*.{ts,tsx}

📄 CodeRabbit inference engine (src/CLAUDE.md)

src/**/{services,composables}/**/*.{ts,tsx}: Use api.apiURL() for backend endpoints instead of constructing URLs directly
Use api.fileURL() for static file access instead of constructing URLs directly

Files:

  • src/renderer/extensions/vueNodes/composables/useSlotLinkInteraction.ts
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

Files:

  • src/renderer/extensions/vueNodes/composables/useSlotLinkInteraction.ts
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/composables/useSlotLinkInteraction.ts
src/**/*.{vue,ts,tsx}

📄 CodeRabbit inference engine (src/CLAUDE.md)

Follow Vue 3 composition API style guide

Files:

  • src/renderer/extensions/vueNodes/composables/useSlotLinkInteraction.ts
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/composables/useSlotLinkInteraction.ts
**/*.ts

📄 CodeRabbit inference engine (AGENTS.md)

Use TypeScript exclusively; no new JavaScript code

Files:

  • src/renderer/extensions/vueNodes/composables/useSlotLinkInteraction.ts
**/*.{ts,vue}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,vue}: Use camelCase for variable and function names
Indent with 2 spaces (see .prettierrc)
Use single quotes for strings (see .prettierrc)
No trailing semicolons (see .prettierrc)
Maximum line width of 80 characters (see .prettierrc)
Sort and group imports by plugin (run pnpm format before committing)
Never use any type; use proper TypeScript types instead
Never use as any type assertions; fix the underlying type issue instead
Avoid code comments unless absolutely necessary; write expressive, self-documenting code instead
When writing new code, ask if there is a simpler way to introduce the same functionality; if yes, choose the simpler approach
Use refactoring to make complex code simpler
Use es-toolkit for utility functions
Use Vite for fast development and building
Implement proper error handling
Write tests for all changes, especially bug fixes to catch future regressions

Files:

  • src/renderer/extensions/vueNodes/composables/useSlotLinkInteraction.ts
**/composables/**/use*.ts

📄 CodeRabbit inference engine (AGENTS.md)

Name composables with useXyz.ts pattern

Files:

  • src/renderer/extensions/vueNodes/composables/useSlotLinkInteraction.ts
🧠 Learnings (3)
📓 Common learnings
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
📚 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/composables/useSlotLinkInteraction.ts
📚 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/composables/useSlotLinkInteraction.ts
🧬 Code graph analysis (1)
src/renderer/extensions/vueNodes/composables/useSlotLinkInteraction.ts (1)
src/scripts/app.ts (1)
  • app (1737-1737)
⏰ 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). (4)
  • GitHub Check: setup
  • GitHub Check: collect
  • GitHub Check: lint-and-format
  • GitHub Check: test
🔇 Additional comments (1)
src/renderer/extensions/vueNodes/composables/useSlotLinkInteraction.ts (1)

302-320: Element resolution via elementFromPoint correctly handles implicit pointer capture

Using document.elementFromPoint(data.clientX, data.clientY) ?? data.target here is a good fix: it makes hover/candidate resolution follow the actual element under the pointer on touch devices while still falling back to the original event target if elementFromPoint returns null. The cache via dragContext.lastPointerEventTarget and the hoverChanged logic still behave consistently with this new target source.

- Extract reusable resolvePointerTarget helper function to unify
  pointer target resolution logic across hover and drop paths
- Add comprehensive unit tests for the helper including:
  - Basic elementFromPoint usage
  - Fallback behavior when elementFromPoint returns null
  - Touch/mobile pointer capture simulation
  - Integration with slot detection via closest()
@dosubot dosubot bot added size:L This PR changes 100-499 lines, ignoring generated files. and removed size:S This PR changes 10-29 lines, ignoring generated files. labels Dec 8, 2025
@Myestery Myestery requested a review from DrJKL December 8, 2025 22:54
@Myestery Myestery enabled auto-merge (squash) December 8, 2025 23:38
@Myestery Myestery disabled auto-merge December 8, 2025 23:54
@Myestery Myestery merged commit 418f8ff into main Dec 8, 2025
27 checks passed
@Myestery Myestery deleted the fix/mobile-touch-slot-link-drag branch December 8, 2025 23:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:L This PR changes 100-499 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Nodes 2.0 does not work on mobile browsers

3 participants