stable-diffusion-webui
148 строк · 5.4 Кб
1function keyupEditAttention(event) {2let target = event.originalTarget || event.composedPath()[0];3if (!target.matches("*:is([id*='_toprow'] [id*='_prompt'], .prompt) textarea")) return;4if (!(event.metaKey || event.ctrlKey)) return;5
6let isPlus = event.key == "ArrowUp";7let isMinus = event.key == "ArrowDown";8if (!isPlus && !isMinus) return;9
10let selectionStart = target.selectionStart;11let selectionEnd = target.selectionEnd;12let text = target.value;13
14function selectCurrentParenthesisBlock(OPEN, CLOSE) {15if (selectionStart !== selectionEnd) return false;16
17// Find opening parenthesis around current cursor18const before = text.substring(0, selectionStart);19let beforeParen = before.lastIndexOf(OPEN);20if (beforeParen == -1) return false;21
22let beforeClosingParen = before.lastIndexOf(CLOSE);23if (beforeClosingParen != -1 && beforeClosingParen > beforeParen) return false;24
25// Find closing parenthesis around current cursor26const after = text.substring(selectionStart);27let afterParen = after.indexOf(CLOSE);28if (afterParen == -1) return false;29
30let afterOpeningParen = after.indexOf(OPEN);31if (afterOpeningParen != -1 && afterOpeningParen < afterParen) return false;32
33// Set the selection to the text between the parenthesis34const parenContent = text.substring(beforeParen + 1, selectionStart + afterParen);35if (/.*:-?[\d.]+/s.test(parenContent)) {36const lastColon = parenContent.lastIndexOf(":");37selectionStart = beforeParen + 1;38selectionEnd = selectionStart + lastColon;39} else {40selectionStart = beforeParen + 1;41selectionEnd = selectionStart + parenContent.length;42}43
44target.setSelectionRange(selectionStart, selectionEnd);45return true;46}47
48function selectCurrentWord() {49if (selectionStart !== selectionEnd) return false;50const whitespace_delimiters = {"Tab": "\t", "Carriage Return": "\r", "Line Feed": "\n"};51let delimiters = opts.keyedit_delimiters;52
53for (let i of opts.keyedit_delimiters_whitespace) {54delimiters += whitespace_delimiters[i];55}56
57// seek backward to find beginning58while (!delimiters.includes(text[selectionStart - 1]) && selectionStart > 0) {59selectionStart--;60}61
62// seek forward to find end63while (!delimiters.includes(text[selectionEnd]) && selectionEnd < text.length) {64selectionEnd++;65}66
67target.setSelectionRange(selectionStart, selectionEnd);68return true;69}70
71// If the user hasn't selected anything, let's select their current parenthesis block or word72if (!selectCurrentParenthesisBlock('<', '>') && !selectCurrentParenthesisBlock('(', ')') && !selectCurrentParenthesisBlock('[', ']')) {73selectCurrentWord();74}75
76event.preventDefault();77
78var closeCharacter = ')';79var delta = opts.keyedit_precision_attention;80var start = selectionStart > 0 ? text[selectionStart - 1] : "";81var end = text[selectionEnd];82
83if (start == '<') {84closeCharacter = '>';85delta = opts.keyedit_precision_extra;86} else if (start == '(' && end == ')' || start == '[' && end == ']') { // convert old-style (((emphasis)))87let numParen = 0;88
89while (text[selectionStart - numParen - 1] == start && text[selectionEnd + numParen] == end) {90numParen++;91}92
93if (start == "[") {94weight = (1 / 1.1) ** numParen;95} else {96weight = 1.1 ** numParen;97}98
99weight = Math.round(weight / opts.keyedit_precision_attention) * opts.keyedit_precision_attention;100
101text = text.slice(0, selectionStart - numParen) + "(" + text.slice(selectionStart, selectionEnd) + ":" + weight + ")" + text.slice(selectionEnd + numParen);102selectionStart -= numParen - 1;103selectionEnd -= numParen - 1;104} else if (start != '(') {105// do not include spaces at the end106while (selectionEnd > selectionStart && text[selectionEnd - 1] == ' ') {107selectionEnd--;108}109
110if (selectionStart == selectionEnd) {111return;112}113
114text = text.slice(0, selectionStart) + "(" + text.slice(selectionStart, selectionEnd) + ":1.0)" + text.slice(selectionEnd);115
116selectionStart++;117selectionEnd++;118}119
120if (text[selectionEnd] != ':') return;121var weightLength = text.slice(selectionEnd + 1).indexOf(closeCharacter) + 1;122var weight = parseFloat(text.slice(selectionEnd + 1, selectionEnd + weightLength));123if (isNaN(weight)) return;124
125weight += isPlus ? delta : -delta;126weight = parseFloat(weight.toPrecision(12));127if (Number.isInteger(weight)) weight += ".0";128
129if (closeCharacter == ')' && weight == 1) {130var endParenPos = text.substring(selectionEnd).indexOf(')');131text = text.slice(0, selectionStart - 1) + text.slice(selectionStart, selectionEnd) + text.slice(selectionEnd + endParenPos + 1);132selectionStart--;133selectionEnd--;134} else {135text = text.slice(0, selectionEnd + 1) + weight + text.slice(selectionEnd + weightLength);136}137
138target.focus();139target.value = text;140target.selectionStart = selectionStart;141target.selectionEnd = selectionEnd;142
143updateInput(target);144}
145
146addEventListener('keydown', (event) => {147keyupEditAttention(event);148});149