return res;
}
-function compareAndorsTrailResourceRow(result, fieldList, id, obj1, obj2) {
+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];
- var fieldName = fieldList.getFieldName(i);
if (f instanceof FieldList) {
- fieldName = f._name;
- }
- var isTranslatableField = (fieldName == "name" || fieldName == "logText" || fieldName == "message" || fieldName == "text");
- var f1 = obj1[fieldName];
- var f2 = obj2[fieldName];
-
- if (f instanceof FieldList) {
- if (!f2) { f2 = []; }
- if (f1.length != f2.length) {
- pushMessage(result, "Row \"" + id + "\", field \"" + fieldName + "\" was expected to contain " + f1.length + " sub-entries, but only " + f2.length + " was found.");
- continue;
- }
- $.each(f1, function(i, obj) {
- var id_ = id + ":" + obj[f._fields[0]];
- compareAndorsTrailResourceRow(result, f, id_, f1[i], f2[i]);
+ // f is subfieldlist
+ $.each(obj[f._name], function(j, elem) {
+ extractTranslatableFields_(id, result, f, prefix+f._name+"["+j+"].", elem);
});
} else {
- if (isTranslatableField && f1.length > 1) {
- if (f1 == f2) {
- pushMessage(result, "Row \"" + id + "\", field \"" + fieldName + "\" does not seem to be translated. Both texts are \"" + f1 + "\".");
- }
- } else {
- if (f1 != f2) {
- pushMessage(result, "Row \"" + id + "\", field \"" + fieldName + "\" was expected to contain \"" + f1 + "\", but \"" + f2 + "\" was found.");
- }
+ // 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: [] };
+ 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);
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 found."); }
+ 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 class1 = text1 ? "ok" : "red";
var class2 = text2 ? "ok" : "red";
var tdTranslated = $("<td />");
- if (text1 && text2) {
- var resourceComparison = compareAndorsTrailResourceFormat(text1, text2);
- if (resourceComparison.isResource) {
- class1 = resourceComparison.class1;
- class2 = resourceComparison.class2;
- if (resourceComparison.messages.length > 0) {
- var errorList = $("<ul />").attr("id", "validationWarnings");
- $.each(resourceComparison.messages, function(i, msg) {
- errorList.append($("<li />").text(msg));
- });
- var d = $("<span />").attr("id", "showValidationWarnings").text("Expand");
- d.click(function() {
- d.hide();
- errorList.show();
- });
- tdTranslated.append(d);
- tdTranslated.append(errorList);
- errorList.hide();
+ 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);
}
}
$("<tr />")
.attr("id", name)
.append($("<td />").text(name))
- .append($("<td />").attr("class", class1))
.append(tdTranslated.attr("class", class2))
);
}
function validateTranslation_(englishData) {
$("#englishData").text(englishData);
- var compareData1 = $( englishData );
- var compareData2 = $( $("#compareToInput").val() );
+ var compareData1 = $( $.parseXML(englishData) );
+ var compareData2 = $( $.parseXML($("#compareToInput").val()) );
- var resultTable = $("#validateResultContent table");
+ var resultTable = $("#validateResultContent #result");
var outputTable = $("tbody", resultTable );
outputTable.empty();
var sectionCount = $("tr", outputTable).size();
var errors1 = sectionCount - $("td:nth-child(2).ok", outputTable).size();
- var errors2 = sectionCount - $("td:nth-child(3).ok", outputTable).size();;
- $("th #count1", resultTable).text( (errors1 > 0) ? " (" + errors1 + ")" : "" );
- $("th #count2", resultTable).text( (errors2 > 0) ? " (" + errors2 + ")" : "" );
+ $("th #count2", resultTable).text( (errors1 > 0) ? " (" + errors1 + ")" : "" );
+
+ $("#export").click(exportHandler(compareData2));
$("#validateResultContent #loading").hide();
$("#validateResultContent #result").show();
}
}
-
function loadStep3() {
var compareToContent = $("#compareToInput").val();
if (compareToContent.length <= 0) {
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() { stepLeft("#validateResult", "#validate2"); });
+ $("#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'} })
}
+