|
1 | | -// Stable Diffusion WebUI - Bracket checker |
2 | | -// By Hingashi no Florin/Bwin4L & @akx |
| 1 | +// Stable Diffusion WebUI - Bracket Checker |
| 2 | +// By @Bwin4L, @akx, @w-e-w, @Haoming02 |
3 | 3 | // Counts open and closed brackets (round, square, curly) in the prompt and negative prompt text boxes in the txt2img and img2img tabs. |
4 | | -// If there's a mismatch, the keyword counter turns red and if you hover on it, a tooltip tells you what's wrong. |
5 | | - |
6 | | -function checkBrackets(textArea, counterElt) { |
7 | | - var counts = {}; |
8 | | - (textArea.value.match(/[(){}[\]]/g) || []).forEach(bracket => { |
9 | | - counts[bracket] = (counts[bracket] || 0) + 1; |
10 | | - }); |
11 | | - var errors = []; |
12 | | - |
13 | | - function checkPair(open, close, kind) { |
14 | | - if (counts[open] !== counts[close]) { |
15 | | - errors.push( |
16 | | - `${open}...${close} - Detected ${counts[open] || 0} opening and ${counts[close] || 0} closing ${kind}.` |
17 | | - ); |
| 4 | +// If there's a mismatch, the keyword counter turns red, and if you hover on it, a tooltip tells you what's wrong. |
| 5 | + |
| 6 | +function checkBrackets(textArea, counterElem) { |
| 7 | + const pairs = [ |
| 8 | + ['(', ')', 'round brackets'], |
| 9 | + ['[', ']', 'square brackets'], |
| 10 | + ['{', '}', 'curly brackets'] |
| 11 | + ]; |
| 12 | + |
| 13 | + const counts = {}; |
| 14 | + const errors = new Set(); |
| 15 | + let i = 0; |
| 16 | + |
| 17 | + while (i < textArea.value.length) { |
| 18 | + let char = textArea.value[i]; |
| 19 | + let escaped = false; |
| 20 | + while (char === '\\' && i + 1 < textArea.value.length) { |
| 21 | + escaped = !escaped; |
| 22 | + i++; |
| 23 | + char = textArea.value[i]; |
| 24 | + } |
| 25 | + |
| 26 | + if (escaped) { |
| 27 | + i++; |
| 28 | + continue; |
| 29 | + } |
| 30 | + |
| 31 | + for (const [open, close, label] of pairs) { |
| 32 | + if (char === open) { |
| 33 | + counts[label] = (counts[label] || 0) + 1; |
| 34 | + } else if (char === close) { |
| 35 | + counts[label] = (counts[label] || 0) - 1; |
| 36 | + if (counts[label] < 0) { |
| 37 | + errors.add(`Incorrect order of ${label}.`); |
| 38 | + } |
| 39 | + } |
| 40 | + } |
| 41 | + |
| 42 | + i++; |
| 43 | + } |
| 44 | + |
| 45 | + for (const [open, close, label] of pairs) { |
| 46 | + if (counts[label] == undefined) { |
| 47 | + continue; |
| 48 | + } |
| 49 | + |
| 50 | + if (counts[label] > 0) { |
| 51 | + errors.add(`${open} ... ${close} - Detected ${counts[label]} more opening than closing ${label}.`); |
| 52 | + } else if (counts[label] < 0) { |
| 53 | + errors.add(`${open} ... ${close} - Detected ${-counts[label]} more closing than opening ${label}.`); |
18 | 54 | } |
19 | 55 | } |
20 | 56 |
|
21 | | - checkPair('(', ')', 'round brackets'); |
22 | | - checkPair('[', ']', 'square brackets'); |
23 | | - checkPair('{', '}', 'curly brackets'); |
24 | | - counterElt.title = errors.join('\n'); |
25 | | - counterElt.classList.toggle('error', errors.length !== 0); |
| 57 | + counterElem.title = [...errors].join('\n'); |
| 58 | + counterElem.classList.toggle('error', errors.size !== 0); |
26 | 59 | } |
27 | 60 |
|
28 | 61 | function setupBracketChecking(id_prompt, id_counter) { |
29 | | - var textarea = gradioApp().querySelector("#" + id_prompt + " > label > textarea"); |
30 | | - var counter = gradioApp().getElementById(id_counter); |
| 62 | + const textarea = gradioApp().querySelector(`#${id_prompt} > label > textarea`); |
| 63 | + const counter = gradioApp().getElementById(id_counter); |
31 | 64 |
|
32 | 65 | if (textarea && counter) { |
33 | | - textarea.addEventListener("input", () => checkBrackets(textarea, counter)); |
| 66 | + onEdit(`${id_prompt}_BracketChecking`, textarea, 400, () => checkBrackets(textarea, counter)); |
34 | 67 | } |
35 | 68 | } |
36 | 69 |
|
|
0 commit comments