-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathapp.js
237 lines (204 loc) · 8.97 KB
/
app.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
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
const fetch = require('node-fetch');
// note: use npm install node-fetch@2.0 to be able to use "require"
function translateText (text, targetLanguage, googleTranslateProxy, googleTranslateApiKey) {
let body = {
'q' : text,
'target': targetLanguage
};
let translatedText = "";
return new Promise((resolve, reject) => {
fetch(`${googleTranslateProxy}https://translation.googleapis.com/language/translate/v2?key=${googleTranslateApiKey}`, {
method: 'POST',
body: JSON.stringify(body),
headers: {
'accept': 'application/json',
'Content-Type': 'application/json'
// fyi, NO need for content length
}
})
.then(res => res.json())
.then(json => {translatedText = json.data.translations[0].translatedText; resolve(translatedText);})
.catch (err => {console.log(err); reject(err);})
})
}
async function tInit(langId, pathName, tConfig, doTranslate, googleTranslateApiKey) {
try {
if (tConfig.translationdata.length == 0 || tConfig.initoptions.force == true) {
// No translation data or force is set to true, so let's collect data
let pathNames = tConfig.initoptions.pathnames;
// Find index of this array element
let pathNameIndex = pathNames.findIndex(el => el == pathName);
// If it's a first page, clear local storage. Or currentpageonly is set to true.
if (pathNameIndex == 0 || tConfig.initoptions.currentpageonly == true) { localStorage.clear() };
// Collect all relevant data for page
await tElements(pathName, tConfig, googleTranslateApiKey);
// Find next element's index in array
let pathNameNextIndex = pathNameIndex + 1;
if (pathNames.length > pathNameNextIndex && tConfig.initoptions.currentpageonly == false) {
// Next element exists, so navigate to it
let pathNextName = pathNames[pathNameNextIndex];
if (window.location.href !== `${tConfig.initoptions.protocol}${tConfig.initoptions.host}${pathNextName}`) {
window.location.href = `${tConfig.initoptions.protocol}${tConfig.initoptions.host}${pathNextName}`;
}
} else {
// This was last element of an array, show results in JSON format and return
let ret = {translationdata: JSON.parse(localStorage.getItem('gTranslationData'))};
console.log(JSON.stringify(ret));
// We will not clear local storage because it's an alternative way for front-end to grab the data
// besides previous console.log line. Local storage will be cleared anyway if new initialization starts
// (due to option force = true or if user manually deletes data from his json config).
// localStorage.clear();
return ret;
}
} else {
// Translation data exists, so let's translate page if doTranslate is set to true
if (doTranslate) {
let ret = tTranslate(langId, pathName, tConfig);
return ret
} else {
return {success: true, message: "Not translated because tTranslate parameter is set to false"};
}
}
}
catch {err => {
localStorage.clear();
console.log("Error tInit(): " + err);
}}
}
async function tElements (pathName, tConfig, googleTranslateApiKey) {
let ret = {};
let arrElements = [];
let translationsArr = [];
let langClass = tConfig.translationoptions.classname;
let langArr = tConfig.initoptions.languages;
// langClass = ".translate"
// langArr = [{ id: 0, code: "hr", text: "Croatian" }, { id: 1, code: "de", text: "German" }];
langArr.forEach(lang =>
translationsArr.push({ langid: lang.id, langcode: lang.code, langtext: lang.text, translation: "" })
)
let items = document.querySelectorAll(langClass);
return new Promise((resolve, reject) => {
// Use local storage to temporarily save data between function calls from different pages
let tempArray = [];
if (localStorage.getItem('gTranslationData') != null) {
tempArray = JSON.parse(localStorage.getItem('gTranslationData'));
}
try {
for (const [idx, item] of items.entries()) {
if (tConfig.initoptions.googletranslate.enable == false) {
// No google translate
arrElements.push(
{
id: item.id,
dotranslate: item.id !=="" ? true: false,
innerhtml: item.innerHTML,
translations: translationsArr
}
)
if (items.length == arrElements.length) {
tempArray.push({ page: pathName, elements: arrElements });
localStorage.setItem('gTranslationData', JSON.stringify(tempArray));
resolve();
}
} else {
// Google translate
for (const [langIdx, lang] of langArr.entries()) {
let googleTranslation = "";
translateText(item.innerHTML, lang.code, tConfig.initoptions.googletranslate.proxy, googleTranslateApiKey)
.then((res) => {googleTranslation = res;console.log(res);})
.then(() => {translationsArr = []; translationsArr[langIdx] = { langid: lang.id, langcode: lang.code, langtext: lang.text, translation: googleTranslation }; })
.then(() => {
let el = arrElements[idx];
if (!el) {
arrElements[idx] =
{
id: item.id,
dotranslate: item.id !=="" ? true: false,
innerhtml: item.innerHTML,
translations: translationsArr
}
} else {
if (arrElements[idx]["translations"] !== undefined) {
arrElements[idx].translations[langIdx] = translationsArr[langIdx];
translationsArr = [];
} else {
arrElements[idx]["translations"][langIdx] = translationsArr;
translationsArr = [];
}
}
})
.then(() => {
if (items.length == arrElements.reduce(c => c + 1, 0) && arrElements[idx].translations.reduce(c => c + 1, 0) == langArr.length) {
tempArray.push({ page: pathName, elements: arrElements });
localStorage.setItem('gTranslationData', JSON.stringify(tempArray));
resolve();
}
})
.catch((err) => {console.log("Error Google Translate: " + err);});
}
}
};
}
catch {err =>
console.log("Error tElements(): " + err);
return {error: "Error tElements(): " + err};
}
})
};
function tTranslate(langId, pathName, tConfig) {
let ret = {};
let retErrors = [];
let retWarnings = [];
let items = document.querySelectorAll(tConfig.translationoptions.classname);
let translationData = tConfig.translationdata.find(el => el.page == pathName);
let elements = translationData?.elements;
if (!elements) {
// No elements data for that page, return
retErrors.push({error: "No elements defined for page " + pathName});
ret = {success: retErrors.length==0 ? true : false, errors: retErrors, warnings: retWarnings};
console.log(ret);
return ret;
}
if (!translationData) {
// No translation data for that page, return
retErrors.push({error: "No translation definition for page " + pathName});
ret = {success: retErrors.length==0 ? true : false, errors: retErrors, warnings: retWarnings};
console.log(ret);
return ret;
}
try {
items.forEach(item => {
let chunk = elements.find(el => el.id == item.id && el.dotranslate == true);
if (chunk) {
if (chunk.id == "") {
retWarnings.push({warning: "Element has no id defined and dotranslate is set to true. Element will not be translated. InnerHTML: " + chunk.innerhtml});
} else {
let translationSection = chunk.translations.find(el => el.langid == langId);
if (translationSection) {
if (chunk.translations[langId].translation == "") {
if (tConfig.translationoptions.translateblanks == true) {
item.innerHTML = chunk.translations[langId].translation;
} else {
retWarnings.push({warning: "Element with id " + item.id + " has no translation defined for langid " + langId + " so it will not be translated because translateblanks is set to false"});
}
} else {
item.innerHTML = chunk.translations[langId].translation;
}
} else {
retErrors.push({error: "No translation definition with langid " + langId + " for element with id " + item.id});
}
}
}
});
}
catch {err =>
console.log("Error tTranslate(): " + err);
return {error: "Error tTranslate(): " + err};
}
ret = {success: retErrors.length==0 ? true : false, errors: retErrors, warnings: retWarnings};
console.log(ret);
return ret;
};
module.exports = {
tInit
}