|
|
|
|
|
|
|
|
|
|
|
class TabsExtensionParser { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static #cloneCheckbox(enabled) { |
|
|
const base = document.getElementById("TABSEX_CHECKBOX"); |
|
|
if (!base) return null; |
|
|
|
|
|
const label = base.querySelector('label')?.cloneNode(true); |
|
|
if (!label) return null; |
|
|
|
|
|
label.style.margin = "1em 0em"; |
|
|
label.checkbox = label.querySelector("input"); |
|
|
if (label.checkbox) label.checkbox.checked = !!enabled; |
|
|
return label; |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static #sanitizeExtensionName(name) { |
|
|
if (typeof name !== 'string' || name.trim().length === 0) return null; |
|
|
const version_pattern = /([Vv](?:er)?[\.\s]*\d)/; |
|
|
return name.split(version_pattern)[0].trim(); |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static #parseObject(node, keep) { |
|
|
if (!node) return [null, null]; |
|
|
|
|
|
|
|
|
if (node.classList.contains("form")) { |
|
|
const scripts = node.querySelector(".gradio-dropdown"); |
|
|
if (!scripts) return [null, null]; |
|
|
|
|
|
const script_block = document.createElement("div"); |
|
|
script_block.style.display = 'none'; |
|
|
scripts.style.margin = '10px 0px'; |
|
|
script_block.appendChild(scripts); |
|
|
|
|
|
script_block.setAttribute("ext-label", "Scripts"); |
|
|
|
|
|
node.style.display = "none"; |
|
|
return ["Scripts", script_block]; |
|
|
} |
|
|
|
|
|
const styler = node.querySelector(".styler"); |
|
|
if (!styler) return [null, null]; |
|
|
|
|
|
const accordion = node.querySelector(".gradio-accordion"); |
|
|
if (!accordion) return [null, null]; |
|
|
|
|
|
const isInput = accordion.classList.contains("input-accordion"); |
|
|
|
|
|
const displayName = accordion.querySelector(".label-wrap>span")?.textContent; |
|
|
if (!displayName) return [null, null]; |
|
|
|
|
|
const extensionName = this.#sanitizeExtensionName(displayName); |
|
|
if (!extensionName || keep.includes(extensionName)) return [null, null]; |
|
|
|
|
|
const contents = [...accordion.children].filter( |
|
|
(div) => !div.classList.contains("hide") |
|
|
&& !div.classList.contains("label-wrap") |
|
|
&& div.children.length > 0 |
|
|
); |
|
|
|
|
|
if (contents.length === 0) return [null, null]; |
|
|
|
|
|
const content = contents[0]; |
|
|
|
|
|
if (isInput) { |
|
|
const checkbox = accordion.querySelector(".input-accordion-checkbox"); |
|
|
const dummy = this.#cloneCheckbox(checkbox?.checked ?? false); |
|
|
|
|
|
|
|
|
if (dummy && dummy.checkbox && checkbox) { |
|
|
dummy.checkbox.onchange = () => { |
|
|
if (checkbox.checked !== dummy.checkbox.checked) checkbox.click(); |
|
|
}; |
|
|
checkbox.onchange = () => { |
|
|
if (checkbox.checked !== dummy.checkbox.checked) dummy.checkbox.click(); |
|
|
}; |
|
|
content.insertBefore(dummy, content.firstElementChild); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
node.style.display = "none"; |
|
|
|
|
|
|
|
|
if (accordion.id && !accordion.id.startsWith("component-")) { |
|
|
content.id = accordion.id; |
|
|
accordion.id = `moved-${accordion.id}`; |
|
|
|
|
|
if (isInput) { |
|
|
|
|
|
content.visibleCheckbox = { checked: null }; |
|
|
content.onVisibleCheckboxChange = () => {}; |
|
|
} |
|
|
} |
|
|
|
|
|
content.setAttribute("ext-label", displayName); |
|
|
return [extensionName, content]; |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static #extra_options(mode) { |
|
|
const extra_options = document.getElementById(`extra_options_${mode}2img`); |
|
|
if (!extra_options || !extra_options.classList.contains("gradio-accordion")) |
|
|
return [null, null]; |
|
|
|
|
|
const styler = extra_options.parentElement; |
|
|
if (styler) styler.style.display = "none"; |
|
|
|
|
|
const contents = [...extra_options.children].filter( |
|
|
(div) => !div.classList.contains("hide") |
|
|
&& !div.classList.contains("label-wrap") |
|
|
&& div.children.length > 0 |
|
|
); |
|
|
if (contents.length === 0) return [null, null]; |
|
|
|
|
|
const content = contents[0]; |
|
|
content.setAttribute("ext-label", "Extra Options"); |
|
|
return ["Extra Options", content]; |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static parse(mode, keep) { |
|
|
const validExtensions = {}; |
|
|
|
|
|
const container = document.getElementById(`${mode}2img_script_container`); |
|
|
const styler = container?.querySelector(".styler"); |
|
|
if (!container || !styler) return validExtensions; |
|
|
|
|
|
const children = Array.from(styler.children); |
|
|
let foundScripts = false; |
|
|
|
|
|
|
|
|
for (const node of children) { |
|
|
|
|
|
if (foundScripts && node.classList.contains("form")) { |
|
|
node.style.display = "none"; |
|
|
continue; |
|
|
} |
|
|
const [name, content] = this.#parseObject(node, keep); |
|
|
if (name && content) validExtensions[name] = content; |
|
|
if (name === "Scripts") foundScripts = true; |
|
|
} |
|
|
|
|
|
const [extra, options] = this.#extra_options(mode); |
|
|
if (extra && options) validExtensions[extra] = options; |
|
|
|
|
|
return validExtensions; |
|
|
} |
|
|
} |
|
|
|