From a4b89f30f1687663d5637f3ff2d619d2cbea5820 Mon Sep 17 00:00:00 2001 From: Haoming Date: Wed, 19 Jul 2023 17:30:48 +0800 Subject: [PATCH] New Feature - Shift Tag Shift + ScrollWheel to move tags around --- README.md | 5 ++- README_ZH.md | 5 ++- javascript/prompt_format.js | 76 +++++++++++++++++++++++++++++++++++-- 3 files changed, 78 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 8e0b178..f401b6a 100644 --- a/README.md +++ b/README.md @@ -26,10 +26,11 @@ Sometimes, when you type too fast or copy prompts from all over the places, you - [x] Toggle between auto formatting and manual formatting - In `Auto`: The process is ran whenever you press **Generate** - In `Manual`: The process is only ran when you press the **Format** button -- [x] **[New]** Toggle between auto updating prompts or not[^1] +- [x] Toggle between auto updating prompts or not[^1] - Some Extensions *(**eg.** [tagcomplete](https://github.com/DominikDoom/a1111-sd-webui-tagcomplete))* listen to the text editing event, which means the formatting causes them to trigger - You only really need to disable this if you have the above Extension - You can open `prompt_format.js` and edit this line at the top `static updateInput = true;` to `static updateInput = false;` to save the setting - When `disabled`, the formatting is purely visual. It will only update once you manually edit the prompt again +- [x] **[New]** Use `Shift + ScrollWheel` to quickly shift the hovered tag in the prompt -[^1]: Due to the implementation being in `JavaScript` instead pf `Python`, the image's metadata will still only be updated in the next generation. This toggle mainly affects when you click `Send to img2img`, will the prompt be already formatted or not, etc. \ No newline at end of file +[^1]: Due to the implementation being in `JavaScript` instead of `Python`, the image's metadata will still only be updated in the next generation. This toggle mainly affects when you click `Send to img2img`, will the prompt be already formatted or not, etc. \ No newline at end of file diff --git a/README_ZH.md b/README_ZH.md index d54e398..8aa9943 100644 --- a/README_ZH.md +++ b/README_ZH.md @@ -10,7 +10,7 @@ 有時候打字太快,或是從各地東拼西湊咒語,常造成多個重複的空格或逗點。這項插件可以幫忙移除它們。 ## 功能實作 -- [x] **[New]** 你可以打開`prompt_format.js`並把上面的`static UseCN = false;`改成`static UseCN = true;`來套用中文翻譯 +- [x] 你可以打開`prompt_format.js`並把上面的`static UseCN = false;`改成`static UseCN = true;`來套用中文翻譯 - [x] 在`txt2img`和`img2img`都有用 - [x] 移除多餘**空格**和**逗點** - [x] 修改錯誤的**括弧** @@ -27,10 +27,11 @@ - [x] 按下`Auto Format`以在手動與自動間切換 - `自動`: 每次按下 **生成 (Generate)** 時處裡 - `手動`: 手動按下`Format`時才處裡 -- [x] **[New]** 按下`Update Input`以開/關格式套用[^1] +- [x] 按下`Update Input`以開/關格式套用[^1] - 有些擴充 *(**如.** [tagcomplete](https://github.com/DominikDoom/a1111-sd-webui-tagcomplete))* 訂閱文字的編輯事件,意即我的格式化會導致它們啟動 - 基本上,只有在有安裝上述擴充時才需要關閉這個功能 - 你可以打開`prompt_format.js`並把上面的`static updateInput = true;`改成`static updateInput = false;`來永久關閉 - 在`關閉`時,前述的美化只是視覺效果。唯有再次手動編輯後,咒語才會更新 +- [x] **[New]** 使用`Shift + 滾輪`來橫移目前游標所在的單字 [^1]: 由於透過`JavaScript`而非`Python`撰寫,生成圖片的內部資料只會在下一次生成才更新。這個選項主要影響,當你按下`Send to img2img`時所傳送的咒語是否已美化過等等。 \ No newline at end of file diff --git a/javascript/prompt_format.js b/javascript/prompt_format.js index 714ad97..661182c 100644 --- a/javascript/prompt_format.js +++ b/javascript/prompt_format.js @@ -124,6 +124,72 @@ return null } + static injectTagShift(id) { + const textarea = gradioApp().getElementById(id).querySelector('textarea') + + textarea.addEventListener('wheel', (event) => { + if (event.shiftKey) { + event.preventDefault() + + if (textarea.selectionStart !== textarea.selectionEnd) + return; + + if (event.deltaY === 0) + return; + + const shift = event.deltaY < 0 ? 1 : -1 + const tags = textarea.value.split(',').map(t => t.trim()) + + var cursor = textarea.selectionStart + + var index = 0 + + for (let i = 0; i < textarea.selectionStart; i++) { + if (textarea.value[i] === ',') + index++ + } + + if (index === 0 && shift === -1) + return; + if (index === tags.length - 1 && shift === 1) + return; + + const shifted = [] + + if (shift < 0) { + for (let i = 0; i < index - 1; i++) + shifted.push(tags[i]) + + shifted.push(tags[index]) + shifted.push(tags[index - 1]) + + cursor -= tags[index - 1].length + 2 + + for (let i = index + 1; i < tags.length; i++) + shifted.push(tags[i]) + } else { + for (let i = 0; i < index; i++) + shifted.push(tags[i]) + + shifted.push(tags[index + 1]) + shifted.push(tags[index]) + + cursor -= tags[index + 1].length * -1 - 2 + + for (let i = index + 2; i < tags.length; i++) + shifted.push(tags[i]) + } + + textarea.value = shifted.join(', ') + + textarea.selectionStart = cursor + textarea.selectionEnd = cursor + + updateInput(textarea) + } + }) + } + static injectBracketEscape(id) { const textarea = gradioApp().getElementById(id).querySelector('textarea') @@ -158,7 +224,7 @@ }) } -} +} onUiLoaded(async () => { const Modes = ['txt', 'img'] @@ -195,11 +261,11 @@ onUiLoaded(async () => { } }) - const dedupeCB = LeFormatter.checkbox((LeFormatter.UseCN ? '去除重複':'Remove Duplicates'), dedupe, { + const dedupeCB = LeFormatter.checkbox((LeFormatter.UseCN ? '去除重複' : 'Remove Duplicates'), dedupe, { onChange: (checked) => { dedupe = checked } }) - const underlineCB = LeFormatter.checkbox((LeFormatter.UseCN ? '去除底線':'Remove Underscores'), removeUnderscore, { + const underlineCB = LeFormatter.checkbox((LeFormatter.UseCN ? '去除底線' : 'Remove Underscores'), removeUnderscore, { onChange: (checked) => { removeUnderscore = checked } }) @@ -248,6 +314,8 @@ onUiLoaded(async () => { LeFormatter.injectBracketEscape(mode + '2img_prompt') LeFormatter.injectBracketEscape(mode + '2img_neg_prompt') + LeFormatter.injectTagShift(mode + '2img_prompt') + LeFormatter.injectTagShift(mode + '2img_neg_prompt') }) -}) \ No newline at end of file +})