mirror of
https://github.com/DominikDoom/a1111-sd-webui-tagcomplete.git
synced 2026-01-26 11:09:54 +00:00
Use new TAC.Globals namespace for CFG
This commit is contained in:
@@ -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 = [];
|
||||
// List of parsers to try
|
||||
this.PARSERS = [];
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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 `<hypernet:${text}:${TAC_CFG.extraNetworksDefaultMultiplier}>`;
|
||||
return `<hypernet:${text}:${TAC.Globals.CFG.extraNetworksDefaultMultiplier}>`;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -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"];
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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 = "";
|
||||
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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 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_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`);
|
||||
|
||||
Reference in New Issue
Block a user