V1.92 Efficiency Nodes MEGA Update (SDXL + MORE)

This PR is a huge update, I added/fixed so many things that I will explain all the updates later on the release notes.
This commit is contained in:
TSC
2023-08-30 20:06:15 -05:00
committed by GitHub
parent 26c81dba51
commit 92ff8fd8c3
21 changed files with 3573 additions and 1459 deletions

95
js/appearance.js Normal file
View File

@@ -0,0 +1,95 @@
import { app } from "../../scripts/app.js";
const COLOR_THEMES = {
red: { nodeColor: "#332222", nodeBgColor: "#553333" },
green: { nodeColor: "#223322", nodeBgColor: "#335533" },
blue: { nodeColor: "#222233", nodeBgColor: "#333355" },
pale_blue: { nodeColor: "#2a363b", nodeBgColor: "#3f5159" },
cyan: { nodeColor: "#223333", nodeBgColor: "#335555" },
purple: { nodeColor: "#332233", nodeBgColor: "#553355" },
yellow: { nodeColor: "#443322", nodeBgColor: "#665533" },
none: { nodeColor: null, nodeBgColor: null } // no color
};
const NODE_COLORS = {
"KSampler (Efficient)": "random",
"KSampler Adv. (Efficient)": "random",
"KSampler SDXL (Eff.)": "random",
"Efficient Loader": "random",
"Eff. Loader SDXL": "random",
"LoRA Stacker": "blue",
"Control Net Stacker": "green",
"Apply ControlNet Stack": "none",
"XY Plot": "purple",
"Unpack SDXL Tuple": "none",
"Pack SDXL Tuple": "none",
"XY Input: Seeds++ Batch": "cyan",
"XY Input: Add/Return Noise": "cyan",
"XY Input: Steps": "cyan",
"XY Input: CFG Scale": "cyan",
"XY Input: Sampler/Scheduler": "cyan",
"XY Input: Denoise": "cyan",
"XY Input: VAE": "cyan",
"XY Input: Prompt S/R": "cyan",
"XY Input: Aesthetic Score": "cyan",
"XY Input: Refiner On/Off": "cyan",
"XY Input: Checkpoint": "cyan",
"XY Input: Clip Skip": "cyan",
"XY Input: LoRA": "cyan",
"XY Input: LoRA Plot": "cyan",
"XY Input: LoRA Stacks": "cyan",
"XY Input: Control Net": "cyan",
"XY Input: Control Net Plot": "cyan",
"XY Input: Manual XY Entry": "cyan",
"Manual XY Entry Info": "cyan",
"Join XY Inputs of Same Type": "cyan",
"Image Overlay": "random",
"HighRes-Fix Script": "yellow",
"Tiled Sampling Script": "none",
"Evaluate Integers": "pale_blue",
"Evaluate Floats": "pale_blue",
"Evaluate Strings": "pale_blue",
"Simple Eval Examples": "pale_blue",
};
function shuffleArray(array) {
for (let i = array.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[array[i], array[j]] = [array[j], array[i]]; // Swap elements
}
}
let colorKeys = Object.keys(COLOR_THEMES).filter(key => key !== "none");
shuffleArray(colorKeys); // Shuffle the color themes initially
function setNodeColors(node, theme) {
node.shape = "box";
if(theme.nodeColor && theme.nodeBgColor) {
node.color = theme.nodeColor;
node.bgcolor = theme.nodeBgColor;
}
}
const ext = {
name: "efficiency.appearance",
nodeCreated(node) {
const title = node.getTitle();
if (NODE_COLORS.hasOwnProperty(title)) {
let colorKey = NODE_COLORS[title];
if (colorKey === "random") {
if (colorKeys.length === 0) {
colorKeys = Object.values(COLOR_THEMES).filter(theme => theme.nodeColor && theme.nodeBgColor);
shuffleArray(colorKeys); // Reshuffle when out of colors
}
colorKey = colorKeys.pop();
}
const theme = COLOR_THEMES[colorKey];
setNodeColors(node, theme);
}
}
};
app.registerExtension(ext);

