Files
2026-07-18 22:51:37 +02:00

74 lines
2.9 KiB
JavaScript

import { app } from "../../../scripts/app.js";
import { ComfyWidgets } from "../../../scripts/widgets.js";
app.registerExtension({
name: "LogToWorkspace.Extension",
async beforeRegisterNodeDef(nodeType, nodeData, app) {
const targetNodes = ["LogToWorkspace", "LogToWorkspaceAdv"];
if (targetNodes.includes(nodeData.name)) {
// 1. GENERATE THE GENUINE TEXTAREA WIDGET ON CREATION
const onNodeCreated = nodeType.prototype.onNodeCreated;
nodeType.prototype.onNodeCreated = function () {
onNodeCreated?.apply(this, arguments);
// Use the official ComfyUI STRING widget constructor for multi-line boxes
const widgetResult = ComfyWidgets["STRING"](
this, // The node instance object
"displayed_text", // The name of your custom widget
["STRING", { multiline: true }], // Tells Comfy to spin up a textarea element
app, // Pass the current app reference
);
const widget = widgetResult.widget;
// Configure parameters for read-only tracking logs
widget.inputEl.readOnly = true;
widget.inputEl.style.opacity = "0.85"; // Gives it a clean, greyed-out terminal appearance
widget.serializeValue = () => undefined; // Prevents logging bloat inside saved workflow metadata
// 2. DEFER REPOSITIONING: Let ComfyUI finish initialization loops first to stop the "true" bug
setTimeout(() => {
const currentIdx = this.widgets.indexOf(widget);
if (currentIdx > -1) this.widgets.splice(currentIdx, 1);
this.widgets.splice(0, 0, widget);
}, 5);
// Adjust standard node bounding boxes
if (nodeData.name === "LogToWorkspaceAdv")
this.size = [400, 340]; // Room for text area above the toggle checkboxes
else this.size = [400, 240]; // Default dimension
// Force layout dimensions to fit the new HTML element
// this.size = [400, 200];
this.setDirtyCanvas(true, true);
};
// 2. FORCE SYNC BACKEND PAYLOADS STRAIGHT INTO THE HTML DOM
const onExecuted = nodeType.prototype.onExecuted;
nodeType.prototype.onExecuted = function (message) {
onExecuted?.apply(this, arguments);
if (message?.text) {
const textValue = message.text.join("\n");
const widget = this.widgets?.find((w) => w.name === "displayed_text");
if (widget) {
// Sync internal LiteGraph state
widget.value = textValue;
// Sync native browser DOM textarea so the lines warp and update visually
if (widget.inputEl) {
widget.inputEl.value = textValue;
// AUTO-SCROLL MECHANISM: Automatically tracks and pulls down to show the latest logs
widget.inputEl.scrollTop = widget.inputEl.scrollHeight;
}
this.setDirtyCanvas(true, true);
}
}
};
}
},
});