Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
automatic1111
GitHub Repository: automatic1111/stable-diffusion-webui
Path: blob/master/javascript/localization.js
3055 views
1
2
// localization = {} -- the dict with translations is created by the backend
3
4
var ignore_ids_for_localization = {
5
setting_sd_hypernetwork: 'OPTION',
6
setting_sd_model_checkpoint: 'OPTION',
7
modelmerger_primary_model_name: 'OPTION',
8
modelmerger_secondary_model_name: 'OPTION',
9
modelmerger_tertiary_model_name: 'OPTION',
10
train_embedding: 'OPTION',
11
train_hypernetwork: 'OPTION',
12
txt2img_styles: 'OPTION',
13
img2img_styles: 'OPTION',
14
setting_random_artist_categories: 'OPTION',
15
setting_face_restoration_model: 'OPTION',
16
setting_realesrgan_enabled_models: 'OPTION',
17
extras_upscaler_1: 'OPTION',
18
extras_upscaler_2: 'OPTION',
19
};
20
21
var re_num = /^[.\d]+$/;
22
var re_emoji = /[\p{Extended_Pictographic}\u{1F3FB}-\u{1F3FF}\u{1F9B0}-\u{1F9B3}]/u;
23
24
var original_lines = {};
25
var translated_lines = {};
26
27
function hasLocalization() {
28
return window.localization && Object.keys(window.localization).length > 0;
29
}
30
31
function textNodesUnder(el) {
32
var n, a = [], walk = document.createTreeWalker(el, NodeFilter.SHOW_TEXT, null, false);
33
while ((n = walk.nextNode())) a.push(n);
34
return a;
35
}
36
37
function canBeTranslated(node, text) {
38
if (!text) return false;
39
if (!node.parentElement) return false;
40
41
var parentType = node.parentElement.nodeName;
42
if (parentType == 'SCRIPT' || parentType == 'STYLE' || parentType == 'TEXTAREA') return false;
43
44
if (parentType == 'OPTION' || parentType == 'SPAN') {
45
var pnode = node;
46
for (var level = 0; level < 4; level++) {
47
pnode = pnode.parentElement;
48
if (!pnode) break;
49
50
if (ignore_ids_for_localization[pnode.id] == parentType) return false;
51
}
52
}
53
54
if (re_num.test(text)) return false;
55
if (re_emoji.test(text)) return false;
56
return true;
57
}
58
59
function getTranslation(text) {
60
if (!text) return undefined;
61
62
if (translated_lines[text] === undefined) {
63
original_lines[text] = 1;
64
}
65
66
var tl = localization[text];
67
if (tl !== undefined) {
68
translated_lines[tl] = 1;
69
}
70
71
return tl;
72
}
73
74
function processTextNode(node) {
75
var text = node.textContent.trim();
76
77
if (!canBeTranslated(node, text)) return;
78
79
var tl = getTranslation(text);
80
if (tl !== undefined) {
81
node.textContent = tl;
82
}
83
}
84
85
function processNode(node) {
86
if (node.nodeType == 3) {
87
processTextNode(node);
88
return;
89
}
90
91
if (node.title) {
92
let tl = getTranslation(node.title);
93
if (tl !== undefined) {
94
node.title = tl;
95
}
96
}
97
98
if (node.placeholder) {
99
let tl = getTranslation(node.placeholder);
100
if (tl !== undefined) {
101
node.placeholder = tl;
102
}
103
}
104
105
textNodesUnder(node).forEach(function(node) {
106
processTextNode(node);
107
});
108
}
109
110
function localizeWholePage() {
111
processNode(gradioApp());
112
113
function elem(comp) {
114
var elem_id = comp.props.elem_id ? comp.props.elem_id : "component-" + comp.id;
115
return gradioApp().getElementById(elem_id);
116
}
117
118
for (var comp of window.gradio_config.components) {
119
if (comp.props.webui_tooltip) {
120
let e = elem(comp);
121
122
let tl = e ? getTranslation(e.title) : undefined;
123
if (tl !== undefined) {
124
e.title = tl;
125
}
126
}
127
if (comp.props.placeholder) {
128
let e = elem(comp);
129
let textbox = e ? e.querySelector('[placeholder]') : null;
130
131
let tl = textbox ? getTranslation(textbox.placeholder) : undefined;
132
if (tl !== undefined) {
133
textbox.placeholder = tl;
134
}
135
}
136
}
137
}
138
139
function dumpTranslations() {
140
if (!hasLocalization()) {
141
// If we don't have any localization,
142
// we will not have traversed the app to find
143
// original_lines, so do that now.
144
localizeWholePage();
145
}
146
var dumped = {};
147
if (localization.rtl) {
148
dumped.rtl = true;
149
}
150
151
for (const text in original_lines) {
152
if (dumped[text] !== undefined) continue;
153
dumped[text] = localization[text] || text;
154
}
155
156
return dumped;
157
}
158
159
function download_localization() {
160
var text = JSON.stringify(dumpTranslations(), null, 4);
161
162
var element = document.createElement('a');
163
element.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(text));
164
element.setAttribute('download', "localization.json");
165
element.style.display = 'none';
166
document.body.appendChild(element);
167
168
element.click();
169
170
document.body.removeChild(element);
171
}
172
173
document.addEventListener("DOMContentLoaded", function() {
174
if (!hasLocalization()) {
175
return;
176
}
177
178
onUiUpdate(function(m) {
179
m.forEach(function(mutation) {
180
mutation.addedNodes.forEach(function(node) {
181
processNode(node);
182
});
183
});
184
});
185
186
localizeWholePage();
187
188
if (localization.rtl) { // if the language is from right to left,
189
(new MutationObserver((mutations, observer) => { // wait for the style to load
190
mutations.forEach(mutation => {
191
mutation.addedNodes.forEach(node => {
192
if (node.tagName === 'STYLE') {
193
observer.disconnect();
194
195
for (const x of node.sheet.rules) { // find all rtl media rules
196
if (Array.from(x.media || []).includes('rtl')) {
197
x.media.appendMedium('all'); // enable them
198
}
199
}
200
}
201
});
202
});
203
})).observe(gradioApp(), {childList: true});
204
}
205
});
206
207