mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-04-30 19:21:54 +00:00
[Refactor] Convert to generic CustomEventTarget (#983)
Converts LinkConnector event target to a generic class. Subgraph pre-requisite.
This commit is contained in:
@@ -1,5 +1,6 @@
|
|||||||
import type { RenderLink } from "./RenderLink"
|
import type { RenderLink } from "./RenderLink"
|
||||||
import type { LinkConnectorEventTarget } from "@/infrastructure/LinkConnectorEventTarget"
|
import type { CustomEventTarget } from "@/infrastructure/CustomEventTarget"
|
||||||
|
import type { LinkConnectorEventMap } from "@/infrastructure/LinkConnectorEventMap"
|
||||||
import type { INodeOutputSlot, LinkNetwork } from "@/interfaces"
|
import type { INodeOutputSlot, LinkNetwork } from "@/interfaces"
|
||||||
import type { INodeInputSlot } from "@/interfaces"
|
import type { INodeInputSlot } from "@/interfaces"
|
||||||
import type { Point } from "@/interfaces"
|
import type { Point } from "@/interfaces"
|
||||||
@@ -113,7 +114,7 @@ export class FloatingRenderLink implements RenderLink {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
connectToInput(node: LGraphNode, input: INodeInputSlot, _events?: LinkConnectorEventTarget): void {
|
connectToInput(node: LGraphNode, input: INodeInputSlot, _events?: CustomEventTarget<LinkConnectorEventMap>): void {
|
||||||
const floatingLink = this.link
|
const floatingLink = this.link
|
||||||
floatingLink.target_id = node.id
|
floatingLink.target_id = node.id
|
||||||
floatingLink.target_slot = node.inputs.indexOf(input)
|
floatingLink.target_slot = node.inputs.indexOf(input)
|
||||||
@@ -125,7 +126,7 @@ export class FloatingRenderLink implements RenderLink {
|
|||||||
input._floatingLinks.add(floatingLink)
|
input._floatingLinks.add(floatingLink)
|
||||||
}
|
}
|
||||||
|
|
||||||
connectToOutput(node: LGraphNode, output: INodeOutputSlot, _events?: LinkConnectorEventTarget): void {
|
connectToOutput(node: LGraphNode, output: INodeOutputSlot, _events?: CustomEventTarget<LinkConnectorEventMap>): void {
|
||||||
const floatingLink = this.link
|
const floatingLink = this.link
|
||||||
floatingLink.origin_id = node.id
|
floatingLink.origin_id = node.id
|
||||||
floatingLink.origin_slot = node.outputs.indexOf(output)
|
floatingLink.origin_slot = node.outputs.indexOf(output)
|
||||||
@@ -138,7 +139,7 @@ export class FloatingRenderLink implements RenderLink {
|
|||||||
connectToRerouteInput(
|
connectToRerouteInput(
|
||||||
reroute: Reroute,
|
reroute: Reroute,
|
||||||
{ node: inputNode, input }: { node: LGraphNode, input: INodeInputSlot },
|
{ node: inputNode, input }: { node: LGraphNode, input: INodeInputSlot },
|
||||||
events: LinkConnectorEventTarget,
|
events: CustomEventTarget<LinkConnectorEventMap>,
|
||||||
) {
|
) {
|
||||||
const floatingLink = this.link
|
const floatingLink = this.link
|
||||||
floatingLink.target_id = inputNode.id
|
floatingLink.target_id = inputNode.id
|
||||||
@@ -155,7 +156,7 @@ export class FloatingRenderLink implements RenderLink {
|
|||||||
reroute: Reroute,
|
reroute: Reroute,
|
||||||
outputNode: LGraphNode,
|
outputNode: LGraphNode,
|
||||||
output: INodeOutputSlot,
|
output: INodeOutputSlot,
|
||||||
events: LinkConnectorEventTarget,
|
events: CustomEventTarget<LinkConnectorEventMap>,
|
||||||
) {
|
) {
|
||||||
const floatingLink = this.link
|
const floatingLink = this.link
|
||||||
floatingLink.origin_id = outputNode.id
|
floatingLink.origin_id = outputNode.id
|
||||||
|
|||||||
@@ -6,7 +6,8 @@ import type { Reroute } from "@/Reroute"
|
|||||||
import type { CanvasPointerEvent } from "@/types/events"
|
import type { CanvasPointerEvent } from "@/types/events"
|
||||||
import type { IWidget } from "@/types/widgets"
|
import type { IWidget } from "@/types/widgets"
|
||||||
|
|
||||||
import { LinkConnectorEventMap, LinkConnectorEventTarget } from "@/infrastructure/LinkConnectorEventTarget"
|
import { CustomEventTarget } from "@/infrastructure/CustomEventTarget"
|
||||||
|
import { LinkConnectorEventMap } from "@/infrastructure/LinkConnectorEventMap"
|
||||||
import { LLink } from "@/LLink"
|
import { LLink } from "@/LLink"
|
||||||
import { LinkDirection } from "@/types/globalEnums"
|
import { LinkDirection } from "@/types/globalEnums"
|
||||||
|
|
||||||
@@ -67,7 +68,7 @@ export class LinkConnector {
|
|||||||
snapLinksPos: undefined,
|
snapLinksPos: undefined,
|
||||||
}
|
}
|
||||||
|
|
||||||
readonly events = new LinkConnectorEventTarget()
|
readonly events = new CustomEventTarget<LinkConnectorEventMap>()
|
||||||
|
|
||||||
/** Contains information for rendering purposes only. */
|
/** Contains information for rendering purposes only. */
|
||||||
readonly renderLinks: RenderLinkUnion[] = []
|
readonly renderLinks: RenderLinkUnion[] = []
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import type { LinkConnectorEventTarget } from "@/infrastructure/LinkConnectorEventTarget"
|
import type { CustomEventTarget } from "@/infrastructure/CustomEventTarget"
|
||||||
|
import type { LinkConnectorEventMap } from "@/infrastructure/LinkConnectorEventMap"
|
||||||
import type { INodeInputSlot, INodeOutputSlot, LinkNetwork, Point } from "@/interfaces"
|
import type { INodeInputSlot, INodeOutputSlot, LinkNetwork, Point } from "@/interfaces"
|
||||||
import type { LGraphNode } from "@/LGraphNode"
|
import type { LGraphNode } from "@/LGraphNode"
|
||||||
import type { LLink } from "@/LLink"
|
import type { LLink } from "@/LLink"
|
||||||
@@ -39,7 +40,7 @@ export class MovingInputLink extends MovingLinkBase {
|
|||||||
return reroute.origin_id !== this.inputNode.id
|
return reroute.origin_id !== this.inputNode.id
|
||||||
}
|
}
|
||||||
|
|
||||||
connectToInput(inputNode: LGraphNode, input: INodeInputSlot, events: LinkConnectorEventTarget): LLink | null | undefined {
|
connectToInput(inputNode: LGraphNode, input: INodeInputSlot, events: CustomEventTarget<LinkConnectorEventMap>): LLink | null | undefined {
|
||||||
if (input === this.inputSlot) return
|
if (input === this.inputSlot) return
|
||||||
|
|
||||||
this.inputNode.disconnectInput(this.inputIndex, true)
|
this.inputNode.disconnectInput(this.inputIndex, true)
|
||||||
@@ -55,7 +56,7 @@ export class MovingInputLink extends MovingLinkBase {
|
|||||||
connectToRerouteInput(
|
connectToRerouteInput(
|
||||||
reroute: Reroute,
|
reroute: Reroute,
|
||||||
{ node: inputNode, input, link: existingLink }: { node: LGraphNode, input: INodeInputSlot, link: LLink },
|
{ node: inputNode, input, link: existingLink }: { node: LGraphNode, input: INodeInputSlot, link: LLink },
|
||||||
events: LinkConnectorEventTarget,
|
events: CustomEventTarget<LinkConnectorEventMap>,
|
||||||
originalReroutes: Reroute[],
|
originalReroutes: Reroute[],
|
||||||
): void {
|
): void {
|
||||||
const { outputNode, outputSlot, fromReroute } = this
|
const { outputNode, outputSlot, fromReroute } = this
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import type { RenderLink } from "./RenderLink"
|
import type { RenderLink } from "./RenderLink"
|
||||||
import type { LinkConnectorEventTarget } from "@/infrastructure/LinkConnectorEventTarget"
|
import type { CustomEventTarget } from "@/infrastructure/CustomEventTarget"
|
||||||
|
import type { LinkConnectorEventMap } from "@/infrastructure/LinkConnectorEventMap"
|
||||||
import type { INodeInputSlot, INodeOutputSlot, LinkNetwork, Point } from "@/interfaces"
|
import type { INodeInputSlot, INodeOutputSlot, LinkNetwork, Point } from "@/interfaces"
|
||||||
import type { LGraphNode, NodeId } from "@/LGraphNode"
|
import type { LGraphNode, NodeId } from "@/LGraphNode"
|
||||||
import type { LLink } from "@/LLink"
|
import type { LLink } from "@/LLink"
|
||||||
@@ -79,10 +80,10 @@ export abstract class MovingLinkBase implements RenderLink {
|
|||||||
this.inputPos = inputNode.getInputPos(inputIndex)
|
this.inputPos = inputNode.getInputPos(inputIndex)
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract connectToInput(node: LGraphNode, input: INodeInputSlot, events?: LinkConnectorEventTarget): void
|
abstract connectToInput(node: LGraphNode, input: INodeInputSlot, events?: CustomEventTarget<LinkConnectorEventMap>): void
|
||||||
abstract connectToOutput(node: LGraphNode, output: INodeOutputSlot, events?: LinkConnectorEventTarget): void
|
abstract connectToOutput(node: LGraphNode, output: INodeOutputSlot, events?: CustomEventTarget<LinkConnectorEventMap>): void
|
||||||
abstract connectToRerouteInput(reroute: Reroute, { node, input, link }: { node: LGraphNode, input: INodeInputSlot, link: LLink }, events: LinkConnectorEventTarget, originalReroutes: Reroute[]): void
|
abstract connectToRerouteInput(reroute: Reroute, { node, input, link }: { node: LGraphNode, input: INodeInputSlot, link: LLink }, events: CustomEventTarget<LinkConnectorEventMap>, originalReroutes: Reroute[]): void
|
||||||
abstract connectToRerouteOutput(reroute: Reroute, outputNode: LGraphNode, output: INodeOutputSlot, events: LinkConnectorEventTarget): void
|
abstract connectToRerouteOutput(reroute: Reroute, outputNode: LGraphNode, output: INodeOutputSlot, events: CustomEventTarget<LinkConnectorEventMap>): void
|
||||||
|
|
||||||
abstract disconnect(): boolean
|
abstract disconnect(): boolean
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import type { LinkConnectorEventTarget } from "@/infrastructure/LinkConnectorEventTarget"
|
import type { CustomEventTarget } from "@/infrastructure/CustomEventTarget"
|
||||||
|
import type { LinkConnectorEventMap } from "@/infrastructure/LinkConnectorEventMap"
|
||||||
import type { INodeInputSlot, INodeOutputSlot, LinkNetwork, Point } from "@/interfaces"
|
import type { INodeInputSlot, INodeOutputSlot, LinkNetwork, Point } from "@/interfaces"
|
||||||
import type { LGraphNode } from "@/LGraphNode"
|
import type { LGraphNode } from "@/LGraphNode"
|
||||||
import type { LLink } from "@/LLink"
|
import type { LLink } from "@/LLink"
|
||||||
@@ -43,7 +44,7 @@ export class MovingOutputLink extends MovingLinkBase {
|
|||||||
throw new Error("MovingOutputLink cannot connect to an input.")
|
throw new Error("MovingOutputLink cannot connect to an input.")
|
||||||
}
|
}
|
||||||
|
|
||||||
connectToOutput(outputNode: LGraphNode, output: INodeOutputSlot, events: LinkConnectorEventTarget): LLink | null | undefined {
|
connectToOutput(outputNode: LGraphNode, output: INodeOutputSlot, events: CustomEventTarget<LinkConnectorEventMap>): LLink | null | undefined {
|
||||||
if (output === this.outputSlot) return
|
if (output === this.outputSlot) return
|
||||||
|
|
||||||
const link = outputNode.connectSlots(output, this.inputNode, this.inputSlot, this.link.parentId)
|
const link = outputNode.connectSlots(output, this.inputNode, this.inputSlot, this.link.parentId)
|
||||||
@@ -59,7 +60,7 @@ export class MovingOutputLink extends MovingLinkBase {
|
|||||||
reroute: Reroute,
|
reroute: Reroute,
|
||||||
outputNode: LGraphNode,
|
outputNode: LGraphNode,
|
||||||
output: INodeOutputSlot,
|
output: INodeOutputSlot,
|
||||||
events: LinkConnectorEventTarget,
|
events: CustomEventTarget<LinkConnectorEventMap>,
|
||||||
): void {
|
): void {
|
||||||
// Moving output side of links
|
// Moving output side of links
|
||||||
const { inputNode, inputSlot, fromReroute } = this
|
const { inputNode, inputSlot, fromReroute } = this
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import type { LinkConnectorEventTarget } from "@/infrastructure/LinkConnectorEventTarget"
|
import type { CustomEventTarget } from "@/infrastructure/CustomEventTarget"
|
||||||
|
import type { LinkConnectorEventMap } from "@/infrastructure/LinkConnectorEventMap"
|
||||||
import type { LinkNetwork, Point } from "@/interfaces"
|
import type { LinkNetwork, Point } from "@/interfaces"
|
||||||
import type { LGraphNode } from "@/LGraphNode"
|
import type { LGraphNode } from "@/LGraphNode"
|
||||||
import type { INodeInputSlot, INodeOutputSlot, LLink, Reroute } from "@/litegraph"
|
import type { INodeInputSlot, INodeOutputSlot, LLink, Reroute } from "@/litegraph"
|
||||||
@@ -25,13 +26,13 @@ export interface RenderLink {
|
|||||||
/** The reroute that the link is being connected from. */
|
/** The reroute that the link is being connected from. */
|
||||||
readonly fromReroute?: Reroute
|
readonly fromReroute?: Reroute
|
||||||
|
|
||||||
connectToInput(node: LGraphNode, input: INodeInputSlot, events?: LinkConnectorEventTarget): void
|
connectToInput(node: LGraphNode, input: INodeInputSlot, events?: CustomEventTarget<LinkConnectorEventMap>): void
|
||||||
connectToOutput(node: LGraphNode, output: INodeOutputSlot, events?: LinkConnectorEventTarget): void
|
connectToOutput(node: LGraphNode, output: INodeOutputSlot, events?: CustomEventTarget<LinkConnectorEventMap>): void
|
||||||
|
|
||||||
connectToRerouteInput(
|
connectToRerouteInput(
|
||||||
reroute: Reroute,
|
reroute: Reroute,
|
||||||
{ node, input, link }: { node: LGraphNode, input: INodeInputSlot, link: LLink },
|
{ node, input, link }: { node: LGraphNode, input: INodeInputSlot, link: LLink },
|
||||||
events: LinkConnectorEventTarget,
|
events: CustomEventTarget<LinkConnectorEventMap>,
|
||||||
originalReroutes: Reroute[],
|
originalReroutes: Reroute[],
|
||||||
): void
|
): void
|
||||||
|
|
||||||
@@ -39,6 +40,6 @@ export interface RenderLink {
|
|||||||
reroute: Reroute,
|
reroute: Reroute,
|
||||||
outputNode: LGraphNode,
|
outputNode: LGraphNode,
|
||||||
output: INodeOutputSlot,
|
output: INodeOutputSlot,
|
||||||
events: LinkConnectorEventTarget,
|
events: CustomEventTarget<LinkConnectorEventMap>,
|
||||||
): void
|
): void
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import type { RenderLink } from "./RenderLink"
|
import type { RenderLink } from "./RenderLink"
|
||||||
import type { LinkConnectorEventTarget } from "@/infrastructure/LinkConnectorEventTarget"
|
import type { CustomEventTarget } from "@/infrastructure/CustomEventTarget"
|
||||||
|
import type { LinkConnectorEventMap } from "@/infrastructure/LinkConnectorEventMap"
|
||||||
import type { INodeInputSlot, INodeOutputSlot, LinkNetwork, Point } from "@/interfaces"
|
import type { INodeInputSlot, INodeOutputSlot, LinkNetwork, Point } from "@/interfaces"
|
||||||
import type { LGraphNode } from "@/LGraphNode"
|
import type { LGraphNode } from "@/LGraphNode"
|
||||||
import type { LLink } from "@/LLink"
|
import type { LLink } from "@/LLink"
|
||||||
@@ -39,7 +40,7 @@ export class ToInputRenderLink implements RenderLink {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
connectToInput(node: LGraphNode, input: INodeInputSlot, events: LinkConnectorEventTarget) {
|
connectToInput(node: LGraphNode, input: INodeInputSlot, events: CustomEventTarget<LinkConnectorEventMap>) {
|
||||||
const { node: outputNode, fromSlot, fromReroute } = this
|
const { node: outputNode, fromSlot, fromReroute } = this
|
||||||
if (node === outputNode) return
|
if (node === outputNode) return
|
||||||
|
|
||||||
@@ -54,7 +55,7 @@ export class ToInputRenderLink implements RenderLink {
|
|||||||
input,
|
input,
|
||||||
link,
|
link,
|
||||||
}: { node: LGraphNode, input: INodeInputSlot, link: LLink },
|
}: { node: LGraphNode, input: INodeInputSlot, link: LLink },
|
||||||
events: LinkConnectorEventTarget,
|
events: CustomEventTarget<LinkConnectorEventMap>,
|
||||||
originalReroutes: Reroute[],
|
originalReroutes: Reroute[],
|
||||||
) {
|
) {
|
||||||
const { node: outputNode, fromSlot, fromReroute } = this
|
const { node: outputNode, fromSlot, fromReroute } = this
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import type { RenderLink } from "./RenderLink"
|
import type { RenderLink } from "./RenderLink"
|
||||||
import type { LinkConnectorEventTarget } from "@/infrastructure/LinkConnectorEventTarget"
|
import type { CustomEventTarget } from "@/infrastructure/CustomEventTarget"
|
||||||
|
import type { LinkConnectorEventMap } from "@/infrastructure/LinkConnectorEventMap"
|
||||||
import type { INodeInputSlot, INodeOutputSlot, LinkNetwork, Point } from "@/interfaces"
|
import type { INodeInputSlot, INodeOutputSlot, LinkNetwork, Point } from "@/interfaces"
|
||||||
import type { LGraphNode } from "@/LGraphNode"
|
import type { LGraphNode } from "@/LGraphNode"
|
||||||
import type { Reroute } from "@/Reroute"
|
import type { Reroute } from "@/Reroute"
|
||||||
@@ -43,7 +44,7 @@ export class ToOutputRenderLink implements RenderLink {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
connectToOutput(node: LGraphNode, output: INodeOutputSlot, events: LinkConnectorEventTarget) {
|
connectToOutput(node: LGraphNode, output: INodeOutputSlot, events: CustomEventTarget<LinkConnectorEventMap>) {
|
||||||
const { node: inputNode, fromSlot, fromReroute } = this
|
const { node: inputNode, fromSlot, fromReroute } = this
|
||||||
if (!inputNode) return
|
if (!inputNode) return
|
||||||
|
|
||||||
@@ -55,7 +56,7 @@ export class ToOutputRenderLink implements RenderLink {
|
|||||||
reroute: Reroute,
|
reroute: Reroute,
|
||||||
outputNode: LGraphNode,
|
outputNode: LGraphNode,
|
||||||
output: INodeOutputSlot,
|
output: INodeOutputSlot,
|
||||||
events: LinkConnectorEventTarget,
|
events: CustomEventTarget<LinkConnectorEventMap>,
|
||||||
): void {
|
): void {
|
||||||
const { node: inputNode, fromSlot } = this
|
const { node: inputNode, fromSlot } = this
|
||||||
const newLink = outputNode.connectSlots(output, inputNode, fromSlot, reroute?.id)
|
const newLink = outputNode.connectSlots(output, inputNode, fromSlot, reroute?.id)
|
||||||
|
|||||||
55
src/infrastructure/CustomEventTarget.ts
Normal file
55
src/infrastructure/CustomEventTarget.ts
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
/** {@link Omit} all properties that evaluate to `never`. */
|
||||||
|
type NeverNever<T> = {
|
||||||
|
[K in keyof T as T[K] extends never ? never : K]: T[K]
|
||||||
|
}
|
||||||
|
|
||||||
|
/** {@link Pick} only properties that evaluate to `never`. */
|
||||||
|
type PickNevers<T> = {
|
||||||
|
[K in keyof T as T[K] extends never ? K : never]: T[K]
|
||||||
|
}
|
||||||
|
|
||||||
|
type EventListeners<T> = {
|
||||||
|
readonly [K in keyof T]: ((this: EventTarget, ev: CustomEvent<T[K]>) => any) | EventListenerObject | null
|
||||||
|
}
|
||||||
|
|
||||||
|
export class CustomEventTarget<
|
||||||
|
EventMap extends Record<Keys, unknown>,
|
||||||
|
Keys extends keyof EventMap & string = keyof EventMap & string,
|
||||||
|
> extends EventTarget {
|
||||||
|
/**
|
||||||
|
* Type-safe event dispatching.
|
||||||
|
* @see {@link EventTarget.dispatchEvent}
|
||||||
|
* @param type Name of the event to dispatch
|
||||||
|
* @param detail A custom object to send with the event
|
||||||
|
* @returns `true` if the event was dispatched successfully, otherwise `false`.
|
||||||
|
*/
|
||||||
|
dispatch<T extends keyof NeverNever<EventMap>>(type: T, detail: EventMap[T]): boolean
|
||||||
|
dispatch<T extends keyof PickNevers<EventMap>>(type: T): boolean
|
||||||
|
dispatch<T extends keyof EventMap>(type: T, detail?: EventMap[T]) {
|
||||||
|
const event = new CustomEvent(type as string, { detail, cancelable: true })
|
||||||
|
return super.dispatchEvent(event)
|
||||||
|
}
|
||||||
|
|
||||||
|
override addEventListener<K extends Keys>(
|
||||||
|
type: K,
|
||||||
|
listener: EventListeners<EventMap>[K],
|
||||||
|
options?: boolean | AddEventListenerOptions,
|
||||||
|
): void {
|
||||||
|
// Assertion: Contravariance on CustomEvent => Event
|
||||||
|
super.addEventListener(type as string, listener as EventListener, options)
|
||||||
|
}
|
||||||
|
|
||||||
|
override removeEventListener<K extends Keys>(
|
||||||
|
type: K,
|
||||||
|
listener: EventListeners<EventMap>[K],
|
||||||
|
options?: boolean | EventListenerOptions,
|
||||||
|
): void {
|
||||||
|
// Assertion: Contravariance on CustomEvent => Event
|
||||||
|
super.removeEventListener(type as string, listener as EventListener, options)
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @deprecated Use {@link dispatch}. */
|
||||||
|
override dispatchEvent(event: never): boolean {
|
||||||
|
return super.dispatchEvent(event)
|
||||||
|
}
|
||||||
|
}
|
||||||
47
src/infrastructure/LinkConnectorEventMap.ts
Normal file
47
src/infrastructure/LinkConnectorEventMap.ts
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
import type { FloatingRenderLink } from "@/canvas/FloatingRenderLink"
|
||||||
|
import type { MovingInputLink } from "@/canvas/MovingInputLink"
|
||||||
|
import type { MovingOutputLink } from "@/canvas/MovingOutputLink"
|
||||||
|
import type { RenderLink } from "@/canvas/RenderLink"
|
||||||
|
import type { ToInputRenderLink } from "@/canvas/ToInputRenderLink"
|
||||||
|
import type { LGraphNode } from "@/LGraphNode"
|
||||||
|
import type { LLink } from "@/LLink"
|
||||||
|
import type { Reroute } from "@/Reroute"
|
||||||
|
import type { CanvasPointerEvent } from "@/types/events"
|
||||||
|
import type { IWidget } from "@/types/widgets"
|
||||||
|
|
||||||
|
export interface LinkConnectorEventMap {
|
||||||
|
"reset": boolean
|
||||||
|
|
||||||
|
"before-drop-links": {
|
||||||
|
renderLinks: RenderLink[]
|
||||||
|
event: CanvasPointerEvent
|
||||||
|
}
|
||||||
|
"after-drop-links": {
|
||||||
|
renderLinks: RenderLink[]
|
||||||
|
event: CanvasPointerEvent
|
||||||
|
}
|
||||||
|
|
||||||
|
"before-move-input": MovingInputLink | FloatingRenderLink
|
||||||
|
"before-move-output": MovingOutputLink | FloatingRenderLink
|
||||||
|
|
||||||
|
"input-moved": MovingInputLink | FloatingRenderLink
|
||||||
|
"output-moved": MovingOutputLink | FloatingRenderLink
|
||||||
|
|
||||||
|
"link-created": LLink | null | undefined
|
||||||
|
|
||||||
|
"dropped-on-reroute": {
|
||||||
|
reroute: Reroute
|
||||||
|
event: CanvasPointerEvent
|
||||||
|
}
|
||||||
|
"dropped-on-node": {
|
||||||
|
node: LGraphNode
|
||||||
|
event: CanvasPointerEvent
|
||||||
|
}
|
||||||
|
"dropped-on-canvas": CanvasPointerEvent
|
||||||
|
|
||||||
|
"dropped-on-widget": {
|
||||||
|
link: ToInputRenderLink
|
||||||
|
node: LGraphNode
|
||||||
|
widget: IWidget
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,106 +0,0 @@
|
|||||||
import type { FloatingRenderLink } from "@/canvas/FloatingRenderLink"
|
|
||||||
import type { MovingInputLink } from "@/canvas/MovingInputLink"
|
|
||||||
import type { MovingOutputLink } from "@/canvas/MovingOutputLink"
|
|
||||||
import type { RenderLink } from "@/canvas/RenderLink"
|
|
||||||
import type { ToInputRenderLink } from "@/canvas/ToInputRenderLink"
|
|
||||||
import type { LGraphNode } from "@/LGraphNode"
|
|
||||||
import type { LLink } from "@/LLink"
|
|
||||||
import type { Reroute } from "@/Reroute"
|
|
||||||
import type { CanvasPointerEvent } from "@/types/events"
|
|
||||||
import type { IWidget } from "@/types/widgets"
|
|
||||||
|
|
||||||
export interface LinkConnectorEventMap {
|
|
||||||
"reset": boolean
|
|
||||||
|
|
||||||
"before-drop-links": {
|
|
||||||
renderLinks: RenderLink[]
|
|
||||||
event: CanvasPointerEvent
|
|
||||||
}
|
|
||||||
"after-drop-links": {
|
|
||||||
renderLinks: RenderLink[]
|
|
||||||
event: CanvasPointerEvent
|
|
||||||
}
|
|
||||||
|
|
||||||
"before-move-input": MovingInputLink | FloatingRenderLink
|
|
||||||
"before-move-output": MovingOutputLink | FloatingRenderLink
|
|
||||||
|
|
||||||
"input-moved": MovingInputLink | FloatingRenderLink
|
|
||||||
"output-moved": MovingOutputLink | FloatingRenderLink
|
|
||||||
|
|
||||||
"link-created": LLink | null | undefined
|
|
||||||
|
|
||||||
"dropped-on-reroute": {
|
|
||||||
reroute: Reroute
|
|
||||||
event: CanvasPointerEvent
|
|
||||||
}
|
|
||||||
"dropped-on-node": {
|
|
||||||
node: LGraphNode
|
|
||||||
event: CanvasPointerEvent
|
|
||||||
}
|
|
||||||
"dropped-on-canvas": CanvasPointerEvent
|
|
||||||
|
|
||||||
"dropped-on-widget": {
|
|
||||||
link: ToInputRenderLink
|
|
||||||
node: LGraphNode
|
|
||||||
widget: IWidget
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** {@link Omit} all properties that evaluate to `never`. */
|
|
||||||
type NeverNever<T> = {
|
|
||||||
[K in keyof T as T[K] extends never ? never : K]: T[K]
|
|
||||||
}
|
|
||||||
|
|
||||||
/** {@link Pick} only properties that evaluate to `never`. */
|
|
||||||
type PickNevers<T> = {
|
|
||||||
[K in keyof T as T[K] extends never ? K : never]: T[K]
|
|
||||||
}
|
|
||||||
|
|
||||||
type LinkConnectorEventListeners = {
|
|
||||||
readonly [K in keyof LinkConnectorEventMap]: ((this: EventTarget, ev: CustomEvent<LinkConnectorEventMap[K]>) => any) | EventListenerObject | null
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Events that _do not_ pass a {@link CustomEvent} `detail` object. */
|
|
||||||
type SimpleEvents = keyof PickNevers<LinkConnectorEventMap>
|
|
||||||
|
|
||||||
/** Events that pass a {@link CustomEvent} `detail` object. */
|
|
||||||
type ComplexEvents = keyof NeverNever<LinkConnectorEventMap>
|
|
||||||
|
|
||||||
export class LinkConnectorEventTarget extends EventTarget {
|
|
||||||
/**
|
|
||||||
* Type-safe event dispatching.
|
|
||||||
* @see {@link EventTarget.dispatchEvent}
|
|
||||||
* @param type Name of the event to dispatch
|
|
||||||
* @param detail A custom object to send with the event
|
|
||||||
* @returns `true` if the event was dispatched successfully, otherwise `false`.
|
|
||||||
*/
|
|
||||||
dispatch<T extends ComplexEvents>(type: T, detail: LinkConnectorEventMap[T]): boolean
|
|
||||||
dispatch<T extends SimpleEvents>(type: T): boolean
|
|
||||||
dispatch<T extends keyof LinkConnectorEventMap>(type: T, detail?: LinkConnectorEventMap[T]) {
|
|
||||||
const event = new CustomEvent(type, { detail, cancelable: true })
|
|
||||||
return super.dispatchEvent(event)
|
|
||||||
}
|
|
||||||
|
|
||||||
override addEventListener<K extends keyof LinkConnectorEventMap>(
|
|
||||||
type: K,
|
|
||||||
listener: LinkConnectorEventListeners[K],
|
|
||||||
options?: boolean | AddEventListenerOptions,
|
|
||||||
): void {
|
|
||||||
// Assertion: Contravariance on CustomEvent => Event
|
|
||||||
super.addEventListener(type, listener as EventListener, options)
|
|
||||||
}
|
|
||||||
|
|
||||||
override removeEventListener<K extends keyof LinkConnectorEventMap>(
|
|
||||||
type: K,
|
|
||||||
listener: LinkConnectorEventListeners[K],
|
|
||||||
options?: boolean | EventListenerOptions,
|
|
||||||
): void {
|
|
||||||
// Assertion: Contravariance on CustomEvent => Event
|
|
||||||
super.removeEventListener(type, listener as EventListener, options)
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @deprecated Use {@link dispatch}. */
|
|
||||||
override dispatchEvent(event: never): boolean {
|
|
||||||
return super.dispatchEvent(event)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user