{
if (! Xex.LogNode)
return;
- var str = '';
- if (indent != undefined)
- for (var i = 0; i <= indent; i++)
- str += ' ';
- Xex.LogNode.value = str + arg + "\n" + Xex.LogNode.value;
+ if (! arg)
+ Xex.LogNode.value = '';
+ else
+ {
+ var str = '';
+ if (indent != undefined)
+ for (var i = 0; i <= indent; i++)
+ str += ' ';
+ Xex.LogNode.value = str + arg + "\n" + Xex.LogNode.value;
+ }
}
};
keysyms["del"] = "delete";
function decode_keysym (str) {
+ if (str.length == 1)
+ return str;
var parts = str.split ("-");
var len = parts.length, i;
var has_modifier = len > 1;
keys[0x90] = "numlock";
keys[0xF0] = "capslock";
+ var keyids = {};
+ keyids['U+0008'] = 'backspace';
+ keyids['U+0009'] = 'tab';
+ keyids['U+0018'] = 'cancel';
+ keyids['U+001B'] = 'escape';
+ keyids['U+0020'] = 'space';
+ keyids['U+007F'] = 'delete';
+
+ var modifiers = {}
+ modifiers.Shift = 1;
+ modifiers.Control = 1;
+ modifiers.Alt = 1;
+ modifiers.AltGraph = 1;
+ modifiers.Meta = 1
+
MIM.decode_key_event = function (event)
{
- var key = ((event.type == 'keydown' || event.keyCode) ? event.keyCode
+ var key = event.keyIdentifier;
+
+ if (key) // keydown event of Chrome
+ {
+ if (modifiers[key])
+ return false;
+ var mod = '';
+ if (event.ctrlKey) mod += 'C-';
+ if (event.metaKey) mod += 'M-';
+ if (event.altKey) mod += 'A-';
+ var keysym = keyids[key];
+ if (keysym)
+ key = keysym;
+ else if (key.match(/^U\+([0-9A-Z]+)$/))
+ {
+ if (mod.length == 0)
+ return;
+ key = String.fromCharCode (parseInt (RegExp.$1, 16));
+ }
+ else
+ key = key.toLowerCase ();
+ if (event.shiftKey) mod += 'S-';
+ return new MIM.Key (mod + key);
+ }
+ else
+ {
+ key = ((event.type == 'keydown' || event.keyCode) ? event.keyCode
: event.charCode ? event.charCode
: false);
- if (! key)
- return false;
- if (event.type == 'keydown')
- {
- key = keys[key];
if (! key)
return false;
- if (event.shiftKey) key = "S-" + key ;
+ if (event.type == 'keydown')
+ {
+ key = keys[key];
+ if (! key)
+ return false;
+ if (event.shiftKey) key = "S-" + key ;
+ }
+ else
+ key = String.fromCharCode (key);
}
- else
- key = String.fromCharCode (key);
if (event.altKey) key = "A-" + key ;
if (event.ctrlKey) key = "C-" + key ;
return new MIM.Key (key);
if (! MIM.debug_nodes)
{
MIM.debug_nodes = new Array ();
- MIM.debug_nodes['keydown'] = document.getElementById ('keydown');
- MIM.debug_nodes['keypress'] = document.getElementById ('keypress');
MIM.debug_nodes['status0'] = document.getElementById ('status0');
MIM.debug_nodes['status1'] = document.getElementById ('status1');
+ MIM.debug_nodes['keydown'] = document.getElementById ('keydown');
+ MIM.debug_nodes['keypress'] = document.getElementById ('keypress');
MIM.debug_nodes['keymap0'] = document.getElementById ('keymap0');
MIM.debug_nodes['keymap1'] = document.getElementById ('keymap1');
MIM.debug_nodes['preedit0'] = document.getElementById ('preedit0');
}
var target = event.target;
var code = event.keyCode;
- var ch = event.type == 'keydown' ? 0 : event.charCode;
+ var ch = event.type == 'keypress' ? event.charCode : 0;
var key = MIM.decode_key_event (event);
var index;
- MIM.debug_nodes[event.type].innerHTML = "" + code + "/" + ch + " : " + key;
+ MIM.debug_nodes[event.type].innerHTML = "" + code + "/" + ch + ":" + key + '/' + event.keyIdentifier;
index = (event.type == 'keydown' ? '0' : '1');
if (ic)
MIM.debug_nodes['status' + index].innerHTML = ic.im.load_status;
}
MIM.debug_print (event, ic);
ic.key = MIM.decode_key_event (event);
+ if (ic.key)
+ {
+ Xex.Log ("filtering " + ic.key);
+ var result = ic.Filter (ic.key);
+ MIM.update (target, ic);
+ if (! ic.key_unhandled)
+ event.preventDefault ();
+ }
};
MIM.keypress = function (event)
MIM.update (target, ic);
if (! ic.key_unhandled)
event.preventDefault ();
+ } catch (e) {
+ Xex.Log ("error:" + e);
+ event.preventDefault ();
} finally {
MIM.debug_print (event, ic);
}
return;
};
-MIM.Lang = {
- European: new Array ('de', 'fr'),
- MiddleEast: new Array ('ar', 'he'),
- SouthAsia: new Array ('hi'),
- SouthEastAsia: new Array ('th'),
- EastAsia: new Array ('ja', 'zh'),
- Other: new Array ()
-};
+(function () {
+ var lang_category = {
+ European: {
+ cs: { name: 'Czech' },
+ da: { name: 'Danish' },
+ el: { name: 'Greek' },
+ en: { name: 'English' },
+ eo: { name: 'Esperanto' },
+ fr: { name: 'French' },
+ grc: { name: 'ClassicGreek' },
+ hr: { name: 'Croatian' },
+ hy: { name: 'Armenian' },
+ ka: { name: 'Georgian' },
+ kk: { name: 'Kazakh' },
+ ru: { name: 'Russian' },
+ sk: { name: 'Slovak' },
+ sr: { name: 'Serbian' },
+ sv: { name: 'Swedish' },
+ vi: { name: 'Vietnamese' },
+ yi: { name: 'Yiddish' } },
+ MiddleEast: {
+ ar: { name: 'Arabic' },
+ dv: { name: 'Divehi' },
+ fa: { name: 'Persian' },
+ he: { name: 'Hebrew' },
+ kk: { name: 'Kazakh' },
+ ps: { name: 'Pushto' },
+ ug: { name: 'Uighur' },
+ yi: { name: 'Yiddish' } },
+ SouthAsia: {
+ as: { name: 'Assamese' },
+ bn: { name: 'Bengali' },
+ bo: { name: 'Tibetan' },
+ gu: { name: 'Gujarati' },
+ hi: { name: 'Hindi' },
+ kn: { name: 'Kannada' },
+ ks: { name: 'Kashmiri' },
+ ml: { name: 'Malayalam' },
+ mr: { name: 'Marathi' },
+ ne: { name: 'Nepali' },
+ or: { name: 'Oriya' },
+ pa: { name: 'Panjabi' },
+ sa: { name: 'Sanskirit' },
+ sd: { name: 'Sindhi' },
+ si: { name: 'Sinhalese' },
+ ta: { name: 'Tamil' },
+ te: { name: 'Telugu' },
+ ur: { name: 'Urdu' } },
+ SouthEastAsia: {
+ cmc: { name: 'Cham' },
+ km: { name: 'Khmer'},
+ lo: { name: 'Lao' },
+ my: { name: 'Burmese' },
+ tai: { name: 'Tai Viet' },
+ th: { name: 'Thai' },
+ vi: { name: 'Vietanamese' } },
+ EastAsia: {
+ ii: { name: 'Yii' },
+ ja: { name: 'Japanese' },
+ ko: { name: 'Korean' },
+ zh: { name: 'Chinese' } },
+ Other: {
+ am: { name: 'Amharic' },
+ ath: { name: 'Carrier' },
+ bla: { name: 'Blackfoot' },
+ cr: { name: 'Cree' },
+ eo: { name: 'Esperanto' },
+ iu: { name: 'Inuktitut' },
+ nsk: { name: 'Naskapi' },
+ oj: { name: 'Ojibwe' },
+ t: { name: 'Generic' } }
+ };
+
+ function categorize_im ()
+ {
+ var cat, lang, list, name;
+ for (lang in MIM.imlist)
+ {
+ list = null;
+ for (cat in lang_category)
+ if (lang_category[cat][lang])
+ {
+ list = lang_category[cat][lang].list;
+ if (! list)
+ list = lang_category[cat][lang].list = {};
+ break;
+ }
+ if (list)
+ for (name in MIM.imlist[lang])
+ list[name] = MIM.imlist[lang][name];
+ else
+ for (name in MIM.imlist[lang])
+ Xex.Log ('no category ' + lang + '-' + name);
+ }
+ }
-// Other
-// am
-// ath
-// bla
-// cr
-// el
-// eo
-// iu
-// nsk
-// oj
-
-// Middle Eastern
-// ar
-// dv
-// fa
-// he
-// hi
-// kk
-// ps
-// ug
-// yi*
-
-// South Asian
-// as
-// bn
-// bo
-// gu
-// kn
-// ks
-// ml
-// mr
-// ne
-// or
-// pa
-// sd
-// sa
-// si
-// ta
-// te
-// ur
-
-// European
-// cs
-// da
-// eo
-// fr
-// hr
-// hy
-// kk
-// ru
-// sk
-// sr
-// sv
-// vi*
-// yi*
-
-// East Asian
-// ii
-// ja
-// ko
-// zh
-
-// SouthEast Asian
-// km
-// lo
-// my
-// tai
-// th
-// vi*
-
-MIM.select_im = function (event)
-{
- var target = event.target.parentNode;
- while (target.tagName != "mim-select-im")
- target = target.parentNode;
- var idx = 0;
- var im = false;
- for (var lang in MIM.imlist)
- for (var name in MIM.imlist[lang])
- if (idx++ == target.selectedIndex)
- {
- im = MIM.imlist[lang][name];
- break;
- }
- document.getElementsByTagName ('body')[0].removeChild (target);
- target.target.focus ();
- if (im && im != MIM.current)
- {
- MIM.current = im;
- Xex.Log ('select IM: ' + im.name);
- }
-};
+ var destroy_timer;
+ var last_target;
-MIM.destroy_menu = function (event)
-{
- if (event.target.tagName == "mim-select-im")
- document.getElementsByTagName ('body')[0].removeChild (event.target);
-};
+ function destroy ()
+ {
+ clearTimeout (destroy_timer);
+ destroy_timer = null;
+ var target = document.getElementById ('mim-menu');
+ if (target)
+ {
+ for (; last_target && last_target.menu_level;
+ last_target = last_target.parentLi)
+ last_target.style.backgroundColor = 'white';
+ var nodes = target.getElementsByTagName ('ul');
+ for (var i = 0; i < nodes.length; i++)
+ nodes[i].style.visibility = 'hidden';
+ document.getElementsByTagName ('body')[0].removeChild (target);
+ }
+ }
-MIM.select_menu = function (event)
-{
- var target = event.target;
- var sel;
+ function destroy_menu () {
+ if (! destroy_timer)
+ destroy_timer = setTimeout (destroy, 1000);
+ }
- if (! ((target.type == "text" || target.type == "textarea")
- && event.which == 1 && event.ctrlKey))
- return;
- if (! sel)
- {
- sel = document.createElement ('select');
- sel.onclick = MIM.select_im;
- sel.onmouseout = MIM.destroy_menu;
- sel.style.position='absolute';
- sel.style.left = (event.clientX - 10) + "px";
- sel.style.top = (event.clientY - 10) + "px";
- sel.target = target;
- var idx = 0;
- for (var lang in MIM.imlist)
- for (var name in MIM.imlist[lang])
+ function show_submenu (event)
+ {
+ if (destroy_timer)
+ {
+ clearTimeout (destroy_timer);
+ destroy_timer = null;
+ }
+ var target = event.target;
+ if (! target.menu_level)
+ return;
+ if (last_target && target.parentLi != last_target)
+ {
+ last_target.style.backgroundColor = 'white';
+ if (target.menu_level < last_target.menu_level)
{
- var option = document.createElement ('option');
- var imname = lang + "-" + name;
- option.appendChild (document.createTextNode (imname));
- option.value = imname;
- sel.appendChild (option);
- if (MIM.imlist[lang][name] == MIM.current)
- sel.selectedIndex = idx;
- idx++;
+ last_target = last_target.parentLi;
+ last_target.style.backgroundColor = 'white';
}
- sel.size = idx;
- }
- document.getElementsByTagName ('body')[0].appendChild (sel);
-};
+ var uls = last_target.getElementsByTagName ('ul');
+ for (var i = 0; i < uls.length; i++)
+ uls[i].style.visibility = 'hidden';
+ }
+ last_target = target;
+ target.style.backgroundColor = 'yellow';
+ if (target.menu_level < 3)
+ {
+ target.lastChild.style.visibility = 'visible';
+ target.lastChild.style.left = target.clientWidth + 'px';
+ }
+ event.preventDefault ();
+ }
+
+ function select_im (event)
+ {
+ var target = event.target;
+ if (target.im)
+ {
+ MIM.current = target.im;
+ destroy ();
+ }
+ event.preventDefault ();
+ }
+
+ function create_ul (visibility)
+ {
+ var ul = document.createElement ('ul');
+ ul.style.position = 'absolute';
+ ul.style.margin = '0px';
+ ul.style.padding = '0px';
+ ul.style.border = '1px solid gray';
+ ul.style.borderBottom = 'none';
+ ul.style.top = '-1px';
+ ul.style.backgroundColor = 'white';
+ ul.style.visibility = visibility;
+ return ul;
+ }
+
+ function create_li (level, text)
+ {
+ var li = document.createElement ('li');
+ li.style.position = 'relative';
+ li.style.margin = '0px';
+ li.style.padding = '1px';
+ li.style.borderBottom = '1px solid gray';
+ li.style.top = '0px';
+ li.style.listStyle = 'none';
+ li.menu_level = level;
+ li.appendChild (document.createTextNode (text));
+ return li;
+ }
-MIM.select_menu = function (event)
-{
- var target = event.target;
var menu;
- if (! ((target.type == "text" || target.type == "textarea")
- && event.which == 1 && event.ctrlKey))
- return;
- if (! menu)
- {
- menu = document.createElement ('ul');
- menu.style.margin = '0';
- menu.style.padding = '0';
- menu.id = 'mim-select-im';
- menu.onclick = MIM.select_im;
- menu.onmouseout = MIM.destroy_menu;
- menu.style.position='absolute';
- menu.style.left = (event.clientX - 10) + "px";
- menu.style.top = (event.clientY - 10) + "px";
- menu.style['border-bottom'] = '1px solid #ccc';
- menu.style['background-color'] = 'white';
- menu.target = target;
- var idx = 0;
- for (var lang in MIM.imlist)
- {
- var li = document.createElement ('li');
- li.style.position = 'relative';
- li.style['list-style']= 'none';
- li.style.margin = '0';
- li.style.padding = '0';
- li.onmouseover = function ()
+ function create_menu (event)
+ {
+ var target = event.target;
+
+ if (! ((target.type == "text" || target.type == "textarea")
+ && event.which == 1 && event.ctrlKey))
+ return;
+ if (! menu)
+ {
+ categorize_im ();
+ menu = create_ul ('visible');
+ menu.style.fontFamily = 'sans-serif';
+ menu.style.fontWeight = 'bold';
+ menu.id = 'mim-menu';
+ menu.onclick = select_im;
+ menu.onmouseover = show_submenu;
+ menu.onmouseout = destroy_menu;
+ for (var catname in lang_category)
{
- this.style.backgroundColor = 'yellow';
- var children = this.getElementsByTagName ('ul');
- for (var i = children.length - 1; i >= 0; i--)
- {
- children[i].display = 'block';
- children[i].visibility = 'visible';
- children[i].left = '100px';
- }
- children = this.getElementsByTagName ('li');
- for (var i = children.length - 1; i >= 0; i--)
+ var cat = lang_category[catname];
+ var li = create_li (1, catname);
+ var sub = create_ul ('hidden');
+ for (var langname in cat)
{
- children[i].display = 'block';
- children[i].visibility = 'visible';
- children[i].left = '100px';
+ var lang = cat[langname];
+ if (! lang.list)
+ continue;
+ var sub_li = create_li (2, lang.name);
+ sub_li.parentLi = li;
+ var subsub = create_ul ('hidden');
+ for (var name in lang.list)
+ {
+ var im = lang.list[name];
+ var subsub_li = create_li (3, im.name);
+ subsub_li.parentLi = sub_li;
+ subsub_li.im = im;
+ subsub.appendChild (subsub_li);
+ }
+ sub_li.appendChild (subsub);
+ sub.appendChild (sub_li);
}
- };
- li.onmouseout = function () { this.style.backgroundColor = 'white'; };
- li.appendChild (document.createTextNode (lang));
- var sub = document.createElement ('ul');
- sub.style.position = 'absolute';
- sub.style.top = '0px';
- sub.style.visibility = 'hidden';
- li.appendChild (sub);
- for (var name in MIM.imlist[lang])
- {
- var sub_li = document.createElement ('li');
- var imname = ' ' + lang + "-" + name;
- sub_li.style.position = 'absolute';
- sub_li.style.top = '0px';
- sub_li.style['list-style']= 'none';
- //sub_li.style.visibility = 'hidden';
- sub_li.appendChild (document.createTextNode (imname));
- sub.appendChild (sub_li);
- if (MIM.imlist[lang][name] == MIM.current)
- menu.selectedIndex = idx;
- idx++;
- }
- menu.appendChild (li);
- }
- menu.size = idx;
- }
- document.getElementsByTagName ('body')[0].appendChild (menu);
-};
+ li.appendChild (sub);
+ menu.appendChild (li);
+ }
+ document.mimmenu = menu;
+ lang_category = null;
+ }
+ menu.style.left = (event.clientX - 10) + "px";
+ menu.style.top = (event.clientY - 10) + "px";
+ document.getElementsByTagName ('body')[0].appendChild (menu);
+ };
+
+ MIM.init = function ()
+ {
+ MIM.add_event_listener (window, 'keydown', MIM.keydown);
+ MIM.add_event_listener (window, 'keypress', MIM.keypress);
+ MIM.add_event_listener (window, 'mousedown', create_menu);
+ if (window.location == 'http://localhost/mim/index.html')
+ MIM.server = 'http://localhost/mim';
+ MIM.current = MIM.imlist['vi']['telex'];
+ };
+}) ();
MIM.test = function ()
{
}
-MIM.init = function ()
-{
- MIM.add_event_listener (window, 'keydown', MIM.keydown);
- MIM.add_event_listener (window, 'keypress', MIM.keypress);
- MIM.add_event_listener (window, 'mousedown', MIM.select_menu);
- if (window.location == 'http://localhost/mim/index.html')
- MIM.server = 'http://localhost/mim';
- MIM.current = MIM.imlist['vi']['telex'];
-};
-
MIM.init_debug = function ()
{
MIM.debug = true;
Xex.LogNode = document.getElementById ('log');
+ Xex.Log (null);
MIM.init ();
};