1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
|
/* --- Auxiliary functions -------------------------------------------------- */
function langpart(conc,abs) { // langpart("FoodsEng","Foods") == "Eng"
return hasPrefix(conc,abs) ? conc.substr(abs.length) : conc;
}
// Lookup language codes (from "flags language = ..." in the source grammar)
function langCode(grammar,conc) {
if(!grammar.langCode) {
var ls=grammar.languages
var langCode={}
for(var i=0;i<ls.length;i++)
if(ls[i].languageCode)
langCode[ls[i].name]=ls[i].languageCode
grammar.langCode=langCode
}
return grammar.langCode[conc]
}
// Words are separated by spaces (for now). GF has other lexers/unlexers.
function gf_lex(s) { return s.split(" "); }
function gf_unlex(ws) { return ws.join(" "); }
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 button_img(url,action) {
var i=node("img",{"class":"button","src":url});
i.onclick=action;
return i;
}
function cycle_images(img_urls) {
var current=0;
function cycle() {
current++;
if(current>=img_urls.length) current=0;
i.src=img_urls[current]
}
var i=button_img(img_urls[0],cycle);
return i
}
function toggle_img(i) {
var tmp=i.src;
i.src=i.other;
i.other=tmp;
}
function setField(form,name,value) {
form[name].value=value;
var el=element(name);
if(el) el.innerHTML=value;
}
function open_popup(url,target) {
var w=window.open(url,target,'toolbar=no,location=no,status=no,menubar=no');
w.focus();
}
function opener_element(id) { with(window.opener) return element(id); }
function supportsSVG() {
return document.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure", "1.1")
}
function speech_buttons(to3,to2,txt) {
var voices = window.speechSynthesis && window.speechSynthesis.getVoices() || []
var dvs = voices.filter(function(v){return v.default})
function pick2dash(v) { return hasPrefix(v.lang,to2dash) }
if(to2)
var pick=function (v) { return v.lang==to2 }
else if(to3.length==3) {
var to2dash=alangcode(to3)+"-"
var pick=pick2dash
}
else {
// Maybe the name of the concrete syntax is the name of the language
// like in Numerals.pgf
var lang=to3.substr(0,1).toUpperCase()+to3.substr(1).toLowerCase()
var codes=langcode[lang]
var to2dash=(codes ? codes.code2 : to3)+"-"
var pick=pick2dash
}
function btn(v) {
// Remove spaces more fluent Thai:
var txt2 = v.lang=="th-TH" ? txt.split(" ").join("") : txt
var u=new SpeechSynthesisUtterance(txt2)
u.lang=v.lang // how to use v.voiceURI or v.name?
function speak() {
speechSynthesis.cancel()
speechSynthesis.speak(u)
}
return button(v.lang,speak)
}
//console.log(voices.length,"voices")
var vs=dvs.filter(pick)
if(vs.length==0) vs=voices.filter(pick)
//console.log(vs.length,"voices for "+to3+" "+to2)
var btns=vs.map(btn)
//console.log(btns.length,"voice buttons")
return wrap("span",btns)
}
|