mirror of
https://github.com/OMGeeky/andors-trail.git
synced 2025-12-26 16:07:57 +01:00
449 lines
14 KiB
JavaScript
449 lines
14 KiB
JavaScript
function IncludeJavascript(jsFile) {
|
||
document.write('<script type="text/javascript" src="' + jsFile + '"></scr' + 'ipt>');
|
||
}
|
||
|
||
IncludeJavascript("FieldList.js");
|
||
IncludeJavascript("DataStore.js");
|
||
|
||
var translateFiles = [
|
||
'strings.xml',
|
||
'strings_about.xml',
|
||
'content_actorconditions.xml',
|
||
'content_conversationlist.xml',
|
||
'content_droplist.xml',
|
||
'content_itemlist.xml',
|
||
'content_itemcategories.xml',
|
||
'content_monsterlist.xml',
|
||
'content_questlist.xml'
|
||
];
|
||
|
||
var translations = [
|
||
{ name: 'French', id: 'values-fr', files: [
|
||
'content_actorconditions.xml',
|
||
'content_conversationlist.xml',
|
||
'content_itemlist.xml',
|
||
'content_monsterlist.xml',
|
||
'content_questlist.xml',
|
||
'strings.xml'
|
||
]},
|
||
{ name: 'Italian', id: 'values-it', files: [
|
||
'content_actorconditions.xml',
|
||
'content_conversationlist.xml',
|
||
'content_itemlist.xml',
|
||
'content_questlist.xml',
|
||
'strings.xml'
|
||
]},
|
||
{ name: 'German', id: 'values-de', files: [
|
||
'content_actorconditions.xml',
|
||
'content_conversationlist.xml',
|
||
'content_itemlist.xml',
|
||
'content_itemcategories.xml',
|
||
'content_monsterlist.xml',
|
||
'content_questlist.xml',
|
||
'strings_about.xml',
|
||
'strings.xml'
|
||
]},
|
||
{ name: 'Hebrew', id: 'values-iw', files: [
|
||
'strings.xml'
|
||
]},
|
||
{ name: 'Russian', id: 'values-ru', files: [
|
||
'content_actorconditions.xml',
|
||
'content_conversationlist.xml',
|
||
'content_itemlist.xml',
|
||
'content_monsterlist.xml',
|
||
'content_questlist.xml',
|
||
'strings.xml'
|
||
]},
|
||
{ name: 'Portugese', id: 'values-pt', files: [
|
||
'content_actorconditions.xml',
|
||
'content_monsterlist.xml',
|
||
'strings.xml'
|
||
]},
|
||
{ name: 'Japanese', id: 'values-ja', files: [
|
||
'content_conversationlist.xml',
|
||
'strings.xml'
|
||
]},
|
||
{ name: 'Brazilian Portugese', id: 'values-pt-rBR', files: [
|
||
'content_actorconditions.xml',
|
||
'content_conversationlist.xml',
|
||
'content_itemlist.xml',
|
||
'content_monsterlist.xml',
|
||
'content_questlist.xml',
|
||
'strings.xml'
|
||
]}
|
||
];
|
||
|
||
function stepRight(divToHide, divToShow, onComplete) {
|
||
$(divToHide).hide('slow');
|
||
$(divToShow).fadeIn('slow', onComplete);
|
||
}
|
||
function stepLeft(divToHide, divToShow) {
|
||
$(divToHide).fadeOut('slow');
|
||
$(divToShow).show('slow');
|
||
}
|
||
|
||
function loadResourceFile(filename, onSuccess) {
|
||
var url = document.location.href;
|
||
url = url.substring(0, url.lastIndexOf('/'));
|
||
url = url.substring(0, url.lastIndexOf('/'));
|
||
url += "/AndorsTrail/res/" + filename;
|
||
//var url = "http://andors-trail.googlecode.com/git/AndorsTrail/res/" + filename;
|
||
$.get(url, function(data) {
|
||
onSuccess(data);
|
||
}, 'text');
|
||
}
|
||
|
||
function addSelectOption(sel, val, text) {
|
||
if (!text) { text = val; }
|
||
sel.append($("<option/>").attr("value", val).text(text));
|
||
}
|
||
|
||
function addSelectOptions(sel, array) {
|
||
array.forEach(function(obj) { addSelectOption( sel , obj); } );
|
||
}
|
||
|
||
function loadStep2() {
|
||
var possibleExistingFiles = [];
|
||
var selectedSourceFile = $("#englishFiles").val();
|
||
translations.forEach(function(t) {
|
||
if ($.inArray(selectedSourceFile, t.files) > -1) {
|
||
possibleExistingFiles.push(t.id + "/" + selectedSourceFile);
|
||
}
|
||
});
|
||
$("#compareToExisting").empty();
|
||
addSelectOptions( $("#compareToExisting"), possibleExistingFiles );
|
||
stepRight("#validate1", "#validate2");
|
||
}
|
||
|
||
function pushMessage(res, msg) {
|
||
res.class2 = "yellow";
|
||
res.messages.push(msg);
|
||
return res;
|
||
}
|
||
|
||
function isTranslatableField(fieldName) {
|
||
return fieldName == "name" || fieldName == "logText" || fieldName == "message" || fieldName == "text";
|
||
}
|
||
|
||
function compareAndorsTrailResourceHeader(result, id, header1, header2) {
|
||
if (header1.length != header2.length) {
|
||
pushMessage(result, "Row \"" + id + "\" was expected to contain " + f1.length + " sub-entries, but only " + f2.length + " was found.");
|
||
return;
|
||
}
|
||
for (var i = 0; i < header1._fields.length; ++i) {
|
||
var f1 = header1._fields[i];
|
||
var fieldName1 = header1.getFieldName(i);
|
||
var f2 = header2._fields[i];
|
||
var fieldName2 = header2.getFieldName(i);
|
||
if (fieldName1 != fieldName2) {
|
||
pushMessage(result, "Row \"" + id + "\", field \"" + fieldName + "\" was expected to contain \"" + f1 + "\", but \"" + f2 + "\" was found.");
|
||
}
|
||
var fieldName2 = header2.getFieldName(i);
|
||
if (f1 instanceof FieldList) {
|
||
compareAndorsTrailResourceHeader(result, id+":"+fieldName1, f1, f2);
|
||
}
|
||
}
|
||
}
|
||
function extractTranslatableFields_(id, result, fieldList, prefix, obj) {
|
||
if (!result) {
|
||
result = {};
|
||
result.id = id;
|
||
result.fields = [];
|
||
}
|
||
if (!prefix) {
|
||
prefix = "";
|
||
}
|
||
for (var i = 0; i < fieldList._fields.length; ++i) {
|
||
var f = fieldList._fields[i];
|
||
if (f instanceof FieldList) {
|
||
// f is subfieldlist
|
||
$.each(obj[f._name], function(j, elem) {
|
||
extractTranslatableFields_(id, result, f, prefix+f._name+"["+j+"].", elem);
|
||
});
|
||
} else {
|
||
// f is field name
|
||
if (isTranslatableField(f)) {
|
||
result.fields.push({
|
||
"name":prefix+f,
|
||
"value":obj[f]
|
||
});
|
||
}
|
||
}
|
||
}
|
||
return result;
|
||
}
|
||
function extractTranslatableFields(id, fieldList, obj) {
|
||
return extractTranslatableFields_(id, undefined, fieldList, "", obj);
|
||
}
|
||
|
||
function compareAndorsTrailResourceRow(result, fieldList, id, obj1, obj2) {
|
||
// Assume the headers of both objects are correctly matched
|
||
trans1 = extractTranslatableFields(id, fieldList, obj1);
|
||
trans2 = extractTranslatableFields(id, fieldList, obj2);
|
||
$.each(trans1.fields, function(i, f1) {
|
||
f2 = trans2.fields[i];
|
||
if (f1.name != f2.name) {
|
||
pushMessage(result, "Row \"" + id + "\", field \"" + f1.name + "\" does not match in translated data field\"" + f2.name + "\".");
|
||
}
|
||
if (f1.value.length > 1) {
|
||
if (f1.value == f2.value) {
|
||
pushMessage(result, "Row \"" + id + "\", field \"" + f1.name + "\" does not seem to be translated. Both texts are \"" + f1.value + "\".");
|
||
}
|
||
}
|
||
});
|
||
}
|
||
|
||
function compareAndorsTrailResourceFormat(text1, text2) {
|
||
var result = {
|
||
isResource: true,
|
||
class1: "ok",
|
||
class2: "ok",
|
||
messages: [],
|
||
header: undefined,
|
||
ds_english: undefined,
|
||
ds_translated: undefined
|
||
};
|
||
|
||
var header1 = findHeader(text1);
|
||
if (!header1) { return { isResource: false }; }
|
||
result.header = header1;
|
||
|
||
var header2 = findHeader(text2);
|
||
if (!header2) { result.class2 = "red"; return result; }
|
||
|
||
compareAndorsTrailResourceHeader(result, "", header1, header2);
|
||
if (result.class2 != "ok") { return result; }
|
||
|
||
var ds1 = new DataStore({});
|
||
var ds2 = new DataStore({});
|
||
ds1.deserialize(text1);
|
||
ds2.deserialize(text2);
|
||
$.each(ds1.items, function(i, obj) {
|
||
var obj1 = obj;
|
||
var obj2 = ds2.get(i);
|
||
var id1 = obj1[header1._fields[0]];
|
||
if (!obj2) { return pushMessage(result, "Row " + i + ": expected to find an object with id \"" + id1 + "\", but such row was not found."); }
|
||
var id2 = obj2[header1._fields[0]];
|
||
if (id2 != id1) { return pushMessage(result, "Row " + i + ": Expected to find id \"" + id1 + "\", but found \"" + id2 + "\" instead."); }
|
||
|
||
compareAndorsTrailResourceRow(result, header1, id1, obj1, obj2);
|
||
});
|
||
|
||
result.ds_english = ds1;
|
||
result.ds_translated = ds2;
|
||
return result;
|
||
}
|
||
|
||
function applyChangeToObject(trans_obj, fieldName, newValue) {
|
||
(new Function("x", "v", "x."+fieldName+" = v;"))(trans_obj, newValue);
|
||
}
|
||
|
||
function appendEditRow(editTable, updateHook, trans_obj, id, fieldName, english_text, translated_text) {
|
||
if (english_text.length <= 1) {
|
||
// there's no meaningful text
|
||
return;
|
||
}
|
||
var row_id = name+"__row";
|
||
var cell_id = name+"__cell";
|
||
var edit_id = name+"__edit";
|
||
var cell = $("<span />").text(translated_text)
|
||
.attr("id", cell_id)
|
||
.attr("class", "clickToEdit");
|
||
var editor = $("<textarea />").val(translated_text)
|
||
.attr("id", cell_id)
|
||
.hide();
|
||
cell.click(function() {
|
||
editor.val(cell.text());
|
||
editor.show().focus();
|
||
cell.hide();
|
||
});
|
||
editor.blur(function() {
|
||
var new_text = editor.val();
|
||
cell.text(new_text);
|
||
editor.hide(); cell.show();
|
||
applyChangeToObject(trans_obj, fieldName, new_text);
|
||
updateHook();
|
||
});
|
||
editTable.append(
|
||
$("<tr />")
|
||
.attr("id", name+"__row")
|
||
.append($("<td />").text(id))
|
||
.append($("<td />").text(fieldName))
|
||
.append($("<td />").text(english_text))
|
||
.append($("<td />").append(cell).append(editor))
|
||
);
|
||
}
|
||
|
||
function clearEditTable() {
|
||
var editTable = $("#editTranslation tbody");
|
||
editTable.children().remove();
|
||
$("#export_text").val("");
|
||
}
|
||
|
||
function editTranslationHandler(data2, name, resourceComparison) {
|
||
var updateHook = function () {
|
||
var header = resourceComparison.header;
|
||
var ds2 = resourceComparison.ds_translated;
|
||
var text2 = ds2.serialize();
|
||
data2.find("string[name=\"" + name + "\"]").text(text2);
|
||
};
|
||
return function () {
|
||
clearEditTable();
|
||
var editTable = $("#editTranslation tbody");
|
||
var header = resourceComparison.header;
|
||
var ds1 = resourceComparison.ds_english;
|
||
var ds2 = resourceComparison.ds_translated;
|
||
$.each(ds1.items, function(i, obj1) {
|
||
var obj2 = ds2.get(i);
|
||
var id = obj1["id"];
|
||
var english_list = extractTranslatableFields(id, header, obj1);
|
||
var translated_list = extractTranslatableFields(id, header, obj2);
|
||
|
||
$.each(english_list.fields, function(j, f1) {
|
||
var f2 = translated_list.fields[j];
|
||
appendEditRow(
|
||
editTable, updateHook, obj2, id,
|
||
f1.name, f1.value, f2.value
|
||
);
|
||
});
|
||
});
|
||
};
|
||
}
|
||
function initTranslationHandler(data1, data2, name) {
|
||
var f = function() {
|
||
if (!confirm("Create new translation unit in this resouce?")) {
|
||
// if canceled
|
||
return;
|
||
}
|
||
clearEditTable();
|
||
// create new node in resource xml by copying english ver.
|
||
var node1 = data1.find("string[name=\"" + name + "\"]");
|
||
var text1 = node1.text();
|
||
data2.find("resources").append($("<string name=\""+name+"\" />").text(text1));
|
||
var resourceComparison = compareAndorsTrailResourceFormat(text1, text1);
|
||
// repalce this handler with "edit" event handler (and etc.)
|
||
var editHandler = editTranslationHandler(data2, name, resourceComparison);
|
||
$(this).parent().attr("class","yellow");
|
||
$(this).text("Edit").unbind('click', f).click(editHandler);
|
||
$(this).click();
|
||
}
|
||
return f;
|
||
}
|
||
function exportHandler(data2) {
|
||
var xmlString = function (data) {
|
||
var xml = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n\n";
|
||
xml += "<resources>\n";
|
||
$.each(data.find("string"), function() {
|
||
xml += "\t<string name=\""+$(this).attr("name")+"\">\n";
|
||
xml += $(this).text();
|
||
xml += "\n\t</string>\n\n";
|
||
});
|
||
xml += "</resources>\n";
|
||
return xml;
|
||
}
|
||
return function () {
|
||
$("#export_text").val(xmlString(data2));
|
||
};
|
||
}
|
||
|
||
function appendOutputRow(outputTable, name, data1, data2) {
|
||
if ($("#" + name, outputTable).size() > 0) return;
|
||
|
||
var text1 = data1.find("string[name=\"" + name + "\"]").text();
|
||
var text2 = data2.find("string[name=\"" + name + "\"]").text();
|
||
var class2 = text2 ? "ok" : "red";
|
||
var tdTranslated = $("<td />");
|
||
if (text1) {
|
||
if (text2) {
|
||
var resourceComparison = compareAndorsTrailResourceFormat(text1, text2);
|
||
if (resourceComparison.isResource) {
|
||
class2 = resourceComparison.class2;
|
||
if (resourceComparison.messages.length > 0 || class2 == "ok") {
|
||
// yellow || ok
|
||
var d = $("<span />").text("Edit");
|
||
d.click(editTranslationHandler(data2, name, resourceComparison));
|
||
tdTranslated.append(d);
|
||
}
|
||
}
|
||
} else /* if (class2 == "red") */ {
|
||
var d = $("<span />").text("Init");
|
||
d.click(initTranslationHandler(data1, data2, name));
|
||
tdTranslated.append(d);
|
||
}
|
||
}
|
||
|
||
outputTable.append(
|
||
$("<tr />")
|
||
.attr("id", name)
|
||
.append($("<td />").text(name))
|
||
.append(tdTranslated.attr("class", class2))
|
||
);
|
||
}
|
||
|
||
function validateTranslation_(englishData) {
|
||
$("#englishData").text(englishData);
|
||
var compareData1 = $( $.parseXML(englishData) );
|
||
var compareData2 = $( $.parseXML($("#compareToInput").val()) );
|
||
|
||
var resultTable = $("#validateResultContent #result");
|
||
var outputTable = $("tbody", resultTable );
|
||
outputTable.empty();
|
||
|
||
compareData1.find("string").each(function() {
|
||
appendOutputRow(outputTable, $(this).attr("name"), compareData1, compareData2);
|
||
});
|
||
compareData2.find("string").each(function() {
|
||
appendOutputRow(outputTable, $(this).attr("name"), compareData1, compareData2);
|
||
});
|
||
|
||
var sectionCount = $("tr", outputTable).size();
|
||
var errors1 = sectionCount - $("td:nth-child(2).ok", outputTable).size();
|
||
$("th #count2", resultTable).text( (errors1 > 0) ? " (" + errors1 + ")" : "" );
|
||
|
||
$("#export").click(exportHandler(compareData2));
|
||
|
||
$("#validateResultContent #loading").hide();
|
||
$("#validateResultContent #result").show();
|
||
}
|
||
function validateTranslation(englishData) {
|
||
try {
|
||
validateTranslation_(englishData);
|
||
} catch (err) {
|
||
alert(err);
|
||
}
|
||
}
|
||
|
||
function loadStep3() {
|
||
var compareToContent = $("#compareToInput").val();
|
||
if (compareToContent.length <= 0) {
|
||
alert("You must enter (or import) some translated content to compare.");
|
||
return;
|
||
}
|
||
|
||
$("#validateResultContent #loading").show();
|
||
$("#validateResultContent #result").hide();
|
||
stepRight("#validate2", "#validateResult", function() {
|
||
loadResourceFile( "values/" + $("#englishFiles").val() , validateTranslation )
|
||
});
|
||
}
|
||
|
||
function startTranslationValidator() {
|
||
addSelectOptions( $("#englishFiles"), translateFiles );
|
||
|
||
$("#next1").button({ icons: {primary:'ui-icon-arrowthick-1-e'} }).click(loadStep2);
|
||
$("#prev2").button({ icons: {primary:'ui-icon-arrowthick-1-w'} }).click(function() { stepLeft("#validate2", "#validate1"); });
|
||
$("#btnImportFromSVN").button().click(function() {
|
||
$("#compareToInput").val("Loading...");
|
||
loadResourceFile( $("#compareToExisting").val(), function(data) { $("#compareToInput").val(data); } );
|
||
});
|
||
$("#next2").button({ icons: {primary:'ui-icon-arrowthick-1-e'} }).click(loadStep3);
|
||
$("#prev3").button({ icons: {primary:'ui-icon-arrowthick-1-w'} }).click(function() {
|
||
if (confirm("Leaving the result page will discard any modifications on current resource. Leave anyway?")) {
|
||
stepLeft("#validateResult", "#validate2");
|
||
clearEditTable();
|
||
}
|
||
});
|
||
$("#export").button({ icons: {primary:'ui-icon-arrowthick-1-e'} })
|
||
}
|
||
|