diff --git a/debugnode.py b/debugnode.py index a0e93f7..1f32b3e 100644 --- a/debugnode.py +++ b/debugnode.py @@ -71,7 +71,7 @@ class WTFDebugNode: info["value"] = str(item) if item is not None else None out.append(info) - return { "ui": { "items": out, "length": [len(anything)] } } + return { "ui": { "items": out } } NODE_CLASS_MAPPINGS = { "WTFDebugNode": WTFDebugNode, diff --git a/js/debugnode.js b/js/debugnode.js index f04a30b..28417d0 100644 --- a/js/debugnode.js +++ b/js/debugnode.js @@ -1,121 +1,118 @@ -import { app } from "../../scripts/app.js"; -import { ComfyWidgets } from "../../scripts/widgets.js"; +import { app } from "../../scripts/app.js" +import { ComfyWidgets } from "../../scripts/widgets.js" const hardLimit = 100 // Does most of the regular textarea cleanup, but leaks a ref in domWidget.js -> elementWidgets until the node is removed function removeWidget(node, widget) { - widget.onRemove?.() - const index = node.widgets.indexOf(widget) - if (index !== -1) - node.widgets.splice(index, 1) + widget.onRemove?.() + const index = node.widgets.indexOf(widget) + if (index !== -1) + node.widgets.splice(index, 1) } function removeAllWidgets(node) { - for (const widget of node.widgets) { - widget.onRemove?.() - } - node.widgets.length = 0 + for (const widget of node.widgets) { + widget.onRemove?.() + } + node.widgets.length = 0 } // Main logic app.registerExtension({ - name: "WTFDebugNode", - async beforeRegisterNodeDef(nodeType, nodeData, app) { - if (nodeData.name === "WTFDebugNode") { - const origOnConnectionsChange = nodeType.prototype.onConnectionsChange - nodeType.prototype.onConnectionsChange = function (type, slotIndex, isConnected, link, ioSlot) { - origOnConnectionsChange?.apply(this, arguments) + name: "WTFDebugNode", + async beforeRegisterNodeDef(nodeType, nodeData, app) { + if (nodeData.name !== "WTFDebugNode") return - if (isConnected && link?.type === "*") - link.type = this.graph.getNodeById(link.origin_id)?.outputs?.[link.origin_slot]?.type - } + // Ensure attached links keep their colours + const origOnConnectionsChange = nodeType.prototype.onConnectionsChange + nodeType.prototype.onConnectionsChange = function (type, slotIndex, isConnected, link, ioSlot) { + origOnConnectionsChange?.apply(this, arguments) - const origOnExecuted = nodeType.prototype.onExecuted; - nodeType.prototype.onExecuted = function (message) { - const r = origOnExecuted - ? origOnExecuted?.apply(this, arguments) - : undefined + if (isConnected && link?.type === "*") + link.type = this.graph.getNodeById(link.origin_id)?.outputs?.[link.origin_slot]?.type + } - // Because debug - console.log(message) + // Show the text in the UI + const origOnExecuted = nodeType.prototype.onExecuted + nodeType.prototype.onExecuted = function (message) { + const r = origOnExecuted + ? origOnExecuted?.apply(this, arguments) + : undefined - // Sanity init - this.widgets ??= [] - this.serialize_widgets = false - const baseOpacity = app.canvas.editor_alpha + // Because debug + console.log(message) - // Clear if invalid - const itemsLength = parseInt(message?.items?.length) - if (isNaN(itemsLength)) { - removeAllWidgets(this) - return r - } + // Sanity init + this.widgets ??= [] + this.serialize_widgets = false + const baseOpacity = app.canvas.editor_alpha - const isMultiItem = itemsLength > 1 - const wasMultiItem = this.debugNodeLength !== 1 + // Clear if invalid + const itemsLength = parseInt(message?.items?.length) + if (isNaN(itemsLength)) { + removeAllWidgets(this) + return r + } - // Clean up existing widgets if required - if (isMultiItem !== wasMultiItem) { - removeAllWidgets(this) - } - // Remove only widgets we can't reuse - else if (this.debugNodeLength > itemsLength) { - for (let i = itemsLength; i <= this.debugNodeLength; i++) { - for (const widget of this.widgets.filter(x => x.name.endsWith(` ${i}`))) { - removeWidget(this, widget) - } - } - } + const isMultiItem = itemsLength > 1 + const wasMultiItem = this.debugNodeLength !== 1 - this.debugNodeLength = itemsLength - const maxItems = Math.min(itemsLength, hardLimit) - - // Create / update widget values for each item - for (let i = 0; i < maxItems; i++) { - const item = message.items[i] - const type = item.type - const len = item.len - const shape = item.shape - const firstIterItem = item.firstIterItem - const value = item.value - - function processWidget(node, name, value, isMultiline = false) { - const numberedName = isMultiItem - ? `${name} ${i}` - : name - const comfyType = isMultiline - ? ["STRING", { multiline: true }] - : "STRING" - - const current = node.widgets.find(x => x.name === numberedName) - const widget = current ?? ComfyWidgets.STRING(node, numberedName, comfyType, app).widget - - if (!widget.options) - widget.options = {} - widget.options.serialize = false - widget.value = value - widget.disabled = value === null || value === undefined - if (isMultiline) { - widget.element.style.opacity = widget.disabled - ? baseOpacity * 0.5 - : baseOpacity - } - } - - processWidget(this, "type", type) - processWidget(this, "len()", len) - processWidget(this, "shape", shape) - processWidget(this, "type of first iter() item", firstIterItem) - processWidget(this, "value", value, true) - } - - requestAnimationFrame(() => { - this.onResize?.(this.size) - }) - - return r - } + // Clean up existing widgets if required + if (isMultiItem !== wasMultiItem) { + removeAllWidgets(this) + } + // Remove only widgets we can't reuse + else if (this.debugNodeLength > itemsLength) { + for (let i = itemsLength; i <= this.debugNodeLength; i++) { + for (const widget of this.widgets.filter(x => x.name.endsWith(` ${i}`))) { + removeWidget(this, widget) + } } - }, -}); + } + + this.debugNodeLength = itemsLength + const maxItems = Math.min(itemsLength, hardLimit) + + // Create / update widget values for each item + for (let i = 0; i < maxItems; i++) { + const item = message.items[i] + const { type, len, shape, firstIterItem, value } = item + + function processWidget(node, name, value, isMultiline = false) { + const numberedName = isMultiItem + ? `${name} ${i}` + : name + const comfyType = isMultiline + ? ["STRING", { multiline: true }] + : ["STRING", {}] + + const current = node.widgets.find(x => x.name === numberedName) + const widget = current ?? ComfyWidgets.STRING(node, numberedName, comfyType, app).widget + + widget.options ??= {} + widget.options.serialize = false + widget.value = value + widget.disabled = value == null + if (isMultiline) { + widget.element.style.opacity = widget.disabled + ? baseOpacity * 0.5 + : baseOpacity + } + } + + processWidget(this, "type", type) + processWidget(this, "len()", len) + processWidget(this, "shape", shape) + processWidget(this, "type of first iter() item", firstIterItem) + processWidget(this, "value", value, true) + } + + requestAnimationFrame(() => { + this.onResize?.(this.size) + }) + + return r + } + }, +})