summaryrefslogtreecommitdiff
path: root/src/runtime
diff options
context:
space:
mode:
authorhallgren <hallgren@chalmers.se>2010-10-26 12:42:33 +0000
committerhallgren <hallgren@chalmers.se>2010-10-26 12:42:33 +0000
commit5fc0e059c5b35ad426f361f37f28036d01f5b412 (patch)
tree2afd76ff64ff1e39eae40e39cf7a2ab643cc2b89 /src/runtime
parent1e51a2e9e54898cb157139a508da851a9f6a137e (diff)
minibar: restructured code and improved user interface
* Keyboard input and completion should now work much more smoothly: + When you press space, the current word will be completed (if incomplete) and a new magnet will be created. If there is more than one possible completion, no magnet is created, but the common prefix of the possible completions is added to the text box. + Instead of asking the server for possible completions every time a new letter is added to the curent word, minibar only ask for completions for whole words and then filters the list locally when more letters are entered, speeding things up when server responses are slow. * Code restructuring: + The PGF server API has been moved to its own file: pgf_online.js. This allows it to be reused in other applicaitons without importing the entire minibar. It also allows minibar to be used with different server interfaces. + The minibar code has been rewritten to avoid storing state information in the document tree and accessing it by referring to named document elements. The code now also avoids using string literals contaning the names of top-level functions to specify event handlers for buttons and menus. (The code is no longer introspective, so alpha conversion will not change its meaning.)
Diffstat (limited to 'src/runtime')
-rw-r--r--src/runtime/javascript/minibar/minibar.html28
-rw-r--r--src/runtime/javascript/minibar/minibar.js760
-rw-r--r--src/runtime/javascript/minibar/pgf_online.js51
-rw-r--r--src/runtime/javascript/minibar/phrasebook.html45
4 files changed, 476 insertions, 408 deletions
diff --git a/src/runtime/javascript/minibar/minibar.html b/src/runtime/javascript/minibar/minibar.html
index dc53167dd..57ee54b38 100644
--- a/src/runtime/javascript/minibar/minibar.html
+++ b/src/runtime/javascript/minibar/minibar.html
@@ -4,6 +4,7 @@
<link rel=stylesheet type="text/css" href="minibar.css">
<script type="text/JavaScript" src="support.js"></script>
<script type="text/JavaScript" src="minibar.js"></script>
+<script type="text/JavaScript" src="pgf_online.js"></script>
<meta name = "viewport" content = "width = device-width">
<meta http-equiv="Content-type" content="text/html;charset=UTF-8">
@@ -12,8 +13,8 @@
</head>
<body>
-<h1>Minibar</h1>
-<div id=minibar>
+<h2>Minibar online</h2>
+<div id=minibar1>
</div>
<noscript>
This page doesn't works unless JavaScript is enabled.
@@ -26,26 +27,33 @@ This page doesn't works unless JavaScript is enabled.
&amp; <a href="http://www.grammaticalframework.org:41296/translate/">Translator</a>]
</small>
<small class=modtime>
-HTML <!-- hhmts start --> Last modified: Fri Sep 24 14:30:47 CEST 2010 <!-- hhmts end -->
+HTML <!-- hhmts start --> Last modified: Tue Oct 26 14:40:33 CEST 2010 <!-- hhmts end -->
</small>
<address>
<a href="http://www.cs.chalmers.se/~hallgren/">TH</a>
<img src="http://www.altocumulus.org/~hallgren/online.cgi?icon" alt=""></address>
-</body>
<script type="text/javascript">
-var my_options= {
- //server: "http://www.grammaticalframework.org:41296",
- //server: "http://tournesol.cs.chalmers.se:41296",
- server: "http://localhost:41296",
- //grammar_list: ["Foods.pgf"],
+var online_options={
+ grammars_url: "http://www.grammaticalframework.org/grammars/"
+//grammars_url: "http://tournesol.cs.chalmers.se:41296/grammars",
+//grammars_url: "http://localhost:41296/grammars",
+//grammar_list: ["Foods.pgf"], // leave undefined to get list from server
+}
+
+var server=pgf_online(online_options);
+
+var minibar_options= {
show_abstract: true,
show_trees: true,
show_grouped_translations: false,
default_source_language: "Eng",
try_google: true
}
-start_minibar(my_options)
+start_minibar(server,minibar_options,"minibar1");
+
</script>
+
+</body>
</html>
diff --git a/src/runtime/javascript/minibar/minibar.js b/src/runtime/javascript/minibar/minibar.js
index 8febfb6a8..b96d7c56b 100644
--- a/src/runtime/javascript/minibar/minibar.js
+++ b/src/runtime/javascript/minibar/minibar.js
@@ -1,414 +1,435 @@
// minibar.js, assumes that support.js has also been loaded
-/* --- Configuration -------------------------------------------------------- */
-
-
var default_server="http://www.grammaticalframework.org:41296"
var tree_icon=default_server+"/translate/se.chalmers.cs.gf.gwt.TranslateApp/tree-btn.png";
-// default values for options:
-var options={
- server: default_server,
- grammars_url: null, // if left null, start_minibar() fills in server+"/grammars/"
- grammar_list: null, // if left null, start_minibar() will fetch a list from the server
- show_abstract: false,
- show_trees: false,
- show_grouped_translations: true,
- delete_button_text: "⌫",
- default_source_language: null,
- try_google: true,
- feedback_url: null,
- random_button: true,
- help_url: null
-}
-
-/* --- Grammar access object ------------------------------------------------ */
-
-var server = {
- // State variables (private):
- current_grammar_url: options.grammars_url+"Foods.pgf",
- // Methods:
- switch_grammar: function(grammar_name) {
- this.current_grammar_url=options.grammars_url+grammar_name;
- },
- get_grammarlist: function(cont) {
- http_get_json(options.grammars_url+"grammars.cgi",cont);
- },
- pgf_call: function(cmd,args,cont) {
- var url=this.current_grammar_url+"?command="+cmd;
- for(var arg in args) url+="&"+arg+"="+encodeURIComponent(args[arg]);
- http_get_json(url,cont);
- },
-
- get_languages: function(cont) {
- this.pgf_call("grammar",{},cont);
- },
-
- get_random: function(cont) {
- this.pgf_call("random",{random:Math.random()},cont);
- },
- linearize: function(tree,to,cont) {
- this.pgf_call("linearize",{tree:tree,to:to},cont);
- },
- complete: function(from,input,cont) {
- this.pgf_call("complete",{from:from,input:input},cont);
- },
- parse: function(from,input,cont) {
- this.pgf_call("parse",{from:from,input:input},cont);
- },
- translate: function(from,input,cont) {
- this.pgf_call("translate",{from:from,input:input},cont);
- },
- translategroup: function(from,input,cont) {
- this.pgf_call("translategroup",{from:from,input:input},cont);
+function start_minibar(server,opts,target) {
+ // Typically called when the HTML document is loaded
+
+ /* --- Configuration ---------------------------------------------------- */
+
+ // default values for options:
+ var options={
+ show_abstract: false,
+ show_trees: false,
+ show_grouped_translations: true,
+ delete_button_text: "⌫",
+ default_source_language: null,
+ try_google: true,
+ feedback_url: null,
+ random_button: true,
+ help_url: null
}
-};
+ /* --- Creating user interface elements --------------------------------- */
-/* --- Initialisation ------------------------------------------------------- */
-
-function start_minibar(opts) {
- // Typically called when the HTML document is loaded
if(opts) for(var o in opts) options[o]=opts[o];
+
var surface=div_id("surface");
var extra=div_id("extra");
- //surface.setAttribute("onclick","add_typed_input(this)");
- var minibar=element("minibar");
- minibar.innerHTML="";
- appendChildren(minibar,
- [div_id("menubar"),
- surface,
- div_id("words"),
- div_id("translations"),
- extra]);
- append_extra_buttons(extra);
- if(!options.grammars_url) options.grammars_url=options.server+"/grammars/";
- if(options.grammar_list) show_grammarlist(options.grammar_list);
- else server.get_grammarlist(show_grammarlist);
-}
+ var menubar=div_id("menubar");
+ var words=div_id("words");
+ var translations=div_id("translations");
+ var minibar=element(target || "minibar");
+ minibar.innerHTML="";
+ appendChildren(minibar,[menubar,surface,words,translations,extra]);
+
+ // Added later:
+ var language_menu=empty_id("select","language_menu");
+ var to_menu=empty_id("select","to_menu");
+
+ /* --- Minibar client state initialisation ------------------------------ */
+ var current={from: null, input: ""};
+ var previous=null;
+
+ /* --- Auxiliary functions ---------------------------------------------- */
+
+ function show_grammarlist(grammars) {
+ //debug("show_grammarlist ")
+ menubar.innerHTML="";
+ if(grammars.length>1) {
+ var menu=empty("select");
+ for(var i=0;i<grammars.length;i++) {
+ var opt=empty("option");
+ opt.setAttribute("value",grammars[i]);
+ opt.innerHTML=grammars[i];
+ menu.appendChild(opt);
+ }
+ menu.onchange=function() {
+ select_grammar(menu.options[menu.selectedIndex].value);
+ };
+ menubar.innerHTML="Grammar: ";
+ menubar.appendChild(menu);
+ }
+ appendChildren(menubar,
+ [text(" From: "), language_menu,
+ text(" To: "), to_menu,
+ button(options.delete_button_text,delete_last,"H"),
+ button("Clear",clear_all,"L")]);
+ if(options.random_button)
+ menubar.appendChild(button("Random",generate_random,"R"));
+ if(options.help_url)
+ menubar.appendChild(button("Help",open_help));
+ select_grammar(grammars[0]);
+ }
-/* --- Functions ------------------------------------------------------------ */
+ function select_grammar(grammar_name) {
+ //debug("select_grammar ");
+ function get_languages() { server.get_languages(show_languages); }
+ server.switch_grammar(grammar_name,get_languages);
+ }
-function show_grammarlist(grammars) {
- var menubar=element("menubar");
- menubar.innerHTML="";
- if(grammars.length>1) {
- var menu=empty("select");
- for(var i=0;i<grammars.length;i++) {
- var opt=empty("option");
- opt.setAttribute("value",grammars[i]);
- opt.innerHTML=grammars[i];
- menu.appendChild(opt);
+ function show_languages(grammar) {
+ //debug("show_languages ");
+ var r="";
+ var lang=grammar.languages;
+ var menu=language_menu;
+ menu.grammar=grammar;
+ var new_language=function () {
+ var ix=menu.options[menu.selectedIndex].value;
+ var langname=grammar.languages[ix].name;
+ current.from=langname;
+ clear_all();
}
- menu.setAttribute("onchange","new_grammar(this)");
- menubar.innerHTML="Grammar: ";
- menubar.appendChild(menu);
+ menu.onchange=new_language;
+
+ menu.innerHTML="";
+
+ for(var i=0; i<lang.length; i++)
+ if(!hasPrefix(lang[i].name,"Disamb"))
+ menu.appendChild(option(langpart(lang[i].name,grammar.name),""+i));
+ set_initial_language(options,menu,grammar)
+ to_menu.onchange=get_translations
+
+ to_menu.innerHMTL="";
+ to_menu.appendChild(option("All","-1"));
+ for(var i=0; i<lang.length; i++)
+ if(!hasPrefix(lang[i].name,"Disamb"))
+ to_menu.appendChild(option(langpart(lang[i].name,grammar.name),lang[i].name));
+ new_language();
}
- appendChildren(menubar,
- [text(" From: "), empty_id("select","language_menu"),
- text(" To: "), empty_id("select","to_menu"),
- button(options.delete_button_text,"delete_last()","H"),
- button("Clear","clear_all()","L")]);
- if(options.random_button)
- menubar.appendChild(button("Random","generate_random()","R"));
- if(options.help_url)
- menubar.appendChild(button("Help","open_help()"));
- select_grammar(grammars[0]);
-}
-function new_grammar(menu) {
- select_grammar(menu.options[menu.selectedIndex].value);
-}
+ function clear_all1() {
+ remove_typed_input();
+ current.input="";
+ previous=null;
+ surface.innerHTML="";
+ translations.innerHTML="";
+ }
-function select_grammar(grammar_name) {
- server.switch_grammar(grammar_name);
- server.get_languages(show_languages);
-}
+ function clear_all() {
+ clear_all1();
+ get_completions();
+ }
-function langpart(conc,abs) { // langpart("FoodsEng","Food") == "Eng"
- return hasPrefix(conc,abs) ? conc.substr(abs.length) : conc;
-}
+ function get_completions() {
+ //debug("get_completions ");
+ words.innerHTML="...";
+ server.complete(current.from,current.input,show_completions);
+ }
-function show_languages(grammar) {
- var r="";
- var lang=grammar.languages;
- var menu=element("language_menu");
- menu.setAttribute("onchange","new_language(this)");
- menu.grammar=grammar;
- menu.innerHTML="";
-
- for(var i=0; i<lang.length; i++)
- if(/*lang[i].canParse &&*/ !hasPrefix(lang[i].name,"Disamb"))
- menu.appendChild(option(langpart(lang[i].name,grammar.name),""+i));
- if(grammar.userLanguage) {
- for(var i=0;i<menu.options.length;i++) {
- var ix=menu.options[i].value;
- var l=menu.grammar.languages[ix].name;
- if(l==grammar.userLanguage) menu.selectedIndex=i;
+ function show_completions(complete_output) {
+ //debug("show_completions ");
+ var completions=complete_output[0].completions;
+ var emptycnt=add_completions(completions)
+ if(true/*emptycnt>0*/) get_translations();
+ else translations.innerHTML="";
+ if(surface.typed && emptycnt==completions.length) {
+ if(surface.typed.value=="") remove_typed_input();
}
+ else add_typed_input();
}
- else if(options.default_source_language) {
- for(var i=0;i<menu.options.length;i++) {
- var ix=menu.options[i].value;
- var l=langpart(menu.grammar.languages[ix].name,menu.grammar.name);
- if(l==options.default_source_language) menu.selectedIndex=i;
+
+ function add_completions(completions) {
+ if(words.timeout) clearTimeout(words.timeout),words.timeout=null;
+ words.innerHTML="";
+ words.completions=completions;
+ words.word=[];
+ var t=surface.typed ? surface.typed.value : "";
+ var emptycnt=0;
+ for(var i=0;i<completions.length;i++) {
+ var s=completions[i];
+ if(s.length>0) {
+ var w=word(s);
+ words.appendChild(w);
+ words.word[i]=w;
+ }
+ else emptycnt++;
}
+ filter_completions(t,true);
+ return emptycnt;
}
- var to=element("to_menu");
- to.langmenu=menu;
- to.setAttribute("onchange","change_tolang(this)");
- to.innerHMTL="";
- to.appendChild(option("All","-1"));
- for(var i=0; i<lang.length; i++)
- if(!hasPrefix(lang[i].name,"Disamb"))
- to.appendChild(option(langpart(lang[i].name,grammar.name),lang[i].name));
- new_language(menu);
-}
-
-function new_language(menu) {
- var ix=menu.options[menu.selectedIndex].value;
- var langname=menu.grammar.languages[ix].name;
- menu.current={from: langname, input: ""};
- clear_all();
-}
-function change_tolang(to_menu) {
- get_translations(to_menu.langmenu)
-}
-
-function clear_all1() {
- var menu=element("language_menu");
- menu.current.input="";
- menu.previous=null;
- var surface=element("surface");
- surface.innerHTML="";
- surface.typed=null;
- element("translations").innerHTML="";
- return menu;
-}
-
-function clear_all() {
- get_completions(clear_all1());
-}
+ function filter_completions(t,dim) {
+ if(words.timeout) clearTimeout(words.timeout),words.timeout=null;
+ words.filtered=t;
+ //if(dim) debug('filter "'+t+'"');
+ var w=words.word;
+ words.count=0;
+ var dimmed=0;
+ var prefix=""; // longest common prefix, for completion
+ for(var i=0;i<w.length;i++) {
+ var s=words.completions[i];
+ var keep=hasPrefix(s,t);
+ if(keep) {
+ if(words.count==0) prefix=s;
+ else prefix=(commonPrefix(prefix,s));
+ words.count++;
+ }
+ if(dim) {
+ w[i].style.opacity= keep ? "1" : "0.5";
+ if(keep) w[i].style.display="inline";
+ else dimmed++;
+ }
+ else
+ w[i].style.display=keep ? "inline" : "none";
+ }
+ words.theword=prefix;
+ if(dimmed>0)
+ words.timeout=setTimeout(function(){ filter_completions(t,false)},1000);
+ }
+
+ function get_translations() {
+ var c=current;
+ if(options.show_grouped_translations)
+ server.translategroup(c.from,c.input,show_groupedtranslations);
+ else
+ server.translate(c.from,c.input,show_translations);
+ }
-function delete_last() {
- var menu=element("language_menu");
- if(menu.previous) {
- menu.current.input=menu.previous.input;
- menu.previous=menu.previous.previous;
- var s=element("surface");
- if(s.typed) {
- s.removeChild(s.typed.previousSibling);
- s.typed.focus();
+ function target_lang() {
+ return langpart(to_menu.options[to_menu.selectedIndex].value,
+ language_menu.grammar.name);
}
- else
- s.removeChild(s.lastChild);
- element("translations").innerHTML="";
- get_completions(menu);
- }
-}
-function add_typed_input(surface) {
- if(surface.typed)
- inp=surface.typed;
- else {
- var inp=empty("input","type","text");
- inp.setAttribute("accesskey","t");
- inp.setAttribute("onkeyup","complete_typed(this)");
- inp.setAttribute("onchange","finish_typed(this)");
- surface.appendChild(inp);
- surface.typed=inp;
+ function add_typed_input() {
+ var inp;
+ if(surface.typed) inp=surface.typed;
+ else {
+ inp=empty("input","type","text");
+ inp.value="";
+ inp.setAttribute("accesskey","t");
+ inp.style.width="10em";
+ inp.onkeyup=complete_typed;
+ surface.appendChild(inp);
+ surface.typed=inp;
+ }
+ inp.focus();
}
- inp.focus();
-}
-function remove_typed_input(surface) {
- if(surface.typed) {
- surface.typed.parentNode.removeChild(surface.typed);
- surface.typed=null;
+ function remove_typed_input() {
+ if(surface.typed) {
+ surface.typed.parentNode.removeChild(surface.typed);
+ surface.typed=null;
+ }
}
-}
-function complete_typed(inp) {
- var menu=element("language_menu");
- var c=menu.current;
- if(!inp.completing || inp.completing!=inp.value) {
- inp.completing=inp.value;
- server.complete(c.from,c.input+inp.value,show_completions);
+ function complete_typed(event) {
+ //element("debug").innerHTML=show_props(event,"event");
+ var inp=surface.typed;
+ //debug('"'+inp.value+'"');
+ var s=inp.value;
+ var ws=s.split(" ");
+ if(ws.length>1 || event.keyCode==13) {
+ if(ws[0]!=words.filtered) filter_completions(ws[0],true);
+ if(words.count==1) add_word(words.theword);
+ else if(elem(ws[0],words.completions)) add_word(ws[0]);
+ else if(words.theword.length>ws[0].length) inp.value=words.theword;
+ }
+ else if(s!=words.filtered) filter_completions(s,true)
}
-}
-function finish_typed(inp) {
- //alert("finish_typed "+inp.value);
- var box=element("words");
- var w=inp.value;
- var keep=w.substr(0,w.length-box.completed_text.length);
- if(box.completions.length==1)
- add_words(keep+box.completions[0]);
- else if(elem(w,box.completions))
- add_words(w);
-}
+ function generate_random() {
-function generate_random() {
- server.get_random(lin_random);
-}
+ function show_random(random) {
+ clear_all1();
+ var menu=language_menu;
+ add_words(random[0].text);
+ }
-function lin_random(abs) {
- var menu=element("language_menu");
- var lang=menu.current.from;
- server.linearize(abs[0].tree,lang,show_random);
-}
+ function lin_random(abs) {
+ server.linearize(abs[0].tree,current.from,show_random);
+ }
+ server.get_random(lin_random);
+ }
-function show_random(random) {
- var menu=clear_all1();
- var words=random[0].text.split(" ");
- for(var i=0;i<words.length;i++)
- add_word1(menu,words[i]+" ");
- element("words").innerHTML="...";
- get_completions(menu);
-}
+ function add_words(s) {
+ var words=s.split(" ");
+ for(var i=0;i<words.length;i++)
+ add_word1(words[i]+" ");
+ get_completions();
+ }
-function get_completions(menu) {
- var c=menu.current;
- server.complete(c.from,c.input,show_completions);
-}
+ function word(s) {
+ function click_word() {
+ if(surface.typed) surface.typed.value="";
+ add_word(s);
+ }
+ return button(s,click_word);
+ }
-function word(s) {
- return button(s,'add_word("'+s+'")');
-}
+ function add_word(s) {
+ add_word1(s+" ");
+ if(surface.typed) {
+ var s2;
+ if(hasPrefix(s2=surface.typed.value,s)) {
+ s2=s2.substr(s.length);
+ while(s2.length>0 && s2[0]==" ") s2=s2.substr(1);
+ surface.typed.value=s2;
+ }
+ else surface.typed.value="";
+ }
+ get_completions();
+ }
+
+ function add_word1(s) {
+ previous={ input: current.input, previous: previous };
+ current.input+=s;
+ var w=span_class("word",text(s));
+ if(surface.typed) surface.insertBefore(w,surface.typed);
+ else surface.appendChild(w);
+ }
-function add_word1(menu,s) {
- menu.previous={ input: menu.current.input, previous: menu.previous };
- menu.current.input+=s;
- var w=span_class("word",text(s));
- var surface=element("surface");
- if(surface.typed) {
- surface.typed.value="";
- surface.insertBefore(w,surface.typed);
+ function delete_last() {
+ if(surface.typed && surface.typed.value!="")
+ surface.typed.value="";
+ else if(previous) {
+ current.input=previous.input;
+ previous=previous.previous;
+ if(surface.typed) {
+ surface.removeChild(surface.typed.previousSibling);
+ surface.typed.focus();
+ }
+ else surface.removeChild(surface.lastChild);
+ translations.innerHTML="";
+ get_completions();
+ }
}
- else
- surface.appendChild(w);
-}
-function add_word(s) {
- var menu=element("language_menu");
- add_word1(menu,s+" ");
- element("words").innerHTML="...";
- get_completions(menu);
-}
+ function tdt(tree_btn,txt) {
+ return options.show_trees ? tda([tree_btn,txt]) : td(txt);
+ }
-function add_words(s) {
- var menu=element("language_menu");
- var words=s.split(" ");
- for(var i=0;i<words.length;i++)
- add_word1(menu,words[i]+" ");
- element("words").innerHTML="...";
- get_completions(menu);
-}
+ function show_translations(translationResults) {
+ var trans=translations;
+ var grammar=language_menu.grammar;
+ var to=target_lang();
+ var cnt=translationResults.length;
+ //trans.translations=translations;
+ trans.single_translation=[];
+ trans.innerHTML="";
+ /*
+ trans.appendChild(wrap("h3",text(cnt<1 ? "No translations?" :
+ cnt>1 ? ""+cnt+" translations:":
+ "One translation:")));
+ */
+ for(p=0;p<cnt;p++) {
+ var tra=translationResults[p];
+ if (tra.translations != null) {
+ for (q = 0; q < tra.translations.length; q++) {
+ var t = tra.translations[q];
+ var lin=t.linearizations;
+ var tbody=empty("tbody");
+ if(options.show_abstract && t.tree)
+ tbody.appendChild(tr([th(text("Abstract: ")),
+ tdt(abstree_button(t.tree),text(" "+t.tree))]));
+ for(var i=0;i<lin.length;i++)
+ if(to=="-1" || lin[i].to==to)
+ tbody.appendChild(tr([th(text(langpart(lin[i].to,grammar.name)+": ")),
+ tdt(parsetree_button(t.tree,lin[i].to),
+ text(lin[i].text))]));
+ trans.appendChild(wrap("table",tbody));
+ }
+ }
+ else if(tra.typeErrors) {
+ var errs=tra.typeErrors;
+ for(var i=0;i<errs.length;i++)
+ trans.appendChild(wrap("pre",text(errs[i].msg)))
+ }
+ }
+ }
+
+ function show_groupedtranslations(translationsResult) {
+ var trans=translations;
+ var grammar=language_menu.grammar;
+ var to=target_lang();
+ var cnt=translationsResult.length;
+ //trans.translations=translationsResult;
+ trans.single_translation=[];
+ trans.innerHTML="";
+ for(p=0;p<cnt;p++) {
+ var t=translationsResult[p];
+ if(to=="-1" || t.to==to) {
+ var lin=t.linearizations;
+ var tbody=empty("tbody");
+ if(to=="-1") tbody.appendChild(tr([th(text(t.to+":"))]));
+ for(var i=0;i<lin.length;i++) {
+ if(to!="-1") trans.single_translation[i]=lin[i].text;
+ tbody.appendChild(tr([td(text(lin[i].text))]));
+ if (lin.length > 1) tbody.appendChild(tr([td(text(lin[i].tree))]));
+ }
+ trans.appendChild(wrap("table",tbody));
+ }
+ }
+ }
-function show_completions(complete_output) {
- var box=element("words");
- var menu=element("language_menu");
- var prefixlen=menu.current.input.length;
- var emptycnt=0;
- var completions=complete_output[0].completions;
- box.innerHTML="";
- box.completions=completions;
- box.completed_text=complete_output[0].text;
- for(var i=0;i<completions.length;i++) {
- var s=completions[i];
- if(s.length>0) box.appendChild(word(s));
- else emptycnt++;
- }
- if(true/*emptycnt>0*/) get_translations(menu);
- else element("translations").innerHTML="";
- var surface=element("surface");
- if(surface.typed && emptycnt==completions.length) {
- if(surface.typed.value=="") remove_typed_input(surface);
- }
- else add_typed_input(surface);
-}
+ function append_extra_buttons(extra,options) {
+ if(options.try_google)
+ extra.appendChild(button("Try Google Translate",try_google));
+ if(options.feedback_url)
+ appendChildren(extra,[text(" "),button("Feedback",open_feedback)]);
+ }
-function get_translations(menu) {
- var c=menu.current;
- if(options.show_grouped_translations)
- server.translategroup(c.from,c.input,show_groupedtranslations);
- else
- server.translate(c.from,c.input,show_translations);
-}
+ function try_google() {
+ var to=target_lang();
+ var grammar=language_menu.grammar;
+ var s=current.input;
+ if(surface.typed) s+=surface.typed.value;
+ var url="http://translate.google.com/?sl="
+ +langpart(current.from,grammar.name);
+ if(to!="-1") url+="&tl="+to;
+ url+="&q="+encodeURIComponent(s);
+ window.open(url);
+ }
+
+ function open_help() { open_popup(options.help_url,"help"); }
+ function open_feedback() {
+ language_menu.current=current;
+ open_popup(options.feedback_url,'feedback');
+ }
+
+ /* --- Main program, this gets things going ----------------------------- */
+ append_extra_buttons(extra,options);
-function tdt(tree_btn,txt) {
- return options.show_trees ? tda([tree_btn,txt]) : td(txt);
+ if(server.grammar_list) show_grammarlist(server.grammar_list);
+ else server.get_grammarlist(show_grammarlist);
}
-function target_lang() {
- var to_menu=element("to_menu");
- var grammar=element("language_menu").grammar;
- return langpart(to_menu.options[to_menu.selectedIndex].value,grammar.name);
+function commonPrefix(s1,s2) {
+ for(var i=0;i<s1.length && i<s2.length && s1[i]==s2[i];i++);
+ return s1.substr(0,i);
}
-function show_translations(translationResults) {
- var trans=element("translations");
- var grammar=element("language_menu").grammar;
- var to=target_lang();
- var cnt=translationResults.length;
- //trans.translations=translations;
- trans.single_translation=[];
- trans.innerHTML="";
- /*
- trans.appendChild(wrap("h3",text(cnt<1 ? "No translations?" :
- cnt>1 ? ""+cnt+" translations:":
- "One translation:")));
- */
- for(p=0;p<cnt;p++) {
- var tra=translationResults[p];
- if (tra.translations != null) {
- for (q = 0; q < tra.translations.length; q++) {
- var t = tra.translations[q];
- var lin=t.linearizations;
- var tbody=empty("tbody");
- if(options.show_abstract && t.tree)
- tbody.appendChild(tr([th(text("Abstract: ")),
- tdt(abstree_button(t.tree),text(" "+t.tree))]));
- for(var i=0;i<lin.length;i++)
- if(to=="-1" || lin[i].to==to)
- tbody.appendChild(tr([th(text(langpart(lin[i].to,grammar.name)+": ")),
- tdt(parsetree_button(t.tree,lin[i].to),
- text(lin[i].text))]));
- trans.appendChild(wrap("table",tbody));
- }
+function set_initial_language(options,menu,grammar) {
+ if(grammar.userLanguage) {
+ for(var i=0;i<menu.options.length;i++) {
+ var ix=menu.options[i].value;
+ var l=grammar.languages[ix].name;
+ if(l==grammar.userLanguage) menu.selectedIndex=i;
}
- else if(tra.typeErrors) {
- var errs=tra.typeErrors;
- for(var i=0;i<errs.length;i++)
- trans.appendChild(wrap("pre",text(errs[i].msg)))
+ }
+ else if(options.default_source_language) {
+ for(var i=0;i<menu.options.length;i++) {
+ var ix=menu.options[i].value;
+ var l=langpart(grammar.languages[ix].name,grammar.name);
+ if(l==options.default_source_language) menu.selectedIndex=i;
}
}
}
-function show_groupedtranslations(translations) {
- var trans=element("translations");
- var grammar=element("language_menu").grammar;
- var to=target_lang();
- var cnt=translations.length;
- //trans.translations=translations;
- trans.single_translation=[];
- trans.innerHTML="";
- for(p=0;p<cnt;p++) {
- var t=translations[p];
- if(to=="-1" || t.to==to) {
- var lin=t.linearizations;
- var tbody=empty("tbody");
- if(to=="-1") tbody.appendChild(tr([th(text(t.to+":"))]));
- for(var i=0;i<lin.length;i++) {
- if(to!="-1") trans.single_translation[i]=lin[i].text;
- tbody.appendChild(tr([td(text(lin[i].text))]));
- if (lin.length > 1) tbody.appendChild(tr([td(text(lin[i].tree))]));
- }
- trans.appendChild(wrap("table",tbody));
- }
- }
+function langpart(conc,abs) { // langpart("FoodsEng","Food") == "Eng"
+ return hasPrefix(conc,abs) ? conc.substr(abs.length) : conc;
}
function abstree_button(abs) {
@@ -432,36 +453,11 @@ function toggle_img(i) {
i.other=tmp;
}
-function append_extra_buttons(extra) {
- if(options.try_google)
- extra.appendChild(button("Try Google Translate","try_google()"));
- if(options.feedback_url)
- appendChildren(extra,[text(" "),button("Feedback","open_feedback()")]);
-}
-
-function try_google() {
- var menu=element("language_menu");
- var trans=element("translations");
- var surface=element("surface");
- var to=target_lang();
- var grammar=menu.grammar;
- var c=menu.current;
- var s=c.input;
- if(surface.typed) s+=surface.typed.value;
- var url="http://translate.google.com/?sl="+langpart(c.from,grammar.name);
- if(to!="-1") url+="&tl="+to;
- url+="&q="+encodeURIComponent(s);
- window.open(url);
-}
-
function open_popup(url,target) {
var w=window.open(url,target,'toolbar=no,location=no,status=no,menubar=no');
w.focus();
}
-function open_help() { open_popup(options.help_url,"help"); }
-function open_feedback() { open_popup(options.feedback_url,'feedback'); }
-
function setField(form,name,value) {
form[name].value=value;
var el=element(name);
@@ -473,7 +469,7 @@ function opener_element(id) { with(window.opener) return element(id); }
function prefill_feedback_form() {
var to_menu=opener_element("to_menu");
var trans=opener_element("translations");
- var menu=to_menu.langmenu;
+ var menu=opener_element("language_menu")
var grammar=menu.grammar;
var gn=grammar.name;
var form=document.forms.namedItem("feedback");
diff --git a/src/runtime/javascript/minibar/pgf_online.js b/src/runtime/javascript/minibar/pgf_online.js
new file mode 100644
index 000000000..d100f8bf9
--- /dev/null
+++ b/src/runtime/javascript/minibar/pgf_online.js
@@ -0,0 +1,51 @@
+
+/* --- Grammar access object ------------------------------------------------ */
+
+function pgf_online(options) {
+ var server = {
+ // State variables (private):
+ grammars_url: "/grammars/",
+ grammar_list: null,
+ current_grammar_url: null,
+
+ // Methods:
+ switch_grammar: function(grammar_url,cont) {
+ this.current_grammar_url=this.grammars_url+grammar_url;
+ cont();
+ },
+ get_grammarlist: function(cont) {
+ http_get_json(this.grammars_url+"grammars.cgi",cont);
+ },
+ pgf_call: function(cmd,args,cont) {
+ var url=this.current_grammar_url+"?command="+cmd;
+ for(var arg in args) url+="&"+arg+"="+encodeURIComponent(args[arg]);
+ http_get_json(url,cont);
+ },
+
+ get_languages: function(cont) {
+ this.pgf_call("grammar",{},cont);
+ },
+
+ get_random: function(cont) {
+ this.pgf_call("random",{random:Math.random()},cont);
+ },
+ linearize: function(tree,to,cont) {
+ this.pgf_call("linearize",{tree:tree,to:to},cont);
+ },
+ complete: function(from,input,cont) {
+ this.pgf_call("complete",{from:from,input:input},cont);
+ },
+ parse: function(from,input,cont) {
+ this.pgf_call("parse",{from:from,input:input},cont);
+ },
+ translate: function(from,input,cont) {
+ this.pgf_call("translate",{from:from,input:input},cont);
+ },
+ translategroup: function(from,input,cont) {
+ this.pgf_call("translategroup",{from:from,input:input},cont);
+ }
+
+ };
+ for(var o in options) server[o]=options[o];
+ return server;
+} \ No newline at end of file
diff --git a/src/runtime/javascript/minibar/phrasebook.html b/src/runtime/javascript/minibar/phrasebook.html
index 73c0e849b..1bd45857d 100644
--- a/src/runtime/javascript/minibar/phrasebook.html
+++ b/src/runtime/javascript/minibar/phrasebook.html
@@ -1,25 +1,17 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
-<html> <head>
+<html>
+<head>
+<meta http-equiv="Content-type" content="text/html;charset=UTF-8">
+<meta charset="UTF-8">
<title>Phrasebook</title>
<link rel=stylesheet type="text/css" href="minibar.css">
<script type="text/JavaScript" src="support.js"></script>
+<script type="text/JavaScript" src="pgf_online.js"></script>
<script type="text/JavaScript" src="minibar.js"></script>
-<script type="text/JavaScript">
-var phrasebook_options={
-// server: "http://localhost:41296",
-// server: "http://tournesol.cs.chalmers.se:41296",
- server: "http://www.grammaticalframework.org:41296",
- grammar_list: ["Phrasebook.pgf"],
- delete_button_text: "Del",
- help_url: "http://www.grammaticalframework.org/examples/phrasebook/help-phrasebook.html",
- feedback_url: "feedback.html",
- default_source_language: "Eng"
-}
-</script>
<meta name = "viewport" content = "width = device-width">
-</head>
+</head>
-<body onload="start_minibar(phrasebook_options)">
+<body>
<div id=minibar></div>
@@ -27,11 +19,32 @@ var phrasebook_options={
<small>
-Powered by <a href="http://www.grammaticalframework.org">GF</a>,
+Powered by <a href="http://www.grammaticalframework.org/">GF</a>,
see <a href="http://www.grammaticalframework.org/examples/phrasebook/doc-phrasebook.html">doc</a>.
</small>
+<script type="text/JavaScript">
+
+var online_options={
+ grammars_url: "http://www.grammaticalframework.org/grammars/",
+//grammars_url: "http://tournesol.cs.chalmers.se:41296/grammars",
+//grammars_url: "http://localhost:41296/grammars",
+ grammar_list: ["Phrasebook.pgf"], // leave undefined to get list from server
+}
+
+var server=pgf_online(online_options);
+
+var phrasebook_options={
+ delete_button_text: "Del",
+ help_url: "http://www.grammaticalframework.org/examples/phrasebook/help-phrasebook.html",
+ feedback_url: "feedback.html",
+ default_source_language: "Eng"
+}
+
+start_minibar(server,phrasebook_options)
+</script>
+
</body>
</html>