231 lines
9.8 KiB
JavaScript
231 lines
9.8 KiB
JavaScript
import { app } from "/scripts/app.js";
|
|
import { api } from "/scripts/api.js";
|
|
import { setWidgetConfig } from "/extensions/core/widgetInputs.js";
|
|
function createCallback(nodename, basename, inputType, withWeights) {
|
|
return async function (nodeType, nodeData, app) {
|
|
if (nodeData.name !== nodename) {
|
|
return;
|
|
}
|
|
const getInputBasename = function (input) {
|
|
return input.name.split('_')[0];
|
|
};
|
|
const getInputExtraname = function (input) {
|
|
return input.name.split('_', 2)[1];
|
|
};
|
|
const updateInputs = function () {
|
|
this.widgets = [];
|
|
// remove empty inputs
|
|
for (let index = this.inputs.length; index--;) {
|
|
const input = this.inputs[index];
|
|
if (getInputBasename(input) === basename && input.link === null && this.removeCancel !== index) {
|
|
this.removeInput(index);
|
|
}
|
|
}
|
|
// current version
|
|
if (typeof this.layoutSlot !== "function") {
|
|
// rename
|
|
let j = 0;
|
|
for (let i = 0, il = this.inputs.length; i < il; ++i) {
|
|
const input = this.inputs[i];
|
|
if (getInputBasename(input) === basename) {
|
|
this.inputs[i].name = [basename, j++].join('_');
|
|
this.inputs[i].widget = void 0;
|
|
}
|
|
}
|
|
// create empty input
|
|
this.addInput([basename, j].join('_'), inputType);
|
|
}
|
|
// legacy version
|
|
else {
|
|
// rename
|
|
let j = 0;
|
|
for (let i = 0, il = this.inputs.length; i < il; ++i) {
|
|
const input = this.inputs[i];
|
|
if (getInputBasename(input) === basename) {
|
|
this.inputs[i].name = [basename, j++].join('_');
|
|
}
|
|
}
|
|
// create empty input
|
|
this.addInput([basename, j].join('_'), inputType);
|
|
for (let i = 0, il = this.inputs.length; i < il; ++i) {
|
|
const input = this.inputs[i];
|
|
// setup widget
|
|
input.widget = {
|
|
name: input.name,
|
|
};
|
|
setWidgetConfig(input, [input.type, { forceInput: true }]);
|
|
}
|
|
for (const [idx, slot] of this.inputs.entries()) {
|
|
if (!slot._layoutElement) {
|
|
this.layoutSlot(slot, { slotIndex: idx });
|
|
}
|
|
}
|
|
}
|
|
};
|
|
const onNodeCreatedOriginal = nodeType.prototype.onNodeCreated;
|
|
nodeType.prototype.onNodeCreated = function () {
|
|
if (onNodeCreatedOriginal) {
|
|
onNodeCreatedOriginal.call(this);
|
|
}
|
|
this.removeCancel = -1;
|
|
const onConnectInputOriginal = this.onConnectInput;
|
|
this.onConnectInput = function (targetSlot, type, output, originNode, originSlot) {
|
|
let retVal = onConnectInputOriginal ? onConnectInputOriginal.apply(this, arguments) : void 0;
|
|
if (originNode.type === "PrimitiveNode") {
|
|
return false;
|
|
}
|
|
this.removeCancel = targetSlot;
|
|
return retVal;
|
|
};
|
|
const onInputDblClickOriginal = this.onInputDblClick;
|
|
this.onInputDblClick = function (slot) {
|
|
if (onInputDblClickOriginal) {
|
|
const originalCreateNode = LiteGraph.createNode;
|
|
if (getInputBasename(this.inputs[slot]) === basename) {
|
|
LiteGraph.createNode = function (nodeType) {
|
|
if (nodeType !== "PrimitiveNode") {
|
|
return originalCreateNode.apply(this, arguments);
|
|
}
|
|
return originalCreateNode.call(this, "StringToolsText");
|
|
};
|
|
}
|
|
onInputDblClickOriginal.call(this, slot);
|
|
LiteGraph.createNode = originalCreateNode;
|
|
}
|
|
};
|
|
const onConnectionsChange = this.onConnectionsChange;
|
|
this.onConnectionsChange = function (type, //(0: ?, 1:input, 2: output )
|
|
slotIndex, isConnected, link, //LLink,
|
|
ioSlot) {
|
|
if (onConnectionsChange) {
|
|
onConnectionsChange.apply(this, arguments);
|
|
}
|
|
if (type !== 1) {
|
|
return;
|
|
}
|
|
updateInputs.call(this);
|
|
this.removeCancel = -1;
|
|
};
|
|
this.onAdded = function (graph) {
|
|
this.tmpWidgets = this.widgets;
|
|
if (app.configuringGraph) {
|
|
this.widgets = [];
|
|
this.widgets_values = [];
|
|
}
|
|
else {
|
|
updateInputs.call(this);
|
|
}
|
|
};
|
|
// デフォルトの onGraphConfigured は動的なソケットを破壊するので使用しない
|
|
const onGraphConfigured = this.onGraphConfigured;
|
|
this.onGraphConfigured = function () {
|
|
if (this.tmpWidgets) {
|
|
this.widgets = this.tmpWidgets.concat(this.widgets);
|
|
delete this.tmpWidgets;
|
|
}
|
|
if (app.configuringGraph) {
|
|
updateInputs.call(this);
|
|
}
|
|
};
|
|
if (withWeights !== void 0) {
|
|
this.calcNodeInputs = function (prompt, workflow) {
|
|
const flattenPrompt = {};
|
|
for (const [key, value] of Object.entries(prompt)) {
|
|
const flattenId = key.split(':').at(-1);
|
|
flattenPrompt[flattenId] = value;
|
|
}
|
|
const node = flattenPrompt[this.id];
|
|
const type = node.class_type;
|
|
for (const input of Object.keys(node.inputs)) {
|
|
if (getInputBasename({ name: input }) !== basename) {
|
|
continue;
|
|
}
|
|
const extraname = getInputExtraname({ name: input });
|
|
const walkdown = (type, id, sum) => {
|
|
const node = flattenPrompt[id.split(':').at(-1)];
|
|
for (const input of Object.keys(node.inputs)) {
|
|
const value = node.inputs[input];
|
|
let start = 0;
|
|
if (withWeights.includes(node.class_type) &&
|
|
getInputBasename({ name: input }) === basename) {
|
|
start = 1;
|
|
}
|
|
if (Array.isArray(value)) {
|
|
sum += walkdown(type, value[0], start);
|
|
}
|
|
}
|
|
return sum;
|
|
};
|
|
const value = node.inputs[input];
|
|
if (Array.isArray(value)) {
|
|
let sum = walkdown(type, value[0], 0);
|
|
if (sum === 0) {
|
|
sum = 1;
|
|
}
|
|
const weightKey = ["weight", extraname].join('_');
|
|
node.inputs[weightKey] = sum;
|
|
node.inputs["title"] = this.title;
|
|
node.inputs["id"] = this.id;
|
|
node.inputs["debug"] = app.extensionManager.setting.get("StringTools.StringToolsBalancedChoice.debug");
|
|
}
|
|
}
|
|
};
|
|
}
|
|
// init inputs
|
|
if (!this.inputs) {
|
|
this.inputs = [];
|
|
}
|
|
};
|
|
};
|
|
}
|
|
const queuePromptOriginal = api.queuePrompt;
|
|
api.queuePrompt = (async function queuePrompt(number, { output, workflow }) {
|
|
for (const idPath of Object.keys(output)) {
|
|
const path = idPath.split(":");
|
|
let node;
|
|
if (path.length === 1) {
|
|
const id = path[0];
|
|
node = app.graph.getNodeById(id);
|
|
}
|
|
else {
|
|
const nodePath = app.graph.resolveSubgraphIdPath(path.slice(0, -1));
|
|
const id = path.at(-1);
|
|
const subgraphNode = nodePath.at(-1);
|
|
if (subgraphNode.isSubgraphNode()) {
|
|
node = subgraphNode.subgraph.getNodeById(id);
|
|
}
|
|
else {
|
|
console.error("last nodePath is not subgraph");
|
|
}
|
|
}
|
|
if (!node) {
|
|
console.error("output node not found:", idPath);
|
|
continue;
|
|
}
|
|
if (node.calcNodeInputs && typeof node.calcNodeInputs === "function") {
|
|
node.calcNodeInputs(output, workflow);
|
|
}
|
|
}
|
|
return await queuePromptOriginal.call(api, number, { output, workflow });
|
|
}).bind(api);
|
|
app.registerExtension({
|
|
name: "Taremin.StringToolsConcat",
|
|
beforeRegisterNodeDef: createCallback("StringToolsConcat", "text", "STRING"),
|
|
});
|
|
app.registerExtension({
|
|
name: "Taremin.StringToolsRandomChoice",
|
|
beforeRegisterNodeDef: createCallback("StringToolsRandomChoice", "text", "STRING", ["StringToolsRandomChoice"]),
|
|
});
|
|
app.registerExtension({
|
|
name: "Taremin.StringToolsBalancedChoice",
|
|
settings: [
|
|
{
|
|
id: "StringTools.StringToolsBalancedChoice.debug",
|
|
name: "Debug",
|
|
type: "boolean",
|
|
defaultValue: false,
|
|
}
|
|
],
|
|
beforeRegisterNodeDef: createCallback("StringToolsBalancedChoice", "text", "STRING", ["StringToolsRandomChoice", "StringToolsBalancedChoice"]),
|
|
});
|