- LiteGraph caches a widget's .width the first time it lays a custom-typed widget out and reuses that cached value on every later draw() call. For a divider/status/preset widget added before the node reaches its final size, that cached width goes stale and never updates, making section-divider lines and the status box stop partway across the node instead of spanning it, and clipping/unevenly sizing the preset chips. All three shared widgets now read node.size[0] directly in draw() instead of trusting the widgetWidth parameter, which sidesteps the stale cache entirely. - Add a ?v=2 query string to every import of the shared/*.mjs modules. aiohttp's static file server doesn't send Cache-Control: no-store for these (unlike the top-level registered extension .js files), so browsers were free to keep serving an old cached copy even across a hard reload. A versioned import URL forces a fresh fetch regardless of cache state.
49 lines
1.9 KiB
JavaScript
49 lines
1.9 KiB
JavaScript
import { app } from "../../scripts/app.js";
|
|
import { createStatusWidget } from "./shared/canvas_widgets.mjs?v=2";
|
|
|
|
app.registerExtension({
|
|
name: "Craftopia.SmartPromptController",
|
|
|
|
async nodeCreated(node) {
|
|
if (node.comfyClass !== "SmartPromptController") return;
|
|
|
|
// Canvas-drawn result display — clearly an output, not an input field
|
|
const statusWidget = createStatusWidget("— RUN TO SEE RESULT —");
|
|
node.addCustomWidget(statusWidget);
|
|
|
|
// Override serialize so non-serializable JS widgets (the result display)
|
|
// are excluded from widgets_values in the saved workflow JSON. Without this,
|
|
// LiteGraph saves null slots for these widgets which then shift all Python
|
|
// widget values on load (configure runs before nodeCreated).
|
|
const origSerialize = node.serialize;
|
|
node.serialize = function () {
|
|
const data = origSerialize.call(this);
|
|
if (data.widgets_values) {
|
|
data.widgets_values = this.widgets
|
|
.filter(w => w.serialize !== false && w.options?.serialize !== false)
|
|
.map(w => w.value);
|
|
}
|
|
return data;
|
|
};
|
|
|
|
// Intercept onExecuted: update our widget, hide ComfyUI's default textarea
|
|
const origOnExecuted = node.onExecuted;
|
|
node.onExecuted = function (output) {
|
|
origOnExecuted?.call(this, output);
|
|
|
|
if (output?.text?.[0]) {
|
|
statusWidget._text = output.text[0];
|
|
|
|
// Collapse the default customtext widget ComfyUI adds for ui.text
|
|
for (const w of node.widgets) {
|
|
if (w !== statusWidget && w.type === "customtext") {
|
|
w.computeSize = () => [0, -4];
|
|
}
|
|
}
|
|
}
|
|
|
|
node.setDirtyCanvas(true);
|
|
};
|
|
},
|
|
});
|