Fix LinkConnector methods cannot be cancelled via API (#934)

- Checks if `e.preventDefault()` has been called for all cancellable
LinkConnector callbacks
- Sets `cancelable: true` on dispatched events
- Dedupes canvas pointer calls
This commit is contained in:
filtered
2025-04-18 20:50:33 +10:00
committed by GitHub
parent 51ec57dc5c
commit ce46f19de9
3 changed files with 24 additions and 18 deletions

View File

@@ -1712,6 +1712,17 @@ export class LGraphCanvas implements ConnectionColorContext {
this.dirty_bgcanvas = true
}
#linkConnectorDrop(): void {
const { graph, linkConnector, pointer } = this
if (!graph) throw new NullGraphError()
pointer.onDragEnd = upEvent => linkConnector.dropLinks(graph, upEvent)
pointer.finally = () => {
this.linkConnector.reset(true)
this.#dirty()
}
}
/**
* Used to attach the canvas in a popup
* @returns returns the window where the canvas is attached (the DOM root node)
@@ -1993,9 +2004,7 @@ export class LGraphCanvas implements ConnectionColorContext {
if (reroute) {
if (e.shiftKey) {
linkConnector.dragFromReroute(graph, reroute)
pointer.onDragEnd = upEvent => linkConnector.dropLinks(graph, upEvent)
pointer.finally = () => linkConnector.reset(true)
this.#linkConnectorDrop()
this.dirty_bgcanvas = true
}
@@ -2029,9 +2038,7 @@ export class LGraphCanvas implements ConnectionColorContext {
if (e.shiftKey && !e.altKey) {
linkConnector.dragFromLinkSegment(graph, linkSegment)
pointer.onDragEnd = upEvent => linkConnector.dropLinks(graph, upEvent)
pointer.finally = () => linkConnector.reset(true)
this.#linkConnectorDrop()
return
} else if (e.altKey && !e.shiftKey) {
@@ -2220,18 +2227,13 @@ export class LGraphCanvas implements ConnectionColorContext {
// Drag multiple output links
if (e.shiftKey && (output.links?.length || output._floatingLinks?.size)) {
linkConnector.moveOutputLink(graph, output)
pointer.onDragEnd = upEvent => linkConnector.dropLinks(graph, upEvent)
pointer.finally = () => linkConnector.reset(true)
this.#linkConnectorDrop()
return
}
// New output link
linkConnector.dragNewFromOutput(graph, node, output)
pointer.onDragEnd = upEvent => linkConnector.dropLinks(graph, upEvent)
pointer.finally = () => linkConnector.reset(true)
this.#linkConnectorDrop()
if (LiteGraph.shift_click_do_break_link_from) {
if (e.shiftKey) {
@@ -2277,8 +2279,8 @@ export class LGraphCanvas implements ConnectionColorContext {
if (!linkConnector.isConnecting) {
linkConnector.dragNewFromInput(graph, node, input)
}
pointer.onDragEnd = upEvent => linkConnector.dropLinks(graph, upEvent)
pointer.finally = () => linkConnector.reset(true)
this.#linkConnectorDrop()
this.dirty_bgcanvas = true
return
@@ -2918,6 +2920,7 @@ export class LGraphCanvas implements ConnectionColorContext {
// esc
if (this.linkConnector.isConnecting) {
this.linkConnector.reset()
this.#dirty()
e.preventDefault()
return
}

View File

@@ -435,6 +435,9 @@ export class LinkConnector {
dropOnNothing(event: CanvasPointerEvent): void {
// For external event only.
const mayContinue = this.events.dispatch("dropped-on-canvas", event)
if (mayContinue === false) return
if (this.state.connectingTo === "input") {
for (const link of this.renderLinks) {
if (link instanceof MovingInputLink) {
@@ -442,7 +445,6 @@ export class LinkConnector {
}
}
}
this.events.dispatch("dropped-on-canvas", event)
}
/**
@@ -608,7 +610,8 @@ export class LinkConnector {
* Effectively cancels moving or connecting links.
*/
reset(force = false): void {
this.events.dispatch("reset", force)
const mayContinue = this.events.dispatch("reset", force)
if (mayContinue === false) return
const { state, outputLinks, inputLinks, hiddenReroutes, renderLinks, floatingLinks } = this

View File

@@ -77,7 +77,7 @@ export class LinkConnectorEventTarget extends EventTarget {
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 })
const event = new CustomEvent(type, { detail, cancelable: true })
return super.dispatchEvent(event)
}