Files
logicalor-comfyui_multi_rep…/js/multi_replace.js
T
2025-12-16 09:42:10 +10:00

154 lines
5.7 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { app } from "../../scripts/app.js";
/**
* ComfyUI Multi-Replace Extension
* Handles dynamic visibility of find/replace pair widgets
*/
const MAX_PAIRS = 80;
app.registerExtension({
name: "comfyui-multi-replace",
async beforeRegisterNodeDef(nodeType, nodeData, app) {
if (nodeData.name === "FindReplacePairs") {
const origOnNodeCreated = nodeType.prototype.onNodeCreated;
nodeType.prototype.onNodeCreated = function() {
if (origOnNodeCreated) {
origOnNodeCreated.apply(this, arguments);
}
this.pairCount = 1;
// Add the "Add Pair" button at the end
this.addWidget("button", "➕ Add Pair", null, () => {
this.addNewPair();
});
// Add the "Remove Last Pair" button
this.addWidget("button", "➖ Remove Last Pair", null, () => {
this.removeLastPair();
});
// Initial visibility update
setTimeout(() => {
this.updatePairVisibility();
}, 50);
};
// Show the next pair
nodeType.prototype.addNewPair = function() {
if (this.pairCount >= MAX_PAIRS) return;
this.pairCount++;
this.updatePairVisibility();
};
// Hide the last pair
nodeType.prototype.removeLastPair = function() {
if (this.pairCount <= 1) return;
// Clear the values of the pair being removed
const findWidget = this.widgets?.find(w => w.name === `find_${this.pairCount}`);
const replaceWidget = this.widgets?.find(w => w.name === `replace_${this.pairCount}`);
if (findWidget) findWidget.value = "";
if (replaceWidget) replaceWidget.value = "";
this.pairCount--;
this.updatePairVisibility();
};
// Update visibility of pair widgets
nodeType.prototype.updatePairVisibility = function() {
if (!this.widgets) return;
for (const widget of this.widgets) {
const match = widget.name?.match(/^(find|replace)_(\d+)$/);
if (match) {
const pairIndex = parseInt(match[2]);
const shouldShow = pairIndex <= this.pairCount;
if (shouldShow) {
// Show widget
widget.type = widget._originalType || widget.type;
if (widget._originalComputeSize) {
widget.computeSize = widget._originalComputeSize;
}
} else {
// Hide widget
if (widget.type !== "hidden") {
widget._originalType = widget.type;
widget._originalComputeSize = widget.computeSize;
}
widget.type = "hidden";
widget.computeSize = () => [0, -4];
}
}
}
// Also hide/show the corresponding inputs
if (this.inputs) {
for (const input of this.inputs) {
const match = input.name?.match(/^(find|replace)_(\d+)$/);
if (match) {
const pairIndex = parseInt(match[2]);
// We can't truly hide inputs, but we can mark them
input._hidden = pairIndex > this.pairCount;
}
}
}
this.setSize(this.computeSize());
app.graph.setDirtyCanvas(true, true);
};
// Override getExtraMenuOptions to add right-click options
const origGetExtraMenuOptions = nodeType.prototype.getExtraMenuOptions;
nodeType.prototype.getExtraMenuOptions = function(_, options) {
if (origGetExtraMenuOptions) {
origGetExtraMenuOptions.apply(this, arguments);
}
options.unshift(
{
content: "Add Find/Replace Pair",
disabled: this.pairCount >= MAX_PAIRS,
callback: () => this.addNewPair()
},
{
content: "Remove Last Pair",
disabled: this.pairCount <= 1,
callback: () => this.removeLastPair()
},
null // separator
);
};
// Save pair count
const origOnSerialize = nodeType.prototype.onSerialize;
nodeType.prototype.onSerialize = function(info) {
if (origOnSerialize) {
origOnSerialize.apply(this, arguments);
}
info.pairCount = this.pairCount;
};
// Restore pair count and visibility
const origOnConfigure = nodeType.prototype.onConfigure;
nodeType.prototype.onConfigure = function(info) {
if (origOnConfigure) {
origOnConfigure.apply(this, arguments);
}
if (info.pairCount) {
this.pairCount = info.pairCount;
}
setTimeout(() => {
this.updatePairVisibility();
}, 50);
};
}
}
});