From 4d6e5b14acd322d047cf710607d94aa55035b699 Mon Sep 17 00:00:00 2001 From: DominikDoom Date: Thu, 10 Jul 2025 14:07:13 +0200 Subject: [PATCH] Use new TAC.Globals namespace for CFG --- javascript/__globals.js | 195 ++++++++++++++++++++++++--------- javascript/_utils.js | 6 +- javascript/ext_chants.js | 6 +- javascript/ext_embeddings.js | 2 +- javascript/ext_hypernets.js | 4 +- javascript/ext_loras.js | 4 +- javascript/ext_lycos.js | 6 +- javascript/ext_modelKeyword.js | 2 +- javascript/ext_styles.js | 2 +- javascript/ext_umi.js | 2 +- javascript/ext_wildcards.js | 14 +-- javascript/tagAutocomplete.js | 118 ++++++++++---------- 12 files changed, 226 insertions(+), 135 deletions(-) diff --git a/javascript/__globals.js b/javascript/__globals.js index 32cf94c..8fea829 100644 --- a/javascript/__globals.js +++ b/javascript/__globals.js @@ -1,65 +1,156 @@ -// Core components -var TAC_CFG = null; -var tagBasePath = ""; -var modelKeywordPath = ""; -var tacSelfTrigger = false; +// Create our TAC namespace +var TAC = TAC || {}; -// Tag completion data loaded from files -var allTags = []; -var translations = new Map(); -var extras = []; -// Same for tag-likes -var wildcardFiles = []; -var wildcardExtFiles = []; -var yamlWildcards = []; -var umiWildcards = []; -var embeddings = []; -var hypernetworks = []; -var loras = []; -var lycos = []; -var modelKeywordDict = new Map(); -var chants = []; -var styleNames = []; +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.tacSelfTrigger = false; -// Selected model info for black/whitelisting -var currentModelHash = ""; -var currentModelName = ""; + // Tag completion data loaded from files + this.allTags = []; + this.translations = new Map(); + this.extras = []; + // Same for tag-likes + this.wildcardFiles = []; + this.wildcardExtFiles = []; + this.yamlWildcards = []; + this.umiWildcards = []; + this.embeddings = []; + this.hypernetworks = []; + this.loras = []; + this.lycos = []; + this.modelKeywordDict = new Map(); + this.chants = []; + this.styleNames = []; -// Current results -var results = []; -var resultCount = 0; + // Selected model info for black/whitelisting + this.currentModelHash = ""; + this.currentModelName = ""; -// Relevant for parsing -var previousTags = []; -var tagword = ""; -var originalTagword = ""; -let hideBlocked = false; + // Current results + this.results = []; + this.resultCount = 0; -// Tag selection for keyboard navigation -var selectedTag = null; -var oldSelectedTag = null; -var resultCountBeforeNormalTags = 0; + // Relevant for parsing + this.previousTags = []; + this.tagword = ""; + this.originalTagword = ""; + this.hideBlocked = false; -// Lora keyword undo/redo history -var textBeforeKeywordInsertion = ""; -var textAfterKeywordInsertion = ""; -var lastEditWasKeywordInsertion = false; -var keywordInsertionUndone = false; + // Tag selection for keyboard navigation + this.selectedTag = null; + this.oldSelectedTag = null; + this.resultCountBeforeNormalTags = 0; -// UMI -var umiPreviousTags = []; + // Lora keyword undo/redo history + this.textBeforeKeywordInsertion = ""; + this.textAfterKeywordInsertion = ""; + this.lastEditWasKeywordInsertion = false; + this.keywordInsertionUndone = false; + + // UMI + this.umiPreviousTags = []; +}; /// Extendability system: /// Provides "queues" for other files of the script (or really any js) /// to add functions to be called at certain points in the script. /// Similar to a callback system, but primitive. +TAC.Parsers = new function() { + // Queues + this.QUEUE_AFTER_INSERT = []; + this.QUEUE_AFTER_SETUP = []; + this.QUEUE_FILE_LOAD = []; + this.QUEUE_AFTER_CONFIG_CHANGE = []; + this.QUEUE_SANITIZE = []; -// Queues -const QUEUE_AFTER_INSERT = []; -const QUEUE_AFTER_SETUP = []; -const QUEUE_FILE_LOAD = []; -const QUEUE_AFTER_CONFIG_CHANGE = []; -const QUEUE_SANITIZE = []; - -// List of parsers to try -const PARSERS = []; \ No newline at end of file + // List of parsers to try + this.PARSERS = []; +} \ No newline at end of file diff --git a/javascript/_utils.js b/javascript/_utils.js index cb86b49..7390d3c 100644 --- a/javascript/_utils.js +++ b/javascript/_utils.js @@ -259,13 +259,13 @@ class TacUtils { */ static calculateUsageBias(result, count, uses) { // Check setting conditions - if (uses < TAC_CFG.frequencyMinCount) { + if (uses < TAC.Globals.CFG.frequencyMinCount) { uses = 0; } else if (uses != 0) { result.usageBias = true; } - switch (TAC_CFG.frequencyFunction) { + switch (TAC.Globals.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_CFG.modelSortOrder || "Name"; + let criterion = TAC.Globals.CFG.modelSortOrder || "Name"; const textSort = (a, b, reverse = false) => { // Assign keys so next sort is faster diff --git a/javascript/ext_chants.js b/javascript/ext_chants.js index 6cba806..802f5d6 100644 --- a/javascript/ext_chants.js +++ b/javascript/ext_chants.js @@ -1,5 +1,5 @@ const CHANT_REGEX = /<(?!e:|h:|l:)[^,> ]*>?/g; -const CHANT_TRIGGER = () => TAC_CFG.chantFile && TAC_CFG.chantFile !== "None" && tagword.match(CHANT_REGEX); +const CHANT_TRIGGER = () => TAC.Globals.CFG.chantFile && TAC.Globals.CFG.chantFile !== "None" && tagword.match(CHANT_REGEX); class ChantParser extends BaseTagParser { parse() { @@ -31,9 +31,9 @@ class ChantParser extends BaseTagParser { } async function load() { - if (TAC_CFG.chantFile && TAC_CFG.chantFile !== "None") { + if (TAC.Globals.CFG.chantFile && TAC.Globals.CFG.chantFile !== "None") { try { - chants = await TacUtils.readFile(`${tagBasePath}/${TAC_CFG.chantFile}?`, true); + chants = await TacUtils.readFile(`${tagBasePath}/${TAC.Globals.CFG.chantFile}?`, true); } catch (e) { console.error("Error loading chants.json: " + e); } diff --git a/javascript/ext_embeddings.js b/javascript/ext_embeddings.js index b1ff607..6b05daa 100644 --- a/javascript/ext_embeddings.js +++ b/javascript/ext_embeddings.js @@ -1,5 +1,5 @@ const EMB_REGEX = /<(?!l:|h:|c:)[^,> ]*>?/g; -const EMB_TRIGGER = () => TAC_CFG.useEmbeddings && (tagword.match(EMB_REGEX) || TAC_CFG.includeEmbeddingsInNormalResults); +const EMB_TRIGGER = () => TAC.Globals.CFG.useEmbeddings && (tagword.match(EMB_REGEX) || TAC.Globals.CFG.includeEmbeddingsInNormalResults); class EmbeddingParser extends BaseTagParser { parse() { diff --git a/javascript/ext_hypernets.js b/javascript/ext_hypernets.js index b2851ba..8d86fae 100644 --- a/javascript/ext_hypernets.js +++ b/javascript/ext_hypernets.js @@ -1,5 +1,5 @@ const HYP_REGEX = /<(?!e:|l:|c:)[^,> ]*>?/g; -const HYP_TRIGGER = () => TAC_CFG.useHypernetworks && tagword.match(HYP_REGEX); +const HYP_TRIGGER = () => TAC.Globals.CFG.useHypernetworks && 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 ``; + return ``; } return null; } diff --git a/javascript/ext_loras.js b/javascript/ext_loras.js index e8a9d91..4615e31 100644 --- a/javascript/ext_loras.js +++ b/javascript/ext_loras.js @@ -1,5 +1,5 @@ const LORA_REGEX = /<(?!e:|h:|c:)[^,> ]*>?/g; -const LORA_TRIGGER = () => TAC_CFG.useLoras && tagword.match(LORA_REGEX); +const LORA_TRIGGER = () => TAC.Globals.CFG.useLoras && 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_CFG.extraNetworksDefaultMultiplier; + let multiplier = TAC.Globals.CFG.extraNetworksDefaultMultiplier; let info = await TacUtils.fetchAPI(`tacapi/v1/lora-info/${text}`) if (info && info["preferred weight"]) { multiplier = info["preferred weight"]; diff --git a/javascript/ext_lycos.js b/javascript/ext_lycos.js index 8224edf..bc75c88 100644 --- a/javascript/ext_lycos.js +++ b/javascript/ext_lycos.js @@ -1,5 +1,5 @@ const LYCO_REGEX = /<(?!e:|h:|c:)[^,> ]*>?/g; -const LYCO_TRIGGER = () => TAC_CFG.useLycos && tagword.match(LYCO_REGEX); +const LYCO_TRIGGER = () => TAC.Globals.CFG.useLycos && 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_CFG.extraNetworksDefaultMultiplier; + let multiplier = TAC.Globals.CFG.extraNetworksDefaultMultiplier; let info = await TacUtils.fetchAPI(`tacapi/v1/lyco-info/${text}`) if (info && info["preferred weight"]) { multiplier = info["preferred weight"]; } - let prefix = TAC_CFG.useLoraPrefixForLycos ? "lora" : "lyco"; + let prefix = TAC.Globals.CFG.useLoraPrefixForLycos ? "lora" : "lyco"; return `<${prefix}:${text}:${multiplier}>`; } return null; diff --git a/javascript/ext_modelKeyword.js b/javascript/ext_modelKeyword.js index 570a010..1729907 100644 --- a/javascript/ext_modelKeyword.js +++ b/javascript/ext_modelKeyword.js @@ -7,7 +7,7 @@ async function load() { try { let csv_lines = []; // Only add default keywords if wanted by the user - if (TAC_CFG.modelKeywordCompletion !== "Only user list") + if (TAC.Globals.CFG.modelKeywordCompletion !== "Only user list") csv_lines = (await TacUtils.loadCSV(`${modelKeywordPath}/lora-keyword.txt`)); // Add custom user keywords if the file exists if (customFileExists) diff --git a/javascript/ext_styles.js b/javascript/ext_styles.js index a22ee8d..dacd1a9 100644 --- a/javascript/ext_styles.js +++ b/javascript/ext_styles.js @@ -1,5 +1,5 @@ const STYLE_REGEX = /(\$(\d*)\(?)[^$|\[\],\s]*\)?/; -const STYLE_TRIGGER = () => TAC_CFG.useStyleVars && tagword.match(STYLE_REGEX); +const STYLE_TRIGGER = () => TAC.Globals.CFG.useStyleVars && tagword.match(STYLE_REGEX); var lastStyleVarIndex = ""; diff --git a/javascript/ext_umi.js b/javascript/ext_umi.js index bc1d6e9..bbc8984 100644 --- a/javascript/ext_umi.js +++ b/javascript/ext_umi.js @@ -1,7 +1,7 @@ const UMI_PROMPT_REGEX = /<[^\s]*?\[[^,<>]*[\]|]?>?/gi; const UMI_TAG_REGEX = /(?:\[|\||--)([^<>\[\]\-|]+)/gi; -const UMI_TRIGGER = () => TAC_CFG.useWildcards && [...tagword.matchAll(UMI_PROMPT_REGEX)].length > 0; +const UMI_TRIGGER = () => TAC.Globals.CFG.useWildcards && [...tagword.matchAll(UMI_PROMPT_REGEX)].length > 0; class UmiParser extends BaseTagParser { parse(textArea, prompt) { diff --git a/javascript/ext_wildcards.js b/javascript/ext_wildcards.js index 7c26b53..1b6f506 100644 --- a/javascript/ext_wildcards.js +++ b/javascript/ext_wildcards.js @@ -2,13 +2,13 @@ const WC_REGEX = new RegExp(/__([^,]+)__([^, ]*)/g); // Trigger conditions -const WC_TRIGGER = () => TAC_CFG.useWildcards && [...tagword.matchAll(new RegExp(WC_REGEX.source.replaceAll("__", escapeRegExp(TAC_CFG.wcWrap)), "g"))].length > 0; -const WC_FILE_TRIGGER = () => TAC_CFG.useWildcards && (tagword.startsWith(TAC_CFG.wcWrap) && !tagword.endsWith(TAC_CFG.wcWrap) || tagword === TAC_CFG.wcWrap); +const WC_TRIGGER = () => TAC.Globals.CFG.useWildcards && [...tagword.matchAll(new RegExp(WC_REGEX.source.replaceAll("__", escapeRegExp(TAC.Globals.CFG.wcWrap)), "g"))].length > 0; +const WC_FILE_TRIGGER = () => TAC.Globals.CFG.useWildcards && (tagword.startsWith(TAC.Globals.CFG.wcWrap) && !tagword.endsWith(TAC.Globals.CFG.wcWrap) || tagword === TAC.Globals.CFG.wcWrap); class WildcardParser extends BaseTagParser { async parse() { // Show wildcards from a file with that name - let wcMatch = [...tagword.matchAll(new RegExp(WC_REGEX.source.replaceAll("__", escapeRegExp(TAC_CFG.wcWrap)), "g"))]; + let wcMatch = [...tagword.matchAll(new RegExp(WC_REGEX.source.replaceAll("__", escapeRegExp(TAC.Globals.CFG.wcWrap)), "g"))]; let wcFile = wcMatch[0][1]; let wcWord = wcMatch[0][2]; @@ -45,7 +45,7 @@ class WildcardParser extends BaseTagParser { } } - if (TAC_CFG.sortWildcardResults) + if (TAC.Globals.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 (tagword !== TAC_CFG.wcWrap) { - let lmb = (x) => x[1].toLowerCase().includes(tagword.replace(TAC_CFG.wcWrap, "")) + if (tagword !== TAC.Globals.CFG.wcWrap) { + let lmb = (x) => x[1].toLowerCase().includes(tagword.replace(TAC.Globals.CFG.wcWrap, "")) tempResults = wildcardFiles.filter(lmb).concat(wildcardExtFiles.filter(lmb)) // Filter by tagword } else { tempResults = wildcardFiles.concat(wildcardExtFiles); @@ -151,7 +151,7 @@ async function load() { function sanitize(tagType, text) { if (tagType === ResultType.wildcardFile || tagType === ResultType.yamlWildcard) { - return `${TAC_CFG.wcWrap}${text}${TAC_CFG.wcWrap}`; + return `${TAC.Globals.CFG.wcWrap}${text}${TAC.Globals.CFG.wcWrap}`; } else if (tagType === ResultType.wildcardTag) { return text; } diff --git a/javascript/tagAutocomplete.js b/javascript/tagAutocomplete.js index 553fd6c..ddd00ea 100644 --- a/javascript/tagAutocomplete.js +++ b/javascript/tagAutocomplete.js @@ -280,20 +280,20 @@ async function syncOptions() { } // Reload translations if the translation file changed - if (!TAC_CFG || newCFG.translation.translationFile !== TAC_CFG.translation.translationFile) { + if (!TAC.Globals.CFG || newCFG.translation.translationFile !== TAC.Globals.CFG.translation.translationFile) { 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_CFG || newCFG.tagFile !== TAC_CFG.tagFile || newCFG.extra.extraFile !== TAC_CFG.extra.extraFile) { + if (!TAC.Globals.CFG || newCFG.tagFile !== TAC.Globals.CFG.tagFile || newCFG.extra.extraFile !== TAC.Globals.CFG.extra.extraFile) { 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_CFG && newCFG.modelSortOrder !== TAC_CFG.modelSortOrder) { + if (TAC.Globals.CFG && newCFG.modelSortOrder !== TAC.Globals.CFG.modelSortOrder) { const dropdown = gradioApp().querySelector("#setting_tac_modelSortOrder"); dropdown.style.opacity = 0.5; dropdown.style.pointerEvents = "none"; @@ -303,7 +303,7 @@ async function syncOptions() { } // Update CSS if maxResults changed - if (TAC_CFG && newCFG.maxResults !== TAC_CFG.maxResults) { + if (TAC.Globals.CFG && newCFG.maxResults !== TAC.Globals.CFG.maxResults) { gradioApp().querySelectorAll(".autocompleteResults").forEach(r => { r.style.maxHeight = `${newCFG.maxResults * 50}px`; }); @@ -317,7 +317,7 @@ async function syncOptions() { } // Apply changes - TAC_CFG = newCFG; + TAC.Globals.CFG = newCFG; // Callback await TacUtils.processQueue(QUEUE_AFTER_CONFIG_CHANGE, null); @@ -336,7 +336,7 @@ function createResultsDiv(textArea) { parentDiv.setAttribute("class", `autocompleteParent${typeClass}`); - resultsDiv.style.maxHeight = `${TAC_CFG.maxResults * 50}px`; + resultsDiv.style.maxHeight = `${TAC.Globals.CFG.maxResults * 50}px`; resultsDiv.setAttribute("class", `autocompleteResults${typeClass} notranslate`); resultsDiv.setAttribute("translate", "no"); resultsList.setAttribute("class", "autocompleteResultsList"); @@ -362,7 +362,7 @@ function showResults(textArea) { let parentDiv = gradioApp().querySelector('.autocompleteParent' + textAreaId); parentDiv.style.display = "flex"; - if (TAC_CFG.slidingPopup) { + if (TAC.Globals.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 +393,18 @@ function hideResults(textArea) { // Function to check activation criteria function isEnabled() { - if (TAC_CFG.activeIn.global) { + if (TAC.Globals.CFG.activeIn.global) { // Skip check if the current model was not correctly detected, since it could wrongly disable the script otherwise if (!currentModelName || !currentModelHash) return true; - let modelList = TAC_CFG.activeIn.modelList + let modelList = TAC.Globals.CFG.activeIn.modelList .split(",") .map(x => x.trim()) .filter(x => x.length > 0); let shortHash = currentModelHash.substring(0, 10); let modelNameWithoutHash = currentModelName.replace(/\[.*\]$/g, "").trim(); - if (TAC_CFG.activeIn.modelListMode.toLowerCase() === "blacklist") { + if (TAC.Globals.CFG.activeIn.modelListMode.toLowerCase() === "blacklist") { // If the current model is in the blacklist, disable return modelList.filter(x => x === currentModelName || x === modelNameWithoutHash || x === currentModelHash || x === shortHash).length === 0; } else { @@ -423,7 +423,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 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"); } +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"); } // 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 +439,13 @@ async function insertTextAtCursor(textArea, result, tagword, tabCompletedWithout if (sanitizeResults && sanitizeResults.length > 0) { sanitizedText = sanitizeResults[0]; } else { - const excluded_tags = TAC_CFG.replaceUnderscoresExclusionList?.split(',').map(s => s.trim()) || []; - if (TAC_CFG.replaceUnderscores && !excluded_tags.includes(sanitizedText)) { + const excluded_tags = TAC.Globals.CFG.replaceUnderscoresExclusionList?.split(',').map(s => s.trim()) || []; + if (TAC.Globals.CFG.replaceUnderscores && !excluded_tags.includes(sanitizedText)) { sanitizedText = text.replaceAll("_", " ") } else { sanitizedText = text; } - if (TAC_CFG.escapeParentheses && tagType === ResultType.tag) { + if (TAC.Globals.CFG.escapeParentheses && tagType === ResultType.tag) { sanitizedText = sanitizedText .replaceAll("(", "\\(") .replaceAll(")", "\\)") @@ -456,9 +456,9 @@ async function insertTextAtCursor(textArea, result, tagword, tabCompletedWithout if ((tagType === ResultType.wildcardFile || tagType === ResultType.yamlWildcard) && tabCompletedWithoutChoice - && TAC_CFG.wildcardCompletionMode !== "Always fully" + && TAC.Globals.CFG.wildcardCompletionMode !== "Always fully" && sanitizedText.includes("/")) { - if (TAC_CFG.wildcardCompletionMode === "To next folder level") { + if (TAC.Globals.CFG.wildcardCompletionMode === "To next folder level") { let regexMatch = sanitizedText.match(new RegExp(`${TacUtils.escapeRegExp(tagword)}([^/]*\\/?)`, "i")); if (regexMatch) { let pathPart = regexMatch[0]; @@ -468,7 +468,7 @@ async function insertTextAtCursor(textArea, result, tagword, tabCompletedWithout } sanitizedText = pathPart; } - } else if (TAC_CFG.wildcardCompletionMode === "To first difference") { + } else if (TAC.Globals.CFG.wildcardCompletionMode === "To first difference") { let firstDifference = 0; let longestResult = 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 +483,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_CFG.wcWrap.length); + sanitizedText = sanitizedText.substring(0, firstDifference + TAC.Globals.CFG.wcWrap.length); } else if (firstDifference === 0) { sanitizedText = tagword; } @@ -491,14 +491,14 @@ async function insertTextAtCursor(textArea, result, tagword, tabCompletedWithout } // Frequency db update - if (TAC_CFG.frequencySort) { + if (TAC.Globals.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_CFG.wcWrap)) + if (sanitizedText.endsWith(TAC.Globals.CFG.wcWrap)) name = text break; case ResultType.chant: @@ -536,17 +536,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_CFG.appendComma) + if (TAC.Globals.CFG.appendComma) optionalSeparator = beforeComma ? "" : ","; // Add space if enabled - if (TAC_CFG.appendSpace && !beforeComma) + if (TAC.Globals.CFG.appendSpace && !beforeComma) optionalSeparator += " "; // If at end of prompt and enabled, override the normal setting if not already added - if (!TAC_CFG.appendSpace && TAC_CFG.alwaysSpaceAtEnd) + if (!TAC.Globals.CFG.appendSpace && TAC.Globals.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_CFG.extraNetworksSeparator || " "; + optionalSeparator = TAC.Globals.CFG.extraNetworksSeparator || " "; } // Escape $ signs since they are special chars for the replace function @@ -562,7 +562,7 @@ async function insertTextAtCursor(textArea, result, tagword, tabCompletedWithout // Add lora/lyco keywords if enabled and found let keywordsLength = 0; - if (TAC_CFG.modelKeywordCompletion !== "Never" && (tagType === ResultType.lora || tagType === ResultType.lyco)) { + if (TAC.Globals.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 +601,9 @@ async function insertTextAtCursor(textArea, result, tagword, tabCompletedWithout if (keywords && keywords.length > 0) { textBeforeKeywordInsertion = newPrompt; - if (TAC_CFG.modelKeywordLocation === "Start of prompt") + if (TAC.Globals.CFG.modelKeywordLocation === "Start of prompt") newPrompt = `${keywords}, ${newPrompt}`; // Insert keywords - else if (TAC_CFG.modelKeywordLocation === "End of prompt") + else if (TAC.Globals.CFG.modelKeywordLocation === "End of prompt") newPrompt = `${newPrompt}, ${keywords}`; // Insert keywords else { let keywordStart = prompt[editStart - 1] === " " ? editStart - 1 : editStart; @@ -688,10 +688,10 @@ function addResultsToList(textArea, results, tagword, resetList) { } // Find right colors from config - let tagFileName = TAC_CFG.tagFile.split(".")[0]; - let tagColors = TAC_CFG.colorMap; + let tagFileName = TAC.Globals.CFG.tagFile.split(".")[0]; + let tagColors = TAC.Globals.CFG.colorMap; let mode = (document.querySelector(".dark") || gradioApp().querySelector(".dark")) ? 0 : 1; - let nextLength = Math.min(results.length, resultCount + TAC_CFG.resultStepLength); + let nextLength = Math.min(results.length, resultCount + TAC.Globals.CFG.resultStepLength); const IS_DAN_OR_E621_TAG_FILE = (tagFileName.toLowerCase().startsWith("danbooru") || tagFileName.toLowerCase().startsWith("e621")); const tagCount = {}; @@ -758,7 +758,7 @@ function addResultsToList(textArea, results, tagword, resetList) { if (translations.has(bestAlias) && translations.get(bestAlias) !== bestAlias && bestAlias !== result.text) displayText += `[${translations.get(bestAlias)}]`; - if (!TAC_CFG.alias.onlyShowAlias && result.text !== bestAlias) + if (!TAC.Globals.CFG.alias.onlyShowAlias && result.text !== bestAlias) displayText += " ➝ " + result.text; } else { // No alias displayText = TacUtils.escapeHTML(result.text); @@ -782,7 +782,7 @@ function addResultsToList(textArea, results, tagword, resetList) { // Add wiki link if the setting is enabled and a supported tag set loaded if ( - TAC_CFG.showWikiLinks && + TAC.Globals.CFG.showWikiLinks && result.type === ResultType.tag && IS_DAN_OR_E621_TAG_FILE ) { @@ -906,7 +906,7 @@ function addResultsToList(textArea, results, tagword, resetList) { }); // Add delayed hover listener for extra network previews if ( - TAC_CFG.showExtraNetworkPreviews && + TAC.Globals.CFG.showExtraNetworkPreviews && [ ResultType.embedding, ResultType.hypernetwork, @@ -976,7 +976,7 @@ async function updateSelectionStyle(textArea, newIndex, oldIndex, scroll = true) let previewDiv = gradioApp().querySelector(`.autocompleteParent${textAreaId} .sideInfo`); - if (TAC_CFG.showExtraNetworkPreviews && previewTypes.includes(selectedType)) { + if (TAC.Globals.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 +995,8 @@ async function updateSelectionStyle(textArea, newIndex, oldIndex, scroll = true) } function updateRuby(textArea, prompt) { - if (!TAC_CFG.translation.liveTranslation) return; - if (!TAC_CFG.translation.translationFile || TAC_CFG.translation.translationFile === "None") return; + if (!TAC.Globals.CFG.translation.liveTranslation) return; + if (!TAC.Globals.CFG.translation.translationFile || TAC.Globals.CFG.translation.translationFile === "None") return; let ruby = gradioApp().querySelector('.acRuby' + getTextAreaIdentifier(textArea)); if (!ruby) { @@ -1101,7 +1101,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_CFG.modelKeywordCompletion === "Never") return; + if (TAC.Globals.CFG.modelKeywordCompletion === "Never") return; switch (event.inputType) { case "historyUndo": @@ -1221,7 +1221,7 @@ async function autocomplete(textArea, prompt, fixedTag = null) { } // Else search the normal tag list if (!resultCandidates || resultCandidates.length === 0 - || (TAC_CFG.includeEmbeddingsInNormalResults && !(tagword.startsWith("<") || tagword.startsWith("*<"))) + || (TAC.Globals.CFG.includeEmbeddingsInNormalResults && !(tagword.startsWith("<") || tagword.startsWith("*<"))) ) { normalTags = true; resultCountBeforeNormalTags = results.length; @@ -1242,11 +1242,11 @@ async function autocomplete(textArea, prompt, fixedTag = null) { || x[3] && x[3].split(",").some(y => translations.has(y) && translations.get(y).toLowerCase().search(searchRegex) > -1); let fil; - if (TAC_CFG.alias.searchByAlias && TAC_CFG.translation.searchByTranslation) + if (TAC.Globals.CFG.alias.searchByAlias && TAC.Globals.CFG.translation.searchByTranslation) fil = (x) => baseFilter(x) || aliasFilter(x) || translationFilter(x); - else if (TAC_CFG.alias.searchByAlias && !TAC_CFG.translation.searchByTranslation) + else if (TAC.Globals.CFG.alias.searchByAlias && !TAC.Globals.CFG.translation.searchByTranslation) fil = (x) => baseFilter(x) || aliasFilter(x); - else if (TAC_CFG.translation.searchByTranslation && !TAC_CFG.alias.searchByAlias) + else if (TAC.Globals.CFG.translation.searchByTranslation && !TAC.Globals.CFG.alias.searchByAlias) fil = (x) => baseFilter(x) || translationFilter(x); else fil = (x) => baseFilter(x); @@ -1261,7 +1261,7 @@ async function autocomplete(textArea, prompt, fixedTag = null) { }); // Add extras - if (TAC_CFG.extra.extraFile) { + if (TAC.Globals.CFG.extra.extraFile) { let extraResults = []; extras.filter(fil).forEach(e => { @@ -1272,7 +1272,7 @@ async function autocomplete(textArea, prompt, fixedTag = null) { extraResults.push(result); }); - if (TAC_CFG.extra.addMode === "Insert before") { + if (TAC.Globals.CFG.extra.addMode === "Insert before") { results = extraResults.concat(results); } else { results = results.concat(extraResults); @@ -1288,7 +1288,7 @@ async function autocomplete(textArea, prompt, fixedTag = null) { } // Sort again with frequency / usage count if enabled - if (TAC_CFG.frequencySort) { + if (TAC.Globals.CFG.frequencySort) { // Split our results into a list of names and types let tagNames = []; let aliasNames = []; @@ -1312,7 +1312,7 @@ async function autocomplete(textArea, prompt, fixedTag = null) { let isNegative = textAreaId.includes("n"); // Request use counts from the DB - const names = TAC_CFG.frequencyIncludeAlias ? tagNames.concat(aliasNames) : tagNames; + const names = TAC.Globals.CFG.frequencyIncludeAlias ? tagNames.concat(aliasNames) : tagNames; const counts = await TacUtils.getUseCounts(names, types, isNegative) || []; // Pre-calculate weights to prevent duplicate work @@ -1334,8 +1334,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_CFG.showAllResults && normalTags) { - results = results.slice(0, TAC_CFG.maxResults + resultCountBeforeNormalTags); + if (!TAC.Globals.CFG.showAllResults && normalTags) { + results = results.slice(0, TAC.Globals.CFG.maxResults + resultCountBeforeNormalTags); } addResultsToList(textArea, results, tagword, true); @@ -1346,7 +1346,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_CFG.keymap; + let keys = TAC.Globals.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 +1400,7 @@ function navigateInList(textArea, event) { } break; case keys["JumpToStart"]: - if (TAC_CFG.includeEmbeddingsInNormalResults && + if (TAC.Globals.CFG.includeEmbeddingsInNormalResults && selectedTag > resultCountBeforeNormalTags && resultCountBeforeNormalTags > 0 ) { @@ -1411,7 +1411,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_CFG.includeEmbeddingsInNormalResults && + if (TAC.Globals.CFG.includeEmbeddingsInNormalResults && selectedTag < resultCountBeforeNormalTags && resultCountBeforeNormalTags > 0 ) { @@ -1433,7 +1433,7 @@ function navigateInList(textArea, event) { if (selectedTag === null) { selectedTag = 0; withoutChoice = true; - } else if (TAC_CFG.wildcardCompletionMode === "To next folder level") { + } else if (TAC.Globals.CFG.wildcardCompletionMode === "To next folder level") { withoutChoice = true; } insertTextAtCursor(textArea, results[selectedTag], tagword, withoutChoice); @@ -1492,10 +1492,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_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"))) { + 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"))) { return; } @@ -1521,7 +1521,7 @@ function addAutocompleteToArea(area) { setTimeout(() => { hideBlocked = false; }, 100); } - TacUtils.debounce(autocomplete(area, area.value), TAC_CFG.delayTime); + TacUtils.debounce(autocomplete(area, area.value), TAC.Globals.CFG.delayTime); checkKeywordInsertionUndo(area, e); }); // Add focusout event listener @@ -1617,10 +1617,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_CFG.activeIn.negativePrompts) { + if (gradioApp().querySelector('.autocompleteParent.n') || !TAC.Globals.CFG.activeIn.negativePrompts) { return; } - } else if (!TAC_CFG.activeIn.txt2img && !TAC_CFG.activeIn.img2img) { + } else if (!TAC.Globals.CFG.activeIn.txt2img && !TAC.Globals.CFG.activeIn.img2img) { return; } @@ -1655,7 +1655,7 @@ var tacLoading = false; onUiUpdate(async () => { if (tacLoading) return; if (Object.keys(opts).length === 0) return; - if (TAC_CFG) return; + if (TAC.Globals.CFG) return; tacLoading = true; // Get our tag base path from the temp file tagBasePath = await TacUtils.readFile(`tmp/tagAutocompletePath.txt`);