File size: 3,145 Bytes
baac5bb | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 | import { app } from "../../scripts/app.js";
function mimicNode(node, target, slot) {
const getWidget = (widget) => {
if (typeof widget.origType === "undefined") return widget;
const newWidget = new Proxy(widget, {
has(target, prop) {
return prop in target && prop !== "origType" && prop !== "computeSize";
},
get(target, prop) {
if (prop.startsWith("orig") || prop === "computeSize") {
return undefined;
} else if (prop === "type") {
return target.origType;
} else if (prop === "name") {
return inputName;
} else {
return target[prop];
}
},
set(target, prop, value) {
target[prop] = value;
return true;
}
});
return newWidget;
}
const input = target.inputs[slot];
const inputName = node.inputs.length > 0 ? node.inputs[0].name : node.widgets[0].name;
if (typeof input.widget === "undefined") { // This is an input
node.inputs = [{ ...input, name: inputName }];
node.widgets = [];
} else { // This is a widget
node.widgets = [getWidget(target.widgets.find(w => w.name === input.name))];
node.inputs = [];
node.size = node.computeSize();
requestAnimationFrame(() => {
if (node.onResize) {
node.onResize(node.size);
}
});
}
}
app.registerExtension({
name: "Comfy.DynamicInput",
dynamicNodes: ["CPackInputAny", "CPackInputFile"],
async beforeRegisterNodeDef(nodeType, nodeData) {
if (!this.dynamicNodes.includes(nodeData.name)) return;
nodeType.prototype.onConnectOutput = function () {
if (this.outputs[0].links?.length > 0) return false;
const target = arguments[3];
if (this.type === "CPackInputFile" && !["COMBO", "STRING"].includes(target.inputs[arguments[4]].type))
return false;
mimicNode(this, target, arguments[4]);
this.title = target.inputs[arguments[4]].name;
}
},
async setup(app) {
app.graph.nodes.forEach((node) => {
if (!this.dynamicNodes.includes(node.type)) return;
if (node.outputs.length > 0 && node.outputs[0].links.length > 0) {
const link = node.graph.links[node.outputs[0].links[0]];
mimicNode(node, app.graph.getNodeById(link.target_id), link.target_slot);
}
})
},
async init(app) {
const originalToPrompt = app.graphToPrompt;
const self = this;
app.graphToPrompt = async function(graph = app.graph, clean = true) {
const { workflow, output } = await originalToPrompt(graph, clean);
Object.entries(output).forEach(([id, nodeData]) => {
if (!nodeData.class_type.startsWith("CPackInput")) return;
const node = graph.getNodeById(parseInt(id));
if (!nodeData["_meta"]) {
nodeData["_meta"] = { title: node.title };
}
if (node.widgets.length === 0) return;
const widget = node.widgets[0];
nodeData["_meta"] = { ...nodeData["_meta"], options: widget.options };
});
return { workflow, output };
};
}
});
|