const enableCheckerInit = () => { function isDarkColor(color) { if (color.length === 0) { return false; } let r; let g; let b; if (color.startsWith("#")) { [r, g, b] = color .substring(1) .match(/.{2}/g) .map((c) => Number(`0x${c}`)); } else if (color.startsWith("rgb")) { [r, g, b] = color.match(/\d+/g).map(Number); } else { const tempElem = document.createElement("div"); tempElem.style.color = color; document.body.appendChild(tempElem); [r, g, b] = window.getComputedStyle(tempElem).color.match(/\d+/g).map(Number); document.body.removeChild(tempElem); } const brightness = (r * 299 + g * 587 + b * 114) / 1000; return brightness < 128; } class Setting { constructor() { this.enable_checker_activate_dropdown_check = opts.enable_checker_activate_dropdown_check; this.enable_checker_activate_weight_check = opts.enable_checker_activate_weight_check; this.enable_checker_activate_extra_network_check = opts.enable_checker_activate_extra_network_check; this.enable_checker_check_version_compatibility = opts.enable_checker_check_version_compatibility; this.loras = null; if (opts?.enable_checker_custom_color) { this.color_enable = opts.enable_checker_custom_color_enable; this.color_disable = opts.enable_checker_custom_color_disable; this.color_dropdown_enable = opts.enable_checker_custom_color_dropdown_enable; this.color_dropdown_disable = opts.enable_checker_custom_color_dropdown_disable; this.custom_color_zero_weihgt = opts.enable_checker_custom_color_zero_weihgt; this.color_invalid_additional_networks = opts.enable_checker_custom_color_invalid_additional_networks; } else { if (isDarkColor(document.body.style.backgroundColor)) { this.color_enable = "#237366"; this.color_disable = "#5a5757"; this.color_dropdown_enable = "#233873"; } else { this.color_enable = "skyblue"; this.color_disable = "#aeaeae"; // light grey this.color_dropdown_enable = "#a4f8f1"; // light green } this.color_dropdown_disable = this.color_disable; this.custom_color_zero_weihgt = this.color_disable; this.color_invalid_additional_networks = "#ed9797"; } this.componentId2componentIndex = {}; for (let index = 0; index < window.gradio_config.components.length; index++) { this.componentId2componentIndex[window.gradio_config.components[index].id] = index; const elem_id = window.gradio_config.components[index]?.props?.elem_id; if (elem_id) { this.componentId2componentIndex[elem_id] = index; } } } getComponent(id) { let target = id; if (id.startsWith("component-")) { target = Number(id.replace(/^component-/, "")); } return window.gradio_config.components[this.componentId2componentIndex[target]]; } } let setting = null; function get_script_area(suffix) { for (const name of ["img2img", "txt2img"]) { const tab = gradioApp().getElementById(`tab_${name}`); if (tab && tab.style.display !== "none") { const area = gradioApp().getElementById(`${name}${suffix}`); return area; } } return null; } function get_enable_span(component) { const spans = component.querySelectorAll("span"); for (let k = 0; k < spans.length; k++) { const span = spans[k]; const text = span.innerText.toLowerCase(); if ( text.startsWith("enable") || text.endsWith("enabled") || text === "active" || text === "啟用" || text === "启用" || text === "Share attention in batch".toLowerCase() // sd-webui-forge ) { return span; } } } function get_sibling_checkbox_status(node) { const snodes = node.parentNode.childNodes; for (let k = 0; k < snodes.length; k++) { const snode = snodes[k]; if (snode.nodeName === "INPUT") { return snode.checked; } } return false; } function change_bg(header, is_active) { if (is_active) { header.style.backgroundColor = setting.color_enable; } else { header.style.backgroundColor = setting.color_disable; } } function operate_controlnet_component(controlnet_parts) { let found_active_tab = false; const accordions = controlnet_parts.querySelectorAll( "#txt2img_controlnet_accordions .input-accordion,#img2img_controlnet_accordions .input-accordion", ); if (accordions.length > 0) { // WebUI Forge for (let k = 0; k < accordions.length; k++) { const accordion = accordions[k]; const accordion_header = accordion.querySelector("div.label-wrap"); const enable_span = accordion.querySelector("input[type=checkbox]"); const is_active = enable_span.checked; change_bg(accordion_header, is_active); found_active_tab = found_active_tab || is_active; } return found_active_tab; } const divs = controlnet_parts.querySelector(".tabs").querySelectorAll(":scope>div"); if (divs === undefined || divs.length < 1) { return null; } const tabs = controlnet_parts.querySelectorAll(".tab-nav")[0].querySelectorAll("button"); if (tabs.length === 0) { return null; } for (let k = 1; k < divs.length; k++) { const enable_span = get_enable_span(divs[k]); const is_active = get_sibling_checkbox_status(enable_span); change_bg(tabs[k - 1], is_active); found_active_tab = found_active_tab || is_active; } return found_active_tab; } function get_component_header(component) { return component.querySelector("div.label-wrap"); } function operate_value_input(component) { if (!setting.enable_checker_activate_weight_check) { return; } const labels = component.querySelectorAll("label"); for (let k = 0; k < labels.length; k++) { const labeldom = labels[k]; const label_text = labeldom.querySelector("span")?.innerText; if (!label_text || !label_text.toLowerCase().includes("weight")) { continue; } const input = labeldom.parentNode.querySelector("input"); if (!input) { continue; } if (input.value === 0) { input.style.backgroundColor = setting.custom_color_zero_weihgt; } else { input.style.backgroundColor = ""; } } } function is_none(str) { return str.toLowerCase() === "none" || str.toLowerCase() === "nothing"; } function is_target_dropdown(component) { let root = component; while (root && !root.id) { root = root.parentNode; } if (!root) { return true; } const info = setting.getComponent(root.id); if (info?.props?.choices) { if (info.props.choices.length <= 1) { return false; } const hasNoneOrNothing = info.props.choices.some((str) => { return is_none(str); }); return hasNoneOrNothing; } return true; } function operate_dropdown(component) { if (!setting.enable_checker_activate_dropdown_check) { return; } const inners = component.querySelectorAll("[class*=wrap-inner]"); for (let k = 0; k < inners.length; k++) { const inner = inners[k]; const ddom = inner.querySelector("input"); if (!is_target_dropdown(ddom)) { continue; } if (is_none(ddom.value)) { inner.style.backgroundColor = setting.color_dropdown_disable; } else { inner.style.backgroundColor = setting.color_dropdown_enable; } } } function operate_component_in_script_container(component) { operate_dropdown(component); operate_value_input(component); const header = get_component_header(component); if (!header) { return; } // check modules.ui_components.InputAccordion let is_active = false; const checkbox = header.querySelector("input[type=checkbox]"); if (checkbox) { is_active = checkbox.checked; change_bg(header, is_active); return; } const enable_span = get_enable_span(component); if (!enable_span) { return; } const controlnet_parts = component.querySelector("#controlnet"); if (controlnet_parts) { is_active = operate_controlnet_component(controlnet_parts); //no tab (single ControlNet) if (is_active === null) { is_active = get_sibling_checkbox_status(enable_span); } } else { is_active = get_sibling_checkbox_status(enable_span); } change_bg(header, is_active); } function operate_component_in_accordion(component) { const header = get_component_header(component); const checkbox = header.querySelector("input[type=checkbox]"); let is_active = checkbox.checked; if (is_active && header.innerText.split("\n")[0] === "Refiner") { const labels = component.querySelectorAll("label"); for (let j = 0; j < labels.length; j++) { const label = labels[j]; const text = label.querySelector(":scope>span").innerText; if (text === "Checkpoint") { const model = label.querySelector("input"); if (model.value === "") { is_active = false; break; } } else if (text === "Switch at") { const input = component.querySelector('input[type="number"]'); if (input.value === 1) { is_active = false; break; } } } } change_bg(header, is_active); } function fix_seed(ev) { let target; if (!ev.composed) { target = ev.target; } else { target = ev.composedPath()[0]; } if (target?.tagName?.toLowerCase() !== "a" || target?.innerText !== "Generate forever") { return; } function get_active_tab() { for (const name of ["img2img", "txt2img"]) { const tab = gradioApp().getElementById(`tab_${name}`); if (tab && tab.style.display !== "none") { return name; } } return null; } const active_tab = get_active_tab(); if (active_tab === null) { return; } const seed_input = gradioApp().getElementById(`${active_tab}_seed`).querySelector("input"); seed_input.value = -1; updateInput(seed_input); } function main_enable_checker(ev) { if (Object.keys(opts).length === 0) { // not ready return; } if (opts.enable_checker_fix_forever_randomly_seed) { fix_seed(ev); } if (!setting) { setting = new Setting(); if (setting.enable_checker_check_version_compatibility) { const ok = check_version_for_enable_checker(); if (!ok) { return; } } } const area_acd = get_script_area("_accordions"); if (area_acd && opts !== undefined) { const components = area_acd.querySelectorAll(":scope>div.input-accordion"); for (let j = 0; j < components.length; j++) { const component = components[j]; operate_component_in_accordion(component); } } const area_sc = get_script_area("_script_container"); if (area_sc && opts !== undefined) { const components = area_sc.querySelectorAll(":scope>div>div"); for (let j = 0; j < components.length; j++) { const component = components[j]; operate_component_in_script_container(component); } } } function init_network_checker(tabname, force) { if (setting === null || !setting?.enable_checker_activate_extra_network_check) { return; } if (!force && setting.loras !== null) { return; } const reload = async () => { const name_doms = gradioApp().getElementById(`${tabname}_lora_cards`).querySelectorAll(".name"); setting.loras = []; for (let j = 0; j < name_doms.length; j++) { setting.loras.push(name_doms[j].innerText); } }; setTimeout(async () => { await reload(); }, 1000); } function main_network_checker(prefix) { if (setting === null || !setting?.enable_checker_activate_extra_network_check) { return; } const dom = gradioApp().querySelector(`#${prefix} > label > textarea`); const log_dom_id = `${prefix}_error_log`; let log_dom = gradioApp().getElementById(log_dom_id); if (!log_dom) { log_dom = document.createElement("div"); log_dom.id = log_dom_id; dom.parentElement.parentElement.appendChild(log_dom); } const regex = /]+>/g; const matches = dom.value.matchAll(regex); const target_lora_names = Array.from(matches, (m) => m[1]); const notIncluded = target_lora_names.filter((item) => !setting.loras.includes(item)); if (notIncluded.length === 0) { dom.style.background = ""; log_dom.innerText = ""; return; } dom.style.background = setting.color_invalid_additional_networks; log_dom.innerText = `Not found LoRA: ${notIncluded.join(", ")}`; } function check_version_for_enable_checker() { const versions_str = document.getElementsByClassName("versions")[0].innerText; const items = versions_str.split(" "); if (items.length >= 2 && items[0] === "version:") { const vers = items[1].split("."); let err = false; if (vers.length < 2) { err = true; } else { // Support >= v1.7.0 for sd-webui if (vers[0].startsWith("v")) { const v0 = Number(vers[0].substring(1)); if (v0 < 1 || (v0 === 1 && Number(vers[1]) < 7)) { err = true; } } else if (vers[0].startsWith("f")) { // Support >= v0.0.11 for sd-webui-forge const v2 = Number(vers[2].split("-")[0]); if (v2 < 11) { err = true; } } else { err = true; } } if (err) { const msg = `Unexpected version (${vers}) for sd-webui-enable-checker. Please try install the latest WebUI and this extension.\n\n[Hint] You can disable this version check by removing the checkmark of "Check version compatibility" in "Enable Checker" setting of the "Setting" tab.`; alert(msg); console.log(msg); return false; } } return true; } function onui_enable_checker() { for (const tabname of ["txt2img", "img2img"]) { gradioApp() .querySelector(`#${tabname}_extra_refresh,#${tabname}_lora_extra_refresh_internal`) .addEventListener("click", () => { init_network_checker(tabname, true); }); for (const target_prompt of ["prompt", "neg_prompt"]) { const prefix = `${tabname}_${target_prompt}`; const textarea = gradioApp().querySelector(`#${prefix} > label > textarea`); textarea.addEventListener("input", () => { init_network_checker(tabname, false); main_network_checker(prefix); }); } } } return [main_enable_checker, init_network_checker, main_network_checker, onui_enable_checker]; }; const init_enableChecker = enableCheckerInit(); const main_enable_checker = init_enableChecker[0]; const init_network_checker = init_enableChecker[1]; const main_network_checker = init_enableChecker[2]; const onui_enable_checker = init_enableChecker[3]; gradioApp().addEventListener("click", (ev) => { main_enable_checker(ev); }); gradioApp().addEventListener("change", (ev) => { main_enable_checker(ev); }); onUiUpdate((ev) => { main_enable_checker(ev); }); onUiLoaded(() => { onui_enable_checker(); });