161 lines
4.5 KiB
JavaScript
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
|
|
}; |