mirror of
https://github.com/GrammaticalFramework/gf-core.git
synced 2026-04-12 06:19:33 -06:00
pgf_online.js has been simplified and generalized to support the full GF Web Service API. The changes are backwards incompatible, unfortunately. The documentation and minibar.js have been updated accordingly.
589 lines
16 KiB
JavaScript
589 lines
16 KiB
JavaScript
// minibar.js, assumes that support.js has also been loaded
|
||
|
||
var tree_icon="tree-btn.png";
|
||
var alignment_icon="align-btn.png";
|
||
|
||
/*
|
||
// This is essentially what happens when you call start_minibar:
|
||
if(server.grammar_list) grammars=server.grammar_list;
|
||
else grammars=server.get_grammarlist();
|
||
show_grammarlist(grammars)
|
||
select_grammar(grammars[0])
|
||
grammar_info=server.get_languages()
|
||
show_languages(grammar_info)
|
||
new_language()
|
||
complete_output=get_completions()
|
||
show_completions(complete_output)
|
||
*/
|
||
|
||
// For backward compatibility:
|
||
function start_minibar(server,opts,target) {
|
||
return new Minibar(server,opts,target);
|
||
}
|
||
|
||
function Minibar(server,opts,target) {
|
||
// Typically called when the HTML document is loaded
|
||
|
||
/* --- Configuration ---------------------------------------------------- */
|
||
|
||
// default values for options:
|
||
this.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
|
||
}
|
||
|
||
// Apply supplied options
|
||
if(opts) for(var o in opts) this.options[o]=opts[o];
|
||
|
||
/* --- Creating user interface elements --------------------------------- */
|
||
|
||
this.surface=div_id("surface");
|
||
this.extra=div_id("extra");
|
||
this.menubar=div_id("menubar");
|
||
this.words=div_id("words");
|
||
this.translations=div_id("translations");
|
||
|
||
this.minibar=element(target || "minibar");
|
||
this.minibar.innerHTML="";
|
||
with(this) {
|
||
appendChildren(minibar,[menubar,surface,words,translations,extra]);
|
||
append_extra_buttons(extra,options);
|
||
}
|
||
|
||
// Filled in and added to minibar later:
|
||
this.grammar_menu=empty_id("select","grammar_menu");
|
||
this.from_menu=empty_id("select","from_menu");
|
||
this.to_menu=empty_id("select","to_menu");
|
||
|
||
/* --- Minibar client state initialisation ------------------------------ */
|
||
this.grammar=null;
|
||
this.current={from: null, input: ""};
|
||
this.previous=null;
|
||
|
||
this.server=server;
|
||
|
||
/* --- Main program, this gets things going ----------------------------- */
|
||
with(this) {
|
||
if(server.grammar_list) show_grammarlist(server.grammar_list);
|
||
else server.get_grammarlist(bind(show_grammarlist,this));
|
||
}
|
||
}
|
||
|
||
/* --- Auxiliary functions ---------------------------------------------- */
|
||
|
||
Minibar.prototype.show_grammarlist=function(grammars) {
|
||
debug(this)
|
||
with(this) {
|
||
//debug("show_grammarlist ")
|
||
menubar.innerHTML="";
|
||
if(grammars.length>1) {
|
||
function opt(g) { return option(g,g); }
|
||
appendChildren(grammar_menu,map(opt,grammars));
|
||
grammar_menu.onchange=
|
||
bind(function() { select_grammar(grammar_menu.value); },this);
|
||
appendChildren(menubar,[text("Grammar: "),grammar_menu]);
|
||
}
|
||
appendChildren(menubar,
|
||
[text(" From: "), from_menu,
|
||
text(" To: "), to_menu,
|
||
button(options.delete_button_text,bind(delete_last,this),"H"),
|
||
button("Clear",bind(clear_all,this),"L")]);
|
||
if(options.random_button)
|
||
menubar.appendChild(button("Random",bind(generate_random,this),"R"));
|
||
if(options.help_url)
|
||
menubar.appendChild(button("Help",bind(open_help,this)));
|
||
select_grammar(grammars[0]);
|
||
}
|
||
}
|
||
|
||
Minibar.prototype.select_grammar=function(grammar_name) {
|
||
var t=this;
|
||
//debug("select_grammar ");
|
||
function get_languages() {
|
||
t.server.get_languages(bind(t.show_languages,t));
|
||
}
|
||
t.server.switch_grammar(grammar_name,get_languages);
|
||
}
|
||
|
||
Minibar.prototype.show_languages=function(grammar_info) {
|
||
var t=this;
|
||
with(t) {
|
||
//debug("show_languages ");
|
||
grammar=grammar_info;
|
||
|
||
var new_language=function () {
|
||
current.from=from_menu.value;
|
||
clear_all();
|
||
}
|
||
from_menu.onchange=bind(new_language,t);
|
||
update_language_menu(from_menu,grammar);
|
||
set_initial_language(options,from_menu,grammar);
|
||
|
||
to_menu.onchange=bind(get_translations,t);
|
||
|
||
update_language_menu(to_menu,grammar);
|
||
insertFirst(to_menu,option("All","All"));
|
||
to_menu.value="All";
|
||
|
||
new_language();
|
||
}
|
||
}
|
||
|
||
Minibar.prototype.clear_all1=function() {
|
||
with(this) {
|
||
remove_typed_input();
|
||
current.input="";
|
||
previous=null;
|
||
surface.innerHTML="";
|
||
translations.innerHTML="";
|
||
}
|
||
}
|
||
|
||
Minibar.prototype.clear_all=function() {
|
||
with(this) {
|
||
clear_all1();
|
||
get_completions();
|
||
}
|
||
}
|
||
|
||
Minibar.prototype.get_completions=function() {
|
||
with(this) {
|
||
//debug("get_completions ");
|
||
words.innerHTML="...";
|
||
server.complete({from:current.from,input:current.input},
|
||
bind(show_completions,this));
|
||
}
|
||
}
|
||
|
||
Minibar.prototype.show_completions=function(complete_output) {
|
||
with(this) {
|
||
//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();
|
||
}
|
||
}
|
||
|
||
Minibar.prototype.add_completions=function(completions) {
|
||
with(this) {
|
||
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;
|
||
}
|
||
}
|
||
|
||
Minibar.prototype.filter_completions=function(t,dim) {
|
||
with(this) {
|
||
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);
|
||
}
|
||
}
|
||
|
||
Minibar.prototype.get_translations=function() {
|
||
with(this) {
|
||
var c=current;
|
||
if(options.show_grouped_translations)
|
||
server.translategroup({from:c.from,input:c.input},
|
||
bind(show_groupedtranslations,this));
|
||
else
|
||
server.translate({from:c.from,input:c.input},
|
||
bind(show_translations,this));
|
||
}
|
||
}
|
||
|
||
Minibar.prototype.target_lang=function() {
|
||
with(this) return langpart(to_menu.value,grammar.name);
|
||
}
|
||
|
||
Minibar.prototype.add_typed_input=function() {
|
||
with(this) {
|
||
if(!surface.typed) {
|
||
var inp=empty("input","type","text");
|
||
inp.value="";
|
||
inp.setAttribute("accesskey","t");
|
||
inp.style.width="10em";
|
||
inp.onkeyup=bind(complete_typed,this);
|
||
surface.appendChild(inp);
|
||
surface.typed=inp;
|
||
inp.focus();
|
||
}
|
||
}
|
||
}
|
||
|
||
Minibar.prototype.remove_typed_input=function() {
|
||
with(this) {
|
||
if(surface.typed) {
|
||
surface.typed.parentNode.removeChild(surface.typed);
|
||
surface.typed=null;
|
||
}
|
||
}
|
||
}
|
||
|
||
Minibar.prototype.complete_typed=function(event) {
|
||
with(this) {
|
||
//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)
|
||
}
|
||
}
|
||
|
||
Minibar.prototype.generate_random=function() {
|
||
var t=this;
|
||
function show_random(random) {
|
||
t.clear_all1();
|
||
t.add_words(random[0].text);
|
||
}
|
||
|
||
function lin_random(abs) {
|
||
t.server.linearize({tree:abs[0].tree,to:t.current.from},show_random);
|
||
}
|
||
t.server.get_random({},lin_random);
|
||
}
|
||
|
||
Minibar.prototype.add_words=function(s) {
|
||
with(this) {
|
||
var ws=s.split(" ");
|
||
for(var i=0;i<ws.length;i++)
|
||
add_word1(ws[i]+" ");
|
||
get_completions();
|
||
}
|
||
}
|
||
|
||
Minibar.prototype.word=function(s) {
|
||
var t=this;
|
||
function click_word() {
|
||
if(t.surface.typed) t.surface.typed.value="";
|
||
t.add_word(s);
|
||
}
|
||
return button(s,click_word);
|
||
}
|
||
|
||
Minibar.prototype.add_word=function(s) {
|
||
with(this) {
|
||
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();
|
||
}
|
||
}
|
||
|
||
Minibar.prototype.add_word1=function(s) {
|
||
with(this) {
|
||
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);
|
||
}
|
||
}
|
||
|
||
Minibar.prototype.delete_last=function() {
|
||
with(this) {
|
||
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();
|
||
}
|
||
}
|
||
}
|
||
|
||
Minibar.prototype.tdt=function(tree_btn,txt) {
|
||
with(this) {
|
||
return options.show_trees ? tda([tree_btn,txt]) : td(txt);
|
||
}
|
||
}
|
||
|
||
Minibar.prototype.show_translations=function(translationResults) {
|
||
with(this) {
|
||
var trans=translations;
|
||
//var to=target_lang(); // wrong
|
||
var to=to_menu.value;
|
||
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(node("span",{},[abstree_button(t.tree),
|
||
alignment_button(t.tree)]),
|
||
text(" "+t.tree))]));
|
||
for(var i=0;i<lin.length;i++) {
|
||
if(lin[i].to==to)
|
||
trans.single_translation.push(lin[i].text);
|
||
if(to=="All" || 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)))
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
Minibar.prototype.show_groupedtranslations=function(translationsResult) {
|
||
with(this) {
|
||
var trans=translations;
|
||
var to=target_lang();
|
||
//var to=to_menu.value // wrong
|
||
var cnt=translationsResult.length;
|
||
//trans.translations=translationsResult;
|
||
trans.single_translation=[];
|
||
trans.innerHTML="";
|
||
for(p=0;p<cnt;p++) {
|
||
var t=translationsResult[p];
|
||
if(to=="All" || t.to==to) {
|
||
var lin=t.linearizations;
|
||
var tbody=empty("tbody");
|
||
if(to=="All") tbody.appendChild(tr([th(text(t.to+":"))]));
|
||
for(var i=0;i<lin.length;i++) {
|
||
if(to!="All") 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));
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
Minibar.prototype.append_extra_buttons=function(extra,options) {
|
||
with(this) {
|
||
if(options.try_google)
|
||
extra.appendChild(button("Try Google Translate",bind(try_google,this)));
|
||
if(options.feedback_url)
|
||
appendChildren(extra,[text(" "),button("Feedback",bind(open_feedback,this))]);
|
||
}
|
||
}
|
||
|
||
Minibar.prototype.try_google=function() {
|
||
with(this) {
|
||
var to=target_lang();
|
||
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!="All") url+="&tl="+to;
|
||
url+="&q="+encodeURIComponent(s);
|
||
window.open(url);
|
||
}
|
||
}
|
||
|
||
Minibar.prototype.open_help=function() {
|
||
with(this) open_popup(options.help_url,"help");
|
||
}
|
||
|
||
Minibar.prototype.open_feedback=function() {
|
||
with(this) {
|
||
// make the minibar state easily accessible from the feedback page:
|
||
minibar.state={grammar:grammar,current:current,to:to_menu.value,
|
||
translations:translations};
|
||
open_popup(options.feedback_url,'feedback');
|
||
}
|
||
}
|
||
|
||
function update_language_menu(menu,grammar) {
|
||
// Replace the options in the menu with the languages in the grammar
|
||
var lang=grammar.languages;
|
||
menu.innerHTML="";
|
||
|
||
for(var i=0; i<lang.length; i++) {
|
||
var ln=lang[i].name;
|
||
if(!hasPrefix(ln,"Disamb")) {
|
||
var lp=langpart(ln,grammar.name);
|
||
menu.appendChild(option(lp,ln));
|
||
}
|
||
}
|
||
}
|
||
|
||
function set_initial_language(options,menu,grammar) {
|
||
if(grammar.userLanguage) menu.value=grammar.userLanguage;
|
||
else if(options.default_source_language) {
|
||
for(var i=0;i<menu.options.length;i++) {
|
||
var o=menu.options[i].value;
|
||
var l=langpart(o,grammar.name);
|
||
if(l==options.default_source_language) menu.value=o;
|
||
}
|
||
}
|
||
}
|
||
|
||
function langpart(conc,abs) { // langpart("FoodsEng","Foods") == "Eng"
|
||
return hasPrefix(conc,abs) ? conc.substr(abs.length) : conc;
|
||
}
|
||
|
||
function button_img(url,action) {
|
||
var i=img(url);
|
||
i.setAttribute("class","button");
|
||
i.setAttribute("onclick",action);
|
||
return i;
|
||
}
|
||
|
||
function abstree_button(abs) {
|
||
var i=button_img(tree_icon,"toggle_img(this)");
|
||
i.title="Click to display abstract syntax tree"
|
||
i.other=server.current_grammar_url+"?command=abstrtree&tree="+encodeURIComponent(abs);
|
||
return i;
|
||
}
|
||
|
||
function alignment_button(abs) {
|
||
var i=button_img(alignment_icon,"toggle_img(this)");
|
||
i.title="Click to display word alignment"
|
||
i.other=server.current_grammar_url+"?command=alignment&tree="+encodeURIComponent(abs);
|
||
return i;
|
||
}
|
||
|
||
function parsetree_button(abs,lang) {
|
||
var i=button_img(tree_icon,"toggle_img(this)");
|
||
i.title="Click to display parse tree"
|
||
i.other=server.current_grammar_url
|
||
+"?command=parsetree&from="+lang+"&tree="+encodeURIComponent(abs);
|
||
return i;
|
||
}
|
||
|
||
function toggle_img(i) {
|
||
var tmp=i.src;
|
||
i.src=i.other;
|
||
i.other=tmp;
|
||
}
|
||
|
||
function open_popup(url,target) {
|
||
var w=window.open(url,target,'toolbar=no,location=no,status=no,menubar=no');
|
||
w.focus();
|
||
}
|
||
|
||
function setField(form,name,value) {
|
||
form[name].value=value;
|
||
var el=element(name);
|
||
if(el) el.innerHTML=value;
|
||
}
|
||
|
||
function opener_element(id) { with(window.opener) return element(id); }
|
||
|
||
// This function is called from feedback.html
|
||
function prefill_feedback_form() {
|
||
var state=opener_element("minibar").state;
|
||
var trans=state.translations;
|
||
var gn=state.grammar.name
|
||
var to=langpart(state.to,gn);
|
||
|
||
var form=document.forms.namedItem("feedback");
|
||
setField(form,"grammar",gn);
|
||
setField(form,"from",langpart(state.current.from,gn));
|
||
setField(form,"input",state.current.input);
|
||
setField(form,"to",to);
|
||
if(to=="All") element("translation_box").style.display="none";
|
||
else setField(form,"translation",trans.single_translation.join(" / "));
|
||
|
||
// Browser info:
|
||
form["inner_size"].value=window.innerWidth+"×"+window.innerHeight;
|
||
form["outer_size"].value=window.outerWidth+"×"+window.outerHeight;
|
||
form["screen_size"].value=screen.width+"×"+screen.height;
|
||
form["available_screen_size"].value=screen.availWidth+"×"+screen.availHeight;
|
||
form["color_depth"].value=screen.colorDepth;
|
||
form["pixel_depth"].value=screen.pixelDepth;
|
||
|
||
window.focus();
|
||
}
|
||
|
||
|
||
/*
|
||
se.chalmers.cs.gf.gwt.TranslateApp/align-btn.png
|
||
|
||
GET /grammars/Foods.pgf?&command=abstrtree&tree=Pred+(This+Fish)+(Very+Fresh)
|
||
GET /grammars/Foods.pgf?&command=parsetree&tree=Pred+(This+Fish)+Expensive&from=FoodsAfr
|
||
GET /grammars/Foods.pgf?&command=alignment&tree=Pred+(This+Fish)+Expensive
|
||
*/
|