106
js/previewfix.js Normal file
View File

@@ -0,0 +1,106 @@
import { app } from "../../scripts/app.js";
const ext = {
name: "efficiency.previewfix",
ws: null,
maxCount: 0,
currentCount: 0,
sendBlob: false,
startProcessing: false,
lastBlobURL: null,
debug: false,
log(...args) {
if (this.debug) console.log(...args);
},
error(...args) {
if (this.debug) console.error(...args);
},
async sendBlobDataAsDataURL(blobURL) {
const blob = await fetch(blobURL).then(res => res.blob());
const reader = new FileReader();
reader.readAsDataURL(blob);
reader.onloadend = () => this.ws.send(reader.result);
},
handleCommandMessage(data) {
Object.assign(this, {
maxCount: data.maxCount,
sendBlob: data.sendBlob,
startProcessing: data.startProcessing,
currentCount: 0
});
if (!this.startProcessing && this.lastBlobURL) {
this.log("[BlobURLLogger] Revoking last Blob URL:", this.lastBlobURL);
URL.revokeObjectURL(this.lastBlobURL);
this.lastBlobURL = null;
}
},
init() {
this.log("[BlobURLLogger] Initializing...");
this.ws = new WebSocket('ws://127.0.0.1:8288');
this.ws.addEventListener('open', () => this.log('[BlobURLLogger] WebSocket connection opened.'));
this.ws.addEventListener('error', err => this.error('[BlobURLLogger] WebSocket Error:', err));
this.ws.addEventListener('message', (event) => {
try {
const data = JSON.parse(event.data);
if (data.maxCount !== undefined && data.sendBlob !== undefined && data.startProcessing !== undefined) {
this.handleCommandMessage(data);
}
} catch (err) {
this.error('[BlobURLLogger] Error parsing JSON:', err);
}
});
const originalCreateObjectURL = URL.createObjectURL;
URL.createObjectURL = (object) => {
const blobURL = originalCreateObjectURL.call(this, object);
if (blobURL.startsWith('blob:') && this.startProcessing) {
this.log("[BlobURLLogger] Blob URL created:", blobURL);
this.lastBlobURL = blobURL;
if (this.sendBlob && this.currentCount < this.maxCount) {
this.sendBlobDataAsDataURL(blobURL);
}
this.currentCount++;
}
return blobURL;
};
this.log("[BlobURLLogger] Hook attached.");
}
};
function toggleWidgetVisibility(node, widgetName, isVisible) {
const widget = node.widgets.find(w => w.name === widgetName);
if (widget) {
widget.visible = isVisible;
node.setDirtyCanvas(true);
}
}
function handleLoraNameChange(node, loraNameWidget) {
const isNone = loraNameWidget.value === "None";
toggleWidgetVisibility(node, "lora_model_strength", !isNone);
toggleWidgetVisibility(node, "lora_clip_strength", !isNone);
}
app.registerExtension({
...ext,
nodeCreated(node) {
if (node.getTitle() === "Efficient Loader") {
const loraNameWidget = node.widgets.find(w => w.name === "lora_name");
if (loraNameWidget) {
handleLoraNameChange(node, loraNameWidget);
loraNameWidget.onChange = function() {
handleLoraNameChange(node, this);
};
}
}
}
});

141
js/seedcontrol.js Normal file
View File

