optimization

pull/8/head
Haoming 2024-01-15 12:14:04 +08:00
parent 6f6f92bf8b
commit 3939e6193b
1 changed files with 156 additions and 164 deletions

View File

@ -1,158 +1,153 @@
class LeFormatter { class LeFormatter {
// ===== Cache Embedding & LoRA Prompts ===== // ===== Cache Embedding & LoRA Prompts =====
static cachedCards = null static cachedCards = null;
static cache_Cards() { static cache_Cards() {
this.cachedCards = [] this.cachedCards = [];
const extras = document.getElementById('txt2img_extra_tabs').querySelectorAll('span.name') const extras = document.getElementById('txt2img_extra_tabs').querySelectorAll('span.name');
extras.forEach((card) => { extras.forEach((card) => {
if (card.innerHTML.includes('_')) if (card.textContent.includes('_'))
this.cachedCards.push(card.innerHTML) this.cachedCards.push(card.textContent);
}) });
} }
// ===== UI Related ===== // ===== UI Related =====
static manualButton({ onClick }) { static manualButton({ onClick }) {
const button = gradioApp().getElementById('txt2img_generate').cloneNode() const button = gradioApp().getElementById('txt2img_extra_refresh').cloneNode();
button.id = 'manual-format' button.id = 'manual-format';
button.classList.remove('gr-button-lg', 'gr-button-primary', 'lg', 'primary') button.textContent = 'Format';
button.classList.add('secondary') button.style.padding = '2px 8px';
button.style.borderRadius = '0.5em' button.style.borderRadius = '0.2em';
button.textContent = 'Format' button.style.fontWeight = 'var(--button-small-text-weight)';
button.style.fontSize = 'var(--button-small-text-size)';
button.addEventListener('click', onClick) button.addEventListener('click', onClick);
return button return button;
} }
static injectButton(id, { onClick }) { static injectButton(id, { onClick }) {
const button = gradioApp().getElementById(id) const button = gradioApp().getElementById(id);
button.addEventListener('click', onClick) button.addEventListener('click', onClick);
} }
static checkbox(text, default_value, { onChange }) { static checkbox(text, default_value, { onChange }) {
const label = document.createElement('label') const label = gradioApp().getElementById('tab_settings').querySelector('input[type=checkbox]').parentNode.cloneNode(true);
label.removeAttribute('id');
label.style.display = 'flex' const checkbox = label.children[0];
label.style.alignItems = 'center'
label.style.margin = '2px 8px'
const checkbox = gradioApp().querySelector('input[type=checkbox]').cloneNode() checkbox.checked = default_value;
checkbox.checked = default_value
checkbox.addEventListener('change', (event) => { checkbox.addEventListener('change', (event) => {
onChange(event.target.checked) onChange(event.target.checked);
}) });
const span = document.createElement('span') const span = label.children[1];
span.style.marginLeft = 'var(--size-2, 4px)' span.textContent = text;
span.textContent = text
label.appendChild(checkbox) label.style.display = 'flex';
label.appendChild(span) label.style.alignItems = 'center';
label.style.margin = '2px 8px';
return label return label;
} }
// ===== Main Format Logics ===== // ===== Main Format Logics =====
static formatPipeline(id, dedupe, removeUnderscore, autoRefresh) { static formatPipeline(id, dedupe, removeUnderscore, autoRefresh) {
let textArea = null const textArea = gradioApp().getElementById(id)?.querySelector('textarea');
try { if (textArea == null)
textArea = gradioApp().getElementById(id).querySelector('textarea')
}
catch {
return; return;
}
let lines = textArea.value.split('\n') const lines = textArea.value.split('\n');
for (let i = 0; i < lines.length; i++) for (let i = 0; i < lines.length; i++)
lines[i] = LeFormatter.formatString(lines[i], dedupe, removeUnderscore) lines[i] = LeFormatter.formatString(lines[i], dedupe, removeUnderscore);
textArea.value = lines.join('\n');
textArea.value = lines.join('\n')
if (autoRefresh) if (autoRefresh)
updateInput(textArea) updateInput(textArea);
} }
static removeUnderscoreSmart(remove, tag) { static removeUnderscoreSmart(remove, tag) {
if (!remove) if (!remove)
return tag return tag;
// [start:end:step] OR <lora:name:str> // [start:end:step] OR <lora:name:str>
const chucks = tag.split(':').map(c => c.trim()) const chucks = tag.split(':').map(c => c.trim());
for (let i = 0; i < chucks.length; i++) { for (let i = 0; i < chucks.length; i++) {
if (!this.cachedCards.includes(chucks[i])) if (!this.cachedCards.includes(chucks[i]))
chucks[i] = chucks[i].replace(/_/g, ' ') chucks[i] = chucks[i].replace(/_/g, ' ');
} }
return chucks.join(':') return chucks.join(':');
} }
static formatString(input, dedupe, removeUnderscore) { static formatString(input, dedupe, removeUnderscore) {
// Remove Duplicate // Remove Duplicate
if (dedupe) { if (dedupe) {
const temp = input.split(',') const temp = input.split(',');
const cleanArray = [] const cleanArray = [];
const finalArray = [] const finalArray = [];
temp.forEach((tag) => { temp.forEach((tag) => {
const cleanedTag = tag.replace(/\[|\]|\(|\)|\s+/g, '').trim() const cleanedTag = tag.replace(/\[|\]|\(|\)|\s+/g, '').trim();
if (/^(AND|BREAK)$/.test(cleanedTag)) { if (/^(AND|BREAK)$/.test(cleanedTag)) {
finalArray.push(cleanedTag) finalArray.push(cleanedTag);
return; return;
} }
if (!cleanArray.includes(cleanedTag)) { if (!cleanArray.includes(cleanedTag)) {
cleanArray.push(cleanedTag) cleanArray.push(cleanedTag);
finalArray.push(tag) finalArray.push(tag);
return; return;
} }
finalArray.push(tag.replace(cleanedTag, '')) finalArray.push(tag.replace(cleanedTag, ''));
}) });
input = finalArray.join(', ') input = finalArray.join(', ');
} }
// Fix Bracket & Comma // Fix Bracket & Comma
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, ',[');
// Remove Commas // Remove Commas
let tags = input.split(',').map(word => this.removeUnderscoreSmart(removeUnderscore, word.trim())).filter(word => word !== '') let tags = input.split(',').map(word => this.removeUnderscoreSmart(removeUnderscore, word.trim())).filter(word => word !== '');
// Remove Stray Brackets // Remove Stray Brackets
const patterns = [/^\(+$/, /^\)+$/, /^\[+$/, /^\]+$/] 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)) 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));
// Remove Spaces // Remove Spaces
input = tags.join(', ').replace(/\s+/g, ' ') input = tags.join(', ').replace(/\s+/g, ' ');
// Fix Bracket & Space // 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 // Fix Empty Bracket
input = input.replace(/\(\s+\)/g, '').replace(/\[\s+\]/g, '') input = input.replace(/\(\s+\)/g, '').replace(/\[\s+\]/g, '');
// Remove Empty Brackets
while (input.match(/\(\s*\)|\[\s*\]/g)) while (input.match(/\(\s*\)|\[\s*\]/g))
input = input.replace(/\(\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(', ');
} }
static grabBrackets(str, index) { static grabBrackets(str, index) {
let openBracket = -1 var openBracket = -1;
let closeBracket = -1 var closeBracket = -1;
for (let i = index; i >= 0; i--) { for (let i = index; i >= 0; i--) {
if (str[i] === '(') { if (str[i] === '(') {
openBracket = i openBracket = i;
break; break;
} }
if (str[i] === ')' && i !== index) { if (str[i] === ')' && i !== index) {
@ -162,7 +157,7 @@ class LeFormatter {
for (let i = index; i < str.length; i++) { for (let i = index; i < str.length; i++) {
if (str[i] === ')') { if (str[i] === ')') {
closeBracket = i closeBracket = i;
break; break;
} }
if (str[i] === '(' && i !== index) { if (str[i] === '(' && i !== index) {
@ -171,24 +166,20 @@ class LeFormatter {
} }
if (openBracket !== -1 && closeBracket !== -1 && openBracket !== closeBracket) if (openBracket !== -1 && closeBracket !== -1 && openBracket !== closeBracket)
return [openBracket, closeBracket] return [openBracket, closeBracket];
else else
return null return null;
} }
static injectTagShift(id) { static injectTagShift(id) {
let textArea = null const textArea = gradioApp().getElementById(id)?.querySelector('textarea');
try { if (textArea == null)
textArea = gradioApp().getElementById(id).querySelector('textarea')
}
catch {
return; return;
}
textArea.addEventListener('wheel', (event) => { textArea.addEventListener('wheel', (event) => {
if (event.shiftKey) { if (event.shiftKey) {
event.preventDefault() event.preventDefault();
if (textArea.selectionStart !== textArea.selectionEnd) if (textArea.selectionStart !== textArea.selectionEnd)
return; return;
@ -196,16 +187,16 @@ class LeFormatter {
if (event.deltaY === 0) if (event.deltaY === 0)
return; return;
const shift = event.deltaY < 0 ? 1 : -1 const shift = event.deltaY < 0 ? 1 : -1;
const tags = textArea.value.split(',').map(t => t.trim()) const tags = textArea.value.split(',').map(t => t.trim());
var cursor = textArea.selectionStart var cursor = textArea.selectionStart;
var index = 0 var index = 0;
for (let i = 0; i < textArea.selectionStart; i++) { for (let i = 0; i < textArea.selectionStart; i++) {
if (textArea.value[i] === ',') if (textArea.value[i] === ',')
index++ index++;
} }
if (index === 0 && shift === -1) if (index === 0 && shift === -1)
@ -213,137 +204,133 @@ class LeFormatter {
if (index === tags.length - 1 && shift === 1) if (index === tags.length - 1 && shift === 1)
return; return;
const shifted = [] const shifted = [];
if (shift < 0) { if (shift < 0) {
for (let i = 0; i < index - 1; i++) for (let i = 0; i < index - 1; i++)
shifted.push(tags[i]) shifted.push(tags[i]);
shifted.push(tags[index]) shifted.push(tags[index]);
shifted.push(tags[index - 1]) shifted.push(tags[index - 1]);
cursor -= tags[index - 1].length + 2 cursor -= tags[index - 1].length + 2;
for (let i = index + 1; i < tags.length; i++) for (let i = index + 1; i < tags.length; i++)
shifted.push(tags[i]) shifted.push(tags[i]);
} else { } else {
for (let i = 0; i < index; i++) for (let i = 0; i < index; i++)
shifted.push(tags[i]) shifted.push(tags[i]);
shifted.push(tags[index + 1]) shifted.push(tags[index + 1]);
shifted.push(tags[index]) shifted.push(tags[index]);
cursor -= tags[index + 1].length * -1 - 2 cursor -= tags[index + 1].length * -1 - 2;
for (let i = index + 2; i < tags.length; i++) for (let i = index + 2; i < tags.length; i++)
shifted.push(tags[i]) shifted.push(tags[i]);
} }
textArea.value = shifted.join(', ') textArea.value = shifted.join(', ');
textArea.selectionStart = cursor textArea.selectionStart = cursor;
textArea.selectionEnd = cursor textArea.selectionEnd = cursor;
updateInput(textArea) updateInput(textArea);
} }
}) });
} }
static injectBracketEscape(id) { static injectBracketEscape(id) {
let textArea = null const textArea = gradioApp().getElementById(id)?.querySelector('textarea');
try { if (textArea == null)
textArea = gradioApp().getElementById(id).querySelector('textarea')
}
catch {
return; return;
}
textArea.addEventListener('keydown', (event) => { textArea.addEventListener('keydown', (event) => {
if (event.ctrlKey && event.key === '\\') { if (event.ctrlKey && event.key === '\\') {
event.preventDefault() event.preventDefault();
let cursorPosition = textArea.selectionStart let cursorPosition = textArea.selectionStart;
if (textArea.selectionStart !== textArea.selectionEnd) if (textArea.selectionStart !== textArea.selectionEnd)
cursorPosition++ cursorPosition++;
let result = LeFormatter.grabBrackets(textArea.value, cursorPosition) let result = LeFormatter.grabBrackets(textArea.value, cursorPosition);
if (result) { if (result) {
const original = textArea.value const original = textArea.value;
if (result[0] !== 0 && textArea.value[result[0] - 1] === '\\' && textArea.value[result[1] - 1] === '\\') { if (result[0] !== 0 && textArea.value[result[0] - 1] === '\\' && textArea.value[result[1] - 1] === '\\') {
textArea.value = original.slice(0, result[0] - 1) + original.slice(result[0] - 1, result[1]).replace(/\\/g, '') + original.slice(result[1]) textArea.value = original.slice(0, result[0] - 1) + original.slice(result[0] - 1, result[1]).replace(/\\/g, '') + original.slice(result[1]);
textArea.selectionStart = result[0] - 1 textArea.selectionStart = result[0] - 1;
textArea.selectionEnd = result[1] - 1 textArea.selectionEnd = result[1] - 1;
} }
else { else {
textArea.value = original.slice(0, result[0]) + '\\' + original.slice(result[0], result[1]) + '\\' + original.slice(result[1]) textArea.value = original.slice(0, result[0]) + '\\' + original.slice(result[0], result[1]) + '\\' + original.slice(result[1]);
textArea.selectionStart = result[0] textArea.selectionStart = result[0];
textArea.selectionEnd = result[1] + 3 textArea.selectionEnd = result[1] + 3;
} }
updateInput(textArea) updateInput(textArea);
} }
} }
}) });
} }
// ===== Load Settings ===== // ===== Load Settings =====
static shouldRefresh() { static shouldRefresh() {
const config = gradioApp().getElementById('setting_pf_disableupdateinput').querySelector('input[type=checkbox]') const config = gradioApp().getElementById('setting_pf_disableupdateinput').querySelector('input[type=checkbox]');
return !config.checked return !config.checked;
} }
} }
onUiLoaded(async () => { onUiLoaded(async () => {
const Modes = ['txt', 'img'] const Modes = ['txt', 'img'];
let autoRun = true var autoRun = true;
let dedupe = true var dedupe = true;
let removeUnderscore = false var removeUnderscore = false;
const manualBtn = LeFormatter.manualButton({ const manualBtn = LeFormatter.manualButton({
onClick: () => { onClick: () => {
const ids = ['txt2img_prompt', 'txt2img_neg_prompt', 'img2img_prompt', 'img2img_neg_prompt', 'hires_prompt', 'hires_neg_prompt'] const ids = ['txt2img_prompt', 'txt2img_neg_prompt', 'img2img_prompt', 'img2img_neg_prompt', 'hires_prompt', 'hires_neg_prompt'];
ids.forEach((id) => LeFormatter.formatPipeline(id, dedupe, removeUnderscore, true)) ids.forEach((id) => LeFormatter.formatPipeline(id, dedupe, removeUnderscore, true));
} }
}) });
manualBtn.style.display = 'none' manualBtn.style.display = 'none';
const autoCB = LeFormatter.checkbox('Auto Format', autoRun, { const autoCB = LeFormatter.checkbox('Auto Format', autoRun, {
onChange: (checked) => { onChange: (checked) => {
autoRun = checked autoRun = checked;
manualBtn.style.display = autoRun ? 'none' : 'block' manualBtn.style.display = autoRun ? 'none' : 'block';
} }
}) });
const dedupeCB = LeFormatter.checkbox('Remove Duplicates', dedupe, { const dedupeCB = LeFormatter.checkbox('Remove Duplicates', dedupe, {
onChange: (checked) => { dedupe = checked } onChange: (checked) => { dedupe = checked; }
}) });
const underlineCB = LeFormatter.checkbox('Remove Underscores', removeUnderscore, { const underlineCB = LeFormatter.checkbox('Remove Underscores', removeUnderscore, {
onChange: (checked) => { onChange: (checked) => {
removeUnderscore = checked removeUnderscore = checked;
if (LeFormatter.cachedCards == null) if (LeFormatter.cachedCards == null)
LeFormatter.cache_Cards() LeFormatter.cache_Cards();
} }
}) });
const formatter = document.createElement('div') const formatter = document.createElement('div');
formatter.id = 'le-formatter' formatter.id = 'le-formatter';
formatter.style.display = 'flex' formatter.style.display = 'flex';
formatter.style.flex.direction = 'row' formatter.style.flex.direction = 'row';
formatter.appendChild(autoCB) formatter.appendChild(autoCB);
formatter.appendChild(manualBtn) formatter.appendChild(manualBtn);
formatter.appendChild(dedupeCB) formatter.appendChild(dedupeCB);
formatter.appendChild(underlineCB) formatter.appendChild(underlineCB);
const tools = document.getElementById('quicksettings') const tools = document.getElementById('quicksettings');
tools.after(formatter) tools.after(formatter);
Modes.forEach((mode) => { Modes.forEach((mode) => {
@ -352,24 +339,29 @@ onUiLoaded(async () => {
if (!autoRun) if (!autoRun)
return; return;
const ids = [mode + '2img_prompt', mode + '2img_neg_prompt'] const ids = [mode + '2img_prompt', mode + '2img_neg_prompt'];
ids.forEach((ID) => LeFormatter.formatPipeline(ID, dedupe, removeUnderscore, LeFormatter.shouldRefresh())) ids.forEach((ID) => LeFormatter.formatPipeline(ID, dedupe, removeUnderscore, LeFormatter.shouldRefresh()));
if (mode === 'txt') {
const hires_id = ['hires_prompt', 'hires_neg_prompt']
hires_id.forEach((hID) => LeFormatter.formatPipeline(hID, dedupe, removeUnderscore, LeFormatter.shouldRefresh()))
} }
});
LeFormatter.injectBracketEscape(mode + '2img_prompt');
LeFormatter.injectBracketEscape(mode + '2img_neg_prompt');
LeFormatter.injectTagShift(mode + '2img_prompt');
LeFormatter.injectTagShift(mode + '2img_neg_prompt');
});
LeFormatter.injectButton('txt2img_generate', {
onClick: () => {
if (!autoRun)
return;
const hires_id = ['hires_prompt', 'hires_neg_prompt'];
hires_id.forEach((hID) => LeFormatter.formatPipeline(hID, dedupe, removeUnderscore, LeFormatter.shouldRefresh()));
} }
}) });
LeFormatter.injectBracketEscape(mode + '2img_prompt') LeFormatter.injectBracketEscape('hires_prompt');
LeFormatter.injectBracketEscape(mode + '2img_neg_prompt') LeFormatter.injectBracketEscape('hires_neg_prompt');
LeFormatter.injectTagShift(mode + '2img_prompt') LeFormatter.injectTagShift('hires_prompt');
LeFormatter.injectTagShift(mode + '2img_neg_prompt') LeFormatter.injectTagShift('hires_neg_prompt');
}) });
LeFormatter.injectBracketEscape('hires_prompt')
LeFormatter.injectBracketEscape('hires_neg_prompt')
LeFormatter.injectTagShift('hires_prompt')
LeFormatter.injectTagShift('hires_neg_prompt')
})