mirror of
https://github.com/DominikDoom/a1111-sd-webui-tagcomplete.git
synced 2026-01-30 13:09:56 +00:00
219 lines
8.6 KiB
JavaScript
219 lines
8.6 KiB
JavaScript
// Utility functions to select text areas the script should work on,
|
|
// including third party options.
|
|
|
|
TAC.TextAreas = new (function () {
|
|
// Core text area selectors
|
|
const core = [
|
|
"#txt2img_prompt > label > textarea",
|
|
"#img2img_prompt > label > textarea",
|
|
"#txt2img_neg_prompt > label > textarea",
|
|
"#img2img_neg_prompt > label > textarea",
|
|
".prompt > label > textarea",
|
|
"#txt2img_edit_style_prompt > label > textarea",
|
|
"#txt2img_edit_style_neg_prompt > label > textarea",
|
|
"#img2img_edit_style_prompt > label > textarea",
|
|
"#img2img_edit_style_neg_prompt > label > textarea",
|
|
];
|
|
|
|
// Third party text area selectors
|
|
const thirdParty = {
|
|
"dataset-tag-editor": {
|
|
base: "#tab_dataset_tag_editor_interface",
|
|
hasIds: false,
|
|
selectors: [
|
|
"Caption of Selected Image",
|
|
"Interrogate Result",
|
|
"Edit Caption",
|
|
"Edit Tags",
|
|
],
|
|
},
|
|
"image browser": {
|
|
base: "#tab_image_browser",
|
|
hasIds: false,
|
|
selectors: ["Filename keyword search", "EXIF keyword search"],
|
|
},
|
|
tab_tagger: {
|
|
base: "#tab_tagger",
|
|
hasIds: false,
|
|
selectors: ["Additional tags (split by comma)", "Exclude tags (split by comma)"],
|
|
},
|
|
"tiled-diffusion-t2i": {
|
|
base: "#txt2img_script_container",
|
|
hasIds: true,
|
|
onDemand: true,
|
|
selectors: [
|
|
"[id^=MD-t2i][id$=prompt] textarea",
|
|
"[id^=MD-t2i][id$=prompt] input[type='text']",
|
|
],
|
|
},
|
|
"tiled-diffusion-i2i": {
|
|
base: "#img2img_script_container",
|
|
hasIds: true,
|
|
onDemand: true,
|
|
selectors: [
|
|
"[id^=MD-i2i][id$=prompt] textarea",
|
|
"[id^=MD-i2i][id$=prompt] input[type='text']",
|
|
],
|
|
},
|
|
"adetailer-t2i": {
|
|
base: "#txt2img_script_container",
|
|
hasIds: true,
|
|
onDemand: true,
|
|
selectors: [
|
|
"[id^=script_txt2img_adetailer_ad_prompt] textarea",
|
|
"[id^=script_txt2img_adetailer_ad_negative_prompt] textarea",
|
|
],
|
|
},
|
|
"adetailer-i2i": {
|
|
base: "#img2img_script_container",
|
|
hasIds: true,
|
|
onDemand: true,
|
|
selectors: [
|
|
"[id^=script_img2img_adetailer_ad_prompt] textarea",
|
|
"[id^=script_img2img_adetailer_ad_negative_prompt] textarea",
|
|
],
|
|
},
|
|
"deepdanbooru-object-recognition": {
|
|
base: "#tab_deepdanboru_object_recg_tab",
|
|
hasIds: false,
|
|
selectors: ["Found tags"],
|
|
},
|
|
TIPO: {
|
|
base: "#tab_txt2img",
|
|
hasIds: false,
|
|
selectors: ["Tag Prompt"],
|
|
},
|
|
};
|
|
|
|
this.getTextAreas = function () {
|
|
// First get all core text areas
|
|
let textAreas = [...gradioApp().querySelectorAll(core.join(", "))];
|
|
|
|
for (const [key, entry] of Object.entries(thirdParty)) {
|
|
if (entry.hasIds) {
|
|
// If the entry has proper ids, we can just select them
|
|
textAreas = textAreas.concat([
|
|
...gradioApp().querySelectorAll(entry.selectors.join(", ")),
|
|
]);
|
|
} else {
|
|
// Otherwise, we have to find the text areas by their adjacent labels
|
|
let base = gradioApp().querySelector(entry.base);
|
|
|
|
// Safety check
|
|
if (!base) continue;
|
|
|
|
let allTextAreas = [...base.querySelectorAll("textarea, input[type='text']")];
|
|
|
|
// Filter the text areas where the adjacent label matches one of the selectors
|
|
let matchingTextAreas = allTextAreas.filter((ta) =>
|
|
[...ta.parentElement.childNodes].some((x) =>
|
|
entry.selectors.includes(x.innerText)
|
|
)
|
|
);
|
|
textAreas = textAreas.concat(matchingTextAreas);
|
|
}
|
|
}
|
|
|
|
return textAreas;
|
|
}
|
|
|
|
this.addOnDemandObservers = function (setupFunction) {
|
|
for (const [key, entry] of Object.entries(thirdParty)) {
|
|
if (!entry.onDemand) continue;
|
|
|
|
let base = gradioApp().querySelector(entry.base);
|
|
if (!base) continue;
|
|
|
|
let accordions = [...base?.querySelectorAll(".gradio-accordion")];
|
|
if (!accordions) continue;
|
|
|
|
accordions.forEach((acc) => {
|
|
let accObserver = new MutationObserver((mutationList, observer) => {
|
|
for (const mutation of mutationList) {
|
|
if (mutation.type === "childList") {
|
|
let newChildren = mutation.addedNodes;
|
|
if (!newChildren) {
|
|
accObserver.disconnect();
|
|
continue;
|
|
}
|
|
|
|
newChildren.forEach((child) => {
|
|
if (
|
|
child.classList.contains("gradio-accordion") ||
|
|
child.querySelector(".gradio-accordion")
|
|
) {
|
|
let newAccordions = [
|
|
...child.querySelectorAll(".gradio-accordion"),
|
|
];
|
|
newAccordions.forEach((nAcc) =>
|
|
accObserver.observe(nAcc, { childList: true })
|
|
);
|
|
}
|
|
});
|
|
|
|
if (entry.hasIds) {
|
|
// If the entry has proper ids, we can just select them
|
|
[
|
|
...gradioApp().querySelectorAll(entry.selectors.join(", ")),
|
|
].forEach((x) => setupFunction(x));
|
|
} else {
|
|
// Otherwise, we have to find the text areas by their adjacent labels
|
|
let base = gradioApp().querySelector(entry.base);
|
|
|
|
// Safety check
|
|
if (!base) continue;
|
|
|
|
let allTextAreas = [
|
|
...base.querySelectorAll("textarea, input[type='text']"),
|
|
];
|
|
|
|
// Filter the text areas where the adjacent label matches one of the selectors
|
|
let matchingTextAreas = allTextAreas.filter((ta) =>
|
|
[...ta.parentElement.childNodes].some((x) =>
|
|
entry.selectors.includes(x.innerText)
|
|
)
|
|
);
|
|
matchingTextAreas.forEach((x) => setupFunction(x));
|
|
}
|
|
}
|
|
}
|
|
});
|
|
accObserver.observe(acc, { childList: true });
|
|
});
|
|
}
|
|
}
|
|
|
|
const thirdPartyIdSet = new Set();
|
|
// Get the identifier for the text area to differentiate between positive and negative
|
|
this.getTextAreaIdentifier = function (textArea) {
|
|
let txt2img_p = gradioApp().querySelector("#txt2img_prompt > label > textarea");
|
|
let txt2img_n = gradioApp().querySelector("#txt2img_neg_prompt > label > textarea");
|
|
let img2img_p = gradioApp().querySelector("#img2img_prompt > label > textarea");
|
|
let img2img_n = gradioApp().querySelector("#img2img_neg_prompt > label > textarea");
|
|
|
|
let modifier = "";
|
|
switch (textArea) {
|
|
case txt2img_p:
|
|
modifier = ".txt2img.p";
|
|
break;
|
|
case txt2img_n:
|
|
modifier = ".txt2img.n";
|
|
break;
|
|
case img2img_p:
|
|
modifier = ".img2img.p";
|
|
break;
|
|
case img2img_n:
|
|
modifier = ".img2img.n";
|
|
break;
|
|
default:
|
|
// If the text area is not a core text area, it must be a third party text area
|
|
// Add it to the set of third party text areas and get its index as a unique identifier
|
|
if (!thirdPartyIdSet.has(textArea)) thirdPartyIdSet.add(textArea);
|
|
|
|
modifier = `.thirdParty.ta${[...thirdPartyIdSet].indexOf(textArea)}`;
|
|
break;
|
|
}
|
|
return modifier;
|
|
}
|
|
})();
|