[TS] Enable strict mode (#3136)

This commit is contained in:
Chenlei Hu
2025-03-18 22:57:17 -04:00
committed by GitHub
parent 44edec7ad2
commit a049e9ae2d
64 changed files with 924 additions and 781 deletions

View File

@@ -1,4 +1,3 @@
// @ts-strict-ignore
import { LGraphCanvas, LiteGraph } from '@comfyorg/litegraph'
import { LGraphNode, type NodeId } from '@comfyorg/litegraph/dist/LGraphNode'
@@ -40,9 +39,11 @@ const Workflow = {
Registered: 1,
InWorkflow: 2
},
// @ts-expect-error fixme ts strict error
isInUseGroupNode(name) {
const id = `${PREFIX}${SEPARATOR}${name}`
// Check if lready registered/in use in this workflow
// @ts-expect-error fixme ts strict error
if (app.graph.extra?.groupNodes?.[name]) {
if (app.graph.nodes.find((n) => n.type === id)) {
return Workflow.InUse.InWorkflow
@@ -57,12 +58,14 @@ const Workflow = {
if (!extra) app.graph.extra = extra = {}
let groupNodes = extra.groupNodes
if (!groupNodes) extra.groupNodes = groupNodes = {}
// @ts-expect-error fixme ts strict error
groupNodes[name] = data
}
}
class GroupNodeBuilder {
nodes: LGraphNode[]
// @ts-expect-error fixme ts strict error
nodeData: GroupNodeWorkflowData
constructor(nodes: LGraphNode[]) {
@@ -121,15 +124,18 @@ class GroupNodeBuilder {
}
getNodeData() {
// @ts-expect-error fixme ts strict error
const storeLinkTypes = (config) => {
// Store link types for dynamically typed nodes e.g. reroutes
for (const link of config.links) {
const origin = app.graph.getNodeById(link[4])
// @ts-expect-error fixme ts strict error
const type = origin.outputs[link[1]].type
link.push(type)
}
}
// @ts-expect-error fixme ts strict error
const storeExternalLinks = (config) => {
// Store any external links to the group in the config so when rebuilding we add extra slots
config.external = []
@@ -160,6 +166,7 @@ class GroupNodeBuilder {
// Use the built in copyToClipboard function to generate the node data we need
try {
// @ts-expect-error fixme ts strict error
const serialised = serialise(this.nodes, app.canvas.graph)
const config = JSON.parse(serialised)
@@ -186,12 +193,18 @@ export class GroupNodeConfig {
primitiveToWidget: {}
nodeInputs: {}
outputVisibility: any[]
// @ts-expect-error fixme ts strict error
nodeDef: ComfyNodeDef
// @ts-expect-error fixme ts strict error
inputs: any[]
// @ts-expect-error fixme ts strict error
linksFrom: {}
// @ts-expect-error fixme ts strict error
linksTo: {}
// @ts-expect-error fixme ts strict error
externalFrom: {}
// @ts-expect-error fixme ts strict error
constructor(name, nodeData) {
this.name = name
this.nodeData = nodeData
@@ -222,6 +235,7 @@ export class GroupNodeConfig {
category: 'group nodes' + (SEPARATOR + source),
input: { required: {} },
description: `Group node combining ${this.nodeData.nodes
// @ts-expect-error fixme ts strict error
.map((n) => n.type)
.join(', ')}`,
python_module: 'custom_nodes.' + this.name,
@@ -239,8 +253,10 @@ export class GroupNodeConfig {
}
for (const p of this.#convertedToProcess) {
// @ts-expect-error fixme ts strict error
p()
}
// @ts-expect-error fixme ts strict error
this.#convertedToProcess = null
await app.registerNodeDef(`${PREFIX}${SEPARATOR}` + this.name, this.nodeDef)
useNodeDefStore().addNodeDef(this.nodeDef)
@@ -258,31 +274,43 @@ export class GroupNodeConfig {
// Skip links outside the copy config
if (sourceNodeId == null) continue
// @ts-expect-error fixme ts strict error
if (!this.linksFrom[sourceNodeId]) {
// @ts-expect-error fixme ts strict error
this.linksFrom[sourceNodeId] = {}
}
// @ts-expect-error fixme ts strict error
if (!this.linksFrom[sourceNodeId][sourceNodeSlot]) {
// @ts-expect-error fixme ts strict error
this.linksFrom[sourceNodeId][sourceNodeSlot] = []
}
// @ts-expect-error fixme ts strict error
this.linksFrom[sourceNodeId][sourceNodeSlot].push(l)
// @ts-expect-error fixme ts strict error
if (!this.linksTo[targetNodeId]) {
// @ts-expect-error fixme ts strict error
this.linksTo[targetNodeId] = {}
}
// @ts-expect-error fixme ts strict error
this.linksTo[targetNodeId][targetNodeSlot] = l
}
if (this.nodeData.external) {
for (const ext of this.nodeData.external) {
// @ts-expect-error fixme ts strict error
if (!this.externalFrom[ext[0]]) {
// @ts-expect-error fixme ts strict error
this.externalFrom[ext[0]] = { [ext[1]]: ext[2] }
} else {
// @ts-expect-error fixme ts strict error
this.externalFrom[ext[0]][ext[1]] = ext[2]
}
}
}
}
// @ts-expect-error fixme ts strict error
processNode(node, seenInputs, seenOutputs) {
const def = this.getNodeDef(node)
if (!def) return
@@ -293,10 +321,13 @@ export class GroupNodeConfig {
if (def.output?.length) this.processNodeOutputs(node, seenOutputs, def)
}
// @ts-expect-error fixme ts strict error
getNodeDef(node) {
// @ts-expect-error fixme ts strict error
const def = globalDefs[node.type]
if (def) return def
// @ts-expect-error fixme ts strict error
const linksFrom = this.linksFrom[node.index]
if (node.type === 'PrimitiveNode') {
// Skip as its not linked
@@ -307,12 +338,14 @@ export class GroupNodeConfig {
// Use the array items
const source = node.outputs[0].widget.name
const fromTypeName = this.nodeData.nodes[linksFrom['0'][0][2]].type
// @ts-expect-error fixme ts strict error
const fromType = globalDefs[fromTypeName]
const input =
fromType.input.required[source] ?? fromType.input.optional[source]
type = input[0]
}
// @ts-expect-error fixme ts strict error
const def = (this.primitiveDefs[node.index] = {
input: {
required: {
@@ -325,7 +358,9 @@ export class GroupNodeConfig {
})
return def
} else if (node.type === 'Reroute') {
// @ts-expect-error fixme ts strict error
const linksTo = this.linksTo[node.index]
// @ts-expect-error fixme ts strict error
if (linksTo && linksFrom && !this.externalFrom[node.index]?.[0]) {
// Being used internally
return null
@@ -341,6 +376,7 @@ export class GroupNodeConfig {
rerouteType = input.type
}
if (input.widget) {
// @ts-expect-error fixme ts strict error
const targetDef = globalDefs[node.type]
const targetWidget =
targetDef.input.required[input.widget.name] ??
@@ -373,6 +409,7 @@ export class GroupNodeConfig {
}
if (rerouteType === '*') {
// Check for an external link
// @ts-expect-error fixme ts strict error
const t = this.externalFrom[node.index]?.[0]
if (t) {
rerouteType = t
@@ -402,10 +439,12 @@ export class GroupNodeConfig {
)
}
// @ts-expect-error fixme ts strict error
getInputConfig(node, inputName, seenInputs, config, extra?) {
const customConfig = this.nodeData.config?.[node.index]?.input?.[inputName]
let name =
customConfig?.name ??
// @ts-expect-error fixme ts strict error
node.inputs?.find((inp) => inp.name === inputName)?.label ??
inputName
let key = name
@@ -427,6 +466,7 @@ export class GroupNodeConfig {
if (config[0] === 'IMAGEUPLOAD') {
if (!extra) extra = {}
extra.widget =
// @ts-expect-error fixme ts strict error
this.oldToNewWidgetMap[node.index]?.[config[1]?.widget ?? 'image'] ??
'image'
}
@@ -438,19 +478,23 @@ export class GroupNodeConfig {
return { name, config, customConfig }
}
// @ts-expect-error fixme ts strict error
processWidgetInputs(inputs, node, inputNames, seenInputs) {
const slots = []
const converted = new Map()
// @ts-expect-error fixme ts strict error
const widgetMap = (this.oldToNewWidgetMap[node.index] = {})
for (const inputName of inputNames) {
if (useWidgetStore().inputIsWidget(inputs[inputName])) {
const convertedIndex = node.inputs?.findIndex(
// @ts-expect-error fixme ts strict error
(inp) => inp.name === inputName && inp.widget?.name === inputName
)
if (convertedIndex > -1) {
// This widget has been converted to a widget
// We need to store this in the correct position so link ids line up
converted.set(convertedIndex, inputName)
// @ts-expect-error fixme ts strict error
widgetMap[inputName] = null
} else {
// Normal widget
@@ -460,8 +504,11 @@ export class GroupNodeConfig {
seenInputs,
inputs[inputName]
)
// @ts-expect-error fixme ts strict error
this.nodeDef.input.required[name] = config
// @ts-expect-error fixme ts strict error
widgetMap[inputName] = name
// @ts-expect-error fixme ts strict error
this.newToOldWidgetMap[name] = { node, inputName }
}
} else {
@@ -472,11 +519,13 @@ export class GroupNodeConfig {
return { converted, slots }
}
// @ts-expect-error fixme ts strict error
checkPrimitiveConnection(link, inputName, inputs) {
const sourceNode = this.nodeData.nodes[link[0]]
if (sourceNode.type === 'PrimitiveNode') {
// Merge link configurations
const [sourceNodeId, _, targetNodeId, __] = link
// @ts-expect-error fixme ts strict error
const primitiveDef = this.primitiveDefs[sourceNodeId]
const targetWidget = inputs[inputName]
const primitiveConfig = primitiveDef.input.required.value
@@ -494,13 +543,16 @@ export class GroupNodeConfig {
? { ...inputs[inputName][1] }
: {}
// @ts-expect-error fixme ts strict error
let name = this.oldToNewWidgetMap[sourceNodeId]['value']
name = name.substr(0, name.length - 6)
primitiveConfig[1].control_after_generate = true
primitiveConfig[1].control_prefix = name
// @ts-expect-error fixme ts strict error
let toPrimitive = this.widgetToPrimitive[targetNodeId]
if (!toPrimitive) {
// @ts-expect-error fixme ts strict error
toPrimitive = this.widgetToPrimitive[targetNodeId] = {}
}
if (toPrimitive[inputName]) {
@@ -508,15 +560,19 @@ export class GroupNodeConfig {
}
toPrimitive[inputName] = sourceNodeId
// @ts-expect-error fixme ts strict error
let toWidget = this.primitiveToWidget[sourceNodeId]
if (!toWidget) {
// @ts-expect-error fixme ts strict error
toWidget = this.primitiveToWidget[sourceNodeId] = []
}
toWidget.push({ nodeId: targetNodeId, inputName })
}
}
// @ts-expect-error fixme ts strict error
processInputSlots(inputs, node, slots, linksTo, inputMap, seenInputs) {
// @ts-expect-error fixme ts strict error
this.nodeInputs[node.index] = {}
for (let i = 0; i < slots.length; i++) {
const inputName = slots[i]
@@ -533,21 +589,30 @@ export class GroupNodeConfig {
inputs[inputName]
)
// @ts-expect-error fixme ts strict error
this.nodeInputs[node.index][inputName] = name
if (customConfig?.visible === false) continue
// @ts-expect-error fixme ts strict error
this.nodeDef.input.required[name] = config
inputMap[i] = this.inputCount++
}
}
processConvertedWidgets(
// @ts-expect-error fixme ts strict error
inputs,
// @ts-expect-error fixme ts strict error
node,
// @ts-expect-error fixme ts strict error
slots,
// @ts-expect-error fixme ts strict error
converted,
// @ts-expect-error fixme ts strict error
linksTo,
// @ts-expect-error fixme ts strict error
inputMap,
// @ts-expect-error fixme ts strict error
seenInputs
) {
// Add converted widgets sorted into their index order (ordered as they were converted) so link ids match up
@@ -576,12 +641,17 @@ export class GroupNodeConfig {
}
)
// @ts-expect-error fixme ts strict error
this.nodeDef.input.required[name] = config
// @ts-expect-error fixme ts strict error
this.newToOldWidgetMap[name] = { node, inputName }
// @ts-expect-error fixme ts strict error
if (!this.oldToNewWidgetMap[node.index]) {
// @ts-expect-error fixme ts strict error
this.oldToNewWidgetMap[node.index] = {}
}
// @ts-expect-error fixme ts strict error
this.oldToNewWidgetMap[node.index][inputName] = name
inputMap[slots.length + i] = this.inputCount++
@@ -589,7 +659,9 @@ export class GroupNodeConfig {
}
#convertedToProcess = []
// @ts-expect-error fixme ts strict error
processNodeInputs(node, seenInputs, inputs) {
// @ts-expect-error fixme ts strict error
const inputMapping = []
const inputNames = Object.keys(inputs)
@@ -601,11 +673,14 @@ export class GroupNodeConfig {
inputNames,
seenInputs
)
// @ts-expect-error fixme ts strict error
const linksTo = this.linksTo[node.index] ?? {}
// @ts-expect-error fixme ts strict error
const inputMap = (this.oldToNewInputMap[node.index] = {})
this.processInputSlots(inputs, node, slots, linksTo, inputMap, seenInputs)
// Converted inputs have to be processed after all other nodes as they'll be at the end of the list
// @ts-expect-error fixme ts strict error
this.#convertedToProcess.push(() =>
this.processConvertedWidgets(
inputs,
@@ -618,17 +693,22 @@ export class GroupNodeConfig {
)
)
// @ts-expect-error fixme ts strict error
return inputMapping
}
// @ts-expect-error fixme ts strict error
processNodeOutputs(node, seenOutputs, def) {
// @ts-expect-error fixme ts strict error
const oldToNew = (this.oldToNewOutputMap[node.index] = {})
// Add outputs
for (let outputId = 0; outputId < def.output.length; outputId++) {
// @ts-expect-error fixme ts strict error
const linksFrom = this.linksFrom[node.index]
// If this output is linked internally we flag it to hide
const hasLink =
// @ts-expect-error fixme ts strict error
linksFrom?.[outputId] && !this.externalFrom[node.index]?.[outputId]
const customConfig =
this.nodeData.config?.[node.index]?.output?.[outputId]
@@ -638,17 +718,22 @@ export class GroupNodeConfig {
continue
}
// @ts-expect-error fixme ts strict error
oldToNew[outputId] = this.nodeDef.output.length
// @ts-expect-error fixme ts strict error
this.newToOldOutputMap[this.nodeDef.output.length] = {
node,
slot: outputId
}
// @ts-expect-error fixme ts strict error
this.nodeDef.output.push(def.output[outputId])
// @ts-expect-error fixme ts strict error
this.nodeDef.output_is_list.push(def.output_is_list[outputId])
let label = customConfig?.name
if (!label) {
label = def.output_name?.[outputId] ?? def.output[outputId]
// @ts-expect-error fixme ts strict error
const output = node.outputs.find((o) => o.name === label)
if (output?.label) {
label = output.label
@@ -665,10 +750,12 @@ export class GroupNodeConfig {
}
seenOutputs[name] = 1
// @ts-expect-error fixme ts strict error
this.nodeDef.output_name.push(name)
}
}
// @ts-expect-error fixme ts strict error
static async registerFromWorkflow(groupNodes, missingNodeTypes) {
for (const g in groupNodes) {
const groupData = groupNodes[g]
@@ -686,6 +773,7 @@ export class GroupNodeConfig {
type: `${PREFIX}${SEPARATOR}` + g,
action: {
text: 'Remove from workflow',
// @ts-expect-error fixme ts strict error
callback: (e) => {
delete groupNodes[g]
e.target.textContent = 'Removed'
@@ -733,6 +821,7 @@ export class GroupNodeHandler {
}
innerNode.index = innerNodeIndex
// @ts-expect-error fixme ts strict error
innerNode.getInputNode = (slot) => {
// Check if this input is internal or external
const externalSlot =
@@ -752,17 +841,17 @@ export class GroupNodeHandler {
return inputNode
}
// @ts-expect-error fixme ts strict error
innerNode.getInputLink = (slot) => {
const externalSlot =
this.groupData.oldToNewInputMap[innerNode.index]?.[slot]
if (externalSlot != null) {
// The inner node is connected via the group node inputs
const linkId = this.node.inputs[externalSlot].link
// @ts-expect-error fixme ts strict error
let link = app.graph.links[linkId]
// Use the outer link, but update the target to the inner node
// @ts-expect-error
// TODO: Fix this
link = {
...link,
target_id: innerNode.id,
@@ -812,10 +901,14 @@ export class GroupNodeHandler {
this.node.getInnerNodes = () => {
if (!this.innerNodes) {
// @ts-expect-error fixme ts strict error
this.node.setInnerNodes(
// @ts-expect-error fixme ts strict error
this.groupData.nodeData.nodes.map((n, i) => {
const innerNode = LiteGraph.createNode(n.type)
// @ts-expect-error fixme ts strict error
innerNode.configure(n)
// @ts-expect-error fixme ts strict error
innerNode.id = `${this.node.id}:${i}`
return innerNode
})
@@ -827,36 +920,50 @@ export class GroupNodeHandler {
return this.innerNodes
}
// @ts-expect-error fixme ts strict error
this.node.recreate = async () => {
const id = this.node.id
const sz = this.node.size
// @ts-expect-error fixme ts strict error
const nodes = this.node.convertToNodes()
// @ts-expect-error fixme ts strict error
const groupNode = LiteGraph.createNode(this.node.type)
// @ts-expect-error fixme ts strict error
groupNode.id = id
// Reuse the existing nodes for this instance
// @ts-expect-error fixme ts strict error
groupNode.setInnerNodes(nodes)
// @ts-expect-error fixme ts strict error
groupNode[GROUP].populateWidgets()
// @ts-expect-error fixme ts strict error
app.graph.add(groupNode)
// @ts-expect-error fixme ts strict error
groupNode.setSize([
// @ts-expect-error fixme ts strict error
Math.max(groupNode.size[0], sz[0]),
// @ts-expect-error fixme ts strict error
Math.max(groupNode.size[1], sz[1])
])
// Remove all converted nodes and relink them
const builder = new GroupNodeBuilder(nodes)
const nodeData = builder.getNodeData()
// @ts-expect-error fixme ts strict error
groupNode[GROUP].groupData.nodeData.links = nodeData.links
// @ts-expect-error fixme ts strict error
groupNode[GROUP].replaceNodes(nodes)
return groupNode
}
// @ts-expect-error fixme ts strict error
this.node.convertToNodes = () => {
const addInnerNodes = () => {
// Clone the node data so we dont mutate it for other nodes
const c = { ...this.groupData.nodeData }
c.nodes = [...c.nodes]
// @ts-expect-error fixme ts strict error
const innerNodes = this.node.getInnerNodes()
let ids = []
for (let i = 0; i < c.nodes.length; i++) {
@@ -864,6 +971,7 @@ export class GroupNodeHandler {
// Use existing IDs if they are set on the inner nodes
// @ts-expect-error id can be string or number
if (id == null || isNaN(id)) {
// @ts-expect-error fixme ts strict error
id = undefined
} else {
ids.push(id)
@@ -886,15 +994,21 @@ export class GroupNodeHandler {
const innerNode = innerNodes[i]
newNodes.push(newNode)
// @ts-expect-error fixme ts strict error
if (left == null || newNode.pos[0] < left) {
// @ts-expect-error fixme ts strict error
left = newNode.pos[0]
}
// @ts-expect-error fixme ts strict error
if (top == null || newNode.pos[1] < top) {
// @ts-expect-error fixme ts strict error
top = newNode.pos[1]
}
// @ts-expect-error fixme ts strict error
if (!newNode.widgets) continue
// @ts-expect-error fixme ts strict error
const map = this.groupData.oldToNewWidgetMap[innerNode.index]
if (map) {
const widgets = Object.keys(map)
@@ -903,6 +1017,7 @@ export class GroupNodeHandler {
const newName = map[oldName]
if (!newName) continue
// @ts-expect-error fixme ts strict error
const widgetIndex = this.node.widgets.findIndex(
(w) => w.name === newName
)
@@ -910,20 +1025,28 @@ export class GroupNodeHandler {
// Populate the main and any linked widgets
if (innerNode.type === 'PrimitiveNode') {
// @ts-expect-error fixme ts strict error
for (let i = 0; i < newNode.widgets.length; i++) {
// @ts-expect-error fixme ts strict error
newNode.widgets[i].value =
// @ts-expect-error fixme ts strict error
this.node.widgets[widgetIndex + i].value
}
} else {
// @ts-expect-error fixme ts strict error
const outerWidget = this.node.widgets[widgetIndex]
// @ts-expect-error fixme ts strict error
const newWidget = newNode.widgets.find(
(w) => w.name === oldName
)
if (!newWidget) continue
newWidget.value = outerWidget.value
// @ts-expect-error fixme ts strict error
for (let w = 0; w < outerWidget.linkedWidgets?.length; w++) {
// @ts-expect-error fixme ts strict error
newWidget.linkedWidgets[w].value =
// @ts-expect-error fixme ts strict error
outerWidget.linkedWidgets[w].value
}
}
@@ -933,13 +1056,16 @@ export class GroupNodeHandler {
// Shift each node
for (const newNode of newNodes) {
// @ts-expect-error fixme ts strict error
newNode.pos[0] -= left - x
// @ts-expect-error fixme ts strict error
newNode.pos[1] -= top - y
}
return { newNodes, selectedIds }
}
// @ts-expect-error fixme ts strict error
const reconnectInputs = (selectedIds) => {
for (const innerNodeIndex in this.groupData.oldToNewInputMap) {
const id = selectedIds[innerNodeIndex]
@@ -954,11 +1080,13 @@ export class GroupNodeHandler {
if (!link) continue
// connect this node output to the input of another node
const originNode = app.graph.getNodeById(link.origin_id)
// @ts-expect-error fixme ts strict error
originNode.connect(link.origin_slot, newNode, +innerInputId)
}
}
}
// @ts-expect-error fixme ts strict error
const reconnectOutputs = (selectedIds) => {
for (
let groupOutputId = 0;
@@ -973,6 +1101,7 @@ export class GroupNodeHandler {
const link = app.graph.links[l]
const targetNode = app.graph.getNodeById(link.target_id)
const newNode = app.graph.getNodeById(selectedIds[slot.node.index])
// @ts-expect-error fixme ts strict error
newNode.connect(slot.slot, targetNode, link.target_slot)
}
}
@@ -995,8 +1124,10 @@ export class GroupNodeHandler {
const getExtraMenuOptions = this.node.getExtraMenuOptions
// @ts-expect-error Should pass patched return value getExtraMenuOptions
this.node.getExtraMenuOptions = function (_, options) {
// @ts-expect-error fixme ts strict error
getExtraMenuOptions?.apply(this, arguments)
// @ts-expect-error fixme ts strict error
let optionIndex = options.findIndex((o) => o.content === 'Outputs')
if (optionIndex === -1) optionIndex = options.length
else optionIndex++
@@ -1008,11 +1139,13 @@ export class GroupNodeHandler {
content: 'Convert to nodes',
// @ts-expect-error
callback: () => {
// @ts-expect-error fixme ts strict error
return this.convertToNodes()
}
},
{
content: 'Manage Group Node',
// @ts-expect-error fixme ts strict error
callback: () => manageGroupNodes(this.type)
}
)
@@ -1021,6 +1154,7 @@ export class GroupNodeHandler {
// Draw custom collapse icon to identity this as a group
const onDrawTitleBox = this.node.onDrawTitleBox
this.node.onDrawTitleBox = function (ctx, height) {
// @ts-expect-error fixme ts strict error
onDrawTitleBox?.apply(this, arguments)
const fill = ctx.fillStyle
@@ -1044,11 +1178,14 @@ export class GroupNodeHandler {
const onDrawForeground = node.onDrawForeground
const groupData = this.groupData.nodeData
node.onDrawForeground = function (ctx) {
// @ts-expect-error fixme ts strict error
onDrawForeground?.apply?.(this, arguments)
if (
// @ts-expect-error fixme ts strict error
+app.runningNodeId === this.id &&
this.runningInternalNodeId !== null
) {
// @ts-expect-error fixme ts strict error
const n = groupData.nodes[this.runningInternalNodeId]
if (!n) return
const message = `Running ${n.title || n.type} (${this.runningInternalNodeId}/${groupData.nodes.length})`
@@ -1075,7 +1212,9 @@ export class GroupNodeHandler {
// Flag this node as needing to be reset
const onExecutionStart = this.node.onExecutionStart
this.node.onExecutionStart = function () {
// @ts-expect-error fixme ts strict error
this.resetExecution = true
// @ts-expect-error fixme ts strict error
return onExecutionStart?.apply(this, arguments)
}
@@ -1094,6 +1233,7 @@ export class GroupNodeHandler {
const widgetName = self.groupData.oldToNewWidgetMap[n][w]
const widget = this.widgets.find((w) => w.name === widgetName)
if (widget) {
// @ts-expect-error fixme ts strict error
widget.type = 'hidden'
widget.computeSize = () => [0, -4]
}
@@ -1101,21 +1241,27 @@ export class GroupNodeHandler {
}
}
// @ts-expect-error fixme ts strict error
return onNodeCreated?.apply(this, arguments)
}
// @ts-expect-error fixme ts strict error
function handleEvent(type, getId, getEvent) {
// @ts-expect-error fixme ts strict error
const handler = ({ detail }) => {
const id = getId(detail)
if (!id) return
const node = app.graph.getNodeById(id)
if (node) return
// @ts-expect-error fixme ts strict error
const innerNodeIndex = this.innerNodes?.findIndex((n) => n.id == id)
if (innerNodeIndex > -1) {
// @ts-expect-error fixme ts strict error
this.node.runningInternalNodeId = innerNodeIndex
api.dispatchCustomEvent(
type,
// @ts-expect-error fixme ts strict error
getEvent(detail, `${this.node.id}`, this.node)
)
}
@@ -1127,14 +1273,18 @@ export class GroupNodeHandler {
const executing = handleEvent.call(
this,
'executing',
// @ts-expect-error fixme ts strict error
(d) => d,
// @ts-expect-error fixme ts strict error
(_, id) => id
)
const executed = handleEvent.call(
this,
'executed',
// @ts-expect-error fixme ts strict error
(d) => d?.display_node || d?.node,
// @ts-expect-error fixme ts strict error
(d, id, node) => ({
...d,
node: id,
@@ -1145,6 +1295,7 @@ export class GroupNodeHandler {
const onRemoved = node.onRemoved
this.node.onRemoved = function () {
// @ts-expect-error fixme ts strict error
onRemoved?.apply(this, arguments)
api.removeEventListener('executing', executing)
api.removeEventListener('executed', executed)
@@ -1153,6 +1304,7 @@ export class GroupNodeHandler {
this.node.refreshComboInNode = (defs) => {
// Update combo widget options
for (const widgetName in this.groupData.newToOldWidgetMap) {
// @ts-expect-error fixme ts strict error
const widget = this.node.widgets.find((w) => w.name === widgetName)
if (widget?.type === 'combo') {
const old = this.groupData.newToOldWidgetMap[widgetName]
@@ -1169,7 +1321,9 @@ export class GroupNodeHandler {
// @ts-expect-error Widget values
!widget.options.values.includes(widget.value)
) {
// @ts-expect-error fixme ts strict error
widget.value = widget.options.values[0]
// @ts-expect-error fixme ts strict error
widget.callback(widget.value)
}
}
@@ -1179,6 +1333,7 @@ export class GroupNodeHandler {
updateInnerWidgets() {
for (const newWidgetName in this.groupData.newToOldWidgetMap) {
// @ts-expect-error fixme ts strict error
const newWidget = this.node.widgets.find((w) => w.name === newWidgetName)
if (!newWidget) continue
@@ -1191,6 +1346,7 @@ export class GroupNodeHandler {
const primitiveLinked = this.groupData.primitiveToWidget[old.node.index]
for (const linked of primitiveLinked ?? []) {
const node = this.innerNodes[linked.nodeId]
// @ts-expect-error fixme ts strict error
const widget = node.widgets.find((w) => w.name === linked.inputName)
if (widget) {
@@ -1206,6 +1362,7 @@ export class GroupNodeHandler {
const input = node.inputs[targetSlot]
if (input.widget) {
const widget = node.widgets?.find(
// @ts-expect-error fixme ts strict error
(w) => w.name === input.widget.name
)
if (widget) {
@@ -1216,6 +1373,7 @@ export class GroupNodeHandler {
}
}
// @ts-expect-error fixme ts strict error
const widget = innerNode.widgets?.find((w) => w.name === old.inputName)
if (widget) {
widget.value = newValue
@@ -1223,12 +1381,14 @@ export class GroupNodeHandler {
}
}
// @ts-expect-error fixme ts strict error
populatePrimitive(_node, nodeId, oldName) {
// Converted widget, populate primitive if linked
const primitiveId = this.groupData.widgetToPrimitive[nodeId]?.[oldName]
if (primitiveId == null) return
const targetWidgetName =
this.groupData.oldToNewWidgetMap[primitiveId]['value']
// @ts-expect-error fixme ts strict error
const targetWidgetIndex = this.node.widgets.findIndex(
(w) => w.name === targetWidgetName
)
@@ -1237,6 +1397,7 @@ export class GroupNodeHandler {
let len = primitiveNode.widgets.length
if (
len - 1 !==
// @ts-expect-error fixme ts strict error
this.node.widgets[targetWidgetIndex].linkedWidgets?.length
) {
// Fallback handling for if some reason the primitive has a different number of widgets
@@ -1244,6 +1405,7 @@ export class GroupNodeHandler {
len = 1
}
for (let i = 0; i < len; i++) {
// @ts-expect-error fixme ts strict error
this.node.widgets[targetWidgetIndex + i].value =
primitiveNode.widgets[i].value
}
@@ -1251,6 +1413,7 @@ export class GroupNodeHandler {
return true
}
// @ts-expect-error fixme ts strict error
populateReroute(node, nodeId, map) {
if (node.type !== 'Reroute') return
@@ -1267,6 +1430,7 @@ export class GroupNodeHandler {
if (v == null) return
const widgetName = Object.values(map)[0]
// @ts-expect-error fixme ts strict error
const widget = this.node.widgets.find((w) => w.name === widgetName)
if (widget) {
widget.value = v
@@ -1306,6 +1470,7 @@ export class GroupNodeHandler {
) {
// Find the inner widget and shift by the number of linked widgets as they will have been removed too
const innerWidget = this.innerNodes[nodeId].widgets?.find(
// @ts-expect-error fixme ts strict error
(w) => w.name === oldName
)
linkedShift += innerWidget?.linkedWidgets?.length ?? 0
@@ -1316,6 +1481,7 @@ export class GroupNodeHandler {
// Populate the main and any linked widget
mainWidget.value = node.widgets_values[i + linkedShift]
// @ts-expect-error fixme ts strict error
for (let w = 0; w < mainWidget.linkedWidgets?.length; w++) {
this.node.widgets[widgetIndex + w + 1].value =
node.widgets_values[i + ++linkedShift]
@@ -1324,6 +1490,7 @@ export class GroupNodeHandler {
}
}
// @ts-expect-error fixme ts strict error
replaceNodes(nodes) {
let top
let left
@@ -1345,6 +1512,7 @@ export class GroupNodeHandler {
this.node.pos = [left, top]
}
// @ts-expect-error fixme ts strict error
linkOutputs(originalNode, nodeId) {
if (!originalNode.outputs) return
@@ -1360,6 +1528,7 @@ export class GroupNodeHandler {
const newSlot =
this.groupData.oldToNewOutputMap[nodeId]?.[link.origin_slot]
if (newSlot != null) {
// @ts-expect-error fixme ts strict error
this.node.connect(newSlot, targetNode, link.target_slot)
}
}
@@ -1380,6 +1549,7 @@ export class GroupNodeHandler {
}
}
// @ts-expect-error fixme ts strict error
static getGroupData(node) {
return (node.nodeData ?? node.constructor?.nodeData)?.[GROUP]
}
@@ -1402,17 +1572,22 @@ export class GroupNodeHandler {
const groupNode = LiteGraph.createNode(`${PREFIX}${SEPARATOR}${name}`)
// Reuse the existing nodes for this instance
// @ts-expect-error fixme ts strict error
groupNode.setInnerNodes(builder.nodes)
// @ts-expect-error fixme ts strict error
groupNode[GROUP].populateWidgets()
// @ts-expect-error fixme ts strict error
app.graph.add(groupNode)
// Remove all converted nodes and relink them
// @ts-expect-error fixme ts strict error
groupNode[GROUP].replaceNodes(builder.nodes)
return groupNode
}
}
function addConvertToGroupOptions() {
// @ts-expect-error fixme ts strict error
function addConvertOption(options, index) {
const selected = Object.values(app.canvas.selected_nodes ?? {})
const disabled =
@@ -1425,6 +1600,7 @@ function addConvertToGroupOptions() {
})
}
// @ts-expect-error fixme ts strict error
function addManageOption(options, index) {
const groups = app.graph.extra?.groupNodes
const disabled = !groups || !Object.keys(groups).length
@@ -1438,6 +1614,7 @@ function addConvertToGroupOptions() {
// Add to canvas
const getCanvasMenuOptions = LGraphCanvas.prototype.getCanvasMenuOptions
LGraphCanvas.prototype.getCanvasMenuOptions = function () {
// @ts-expect-error fixme ts strict error
const options = getCanvasMenuOptions.apply(this, arguments)
const index =
options.findIndex((o) => o?.content === 'Add Group') + 1 || options.length
@@ -1449,6 +1626,7 @@ function addConvertToGroupOptions() {
// Add to nodes
const getNodeMenuOptions = LGraphCanvas.prototype.getNodeMenuOptions
LGraphCanvas.prototype.getNodeMenuOptions = function (node) {
// @ts-expect-error fixme ts strict error
const options = getNodeMenuOptions.apply(this, arguments)
if (!GroupNodeHandler.isGroupNode(node)) {
const index =
@@ -1505,6 +1683,7 @@ function manageGroupNodes(type?: string) {
}
const id = 'Comfy.GroupNode'
// @ts-expect-error fixme ts strict error
let globalDefs
const ext: ComfyExtension = {
name: id,
@@ -1567,16 +1746,21 @@ const ext: ComfyExtension = {
},
nodeCreated(node) {
if (GroupNodeHandler.isGroupNode(node)) {
// @ts-expect-error fixme ts strict error
node[GROUP] = new GroupNodeHandler(node)
// Ensure group nodes pasted from other workflows are stored
// @ts-expect-error fixme ts strict error
if (node.title && node[GROUP]?.groupData?.nodeData) {
// @ts-expect-error fixme ts strict error
Workflow.storeGroupNode(node.title, node[GROUP].groupData.nodeData)
}
}
},
// @ts-expect-error fixme ts strict error
async refreshComboInNodes(defs) {
// Re-register group nodes so new ones are created with the correct options
// @ts-expect-error fixme ts strict error
Object.assign(globalDefs, defs)
const nodes = app.graph.extra?.groupNodes
if (nodes) {

View File

@@ -1,4 +1,3 @@
// @ts-strict-ignore
import {
type LGraphNode,
type LGraphNodeConstructor,
@@ -17,6 +16,7 @@ const ORDER: symbol = Symbol()
const PREFIX = 'workflow'
const SEPARATOR = '>'
// @ts-expect-error fixme ts strict error
function merge(target, source) {
if (typeof target === 'object' && typeof source === 'object') {
for (const key in source) {
@@ -35,6 +35,7 @@ function merge(target, source) {
}
export class ManageGroupDialog extends ComfyDialog<HTMLDialogElement> {
// @ts-expect-error fixme ts strict error
tabs: Record<
'Inputs' | 'Outputs' | 'Widgets',
{ tab: HTMLAnchorElement; page: HTMLElement }
@@ -52,22 +53,30 @@ export class ManageGroupDialog extends ComfyDialog<HTMLDialogElement> {
>
>
> = {}
// @ts-expect-error fixme ts strict error
nodeItems: any[]
app: ComfyApp
// @ts-expect-error fixme ts strict error
groupNodeType: LGraphNodeConstructor<LGraphNode>
groupNodeDef: any
groupData: any
// @ts-expect-error fixme ts strict error
innerNodesList: HTMLUListElement
// @ts-expect-error fixme ts strict error
widgetsPage: HTMLElement
// @ts-expect-error fixme ts strict error
inputsPage: HTMLElement
// @ts-expect-error fixme ts strict error
outputsPage: HTMLElement
draggable: any
get selectedNodeInnerIndex() {
// @ts-expect-error fixme ts strict error
return +this.nodeItems[this.selectedNodeIndex].dataset.nodeindex
}
// @ts-expect-error fixme ts strict error
constructor(app) {
super()
this.app = app
@@ -76,14 +85,18 @@ export class ManageGroupDialog extends ComfyDialog<HTMLDialogElement> {
}) as HTMLDialogElement
}
// @ts-expect-error fixme ts strict error
changeTab(tab) {
this.tabs[this.selectedTab].tab.classList.remove('active')
this.tabs[this.selectedTab].page.classList.remove('active')
// @ts-expect-error fixme ts strict error
this.tabs[tab].tab.classList.add('active')
// @ts-expect-error fixme ts strict error
this.tabs[tab].page.classList.add('active')
this.selectedTab = tab
}
// @ts-expect-error fixme ts strict error
changeNode(index, force?) {
if (!force && this.selectedNodeIndex === index) return
@@ -114,11 +127,13 @@ export class ManageGroupDialog extends ComfyDialog<HTMLDialogElement> {
this.groupData = GroupNodeHandler.getGroupData(this.groupNodeType)
}
// @ts-expect-error fixme ts strict error
changeGroup(group, reset = true) {
this.selectedGroup = group
this.getGroupData()
const nodes = this.groupData.nodeData.nodes
// @ts-expect-error fixme ts strict error
this.nodeItems = nodes.map((n, i) =>
$el(
'li.draggable-item',
@@ -154,6 +169,7 @@ export class ManageGroupDialog extends ComfyDialog<HTMLDialogElement> {
this.changeNode(0)
} else {
const items = this.draggable.getAllItems()
// @ts-expect-error fixme ts strict error
let index = items.findIndex((item) => item.classList.contains('selected'))
if (index === -1) index = this.selectedNodeIndex
this.changeNode(index, true)
@@ -164,6 +180,7 @@ export class ManageGroupDialog extends ComfyDialog<HTMLDialogElement> {
this.draggable = new DraggableList(this.innerNodesList, 'li')
this.draggable.addEventListener(
'dragend',
// @ts-expect-error fixme ts strict error
({ detail: { oldPosition, newPosition } }) => {
if (oldPosition === newPosition) return
ordered.splice(newPosition, 0, ordered.splice(oldPosition, 1)[0])
@@ -186,6 +203,7 @@ export class ManageGroupDialog extends ComfyDialog<HTMLDialogElement> {
value: any
}) {
const { nodeIndex, section, prop, value } = props
// @ts-expect-error fixme ts strict error
const groupMod = (this.modifications[this.selectedGroup] ??= {})
const nodesMod = (groupMod.nodes ??= {})
const nodeMod = (nodesMod[nodeIndex ?? this.selectedNodeInnerIndex] ??= {})
@@ -198,10 +216,12 @@ export class ManageGroupDialog extends ComfyDialog<HTMLDialogElement> {
}
}
// @ts-expect-error fixme ts strict error
getEditElement(section, prop, value, placeholder, checked, checkable = true) {
if (value === placeholder) value = ''
const mods =
// @ts-expect-error fixme ts strict error
this.modifications[this.selectedGroup]?.nodes?.[
this.selectedNodeInnerIndex
]?.[section]?.[prop]
@@ -219,6 +239,7 @@ export class ManageGroupDialog extends ComfyDialog<HTMLDialogElement> {
value,
placeholder,
type: 'text',
// @ts-expect-error fixme ts strict error
onchange: (e) => {
this.storeModification({
section,
@@ -232,6 +253,7 @@ export class ManageGroupDialog extends ComfyDialog<HTMLDialogElement> {
type: 'checkbox',
checked,
disabled: !checkable,
// @ts-expect-error fixme ts strict error
onchange: (e) => {
this.storeModification({
section,
@@ -248,6 +270,7 @@ export class ManageGroupDialog extends ComfyDialog<HTMLDialogElement> {
const widgets =
this.groupData.oldToNewWidgetMap[this.selectedNodeInnerIndex]
const items = Object.keys(widgets ?? {})
// @ts-expect-error fixme ts strict error
const type = app.graph.extra.groupNodes[this.selectedGroup]
const config = type.config?.[this.selectedNodeInnerIndex]?.input
this.widgetsPage.replaceChildren(
@@ -267,9 +290,11 @@ export class ManageGroupDialog extends ComfyDialog<HTMLDialogElement> {
buildInputsPage() {
const inputs = this.groupData.nodeInputs[this.selectedNodeInnerIndex]
const items = Object.keys(inputs ?? {})
// @ts-expect-error fixme ts strict error
const type = app.graph.extra.groupNodes[this.selectedGroup]
const config = type.config?.[this.selectedNodeInnerIndex]?.input
this.inputsPage.replaceChildren(
// @ts-expect-error fixme ts strict error
...items
.map((oldName) => {
let value = inputs[oldName]
@@ -299,12 +324,14 @@ export class ManageGroupDialog extends ComfyDialog<HTMLDialogElement> {
const groupOutputs =
this.groupData.oldToNewOutputMap[this.selectedNodeInnerIndex]
// @ts-expect-error fixme ts strict error
const type = app.graph.extra.groupNodes[this.selectedGroup]
const config = type.config?.[this.selectedNodeInnerIndex]?.output
const node = this.groupData.nodeData.nodes[this.selectedNodeInnerIndex]
const checkable = node.type !== 'PrimitiveNode'
this.outputsPage.replaceChildren(
...outputs
// @ts-expect-error fixme ts strict error
.map((type, slot) => {
const groupOutputIndex = groupOutputs?.[slot]
const oldName = innerNodeDef.output_name?.[slot] ?? type
@@ -327,6 +354,7 @@ export class ManageGroupDialog extends ComfyDialog<HTMLDialogElement> {
return !!outputs.length
}
// @ts-expect-error fixme ts strict error
show(type?) {
const groupNodes = Object.keys(app.graph.extra?.groupNodes ?? {}).sort(
(a, b) => a.localeCompare(b)
@@ -348,7 +376,9 @@ export class ManageGroupDialog extends ComfyDialog<HTMLDialogElement> {
['Inputs', this.inputsPage],
['Widgets', this.widgetsPage],
['Outputs', this.outputsPage]
// @ts-expect-error fixme ts strict error
].reduce((p, [name, page]: [string, HTMLElement]) => {
// @ts-expect-error fixme ts strict error
p[name] = {
tab: $el('a', {
onclick: () => {
@@ -367,6 +397,7 @@ export class ManageGroupDialog extends ComfyDialog<HTMLDialogElement> {
$el(
'select',
{
// @ts-expect-error fixme ts strict error
onchange: (e) => {
this.changeGroup(e.target.value)
}
@@ -409,6 +440,7 @@ export class ManageGroupDialog extends ComfyDialog<HTMLDialogElement> {
`Are you sure you want to remove the node: "${this.selectedGroup}"`
)
) {
// @ts-expect-error fixme ts strict error
delete app.graph.extra.groupNodes[this.selectedGroup]
LiteGraph.unregisterNodeType(
`${PREFIX}${SEPARATOR}` + this.selectedGroup
@@ -427,12 +459,14 @@ export class ManageGroupDialog extends ComfyDialog<HTMLDialogElement> {
let recreateNodes = []
const types = {}
for (const g in this.modifications) {
// @ts-expect-error fixme ts strict error
const type = app.graph.extra.groupNodes[g]
let config = (type.config ??= {})
let nodeMods = this.modifications[g]?.nodes
if (nodeMods) {
const keys = Object.keys(nodeMods)
// @ts-expect-error fixme ts strict error
if (nodeMods[keys[0]][ORDER]) {
// If any node is reordered, they will all need sequencing
const orderedNodes = []
@@ -440,8 +474,10 @@ export class ManageGroupDialog extends ComfyDialog<HTMLDialogElement> {
const orderedConfig = {}
for (const n of keys) {
// @ts-expect-error fixme ts strict error
const order = nodeMods[n][ORDER].order
orderedNodes[order] = type.nodes[+n]
// @ts-expect-error fixme ts strict error
orderedMods[order] = nodeMods[n]
orderedNodes[order].index = order
}
@@ -462,6 +498,7 @@ export class ManageGroupDialog extends ComfyDialog<HTMLDialogElement> {
// Rewrite modifications
for (const id of keys) {
if (config[id]) {
// @ts-expect-error fixme ts strict error
orderedConfig[type.nodes[id].index] = config[id]
}
delete config[id]
@@ -475,16 +512,20 @@ export class ManageGroupDialog extends ComfyDialog<HTMLDialogElement> {
merge(config, nodeMods)
}
// @ts-expect-error fixme ts strict error
types[g] = type
if (!nodesByType) {
nodesByType = app.graph.nodes.reduce((p, n) => {
// @ts-expect-error fixme ts strict error
p[n.type] ??= []
// @ts-expect-error fixme ts strict error
p[n.type].push(n)
return p
}, {})
}
// @ts-expect-error fixme ts strict error
const nodes = nodesByType[`${PREFIX}${SEPARATOR}` + g]
if (nodes) recreateNodes.push(...nodes)
}

View File

@@ -1,4 +1,3 @@
// @ts-strict-ignore
import { LGraphGroup } from '@comfyorg/litegraph'
import { LGraphCanvas } from '@comfyorg/litegraph'
import type { LGraphNode } from '@comfyorg/litegraph'
@@ -26,7 +25,9 @@ app.registerExtension({
LGraphCanvas.prototype.getCanvasMenuOptions = function (
this: LGraphCanvas
) {
// @ts-expect-error fixme ts strict error
const options = orig.apply(this, arguments)
// @ts-expect-error fixme ts strict error
const group = this.graph.getGroupOnPos(
this.graph_mouse[0],
this.graph_mouse[1]
@@ -38,7 +39,9 @@ app.registerExtension({
callback: () => {
const group = new LGraphGroup()
addNodesToGroup(group, this.selectedItems)
// @ts-expect-error fixme ts strict error
this.graph.add(group)
// @ts-expect-error fixme ts strict error
this.graph.change()
}
})
@@ -56,6 +59,7 @@ app.registerExtension({
disabled: !this.selectedItems?.size,
callback: () => {
addNodesToGroup(group, this.selectedItems)
// @ts-expect-error fixme ts strict error
this.graph.change()
}
})
@@ -65,6 +69,7 @@ app.registerExtension({
return options
} else {
// Add a separator between the default options and the group options
// @ts-expect-error fixme ts strict error
options.push(null)
}
@@ -85,6 +90,7 @@ app.registerExtension({
'Comfy.GroupSelectedNodes.Padding'
)
group.resizeTo(group.children, padding)
// @ts-expect-error fixme ts strict error
this.graph.change()
}
})
@@ -93,6 +99,7 @@ app.registerExtension({
content: 'Select Nodes',
callback: () => {
this.selectNodes(nodesInGroup)
// @ts-expect-error fixme ts strict error
this.graph.change()
this.canvas.focus()
}

View File

@@ -1,4 +1,3 @@
// @ts-strict-ignore
import { api } from '../../scripts/api'
import { app } from '../../scripts/app'
import { ComfyApp } from '../../scripts/app'
@@ -6,6 +5,7 @@ import { $el, ComfyDialog } from '../../scripts/ui'
import { ClipspaceDialog } from './clipspace'
// Helper function to convert a data URL to a Blob object
// @ts-expect-error fixme ts strict error
function dataURLToBlob(dataURL) {
const parts = dataURL.split(';base64,')
const contentType = parts[0].split(':')[1]
@@ -18,6 +18,7 @@ function dataURLToBlob(dataURL) {
return new Blob([arrayBuffer], { type: contentType })
}
// @ts-expect-error fixme ts strict error
function loadImage(imagePath) {
return new Promise((resolve) => {
const image = new Image()
@@ -30,6 +31,7 @@ function loadImage(imagePath) {
})
}
// @ts-expect-error fixme ts strict error
async function uploadMask(filepath, formData) {
await api
.fetchApi('/upload/mask', {
@@ -40,7 +42,9 @@ async function uploadMask(filepath, formData) {
console.error('Error:', error)
})
// @ts-expect-error fixme ts strict error
ComfyApp.clipspace.imgs[ComfyApp.clipspace['selectedIndex']] = new Image()
// @ts-expect-error fixme ts strict error
ComfyApp.clipspace.imgs[ComfyApp.clipspace['selectedIndex']].src = api.apiURL(
'/view?' +
new URLSearchParams(filepath).toString() +
@@ -48,12 +52,15 @@ async function uploadMask(filepath, formData) {
app.getRandParam()
)
// @ts-expect-error fixme ts strict error
if (ComfyApp.clipspace.images)
// @ts-expect-error fixme ts strict error
ComfyApp.clipspace.images[ComfyApp.clipspace['selectedIndex']] = filepath
ClipspaceDialog.invalidatePreview()
}
// @ts-expect-error fixme ts strict error
function prepare_mask(image, maskCanvas, maskCtx, maskColor) {
// paste mask data into alpha channel
maskCtx.drawImage(image, 0, 0, maskCanvas.width, maskCanvas.height)
@@ -94,32 +101,55 @@ export class MaskEditorDialogOld extends ComfyDialog {
static mousedown_x: number | null = null
static mousedown_y: number | null = null
// @ts-expect-error fixme ts strict error
brush: HTMLDivElement
maskCtx: any
// @ts-expect-error fixme ts strict error
maskCanvas: HTMLCanvasElement
// @ts-expect-error fixme ts strict error
brush_size_slider: HTMLDivElement
// @ts-expect-error fixme ts strict error
brush_opacity_slider: HTMLDivElement
// @ts-expect-error fixme ts strict error
colorButton: HTMLButtonElement
// @ts-expect-error fixme ts strict error
saveButton: HTMLButtonElement
// @ts-expect-error fixme ts strict error
zoom_ratio: number
// @ts-expect-error fixme ts strict error
pan_x: number
// @ts-expect-error fixme ts strict error
pan_y: number
// @ts-expect-error fixme ts strict error
imgCanvas: HTMLCanvasElement
// @ts-expect-error fixme ts strict error
last_display_style: string
// @ts-expect-error fixme ts strict error
is_visible: boolean
// @ts-expect-error fixme ts strict error
image: HTMLImageElement
// @ts-expect-error fixme ts strict error
handler_registered: boolean
// @ts-expect-error fixme ts strict error
brush_slider_input: HTMLInputElement
// @ts-expect-error fixme ts strict error
cursorX: number
// @ts-expect-error fixme ts strict error
cursorY: number
// @ts-expect-error fixme ts strict error
mousedown_pan_x: number
// @ts-expect-error fixme ts strict error
mousedown_pan_y: number
// @ts-expect-error fixme ts strict error
last_pressure: number
// @ts-expect-error fixme ts strict error
pointer_type: PointerType
// @ts-expect-error fixme ts strict error
brush_pointer_type_select: HTMLDivElement
static getInstance() {
if (!MaskEditorDialogOld.instance) {
// @ts-expect-error fixme ts strict error
MaskEditorDialogOld.instance = new MaskEditorDialogOld()
}
@@ -139,6 +169,7 @@ export class MaskEditorDialogOld extends ComfyDialog {
return []
}
// @ts-expect-error fixme ts strict error
createButton(name, callback): HTMLButtonElement {
var button = document.createElement('button')
button.style.pointerEvents = 'auto'
@@ -147,6 +178,7 @@ export class MaskEditorDialogOld extends ComfyDialog {
return button
}
// @ts-expect-error fixme ts strict error
createLeftButton(name, callback) {
var button = this.createButton(name, callback)
button.style.cssFloat = 'left'
@@ -154,6 +186,7 @@ export class MaskEditorDialogOld extends ComfyDialog {
return button
}
// @ts-expect-error fixme ts strict error
createRightButton(name, callback) {
var button = this.createButton(name, callback)
button.style.cssFloat = 'right'
@@ -161,6 +194,7 @@ export class MaskEditorDialogOld extends ComfyDialog {
return button
}
// @ts-expect-error fixme ts strict error
createLeftSlider(self, name, callback): HTMLDivElement {
const divElement = document.createElement('div')
divElement.id = 'maskeditor-slider'
@@ -195,6 +229,7 @@ export class MaskEditorDialogOld extends ComfyDialog {
return divElement
}
// @ts-expect-error fixme ts strict error
createOpacitySlider(self, name, callback): HTMLDivElement {
const divElement = document.createElement('div')
divElement.id = 'maskeditor-opacity-slider'
@@ -339,6 +374,7 @@ export class MaskEditorDialogOld extends ComfyDialog {
this.brush_size_slider = this.createLeftSlider(
self,
'Thickness',
// @ts-expect-error fixme ts strict error
(event) => {
self.brush_size = event.target.value
self.updateBrushPreview(self)
@@ -348,6 +384,7 @@ export class MaskEditorDialogOld extends ComfyDialog {
this.brush_opacity_slider = this.createOpacitySlider(
self,
'Opacity',
// @ts-expect-error fixme ts strict error
(event) => {
self.brush_opacity = event.target.value
if (self.brush_color_mode !== 'negative') {
@@ -482,6 +519,7 @@ export class MaskEditorDialogOld extends ComfyDialog {
return this.element.style.display == 'block'
}
// @ts-expect-error fixme ts strict error
invalidateCanvas(orig_image, mask_image) {
this.imgCanvas.width = orig_image.width
this.imgCanvas.height = orig_image.height
@@ -494,10 +532,12 @@ export class MaskEditorDialogOld extends ComfyDialog {
willReadFrequently: true
})
// @ts-expect-error fixme ts strict error
imgCtx.drawImage(orig_image, 0, 0, orig_image.width, orig_image.height)
prepare_mask(mask_image, this.maskCanvas, maskCtx, this.getMaskColor())
}
// @ts-expect-error fixme ts strict error
async setImages(imgCanvas) {
let self = this
@@ -510,6 +550,7 @@ export class MaskEditorDialogOld extends ComfyDialog {
// image load
const alpha_url = new URL(
// @ts-expect-error fixme ts strict error
ComfyApp.clipspace.imgs[ComfyApp.clipspace['selectedIndex']].src
)
alpha_url.searchParams.delete('channel')
@@ -519,6 +560,7 @@ export class MaskEditorDialogOld extends ComfyDialog {
// original image load
const rgb_url = new URL(
// @ts-expect-error fixme ts strict error
ComfyApp.clipspace.imgs[ComfyApp.clipspace['selectedIndex']].src
)
rgb_url.searchParams.delete('channel')
@@ -591,10 +633,12 @@ export class MaskEditorDialogOld extends ComfyDialog {
this.imgCanvas.style.top = top
}
// @ts-expect-error fixme ts strict error
setEventHandler(maskCanvas) {
const self = this
if (!this.handler_registered) {
// @ts-expect-error fixme ts strict error
maskCanvas.addEventListener('contextmenu', (event) => {
event.preventDefault()
})
@@ -615,12 +659,15 @@ export class MaskEditorDialogOld extends ComfyDialog {
}
})
// @ts-expect-error fixme ts strict error
maskCanvas.addEventListener('pointerdown', (event) =>
this.handlePointerDown(self, event)
)
// @ts-expect-error fixme ts strict error
maskCanvas.addEventListener('pointermove', (event) =>
this.draw_move(self, event)
)
// @ts-expect-error fixme ts strict error
maskCanvas.addEventListener('touchmove', (event) =>
this.draw_move(self, event)
)
@@ -726,30 +773,40 @@ export class MaskEditorDialogOld extends ComfyDialog {
lasty = -1
lasttime = 0
// @ts-expect-error fixme ts strict error
static handleKeyDown(event) {
const self = MaskEditorDialogOld.instance
if (event.key === ']') {
// @ts-expect-error fixme ts strict error
self.brush_size = Math.min(self.brush_size + 2, 100)
// @ts-expect-error fixme ts strict error
self.brush_slider_input.value = self.brush_size
} else if (event.key === '[') {
// @ts-expect-error fixme ts strict error
self.brush_size = Math.max(self.brush_size - 2, 1)
// @ts-expect-error fixme ts strict error
self.brush_slider_input.value = self.brush_size
} else if (event.key === 'Enter') {
// @ts-expect-error fixme ts strict error
self.save()
}
// @ts-expect-error fixme ts strict error
self.updateBrushPreview(self)
}
// @ts-expect-error fixme ts strict error
static handlePointerUp(event) {
event.preventDefault()
this.mousedown_x = null
this.mousedown_y = null
// @ts-expect-error fixme ts strict error
MaskEditorDialogOld.instance.drawing_mode = false
}
// @ts-expect-error fixme ts strict error
updateBrushPreview(self) {
const brush = self.brush
@@ -762,6 +819,7 @@ export class MaskEditorDialogOld extends ComfyDialog {
brush.style.top = centerY - self.brush_size * this.zoom_ratio + 'px'
}
// @ts-expect-error fixme ts strict error
handleWheelEvent(_, event) {
event.preventDefault()
@@ -785,6 +843,7 @@ export class MaskEditorDialogOld extends ComfyDialog {
}
}
// @ts-expect-error fixme ts strict error
pointMoveEvent(self, event) {
this.cursorX = event.pageX
this.cursorY = event.pageY
@@ -814,10 +873,12 @@ export class MaskEditorDialogOld extends ComfyDialog {
}
}
// @ts-expect-error fixme ts strict error
pan_move(self, event) {
if (event.buttons == 1) {
if (MaskEditorDialogOld.mousedown_x) {
let deltaX = MaskEditorDialogOld.mousedown_x - event.clientX
// @ts-expect-error fixme ts strict error
let deltaY = MaskEditorDialogOld.mousedown_y - event.clientY
self.pan_x = this.mousedown_pan_x - deltaX
@@ -828,6 +889,7 @@ export class MaskEditorDialogOld extends ComfyDialog {
}
}
// @ts-expect-error fixme ts strict error
draw_move(self, event) {
if (event.ctrlKey || event.shiftKey) {
return
@@ -922,6 +984,7 @@ export class MaskEditorDialogOld extends ComfyDialog {
} else if (
window.TouchEvent &&
event instanceof TouchEvent &&
// @ts-expect-error fixme ts strict error
diff < 20
) {
brush_size *= this.last_pressure
@@ -929,6 +992,7 @@ export class MaskEditorDialogOld extends ComfyDialog {
brush_size = this.brush_size
}
// @ts-expect-error fixme ts strict error
if (diff > 20 && !this.drawing_mode)
// cannot tracking drawing_mode for touch event
requestAnimationFrame(() => {
@@ -961,6 +1025,7 @@ export class MaskEditorDialogOld extends ComfyDialog {
}
}
// @ts-expect-error fixme ts strict error
handlePointerDown(self, event) {
if (event.ctrlKey) {
if (event.buttons == 1) {
@@ -1010,6 +1075,7 @@ export class MaskEditorDialogOld extends ComfyDialog {
}
}
// @ts-expect-error fixme ts strict error
init_shape(self, compositionOperation) {
self.maskCtx.beginPath()
if (compositionOperation == CompositionOperation.SourceOver) {
@@ -1021,6 +1087,7 @@ export class MaskEditorDialogOld extends ComfyDialog {
}
}
// @ts-expect-error fixme ts strict error
draw_shape(self, x, y, brush_size) {
if (self.pointer_type === PointerType.Rect) {
self.maskCtx.rect(
@@ -1043,7 +1110,9 @@ export class MaskEditorDialogOld extends ComfyDialog {
backupCanvas.width = this.image.width
backupCanvas.height = this.image.height
// @ts-expect-error fixme ts strict error
backupCtx.clearRect(0, 0, backupCanvas.width, backupCanvas.height)
// @ts-expect-error fixme ts strict error
backupCtx.drawImage(
this.maskCanvas,
0,
@@ -1057,6 +1126,7 @@ export class MaskEditorDialogOld extends ComfyDialog {
)
// paste mask data into alpha channel
// @ts-expect-error fixme ts strict error
const backupData = backupCtx.getImageData(
0,
0,
@@ -1074,7 +1144,9 @@ export class MaskEditorDialogOld extends ComfyDialog {
backupData.data[i + 2] = 0
}
// @ts-expect-error fixme ts strict error
backupCtx.globalCompositeOperation = CompositionOperation.SourceOver
// @ts-expect-error fixme ts strict error
backupCtx.putImageData(backupData, 0, 0)
const formData = new FormData()
@@ -1086,13 +1158,17 @@ export class MaskEditorDialogOld extends ComfyDialog {
type: 'input'
}
// @ts-expect-error fixme ts strict error
if (ComfyApp.clipspace.images) ComfyApp.clipspace.images[0] = item
// @ts-expect-error fixme ts strict error
if (ComfyApp.clipspace.widgets) {
// @ts-expect-error fixme ts strict error
const index = ComfyApp.clipspace.widgets.findIndex(
(obj) => obj.name === 'image'
)
// @ts-expect-error fixme ts strict error
if (index >= 0) ComfyApp.clipspace.widgets[index].value = item
}
@@ -1104,6 +1180,7 @@ export class MaskEditorDialogOld extends ComfyDialog {
type Ref = { filename: string; subfolder?: string; type?: string }
const original_ref: Ref = {
// @ts-expect-error fixme ts strict error
filename: original_url.searchParams.get('filename')
}

View File

@@ -1,4 +1,3 @@
// @ts-strict-ignore
import { LGraphCanvas } from '@comfyorg/litegraph'
import { t } from '@/i18n'
@@ -32,6 +31,7 @@ const id = 'Comfy.NodeTemplates'
const file = 'comfy.templates.json'
class ManageTemplates extends ComfyDialog {
// @ts-expect-error fixme ts strict error
templates: any[]
draggedEl: HTMLElement | null
saveVisualCue: number | null
@@ -65,6 +65,7 @@ class ManageTemplates extends ComfyDialog {
const btns = super.createButtons()
btns[0].textContent = 'Close'
btns[0].onclick = () => {
// @ts-expect-error fixme ts strict error
clearTimeout(this.saveVisualCue)
this.close()
}
@@ -106,11 +107,13 @@ class ManageTemplates extends ComfyDialog {
await api.storeUserData(file, templates, { stringify: false })
} catch (error) {
console.error(error)
// @ts-expect-error fixme ts strict error
useToastStore().addAlert(error.message)
}
}
async importAll() {
// @ts-expect-error fixme ts strict error
for (const file of this.importInput.files) {
if (file.type === 'application/json' || file.name.endsWith('.json')) {
const reader = new FileReader()
@@ -129,6 +132,7 @@ class ManageTemplates extends ComfyDialog {
}
}
// @ts-expect-error fixme ts strict error
this.importInput.value = null
this.close()
@@ -163,6 +167,7 @@ class ManageTemplates extends ComfyDialog {
'div',
{},
this.templates.flatMap((t, i) => {
// @ts-expect-error fixme ts strict error
let nameInput
return [
$el(
@@ -177,6 +182,7 @@ class ManageTemplates extends ComfyDialog {
gap: '5px',
backgroundColor: 'var(--comfy-menu-bg)'
},
// @ts-expect-error fixme ts strict error
ondragstart: (e) => {
this.draggedEl = e.currentTarget
e.currentTarget.style.opacity = '0.6'
@@ -184,6 +190,7 @@ class ManageTemplates extends ComfyDialog {
e.dataTransfer.effectAllowed = 'move'
e.dataTransfer.setDragImage(this.emptyImg, 0, 0)
},
// @ts-expect-error fixme ts strict error
ondragend: (e) => {
e.target.style.opacity = '1'
e.currentTarget.style.border = '1px dashed transparent'
@@ -192,7 +199,9 @@ class ManageTemplates extends ComfyDialog {
// rearrange the elements
this.element
.querySelectorAll('.templateManagerRow')
// @ts-expect-error fixme ts strict error
.forEach((el: HTMLElement, i) => {
// @ts-expect-error fixme ts strict error
var prev_i = Number.parseInt(el.dataset.id)
if (el == this.draggedEl && prev_i != i) {
@@ -206,6 +215,7 @@ class ManageTemplates extends ComfyDialog {
})
this.store()
},
// @ts-expect-error fixme ts strict error
ondragover: (e) => {
e.preventDefault()
if (e.currentTarget == this.draggedEl) return
@@ -232,6 +242,7 @@ class ManageTemplates extends ComfyDialog {
style: {
cursor: 'grab'
},
// @ts-expect-error fixme ts strict error
onmousedown: (e) => {
// enable dragging only from the label
if (e.target.localName == 'label')
@@ -246,7 +257,9 @@ class ManageTemplates extends ComfyDialog {
transitionProperty: 'background-color',
transitionDuration: '0s'
},
// @ts-expect-error fixme ts strict error
onchange: (e) => {
// @ts-expect-error fixme ts strict error
clearTimeout(this.saveVisualCue)
var el = e.target
var row = el.parentNode.parentNode
@@ -262,8 +275,10 @@ class ManageTemplates extends ComfyDialog {
el.style.backgroundColor = 'var(--comfy-input-bg)'
}, 15)
},
// @ts-expect-error fixme ts strict error
onkeypress: (e) => {
var el = e.target
// @ts-expect-error fixme ts strict error
clearTimeout(this.saveVisualCue)
el.style.transitionDuration = '0s'
el.style.backgroundColor = 'var(--comfy-input-bg)'
@@ -287,6 +302,7 @@ class ManageTemplates extends ComfyDialog {
const url = URL.createObjectURL(blob)
const a = $el('a', {
href: url,
// @ts-expect-error fixme ts strict error
download: (nameInput.value || t.name) + '.json',
style: { display: 'none' },
parent: document.body
@@ -305,6 +321,7 @@ class ManageTemplates extends ComfyDialog {
color: 'red',
fontWeight: 'normal'
},
// @ts-expect-error fixme ts strict error
onclick: (e) => {
const item = e.target.parentNode.parentNode
item.parentNode.removeChild(item)
@@ -315,6 +332,7 @@ class ManageTemplates extends ComfyDialog {
setTimeout(function () {
that.element
.querySelectorAll('.templateManagerRow')
// @ts-expect-error fixme ts strict error
.forEach((el: HTMLElement, i) => {
el.dataset.id = i.toString()
})
@@ -336,22 +354,27 @@ app.registerExtension({
setup() {
const manage = new ManageTemplates()
// @ts-expect-error fixme ts strict error
const clipboardAction = async (cb) => {
// We use the clipboard functions but dont want to overwrite the current user clipboard
// Restore it after we've run our callback
const old = localStorage.getItem('litegrapheditor_clipboard')
await cb()
// @ts-expect-error fixme ts strict error
localStorage.setItem('litegrapheditor_clipboard', old)
}
const orig = LGraphCanvas.prototype.getCanvasMenuOptions
LGraphCanvas.prototype.getCanvasMenuOptions = function () {
// @ts-expect-error fixme ts strict error
const options = orig.apply(this, arguments)
// @ts-expect-error fixme ts strict error
options.push(null)
options.push({
content: `Save Selected as Template`,
disabled: !Object.keys(app.canvas.selected_nodes || {}).length,
// @ts-expect-error fixme ts strict error
callback: async () => {
const name = await useDialogService().prompt({
title: t('nodeTemplates.saveAsTemplate'),
@@ -363,6 +386,7 @@ app.registerExtension({
clipboardAction(() => {
app.canvas.copyToClipboard()
let data = localStorage.getItem('litegrapheditor_clipboard')
// @ts-expect-error fixme ts strict error
data = JSON.parse(data)
const nodeIds = Object.keys(app.canvas.selected_nodes)
for (let i = 0; i < nodeIds.length; i++) {
@@ -414,6 +438,7 @@ app.registerExtension({
}
})
// @ts-expect-error fixme ts strict error
subItems.push(null, {
content: 'Manage',
callback: () => manage.show()

View File

@@ -1,4 +1,3 @@
// @ts-strict-ignore
import { LGraphCanvas, LiteGraph } from '@comfyorg/litegraph'
import { LGraphNode } from '@comfyorg/litegraph'
@@ -21,6 +20,7 @@ app.registerExtension({
isVirtualNode: boolean
constructor(title?: string) {
// @ts-expect-error fixme ts strict error
super(title)
if (!this.properties) {
this.properties = { text: '' }
@@ -59,6 +59,7 @@ app.registerExtension({
groupcolor = LGraphCanvas.node_colors.yellow.groupcolor
constructor(title?: string) {
// @ts-expect-error fixme ts strict error
super(title)
if (!this.properties) {
this.properties = { text: '' }

View File

@@ -1,4 +1,3 @@
// @ts-strict-ignore
import type { IContextMenuValue } from '@comfyorg/litegraph'
import { LGraphCanvas, LGraphNode, LiteGraph } from '@comfyorg/litegraph'
@@ -19,6 +18,7 @@ app.registerExtension({
static defaultVisibility = false
constructor(title?: string) {
// @ts-expect-error fixme ts strict error
super(title)
if (!this.properties) {
this.properties = {}
@@ -31,6 +31,7 @@ app.registerExtension({
this.onAfterGraphConfigured = function () {
requestAnimationFrame(() => {
// @ts-expect-error fixme ts strict error
this.onConnectionsChange(LiteGraph.INPUT, null, true, null)
})
}
@@ -42,19 +43,23 @@ app.registerExtension({
if (connected && type === LiteGraph.OUTPUT) {
// Ignore wildcard nodes as these will be updated to real types
const types = new Set(
// @ts-expect-error fixme ts strict error
this.outputs[0].links
.map((l) => app.graph.links[l].type)
.filter((t) => t !== '*')
)
if (types.size > 1) {
const linksToDisconnect = []
// @ts-expect-error fixme ts strict error
for (let i = 0; i < this.outputs[0].links.length - 1; i++) {
// @ts-expect-error fixme ts strict error
const linkId = this.outputs[0].links[i]
const link = app.graph.links[linkId]
linksToDisconnect.push(link)
}
for (const link of linksToDisconnect) {
const node = app.graph.getNodeById(link.target_id)
// @ts-expect-error fixme ts strict error
node.disconnectInput(link.target_slot)
}
}
@@ -72,6 +77,7 @@ app.registerExtension({
const link = app.graph.links[linkId]
if (!link) return
const node = app.graph.getNodeById(link.origin_id)
// @ts-expect-error fixme ts strict error
const type = node.constructor.type
if (type === 'Reroute') {
if (node === this) {
@@ -85,6 +91,7 @@ app.registerExtension({
} else {
// We've found the end
inputNode = currentNode
// @ts-expect-error fixme ts strict error
inputType = node.outputs[link.origin_slot]?.type ?? null
break
}
@@ -99,8 +106,10 @@ app.registerExtension({
const nodes: LGraphNode[] = [this]
let outputType = null
while (nodes.length) {
// @ts-expect-error fixme ts strict error
currentNode = nodes.pop()
const outputs =
// @ts-expect-error fixme ts strict error
(currentNode.outputs ? currentNode.outputs[0].links : []) || []
if (outputs.length) {
for (const linkId of outputs) {
@@ -110,25 +119,33 @@ app.registerExtension({
if (!link) continue
const node = app.graph.getNodeById(link.target_id)
// @ts-expect-error fixme ts strict error
const type = node.constructor.type
if (type === 'Reroute') {
// Follow reroute nodes
// @ts-expect-error fixme ts strict error
nodes.push(node)
updateNodes.push(node)
} else {
// We've found an output
const nodeOutType =
// @ts-expect-error fixme ts strict error
node.inputs &&
// @ts-expect-error fixme ts strict error
node.inputs[link?.target_slot] &&
// @ts-expect-error fixme ts strict error
node.inputs[link.target_slot].type
? node.inputs[link.target_slot].type
? // @ts-expect-error fixme ts strict error
node.inputs[link.target_slot].type
: null
if (
inputType &&
// @ts-expect-error fixme ts strict error
!LiteGraph.isValidConnection(inputType, nodeOutType)
) {
// The output doesnt match our input so disconnect it
// @ts-expect-error fixme ts strict error
node.disconnectInput(link.target_slot)
} else {
outputType = nodeOutType
@@ -149,13 +166,18 @@ app.registerExtension({
for (const node of updateNodes) {
// If we dont have an input type we are always wildcard but we'll show the output type
// This lets you change the output link to a different type and all nodes will update
// @ts-expect-error fixme ts strict error
node.outputs[0].type = inputType || '*'
// @ts-expect-error fixme ts strict error
node.__outputType = displayType
// @ts-expect-error fixme ts strict error
node.outputs[0].name = node.properties.showOutputText
? displayType
: ''
// @ts-expect-error fixme ts strict error
node.setSize(node.computeSize())
// @ts-expect-error fixme ts strict error
for (const l of node.outputs[0].links || []) {
const link = app.graph.links[l]
if (link) {
@@ -163,6 +185,7 @@ app.registerExtension({
if (app.configuringGraph) continue
const targetNode = app.graph.getNodeById(link.target_id)
// @ts-expect-error fixme ts strict error
const targetInput = targetNode.inputs?.[link.target_slot]
if (targetInput?.widget) {
const config = getWidgetConfig(targetInput)
@@ -185,17 +208,21 @@ app.registerExtension({
for (const node of updateNodes) {
if (widgetConfig && outputType) {
// @ts-expect-error fixme ts strict error
node.inputs[0].widget = { name: 'value' }
// @ts-expect-error fixme ts strict error
setWidgetConfig(node.inputs[0], [
widgetType ?? displayType,
widgetConfig
])
} else {
// @ts-expect-error fixme ts strict error
setWidgetConfig(node.inputs[0], null)
}
}
if (inputNode) {
// @ts-expect-error fixme ts strict error
const link = app.graph.links[inputNode.inputs[0].link]
if (link) {
link.color = color
@@ -205,8 +232,11 @@ app.registerExtension({
this.clone = function () {
const cloned = RerouteNode.prototype.clone.apply(this)
// @ts-expect-error fixme ts strict error
cloned.removeOutput(0)
// @ts-expect-error fixme ts strict error
cloned.addOutput(this.properties.showOutputText ? '*' : '', '*')
// @ts-expect-error fixme ts strict error
cloned.setSize(cloned.computeSize())
return cloned
}
@@ -215,6 +245,7 @@ app.registerExtension({
this.isVirtualNode = true
}
// @ts-expect-error fixme ts strict error
getExtraMenuOptions(_, options): IContextMenuValue[] {
options.unshift(
{
@@ -258,6 +289,7 @@ app.registerExtension({
]
}
// @ts-expect-error fixme ts strict error
static setDefaultTextVisibility(visible) {
RerouteNode.defaultVisibility = visible
if (visible) {

View File

@@ -1,4 +1,3 @@
// @ts-strict-ignore
import { applyTextReplacements } from '@/utils/searchAndReplace'
import { app } from '../../scripts/app'
@@ -17,11 +16,15 @@ app.registerExtension({
// When the SaveImage node is created we want to override the serialization of the output name widget to run our S&R
nodeType.prototype.onNodeCreated = function () {
const r = onNodeCreated
? onNodeCreated.apply(this, arguments)
? // @ts-expect-error fixme ts strict error
onNodeCreated.apply(this, arguments)
: undefined
// @ts-expect-error fixme ts strict error
const widget = this.widgets.find((w) => w.name === 'filename_prefix')
// @ts-expect-error fixme ts strict error
widget.serializeValue = () => {
// @ts-expect-error fixme ts strict error
return applyTextReplacements(app.graph.nodes, widget.value)
}
@@ -32,7 +35,8 @@ app.registerExtension({
const onNodeCreated = nodeType.prototype.onNodeCreated
nodeType.prototype.onNodeCreated = function () {
const r = onNodeCreated
? onNodeCreated.apply(this, arguments)
? // @ts-expect-error fixme ts strict error
onNodeCreated.apply(this, arguments)
: undefined
if (!this.properties || !('Node name for S&R' in this.properties)) {

View File

@@ -1,18 +1,23 @@
// @ts-strict-ignore
import { LGraphCanvas, LiteGraph } from '@comfyorg/litegraph'
import { app } from '../../scripts/app'
// @ts-expect-error fixme ts strict error
let touchZooming
let touchCount = 0
app.registerExtension({
name: 'Comfy.SimpleTouchSupport',
setup() {
// @ts-expect-error fixme ts strict error
let touchDist
// @ts-expect-error fixme ts strict error
let touchTime
// @ts-expect-error fixme ts strict error
let lastTouch
// @ts-expect-error fixme ts strict error
let lastScale
// @ts-expect-error fixme ts strict error
function getMultiTouchPos(e) {
return Math.hypot(
e.touches[0].clientX - e.touches[1].clientX,
@@ -20,6 +25,7 @@ app.registerExtension({
)
}
// @ts-expect-error fixme ts strict error
function getMultiTouchCenter(e) {
return {
clientX: (e.touches[0].clientX + e.touches[1].clientX) / 2,
@@ -27,6 +33,7 @@ app.registerExtension({
}
}
// @ts-expect-error fixme ts strict error
app.canvasEl.parentElement.addEventListener(
'touchstart',
(e: TouchEvent) => {
@@ -52,10 +59,12 @@ app.registerExtension({
true
)
// @ts-expect-error fixme ts strict error
app.canvasEl.parentElement.addEventListener('touchend', (e: TouchEvent) => {
touchCount--
if (e.touches?.length !== 1) touchZooming = false
// @ts-expect-error fixme ts strict error
if (touchTime && !e.touches?.length) {
if (new Date().getTime() - touchTime > 600) {
if (e.target === app.canvasEl) {
@@ -73,10 +82,12 @@ app.registerExtension({
}
})
// @ts-expect-error fixme ts strict error
app.canvasEl.parentElement.addEventListener(
'touchmove',
(e) => {
touchTime = null
// @ts-expect-error fixme ts strict error
if (e.touches?.length === 2 && lastTouch && !e.ctrlKey && !e.shiftKey) {
e.preventDefault() // Prevent browser from zooming when two textareas are touched
app.canvas.pointer.isDown = false
@@ -89,6 +100,7 @@ app.registerExtension({
const center = getMultiTouchCenter(e)
// @ts-expect-error fixme ts strict error
let scale = (lastScale * newTouchDist) / touchDist
const newX = (center.clientX - lastTouch.clientX) / scale
@@ -112,6 +124,7 @@ app.registerExtension({
const newScale = app.canvas.ds.scale
// @ts-expect-error fixme ts strict error
const convertScaleToOffset = (scale) => [
center.clientX / scale - app.canvas.ds.offset[0],
center.clientY / scale - app.canvas.ds.offset[1]
@@ -135,17 +148,21 @@ app.registerExtension({
const processMouseDown = LGraphCanvas.prototype.processMouseDown
LGraphCanvas.prototype.processMouseDown = function () {
// @ts-expect-error fixme ts strict error
if (touchZooming || touchCount) {
return
}
app.canvas.pointer.isDown = false // Prevent context menu from opening on second tap
// @ts-expect-error fixme ts strict error
return processMouseDown.apply(this, arguments)
}
const processMouseMove = LGraphCanvas.prototype.processMouseMove
LGraphCanvas.prototype.processMouseMove = function () {
// @ts-expect-error fixme ts strict error
if (touchZooming || touchCount > 1) {
return
}
// @ts-expect-error fixme ts strict error
return processMouseMove.apply(this, arguments)
}

View File

@@ -1,4 +1,3 @@
// @ts-strict-ignore
import type { IWidget, LGraphNode } from '@comfyorg/litegraph'
import type { IStringWidget } from '@comfyorg/litegraph/dist/types/widgets'
@@ -64,7 +63,9 @@ async function uploadFile(
let path = data.name
if (data.subfolder) path = data.subfolder + '/' + path
// @ts-expect-error fixme ts strict error
if (!audioWidget.options.values.includes(path)) {
// @ts-expect-error fixme ts strict error
audioWidget.options.values.push(path)
}
@@ -78,6 +79,7 @@ async function uploadFile(
useToastStore().addAlert(resp.status + ' - ' + resp.statusText)
}
} catch (error) {
// @ts-expect-error fixme ts strict error
useToastStore().addAlert(error)
}
}
@@ -89,9 +91,11 @@ app.registerExtension({
async beforeRegisterNodeDef(nodeType, nodeData) {
if (
['LoadAudio', 'SaveAudio', 'PreviewAudio'].includes(
// @ts-expect-error fixme ts strict error
nodeType.prototype.comfyClass
)
) {
// @ts-expect-error fixme ts strict error
nodeData.input.required.audioUI = ['AUDIO_UI', {}]
}
},
@@ -115,6 +119,7 @@ app.registerExtension({
// Populate the audio widget UI on node execution.
const onExecuted = node.onExecuted
node.onExecuted = function (message: any) {
// @ts-expect-error fixme ts strict error
onExecuted?.apply(this, arguments)
const audios = message.audio
if (!audios) return
@@ -133,6 +138,7 @@ app.registerExtension({
for (const [nodeId, output] of Object.entries(nodeOutputs)) {
const node = app.graph.getNodeById(nodeId)
if ('audio' in output) {
// @ts-expect-error fixme ts strict error
const audioUIWidget = node.widgets.find(
(w) => w.name === 'audioUI'
) as unknown as DOMWidget<HTMLAudioElement, string>
@@ -157,9 +163,11 @@ app.registerExtension({
return {
AUDIOUPLOAD(node, inputName: string) {
// The widget that allows user to select file.
// @ts-expect-error fixme ts strict error
const audioWidget = node.widgets.find(
(w: IWidget) => w.name === 'audio'
) as IStringWidget
// @ts-expect-error fixme ts strict error
const audioUIWidget = node.widgets.find(
(w: IWidget) => w.name === 'audioUI'
) as unknown as DOMWidget<HTMLAudioElement, string>
@@ -178,6 +186,7 @@ app.registerExtension({
// Load saved audio file widget values if restoring from workflow
const onGraphConfigured = node.onGraphConfigured
node.onGraphConfigured = function () {
// @ts-expect-error fixme ts strict error
onGraphConfigured?.apply(this, arguments)
if (audioWidget.value) {
onAudioWidgetUpdate()

View File

@@ -1,4 +1,3 @@
// @ts-strict-ignore
import { t } from '@/i18n'
import { useToastStore } from '@/stores/toastStore'
@@ -12,7 +11,9 @@ app.registerExtension({
getCustomWidgets() {
return {
WEBCAM(node, inputName) {
// @ts-expect-error fixme ts strict error
let res
// @ts-expect-error fixme ts strict error
node[WEBCAM_READY] = new Promise((resolve) => (res = resolve))
const container = document.createElement('div')
@@ -30,7 +31,9 @@ app.registerExtension({
})
container.replaceChildren(video)
// @ts-expect-error fixme ts strict error
setTimeout(() => res(video), 500) // Fallback as loadedmetadata doesnt fire sometimes?
// @ts-expect-error fixme ts strict error
video.addEventListener('loadedmetadata', () => res(video), false)
video.srcObject = stream
video.play()
@@ -44,10 +47,12 @@ app.registerExtension({
if (window.isSecureContext) {
label.textContent =
'Unable to load webcam, please ensure access is granted:\n' +
// @ts-expect-error fixme ts strict error
error.message
} else {
label.textContent =
'Unable to load webcam. A secure context is required, if you are not accessing ComfyUI on localhost (127.0.0.1) you will have to enable TLS (https)\n\n' +
// @ts-expect-error fixme ts strict error
error.message
}
@@ -64,10 +69,15 @@ app.registerExtension({
nodeCreated(node) {
if ((node.type, node.constructor.comfyClass !== 'WebcamCapture')) return
// @ts-expect-error fixme ts strict error
let video
// @ts-expect-error fixme ts strict error
const camera = node.widgets.find((w) => w.name === 'image')
// @ts-expect-error fixme ts strict error
const w = node.widgets.find((w) => w.name === 'width')
// @ts-expect-error fixme ts strict error
const h = node.widgets.find((w) => w.name === 'height')
// @ts-expect-error fixme ts strict error
const captureOnQueue = node.widgets.find(
(w) => w.name === 'capture_on_queue'
)
@@ -101,7 +111,9 @@ app.registerExtension({
btn.disabled = true
btn.serializeValue = () => undefined
// @ts-expect-error fixme ts strict error
camera.serializeValue = async () => {
// @ts-expect-error fixme ts strict error
if (captureOnQueue.value) {
capture()
} else if (!node.imgs?.length) {
@@ -111,6 +123,7 @@ app.registerExtension({
}
// Upload image to temp storage
// @ts-expect-error fixme ts strict error
const blob = await new Promise<Blob>((r) => canvas.toBlob(r))
const name = `${+new Date()}.png`
const file = new File([blob], name)
@@ -130,11 +143,15 @@ app.registerExtension({
return `webcam/${name} [temp]`
}
// @ts-expect-error fixme ts strict error
node[WEBCAM_READY].then((v) => {
video = v
// If width isnt specified then use video output resolution
// @ts-expect-error fixme ts strict error
if (!w.value) {
// @ts-expect-error fixme ts strict error
w.value = video.videoWidth || 640
// @ts-expect-error fixme ts strict error
h.value = video.videoHeight || 480
}
btn.disabled = false

View File

@@ -1,4 +1,3 @@
// @ts-strict-ignore
import { LGraphNode, LiteGraph } from '@comfyorg/litegraph'
import type {
IFoundSlot,
@@ -35,10 +34,13 @@ const GET_CONFIG = Symbol()
const replacePropertyName = 'Run widget replace on values'
export class PrimitiveNode extends LGraphNode {
// @ts-expect-error fixme ts strict error
controlValues: any[]
// @ts-expect-error fixme ts strict error
lastType: string
static category: string
constructor(title?: string) {
// @ts-expect-error fixme ts strict error
super(title)
this.addOutput('connect to widget input', '*')
this.serialize_widgets = true
@@ -63,11 +65,14 @@ export class PrimitiveNode extends LGraphNode {
// For each output link copy our value over the original widget value
for (const linkInfo of links) {
// @ts-expect-error fixme ts strict error
const node = this.graph.getNodeById(linkInfo.target_id)
// @ts-expect-error fixme ts strict error
const input = node.inputs[linkInfo.target_slot]
let widget: IWidget | undefined
const widgetName = (input.widget as { name: string }).name
if (widgetName) {
// @ts-expect-error fixme ts strict error
widget = node.widgets.find((w) => w.name === widgetName)
}
@@ -77,6 +82,7 @@ export class PrimitiveNode extends LGraphNode {
widget.callback(
widget.value,
app.canvas,
// @ts-expect-error fixme ts strict error
node,
app.canvas.graph_mouse,
{} as CanvasMouseEvent
@@ -91,7 +97,9 @@ export class PrimitiveNode extends LGraphNode {
if (widget?.type === 'combo') {
widget.options.values = this.outputs[0].widget[GET_CONFIG]()[0]
// @ts-expect-error fixme ts strict error
if (!widget.options.values.includes(widget.value as string)) {
// @ts-expect-error fixme ts strict error
widget.value = widget.options.values[0]
;(widget.callback as Function)(widget.value)
}
@@ -106,6 +114,7 @@ export class PrimitiveNode extends LGraphNode {
// Populate widget values from config data
if (this.widgets) {
// @ts-expect-error fixme ts strict error
for (let i = 0; i < this.widgets_values.length; i++) {
const w = this.widgets[i]
if (w) {
@@ -141,6 +150,7 @@ export class PrimitiveNode extends LGraphNode {
}
}
// @ts-expect-error fixme ts strict error
onConnectOutput(
slot: number,
_type: string,
@@ -171,9 +181,11 @@ export class PrimitiveNode extends LGraphNode {
return
}
const linkId = this.outputs[0].links[0]
// @ts-expect-error fixme ts strict error
const link = this.graph.links[linkId]
if (!link) return
// @ts-expect-error fixme ts strict error
const theirNode = this.graph.getNodeById(link.target_id)
if (!theirNode || !theirNode.inputs) return
@@ -188,6 +200,7 @@ export class PrimitiveNode extends LGraphNode {
widget = input.widget
}
// @ts-expect-error fixme ts strict error
const config = widget[GET_CONFIG]?.()
if (!config) return
@@ -198,9 +211,11 @@ export class PrimitiveNode extends LGraphNode {
this.outputs[0].widget = widget
this.#createWidget(
// @ts-expect-error fixme ts strict error
widget[CONFIG] ?? config,
theirNode,
widget.name,
// @ts-expect-error fixme ts strict error
recreating
)
}
@@ -221,6 +236,7 @@ export class PrimitiveNode extends LGraphNode {
const [oldWidth, oldHeight] = this.size
let widget: IWidget | undefined
if (type in ComfyWidgets) {
// @ts-expect-error fixme ts strict error
widget = (ComfyWidgets[type](this, 'value', inputData, app) || {}).widget
} else {
// @ts-expect-error InputSpec is not typed correctly
@@ -243,6 +259,7 @@ export class PrimitiveNode extends LGraphNode {
control_value = 'fixed'
}
addValueControlWidgets(
// @ts-expect-error fixme ts strict error
this,
widget,
control_value as string,
@@ -250,6 +267,7 @@ export class PrimitiveNode extends LGraphNode {
inputData
)
let filter = this.widgets_values?.[2]
// @ts-expect-error fixme ts strict error
if (filter && this.widgets.length === 3) {
// @ts-expect-error change widget type from string to unknown
this.widgets[2].value = filter
@@ -259,10 +277,13 @@ export class PrimitiveNode extends LGraphNode {
// Restore any saved control values
const controlValues = this.controlValues
if (
// @ts-expect-error fixme ts strict error
this.lastType === this.widgets[0].type &&
// @ts-expect-error fixme ts strict error
controlValues?.length === this.widgets.length - 1
) {
for (let i = 0; i < controlValues.length; i++) {
// @ts-expect-error fixme ts strict error
this.widgets[i + 1].value = controlValues[i]
}
}
@@ -272,6 +293,7 @@ export class PrimitiveNode extends LGraphNode {
const callback = widget.callback
const self = this
widget.callback = function () {
// @ts-expect-error fixme ts strict error
const r = callback ? callback.apply(this, arguments) : undefined
self.applyToGraph()
return r
@@ -295,6 +317,7 @@ export class PrimitiveNode extends LGraphNode {
requestAnimationFrame(() => {
if (this.onResize) {
// @ts-expect-error fixme ts strict error
this.onResize(this.size)
}
})
@@ -306,7 +329,9 @@ export class PrimitiveNode extends LGraphNode {
this.#removeWidgets()
this.#onFirstConnection(true)
if (values?.length) {
// @ts-expect-error fixme ts strict error
for (let i = 0; i < this.widgets?.length; i++)
// @ts-expect-error fixme ts strict error
this.widgets[i].value = values[i]
}
return this.widgets?.[0]
@@ -322,8 +347,10 @@ export class PrimitiveNode extends LGraphNode {
delete output.widget[CONFIG]
}
// @ts-expect-error fixme ts strict error
if (links?.length < 2 && hasConfig) {
// Copy the widget options from the source
// @ts-expect-error fixme ts strict error
if (links.length) {
this.recreateWidget()
}
@@ -335,11 +362,13 @@ export class PrimitiveNode extends LGraphNode {
const isNumber = config1[0] === 'INT' || config1[0] === 'FLOAT'
if (!isNumber) return
// @ts-expect-error fixme ts strict error
for (const linkId of links) {
const link = app.graph.links[linkId]
if (!link) continue // Can be null when removing a node
const theirNode = app.graph.getNodeById(link.target_id)
// @ts-expect-error fixme ts strict error
const theirInput = theirNode.inputs[link.target_slot]
// Call is valid connection so it can merge the configs when validating
@@ -370,6 +399,7 @@ export class PrimitiveNode extends LGraphNode {
#isValidConnection(input: INodeInputSlot, forceUpdate?: boolean) {
// Only allow connections where the configs match
const output = this.outputs[0]
// @ts-expect-error fixme ts strict error
const config2 = input.widget[GET_CONFIG]()
return !!mergeIfValid.call(
this,
@@ -397,7 +427,9 @@ export class PrimitiveNode extends LGraphNode {
this.controlValues.push(this.widgets[i].value)
}
setTimeout(() => {
// @ts-expect-error fixme ts strict error
delete this.lastType
// @ts-expect-error fixme ts strict error
delete this.controlValues
}, 15)
this.widgets.length = 0
@@ -420,6 +452,7 @@ export function getWidgetConfig(slot: INodeInputSlot | INodeOutputSlot) {
}
function getConfig(widgetName: string) {
// @ts-expect-error fixme ts strict error
const { nodeData } = this.constructor
return (
nodeData?.input?.required?.[widgetName] ??
@@ -513,7 +546,9 @@ export function convertToInput(
...(inputIsOptional ? { shape: LiteGraph.SlotShape.HollowCircle } : {})
})
// @ts-expect-error fixme ts strict error
for (const widget of node.widgets) {
// @ts-expect-error fixme ts strict error
widget.last_y += LiteGraph.NODE_SLOT_HEIGHT
}
@@ -530,7 +565,9 @@ function convertToWidget(node: LGraphNode, widget: IWidget) {
const [oldWidth, oldHeight] = node.size
node.removeInput(node.inputs.findIndex((i) => i.widget?.name === widget.name))
// @ts-expect-error fixme ts strict error
for (const widget of node.widgets) {
// @ts-expect-error fixme ts strict error
widget.last_y -= LiteGraph.NODE_SLOT_HEIGHT
}
@@ -562,9 +599,11 @@ export function setWidgetConfig(
}
if ('link' in slot) {
// @ts-expect-error fixme ts strict error
const link = app.graph.links[slot.link]
if (link) {
const originNode = app.graph.getNodeById(link.origin_id)
// @ts-expect-error fixme ts strict error
if (isPrimitiveNode(originNode)) {
if (config) {
originNode.recreateWidget()
@@ -588,6 +627,7 @@ export function mergeIfValid(
config1 = getWidgetConfig(output)
}
// @ts-expect-error fixme ts strict error
const customSpec = mergeInputSpec(config1, config2)
if (customSpec || forceUpdate) {
@@ -595,17 +635,24 @@ export function mergeIfValid(
output.widget[CONFIG] = customSpec
}
// @ts-expect-error fixme ts strict error
const widget = recreateWidget?.call(this)
// When deleting a node this can be null
if (widget) {
// @ts-expect-error fixme ts strict error
const min = widget.options.min
// @ts-expect-error fixme ts strict error
const max = widget.options.max
// @ts-expect-error fixme ts strict error
if (min != null && widget.value < min) widget.value = min
// @ts-expect-error fixme ts strict error
if (max != null && widget.value > max) widget.value = max
// @ts-expect-error fixme ts strict error
widget.callback(widget.value)
}
}
// @ts-expect-error fixme ts strict error
return { customConfig: customSpec[1] }
}
@@ -622,6 +669,7 @@ app.registerExtension({
setup() {
app.canvas.getWidgetLinkType = function (widget, node) {
const nodeDefStore = useNodeDefStore()
// @ts-expect-error fixme ts strict error
const nodeDef = nodeDefStore.nodeDefsByName[node.type]
const input = nodeDef.inputs[widget.name]
return input?.type
@@ -675,6 +723,7 @@ app.registerExtension({
) {
if (!slot.input || !slot.input.widget) return []
// @ts-expect-error fixme ts strict error
const widget = this.widgets.find((w) => w.name === slot.input.widget.name)
if (!widget) return []
return [
@@ -685,13 +734,15 @@ app.registerExtension({
]
}
// @ts-expect-error fixme ts strict error
nodeType.prototype.getExtraMenuOptions = function (
this: LGraphNode,
_,
options
) {
const r = origGetExtraMenuOptions
? origGetExtraMenuOptions.apply(this, arguments)
? // @ts-expect-error fixme ts strict error
origGetExtraMenuOptions.apply(this, arguments)
: undefined
const getPointerCanvasPos = () => {
@@ -700,6 +751,7 @@ app.registerExtension({
}
if (this.widgets) {
// @ts-expect-error fixme ts strict error
const { canvasX, canvasY } = getPointerCanvasPos()
const widget = this.getWidgetOnPos(canvasX, canvasY)
// @ts-expect-error custom widget type
@@ -748,10 +800,12 @@ app.registerExtension({
options.push({
content: 'Convert Widget to Input',
submenu: {
// @ts-expect-error fixme ts strict error
options: toInput
}
})
} else {
// @ts-expect-error fixme ts strict error
options.push(...toInput, null)
}
}
@@ -778,8 +832,11 @@ app.registerExtension({
for (const input of this.inputs) {
if (input.widget) {
// @ts-expect-error fixme ts strict error
if (!input.widget[GET_CONFIG]) {
// @ts-expect-error fixme ts strict error
input.widget[GET_CONFIG] = () =>
// @ts-expect-error fixme ts strict error
getConfig.call(this, input.widget.name)
}
@@ -791,6 +848,7 @@ app.registerExtension({
// If we are an old converted combo then replace the input type and the stored link data
input.type = 'COMBO'
// @ts-expect-error fixme ts strict error
const link = app.graph.links[input.link]
if (link) {
link.type = input.type
@@ -800,6 +858,7 @@ app.registerExtension({
delete input.widget.config
}
// @ts-expect-error fixme ts strict error
const w = this.widgets.find((w) => w.name === input.widget.name)
if (w) {
hideWidget(this, w)
@@ -833,14 +892,19 @@ app.registerExtension({
const origOnConfigure = nodeType.prototype.onConfigure
nodeType.prototype.onConfigure = function (this: LGraphNode) {
const r = origOnConfigure
? origOnConfigure.apply(this, arguments)
? // @ts-expect-error fixme ts strict error
origOnConfigure.apply(this, arguments)
: undefined
if (!app.configuringGraph && this.inputs) {
// On copy + paste of nodes, ensure that widget configs are set up
for (const input of this.inputs) {
// @ts-expect-error fixme ts strict error
if (input.widget && !input.widget[GET_CONFIG]) {
// @ts-expect-error fixme ts strict error
input.widget[GET_CONFIG] = () =>
// @ts-expect-error fixme ts strict error
getConfig.call(this, input.widget.name)
// @ts-expect-error fixme ts strict error
const w = this.widgets.find((w) => w.name === input.widget.name)
if (w) {
hideWidget(this, w)
@@ -868,7 +932,8 @@ app.registerExtension({
slot: number
) {
const r = origOnInputDblClick
? origOnInputDblClick.apply(this, arguments)
? // @ts-expect-error fixme ts strict error
origOnInputDblClick.apply(this, arguments)
: undefined
const input = this.inputs[slot]
@@ -876,6 +941,7 @@ app.registerExtension({
// Not a widget input or already handled input
if (
!(input.type in ComfyWidgets) &&
// @ts-expect-error fixme ts strict error
!(input.widget?.[GET_CONFIG]?.()?.[0] instanceof Array)
) {
return r //also Not a ComfyWidgets input or combo (do nothing)
@@ -884,10 +950,12 @@ app.registerExtension({
// Create a primitive node
const node = LiteGraph.createNode('PrimitiveNode')
// @ts-expect-error fixme ts strict error
app.graph.add(node)
// Calculate a position that wont directly overlap another node
const pos: [number, number] = [
// @ts-expect-error fixme ts strict error
this.pos[0] - node.size[0] - 30,
this.pos[1]
]
@@ -895,8 +963,11 @@ app.registerExtension({
pos[1] += LiteGraph.NODE_TITLE_HEIGHT
}
// @ts-expect-error fixme ts strict error
node.pos = pos
// @ts-expect-error fixme ts strict error
node.connect(0, this, slot)
// @ts-expect-error fixme ts strict error
node.title = input.name
return r
@@ -905,6 +976,7 @@ app.registerExtension({
registerCustomNodes() {
LiteGraph.registerNodeType(
'PrimitiveNode',
// @ts-expect-error fixme ts strict error
Object.assign(PrimitiveNode, {
title: 'Primitive'
})