summaryrefslogtreecommitdiff
path: root/src/www/minibar/minibar_support.js
blob: 13345ce378fc3e618a78062c404c38c9e142dcb3 (plain)
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)
}