diff --git a/javascript/prompt_format.js b/javascript/prompt_format.js index 5fa784c..705e111 100644 --- a/javascript/prompt_format.js +++ b/javascript/prompt_format.js @@ -1,27 +1,13 @@ class LeFormatter { - // ===== Cache Embedding & LoRA Prompts ===== - static cachedCards = null; + static #cachedCards = null; - static cacheCards() { - this.cachedCards = []; - - const extras = document.getElementById('txt2img_extra_tabs')?.querySelectorAll('span.name'); - if (extras == null) - return; - - extras.forEach((card) => { - if (card.textContent.includes('_')) - this.cachedCards.push(card.textContent); - }); - } - - // ===== Main Format Logics ===== + /** @param {Element} textArea @param {boolean} dedupe @param {boolean} removeUnderscore @param {boolean} autoRefresh */ static formatPipeline(textArea, dedupe, removeUnderscore, autoRefresh) { const lines = textArea.value.split('\n'); for (let i = 0; i < lines.length; i++) - lines[i] = LeFormatter.formatString(lines[i], dedupe, removeUnderscore); + lines[i] = this.#formatString(lines[i], dedupe, removeUnderscore); textArea.value = lines.join('\n'); @@ -29,159 +15,130 @@ class LeFormatter { updateInput(textArea); } - static removeUnderscoreSmart(remove, tag) { - if (!remove) - return tag; - - if (this.cachedCards == null) - this.cacheCards(); - - // [start:end:step] OR - const chucks = tag.split(':').map(c => c.trim()); - - for (let i = 0; i < chucks.length; i++) { - if (!this.cachedCards.includes(chucks[i])) - chucks[i] = chucks[i].replace(/_/g, ' '); - } - - return chucks.join(':'); - } - - static formatString(input, dedupe, removeUnderscore) { + /** @param {string} input @param {boolean} dedupe @param {boolean} removeUnderscore @returns {string} */ + static #formatString(input, dedupe, removeUnderscore) { // Remove Duplicate - if (dedupe) { - const temp = input.split(','); + if (dedupe) + input = this.#dedupe(input); - const cleanArray = []; - const finalArray = []; + // Fix Commas inside Brackets + input = input + .replace(/,+\s*\)/g, '),') + .replace(/,+\s*\]/g, '],') + .replace(/\(\s*,+/g, ',(') + .replace(/\[\s*,+/g, ',['); - temp.forEach((tag) => { - const cleanedTag = tag.replace(/\[|\]|\(|\)|\s+/g, '').trim(); + // Sentence -> Tags + var tags = input.split(','); - if (/^(AND|BREAK)$/.test(cleanedTag)) { - finalArray.push(cleanedTag); - return; - } - - if (!cleanArray.includes(cleanedTag)) { - cleanArray.push(cleanedTag); - finalArray.push(tag); - return; - } - - finalArray.push(tag.replace(cleanedTag, '')); - }); - - input = finalArray.join(', '); + // Remove Underscore + if (removeUnderscore) { + if (this.#cachedCards == null) + this.#cachedCards = LeFormatterConfig.cacheCards(); + tags = this.#removeUnderscore(tags); } - // Fix Bracket & Comma - input = input.replace(/,\s*\)/g, '),').replace(/,\s*\]/g, '],').replace(/\(\s*,/g, ',(').replace(/\[\s*,/g, ',['); - - // Remove Commas - let tags = input.split(',').map(word => this.removeUnderscoreSmart(removeUnderscore, word.trim())).filter(word => word !== ''); - // Remove Stray Brackets - const patterns = [/^\(+$/, /^\)+$/, /^\[+$/, /^\]+$/]; - tags = tags.filter(word => !patterns[0].test(word)).filter(word => !patterns[1].test(word)).filter(word => !patterns[2].test(word)).filter(word => !patterns[3].test(word)); + const patterns = /^\(+$|^\)+$|^\[+$|^\]+$/; + tags = tags.filter(word => !patterns.test(word)); - // Remove Spaces - input = tags.join(', ').replace(/\s+/g, ' '); + // Remove extra Spaces + input = tags.join(', ').replace(/\s{2,}/g, ' '); // Fix Bracket & Space - input = input.replace(/\s+\)/g, ')').replace(/\s+\]/g, ']').replace(/\(\s+/g, '(').replace(/\[\s+/g, '['); + input = input + .replace(/\s\)/g, ')') + .replace(/\s\]/g, ']') + .replace(/\(\s/g, '(') + .replace(/\[\s/g, '['); // Fix Empty Bracket - input = input.replace(/\(\s+\)/g, '').replace(/\[\s+\]/g, ''); - - // Remove Empty Brackets while (input.match(/\(\s*\)|\[\s*\]/g)) input = input.replace(/\(\s*\)|\[\s*\]/g, ''); - return input.split(',').map(word => word.trim()).filter(word => word !== '').join(', '); + return input.split(',').map(word => word.trim()).filter(word => word).join(', '); } - // ===== Load Settings ===== - /** @returns {boolean} */ - static shouldRefresh() { - const config = gradioApp().getElementById('setting_pf_disableupdateinput').querySelector('input[type=checkbox]'); - return !config.checked; - } + /** @param {string} input @returns {string} */ + static #dedupe(input) { + const chunks = input.split(','); - /** @returns {boolean} */ - static defaultAuto() { - const config = gradioApp().getElementById('setting_pf_startinauto').querySelector('input[type=checkbox]'); - return config.checked; - } + const uniqueSet = new Set(); + const resultArray = []; + const KEYWORD = /^(AND|BREAK)$/; - /** @returns {boolean} */ - static defaultDedupe() { - const config = gradioApp().getElementById('setting_pf_startwithdedupe').querySelector('input[type=checkbox]'); - return config.checked; - } + chunks.forEach((tag) => { + const cleanedTag = tag.replace(/\[|\]|\(|\)|\s+/g, '').trim(); - /** @returns {boolean} */ - static defaultRemoveUnderscore() { - const config = gradioApp().getElementById('setting_pf_startwithrmudscr').querySelector('input[type=checkbox]'); - return config.checked; - } + if (KEYWORD.test(cleanedTag)) { + resultArray.push(tag); + return; + } - // ===== Cache All Prompt Fields ===== - /** @returns {Array} */ - static getPromptFields() { - const textareas = []; + if (!uniqueSet.has(cleanedTag)) { + uniqueSet.add(cleanedTag); + resultArray.push(tag); + return; + } - // Expandable ID List in 1 place - [ - 'txt2img_prompt', - 'txt2img_neg_prompt', - 'img2img_prompt', - 'img2img_neg_prompt', - 'hires_prompt', - 'hires_neg_prompt' - ].forEach((id) => { - const textArea = gradioApp().getElementById(id)?.querySelector('textarea'); - if (textArea != null) - textareas.push(textArea); + resultArray.push(tag.replace(cleanedTag, '')); }); - return textareas; + return resultArray.join(', '); + } + + /** @param {Array { + if (!tag.trim()) + return; + + // [start:end:step] OR + const chucks = tag.split(':').map(c => c.trim()); + + for (let i = 0; i < chucks.length; i++) { + if (!this.#cachedCards.includes(chucks[i])) + chucks[i] = chucks[i].replace(/_/g, ' '); + } + + result.push(chucks.join(':').trim()); + }); + + return result; } } onUiLoaded(async () => { - const promptFields = LeFormatter.getPromptFields(); - const refresh = LeFormatter.shouldRefresh(); - var autoRun = LeFormatter.defaultAuto(); - var dedupe = LeFormatter.defaultDedupe(); - var removeUnderscore = LeFormatter.defaultRemoveUnderscore(); + const config = new LeFormatterConfig(); document.addEventListener('keydown', (e) => { if (e.altKey && e.shiftKey && e.code === 'KeyF') { e.preventDefault(); - promptFields.forEach((field) => LeFormatter.formatPipeline(field, dedupe, removeUnderscore, true)); + config.promptFields.forEach((field) => LeFormatter.formatPipeline(field, config.dedupe, config.removeUnderscore, true)); } }); const formatter = LeFormatterUI.setupUIs( () => { - promptFields.forEach((field) => LeFormatter.formatPipeline(field, dedupe, removeUnderscore, true)); + config.promptFields.forEach((field) => LeFormatter.formatPipeline(field, config.dedupe, config.removeUnderscore, true)); }, - autoRun, dedupe, removeUnderscore + config.autoRun, config.dedupe, config.removeUnderscore ); formatter.checkboxs[0].addEventListener("change", (e) => { - autoRun = e.target.checked; - formatter.btn.style.display = autoRun ? 'none' : 'flex'; + config.autoRun = e.target.checked; + formatter.btn.style.display = config.autoRun ? 'none' : 'flex'; }); formatter.checkboxs[1].addEventListener("change", (e) => { - dedupe = e.target.checked; + config.dedupe = e.target.checked; }); formatter.checkboxs[2].addEventListener("change", (e) => { - removeUnderscore = e.target.checked; + config.removeUnderscore = e.target.checked; }); const tools = document.getElementById('quicksettings'); @@ -192,13 +149,13 @@ onUiLoaded(async () => { const enqueueButton = gradioApp().getElementById(`${mode}2img_enqueue`); generateButton?.addEventListener('click', () => { - if (autoRun) - promptFields.forEach((field) => LeFormatter.formatPipeline(field, dedupe, removeUnderscore, refresh)); + if (config.autoRun) + config.promptFields.forEach((field) => LeFormatter.formatPipeline(field, config.dedupe, config.removeUnderscore, config.refresh)); }); enqueueButton?.addEventListener('click', () => { - if (autoRun) - promptFields.forEach((field) => LeFormatter.formatPipeline(field, dedupe, removeUnderscore, refresh)); + if (config.autoRun) + config.promptFields.forEach((field) => LeFormatter.formatPipeline(field, config.dedupe, config.removeUnderscore, config.refresh)); }); }); }); diff --git a/javascript/prompt_format_Configs.js b/javascript/prompt_format_Configs.js new file mode 100644 index 0000000..3d6ee5e --- /dev/null +++ b/javascript/prompt_format_Configs.js @@ -0,0 +1,71 @@ +class LeFormatterConfig { + + constructor() { + this.refresh = this.#shouldRefresh(); + this.autoRun = this.#defaultAuto(); + this.dedupe = this.#defaultDedupe(); + this.removeUnderscore = this.#defaultRemoveUnderscore(); + this.promptFields = this.#getPromptFields(); + } + + /** @returns {boolean} */ + #shouldRefresh() { + const config = gradioApp().getElementById('setting_pf_disableupdateinput').querySelector('input[type=checkbox]'); + return !config.checked; + } + + /** @returns {boolean} */ + #defaultAuto() { + const config = gradioApp().getElementById('setting_pf_startinauto').querySelector('input[type=checkbox]'); + return config.checked; + } + + /** @returns {boolean} */ + #defaultDedupe() { + const config = gradioApp().getElementById('setting_pf_startwithdedupe').querySelector('input[type=checkbox]'); + return config.checked; + } + + /** @returns {boolean} */ + #defaultRemoveUnderscore() { + const config = gradioApp().getElementById('setting_pf_startwithrmudscr').querySelector('input[type=checkbox]'); + return config.checked; + } + + // ===== Cache All Prompt Fields ===== + /** @returns {Array} */ + #getPromptFields() { + const textareas = []; + + // Expandable ID List in 1 place + [ + 'txt2img_prompt', + 'txt2img_neg_prompt', + 'img2img_prompt', + 'img2img_neg_prompt', + 'hires_prompt', + 'hires_neg_prompt' + ].forEach((id) => { + const textArea = gradioApp().getElementById(id)?.querySelector('textarea'); + if (textArea != null) + textareas.push(textArea); + }); + + return textareas; + } + + /** @returns {Array} */ + static cacheCards() { + const extras = gradioApp().getElementById('txt2img_extra_tabs'); + if (!extras) + return []; + + const cards = []; + extras.querySelectorAll('span.name').forEach((card) => { + if (card.textContent.includes('_')) + cards.push(card.textContent); + }); + + return cards; + } +}