[TS] Use strict mode in dialog & panel (#666)

Includes minor refactors to retain inferred types in branches.
This commit is contained in:
filtered
2025-03-02 13:27:10 +11:00
committed by GitHub
parent 6a42484669
commit 193b09999f

View File

@@ -123,16 +123,18 @@ interface ICreateNodeOptions {
) => HTMLDivElement | void ) => HTMLDivElement | void
} }
interface ICloseableDiv extends HTMLDivElement { interface ICloseable {
close?(): void close(): void
} }
interface IDialog extends ICloseableDiv { interface IDialogExtensions extends ICloseable {
modified?(): void modified(): void
close?(): void is_modified: boolean
is_modified?: boolean
} }
interface IDialog extends HTMLDivElement, IDialogExtensions {}
type PromptDialog = Omit<IDialog, "modified">
interface IDialogOptions { interface IDialogOptions {
position?: Point position?: Point
event?: MouseEvent event?: MouseEvent
@@ -179,6 +181,15 @@ interface IPasteFromClipboardOptions {
position?: Point position?: Point
} }
interface ICreatePanelOptions {
closable?: any
window?: any
onOpen?: () => void
onClose?: () => void
width?: any
height?: any
}
/** /**
* This class is in charge of rendering one graph inside a canvas. And provides all the interaction required. * This class is in charge of rendering one graph inside a canvas. And provides all the interaction required.
* Valid callbacks are: onNodeSelected, onNodeDeselected, onShowNodePanel, onNodeDblClicked * Valid callbacks are: onNodeSelected, onNodeDeselected, onShowNodePanel, onNodeDblClicked
@@ -505,7 +516,7 @@ export class LGraphCanvas implements ConnectionColorContext {
_pattern?: CanvasPattern _pattern?: CanvasPattern
_pattern_img?: HTMLImageElement _pattern_img?: HTMLImageElement
// TODO: This looks like another panel thing // TODO: This looks like another panel thing
prompt_box?: IDialog | null prompt_box?: PromptDialog | null
search_box?: HTMLDivElement search_box?: HTMLDivElement
/** @deprecated Panels */ /** @deprecated Panels */
SELECTED_NODE?: LGraphNode SELECTED_NODE?: LGraphNode
@@ -3336,12 +3347,14 @@ export class LGraphCanvas implements ConnectionColorContext {
serialisable.nodes.push(cloned) serialisable.nodes.push(cloned)
// Links // Links
const links = item.inputs if (item.inputs) {
?.map(input => this.graph?._links.get(input?.link)?.asSerialisable()) for (const { link: linkId } of item.inputs) {
.filter(x => !!x) if (linkId == null) continue
if (!links) continue const link = this.graph?._links.get(linkId)?.asSerialisable()
serialisable.links.push(...links) if (link) serialisable.links.push(link)
}
}
} else if (item instanceof LGraphGroup) { } else if (item instanceof LGraphGroup) {
// Groups // Groups
serialisable.groups.push(item.serialize()) serialisable.groups.push(item.serialize())
@@ -5895,18 +5908,22 @@ export class LGraphCanvas implements ConnectionColorContext {
const that = this const that = this
title = title || "" title = title || ""
const dialog: IDialog = document.createElement("div") const customProperties = {
dialog.is_modified = false is_modified: false,
dialog.className = "graphdialog rounded" className: "graphdialog rounded",
dialog.innerHTML = multiline innerHTML: multiline
? "<span class='name'></span> <textarea autofocus class='value'></textarea><button class='rounded'>OK</button>" ? "<span class='name'></span> <textarea autofocus class='value'></textarea><button class='rounded'>OK</button>"
: "<span class='name'></span> <input autofocus type='text' class='value'/><button class='rounded'>OK</button>" : "<span class='name'></span> <input autofocus type='text' class='value'/><button class='rounded'>OK</button>",
dialog.close = function () { close() {
that.prompt_box = null that.prompt_box = null
if (dialog.parentNode) { if (dialog.parentNode) {
dialog.remove() dialog.remove()
} }
} },
} satisfies Partial<IDialog>
const div = document.createElement("div")
const dialog: PromptDialog = Object.assign(div, customProperties)
const graphcanvas = LGraphCanvas.active_canvas const graphcanvas = LGraphCanvas.active_canvas
const canvas = graphcanvas.canvas const canvas = graphcanvas.canvas
@@ -6686,10 +6703,21 @@ export class LGraphCanvas implements ConnectionColorContext {
closeOnLeave_checkModified: true, closeOnLeave_checkModified: true,
} }
options = Object.assign(def_options, options || {}) options = Object.assign(def_options, options || {})
const dialog: IDialog = document.createElement("div")
dialog.className = "graphdialog" const customProperties = {
dialog.innerHTML = html className: "graphdialog",
dialog.is_modified = false innerHTML: html,
is_modified: false,
modified() {
this.is_modified = true
},
close(this: IDialog) {
this.remove()
},
} satisfies Partial<IDialog>
const div = document.createElement("div")
const dialog: IDialog = Object.assign(div, customProperties)
const rect = this.canvas.getBoundingClientRect() const rect = this.canvas.getBoundingClientRect()
let offsetx = -20 let offsetx = -20
@@ -6738,13 +6766,6 @@ export class LGraphCanvas implements ConnectionColorContext {
} }
} }
dialog.modified = function () {
dialog.is_modified = true
}
dialog.close = function () {
dialog.remove()
}
let dialogCloseTimer = null let dialogCloseTimer = null
let prevent_timeout = 0 let prevent_timeout = 0
dialog.addEventListener("mouseleave", function () { dialog.addEventListener("mouseleave", function () {
@@ -6781,7 +6802,7 @@ export class LGraphCanvas implements ConnectionColorContext {
return dialog return dialog
} }
createPanel(title, options) { createPanel(title: string, options: ICreatePanelOptions) {
options = options || {} options = options || {}
const ref_window = options.window || window const ref_window = options.window || window
@@ -6959,14 +6980,15 @@ export class LGraphCanvas implements ConnectionColorContext {
return elem return elem
} }
if (root.onOpen && typeof root.onOpen == "function") root.onOpen() if (typeof root.onOpen == "function") root.onOpen()
return root return root
} }
closePanels(): void { closePanels(): void {
document.querySelector<ICloseableDiv>("#node-panel")?.close() type MightHaveClose = HTMLDivElement & Partial<ICloseable>
document.querySelector<ICloseableDiv>("#option-panel")?.close() document.querySelector<MightHaveClose>("#node-panel")?.close?.()
document.querySelector<MightHaveClose>("#option-panel")?.close?.()
} }
showShowNodePanel(node: LGraphNode): void { showShowNodePanel(node: LGraphNode): void {
@@ -7290,49 +7312,47 @@ export class LGraphCanvas implements ConnectionColorContext {
extra: node, extra: node,
} }
if (node) options.title = node.type
// check if mouse is in input
let slot: ReturnType<LGraphNode["getSlotInPosition"]>
if (node) { if (node) {
slot = node.getSlotInPosition(event.canvasX, event.canvasY) options.title = node.type ?? undefined
LGraphCanvas.active_node = node LGraphCanvas.active_node = node
}
if (slot) { // check if mouse is in input
// on slot const slot = node.getSlotInPosition(event.canvasX, event.canvasY)
menu_info = [] if (slot) {
if (node.getSlotMenuOptions) { // on slot
menu_info = node.getSlotMenuOptions(slot) menu_info = []
if (node.getSlotMenuOptions) {
menu_info = node.getSlotMenuOptions(slot)
} else {
if (slot?.output?.links?.length)
menu_info.push({ content: "Disconnect Links", slot: slot })
const _slot = slot.input || slot.output
if (_slot.removable) {
menu_info.push(
_slot.locked
? "Cannot remove"
: { content: "Remove Slot", slot: slot },
)
}
if (!_slot.nameLocked)
menu_info.push({ content: "Rename Slot", slot: slot })
if (node.getExtraSlotMenuOptions) {
menu_info.push(...node.getExtraSlotMenuOptions(slot))
}
}
// @ts-expect-error Slot type can be number and has number checks
options.title = (slot.input ? slot.input.type : slot.output.type) || "*"
if (slot.input && slot.input.type == LiteGraph.ACTION)
options.title = "Action"
if (slot.output && slot.output.type == LiteGraph.EVENT)
options.title = "Event"
} else { } else {
if (slot?.output?.links?.length) // on node
menu_info.push({ content: "Disconnect Links", slot: slot }) menu_info = this.getNodeMenuOptions(node)
const _slot = slot.input || slot.output
if (_slot.removable) {
menu_info.push(
_slot.locked
? "Cannot remove"
: { content: "Remove Slot", slot: slot },
)
}
if (!_slot.nameLocked)
menu_info.push({ content: "Rename Slot", slot: slot })
if (node.getExtraSlotMenuOptions) {
menu_info.push(...node.getExtraSlotMenuOptions(slot))
}
} }
// @ts-expect-error Slot type can be number and has number checks
options.title = (slot.input ? slot.input.type : slot.output.type) || "*"
if (slot.input && slot.input.type == LiteGraph.ACTION)
options.title = "Action"
if (slot.output && slot.output.type == LiteGraph.EVENT)
options.title = "Event"
} else if (node) {
// on node
menu_info = this.getNodeMenuOptions(node)
} else { } else {
menu_info = this.getCanvasMenuOptions() menu_info = this.getCanvasMenuOptions()
if (!this.graph) throw new NullGraphError() if (!this.graph) throw new NullGraphError()