diff --git a/src/server/MainFastCGI.hs b/src/server/MainFastCGI.hs
index e275d6e7e..a0ce72f9d 100644
--- a/src/server/MainFastCGI.hs
+++ b/src/server/MainFastCGI.hs
@@ -42,8 +42,8 @@ cgiMain pgf =
mfrom <- getLang pgf "from"
mto <- getLang pgf "to"
outputJSON $ translate pgf input mcat mfrom mto
- "/cats" -> outputJSON $ categories pgf
- "/langs" -> outputJSON $ languages pgf
+ "/categories" -> outputJSON $ categories pgf
+ "/languages" -> outputJSON $ languages pgf
_ -> outputNotFound path
getCat :: PGF -> String -> CGI (Maybe Category)
diff --git a/src/server/gf-client.html b/src/server/gf-client.html
index 6a4627981..68131a44f 100644
--- a/src/server/gf-client.html
+++ b/src/server/gf-client.html
@@ -4,9 +4,36 @@
+
+
Web-based GF Translator
-
+
diff --git a/src/server/gf-server-jsapi.js b/src/server/gf-server-jsapi.js
index f9db41ef2..9a2096532 100644
--- a/src/server/gf-server-jsapi.js
+++ b/src/server/gf-server-jsapi.js
@@ -1,8 +1,14 @@
-function translate (input,from,to,cat) {
- httpGetText("gf.fcgi/translate?input="+escape(input)+"&from="+escape(from)+"&to="+escape(to)+"&cat="+escape(cat), function (output) { alert(output); });
-}
+var gf = new Object();
-function httpGetText(url, callback) {
+gf.translate = function (input,from,to,cat,callback) {
+ gf.httpGetText("gf.fcgi/translate?input="+escape(input)+"&from="+escape(from)+"&to="+escape(to)+"&cat="+escape(cat), function (output) { callback(gf.readJSON(output)); });
+};
+
+gf.getLanguages = function (callback) {
+ gf.httpGetText("gf.fcgi/languages", function (output) { callback(gf.readJSON(output)); });
+};
+
+gf.httpGetText = function (url, callback) {
var XMLHttpRequestObject = false;
if (window.XMLHttpRequest) {
@@ -25,5 +31,8 @@ function httpGetText(url, callback) {
XMLHttpRequestObject.send(null);
}
+};
-}
+gf.readJSON = function (text) {
+ return eval("("+text+")");
+};
diff --git a/src/server/translator.js b/src/server/translator.js
new file mode 100644
index 000000000..99bd8b191
--- /dev/null
+++ b/src/server/translator.js
@@ -0,0 +1,49 @@
+function formatTranslation (outputs) {
+ var dl1 = document.createElement("dl");
+ for (var fromLang in outputs) {
+ var ul = document.createElement("ul");
+ addDefinition(dl1, document.createTextNode(fromLang), ul);
+ for (var i in outputs[fromLang]) {
+ var dl2 = document.createElement("dl");
+ for (var toLang in outputs[fromLang][i]) {
+ addDefinition(dl2, document.createTextNode(toLang), document.createTextNode(outputs[fromLang][i][toLang]));
+ }
+ addItem(ul, dl2);
+ }
+ }
+
+ return dl1;
+}
+
+/* DOM utilities for specific tags */
+
+function addDefinition (dl, t, d) {
+ var dt = document.createElement("dt");
+ dt.appendChild(t);
+ dl.appendChild(dt);
+ var dd = document.createElement("dd");
+ dd.appendChild(d);
+ dl.appendChild(dd);
+}
+
+function addItem (ul, i) {
+ var li = document.createElement("ul");
+ li.appendChild(i);
+ ul.appendChild(li);
+}
+
+function addOption (select, value, content) {
+ var option = document.createElement("option");
+ option.value = value;
+ option.appendChild(document.createTextNode(content));
+ select.appendChild(option);
+}
+
+/* General DOM utilities */
+
+/* Removes all the children of a node */
+function removeChildren(node) {
+ while (node.hasChildNodes()) {
+ node.removeChild(node.firstChild);
+ }
+}