if (indent != undefined)
for (var i = 0; i <= indent; i++)
str += ' ';
- Xex.LogNode.value = str + arg + "\n" + Xex.LogNode.value;
+ Xex.LogNode.value += "\n" + str + arg;
+ Xex.LogNode.scrollTop = Xex.LogNode.scrollHeight;
}
}
};
for (elt in parent.functions)
this.functions[elt] = parent.functions[elt];
for (elt in parent.variables)
- this.variables[elt] = parent.variables[elt];
+ {
+ var vari = parent.variables[elt];
+ this.variables[elt] = new Xex.Variable (this, vari.name, vari.desc,
+ vari.val, vari.range);
+ }
}
this.call_stack = new Array ();
proto.Clone = function () { return new Xex.Varref (this.val); }
proto.Eval = function (domain)
{
- if (! this.vari || this.vari.domain != domain)
- this.vari = domain.GetVarCreate (this.val);
- Xex.Log (this.ToString () + '=>' + this.vari.val, domain.depth);
- return this.vari.val;
+ var vari = domain.GetVarCreate (this.val);
+ Xex.Log (this.ToString () + '=>' + vari.val, domain.depth);
+ return vari.val;
}
proto.Parser = function (domain, node)
var null_args = new Array ();
-Xex.Funcall = function (func, vari, args)
+Xex.Funcall = function (func, vname, args)
{
this.func = func;
- this.vari = vari;
+ this.vname = vname;
this.args = args || null_args;
};
if (fname == 'funcall')
fname = node.attributes['fname'].nodeValue;
var func = domain.GetFunc (fname);
- var vari;
+ var vname;
attr = node.attributes['vname'];
- vari = attr != undefined ? domain.GetVarCreate (attr.nodeValue) : null;
+ vname = attr != undefined ? attr.nodeValue : null;
var args = Xex.Term.Parse (domain, node.firstElement (), null);
- return new Xex.Funcall (func, vari, args);
+ return new Xex.Funcall (func, vname, args);
}
proto.New = function (domain, fname, vname, args)
{
var func = domain.GetFunc (fname);
- var vari = vname ? domain.GetVarCreate (vname) : null;
- var funcall = new Xex.Funcall (func, vari, args);
+ var funcall = new Xex.Funcall (func, vname, args);
if (func instanceof Xex.Macro)
funcall = funcall.Eval (domain);
return funcall;
{
if (! (this.func instanceof Xex.Subrountine))
Xex.Log (this, domain.depth);
+ var vari;
+ if (this.vname)
+ vari = domain.GetVarCreate (this.vname);
domain.depth++;
var result;
try {
- result = this.func.Call (domain, this.vari, this.args);
+ result = this.func.Call (domain, vari, this.args);
} finally {
Xex.Log (this + ' => ' + result, --domain.depth);
}
MIM.Key = function (val)
{
this.key;
- this.has_modifier = false;
if (val instanceof Xex.Term)
this.key = val.val;
else if (typeof val == 'string' || val instanceof String)
MIM.KeySeq = function (seq)
{
this.val = new Array ();
- this.has_modifier = false;
if (seq)
{
selectors["@>"] = selectors["@last"] = new MIM.Selector ('@>');
selectors["@-"] = selectors["@previous"] = new MIM.Selector ('@-');
selectors["@+"] = selectors["@next"] = new MIM.Selector ('@+');
- selectors["@["] = selectors["@previous-candidate-change"]
- = new MIM.Selector ('@[');
- selectors["@]"] = selectors["@next-candidate-change"]
- = new MIM.Selector ('@]');
+ selectors["@["] = selectors["@previous-group"] = new MIM.Selector ('@[');
+ selectors["@]"] = selectors["@next-group"] = new MIM.Selector ('@]');
MIM.Selector.prototype.Parser = function (domain, node)
{
var sub;
if (index < keys.val.length && this.submaps
+ && ! keys.val[index])
+ {
+ Xex.Log ('invalid key at ' + index);
+ throw 'invalid key';
+ }
+
+ if (index < keys.val.length && this.submaps
&& (sub = this.submaps[keys.val[index].key]))
{
index++;
{
var ic = domain.context;
var n = args.length == 0 ? -2 : args[0].val;
+ Xex.Log ('undo with arg ' + args[0]);
if (n < 0)
ic.keys.val.splice (ic.keys.val.length + n, -n);
else
}
function Funhandle (domain, vari, args)
- {
- domain.context.commit ();
- return Xex.Fthrow (domain, vari, Xex.CatchTag._mimtag);
- }
+ {
+ domain.context.commit ();
+ return Xex.Fthrow (domain, vari, Xex.CatchTag._mimtag);
+ }
function Fshift (domain, vari, args)
{
continue;
}
for (var mname in im.map_list)
- {
- this.map_list[mname] = im.map_list[mname];
- Xex.Log ('include map ' + mname);
- }
+ this.map_list[mname] = im.map_list[mname];
}
else
{
if (! this.initial_state)
this.initial_state = state;
this.state_list[sname] = state;
- Xex.Log ('include state ' + sname);
}
}
else if (node.nodeName == 'state')
function handle_key ()
{
- var out = this.keymap.Lookup (this.keys, this.key_head);
+ Xex.Log ('Key(' + this.key_head + ') "' + this.keys.val[this.key_head]
+ + '" in ' + this.state.name + ':' + this.keymap.name
+ + " key/state/commit-head/len:"
+ + this.key_head + '/' + this.state_key_head + '/' + this.commit_key_head + '/' + this.keys.val.length);
+ var out = this.state.keymap.Lookup (this.keys, this.state_key_head);
var sub = out.map;
- Xex.Log ('handling ' + this.keys.val[this.key_head]
- + ' in ' + this.state.name + ':' + this.keymap.name);
- this.key_head = out.index;
- if (sub != this.keymap)
+ if (out.index > this.key_head)
{
-
+ this.key_head = out.index;
+ Xex.Log (' with submap for ' + this.key_head + 'keys');
restore_state.call (this);
this.keymap = sub;
- Xex.Log ('submap found');
- if (this.keymap.map_actions)
+ if (sub.map_actions)
{
Xex.Log ('taking map actions:');
- if (! this.take_actions (this.keymap.map_actions))
+ if (! this.take_actions (sub.map_actions))
return false;
}
- else if (this.keymap.submaps)
+ else if (sub.submaps)
{
Xex.Log ('no map actions');
for (var i = this.state_key_head; i < this.key_head; i++)
this.ins (this.keys.val[i].key, null);
}
}
- if (! this.keymap.submaps)
+ if (! sub.submaps)
{
Xex.Log ('terminal:');
if (this.keymap.branch_actions != null)
if (! this.take_actions (this.keymap.branch_actions))
return false;
}
- if (this.keymap != this.state.keymap)
+ if (sub != this.state.keymap)
this.shift (this.state);
}
}
else
{
- Xex.Log ('no submap');
+ Xex.Log (' without submap');
+ this.keymap = sub;
var current_state = this.state;
var map = this.keymap;
proto = {
reset: function ()
{
- Xex.Log ('reseting ' + this.im.lang + '-' + this.im.name);
this.cursor_pos = 0;
this.candidate_show = false;
this.prev_state = null;
this.state_var_values = {};
this.state_pos = 0;
this.key_head = 0;
+ this.commit_key_head = 0;
this.key_unhandled = false;
this.unhandled_key = null;
this.changed = MIM.ChangedStatus.None;
if (this.key_head > this.keys.val.length)
this.key_head = this.keys.val.length;
}
+ Xex.Log ('0: key head = ' + this.key_head);
},
pop: function ()
this.candidate_table.clear ();
this.produced += this.preedit;
this.preedit_replace.call (this, 0, this.preedit.length, '', null);
+ this.preedit_saved = '';
+ this.state_pos = 0;
+ this.commit_key_head = this.key_head;
}
},
{
this.commit ();
this.keys.val.splice (0, this.key_head);
- this.key_head = 0;
+ this.key_head = this.state_key_head = this.commit_key_head = 0;
this.prev_state = null;
}
}
this.changed |= MIM.ChangedStatus.StateTitle;
this.state = state;
this.keymap = state.keymap;
- this.state_key_head = this.key_head;
save_state.call (this);
},
{
if (! this.active)
{
+ Xex.Log ("active = false");
this.key_unhandled = true;
this.unhandled_key = key;
return false;
this.key_unhandled = false;
this.keys.val.push (key);
var count = 0;
+ Xex.Log ("keyhead=" + this.key_head + " len="+this.keys.val.length);
while (this.key_head < this.keys.val.length)
{
if (! handle_key.call (this))
this.unhandled_key = this.keys.val[this.key_head];
this.keys.val.splice (this.key_head, this.key_head + 1);
}
+ if (this.state_key_head > 0)
+ this.state_key_head--;
+ if (this.commit_key_head > 0)
+ this.commit_key_head--;
this.key_unhandled = true;
break;
}
break;
}
}
+ if (this.keymap == this.initial_state.keymap)
+ this.commit ();
+
+ if (this.commit_key_head > 0)
+ {
+ this.keys.val.splice (0, this.commit_key_head);
+ this.key_head -= this.commit_key_head;
+ this.state_key_head -= this.commit_key_head;
+ this.commit_key_head = 0;
+ }
if (this.key_unhandled)
{
this.keys.val.length = 0;
+ //this.keys.val.splice (0, this.keys.val.length);
this.key_head = this.state_key_head = this.commit_key_head = 0;
}
return (! this.key_unhandled
- && this.produced.length == 0
- && this.preedit.length == 0);
+ && this.produced.length == 0);
}
}
}
};
-MIM.ignore_focus = false;
-
MIM.update = function (target, ic)
{
var text = target.value;
MIM.set_caret (target, ic);
};
+(function () {
+ var style_props = {
+ width: 'width',
+ height: 'height',
+ padingLeft: 'padding-left',
+ paddingRight: 'padding-right',
+ paddingTop: 'padding-top',
+ paddintBottom: 'padding-bottom',
+ borderLeftStyle: 'border-left-style',
+ borderRightStyle: 'border-right-style',
+ borderTopStyle: 'border-top-style',
+ borderBottomStyle: 'border-bottom-style',
+ borderLeftWidth: 'border-left-width',
+ borderRightWidth: 'border-right-width',
+ borderTopWidth: 'border-top-width',
+ borderBottomWidth: 'border-bottom-width',
+ fontFamily: 'font-family',
+ fontSize: 'font-size',
+ lineHeight: 'line-height',
+ letterSpacing: 'letter-spacing',
+ wordSpacing: 'word-spacing' };
+
+ function copy_style (from, to)
+ {
+ var from_style = getComputedStyle(from,'');
+
+ for(var name in style_props)
+ to.style[name] = from_style.getPropertyValue (style_props[name]);
+
+ to.style.left = from.offsetLeft + 'px';
+ to.style.top = from.offsetTop + 'px';
+ to.style.width = from.offsetWidth;
+ to.style.height = from.offsetHeight;
+ }
+
+ MIM.show = function (target, ic)
+ {
+ if (! ic.div_node)
+ {
+ ic.target_top = 0;
+ ic.target_left = 0;
+ for (var elm = ic.target.offsetParent; elm; elm = elm.offsetParent)
+ {
+ ic.target_top += elm.offsetTop;
+ ic.target_left += elm.offsetLeft;
+ }
+ ic.div_node = document.createElement ('div');
+ ic.div_node.style.visibility="hidden";
+ ic.div_node.style.position = "absolute";
+ document.getElementsByTagName ('body')[0].appendChild (ic.div_node);
+ ic.div_node_first = document.createElement ('span');
+ ic.div_node_last = document.createElement('span');
+ ic.div_node_last.innerHTML = '.';
+ ic.can_node = document.createElement ('div');
+ ic.can_node.appendChild (document.createTextNode ('1. abc'));
+ ic.can_node.appendChild (document.createTextNode ('2. def'));
+ ic.can_node.style.position = 'absolute';
+ ic.can_node.style.display = 'none';
+ document.getElementsByTagName ('body')[0].appendChild (ic.can_node);
+ }
+
+ copy_style (target, ic.div_node);
+ ic.div_node.innerHTML = '';
+ ic.div_node_first.innerHTML = target.value.substr (0, ic.range[0]);
+ ic.div_node.appendChild (ic.div_node_first);
+ ic.div_node.appendChild (ic.div_node_last);
+ Xex.Log (ic.div_node.firstChild.innerHTML);
+ var x = ic.target_left + ic.div_node.lastChild.offsetLeft;
+ var y = ic.target_top + ic.div_node.lastChild.offsetTop - target.scrollTop;
+ ic.can_node.style.left = x + 'px';
+ ic.can_node.style.top = y + 'px';
+ ic.can_node.style.display = 'block';
+ Xex.Log ("x:" + x + "px y:" + y + "px");
+ }
+}) ();
+
MIM.focus_in = function (event)
{
var target = event.target;
var ic = target.mim_ic;
- if (ic)
+ if (ic.wait_update == true)
{
- if (target.mim_ignore_focus_in)
- {
- Xex.Log ('ignore focus_in in ' + target.tagName);
- // Ignore this event which is caused by setSelectionRange ().
- target.mim_ignore_focus_in = false;
- event.preventDefault ();
- }
- else
- {
- Xex.Log ('focus_in in ' + target.tagName);
- try {
- ic.Filter (MIM.Key.FocusIn);
- MIM.update (target, ic);
- // Ignore further focus-in caused by setSelectionRange ().
- // target.mim_ignore_focus_in = true;
- }
- catch (e) { Xex.Log ('Error:' + e); throw (e); }
- }
+ Xex.Log ("Focus in " + target.tagName + ' IGNORED');
+ event.preventDefault ();
+ return false;
}
+ Xex.Log ("Focus in " + target.tagName);
+ ic.Filter (MIM.Key.FocusIn);
+ MIM.update (target, ic);
}
MIM.focus_out = function (event)
{
var target = event.target;
var ic = target.mim_ic;
- if (ic)
+ function reset_update () { ic.wait_update = false; };
+ if (ic.wait_update == true)
{
- if (target.mim_ignore_focus_out)
- {
- Xex.Log ('ignore focus_out in ' + target.tagName);
- // Ignore this event which is caused by setSelectionRange ().
- target.mim_ignore_focus_out = false;
- event.preventDefault ();
- }
- else
- {
- Xex.Log ('focus_out in ' + target.tagName);
- try {
- if (! MIM.get_range (target, ic))
- ic.reset ();
- ic.Filter (MIM.Key.FocusOut);
- // Ignore further focus-out caused by setSelectionRange ().
- target.mim_ignore_focus_in = true;
- target.mim_ignore_focus_out = true;
- MIM.update (target, ic);
- }
- catch (e) { Xex.Log ('Error:' + e); throw (e); }
- }
+ Xex.Log ("Focus out " + target.tagName + ' IGNORED');
+ event.preventDefault ();
+ return false;
}
+ Xex.Log ("Focus out " + target.tagName);
+ ic.Filter (MIM.Key.FocusOut);
+ ic.wait_update = true;
+ MIM.update (target, ic, true);
+ setTimeout (reset_update, 1000);
};
MIM.keydown = function (event)
return;
if (! (target.type == "text" || target.type == "textarea"))
return;
- document.akey = event;
var ic = target.mim_ic;
if (! ic || ic.im != MIM.current)
if (! MIM.get_range (target, ic))
ic.reset ();
}
+ MIM.show (target, ic);
MIM.debug_print (event, ic);
ic.key = MIM.decode_key_event (event);
if (ic.key)
Xex.Log ("filtering " + ic.key);
try {
var result = ic.Filter (ic.key);
+ Xex.Log ("result = " + result);
} catch (e) {
- Xex.Log ('Error;' + e);
+ Xex.Log ('Error:' + e);
throw (e);
}
MIM.update (target, ic);
} finally {
MIM.debug_print (event, ic);
}
+
return;
};
sk: { name: 'Slovak' },
sr: { name: 'Serbian' },
sv: { name: 'Swedish' },
- vi: { name: 'Vietnamese' },
yi: { name: 'Yiddish' } },
MiddleEast: {
ar: { name: 'Arabic' },
list = lang_category[cat][lang].list;
if (! list)
list = lang_category[cat][lang].list = {};
- break;
+ for (name in MIM.imlist[lang])
+ list[name] = MIM.imlist[lang][name];
}
- if (list)
- for (name in MIM.imlist[lang])
- list[name] = MIM.imlist[lang][name];
- else
+ if (! list)
for (name in MIM.imlist[lang])
Xex.Log ('no category ' + lang + '-' + name);
}
li.style.top = '0px';
li.style.listStyle = 'none';
li.menu_level = level;
- li.appendChild (document.createTextNode (text));
+ var nobr = document.createElement ('nobr');
+ nobr.innerHTML = text;
+ li.appendChild (nobr);
return li;
}
li.appendChild (sub);
menu.appendChild (li);
}
- document.mimmenu = menu;
lang_category = null;
}
menu.style.left = (event.clientX - 10) + "px";
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.current = MIM.imlist['zh']['tonepy'];
};
}) ();