diff --git a/js/connections.js b/js/connections.js index de9c3be..d08f114 100644 --- a/js/connections.js +++ b/js/connections.js @@ -46,8 +46,10 @@ export function input_changed(node, slot, connect, link_info) { } else { if (in_slot.transient_label) { in_slot.label = in_slot.transient_label + Logger.log("Restoring transient label") } else if (in_slot.label && in_slot.label != i18n('anything')) { // leave custom label alone + Logger.log("Leaving custom label") } else if (app.ui.settings.getSettingValue("Use Everywhere.Options.use_output_name") && link_info) { const out_slot = (link_info.origin_id==-10) ? graph.inputNode?.allSlots[link_info.origin_slot] : @@ -61,9 +63,11 @@ export function input_changed(node, slot, connect, link_info) { } } else { in_slot.transient_label = in_slot.label - in_slot.label = i18n('anything'); - in_slot.color_on = undefined; - in_slot.type = '*' + if (is_removable(node, in_slot, slot)) { + in_slot.label = i18n('anything'); + in_slot.color_on = undefined; + in_slot.type = '*' + } setTimeout(()=>{in_slot.transient_label=null}, 100) } @@ -86,7 +90,7 @@ function add_new_input(node) { } function remove_excess_input(node) { - const idx = node.inputs.findIndex((inputslot)=>(inputslot.type=='*')) + const idx = node.inputs.findIndex((inputslot, i)=>(is_removable(node,inputslot,i))) if (idx>=0) { try { Logger.log_info(`Removing excess anything input from node ${node.id} (${fix_call_message})`) @@ -97,17 +101,24 @@ function remove_excess_input(node) { return false } -/* -This is called in various places (node load, creation, link change) to ensure there is exactly one empty input -*/ - var fix_call_message; -function fix_star_inputs(node) { - node.inputs.filter((input)=>(!input.link)).forEach((input)=>{ +function to_keep(node, i) { + return (node.properties.ue_properties?.keep_inputs && node.properties.ue_properties?.keep_inputs.includes(i)) +} + +function is_removable(node, inputslot, i) { + return (inputslot.type=='*' && !to_keep(node,i)) +} + +function fix_unconnected_inputs(node) { + node.inputs.filter((input, i)=>(!input.link && !to_keep(node,i))).forEach((input)=>{ input.type = '*' - input.label = i18n('anything'); + input.label = i18n('anything') }) +} + +function fix_star_inputs(node) { node.inputs.filter((input)=>(input.type=='*' && input.link)).forEach((input)=>{ const llink = node.graph.links[input.link] if (llink.type) input.type = llink.type @@ -120,15 +131,16 @@ export function fix_inputs(node, message) { if (shared.graph_being_configured) return if (node.properties.ue_properties.fixed_inputs) return + fix_unconnected_inputs(node) fix_star_inputs(node) - const empty_inputs = node.inputs.filter((inputslot)=>(inputslot.type=='*')) - var excess_inputs = empty_inputs.length - 1 + const empty_removable_inputs = node.inputs.filter((inputslot, i)=>(is_removable(node, inputslot, i))) + var excess_inputs = empty_removable_inputs.length - 1 if (excess_inputs<0) { - if (add_new_input(node)) fix_inputs(node) + if (add_new_input(node)) fix_inputs(node, message) } else if (excess_inputs>0) { - if (remove_excess_input(node)) fix_inputs(node) + if (remove_excess_input(node)) fix_inputs(node, message) } } \ No newline at end of file diff --git a/js/i18n.js b/js/i18n.js index 2381b6b..1821a42 100644 --- a/js/i18n.js +++ b/js/i18n.js @@ -54,6 +54,10 @@ function get_functional() { seed_input_regex : `seed|${nd.inputs.find((i)=>(i.name=='seed')).localized_name}`, prompt_regex : `(_|\\b)pos(itive|_|\\b)|${nd.inputs.find((i)=>(i.name=='positive')).localized_name}`, negative_regex : `(_|\\b)neg(ative|_|\\b)|${nd.inputs.find((i)=>(i.name=='negative')).localized_name}`, + seed : nd.inputs.find((i)=>(i.name=='seed')).localized_name, + positive : nd.inputs.find((i)=>(i.name=='positive')).localized_name, + negative : nd.inputs.find((i)=>(i.name=='negative')).localized_name, + } } } diff --git a/js/ue_properties.js b/js/ue_properties.js index 0e8f8aa..3dabd01 100644 --- a/js/ue_properties.js +++ b/js/ue_properties.js @@ -133,14 +133,18 @@ function convert_node_types(node) { if (node.title=="Anything Everywhere3") node.title = "Anything Everywhere" node.type = "Anything Everywhere" } else if (node.type=="Seed Everywhere") { + if (node.title=="Anything Everywhere3") node.title = "PrimitiveInt" node.type = "PrimitiveInt" node.properties.ue_convert = true node.properties.ue_properties.fixed_inputs = true node.properties.ue_properties.seed_inputs = true node.properties.ue_properties.input_regex = node.properties.ue_properties.input_regex || i18n_functional('seed_input_regex') } else if (node.type=="Prompts Everywhere") { - node.properties.ue_properties.fixed_inputs = true - node.properties.ue_properties.prompt_regexes = true + if (node.title=="Prompts Everywhere") node.title = "Anything Everywhere" + node.properties.ue_properties.fixed_inputs = false + node.inputs[0].label = i18n_functional('positive') + node.inputs[1].label = i18n_functional('negative') + node.properties.ue_properties['keep_inputs'] = [0,1] } ALL_REGEXES.forEach((r)=>{ diff --git a/js/ue_properties_editor.js b/js/ue_properties_editor.js index 4af3214..9452649 100644 --- a/js/ue_properties_editor.js +++ b/js/ue_properties_editor.js @@ -1,9 +1,9 @@ -import { LinkRenderController } from "./use_everywhere_ui.js"; import { i18n, i18n_functional, GROUP_RESTRICTION_OPTIONS, COLOR_RESTRICTION_OPTIONS, REPEATED_TYPE_OPTIONS } from "./i18n.js"; import { app } from "../../scripts/app.js"; import { default_priority } from "./ue_properties.js"; import { edit_window } from "./floating_window.js"; import { shared } from "./shared.js"; +import { Logger } from "./use_everywhere_utilities.js"; const REGEXES = ['title', 'input', 'group'] const P_REGEXES = ['prompt', 'negative'] @@ -44,14 +44,6 @@ function changed(node, property, value) { document.getElementById('priority_value').value = `${default_priority(node)}` } - if (node.properties.ue_properties.prompt_regexes) { - for (var i=0; i<2; i++) { - if (!node.properties.ue_properties[`${P_REGEXES[i]}_regex`]) { - document.getElementById(`${P_REGEXES[i]}_regex_value`).value = i18n_functional(`${P_REGEXES[i]}_regex`) - } - } - } - const elem = document.getElementById(`${property}_value`) if (elem) elem.style.opacity = (value) ? "1" : "0.5" @@ -63,47 +55,26 @@ function create_editor_html(node) { const table = document.createElement('table') for (var i=0; i<=2; i++) { - - if (i==1 && node.properties.ue_properties.prompt_regexes) { - for (var j=0; j<2; j++) { - const name = P_REGEXES[j] - const row = add_row(table, `${i18n(name)} regex`) + const name = REGEXES[i] + const row = add_row(table, `${i18n(name)} regex`) - const input_props = { - type:'text', - id:`${name}_regex_value`, - value: node.properties.ue_properties[`${name}_regex`] || i18n_functional(`${name}_regex`), - } + const contents = create_element('span', null, {'className':'regex_input_container'}) - const input = create_element('input', contents, input_props). - addEventListener('input', (e)=>{ changed(node, `${name}_regex`, e.target.value)}) - - if (!node.properties.ue_properties[`${name}_regex`]) input.style.opacity = 0.5 - - add_cell(row,input) - } - } else { - const name = REGEXES[i] - const row = add_row(table, `${i18n(name)} regex`) - - const contents = create_element('span', null, {'className':'regex_input_container'}) - - const checkbox_props = { - type:'checkbox', - id:`${name}_regex_invert`, - checked: (node.properties.ue_properties[`${name}_regex_invert`]) ? true : undefined, - className: 'checkbox' - } - create_element('input', contents, checkbox_props). - addEventListener('input', (e)=>{ changed(node, `${name}_regex_invert`, e.target.checked); } ) - - create_element('span', contents, {innerText:i18n('Invert'), className:'regex_checkbox_label'}) - - create_element('input', contents, {type:'text', value:node.properties.ue_properties[`${name}_regex`] || ''}). - addEventListener('input', (e)=>{ changed(node, `${name}_regex`, e.target.value)}) - - add_cell(row,contents) + const checkbox_props = { + type:'checkbox', + id:`${name}_regex_invert`, + checked: (node.properties.ue_properties[`${name}_regex_invert`]) ? true : undefined, + className: 'checkbox' } + create_element('input', contents, checkbox_props). + addEventListener('input', (e)=>{ changed(node, `${name}_regex_invert`, e.target.checked); } ) + + create_element('span', contents, {innerText:i18n('Invert'), className:'regex_checkbox_label'}) + + create_element('input', contents, {type:'text', value:node.properties.ue_properties[`${name}_regex`] || ''}). + addEventListener('input', (e)=>{ changed(node, `${name}_regex`, e.target.value)}) + + add_cell(row,contents) } const gr_row = add_row(table, i18n("Group")) @@ -116,12 +87,11 @@ function create_editor_html(node) { add_cell(col_row,col_select) add_select_options(node, col_select, COLOR_RESTRICTION_OPTIONS, `color_restricted` ) - if (!node.properties.ue_properties.prompt_regexes) { - const repeated_type_row = add_row(table, i18n("Repeated Types")) - const repeated_type_select = document.createElement('select') - add_cell(repeated_type_row,repeated_type_select) - add_select_options(node, repeated_type_select, REPEATED_TYPE_OPTIONS, `repeated_type_rule`) - } + const repeated_type_row = add_row(table, i18n("Repeated Types")) + const repeated_type_select = document.createElement('select') + add_cell(repeated_type_row,repeated_type_select) + add_select_options(node, repeated_type_select, REPEATED_TYPE_OPTIONS, `repeated_type_rule`) + if (node.inputs.find((i)=>(i.type=="STRING"))) { const send_to_combos_row = add_row(table, i18n("String to Combos")) diff --git a/js/use_everywhere_apply.js b/js/use_everywhere_apply.js index d984a53..208e722 100644 --- a/js/use_everywhere_apply.js +++ b/js/use_everywhere_apply.js @@ -127,18 +127,3 @@ function _convert_graph_to_links(graph, ues, control_node_id) { return {restorer:restorer, added_links:added_links} } - -function is_removable_ue(node) { - return (is_UEnode(node, false) && !(node.comfyClass=="Seed Everywhere") ) -} - -export function remove_all_ues(keep_seed_everywhere, graph, recurse) { - graph._nodes.filter((node)=>is_removable_ue(node, keep_seed_everywhere)).forEach((node)=>{graph.remove(node)}) - if (recurse) { - graph._nodes.filter((node)=>(node.subgraph)).forEach((node)=>{remove_all_ues(keep_seed_everywhere, node.subgraph, recurse)}) - } -} - -export function remove_removable_ues(graph) { - graph._nodes.filter((node)=>is_removable_ue(node, keep_seed_everywhere)).forEach((node)=>{graph.remove(node)}) -} diff --git a/js/use_everywhere_classes.js b/js/use_everywhere_classes.js index 983fe5b..9f9a5a7 100644 --- a/js/use_everywhere_classes.js +++ b/js/use_everywhere_classes.js @@ -304,9 +304,9 @@ export class UseEverywhereList { the_possibles.forEach((possible, i) => { const connection = connection_finder(node, i); if (connection.link) { - const input_regex = (node.properties.ue_properties.prompt_regexes) ? prompt_regex(node,i) : undefined + const input_regex = undefined var additional_requirement = null - if (duplicated_broadcasted_types.has(connection.type) && !node.properties.ue_properties.prompt_regexes) { + if (duplicated_broadcasted_types.has(connection.type)) { const input_name = possible.label || possible.name const rule = node.properties.ue_properties?.repeated_type_rule || 0 if (rule == 0) { // 0 is exact match of input name diff --git a/js/use_everywhere_graph_analysis.js b/js/use_everywhere_graph_analysis.js index fb541f1..dc48b8b 100644 --- a/js/use_everywhere_graph_analysis.js +++ b/js/use_everywhere_graph_analysis.js @@ -65,6 +65,9 @@ class GraphAnalyser extends Pausable { /* work around known bug in ComfyUI front end that doesn't clean up the linkIds https://github.com/Comfy-Org/ComfyUI_frontend/issues/5673#issuecomment-3314310014 + + Maybe fixed? Or maybe just for the input links? + https://github.com/Comfy-Org/ComfyUI_frontend/pull/6258 */ if (graph.inputNode) { graph.inputNode.slots.forEach((slot)=>{ diff --git a/js/use_everywhere_settings.js b/js/use_everywhere_settings.js index 43e5a24..c3520c7 100644 --- a/js/use_everywhere_settings.js +++ b/js/use_everywhere_settings.js @@ -1,5 +1,5 @@ import { app } from "../../scripts/app.js"; -import { convert_to_links, remove_removable_ues } from "./use_everywhere_apply.js"; +import { convert_to_links } from "./use_everywhere_apply.js"; import { Logger } from "./use_everywhere_utilities.js"; import { settingsCache } from "./use_everywhere_cache.js"; import { visible_graph } from "./use_everywhere_subgraph_utils.js"; @@ -197,7 +197,7 @@ function node_menu_settings(options, node) { callback: edit_restrictions, } ) - if (is_UEnode(node, false)) { + if (is_UEnode(node, true)) { options.push( { content: "Convert to real links", @@ -208,7 +208,11 @@ function node_menu_settings(options, node) { alert("Convert failed - press f12 to see the console log") } else { convert_to_links(ues, node); - visible_graph().remove(node); + if (is_UEnode(node)) { + visible_graph().remove(node); + } else { + node.properties.ue_convert = false + } } } } @@ -244,6 +248,9 @@ function non_ue_menu_settings(options, node) { ) } +function remove_ue_nodes(graph) { + graph._nodes.filter((node)=>is_UEnode(node, false)).forEach((node)=>{graph.remove(node)}) +} export function canvas_menu_settings(options) { options.push(null); // divider @@ -264,7 +271,7 @@ export function canvas_menu_settings(options) { try { const graph = visible_graph() shared.graphAnalyser.modify_graph( graph ) - remove_removable_ues( graph ) + remove_ue_nodes( graph ) } finally { app.graph.change(); shared.linkRenderController.unpause() @@ -279,7 +286,7 @@ export function canvas_menu_settings(options) { shared.linkRenderController.pause("convert"); try { for_all_graphs(shared.graphAnalyser.modify_graph.bind(shared.graphAnalyser)) - for_all_graphs(remove_removable_ues) + for_all_graphs(remove_ue_nodes) } finally { app.graph.change(); shared.linkRenderController.unpause()