mirror of
https://github.com/DominikDoom/a1111-sd-webui-tagcomplete.git
synced 2026-01-26 11:09:54 +00:00
Move CFG to top level for shorter access, add hacky jsdoc typedef
This commit is contained in:
@@ -1,94 +1,142 @@
|
||||
// Create our TAC namespace
|
||||
var TAC = TAC || {};
|
||||
|
||||
/**
|
||||
* @typedef {Object} TAC.CFG
|
||||
* @property {string} tagFile - Tag filename
|
||||
* @property {{ global: boolean, txt2img: boolean, img2img: boolean, negativePrompts: boolean, thirdParty: boolean, modelList: string, modelListMode: "Blacklist"|"Whitelist" }} activeIn - Settings for which parts of the UI the tag completion is active in.
|
||||
* @property {boolean} slidingPopup - Move completion popup together with text cursor
|
||||
* @property {number} maxResults - Maximum results
|
||||
* @property {boolean} showAllResults - Show all results
|
||||
* @property {number} resultStepLength - How many results to load at once
|
||||
* @property {number} delayTime - Time in ms to wait before triggering completion again
|
||||
* @property {boolean} useWildcards - Search for wildcards
|
||||
* @property {boolean} sortWildcardResults - Sort wildcard file contents alphabetically
|
||||
* @property {boolean} useEmbeddings - Search for embeddings
|
||||
* @property {boolean} includeEmbeddingsInNormalResults - Include embeddings in normal tag results
|
||||
* @property {boolean} useHypernetworks - Search for hypernetworks
|
||||
* @property {boolean} useLoras - Search for Loras
|
||||
* @property {boolean} useLycos - Search for LyCORIS/LoHa
|
||||
* @property {boolean} useLoraPrefixForLycos - Use the '<lora:' prefix instead of '<lyco:' for models in the LyCORIS folder
|
||||
* @property {boolean} showWikiLinks - Show '?' next to tags, linking to its Danbooru or e621 wiki page
|
||||
* @property {boolean} showExtraNetworkPreviews - Show preview thumbnails for extra networks if available
|
||||
* @property {string} modelSortOrder - Model sort order
|
||||
* @property {boolean} frequencySort - Locally record tag usage and sort frequent tags higher
|
||||
* @property {string} frequencyFunction - Function to use for frequency sorting
|
||||
* @property {number} frequencyMinCount - Minimum number of uses for a tag to be considered frequent
|
||||
* @property {number} frequencyMaxAge - Maximum days since last use for a tag to be considered frequent
|
||||
* @property {number} frequencyRecommendCap - Maximum number of recommended tags
|
||||
* @property {boolean} frequencyIncludeAlias - Frequency sorting matches aliases for frequent tags
|
||||
* @property {boolean} useStyleVars - Search for webui style names
|
||||
* @property {boolean} replaceUnderscores - Replace underscores with spaces on insertion
|
||||
* @property {string} replaceUnderscoresExclusionList - Underscore replacement exclusion list
|
||||
* @property {boolean} escapeParentheses - Escape parentheses on insertion
|
||||
* @property {boolean} appendComma - Append comma on tag autocompletion
|
||||
* @property {boolean} appendSpace - Append space on tag autocompletion
|
||||
* @property {boolean} alwaysSpaceAtEnd - Always append space if inserting at the end of the textbox
|
||||
* @property {string} wildcardCompletionMode - How to complete nested wildcard paths
|
||||
* @property {string} modelKeywordCompletion - Try to add known trigger words for LORA/LyCO models
|
||||
* @property {string} modelKeywordLocation - Where to insert the trigger keyword
|
||||
* @property {string} wcWrap - Wrapper characters for wildcard tags.
|
||||
* @property {{ searchByAlias: boolean, onlyShowAlias: boolean }} alias - Alias-related settings.
|
||||
* @property {{ translationFile: string, oldFormat: boolean, searchByTranslation: boolean, liveTranslation: boolean }} translation - Translation-related settings.
|
||||
* @property {{ extraFile: string, addMode: "Insert before"|"Insert after" }} extra - Extra file-related settings.
|
||||
* @property {string} chantFile - Chant filename
|
||||
* @property {number} extraNetworksDefaultMultiplier - Default multiplier for extra networks.
|
||||
* @property {string} extraNetworksSeparator - Separator used for extra networks.
|
||||
* @property {{ MoveUp: string, MoveDown: string, JumpUp: string, JumpDown: string, JumpToStart: string, JumpToEnd: string, ChooseSelected: string, ChooseFirstOrSelected: string, Close: string }} keymap - Custom key mappings for tag completion.
|
||||
* @property {{ [filename: string]: { [category: string]: string[] } }} colorMap - Color mapping for tag categories.
|
||||
*/
|
||||
/** @type {TAC.CFG} */
|
||||
TAC.CFG = {
|
||||
// Main tag file
|
||||
tagFile,
|
||||
// Active in settings
|
||||
activeIn: {
|
||||
global,
|
||||
txt2img,
|
||||
img2img,
|
||||
negativePrompts,
|
||||
thirdParty,
|
||||
modelList,
|
||||
modelListMode,
|
||||
},
|
||||
// Results related settings
|
||||
slidingPopup,
|
||||
maxResults,
|
||||
showAllResults,
|
||||
resultStepLength,
|
||||
delayTime,
|
||||
useWildcards,
|
||||
sortWildcardResults,
|
||||
useEmbeddings,
|
||||
includeEmbeddingsInNormalResults,
|
||||
useHypernetworks,
|
||||
useLoras,
|
||||
useLycos,
|
||||
useLoraPrefixForLycos,
|
||||
showWikiLinks,
|
||||
showExtraNetworkPreviews,
|
||||
modelSortOrder,
|
||||
frequencySort,
|
||||
frequencyFunction,
|
||||
frequencyMinCount,
|
||||
frequencyMaxAge,
|
||||
frequencyRecommendCap,
|
||||
frequencyIncludeAlias,
|
||||
useStyleVars,
|
||||
// Insertion related settings
|
||||
replaceUnderscores,
|
||||
replaceUnderscoresExclusionList,
|
||||
escapeParentheses,
|
||||
appendComma,
|
||||
appendSpace,
|
||||
alwaysSpaceAtEnd,
|
||||
wildcardCompletionMode,
|
||||
modelKeywordCompletion,
|
||||
modelKeywordLocation,
|
||||
wcWrap, // to support custom wrapper chars set by dp_parser
|
||||
// Alias settings
|
||||
alias: {
|
||||
searchByAlias,
|
||||
onlyShowAlias,
|
||||
},
|
||||
// Translation settings
|
||||
translation: {
|
||||
translationFile,
|
||||
oldFormat,
|
||||
searchByTranslation,
|
||||
liveTranslation,
|
||||
},
|
||||
// Extra file settings
|
||||
extra: {
|
||||
extraFile,
|
||||
addMode,
|
||||
},
|
||||
// Chant file settings
|
||||
chantFile,
|
||||
// Settings not from tac but still used by the script
|
||||
extraNetworksDefaultMultiplier,
|
||||
extraNetworksSeparator,
|
||||
// Custom mapping settings
|
||||
keymap: {
|
||||
MoveUp,
|
||||
MoveDown,
|
||||
JumpUp,
|
||||
JumpDown,
|
||||
JumpToStart,
|
||||
JumpToEnd,
|
||||
ChooseSelected,
|
||||
ChooseFirstOrSelected,
|
||||
Close,
|
||||
},
|
||||
colorMap: {
|
||||
[filename]: { [category]: ["light", "dark"] },
|
||||
},
|
||||
};
|
||||
|
||||
TAC.Globals = new (function () {
|
||||
// Core components
|
||||
this.CFG = {
|
||||
// Main tag file
|
||||
tagFile,
|
||||
// Active in settings
|
||||
activeIn: {
|
||||
global,
|
||||
txt2img,
|
||||
img2img,
|
||||
negativePrompts,
|
||||
thirdParty,
|
||||
modelList,
|
||||
modelListMode,
|
||||
},
|
||||
// Results related settings
|
||||
slidingPopup,
|
||||
maxResults,
|
||||
showAllResults,
|
||||
resultStepLength,
|
||||
delayTime,
|
||||
useWildcards,
|
||||
sortWildcardResults,
|
||||
useEmbeddings,
|
||||
includeEmbeddingsInNormalResults,
|
||||
useHypernetworks,
|
||||
useLoras,
|
||||
useLycos,
|
||||
useLoraPrefixForLycos,
|
||||
showWikiLinks,
|
||||
showExtraNetworkPreviews,
|
||||
modelSortOrder,
|
||||
frequencySort,
|
||||
frequencyFunction,
|
||||
frequencyMinCount,
|
||||
frequencyMaxAge,
|
||||
frequencyRecommendCap,
|
||||
frequencyIncludeAlias,
|
||||
useStyleVars,
|
||||
// Insertion related settings
|
||||
replaceUnderscores,
|
||||
replaceUnderscoresExclusionList,
|
||||
escapeParentheses,
|
||||
appendComma,
|
||||
appendSpace,
|
||||
alwaysSpaceAtEnd,
|
||||
wildcardCompletionMode,
|
||||
modelKeywordCompletion,
|
||||
modelKeywordLocation,
|
||||
wcWrap: "__", // to support custom wrapper chars set by dp_parser
|
||||
// Alias settings
|
||||
alias: {
|
||||
searchByAlias,
|
||||
onlyShowAlias,
|
||||
},
|
||||
// Translation settings
|
||||
translation: {
|
||||
translationFile,
|
||||
oldFormat,
|
||||
searchByTranslation,
|
||||
liveTranslation,
|
||||
},
|
||||
// Extra file settings
|
||||
extra: {
|
||||
extraFile,
|
||||
addMode,
|
||||
},
|
||||
// Chant file settings
|
||||
chantFile,
|
||||
// Settings not from tac but still used by the script
|
||||
extraNetworksDefaultMultiplier,
|
||||
extraNetworksSeparator,
|
||||
// Custom mapping settings
|
||||
keymap: {
|
||||
MoveUp: "ArrowUp",
|
||||
MoveDown: "ArrowDown",
|
||||
JumpUp: "PageUp",
|
||||
JumpDown: "PageDown",
|
||||
JumpToStart: "Home",
|
||||
JumpToEnd: "End",
|
||||
ChooseSelected: "Enter",
|
||||
ChooseFirstOrSelected: "Tab",
|
||||
Close: "Escape",
|
||||
},
|
||||
colorMap: {
|
||||
filename: { category: ["light", "dark"] },
|
||||
},
|
||||
};
|
||||
this.tagBasePath = "";
|
||||
this.modelKeywordPath = "";
|
||||
this.selfTrigger = false;
|
||||
|
||||
@@ -259,13 +259,13 @@ class TacUtils {
|
||||
*/
|
||||
static calculateUsageBias(result, count, uses) {
|
||||
// Check setting conditions
|
||||
if (uses < TAC.Globals.CFG.frequencyMinCount) {
|
||||
if (uses < TAC.CFG.frequencyMinCount) {
|
||||
uses = 0;
|
||||
} else if (uses != 0) {
|
||||
result.usageBias = true;
|
||||
}
|
||||
|
||||
switch (TAC.Globals.CFG.frequencyFunction) {
|
||||
switch (TAC.CFG.frequencyFunction) {
|
||||
case "Logarithmic (weak)":
|
||||
return Math.log(1 + count) + Math.log(1 + uses);
|
||||
case "Logarithmic (strong)":
|
||||
@@ -492,7 +492,7 @@ class TacUtils {
|
||||
* @returns {((a: any, b: any) => number)}
|
||||
*/
|
||||
static getSortFunction() {
|
||||
let criterion = TAC.Globals.CFG.modelSortOrder || "Name";
|
||||
let criterion = TAC.CFG.modelSortOrder || "Name";
|
||||
|
||||
const textSort = (a, b, reverse = false) => {
|
||||
// Assign keys so next sort is faster
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
const CHANT_REGEX = /<(?!e:|h:|l:)[^,> ]*>?/g;
|
||||
const CHANT_TRIGGER = () => TAC.Globals.CFG.chantFile && TAC.Globals.CFG.chantFile !== "None" && TAC.Globals.tagword.match(CHANT_REGEX);
|
||||
const CHANT_TRIGGER = () => TAC.CFG.chantFile && TAC.CFG.chantFile !== "None" && TAC.Globals.tagword.match(CHANT_REGEX);
|
||||
|
||||
class ChantParser extends BaseTagParser {
|
||||
parse() {
|
||||
@@ -31,9 +31,9 @@ class ChantParser extends BaseTagParser {
|
||||
}
|
||||
|
||||
async function load() {
|
||||
if (TAC.Globals.CFG.chantFile && TAC.Globals.CFG.chantFile !== "None") {
|
||||
if (TAC.CFG.chantFile && TAC.CFG.chantFile !== "None") {
|
||||
try {
|
||||
TAC.Globals.chants = await TacUtils.readFile(`${TAC.Globals.tagBasePath}/${TAC.Globals.CFG.chantFile}?`, true);
|
||||
TAC.Globals.chants = await TacUtils.readFile(`${TAC.Globals.tagBasePath}/${TAC.CFG.chantFile}?`, true);
|
||||
} catch (e) {
|
||||
console.error("Error loading chants.json: " + e);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
const EMB_REGEX = /<(?!l:|h:|c:)[^,> ]*>?/g;
|
||||
const EMB_TRIGGER = () => TAC.Globals.CFG.useEmbeddings && (TAC.Globals.tagword.match(EMB_REGEX) || TAC.Globals.CFG.includeEmbeddingsInNormalResults);
|
||||
const EMB_TRIGGER = () => TAC.CFG.useEmbeddings && (TAC.Globals.tagword.match(EMB_REGEX) || TAC.CFG.includeEmbeddingsInNormalResults);
|
||||
|
||||
class EmbeddingParser extends BaseTagParser {
|
||||
parse() {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
const HYP_REGEX = /<(?!e:|l:|c:)[^,> ]*>?/g;
|
||||
const HYP_TRIGGER = () => TAC.Globals.CFG.useHypernetworks && TAC.Globals.tagword.match(HYP_REGEX);
|
||||
const HYP_TRIGGER = () => TAC.CFG.useHypernetworks && TAC.Globals.tagword.match(HYP_REGEX);
|
||||
|
||||
class HypernetParser extends BaseTagParser {
|
||||
parse() {
|
||||
@@ -43,7 +43,7 @@ async function load() {
|
||||
|
||||
function sanitize(tagType, text) {
|
||||
if (tagType === ResultType.hypernetwork) {
|
||||
return `<hypernet:${text}:${TAC.Globals.CFG.extraNetworksDefaultMultiplier}>`;
|
||||
return `<hypernet:${text}:${TAC.CFG.extraNetworksDefaultMultiplier}>`;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
const LORA_REGEX = /<(?!e:|h:|c:)[^,> ]*>?/g;
|
||||
const LORA_TRIGGER = () => TAC.Globals.CFG.useLoras && TAC.Globals.tagword.match(LORA_REGEX);
|
||||
const LORA_TRIGGER = () => TAC.CFG.useLoras && TAC.Globals.tagword.match(LORA_REGEX);
|
||||
|
||||
class LoraParser extends BaseTagParser {
|
||||
parse() {
|
||||
@@ -49,7 +49,7 @@ async function load() {
|
||||
|
||||
async function sanitize(tagType, text) {
|
||||
if (tagType === ResultType.lora) {
|
||||
let multiplier = TAC.Globals.CFG.extraNetworksDefaultMultiplier;
|
||||
let multiplier = TAC.CFG.extraNetworksDefaultMultiplier;
|
||||
let info = await TacUtils.fetchAPI(`tacapi/v1/lora-info/${text}`)
|
||||
if (info && info["preferred weight"]) {
|
||||
multiplier = info["preferred weight"];
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
const LYCO_REGEX = /<(?!e:|h:|c:)[^,> ]*>?/g;
|
||||
const LYCO_TRIGGER = () => TAC.Globals.CFG.useLycos && TAC.Globals.tagword.match(LYCO_REGEX);
|
||||
const LYCO_TRIGGER = () => TAC.CFG.useLycos && TAC.Globals.tagword.match(LYCO_REGEX);
|
||||
|
||||
class LycoParser extends BaseTagParser {
|
||||
parse() {
|
||||
@@ -49,13 +49,13 @@ async function load() {
|
||||
|
||||
async function sanitize(tagType, text) {
|
||||
if (tagType === ResultType.lyco) {
|
||||
let multiplier = TAC.Globals.CFG.extraNetworksDefaultMultiplier;
|
||||
let multiplier = TAC.CFG.extraNetworksDefaultMultiplier;
|
||||
let info = await TacUtils.fetchAPI(`tacapi/v1/lyco-info/${text}`)
|
||||
if (info && info["preferred weight"]) {
|
||||
multiplier = info["preferred weight"];
|
||||
}
|
||||
|
||||
let prefix = TAC.Globals.CFG.useLoraPrefixForLycos ? "lora" : "lyco";
|
||||
let prefix = TAC.CFG.useLoraPrefixForLycos ? "lora" : "lyco";
|
||||
return `<${prefix}:${text}:${multiplier}>`;
|
||||
}
|
||||
return null;
|
||||
|
||||
@@ -7,7 +7,7 @@ async function load() {
|
||||
try {
|
||||
let csv_lines = [];
|
||||
// Only add default keywords if wanted by the user
|
||||
if (TAC.Globals.CFG.modelKeywordCompletion !== "Only user list")
|
||||
if (TAC.CFG.modelKeywordCompletion !== "Only user list")
|
||||
csv_lines = (await TacUtils.loadCSV(`${TAC.Globals.modelKeywordPath}/lora-keyword.txt`));
|
||||
// Add custom user keywords if the file exists
|
||||
if (customFileExists)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
const STYLE_REGEX = /(\$(\d*)\(?)[^$|\[\],\s]*\)?/;
|
||||
const STYLE_TRIGGER = () => TAC.Globals.CFG.useStyleVars && TAC.Globals.tagword.match(STYLE_REGEX);
|
||||
const STYLE_TRIGGER = () => TAC.CFG.useStyleVars && TAC.Globals.tagword.match(STYLE_REGEX);
|
||||
|
||||
var lastStyleVarIndex = "";
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
const UMI_PROMPT_REGEX = /<[^\s]*?\[[^,<>]*[\]|]?>?/gi;
|
||||
const UMI_TAG_REGEX = /(?:\[|\||--)([^<>\[\]\-|]+)/gi;
|
||||
|
||||
const UMI_TRIGGER = () => TAC.Globals.CFG.useWildcards && [...TAC.Globals.tagword.matchAll(UMI_PROMPT_REGEX)].length > 0;
|
||||
const UMI_TRIGGER = () => TAC.CFG.useWildcards && [...TAC.Globals.tagword.matchAll(UMI_PROMPT_REGEX)].length > 0;
|
||||
|
||||
class UmiParser extends BaseTagParser {
|
||||
parse(textArea, prompt) {
|
||||
|
||||
@@ -2,13 +2,13 @@
|
||||
const WC_REGEX = new RegExp(/__([^,]+)__([^, ]*)/g);
|
||||
|
||||
// Trigger conditions
|
||||
const WC_TRIGGER = () => TAC.Globals.CFG.useWildcards && [...TAC.Globals.tagword.matchAll(new RegExp(WC_REGEX.source.replaceAll("__", escapeRegExp(TAC.Globals.CFG.wcWrap)), "g"))].length > 0;
|
||||
const WC_FILE_TRIGGER = () => TAC.Globals.CFG.useWildcards && (TAC.Globals.tagword.startsWith(TAC.Globals.CFG.wcWrap) && !TAC.Globals.tagword.endsWith(TAC.Globals.CFG.wcWrap) || TAC.Globals.tagword === TAC.Globals.CFG.wcWrap);
|
||||
const WC_TRIGGER = () => TAC.CFG.useWildcards && [...TAC.Globals.tagword.matchAll(new RegExp(WC_REGEX.source.replaceAll("__", escapeRegExp(TAC.CFG.wcWrap)), "g"))].length > 0;
|
||||
const WC_FILE_TRIGGER = () => TAC.CFG.useWildcards && (TAC.Globals.tagword.startsWith(TAC.CFG.wcWrap) && !TAC.Globals.tagword.endsWith(TAC.CFG.wcWrap) || TAC.Globals.tagword === TAC.CFG.wcWrap);
|
||||
|
||||
class WildcardParser extends BaseTagParser {
|
||||
async parse() {
|
||||
// Show wildcards from a file with that name
|
||||
let wcMatch = [...TAC.Globals.tagword.matchAll(new RegExp(WC_REGEX.source.replaceAll("__", escapeRegExp(TAC.Globals.CFG.wcWrap)), "g"))];
|
||||
let wcMatch = [...TAC.Globals.tagword.matchAll(new RegExp(WC_REGEX.source.replaceAll("__", escapeRegExp(TAC.CFG.wcWrap)), "g"))];
|
||||
let wcFile = wcMatch[0][1];
|
||||
let wcWord = wcMatch[0][2];
|
||||
|
||||
@@ -45,7 +45,7 @@ class WildcardParser extends BaseTagParser {
|
||||
}
|
||||
}
|
||||
|
||||
if (TAC.Globals.CFG.sortWildcardResults)
|
||||
if (TAC.CFG.sortWildcardResults)
|
||||
wildcards.sort((a, b) => a.localeCompare(b));
|
||||
|
||||
let finalResults = [];
|
||||
@@ -64,8 +64,8 @@ class WildcardFileParser extends BaseTagParser {
|
||||
parse() {
|
||||
// Show available wildcard files
|
||||
let tempResults = [];
|
||||
if (TAC.Globals.tagword !== TAC.Globals.CFG.wcWrap) {
|
||||
let lmb = (x) => x[1].toLowerCase().includes(TAC.Globals.tagword.replace(TAC.Globals.CFG.wcWrap, ""))
|
||||
if (TAC.Globals.tagword !== TAC.CFG.wcWrap) {
|
||||
let lmb = (x) => x[1].toLowerCase().includes(TAC.Globals.tagword.replace(TAC.CFG.wcWrap, ""))
|
||||
tempResults = TAC.Globals.wildcardFiles.filter(lmb).concat(TAC.Globals.wildcardExtFiles.filter(lmb)) // Filter by tagword
|
||||
} else {
|
||||
tempResults = TAC.Globals.wildcardFiles.concat(TAC.Globals.wildcardExtFiles);
|
||||
@@ -151,7 +151,7 @@ async function load() {
|
||||
|
||||
function sanitize(tagType, text) {
|
||||
if (tagType === ResultType.wildcardFile || tagType === ResultType.yamlWildcard) {
|
||||
return `${TAC.Globals.CFG.wcWrap}${text}${TAC.Globals.CFG.wcWrap}`;
|
||||
return `${TAC.CFG.wcWrap}${text}${TAC.CFG.wcWrap}`;
|
||||
} else if (tagType === ResultType.wildcardTag) {
|
||||
return text;
|
||||
}
|
||||
|
||||
@@ -200,6 +200,7 @@ async function loadTranslations(c) {
|
||||
}
|
||||
|
||||
async function syncOptions() {
|
||||
/** @type {TAC.CFG} */
|
||||
let newCFG = {
|
||||
// Main tag file
|
||||
tagFile: opts["tac_tagFile"],
|
||||
@@ -280,20 +281,20 @@ async function syncOptions() {
|
||||
}
|
||||
|
||||
// Reload translations if the translation file changed
|
||||
if (!TAC.Globals.CFG || newCFG.translation.translationFile !== TAC.Globals.CFG.translation.translationFile) {
|
||||
if (!TAC.CFG || newCFG.translation.translationFile !== TAC.CFG.translation.translationFile) {
|
||||
TAC.Globals.translations.clear();
|
||||
await loadTranslations(newCFG);
|
||||
await loadExtraTags(newCFG);
|
||||
}
|
||||
// Reload tags if the tag file changed (after translations so extra tag translations get re-added)
|
||||
if (!TAC.Globals.CFG || newCFG.tagFile !== TAC.Globals.CFG.tagFile || newCFG.extra.extraFile !== TAC.Globals.CFG.extra.extraFile) {
|
||||
if (!TAC.CFG || newCFG.tagFile !== TAC.CFG.tagFile || newCFG.extra.extraFile !== TAC.CFG.extra.extraFile) {
|
||||
TAC.Globals.allTags = [];
|
||||
await loadTags(newCFG);
|
||||
}
|
||||
|
||||
// Refresh temp files if model sort order changed
|
||||
// Contrary to the other loads, this one shouldn't happen on a first time load
|
||||
if (TAC.Globals.CFG && newCFG.modelSortOrder !== TAC.Globals.CFG.modelSortOrder) {
|
||||
if (TAC.CFG && newCFG.modelSortOrder !== TAC.CFG.modelSortOrder) {
|
||||
const dropdown = gradioApp().querySelector("#setting_tac_modelSortOrder");
|
||||
dropdown.style.opacity = 0.5;
|
||||
dropdown.style.pointerEvents = "none";
|
||||
@@ -303,7 +304,7 @@ async function syncOptions() {
|
||||
}
|
||||
|
||||
// Update CSS if maxResults changed
|
||||
if (TAC.Globals.CFG && newCFG.maxResults !== TAC.Globals.CFG.maxResults) {
|
||||
if (TAC.CFG && newCFG.maxResults !== TAC.CFG.maxResults) {
|
||||
gradioApp().querySelectorAll(".autocompleteResults").forEach(r => {
|
||||
r.style.maxHeight = `${newCFG.maxResults * 50}px`;
|
||||
});
|
||||
@@ -317,7 +318,7 @@ async function syncOptions() {
|
||||
}
|
||||
|
||||
// Apply changes
|
||||
TAC.Globals.CFG = newCFG;
|
||||
TAC.CFG = newCFG;
|
||||
|
||||
// Callback
|
||||
await TacUtils.processQueue(TAC.Ext.QUEUE_AFTER_CONFIG_CHANGE, null);
|
||||
@@ -336,7 +337,7 @@ function createResultsDiv(textArea) {
|
||||
|
||||
parentDiv.setAttribute("class", `autocompleteParent${typeClass}`);
|
||||
|
||||
resultsDiv.style.maxHeight = `${TAC.Globals.CFG.maxResults * 50}px`;
|
||||
resultsDiv.style.maxHeight = `${TAC.CFG.maxResults * 50}px`;
|
||||
resultsDiv.setAttribute("class", `autocompleteResults${typeClass} notranslate`);
|
||||
resultsDiv.setAttribute("translate", "no");
|
||||
resultsList.setAttribute("class", "autocompleteResultsList");
|
||||
@@ -362,7 +363,7 @@ function showResults(textArea) {
|
||||
let parentDiv = gradioApp().querySelector('.autocompleteParent' + textAreaId);
|
||||
parentDiv.style.display = "flex";
|
||||
|
||||
if (TAC.Globals.CFG.slidingPopup) {
|
||||
if (TAC.CFG.slidingPopup) {
|
||||
let caretPosition = CaretUtils.getCaretCoordinates(textArea, textArea.selectionEnd);
|
||||
// Top cursor offset fix for SDNext modern UI, based on code by https://github.com/Nyx01
|
||||
let offsetTop = textArea.offsetTop + caretPosition.top - textArea.scrollTop + 10; // Adjust this value for desired distance below cursor
|
||||
@@ -393,18 +394,18 @@ function hideResults(textArea) {
|
||||
|
||||
// Function to check activation criteria
|
||||
function isEnabled() {
|
||||
if (TAC.Globals.CFG.activeIn.global) {
|
||||
if (TAC.CFG.activeIn.global) {
|
||||
// Skip check if the current model was not correctly detected, since it could wrongly disable the script otherwise
|
||||
if (!TAC.Globals.currentModelName || !TAC.Globals.currentModelHash) return true;
|
||||
|
||||
let modelList = TAC.Globals.CFG.activeIn.modelList
|
||||
let modelList = TAC.CFG.activeIn.modelList
|
||||
.split(",")
|
||||
.map(x => x.trim())
|
||||
.filter(x => x.length > 0);
|
||||
|
||||
let shortHash = TAC.Globals.currentModelHash.substring(0, 10);
|
||||
let modelNameWithoutHash = TAC.Globals.currentModelName.replace(/\[.*\]$/g, "").trim();
|
||||
if (TAC.Globals.CFG.activeIn.modelListMode.toLowerCase() === "blacklist") {
|
||||
if (TAC.CFG.activeIn.modelListMode.toLowerCase() === "blacklist") {
|
||||
// If the current model is in the blacklist, disable
|
||||
return modelList.filter(x => x === TAC.Globals.currentModelName || x === modelNameWithoutHash || x === TAC.Globals.currentModelHash || x === shortHash).length === 0;
|
||||
} else {
|
||||
@@ -423,7 +424,7 @@ const COMPLETED_WILDCARD_REGEX = /__[^\s,_][^\t\n\r,_]*[^\s,_]__[^\s,_]*/g;
|
||||
const STYLE_VAR_REGEX = /\$\(?[^$|\[\],\s]*\)?/g;
|
||||
const NORMAL_TAG_REGEX = /[^\s,|<>\[\]:]+_\([^\s,|<>\[\]:]*\)?|[^\s,|<>():\[\]]+|</g;
|
||||
const RUBY_TAG_REGEX = /[\w\d<][\w\d' \-?!/$%]{2,}>?/g;
|
||||
const TAG_REGEX = () => { return new RegExp(`${POINTY_REGEX.source}|${COMPLETED_WILDCARD_REGEX.source.replaceAll("__", escapeRegExp(TAC.Globals.CFG.wcWrap))}|${STYLE_VAR_REGEX.source}|${NORMAL_TAG_REGEX.source}`, "g"); }
|
||||
const TAG_REGEX = () => { return new RegExp(`${POINTY_REGEX.source}|${COMPLETED_WILDCARD_REGEX.source.replaceAll("__", escapeRegExp(TAC.CFG.wcWrap))}|${STYLE_VAR_REGEX.source}|${NORMAL_TAG_REGEX.source}`, "g"); }
|
||||
|
||||
// On click, insert the tag into the prompt textbox with respect to the cursor position
|
||||
async function insertTextAtCursor(textArea, result, tagword, tabCompletedWithoutChoice = false) {
|
||||
@@ -439,13 +440,13 @@ async function insertTextAtCursor(textArea, result, tagword, tabCompletedWithout
|
||||
if (sanitizeResults && sanitizeResults.length > 0) {
|
||||
sanitizedText = sanitizeResults[0];
|
||||
} else {
|
||||
const excluded_tags = TAC.Globals.CFG.replaceUnderscoresExclusionList?.split(',').map(s => s.trim()) || [];
|
||||
if (TAC.Globals.CFG.replaceUnderscores && !excluded_tags.includes(sanitizedText)) {
|
||||
const excluded_tags = TAC.CFG.replaceUnderscoresExclusionList?.split(',').map(s => s.trim()) || [];
|
||||
if (TAC.CFG.replaceUnderscores && !excluded_tags.includes(sanitizedText)) {
|
||||
sanitizedText = text.replaceAll("_", " ")
|
||||
} else {
|
||||
sanitizedText = text;
|
||||
}
|
||||
if (TAC.Globals.CFG.escapeParentheses && tagType === ResultType.tag) {
|
||||
if (TAC.CFG.escapeParentheses && tagType === ResultType.tag) {
|
||||
sanitizedText = sanitizedText
|
||||
.replaceAll("(", "\\(")
|
||||
.replaceAll(")", "\\)")
|
||||
@@ -456,9 +457,9 @@ async function insertTextAtCursor(textArea, result, tagword, tabCompletedWithout
|
||||
|
||||
if ((tagType === ResultType.wildcardFile || tagType === ResultType.yamlWildcard)
|
||||
&& tabCompletedWithoutChoice
|
||||
&& TAC.Globals.CFG.wildcardCompletionMode !== "Always fully"
|
||||
&& TAC.CFG.wildcardCompletionMode !== "Always fully"
|
||||
&& sanitizedText.includes("/")) {
|
||||
if (TAC.Globals.CFG.wildcardCompletionMode === "To next folder level") {
|
||||
if (TAC.CFG.wildcardCompletionMode === "To next folder level") {
|
||||
let regexMatch = sanitizedText.match(new RegExp(`${TacUtils.escapeRegExp(tagword)}([^/]*\\/?)`, "i"));
|
||||
if (regexMatch) {
|
||||
let pathPart = regexMatch[0];
|
||||
@@ -468,7 +469,7 @@ async function insertTextAtCursor(textArea, result, tagword, tabCompletedWithout
|
||||
}
|
||||
sanitizedText = pathPart;
|
||||
}
|
||||
} else if (TAC.Globals.CFG.wildcardCompletionMode === "To first difference") {
|
||||
} else if (TAC.CFG.wildcardCompletionMode === "To first difference") {
|
||||
let firstDifference = 0;
|
||||
let longestResult = TAC.Globals.results.map(x => x.text.length).reduce((a, b) => Math.max(a, b));
|
||||
// Compare the results to each other to find the first point where they differ
|
||||
@@ -483,7 +484,7 @@ async function insertTextAtCursor(textArea, result, tagword, tabCompletedWithout
|
||||
// Don't cut off the __ at the end if it is already the full path
|
||||
if (firstDifference > 0 && firstDifference < longestResult) {
|
||||
// +2 because the sanitized text already has the __ at the start but the matched text doesn't
|
||||
sanitizedText = sanitizedText.substring(0, firstDifference + TAC.Globals.CFG.wcWrap.length);
|
||||
sanitizedText = sanitizedText.substring(0, firstDifference + TAC.CFG.wcWrap.length);
|
||||
} else if (firstDifference === 0) {
|
||||
sanitizedText = tagword;
|
||||
}
|
||||
@@ -491,14 +492,14 @@ async function insertTextAtCursor(textArea, result, tagword, tabCompletedWithout
|
||||
}
|
||||
|
||||
// Frequency db update
|
||||
if (TAC.Globals.CFG.frequencySort) {
|
||||
if (TAC.CFG.frequencySort) {
|
||||
let name = null;
|
||||
|
||||
switch (tagType) {
|
||||
case ResultType.wildcardFile:
|
||||
case ResultType.yamlWildcard:
|
||||
// We only want to update the frequency for a full wildcard, not partial paths
|
||||
if (sanitizedText.endsWith(TAC.Globals.CFG.wcWrap))
|
||||
if (sanitizedText.endsWith(TAC.CFG.wcWrap))
|
||||
name = text
|
||||
break;
|
||||
case ResultType.chant:
|
||||
@@ -536,17 +537,17 @@ async function insertTextAtCursor(textArea, result, tagword, tabCompletedWithout
|
||||
if (!noCommaTypes.includes(tagType)) {
|
||||
// Append comma if enabled and not already present
|
||||
let beforeComma = surrounding.match(new RegExp(`${TacUtils.escapeRegExp(tagword)}[,:]`, "i")) !== null;
|
||||
if (TAC.Globals.CFG.appendComma)
|
||||
if (TAC.CFG.appendComma)
|
||||
optionalSeparator = beforeComma ? "" : ",";
|
||||
// Add space if enabled
|
||||
if (TAC.Globals.CFG.appendSpace && !beforeComma)
|
||||
if (TAC.CFG.appendSpace && !beforeComma)
|
||||
optionalSeparator += " ";
|
||||
// If at end of prompt and enabled, override the normal setting if not already added
|
||||
if (!TAC.Globals.CFG.appendSpace && TAC.Globals.CFG.alwaysSpaceAtEnd)
|
||||
if (!TAC.CFG.appendSpace && TAC.CFG.alwaysSpaceAtEnd)
|
||||
optionalSeparator += surrounding.match(new RegExp(`${TacUtils.escapeRegExp(tagword)}$`, "im")) !== null ? " " : "";
|
||||
} else if (extraNetworkTypes.includes(tagType)) {
|
||||
// Use the dedicated separator for extra networks if it's defined, otherwise fall back to space
|
||||
optionalSeparator = TAC.Globals.CFG.extraNetworksSeparator || " ";
|
||||
optionalSeparator = TAC.CFG.extraNetworksSeparator || " ";
|
||||
}
|
||||
|
||||
// Escape $ signs since they are special chars for the replace function
|
||||
@@ -562,7 +563,7 @@ async function insertTextAtCursor(textArea, result, tagword, tabCompletedWithout
|
||||
// Add lora/lyco keywords if enabled and found
|
||||
let keywordsLength = 0;
|
||||
|
||||
if (TAC.Globals.CFG.modelKeywordCompletion !== "Never" && (tagType === ResultType.lora || tagType === ResultType.lyco)) {
|
||||
if (TAC.CFG.modelKeywordCompletion !== "Never" && (tagType === ResultType.lora || tagType === ResultType.lyco)) {
|
||||
let keywords = null;
|
||||
// Check built-in activation words first
|
||||
if (tagType === ResultType.lora || tagType === ResultType.lyco) {
|
||||
@@ -601,9 +602,9 @@ async function insertTextAtCursor(textArea, result, tagword, tabCompletedWithout
|
||||
if (keywords && keywords.length > 0) {
|
||||
TAC.Globals.textBeforeKeywordInsertion = newPrompt;
|
||||
|
||||
if (TAC.Globals.CFG.modelKeywordLocation === "Start of prompt")
|
||||
if (TAC.CFG.modelKeywordLocation === "Start of prompt")
|
||||
newPrompt = `${keywords}, ${newPrompt}`; // Insert keywords
|
||||
else if (TAC.Globals.CFG.modelKeywordLocation === "End of prompt")
|
||||
else if (TAC.CFG.modelKeywordLocation === "End of prompt")
|
||||
newPrompt = `${newPrompt}, ${keywords}`; // Insert keywords
|
||||
else {
|
||||
let keywordStart = prompt[editStart - 1] === " " ? editStart - 1 : editStart;
|
||||
@@ -688,10 +689,10 @@ function addResultsToList(textArea, results, tagword, resetList) {
|
||||
}
|
||||
|
||||
// Find right colors from config
|
||||
let tagFileName = TAC.Globals.CFG.tagFile.split(".")[0];
|
||||
let tagColors = TAC.Globals.CFG.colorMap;
|
||||
let tagFileName = TAC.CFG.tagFile.split(".")[0];
|
||||
let tagColors = TAC.CFG.colorMap;
|
||||
let mode = (document.querySelector(".dark") || gradioApp().querySelector(".dark")) ? 0 : 1;
|
||||
let nextLength = Math.min(results.length, TAC.Globals.resultCount + TAC.Globals.CFG.resultStepLength);
|
||||
let nextLength = Math.min(results.length, TAC.Globals.resultCount + TAC.CFG.resultStepLength);
|
||||
const IS_DAN_OR_E621_TAG_FILE = (tagFileName.toLowerCase().startsWith("danbooru") || tagFileName.toLowerCase().startsWith("e621"));
|
||||
|
||||
const tagCount = {};
|
||||
@@ -758,7 +759,7 @@ function addResultsToList(textArea, results, tagword, resetList) {
|
||||
if (TAC.Globals.translations.has(bestAlias) && TAC.Globals.translations.get(bestAlias) !== bestAlias && bestAlias !== result.text)
|
||||
displayText += `[${TAC.Globals.translations.get(bestAlias)}]`;
|
||||
|
||||
if (!TAC.Globals.CFG.alias.onlyShowAlias && result.text !== bestAlias)
|
||||
if (!TAC.CFG.alias.onlyShowAlias && result.text !== bestAlias)
|
||||
displayText += " ➝ " + result.text;
|
||||
} else { // No alias
|
||||
displayText = TacUtils.escapeHTML(result.text);
|
||||
@@ -782,7 +783,7 @@ function addResultsToList(textArea, results, tagword, resetList) {
|
||||
|
||||
// Add wiki link if the setting is enabled and a supported tag set loaded
|
||||
if (
|
||||
TAC.Globals.CFG.showWikiLinks &&
|
||||
TAC.CFG.showWikiLinks &&
|
||||
result.type === ResultType.tag &&
|
||||
IS_DAN_OR_E621_TAG_FILE
|
||||
) {
|
||||
@@ -906,7 +907,7 @@ function addResultsToList(textArea, results, tagword, resetList) {
|
||||
});
|
||||
// Add delayed hover listener for extra network previews
|
||||
if (
|
||||
TAC.Globals.CFG.showExtraNetworkPreviews &&
|
||||
TAC.CFG.showExtraNetworkPreviews &&
|
||||
[
|
||||
ResultType.embedding,
|
||||
ResultType.hypernetwork,
|
||||
@@ -976,7 +977,7 @@ async function updateSelectionStyle(textArea, newIndex, oldIndex, scroll = true)
|
||||
|
||||
let previewDiv = gradioApp().querySelector(`.autocompleteParent${textAreaId} .sideInfo`);
|
||||
|
||||
if (TAC.Globals.CFG.showExtraNetworkPreviews && previewTypes.includes(selectedType)) {
|
||||
if (TAC.CFG.showExtraNetworkPreviews && previewTypes.includes(selectedType)) {
|
||||
let img = previewDiv.querySelector("img");
|
||||
// String representation of our type enum
|
||||
const typeString = Object.keys(ResultType)[selectedType - 1].toLowerCase();
|
||||
@@ -995,8 +996,8 @@ async function updateSelectionStyle(textArea, newIndex, oldIndex, scroll = true)
|
||||
}
|
||||
|
||||
function updateRuby(textArea, prompt) {
|
||||
if (!TAC.Globals.CFG.translation.liveTranslation) return;
|
||||
if (!TAC.Globals.CFG.translation.translationFile || TAC.Globals.CFG.translation.translationFile === "None") return;
|
||||
if (!TAC.CFG.translation.liveTranslation) return;
|
||||
if (!TAC.CFG.translation.translationFile || TAC.CFG.translation.translationFile === "None") return;
|
||||
|
||||
let ruby = gradioApp().querySelector('.acRuby' + getTextAreaIdentifier(textArea));
|
||||
if (!ruby) {
|
||||
@@ -1101,7 +1102,7 @@ function rubyTagClicked(node, textBefore, prompt, textArea) {
|
||||
|
||||
// Check if the last edit was the keyword insertion, and catch undo/redo in that case
|
||||
function checkKeywordInsertionUndo(textArea, event) {
|
||||
if (TAC.Globals.CFG.modelKeywordCompletion === "Never") return;
|
||||
if (TAC.CFG.modelKeywordCompletion === "Never") return;
|
||||
|
||||
switch (event.inputType) {
|
||||
case "historyUndo":
|
||||
@@ -1221,7 +1222,7 @@ async function autocomplete(textArea, prompt, fixedTag = null) {
|
||||
}
|
||||
// Else search the normal tag list
|
||||
if (!resultCandidates || resultCandidates.length === 0
|
||||
|| (TAC.Globals.CFG.includeEmbeddingsInNormalResults && !(TAC.Globals.tagword.startsWith("<") || TAC.Globals.tagword.startsWith("*<")))
|
||||
|| (TAC.CFG.includeEmbeddingsInNormalResults && !(TAC.Globals.tagword.startsWith("<") || TAC.Globals.tagword.startsWith("*<")))
|
||||
) {
|
||||
normalTags = true;
|
||||
TAC.Globals.resultCountBeforeNormalTags = TAC.Globals.results.length;
|
||||
@@ -1242,11 +1243,11 @@ async function autocomplete(textArea, prompt, fixedTag = null) {
|
||||
|| x[3] && x[3].split(",").some(y => TAC.Globals.translations.has(y) && TAC.Globals.translations.get(y).toLowerCase().search(searchRegex) > -1);
|
||||
|
||||
let fil;
|
||||
if (TAC.Globals.CFG.alias.searchByAlias && TAC.Globals.CFG.translation.searchByTranslation)
|
||||
if (TAC.CFG.alias.searchByAlias && TAC.CFG.translation.searchByTranslation)
|
||||
fil = (x) => baseFilter(x) || aliasFilter(x) || translationFilter(x);
|
||||
else if (TAC.Globals.CFG.alias.searchByAlias && !TAC.Globals.CFG.translation.searchByTranslation)
|
||||
else if (TAC.CFG.alias.searchByAlias && !TAC.CFG.translation.searchByTranslation)
|
||||
fil = (x) => baseFilter(x) || aliasFilter(x);
|
||||
else if (TAC.Globals.CFG.translation.searchByTranslation && !TAC.Globals.CFG.alias.searchByAlias)
|
||||
else if (TAC.CFG.translation.searchByTranslation && !TAC.CFG.alias.searchByAlias)
|
||||
fil = (x) => baseFilter(x) || translationFilter(x);
|
||||
else
|
||||
fil = (x) => baseFilter(x);
|
||||
@@ -1261,7 +1262,7 @@ async function autocomplete(textArea, prompt, fixedTag = null) {
|
||||
});
|
||||
|
||||
// Add TAC.Globals.extras
|
||||
if (TAC.Globals.CFG.extra.extraFile) {
|
||||
if (TAC.CFG.extra.extraFile) {
|
||||
let extraResults = [];
|
||||
|
||||
TAC.Globals.extras.filter(fil).forEach(e => {
|
||||
@@ -1272,7 +1273,7 @@ async function autocomplete(textArea, prompt, fixedTag = null) {
|
||||
extraResults.push(result);
|
||||
});
|
||||
|
||||
if (TAC.Globals.CFG.extra.addMode === "Insert before") {
|
||||
if (TAC.CFG.extra.addMode === "Insert before") {
|
||||
TAC.Globals.results = extraResults.concat(TAC.Globals.results);
|
||||
} else {
|
||||
TAC.Globals.results = TAC.Globals.results.concat(extraResults);
|
||||
@@ -1288,7 +1289,7 @@ async function autocomplete(textArea, prompt, fixedTag = null) {
|
||||
}
|
||||
|
||||
// Sort again with frequency / usage count if enabled
|
||||
if (TAC.Globals.CFG.frequencySort) {
|
||||
if (TAC.CFG.frequencySort) {
|
||||
// Split our results into a list of names and types
|
||||
let tagNames = [];
|
||||
let aliasNames = [];
|
||||
@@ -1312,7 +1313,7 @@ async function autocomplete(textArea, prompt, fixedTag = null) {
|
||||
let isNegative = textAreaId.includes("n");
|
||||
|
||||
// Request use counts from the DB
|
||||
const names = TAC.Globals.CFG.frequencyIncludeAlias ? tagNames.concat(aliasNames) : tagNames;
|
||||
const names = TAC.CFG.frequencyIncludeAlias ? tagNames.concat(aliasNames) : tagNames;
|
||||
const counts = await TacUtils.getUseCounts(names, types, isNegative) || [];
|
||||
|
||||
// Pre-calculate weights to prevent duplicate work
|
||||
@@ -1334,8 +1335,8 @@ async function autocomplete(textArea, prompt, fixedTag = null) {
|
||||
}
|
||||
|
||||
// Slice if the user has set a max result count and we are not in a extra networks / wildcard list
|
||||
if (!TAC.Globals.CFG.showAllResults && normalTags) {
|
||||
TAC.Globals.results = TAC.Globals.results.slice(0, TAC.Globals.CFG.maxResults + TAC.Globals.resultCountBeforeNormalTags);
|
||||
if (!TAC.CFG.showAllResults && normalTags) {
|
||||
TAC.Globals.results = TAC.Globals.results.slice(0, TAC.CFG.maxResults + TAC.Globals.resultCountBeforeNormalTags);
|
||||
}
|
||||
|
||||
addResultsToList(textArea, TAC.Globals.results, TAC.Globals.tagword, true);
|
||||
@@ -1346,7 +1347,7 @@ function navigateInList(textArea, event) {
|
||||
// Return if the function is deactivated in the UI or the current model is excluded due to white/blacklist settings
|
||||
if (!isEnabled()) return;
|
||||
|
||||
let keys = TAC.Globals.CFG.keymap;
|
||||
let keys = TAC.CFG.keymap;
|
||||
|
||||
// Close window if Home or End is pressed while not a keybinding, since it would break completion on leaving the original tag
|
||||
if ((event.key === "Home" || event.key === "End") && !Object.values(keys).includes(event.key)) {
|
||||
@@ -1400,7 +1401,7 @@ function navigateInList(textArea, event) {
|
||||
}
|
||||
break;
|
||||
case keys["JumpToStart"]:
|
||||
if (TAC.Globals.CFG.includeEmbeddingsInNormalResults &&
|
||||
if (TAC.CFG.includeEmbeddingsInNormalResults &&
|
||||
TAC.Globals.selectedTag > TAC.Globals.resultCountBeforeNormalTags &&
|
||||
TAC.Globals.resultCountBeforeNormalTags > 0
|
||||
) {
|
||||
@@ -1411,7 +1412,7 @@ function navigateInList(textArea, event) {
|
||||
break;
|
||||
case keys["JumpToEnd"]:
|
||||
// Jump to the end of the list, or the end of embeddings if they are included in the normal results
|
||||
if (TAC.Globals.CFG.includeEmbeddingsInNormalResults &&
|
||||
if (TAC.CFG.includeEmbeddingsInNormalResults &&
|
||||
TAC.Globals.selectedTag < TAC.Globals.resultCountBeforeNormalTags &&
|
||||
TAC.Globals.resultCountBeforeNormalTags > 0
|
||||
) {
|
||||
@@ -1433,7 +1434,7 @@ function navigateInList(textArea, event) {
|
||||
if (TAC.Globals.selectedTag === null) {
|
||||
TAC.Globals.selectedTag = 0;
|
||||
withoutChoice = true;
|
||||
} else if (TAC.Globals.CFG.wildcardCompletionMode === "To next folder level") {
|
||||
} else if (TAC.CFG.wildcardCompletionMode === "To next folder level") {
|
||||
withoutChoice = true;
|
||||
}
|
||||
insertTextAtCursor(textArea, TAC.Globals.results[TAC.Globals.selectedTag], TAC.Globals.tagword, withoutChoice);
|
||||
@@ -1492,10 +1493,10 @@ async function refreshEmbeddings() {
|
||||
function addAutocompleteToArea(area) {
|
||||
// Return if autocomplete is disabled for the current area type in config
|
||||
let textAreaId = getTextAreaIdentifier(area);
|
||||
if ((!TAC.Globals.CFG.activeIn.img2img && textAreaId.includes("img2img"))
|
||||
|| (!TAC.Globals.CFG.activeIn.txt2img && textAreaId.includes("txt2img"))
|
||||
|| (!TAC.Globals.CFG.activeIn.negativePrompts && textAreaId.includes("n"))
|
||||
|| (!TAC.Globals.CFG.activeIn.thirdParty && textAreaId.includes("thirdParty"))) {
|
||||
if ((!TAC.CFG.activeIn.img2img && textAreaId.includes("img2img"))
|
||||
|| (!TAC.CFG.activeIn.txt2img && textAreaId.includes("txt2img"))
|
||||
|| (!TAC.CFG.activeIn.negativePrompts && textAreaId.includes("n"))
|
||||
|| (!TAC.CFG.activeIn.thirdParty && textAreaId.includes("thirdParty"))) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1521,7 +1522,7 @@ function addAutocompleteToArea(area) {
|
||||
setTimeout(() => { TAC.Globals.hideBlocked = false; }, 100);
|
||||
}
|
||||
|
||||
TacUtils.debounce(autocomplete(area, area.value), TAC.Globals.CFG.delayTime);
|
||||
TacUtils.debounce(autocomplete(area, area.value), TAC.CFG.delayTime);
|
||||
checkKeywordInsertionUndo(area, e);
|
||||
});
|
||||
// Add focusout event listener
|
||||
@@ -1617,10 +1618,10 @@ async function setup() {
|
||||
if (textAreas.every(v => v === null || v === undefined)) return;
|
||||
// Already added or unnecessary to add
|
||||
if (gradioApp().querySelector('.autocompleteParent.p')) {
|
||||
if (gradioApp().querySelector('.autocompleteParent.n') || !TAC.Globals.CFG.activeIn.negativePrompts) {
|
||||
if (gradioApp().querySelector('.autocompleteParent.n') || !TAC.CFG.activeIn.negativePrompts) {
|
||||
return;
|
||||
}
|
||||
} else if (!TAC.Globals.CFG.activeIn.txt2img && !TAC.Globals.CFG.activeIn.img2img) {
|
||||
} else if (!TAC.CFG.activeIn.txt2img && !TAC.CFG.activeIn.img2img) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1655,7 +1656,7 @@ var tacLoading = false;
|
||||
onUiUpdate(async () => {
|
||||
if (tacLoading) return;
|
||||
if (Object.keys(opts).length === 0) return;
|
||||
if (TAC.Globals.CFG) return;
|
||||
if (TAC.CFG) return;
|
||||
tacLoading = true;
|
||||
// Get our tag base path from the temp file
|
||||
TAC.Globals.tagBasePath = await TacUtils.readFile(`tmp/tagAutocompletePath.txt`);
|
||||
|
||||
Reference in New Issue
Block a user