stable-diffusion-webui/javascript/edit-attention.js

122 lines
4.5 KiB
JavaScript
Raw Normal View History

2023-01-22 13:05:21 +08:00
function keyupEditAttention(event){
let target = event.originalTarget || event.composedPath()[0];
if (! target.matches("[id*='_toprow'] [id*='_prompt'] textarea")) return;
if (! (event.metaKey || event.ctrlKey)) return;
2023-01-22 13:05:21 +08:00
let isPlus = event.key == "ArrowUp"
let isMinus = event.key == "ArrowDown"
if (!isPlus && !isMinus) return;
let selectionStart = target.selectionStart;
let selectionEnd = target.selectionEnd;
2023-01-22 13:05:21 +08:00
let text = target.value;
function selectCurrentParenthesisBlock(OPEN, CLOSE){
if (selectionStart !== selectionEnd) return false;
// Find opening parenthesis around current cursor
2023-01-22 13:05:21 +08:00
const before = text.substring(0, selectionStart);
let beforeParen = before.lastIndexOf(OPEN);
2023-04-20 12:04:34 +08:00
if (beforeParen == -1) return false;
2023-01-22 13:05:21 +08:00
let beforeParenClose = before.lastIndexOf(CLOSE);
while (beforeParenClose !== -1 && beforeParenClose > beforeParen) {
2023-01-22 13:05:21 +08:00
beforeParen = before.lastIndexOf(OPEN, beforeParen - 1);
beforeParenClose = before.lastIndexOf(CLOSE, beforeParenClose - 1);
}
// Find closing parenthesis around current cursor
2023-01-22 13:05:21 +08:00
const after = text.substring(selectionStart);
let afterParen = after.indexOf(CLOSE);
2023-04-20 12:04:34 +08:00
if (afterParen == -1) return false;
2023-01-22 13:05:21 +08:00
let afterParenOpen = after.indexOf(OPEN);
while (afterParenOpen !== -1 && afterParen > afterParenOpen) {
2023-01-22 13:05:21 +08:00
afterParen = after.indexOf(CLOSE, afterParen + 1);
afterParenOpen = after.indexOf(OPEN, afterParenOpen + 1);
}
2023-01-22 13:05:21 +08:00
if (beforeParen === -1 || afterParen === -1) return false;
// Set the selection to the text between the parenthesis
2023-01-22 13:05:21 +08:00
const parenContent = text.substring(beforeParen + 1, selectionStart + afterParen);
const lastColon = parenContent.lastIndexOf(":");
selectionStart = beforeParen + 1;
selectionEnd = selectionStart + lastColon;
target.setSelectionRange(selectionStart, selectionEnd);
2023-01-22 13:05:21 +08:00
return true;
}
2023-04-20 12:04:34 +08:00
function selectCurrentWord(){
if (selectionStart !== selectionEnd) return false;
2023-04-20 15:12:59 +08:00
const delimiters = ".,\/#!$%\^&\*;:{}=\-_`~()";
2023-04-20 12:04:34 +08:00
// Select the current word, find the start and end of the word (first space before and after)
const wordStart = text.substring(0, selectionStart).lastIndexOf(" ") + 1;
const wordEnd = text.substring(selectionEnd).indexOf(" ");
// If there is no space after the word, select to the end of the string
if (wordEnd === -1) {
selectionEnd = text.length;
} else {
selectionEnd += wordEnd;
}
selectionStart = wordStart;
// Remove all punctuation at the end and beginning of the word
2023-04-20 15:12:59 +08:00
while (delimiters.includes(text[selectionStart])) {
2023-04-20 12:04:34 +08:00
selectionStart++;
}
2023-04-20 15:12:59 +08:00
while (delimiters.includes(text[selectionEnd - 1])) {
2023-04-20 12:04:34 +08:00
selectionEnd--;
}
target.setSelectionRange(selectionStart, selectionEnd);
return true;
}
2023-01-22 13:05:21 +08:00
2023-04-20 12:04:34 +08:00
// If the user hasn't selected anything, let's select their current parenthesis block or word
if (!selectCurrentParenthesisBlock('<', '>') && !selectCurrentParenthesisBlock('(', ')')) {
selectCurrentWord();
2023-01-22 13:05:21 +08:00
}
event.preventDefault();
2023-01-22 13:05:21 +08:00
closeCharacter = ')'
delta = opts.keyedit_precision_attention
if (selectionStart > 0 && text[selectionStart - 1] == '<'){
closeCharacter = '>'
delta = opts.keyedit_precision_extra
} else if (selectionStart == 0 || text[selectionStart - 1] != "(") {
// do not include spaces at the end
while(selectionEnd > selectionStart && text[selectionEnd-1] == ' '){
selectionEnd -= 1;
}
if(selectionStart == selectionEnd){
return
}
2023-01-22 13:05:21 +08:00
text = text.slice(0, selectionStart) + "(" + text.slice(selectionStart, selectionEnd) + ":1.0)" + text.slice(selectionEnd);
2023-01-22 13:05:21 +08:00
selectionStart += 1;
selectionEnd += 1;
}
2023-01-22 13:05:21 +08:00
end = text.slice(selectionEnd + 1).indexOf(closeCharacter) + 1;
weight = parseFloat(text.slice(selectionEnd + 1, selectionEnd + 1 + end));
if (isNaN(weight)) return;
2023-01-22 13:05:21 +08:00
weight += isPlus ? delta : -delta;
weight = parseFloat(weight.toPrecision(12));
if(String(weight).length == 1) weight += ".0"
2023-01-22 13:05:21 +08:00
text = text.slice(0, selectionEnd + 1) + weight + text.slice(selectionEnd + 1 + end - 1);
target.focus();
target.value = text;
target.selectionStart = selectionStart;
target.selectionEnd = selectionEnd;
updateInput(target)
2023-01-22 13:05:21 +08:00
}
addEventListener('keydown', (event) => {
keyupEditAttention(event);
});