@@ -0,0 +1,141 @@
import { app } from "../../scripts/app.js";
const LAST_SEED_BUTTON_LABEL = '🎲 Randomize / ♻️ Last Queued Seed';
const NODE_WIDGET_MAP = {
"KSampler (Efficient)": "seed",
"KSampler Adv. (Efficient)": "noise_seed",
"KSampler SDXL (Eff.)": "noise_seed"
};
const SPECIFIC_WIDTH = 325; // Set to desired width
function setNodeWidthForMappedTitles(node) {
if (NODE_WIDGET_MAP[node.getTitle()]) {
node.setSize([SPECIFIC_WIDTH, node.size[1]]);
}
}
class SeedControl {
constructor(node, seedName) {
this.lastSeed = -1;
this.serializedCtx = {};
this.node = node;
this.holdFlag = false; // Flag to track if sampler_state was set to "Hold"
this.usedLastSeedOnHoldRelease = false; // To track if we used the lastSeed after releasing hold
let controlAfterGenerateIndex;
this.samplerStateWidget = this.node.widgets.find(w => w.name === 'sampler_state');
for (const [i, w] of this.node.widgets.entries()) {
if (w.name === seedName) {
this.seedWidget = w;
} else if (w.name === 'control_after_generate') {
controlAfterGenerateIndex = i;
this.node.widgets.splice(i, 1);
}
}
if (!this.seedWidget) {
throw new Error('Something\'s wrong; expected seed widget');
}
this.lastSeedButton = this.node.addWidget("button", LAST_SEED_BUTTON_LABEL, null, () => {
if (this.seedWidget.value != -1) {
this.seedWidget.value = -1;
} else if (this.lastSeed !== -1) {
this.seedWidget.value = this.lastSeed;
}
}, { width: 50, serialize: false });
setNodeWidthForMappedTitles(node);
if (controlAfterGenerateIndex !== undefined) {
const addedWidget = this.node.widgets.pop();
this.node.widgets.splice(controlAfterGenerateIndex, 0, addedWidget);
setNodeWidthForMappedTitles(node);
}
const max = Math.min(1125899906842624, this.seedWidget.options.max);
const min = Math.max(-1125899906842624, this.seedWidget.options.min);
const range = (max - min) / (this.seedWidget.options.step / 10);
this.seedWidget.serializeValue = async (node, index) => {
const currentSeed = this.seedWidget.value;
this.serializedCtx = {
wasRandom: currentSeed == -1,
};
// Check for the state transition and act accordingly.
if (this.samplerStateWidget) {
if (this.samplerStateWidget.value !== "Hold" && this.holdFlag && !this.usedLastSeedOnHoldRelease) {
this.serializedCtx.seedUsed = this.lastSeed;
this.usedLastSeedOnHoldRelease = true;
this.holdFlag = false; // Reset flag for the next cycle
}
}
if (!this.usedLastSeedOnHoldRelease) {
if (this.serializedCtx.wasRandom) {
this.serializedCtx.seedUsed = Math.floor(Math.random() * range) * (this.seedWidget.options.step / 10) + min;
} else {
this.serializedCtx.seedUsed = this.seedWidget.value;
}
}
if (node && node.widgets_values) {
node.widgets_values[index] = this.serializedCtx.seedUsed;
}else{
// Update the last seed value and the button's label to show the current seed value
this.lastSeed = this.serializedCtx.seedUsed;
this.lastSeedButton.name = `🎲 Randomize / ♻️ ${this.lastSeed}`;
}
this.seedWidget.value = this.serializedCtx.seedUsed;
if (this.serializedCtx.wasRandom) {
this.lastSeed = this.serializedCtx.seedUsed;
this.lastSeedButton.name = `🎲 Randomize / ♻️ ${this.lastSeed}`;
if (this.samplerStateWidget.value === "Hold") {
this.holdFlag = true;
}
}
if (this.usedLastSeedOnHoldRelease && this.samplerStateWidget.value !== "Hold") {
// Reset the flag to ensure default behavior is restored
this.usedLastSeedOnHoldRelease = false;
}
return this.serializedCtx.seedUsed;
};
this.seedWidget.afterQueued = () => {
if (this.serializedCtx.wasRandom) {
this.seedWidget.value = -1;
}
// Check if seed has changed to a non -1 value, and if so, update lastSeed
if (this.seedWidget.value !== -1) {
this.lastSeed = this.seedWidget.value;
}
// Update the button's label to show the current last seed value
this.lastSeedButton.name = `🎲 Randomize / ♻️ ${this.lastSeed}`;
this.serializedCtx = {};
};
}
}
app.registerExtension({
name: "efficiency.seedcontrol",
async beforeRegisterNodeDef(nodeType, nodeData, _app) {
if (NODE_WIDGET_MAP[nodeData.name]) {
const onNodeCreated = nodeType.prototype.onNodeCreated;
nodeType.prototype.onNodeCreated = function () {
onNodeCreated ? onNodeCreated.apply(this, []) : undefined;
this.seedControl = new SeedControl(this, NODE_WIDGET_MAP[nodeData.name]);
this.seedControl.seedWidget.value = -1;
};
}
},
});

