forked from FSpark/Danbooru-Tags-Exporter
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Danbooru-Tags-Exporter.user.js
179 lines (163 loc) · 7.46 KB
/
Danbooru-Tags-Exporter.user.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
// ==UserScript==
// @name Danbooru Tags Select to Export
// @name:zh-TW Danbooru 標籤導出器
// @name:zh-HK Danbooru 標籤導出器
// @name:zh-CN Danbooru 标签导出器
// @name:ja Danbooru Tags Select to Export
// @namespace https://github.com/FSpark/Danbooru-Tags-Exporter
// @supportURL https://github.com/FSpark/Danbooru-Tags-Exporter/issues
// @homepageURL https://github.com/FSpark/Danbooru-Tags-Exporter
// @require https://greasemonkey.github.io/gm4-polyfill/gm4-polyfill.js
// @version 0.3.3
// @description Select specified tags and copy to clipboard, for Stable Diffusion WebUI or NovelAI to use.
// @description:zh-TW 選擇指定標籤並複製到剪貼板,供Stable Diffusion WebUI或NovelAI等使用
// @description:zh-HK 選擇指定標籤並複製到剪貼板,供Stable Diffusion WebUI或NovelAI等使用
// @description:zh-CN 选择指定标签并复制到剪贴板,供Stable Diffusion WebUI或NovelAI等使用
// @description:ja 指定したタグを選択し、クリップボードにコピーして、Stable Diffusion WebUIやNovelAIなどで使用することができます。
// @author FSpark
// @match https://danbooru.donmai.us/posts/*
// @match https://safebooru.donmai.us/posts/*
// @match https://aibooru.online/posts/*
// @match https://betabooru.donmai.us/posts/*
// @icon https://www.google.com/s2/favicons?sz=64&domain=donmai.us
// @grant GM.setClipboard
// @grant GM.notification
// @grant GM.addStyle
// @license AGPL-3.0
// ==/UserScript==
(function () {
'use strict';
GM.addStyle(`#tags-exporter-setting button, #tag-list button {padding: 0.25em 0.75em;}
#tags-exporter-setting label{margin: .25em; line-height: 1.5em;}
.tag-weight {width: 3em; margin-left: .25em}`);
let SettingPanel = document.createElement('section');
SettingPanel.id = "tags-exporter-setting";
SettingPanel.innerHTML = `
<h2>Tags Export Settings</h2>
<input type="checkbox" id="bracket-escape" checked/><label for="bracket-escape"><code>(</code> <code>)</code> -> <code>\\(</code> <code>\\)</code></label><br>
<input type="checkbox" id="set-weight" /><label for="set-weight">Setting weights</label><br>
<div>
<input type="radio" name="use-bracket" id="round-brackets" value="0" checked/><label for="round-brackets">Using ( )</label>
<input type="radio" name="use-bracket" id="curly-brackets" value="-1"/><label for="curly-brackets">Using { }</label></div>
`
let Container = document.createElement('div');
Container.id = "tags-exporter-container";
Container.innerHTML = `<button name="select_all">All</button>
<button name="select_none">None</button>
<button name="invert_select">Invert</button>
<button name="export">Export</button>
`
function insertAfter(newNode, referenceNode) {
referenceNode.parentNode.insertBefore(newNode, referenceNode.nextSibling);
}
insertAfter(SettingPanel, document.querySelector("#search-box"))
insertAfter(Container, document.querySelector("#tags-exporter-setting > h2"))
function addBrackets(prompts,isRound,n){
let l,r;
if(n==0)
return prompts
else if(n>0){
if(isRound){
l='('
r=')'}
else{
l='{'
r='}'
}
}else{
l='['
r=']'
}
n=Math.abs(n)
return l.repeat(n).concat(prompts,r.repeat(n))
}
function exportTags(target){
let tags = []
let bracket_escape = document.getElementById("bracket-escape").checked
let set_weight = document.getElementById("set-weight").checked
let round_brackets = document.getElementById("round-brackets").checked
document.querySelectorAll(target).forEach((e) => {
let prompts = e.value
if(bracket_escape)
prompts = prompts.replaceAll(`(`,`\\(`).replaceAll(`)`,`\\)`)
if(set_weight){
prompts = addBrackets(prompts,round_brackets,e.nextSibling.value)
}
tags.push(prompts)
})
let res = tags.join(", ")
GM.setClipboard(res)
GM.notification(`${tags.length} tag(s) were copied.`, "Danbooru Tags Exporter")
}
function insertButtons(target){
let head = document.querySelector(`h3.${target}-list`)
if(!head) return;
let buttonContainer = Container.cloneNode(true)
buttonContainer.id = `${target}-buttons`
insertAfter(buttonContainer, head)
document.querySelectorAll(`.${target}-list>li`).forEach((e) => {
let chk = document.createElement('input');
chk.type = "checkbox"
chk.name = `${target}s`
chk.value = e.dataset.tagName.replaceAll("_", " ")
e.insertBefore(chk, e.firstChild)
let nbr = document.createElement('input');
nbr.type = "number"
nbr.name = `${target}s-weight`
nbr.className = "tag-weight"
nbr.value = 0
nbr.hidden = true
insertAfter(nbr,chk)
})
buttonContainer.querySelector("[name='select_all']").onclick = function () {
var items = document.getElementsByName(`${target}s`);
for (var i = 0; i < items.length; i++) {
items[i].checked = true;
}
};
buttonContainer.querySelector("[name='select_none']").onclick = function () {
var items = document.getElementsByName(`${target}s`);
for (var i = 0; i < items.length; i++) {
items[i].checked = false;
}
};
buttonContainer.querySelector("[name='invert_select']").onclick = function () {
var items = document.getElementsByName(`${target}s`);
for (var i = 0; i < items.length; i++) {
items[i].checked == true ? items[i].checked = false : items[i].checked = true;
}
};
buttonContainer.querySelector("[name='export']").onclick = function () {
exportTags(`[name=${target}s]:checked`)
};
}
["artist-tag","character-tag","copyright-tag","general-tag"].forEach((t)=>insertButtons(t))
Container.querySelector("[name='select_all']").onclick = function () {
var items = document.querySelectorAll("#tag-list input[type='checkbox']")
for (var i = 0; i < items.length; i++) {
items[i].checked = true;
}
};
Container.querySelector("[name='select_none']").onclick = function () {
var items = document.querySelectorAll("#tag-list input[type='checkbox']")
for (var i = 0; i < items.length; i++) {
items[i].checked = false;
}
};
Container.querySelector("[name='invert_select']").onclick = function () {
var items = document.querySelectorAll("#tag-list input[type='checkbox']")
for (var i = 0; i < items.length; i++) {
items[i].checked == true ? items[i].checked = false : items[i].checked = true;
}
};
Container.querySelector("[name='export']").onclick = function () {
exportTags(`#tag-list input[type='checkbox']:checked`)
};
document.getElementById("set-weight").onchange = function (e){
if(e.target.checked){
document.querySelectorAll("#tag-list input[type='number']").forEach((e)=>e.hidden=false)
}else{
document.querySelectorAll("#tag-list input[type='number']").forEach((e)=>e.hidden=true)
}
}
})();