Translations minor refactoring

This commit is contained in:
Georgy Litvinov 2021-07-06 12:44:17 +02:00
parent 346ca096f9
commit f9a017cc9f

View file

@ -1,13 +1,3 @@
var pageTranslations = new Map();
var overridenTranslations = new Map();
var startSep = '\u25a4';
var endSep = '\u25a5';
var intSep = '\u25a6';
var resultSep = '\u200b\uFEFF\u200b\uFEFF\u200b';
var resultSepChars = '\u200b\uFEFF';
class PropAddr { class PropAddr {
constructor(node, number, args) { constructor(node, number, args) {
this.node = node; this.node = node;
@ -25,34 +15,46 @@ class PropInfo {
} }
} }
function saveTranslations() { function onlineTranslation() {
var pageTranslations = new Map();
var overridenTranslations = new Map();
var startSep = '\u25a4';
var endSep = '\u25a5';
var intSep = '\u25a6';
var resultSep = '\u200b\uFEFF\u200b\uFEFF\u200b';
var resultSepChars = '\u200b\uFEFF';
translationsParsing();
createTranslationsInterface();
function saveTranslations() {
var storage = window.localStorage; var storage = window.localStorage;
var serializedTranslations = JSON.stringify(Array.from(overridenTranslations.entries())); var serializedTranslations = JSON.stringify(Array.from(overridenTranslations.entries()));
storage.setItem("overridenTranslations", serializedTranslations); storage.setItem("overridenTranslations", serializedTranslations);
} }
function readTranslations() {
function readTranslations() {
var storage = window.localStorage; var storage = window.localStorage;
var serializedTranslations = storage.getItem("overridenTranslations"); var serializedTranslations = storage.getItem("overridenTranslations");
if (serializedTranslations != null) { if (serializedTranslations != null) {
overridenTranslations = new Map(JSON.parse(serializedTranslations)); overridenTranslations = new Map(JSON.parse(serializedTranslations));
} }
} }
function createTranslationsInterface() { function createTranslationsInterface() {
var devPanel = document.getElementById("developerPanel");
if (devPanel !== null) {
var container = document.createElement("div"); var container = document.createElement("div");
container.setAttribute("id", "translationsContainer"); container.setAttribute("id", "translationsContainer");
container.setAttribute("style", "font-size:0.8em !important;width: 440px; resize: horizontal; overflow: auto; padding: 10px; position: absolute;background-color:#f7dd8a;border:1px dotted;z-index:10000"); container.setAttribute("style", "font-size:0.8em !important;width: 440px; resize: horizontal; \
//document.body.appendChild(container); overflow: auto; padding: 10px; position: absolute;background-color:#f7dd8a;border:1px dotted;z-index:10000");
var devPanel = document.getElementById("developerPanel");
devPanel.parentNode.insertBefore(container, devPanel.nextSibling); devPanel.parentNode.insertBefore(container, devPanel.nextSibling);
createTranslationControls(container); createTranslationControls(container);
createTableFromPageTranslations(container); createTableFromPageTranslations(container);
//$(document.getElementById("translationsContainer")).draggable(); }
} }
function createTranslationControls(container){ function createTranslationControls(container) {
var controls = document.createElement("div") var controls = document.createElement("div");
controls.setAttribute("id", "translationControls"); controls.setAttribute("id", "translationControls");
controls.setAttribute("style", "margin-bottom:8px;") controls.setAttribute("style", "margin-bottom:8px;")
container.appendChild(controls); container.appendChild(controls);
@ -60,19 +62,19 @@ function createTranslationControls(container){
var cleanButton = document.createElement("button"); var cleanButton = document.createElement("button");
cleanButton.textContent = "Clean All"; cleanButton.textContent = "Clean All";
cleanButton.setAttribute("onclick", "cleanTranslations()"); cleanButton.setAttribute("onclick", "cleanTranslations()");
cleanButton.setAttribute("style","margin-right:10px;") cleanButton.setAttribute("style", "margin-right:10px;");
controls.appendChild(cleanButton); controls.appendChild(cleanButton);
var exportAllButton = document.createElement("button"); var exportAllButton = document.createElement("button");
exportAllButton.textContent = "Export All"; exportAllButton.textContent = "Export All";
exportAllButton.setAttribute("onclick", "exportAll()"); exportAllButton.setAttribute("onclick", "exportAll()");
exportAllButton.setAttribute("style","margin-right:10px;") exportAllButton.setAttribute("style", "margin-right:10px;");
controls.appendChild(exportAllButton); controls.appendChild(exportAllButton);
var exportFileInput = document.createElement("input"); var exportFileInput = document.createElement("input");
var exportFileButton = document.createElement("button"); var exportFileButton = document.createElement("button");
exportFileButton.setAttribute("style","margin-right:10px;") exportFileButton.setAttribute("style", "margin-right:10px;");
exportFileInput.type = "file"; exportFileInput.type = "file";
exportFileInput.setAttribute("id", "exportFile"); exportFileInput.setAttribute("id", "exportFile");
exportFileInput.setAttribute("style", "display:none;"); exportFileInput.setAttribute("style", "display:none;");
@ -80,7 +82,7 @@ function createTranslationControls(container){
var exportFileLabel = document.createElement("label"); var exportFileLabel = document.createElement("label");
exportFileLabel.setAttribute("for", "exportFile"); exportFileLabel.setAttribute("for", "exportFile");
exportFileLabel.textContent = "Update file"; exportFileLabel.textContent = "Update file";
exportFileLabel.setAttribute("style","margin:0px;color:black;") exportFileLabel.setAttribute("style", "margin:0px;color:black;")
exportFileButton.appendChild(exportFileLabel); exportFileButton.appendChild(exportFileLabel);
controls.appendChild(exportFileButton); controls.appendChild(exportFileButton);
controls.appendChild(exportFileInput); controls.appendChild(exportFileInput);
@ -93,23 +95,22 @@ function createTranslationControls(container){
importFileInput.setAttribute("id", "importFile"); importFileInput.setAttribute("id", "importFile");
importFileInput.setAttribute("accept", ".properties"); importFileInput.setAttribute("accept", ".properties");
var importFileLabel = document.createElement("label"); var importFileLabel = document.createElement("label");
importFileLabel.setAttribute("style","margin:0px;color:black;") importFileLabel.setAttribute("style", "margin:0px;color:black;")
importFileLabel.setAttribute("for", "importFile"); importFileLabel.setAttribute("for", "importFile");
importFileLabel.textContent = "Import from file"; importFileLabel.textContent = "Import from file";
importFileButton.appendChild(importFileLabel); importFileButton.appendChild(importFileLabel);
controls.appendChild(importFileButton); controls.appendChild(importFileButton);
controls.appendChild(importFileInput); controls.appendChild(importFileInput);
importFileInput.addEventListener("change", onImportFileUpload); importFileInput.addEventListener("change", onImportFileUpload);
}
} function cleanTranslations() {
function cleanTranslations() {
overridenTranslations.clear(); overridenTranslations.clear();
saveTranslations(); saveTranslations();
location.reload(); location.reload();
} }
function onImportFileUpload(e) { function onImportFileUpload(e) {
const fileList = e.target.files; const fileList = e.target.files;
const numFiles = fileList.length; const numFiles = fileList.length;
if (numFiles > 0) { if (numFiles > 0) {
@ -122,11 +123,11 @@ function onImportFileUpload(e) {
for (var i = 0; i < lines.length; i++) { for (var i = 0; i < lines.length; i++) {
if (!isCommentLine(lines[i])) { if (!isCommentLine(lines[i])) {
if (followLine) { if (followLine) {
followLine = goesToNextLine(lines[i]); followLine = isNextLineFollow(lines[i]);
var lineValue = lines[i].replace(/\\$/, ""); var lineValue = lines[i].replace(/\\$/, "");
overridenTranslations.set(lineKey, overridenTranslations.get(lineKey) + lineValue); overridenTranslations.set(lineKey, overridenTranslations.get(lineKey) + lineValue);
} else { } else {
followLine = goesToNextLine(lines[i]); followLine = isNextLineFollow(lines[i]);
lineKey = getLineKey(lines[i]); lineKey = getLineKey(lines[i]);
if (lineKey.trim() != "") { if (lineKey.trim() != "") {
let lineValue = getLineValue(lines[i]); let lineValue = getLineValue(lines[i]);
@ -140,14 +141,14 @@ function onImportFileUpload(e) {
} }
reader.readAsText(file); reader.readAsText(file);
} }
} }
function onExportFileUpload(e) { function onExportFileUpload(e) {
const fileList = e.target.files; const fileList = e.target.files;
const numFiles = fileList.length; const numFiles = fileList.length;
if (numFiles > 0) { if (numFiles > 0) {
const file = fileList[0]; const file = fileList[0];
var fileName = e.target.value.split(/(\\|\/)/g).pop() var fileName = e.target.value.split(/(\\|\/)/g).pop();
var reader = new FileReader(); var reader = new FileReader();
reader.onload = function(progressEvent) { reader.onload = function(progressEvent) {
var lines = this.result.split(/\r\n|\n\r|\n|\r/); var lines = this.result.split(/\r\n|\n\r|\n|\r/);
@ -157,7 +158,7 @@ function onExportFileUpload(e) {
for (var i = 0; i < lines.length; i++) { for (var i = 0; i < lines.length; i++) {
if (!isCommentLine(lines[i])) { if (!isCommentLine(lines[i])) {
if (followLine) { if (followLine) {
followLine = goesToNextLine(lines[i]); followLine = isNextLineFollow(lines[i]);
if (keyLineHasChanged) { if (keyLineHasChanged) {
//clean line as it's upper content has changed //clean line as it's upper content has changed
lines[i] = ""; lines[i] = "";
@ -168,7 +169,7 @@ function onExportFileUpload(e) {
// skip line // skip line
} else { } else {
keyLineHasChanged = false; keyLineHasChanged = false;
followLine = goesToNextLine(lines[i]); followLine = isNextLineFollow(lines[i]);
lineKey = getLineKey(lines[i]); lineKey = getLineKey(lines[i]);
if (overridenTranslations.has(lineKey)) { if (overridenTranslations.has(lineKey)) {
var value = overridenTranslations.get(lineKey); var value = overridenTranslations.get(lineKey);
@ -182,25 +183,24 @@ function onExportFileUpload(e) {
} }
reader.readAsText(file); reader.readAsText(file);
} }
//const selectedFile = document.getElementById('exportFile').files[0]; }
}
function exportAll() { function exportAll() {
var date = new Date; var date = new Date;
var fileName = "export_" + date.toLocaleString() + "_all.properties" var fileName = "export_" + date.toLocaleString() + "_all.properties";
var lines = []; var lines = [];
for (let [key, value] of overridenTranslations) { for (let [key, value] of overridenTranslations) {
lines.push(key + " = " + value); lines.push(key + " = " + value);
} }
exportFile(fileName, lines); exportFile(fileName, lines);
} }
function exportFile(fileName, lines) { function exportFile(fileName, lines) {
var blob = new Blob([lines.join("\n")], { type: 'text/plain;charset=utf-8' }); var blob = new Blob([lines.join("\n")], { type: 'text/plain;charset=utf-8' });
saveAs(blob, fileName); saveAs(blob, fileName);
} }
function getLineKey(line) { function getLineKey(line) {
var matches = line.match(/^\s*[^=\s]*(?=\s*=)/); var matches = line.match(/^\s*[^=\s]*(?=\s*=)/);
var key; var key;
if (matches == null) { if (matches == null) {
@ -209,23 +209,23 @@ function getLineKey(line) {
key = matches[0].trim(); key = matches[0].trim();
} }
return key; return key;
} }
function getLineValue(line) { function getLineValue(line) {
var value = line.replace(/^\s*[^=\s]*\s*=\s*/, ""); var value = line.replace(/^\s*[^=\s]*\s*=\s*/, "");
value = value.replace(/\\$/, ""); value = value.replace(/\\$/, "");
return value; return value;
} }
function goesToNextLine(line) { function isNextLineFollow(line) {
return line.match(/\\(\\\\)*$/) != null; return line.match(/\\(\\\\)*$/) != null;
} }
function isCommentLine(line) { function isCommentLine(line) {
return line.match(/^\s*[#!]/) != null; return line.match(/^\s*[#!]/) != null;
} }
function createTableFromPageTranslations(container) { function createTableFromPageTranslations(container) {
var table = document.createElement("table"); var table = document.createElement("table");
table.setAttribute("id", "translationsTable"); table.setAttribute("id", "translationsTable");
table.setAttribute("style", "width:100%;"); table.setAttribute("style", "width:100%;");
@ -235,7 +235,7 @@ function createTableFromPageTranslations(container) {
var tr = document.createElement("tr"); var tr = document.createElement("tr");
table.appendChild(tr); table.appendChild(tr);
var td1 = document.createElement("td"); var td1 = document.createElement("td");
td1.setAttribute("style", " width:1%;white-space:nowrap;") td1.setAttribute("style", " width:1%;white-space:nowrap;");
var keyText = document.createTextNode(key); var keyText = document.createTextNode(key);
var td2 = document.createElement("td"); var td2 = document.createElement("td");
var rawText = document.createElement("input"); var rawText = document.createElement("input");
@ -258,9 +258,9 @@ function createTableFromPageTranslations(container) {
onTranslationChange(this); onTranslationChange(this);
}); });
} }
} }
function onTranslationChange(input) { function onTranslationChange(input) {
if (input.value != input.nextSibling.value) { if (input.value != input.nextSibling.value) {
var key = input.parentElement.previousSibling.firstChild.textContent; var key = input.parentElement.previousSibling.firstChild.textContent;
if (input.value == "") { if (input.value == "") {
@ -279,14 +279,14 @@ function onTranslationChange(input) {
} }
} }
saveTranslations(); saveTranslations();
if (jsHasChanged(key)) { if (isJSHasChanged(key)) {
location.reload(); location.reload();
} }
updateTranslationOnPage(key, value); updateTranslationOnPage(key, value);
} }
} }
function jsHasChanged(key) { function isJSHasChanged(key) {
var result = false; var result = false;
if (pageTranslations.has(key)) { if (pageTranslations.has(key)) {
var addresses = pageTranslations.get(key).addresses; var addresses = pageTranslations.get(key).addresses;
@ -298,9 +298,9 @@ function jsHasChanged(key) {
} }
} }
return result; return result;
} }
function updateTranslationOnPage(key, value) { function updateTranslationOnPage(key, value) {
var propInfo = pageTranslations.get(key); var propInfo = pageTranslations.get(key);
var addresses = propInfo.addresses; var addresses = propInfo.addresses;
for (let i = 0; i < addresses.length; i++) { for (let i = 0; i < addresses.length; i++) {
@ -312,20 +312,20 @@ function updateTranslationOnPage(key, value) {
const regEx = new RegExp("^(?:[^" + resultSepChars + "]*" + regexStr + "){" + number + "}"); const regEx = new RegExp("^(?:[^" + resultSepChars + "]*" + regexStr + "){" + number + "}");
var newString = content.replace(regEx, var newString = content.replace(regEx,
function(x) { function(x) {
return x.replace(RegExp(regexStr + "$"), resultSep + formattedValue + resultSep) return x.replace(RegExp(regexStr + "$"), resultSep + formattedValue + resultSep);
}); });
node.textContent = newString; node.textContent = newString;
} }
} }
function formatTranslation(value, args) { function formatTranslation(value, args) {
for (let i = 0; i < args.length; i++) { for (let i = 0; i < args.length; i++) {
value = value.replaceAll("{" + i + "}", args[i]) value = value.replaceAll("{" + i + "}", args[i]);
} }
return value; return value;
} }
function translationsParsing() { function translationsParsing() {
var translatedTexts = []; var translatedTexts = [];
var translatedAttrs = []; var translatedAttrs = [];
var xpath = "//attribute::*[contains(., '" + startSep + "')]"; var xpath = "//attribute::*[contains(., '" + startSep + "')]";
@ -346,9 +346,9 @@ function translationsParsing() {
removePropInfoFromPage(); removePropInfoFromPage();
updatePageWithOverridenTranslations(); updatePageWithOverridenTranslations();
reloadJS(); reloadJS();
} }
function reloadJS() { function reloadJS() {
var scriptBlocks = document.getElementsByTagName('script'); var scriptBlocks = document.getElementsByTagName('script');
for (let i = 0; i < scriptBlocks.length; i++) { for (let i = 0; i < scriptBlocks.length; i++) {
var scriptBlock = scriptBlocks[i]; var scriptBlock = scriptBlocks[i];
@ -369,32 +369,32 @@ function reloadJS() {
addInlineJS(content); addInlineJS(content);
} }
} }
} }
function addInlineJS(content) { function addInlineJS(content) {
var head = document.getElementsByTagName('head')[0]; var head = document.getElementsByTagName('head')[0];
var script = document.createElement('script'); var script = document.createElement('script');
script.textContent = content; script.textContent = content;
head.appendChild(script); head.appendChild(script);
} }
function addJSLink(fileUrl) { function addJSLink(fileUrl) {
var head = document.getElementsByTagName('head')[0]; var head = document.getElementsByTagName('head')[0];
var script = document.createElement('script'); var script = document.createElement('script');
script.type = "text/javascript"; script.type = "text/javascript";
script.src = fileUrl; script.src = fileUrl;
head.appendChild(script); head.appendChild(script);
} }
function updatePageWithOverridenTranslations() { function updatePageWithOverridenTranslations() {
for (let [key, value] of overridenTranslations) { for (let [key, value] of overridenTranslations) {
if (pageTranslations.has(key)) { if (pageTranslations.has(key)) {
updateTranslationOnPage(key, value); updateTranslationOnPage(key, value);
} }
} }
} }
function removePropInfoFromPage() { function removePropInfoFromPage() {
for (let [key, propInfo] of pageTranslations) { for (let [key, propInfo] of pageTranslations) {
var addresses = propInfo.addresses; var addresses = propInfo.addresses;
for (let i = 0; i < addresses.length; i++) { for (let i = 0; i < addresses.length; i++) {
@ -402,28 +402,27 @@ function removePropInfoFromPage() {
var content = node.textContent; var content = node.textContent;
var regexStr = startSep + "[^" + endSep + "]*" + intSep + "([^" + endSep + intSep + "]*)" + endSep; var regexStr = startSep + "[^" + endSep + "]*" + intSep + "([^" + endSep + intSep + "]*)" + endSep;
const regEx = new RegExp(regexStr, "g"); const regEx = new RegExp(regexStr, "g");
//console.log(regexStr);
var newString = content.replaceAll(regEx, resultSep + "$1" + resultSep); var newString = content.replaceAll(regEx, resultSep + "$1" + resultSep);
node.textContent = newString; node.textContent = newString;
} }
} }
} }
function addPropsFromTextNode(node) { function addPropsFromTextNode(node) {
var textString = node.textContent; var textString = node.textContent;
var i = 0; var i = 0;
while (textString.indexOf(startSep) >= 0) { while (textString.indexOf(startSep) >= 0) {
textString = textString.substring(textString.indexOf(startSep) + startSep.length); textString = textString.substring(textString.indexOf(startSep) + startSep.length);
var prop = textString.substring(0, textString.indexOf(endSep)) var prop = textString.substring(0, textString.indexOf(endSep));
var address = new PropAddr(node, i, []); var address = new PropAddr(node, i, []);
addProp(prop, address); addProp(prop, address);
i++; i++;
} }
} }
function addPropsFromAttribute(node) { function addPropsFromAttribute(node) {
var attrString = node.textContent; var attrString = node.textContent;
var i = 0 var i = 0;
while (attrString.indexOf(startSep) >= 0) { while (attrString.indexOf(startSep) >= 0) {
attrString = attrString.substring(attrString.indexOf(startSep) + startSep.length); attrString = attrString.substring(attrString.indexOf(startSep) + startSep.length);
var prop = attrString.substring(0, attrString.indexOf(endSep)); var prop = attrString.substring(0, attrString.indexOf(endSep));
@ -431,17 +430,17 @@ function addPropsFromAttribute(node) {
addProp(prop, address); addProp(prop, address);
i++; i++;
} }
} }
function addProp(prop, address) { function addProp(prop, address) {
var key = prop.substring(0, prop.indexOf(intSep)); var key = prop.substring(0, prop.indexOf(intSep));
prop = prop.substring(prop.indexOf(intSep) + intSep.length) prop = prop.substring(prop.indexOf(intSep) + intSep.length);
var rawText = prop.substring(0, prop.indexOf(intSep)); var rawText = prop.substring(0, prop.indexOf(intSep));
prop = prop.substring(prop.indexOf(intSep) + intSep.length) prop = prop.substring(prop.indexOf(intSep) + intSep.length);
var textArgs = []; var textArgs = [];
var i = 0; var i = 0;
while (prop.indexOf(intSep) >= 0) { while (prop.indexOf(intSep) >= 0) {
var textArg = prop.substring(0, prop.indexOf(intSep)) var textArg = prop.substring(0, prop.indexOf(intSep));
prop = prop.substring(prop.indexOf(intSep) + intSep.length); prop = prop.substring(prop.indexOf(intSep) + intSep.length);
textArgs.push(textArg); textArgs.push(textArg);
i++; i++;
@ -451,21 +450,20 @@ function addProp(prop, address) {
var propInfo = null; var propInfo = null;
if (pageTranslations.has(key)) { if (pageTranslations.has(key)) {
propInfo = pageTranslations.get(key); propInfo = pageTranslations.get(key);
//TODO: CHECK ADDRESS BEFORE ADDING ANOTHER ONE
propInfo.addresses.push(address); propInfo.addresses.push(address);
} else { } else {
propInfo = new PropInfo(rawText, formText, address); propInfo = new PropInfo(rawText, formText, address);
pageTranslations.set(key, propInfo) pageTranslations.set(key, propInfo);
} }
return propInfo; return propInfo;
}
} }
window.addEventListener('load', function() { window.addEventListener('load', function() {
setTimeout(function() { setTimeout(function() {
var developerSetting = document.getElementById("developer_i18n_onlineTranslation"); var developerSetting = document.getElementById("developer_i18n_onlineTranslation");
if (developerSetting !== null && developerSetting.checked) { if (developerSetting !== null && developerSetting.checked) {
translationsParsing(); onlineTranslation();
createTranslationsInterface();
} }
}, 1000); }, 1000);
}) })