452
js/widgethider.js Normal file
View File

@@ -0,0 +1,452 @@
import { app } from "/scripts/app.js";
let origProps = {};
const findWidgetByName = (node, name) => {
return node.widgets ? node.widgets.find((w) => w.name === name) : null;
};
const doesInputWithNameExist = (node, name) => {
return node.inputs ? node.inputs.some((input) => input.name === name) : false;
};
function computeNodeSizeBasedOnWidgetCount(node) {
const DEFAULT_BASE_HEIGHT = 40;
const NODE_TITLE_BASE_HEIGHTS = {
"XY Input: LoRA Stacks": 110,
"XY Input: LoRA Plot": 60,
"XY Input: Control Net": 80,
"XY Input: Control Net Plot": 80,
};
const BASE_HEIGHT = NODE_TITLE_BASE_HEIGHTS[node.getTitle()] || DEFAULT_BASE_HEIGHT;
const WIDGET_HEIGHT = 24;
let visibleWidgetCount = 0;
node.widgets.forEach(widget => {
if (widget.type !== "tschide") {
visibleWidgetCount++;
}
});
return [node.size[0], BASE_HEIGHT + (visibleWidgetCount * WIDGET_HEIGHT)];
}
// Toggle Widget + change size
function toggleWidget(node, widget, show = false, suffix = "") {
if (!widget || doesInputWithNameExist(node, widget.name)) return;
if (!origProps[widget.name]) {
origProps[widget.name] = { origType: widget.type, origComputeSize: widget.computeSize };
}
const origSize = node.size;
widget.type = show ? origProps[widget.name].origType : "tschide" + suffix;
widget.computeSize = show ? origProps[widget.name].origComputeSize : () => [0, -4];
const height = show ? Math.max(node.computeSize()[1], origSize[1]) : node.size[1];
node.setSize([node.size[0], height]);
// Compute the new size based on widget count and set it
node.setSize(computeNodeSizeBasedOnWidgetCount(node));
}
// New function to handle widget visibility based on input_mode
function handleInputModeWidgetsVisibility(node, inputModeValue) {
// Utility function to generate widget names up to a certain count
function generateWidgetNames(baseName, count) {
return Array.from({ length: count }, (_, i) => `${baseName}_${i + 1}`);
}
// Common widget groups
const batchWidgets = ["batch_path", "subdirectories", "batch_sort", "batch_max"];
const xbatchWidgets = ["X_batch_path", "X_subdirectories", "X_batch_sort", "X_batch_max"];
const ckptWidgets = [...generateWidgetNames("ckpt_name", 50)];
const clipSkipWidgets = [...generateWidgetNames("clip_skip", 50)];
const vaeNameWidgets = [...generateWidgetNames("vae_name", 50)];
const loraNameWidgets = [...generateWidgetNames("lora_name", 50)];
const loraWtWidgets = [...generateWidgetNames("lora_wt", 50)];
const modelStrWidgets = [...generateWidgetNames("model_str", 50)];
const clipStrWidgets = [...generateWidgetNames("clip_str", 50)];
const xWidgets = ["X_batch_count", "X_first_value", "X_last_value"]
const yWidgets = ["Y_batch_count", "Y_first_value", "Y_last_value"]
const nodeVisibilityMap = {
"LoRA Stacker": {
"simple": [...modelStrWidgets, ...clipStrWidgets],
"advanced": [...loraWtWidgets]
},
"XY Input: Steps": {
"steps": ["first_start_step", "last_start_step", "first_end_step", "last_end_step", "first_refine_step", "last_refine_step"],
"start_at_step": ["first_step", "last_step", "first_end_step", "last_end_step", "first_refine_step", "last_refine_step"],
"end_at_step": ["first_step", "last_step", "first_start_step", "last_start_step", "first_refine_step", "last_refine_step"],
"refine_at_step": ["first_step", "last_step", "first_start_step", "last_start_step", "first_end_step", "last_end_step"]
},
"XY Input: VAE": {
"VAE Names": [...batchWidgets],
"VAE Batch": [...vaeNameWidgets, "vae_count"]
},
"XY Input: Checkpoint": {
"Ckpt Names": [...clipSkipWidgets, ...vaeNameWidgets, ...batchWidgets],
"Ckpt Names+ClipSkip": [...vaeNameWidgets, ...batchWidgets],
"Ckpt Names+ClipSkip+VAE": [...batchWidgets],
"Checkpoint Batch": [...ckptWidgets, ...clipSkipWidgets, ...vaeNameWidgets, "ckpt_count"]
},
"XY Input: LoRA": {
"LoRA Names": [...modelStrWidgets, ...clipStrWidgets, ...batchWidgets],
"LoRA Names+Weights": [...batchWidgets, "model_strength", "clip_strength"],
"LoRA Batch": [...loraNameWidgets, ...modelStrWidgets, ...clipStrWidgets, "lora_count"]
},
"XY Input: LoRA Plot": {
"X: LoRA Batch, Y: LoRA Weight": ["lora_name", "model_strength", "clip_strength", "X_first_value", "X_last_value"],
"X: LoRA Batch, Y: Model Strength": ["lora_name", "model_strength", "model_strength", "X_first_value", "X_last_value"],
"X: LoRA Batch, Y: Clip Strength": ["lora_name", "clip_strength", "X_first_value", "X_last_value"],
"X: Model Strength, Y: Clip Strength": [...xbatchWidgets, "model_strength", "clip_strength"],
},
"XY Input: Control Net": {
"strength": ["first_start_percent", "last_start_percent", "first_end_percent", "last_end_percent", "strength"],
"start_percent": ["first_strength", "last_strength", "first_end_percent", "last_end_percent", "start_percent"],
"end_percent": ["first_strength", "last_strength", "first_start_percent", "last_start_percent", "end_percent"]
},
"XY Input: Control Net Plot": {
"X: Strength, Y: Start%": ["strength", "start_percent"],
"X: Strength, Y: End%": ["strength","end_percent"],
"X: Start%, Y: Strength": ["start_percent", "strength"],
"X: Start%, Y: End%": ["start_percent", "end_percent"],
"X: End%, Y: Strength": ["end_percent", "strength"],
"X: End%, Y: Start%": ["end_percent", "start_percent"],
}
};
const inputModeVisibilityMap = nodeVisibilityMap[node.getTitle()];
if (!inputModeVisibilityMap || !inputModeVisibilityMap[inputModeValue]) return;
// Reset all widgets to visible
for (const key in inputModeVisibilityMap) {
for (const widgetName of inputModeVisibilityMap[key]) {
const widget = findWidgetByName(node, widgetName);
toggleWidget(node, widget, true);
}
}
// Hide the specific widgets for the current input_mode value
for (const widgetName of inputModeVisibilityMap[inputModeValue]) {
const widget = findWidgetByName(node, widgetName);
toggleWidget(node, widget, false);
}
}
// Handle multi-widget visibilities
function handleVisibility(node, countValue, mode) {
const inputModeValue = findWidgetByName(node, "input_mode").value;
const baseNamesMap = {
"LoRA": ["lora_name", "model_str", "clip_str"],
"Checkpoint": ["ckpt_name", "clip_skip", "vae_name"],
"LoRA Stacker": ["lora_name", "model_str", "clip_str", "lora_wt"]
};
const baseNames = baseNamesMap[mode];
const isBatchMode = inputModeValue.includes("Batch");
if (isBatchMode) {
countValue = 0;
}
for (let i = 1; i <= 50; i++) {
const nameWidget = findWidgetByName(node, `${baseNames[0]}_${i}`);
const firstWidget = findWidgetByName(node, `${baseNames[1]}_${i}`);
const secondWidget = findWidgetByName(node, `${baseNames[2]}_${i}`);
const thirdWidget = mode === "LoRA Stacker" ? findWidgetByName(node, `${baseNames[3]}_${i}`) : null;
if (i <= countValue) {
toggleWidget(node, nameWidget, true);
if (mode === "LoRA Stacker") {
if (inputModeValue === "simple") {
toggleWidget(node, firstWidget, false); // model_str
toggleWidget(node, secondWidget, false); // clip_str
toggleWidget(node, thirdWidget, true); // lora_wt
} else if (inputModeValue === "advanced") {
toggleWidget(node, firstWidget, true); // model_str
toggleWidget(node, secondWidget, true); // clip_str
toggleWidget(node, thirdWidget, false); // lora_wt
}
} else if (inputModeValue.includes("Names+Weights") || inputModeValue.includes("+ClipSkip")) {
toggleWidget(node, firstWidget, true);
}
if (!inputModeValue.includes("Names") && mode !== "LoRA Stacker") {
toggleWidget(node, secondWidget, true);
}
} else {
toggleWidget(node, nameWidget, false);
toggleWidget(node, firstWidget, false);
toggleWidget(node, secondWidget, false);
if (thirdWidget) {
toggleWidget(node, thirdWidget, false);
}
}
}
}
// Sampler & Scheduler XY input visibility logic
function handleSamplerSchedulerVisibility(node, countValue, targetParameter) {
for (let i = 1; i <= 50; i++) {
const samplerWidget = findWidgetByName(node, `sampler_${i}`);
const schedulerWidget = findWidgetByName(node, `scheduler_${i}`);
if (i <= countValue) {
if (targetParameter === "sampler") {
toggleWidget(node, samplerWidget, true);
toggleWidget(node, schedulerWidget, false);
} else if (targetParameter === "scheduler") {
toggleWidget(node, samplerWidget, false);
toggleWidget(node, schedulerWidget, true);
} else { // targetParameter is "sampler & scheduler"
toggleWidget(node, samplerWidget, true);
toggleWidget(node, schedulerWidget, true);
}
} else {
toggleWidget(node, samplerWidget, false);
toggleWidget(node, schedulerWidget, false);
}
}
}
// Handle simple widget visibility based on a count
function handleWidgetVisibility(node, thresholdValue, widgetNamePrefix, maxCount) {
for (let i = 1; i <= maxCount; i++) {
const widget = findWidgetByName(node, `${widgetNamePrefix}${i}`);
if (widget) {
toggleWidget(node, widget, i <= thresholdValue);
}
}
}
// Disable the 'Ckpt Name+ClipSkip+VAE' option if 'target_ckpt' is "Refiner"
let last_ckpt_input_mode;
let last_target_ckpt;
function xyCkptRefinerOptionsRemove(widget, node) {
let target_ckpt = findWidgetByName(node, "target_ckpt").value
let input_mode = widget.value
if ((input_mode === "Ckpt Names+ClipSkip+VAE") && (target_ckpt === "Refiner")) {
if (last_ckpt_input_mode === "Ckpt Names+ClipSkip") {
if (last_target_ckpt === "Refiner"){
widget.value = "Checkpoint Batch";
} else {widget.value = "Ckpt Names+ClipSkip";}
} else if (last_ckpt_input_mode === "Checkpoint Batch") {
if (last_target_ckpt === "Refiner"){
widget.value = "Ckpt Names+ClipSkip";
} else {widget.value = "Checkpoint Batch";}
} else if (last_ckpt_input_mode !== 'undefined') {
widget.value = last_ckpt_input_mode;
} else {
widget.value = "Ckpt Names";
}
} else if (input_mode !== "Ckpt Names+ClipSkip+VAE"){
last_ckpt_input_mode = input_mode;
}
last_target_ckpt = target_ckpt
}
// Create a map of node titles to their respective widget handlers
const nodeWidgetHandlers = {
"Efficient Loader": {
'lora_name': handleEfficientLoaderLoraName
},
"Eff. Loader SDXL": {
'refiner_ckpt_name': handleEffLoaderSDXLRefinerCkptName
},
"LoRA Stacker": {
'input_mode': handleLoRAStackerInputMode,
'lora_count': handleLoRAStackerLoraCount
},
"XY Input: Steps": {
'target_parameter': handleXYInputStepsTargetParameter
},
"XY Input: Sampler/Scheduler": {
'target_parameter': handleXYInputSamplerSchedulerTargetParameter,
'input_count': handleXYInputSamplerSchedulerInputCount
},
"XY Input: VAE": {
'input_mode': handleXYInputVAEInputMode,
'vae_count': handleXYInputVAEVaeCount
},
"XY Input: Prompt S/R": {
'replace_count': handleXYInputPromptSRReplaceCount
},
"XY Input: Checkpoint": {
'input_mode': handleXYInputCheckpointInputMode,
'ckpt_count': handleXYInputCheckpointCkptCount,
'target_ckpt': handleXYInputCheckpointTargetCkpt
},
"XY Input: LoRA": {
'input_mode': handleXYInputLoRAInputMode,
'lora_count': handleXYInputLoRALoraCount
},
"XY Input: LoRA Plot": {
'input_mode': handleXYInputLoRAPlotInputMode
},
"XY Input: LoRA Stacks": {
'node_state': handleXYInputLoRAStacksNodeState
},
"XY Input: Control Net": {
'target_parameter': handleXYInputControlNetTargetParameter
},
"XY Input: Control Net Plot": {
'plot_type': handleXYInputControlNetPlotPlotType
}
};
// In the main function where widgetLogic is called
function widgetLogic(node, widget) {
// Retrieve the handler for the current node title and widget name
const handler = nodeWidgetHandlers[node.getTitle()]?.[widget.name];
if (handler) {
handler(node, widget);
}
}
// Efficient Loader Handlers
function handleEfficientLoaderLoraName(node, widget) {
const action = widget.value === 'None' ? toggleWidget : (node, widget) => toggleWidget(node, widget, true);
['lora_model_strength', 'lora_clip_strength'].forEach(wName => {
action(node, findWidgetByName(node, wName));
});
}
// Eff. Loader SDXL Handlers
function handleEffLoaderSDXLRefinerCkptName(node, widget) {
const action = widget.value === 'None' ? toggleWidget : (node, widget) => toggleWidget(node, widget, true);
['refiner_clip_skip', 'positive_ascore', 'negative_ascore'].forEach(wName => {
action(node, findWidgetByName(node, wName));
});
}
// LoRA Stacker Handlers
function handleLoRAStackerInputMode(node, widget) {
handleInputModeWidgetsVisibility(node, widget.value);
handleVisibility(node, findWidgetByName(node, "lora_count").value, "LoRA Stacker");
}
function handleLoRAStackerLoraCount(node, widget) {
handleVisibility(node, widget.value, "LoRA Stacker");
}
// XY Input: Steps Handlers
function handleXYInputStepsTargetParameter(node, widget) {
handleInputModeWidgetsVisibility(node, widget.value);
}
// XY Input: Sampler/Scheduler Handlers
function handleXYInputSamplerSchedulerTargetParameter(node, widget) {
handleSamplerSchedulerVisibility(node, findWidgetByName(node, 'input_count').value, widget.value);
}
function handleXYInputSamplerSchedulerInputCount(node, widget) {
handleSamplerSchedulerVisibility(node, widget.value, findWidgetByName(node, 'target_parameter').value);
}
// XY Input: VAE Handlers
function handleXYInputVAEInputMode(node, widget) {
handleInputModeWidgetsVisibility(node, widget.value);
if (widget.value === "VAE Names") {
handleWidgetVisibility(node, findWidgetByName(node, "vae_count").value, "vae_name_", 50);
} else {
handleWidgetVisibility(node, 0, "vae_name_", 50);
}
}
function handleXYInputVAEVaeCount(node, widget) {
if (findWidgetByName(node, "input_mode").value === "VAE Names") {
handleWidgetVisibility(node, widget.value, "vae_name_", 50);
}
}
// XY Input: Prompt S/R Handlers
function handleXYInputPromptSRReplaceCount(node, widget) {
handleWidgetVisibility(node, widget.value, "replace_", 49);
}
// XY Input: Checkpoint Handlers
function handleXYInputCheckpointInputMode(node, widget) {
xyCkptRefinerOptionsRemove(widget, node);
handleInputModeWidgetsVisibility(node, widget.value);
handleVisibility(node, findWidgetByName(node, "ckpt_count").value, "Checkpoint");
}
function handleXYInputCheckpointCkptCount(node, widget) {
handleVisibility(node, widget.value, "Checkpoint");
}
function handleXYInputCheckpointTargetCkpt(node, widget) {
xyCkptRefinerOptionsRemove(findWidgetByName(node, "input_mode"), node);
}
// XY Input: LoRA Handlers
function handleXYInputLoRAInputMode(node, widget) {
handleInputModeWidgetsVisibility(node, widget.value);
handleVisibility(node, findWidgetByName(node, "lora_count").value, "LoRA");
}
function handleXYInputLoRALoraCount(node, widget) {
handleVisibility(node, widget.value, "LoRA");
}
// XY Input: LoRA Plot Handlers
function handleXYInputLoRAPlotInputMode(node, widget) {
handleInputModeWidgetsVisibility(node, widget.value);
}
// XY Input: LoRA Stacks Handlers
function handleXYInputLoRAStacksNodeState(node, widget) {
toggleWidget(node, findWidgetByName(node, "node_state"), false);
}
// XY Input: Control Net Handlers
function handleXYInputControlNetTargetParameter(node, widget) {
handleInputModeWidgetsVisibility(node, widget.value);
}
// XY Input: Control Net Plot Handlers
function handleXYInputControlNetPlotPlotType(node, widget) {
handleInputModeWidgetsVisibility(node, widget.value);
}
app.registerExtension({
name: "efficiency.widgethider",
nodeCreated(node) {
for (const w of node.widgets || []) {
let widgetValue = w.value;
// Store the original descriptor if it exists
let originalDescriptor = Object.getOwnPropertyDescriptor(w, 'value');
widgetLogic(node, w);
Object.defineProperty(w, 'value', {
get() {
// If there's an original getter, use it. Otherwise, return widgetValue.
let valueToReturn = originalDescriptor && originalDescriptor.get
? originalDescriptor.get.call(w)
: widgetValue;
return valueToReturn;
},
set(newVal) {
// If there's an original setter, use it. Otherwise, set widgetValue.
if (originalDescriptor && originalDescriptor.set) {
originalDescriptor.set.call(w, newVal);
} else {
widgetValue = newVal;
}
widgetLogic(node, w);
}
});
}
}
});