1
0
forked from GitHub/gf-core

Wide Coverage Demo web app: more client side caching

For example, you can now reorder paragraphs by cut & paste, without causing
anything to be sent to the server for re-translation.

Also some color & layout tweaks.
This commit is contained in:
hallgren
2014-04-17 13:48:00 +00:00
parent 0c04bdb4b9
commit 3fd6dc90f9
2 changed files with 63 additions and 73 deletions

View File

@@ -4,8 +4,8 @@ wc.f=document.forms[0]
wc.o=element("output") wc.o=element("output")
wc.e=element("extra") wc.e=element("extra")
wc.p=element("pick") wc.p=element("pick")
wc.serial=0
wc.os=[] // output segment list wc.os=[] // output segment list
wc.cache={} // output segment cache, indexed by source text
wc.local=appLocalStorage("gf.wc.") wc.local=appLocalStorage("gf.wc.")
wc.delayed_translate=function() { wc.delayed_translate=function() {
@@ -43,9 +43,7 @@ wc.load=function() {
} }
wc.translate=function() { wc.translate=function() {
var current= ++wc.serial
var f=wc.f, e=wc.e, p=wc.p var f=wc.f, e=wc.e, p=wc.p
var selected= -1
/* /*
function disable(yes) { function disable(yes) {
@@ -59,18 +57,16 @@ wc.translate=function() {
return s.split(/([.!?]+[ \t\n]+|\n\n+|[ \t\n]*[-•*+#]+[ \t\n]+)/) return s.split(/([.!?]+[ \t\n]+|\n\n+|[ \t\n]*[-•*+#]+[ \t\n]+)/)
} }
function translate_segment(si) { // si = segment index function translate_segment(so) { // so = segment output
var rs=[] // list of alternative translations for this segment var rs=[] // list of alternative translations for this segment
var current_pick=0 // index of currently selected alternative var current_pick=0 // index of currently selected alternative
var get_more // if defined, a function that will fetch more alternatives
var output=wc.os[si].target // the element where this segment is shown
function show_error(msg) { function show_error(msg) {
//if(e) e.innerHTML="<span class=low_quality>Translation problem: "+msg+"</span>" //if(e) e.innerHTML="<span class=low_quality>Translation problem: "+msg+"</span>"
//else //else
{ {
replaceChildren(output,text("["+msg+"]")) replaceChildren(so.target,text("["+msg+"]"))
output.className="error" so.target.className="error"
} }
//disable(false) //disable(false)
} }
@@ -95,32 +91,27 @@ wc.translate=function() {
*/ */
} }
function show_more() { function show_more() {
selected=si wc.selected=so
var r=rs[current_pick] var r=rs[current_pick]
if(e) e.innerHTML=(r.prob||"")+"<br>"+(r.tree||"") if(e) e.innerHTML=(r.prob||"")+"<br>"+(r.tree||"")
if(wc.p /*&& rs.length>1*/) show_picks() if(wc.p /*&& rs.length>1*/) show_picks()
//if(f.speak.checked) wc.speak(t.text,f.to.value) //if(f.speak.checked) wc.speak(t.text,f.to.value)
if(get_more) {
var f=get_more
get_more=null
f()
}
} }
output.onclick=show_more so.target.onclick=show_more
function show_trans(i) { function show_trans(i) {
var r=rs[i] var r=rs[i]
replaceChildren(output,text(r.text)) replaceChildren(so.target,text(r.text))
wc.os[si].text=r.text so.text=r.text
output.className=r.t.quality so.target.className=r.t.quality
current_pick=i current_pick=i
if(selected==si) show_more() if(wc.selected==so) show_more()
} }
function showit2(r) { function showit2(r) {
rs.push(r) rs.push(r)
var j=rs.length-1 var j=rs.length-1
if(current_pick==j) show_trans(j) if(current_pick==j) show_trans(j)
else if(selected==si) show_picks() else if(wc.selected==so) show_picks()
//disable(false) //disable(false)
} }
function showit(r) { function showit(r) {
@@ -136,52 +127,42 @@ wc.translate=function() {
function word_for_word(text,cont) { function word_for_word(text,cont) {
function step3(tra) { function step3(tra) {
if(wc.serial==current) { if(tra.length>=1) {
if(tra.length>=1) { var r=tra[0]
var r=tra[0] if(r.error!=undefined) {
if(r.error!=undefined) { if(i==0 && rs.length==0) show_error(tra[0].error)
if(i==0 && rs.length==0) show_error(tra[0].error) }
} else {
else { var r=tra[0]
var r=tra[0] if(r.linearizations) show_words(r)
if(r.linearizations) show_words(r)
}
} }
else if(i==0 && rs.length==0)
show_error("Unable to translate")
} }
else if(i==0 && rs.length==0)
show_error("Unable to translate")
} }
gftranslate.wordforword(text,f.from.value,f.to.value,step3) gftranslate.wordforword(text,f.from.value,f.to.value,step3)
} }
function trans(text,i,count) { function trans(text,i,count) {
function step3(tra) { function step3(tra) {
if(wc.serial==current) { if(tra.length>=1) {
if(tra.length>=1) { var r=tra[0]
var r=tra[0] if(r.error!=undefined) {
if(r.error!=undefined) { if(i==0 && rs.length==0) {
if(i==0 && rs.length==0) { //show_error(tra[0].error)
//show_error(tra[0].error) word_for_word(text)
word_for_word(text) }
} }
} else {
else { for(var ti=0;ti<tra.length;ti++) {
for(var ti=0;ti<tra.length;ti++) { var r=tra[ti]
var r=tra[ti] if(r.linearizations) showit(r)
if(r.linearizations) showit(r) //else show_error("no linearizations")
//else show_error("no linearizations")
}
/*
if(wc.p && i==0 && count==1) {
if(si==selected) trans(text,1,9)
else get_more=function() { trans(text,1,9) }
}
*/
} }
} }
else if(i==0 && rs.length==0)
show_error("Unable to translate")
} }
else if(i==0 && rs.length==0)
show_error("Unable to translate")
} }
gftranslate.translate(text,f.from.value,f.to.value,i,count,step3) gftranslate.translate(text,f.from.value,f.to.value,i,count,step3)
} }
@@ -202,8 +183,8 @@ wc.translate=function() {
step3cnl, step3cnl,
function(){step2(text)}) function(){step2(text)})
} }
if(wc.cnl) step2cnl(is[si]) if(wc.cnl) step2cnl(so.input)
else step2(is[si]) else step2(so.input)
} }
//disable(true) //disable(true)
@@ -212,7 +193,9 @@ wc.translate=function() {
clear(p) clear(p)
var old={} var old=wc.cache
var old_selected=wc.selected
wc.selected=null
for(var i=0;i<wc.os.length;i++) old[wc.os[i].input]=wc.os[i] for(var i=0;i<wc.os.length;i++) old[wc.os[i].input]=wc.os[i]
// could also keep all copies if the same text occurs more than once... // could also keep all copies if the same text occurs more than once...
wc.os=[] wc.os=[]
@@ -222,21 +205,25 @@ wc.translate=function() {
for(var i=0;i<is.length;i++) { for(var i=0;i<is.length;i++) {
var same=old[is[i]] var same=old[is[i]]
if(same && same.to==f.to.value) { // reuse unchanged segment? if(same && same.to==f.to.value && same.from==f.from.value) {
// reuse an unchanged segment
wc.os[i]=same wc.os[i]=same
wc.o.appendChild(same.target) wc.o.appendChild(same.target)
if(same==old_selected) wc.selected=same
delete old[is[i]] // can't use the same node twice delete old[is[i]] // can't use the same node twice
} }
else { else {
wc.os[i]={input:is[i],text:is[i],to:f.to.value} // create a new output segment
var o=wc.os[i]={input:is[i],text:is[i],
from:f.from.value,to:f.to.value}
if(i&1) { // punctuation if(i&1) { // punctuation
var o=wc.os[i].target=span_class("punct",text(is[i])) o.target=span_class("punct",text(is[i]))
wc.o.appendChild(o) wc.o.appendChild(o.target)
} }
else { // text segment to be translated else { // text segment to be translated
var o=wc.os[i].target=span_class("placeholder",text(is[i])) o.target=span_class("placeholder",text(is[i]))
wc.o.appendChild(o) wc.o.appendChild(o.target)
translate_segment(i) translate_segment(o)
} }
} }
} }

