[Refactor] Move DOM widget event listeners to vue (#2960)

This commit is contained in:
Chenlei Hu
2025-03-10 13:07:23 -04:00
committed by GitHub
parent abe4754904
commit 62528fde2e
2 changed files with 34 additions and 41 deletions

View File

@@ -1,6 +1,7 @@
<template>
<div
class="dom-widget"
:title="tooltip"
ref="widgetElement"
:style="style"
v-show="widgetState.visible"
@@ -9,6 +10,7 @@
<script setup lang="ts">
import type { LGraphNode } from '@comfyorg/litegraph'
import { useEventListener } from '@vueuse/core'
import { CSSProperties, computed, onMounted, ref, watch } from 'vue'
import { useAbsolutePosition } from '@/composables/element/useAbsolutePosition'
@@ -90,6 +92,25 @@ watch(
}
)
if (widget.element.blur) {
useEventListener(document, 'mousedown', (event) => {
if (!widget.element.contains(event.target as HTMLElement)) {
widget.element.blur()
}
})
}
for (const evt of widget.options.selectOn ?? ['focus', 'click']) {
useEventListener(widget.element, evt, () => {
const lgCanvas = canvasStore.canvas
lgCanvas?.selectNode(widget.node)
lgCanvas?.bringToFront(widget.node)
})
}
const inputSpec = widget.node.constructor.nodeData
const tooltip = inputSpec?.inputs?.[widget.name]?.tooltip
onMounted(() => {
widgetElement.value.appendChild(widget.element)
})

View File

@@ -6,7 +6,6 @@ import type {
import _ from 'lodash'
import { useChainCallback } from '@/composables/functional/useChainCallback'
import { app } from '@/scripts/app'
import { useDomWidgetStore } from '@/stores/domWidgetStore'
import { generateUUID } from '@/utils/formatUtil'
@@ -69,7 +68,6 @@ export class DOMWidgetImpl<T extends HTMLElement, V extends object | string>
readonly id: string
readonly node: LGraphNode
mouseDownHandler?: (event: MouseEvent) => void
constructor(obj: {
id: string
@@ -87,15 +85,6 @@ export class DOMWidgetImpl<T extends HTMLElement, V extends object | string>
this.id = obj.id
this.node = obj.node
if (this.element.blur) {
this.mouseDownHandler = (event) => {
if (!this.element.contains(event.target as HTMLElement)) {
this.element.blur()
}
}
document.addEventListener('mousedown', this.mouseDownHandler)
}
}
get value(): V {
@@ -164,10 +153,6 @@ export class DOMWidgetImpl<T extends HTMLElement, V extends object | string>
}
onRemove(): void {
if (this.mouseDownHandler) {
document.removeEventListener('mousedown', this.mouseDownHandler)
}
this.element.remove()
useDomWidgetStore().unregisterWidget(this.id)
}
}
@@ -182,22 +167,20 @@ LGraphNode.prototype.addDOMWidget = function <
element: T,
options: DOMWidgetOptions<T, V> = {}
): DOMWidget<T, V> {
options = { hideOnZoom: true, selectOn: ['focus', 'click'], ...options }
const { nodeData } = this.constructor
const tooltip = nodeData?.inputs?.[name]?.tooltip
if (tooltip && !element.title) {
element.title = tooltip
}
// Note: Before `LGraphNode.configure` is called, `this.id` is always `-1`.
const widget = new DOMWidgetImpl({
id: generateUUID(),
node: this,
name,
type,
element,
options
})
const widget = this.addCustomWidget(
new DOMWidgetImpl({
id: generateUUID(),
node: this,
name,
type,
element,
options: {
...options,
hideOnZoom: true
}
})
)
// Workaround for https://github.com/Comfy-Org/ComfyUI_frontend/issues/2493
// Some custom nodes are explicitly expecting getter and setter of `value`
@@ -212,17 +195,6 @@ LGraphNode.prototype.addDOMWidget = function <
}
})
// Ensure selectOn exists before iteration
const selectEvents = options.selectOn ?? ['focus', 'click']
for (const evt of selectEvents) {
element.addEventListener(evt, () => {
app.canvas.selectNode(this)
app.canvas.bringToFront(this)
})
}
this.addCustomWidget(widget)
this.onRemoved = useChainCallback(this.onRemoved, () => {
widget.onRemove()
})