Files
arcum42-ComfyUI_SageUtils/js/utils/textCopyUtils.js
T

161 lines
4.5 KiB
JavaScript

/**
* Utility functions for copying text to ComfyUI nodes
*/
/**
* Finds a widget by name in a node
* @param {Object} node - The ComfyUI node
* @param {string} widgetName - Name of the widget to find
* @returns {Object|null} The widget if found, null otherwise
*/
function findWidget(node, widgetName) {
if (!node.widgets) return null;
return node.widgets.find(w => w.name === widgetName) || null;
}
/**
* Checks if a node is a valid target for text copying
* @param {Object} node - The ComfyUI node to check
* @returns {boolean} True if the node can accept text
*/
function isValidTextTarget(node) {
if (!node || !node.widgets) return false;
// Check for CLIPTextEncode nodes
if (node.type === "CLIPTextEncode") {
return findWidget(node, "text") !== null;
}
// Check for Sage Utils text nodes
const sageTextNodePrefixes = [
"Sage_SetText",
"Sage_SetTextWithInt",
"SageSetWildcardText",
"Sage_TextSwitch",
"Sage_JoinText",
"Sage_TripleJoinText",
"Sage_CleanText",
"Sage_TextRandomLine",
"Sage_TextSelectLine",
"Sage_TextSubstitution",
"Sage_HiDreamE1_Instruction",
"Sage_TextWeight"
];
const isSageTextNode = sageTextNodePrefixes.some(prefix =>
node.type?.startsWith(prefix)
);
if (isSageTextNode) {
// Try to find either "str" or "text" widget
return findWidget(node, "str") !== null ||
findWidget(node, "text") !== null;
}
return false;
}
/**
* Copies text to a target node's text widget
* @param {Object} node - The target ComfyUI node
* @param {string} text - The text to copy
* @returns {boolean} True if successful, false otherwise
*/
function copyTextToNode(node, text) {
if (!isValidTextTarget(node)) {
console.warn("Node is not a valid text target:", node.type);
return false;
}
let targetWidget = null;
// For CLIPTextEncode, use "text" widget
if (node.type === "CLIPTextEncode") {
targetWidget = findWidget(node, "text");
} else {
// For Sage text nodes, try "str" first, then "text"
targetWidget = findWidget(node, "str") || findWidget(node, "text");
}
if (!targetWidget) {
console.warn("No suitable text widget found in node:", node.type);
return false;
}
// Set the value
targetWidget.value = text;
// Trigger any callbacks
if (targetWidget.callback) {
targetWidget.callback(text);
}
// Mark the graph as dirty to ensure it updates
if (node.graph && node.graph.setDirtyCanvas) {
node.graph.setDirtyCanvas(true, true);
}
return true;
}
/**
* Gets the currently selected node in the graph
* @param {Object} app - The ComfyUI app instance
* @returns {Object|null} The selected node, or null if none selected
*/
function getSelectedNode(app) {
if (!app.canvas || !app.canvas.selected_nodes) return null;
const selectedNodes = Object.keys(app.canvas.selected_nodes);
if (selectedNodes.length !== 1) return null;
const nodeId = parseInt(selectedNodes[0]);
return app.graph.getNodeById(nodeId);
}
/**
* Copies text to the currently selected node
* @param {Object} app - The ComfyUI app instance
* @param {string} text - The text to copy
* @returns {boolean} True if successful, false otherwise
*/
function copyTextToSelectedNode(app, text) {
const selectedNode = getSelectedNode(app);
if (!selectedNode) {
console.warn("No node selected");
return false;
}
return copyTextToNode(selectedNode, text);
}
/**
* Creates a context menu action for copying text to a node
* @param {string} text - The text to copy
* @param {string} label - Label for the menu item (default: "Copy to selected node")
* @returns {Object} Context menu item configuration
*/
function createCopyTextMenuItem(text, label = "Copy to selected node") {
return {
content: label,
callback: (app) => {
const success = copyTextToSelectedNode(app, text);
if (success) {
console.log("Text copied to selected node");
} else {
alert("Please select a valid text node (CLIPTextEncode or Sage text node)");
}
}
};
}
// Export functions
export {
findWidget,
isValidTextTarget,
copyTextToNode,
getSelectedNode,
copyTextToSelectedNode,
createCopyTextMenuItem
};