View File

@@ -9,18 +9,19 @@
div.center { text-align: center; } div.center { text-align: center; }
table { border-collapse: collapse; table-layout: fixed; width: 100%; } table { border-collapse: collapse; table-layout: fixed; width: 100%; }
td { padding: 0 5px; vertical-align: top; } td { padding: 0 5px; vertical-align: top; }
td.output { background: #fcfcfc; } td.output { background: #fcfcfc; border: 1px solid grey; }
td.input, td.output { font-family: sans-serif; font-size: 90%; } td.input, td.output { font-family: sans-serif; font-size: 90%; }
div#output { white-space: pre-line; } div#output { white-space: pre-line; }
textarea { margin: 0; font: inherit; } div.input { margin-right: 5px; }
textarea { font: inherit; }
body:target h1, body:target div.modtime { display: none; } body:target h1, body:target div.modtime { display: none; }
small { color: #666; } small { color: #666; }
#pick>* { padding: 0 0.5ex; } #pick>* { padding: 0 0.5ex; }
#speak { display: none; } #speak { display: none; }
.colors .default_quality { background-color: #ffc; } .colors .default_quality { background-color: #ffb; }
.colors .high_quality { background-color: #cfc; } .colors .high_quality { background-color: #bfb; }
.colors .low_quality { background-color: #fba; } .colors .low_quality { background-color: #fa7; }
.colors .bad_quality { background-color: #f88; } .colors .bad_quality { background-color: #f89; }
.placeholder { color: #999; } .placeholder { color: #999; }
.error { color: #c00; } .error { color: #c00; }
</style> </style>
@@ -61,12 +62,14 @@ small { color: #666; }
<input name=colors type=checkbox checked onchange="wc.colors()"> Colors <input name=colors type=checkbox checked onchange="wc.colors()"> Colors
<td><button name=translate type=submit><strong>Translate</strong></button> <td><button name=translate type=submit><strong>Translate</strong></button>
<tr><td class=input colspan=2> <tr><td class=input colspan=2>
<div class=input>
<textarea name=input rows=5 style="width: 100%" onkeyup="wc.delayed_translate()"></textarea> <textarea name=input rows=5 style="width: 100%" onkeyup="wc.delayed_translate()"></textarea>
<small>Enter text to translate above.</small> </div>
<td class=output colspan=2> <td class=output colspan=2>
<div id=output></div> <div id=output></div>
<tr><td colspan=2> <tr><td colspan=2>
<small>Enter text to translate above.</small>
<td colspan=2> <td colspan=2>
<!--<small id=speak><input name=speak type=checkbox> Enable speech synthesis</small>--> <!--<small id=speak><input name=speak type=checkbox> Enable speech synthesis</small>-->
@@ -80,7 +83,7 @@ small { color: #666; }
</div> </div>
<p> <p>
<div class=modtime><small> <div class=modtime><small>
<!-- hhmts start -->Last modified: Wed Apr 16 16:48:16 CEST 2014 <!-- hhmts end --> <!-- hhmts start -->Last modified: Thu Apr 17 15:45:17 CEST 2014 <!-- hhmts end -->
</small></div> </small></div>
<script src="js/support.js"></script> <script src="js/support.js"></script>
<script src="js/gftranslate.js"></script> <script src="js/gftranslate.js"></script>