var Xex = {
LogNode: null,
- Log: function (arg, indent)
+ LogSuspended: '',
+ Log: function (arg, indent, suspend)
{
if (! Xex.LogNode)
return;
if (! arg)
Xex.LogNode.value = '';
+ else if (suspend)
+ Xex.LogSuspended += arg;
else
{
- var str = '';
+ var str = Xex.LogSuspended;
+ Xex.LogSuspended = '';
if (indent != undefined)
for (var i = 0; i <= indent; i++)
str += ' ';
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) : false;
+ 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);
}
proto.Clone = function () { return new Xex.StrTerm (this.val); }
proto.Parser = function (domain, node)
{
- return new Xex.StrTerm (node.firstChild.nodeValue);
+ return new Xex.StrTerm (node.firstChild ? node.firstChild.nodeValue : '');
}
Xex.StrTerm.prototype = proto;
}) ();
return args[0];
}
+ function Fnot (domain, vari, args)
+ {
+ return (args[0].IsTrue () ? Xex.Zero : Xex.One);
+ }
+
function maybe_set_intvar (vari, n)
{
var term = new Xex.IntTerm (n);
return maybe_set_intvar (vari, n);
}
+ function Flogand (domain, vari, args)
+ {
+ var n, i;
+ if (vari == null)
+ {
+ Xex.Log ("logand arg args[0]" + args[0]);
+ n = args[0].Intval ()
+ i = 1;
+ }
+ else
+ {
+ Xex.Log ("logand arg var " + vari);
+ n = vari.val.Intval ();
+ i = 0;
+ }
+ while (n > 0 && i < args.length)
+ {
+ Xex.Log ("logand arg " + args[i]);
+ n &= args[i++].val;
+ }
+ return maybe_set_intvar (vari, n);
+ }
+
+ function Flsh (domain, vari, args)
+ {
+ return maybe_set_intvar (vari, args[0].Intval () << args[1].Intval ());
+ }
+
+ function Frsh (domain, vari, args)
+ {
+ return maybe_set_intvar (vari, args[0].Intval () >> args[1].Intval ());
+ }
+
function Fand (domain, vari, args)
{
var len = args.length;
return Xex.One;
}
+ function Fnoteq (domain, vari, args)
+ {
+ return (Feq (domain, vari, args) == Xex.One ? Xex.Zero : Xex.One);
+ }
+
function Flt (domain, vari, args)
{
- var n = args[0].Intval;
+ var n = args[0].Intval ();
for (var i = 1; i < args.length; i++)
{
- var n1 = args[i].Intval;
+ var n1 = args[i].Intval ();
if (n >= n1)
return Xex.Zero;
n = n1;
function Fle (domain, vari, args)
{
- var n = args[0].Intval;
+ var n = args[0].Intval ();
for (var i = 1; i < args.length; i++)
{
- var n1 = args[i].Intval;
+ var n1 = args[i].Intval ();
if (n > n1)
return Xex.Zero;
n = n1;
function Fgt (domain, vari, args)
{
- var n = args[0].Intval;
+ var n = args[0].Intval ();
for (var i = 1; i < args.length; i++)
{
- var n1 = args[i].Intval;
+ var n1 = args[i].Intval ();
if (n <= n1)
return Xex.Zero;
n = n1;
function Fge (domain, vari, args)
{
- var n = args[0].Intval;
+ var n = args[0].Intval ();
for (var i = 1; i < args.Length; i++)
{
- var n1 = args[i].Intval;
+ var n1 = args[i].Intval ();
if (n < n1)
return Xex.Zero;
n = n1;
basic.DefSubr (Fset, "set", true, 1, 1);
basic.DefAlias ("=", "set");
- //basic.DefSubr (Fnot, "not", false, 1, 1);
- //basic.DefAlias ("!", "not");
+ basic.DefSubr (Fnot, "not", false, 1, 1);
+ basic.DefAlias ("!", "not");
basic.DefSubr (Fadd, "add", true, 1, -1);
basic.DefSubr (Fmul, "mul", true, 1, -1);
basic.DefAlias ("*", "mul");
basic.DefAlias ("%", "mod");
basic.DefSubr (Flogior, "logior", true, 1, -1);
basic.DefAlias ('|', "logior");
- //basic.DefSubr (Flogand, "logand", true, 1, -1);
- //basic.DefAlias ("&", "logand");
- //basic.DefSubr (Flsh, "lsh", true, 1, 2);
- //basic.DefAlias ("<<", "lsh");
- //basic.DefSubr (Frsh, "rsh", true, 1, 2);
- //basic.DefAlias (">>", "rsh");
+ basic.DefSubr (Flogand, "logand", true, 1, -1);
+ basic.DefAlias ("&", "logand");
+ basic.DefSubr (Flsh, "lsh", true, 1, 2);
+ basic.DefAlias ("<<", "lsh");
+ basic.DefSubr (Frsh, "rsh", true, 1, 2);
+ basic.DefAlias (">>", "rsh");
basic.DefSubr (Feq, "eq", false, 2, -1);
basic.DefAlias ("==", "eq");
- //basic.DefSubr (Fnoteq, "noteq", false, 2, 2);
- //basic.DefAlias ("!=", "noteq");
+ basic.DefSubr (Fnoteq, "noteq", false, 2, 2);
+ basic.DefAlias ("!=", "noteq");
basic.DefSubr (Flt, "lt", false, 2, -1);
basic.DefAlias ("<", "lt");
basic.DefSubr (Fle, "le", false, 2, -1);
{
this.key;
this.has_modifier = false;
- if (typeof val == 'string' || val instanceof String)
+ if (val instanceof Xex.Term)
+ this.key = val.val;
+ else if (typeof val == 'string' || val instanceof String)
{
this.key = decode_keysym (val);
if (! this.key)
}
MIM.Key.prototype.toString = function () { return this.key; };
+
+ MIM.Key.FocusIn = new MIM.Key (new Xex.StrTerm ('input-focus-in'));
+ MIM.Key.FocusOut = new MIM.Key (new Xex.StrTerm ('input-focus-out'));
+ MIM.Key.FocusMove = new MIM.Key (new Xex.StrTerm ('input-focus-move'));
}) ();
(function () {
var len = seq.val.length;
for (var i = 0; i < len; i++)
{
- var v = seq.val[i];
- if (v.type != 'string' && v.type != 'integer'
- && v.type != 'symbol')
+ var v = seq.val[i], key;
+ if (v.type == 'symbol' || v.type == 'string')
+ key = new MIM.Key (v);
+ else if (v.type == 'integer')
+ key = new MIM.Key (v.val);
+ else
throw new Xex.ErrTerm (MIM.Error.ParseError,
"Invalid key: " + v);
- var key = new MIM.Key (v.val);
this.val.push (key);
if (key.has_modifier)
this.has_modifier = true;
var n = predefined[name];
if (n)
return n;
- if (name.charAt (1) == '-')
+ if (name.charAt (1) == '-' || name.charAt (1) == '+')
return new MIM.SurroundMarker (name);
throw new Xex.ErrTerm (MIM.Error.ParseError,
"Invalid marker: " + name);
{
var ic = domain.context;
var gsize = domain.variables['candidates_group_size'];
- var candidates = new MIM.Candidates (args, gsize ? gsize.Intval : 0);
+ var candidates = new MIM.Candidates (args, gsize ? gsize.Intval () : 0);
ic.ins (candidates.Current (), candidates);
return args[0];
}
function Fdelete (domain, vari, args)
{
var ic = domain.context;
- var pos = args[0].IsInt ? args[0].Intval : args[0].Position (ic);
+ var pos = args[0].IsInt ? args[0].Intval () : args[0].Position (ic);
return new Xex.IntTerm (ic.del (pos));
}
return args[0];
}
+ function Fshow (domain, vari, args)
+ {
+ domain.context.candidate_show = true;
+ domain.context.changed |= MIM.ChangedStatus.CandidateShow;
+ return Xex.nil;
+ }
+
+ function Fhide (domain, vari, args)
+ {
+ domain.context.candidate_show = false;
+ domain.context.changed |= MIM.ChangedStatus.CandidateShow;
+ return Xex.nil;
+ }
+
function Fchar_at (domain, vari, args)
{
return new Xex.IntTerm (args[0].CharAt (domain.context));
return args[0];
}
+ function Fpop (domain, vari, args)
+ {
+ var ic = domain.context;
+ if (ic.key_head < ic.keys.val.length)
+ ic.keys.val.splice (ic.keys_head, 1);
+ return Xex.nil;
+ }
+
function Fundo (domain, vari, args)
{
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.length + n, -n);
+ ic.keys.val.splice (ic.keys.val.length + n, -n);
else
- ic.keys.val.splice (n, ic.keys.length);
+ ic.keys.val.splice (n, ic.keys.val.length);
ic.reset ();
return Xex.nil;
}
}
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)
{
return args[0];
}
+ function Fshiftback (domain, vari, args)
+ {
+ domain.context.shift (null);
+ return Xex.nil;
+ }
+
+ function Fkey_count (domain, vari, args)
+ {
+ return new Xex.IntTerm (domain.context.key_head);
+ }
+
function Fsurrounding_flag (domain, vari, args)
{
return new Xex.IntTerm (-1);
im_domain.DefSubr (Finsert_candidates, "insert-candidates", false, 1, 1);
im_domain.DefSubr (Fdelete, "delete", false, 1, 1);
im_domain.DefSubr (Fselect, "select", false, 1, 1);
- //im_domain.DefSubr (Fshow, "show-candidates", false, 0, 0);
- //im_domain.DefSubr (Fhide, "hide-candidates", false, 0, 0);
+ im_domain.DefSubr (Fshow, "show-candidates", false, 0, 0);
+ im_domain.DefSubr (Fhide, "hide-candidates", false, 0, 0);
im_domain.DefSubr (Fmove, "move", false, 1, 1);
im_domain.DefSubr (Fmark, "mark", false, 1, 1);
im_domain.DefSubr (Fpushback, "pushback", false, 1, 1);
- //im_domain.DefSubr (Fpop, "pop", false, 0, 0);
+ im_domain.DefSubr (Fpop, "pop", false, 0, 0);
im_domain.DefSubr (Fundo, "undo", false, 0, 1);
im_domain.DefSubr (Fcommit, "commit", false, 0, 0);
im_domain.DefSubr (Funhandle, "unhandle", false, 0, 0);
im_domain.DefSubr (Fshift, "shift", false, 1, 1);
- //im_domain.DefSubr (Fshiftback, "shiftback", false, 0, 0);
+ im_domain.DefSubr (Fshiftback, "shiftback", false, 0, 0);
im_domain.DefSubr (Fchar_at, "char-at", false, 1, 1);
- //im_domain.DefSubr (Fkey_count, "key-count", false, 0, 0);
+ im_domain.DefSubr (Fkey_count, "key-count", false, 0, 0);
im_domain.DefSubr (Fsurrounding_flag, "surrounding-text-flag", false, 0, 0);
}) ();
alert ('inclusion fail');
continue;
}
- for (var mapname in im.map_list)
- this.map_list[mapname] = im.map_list[mapname];
+ for (var mname in im.map_list)
+ this.map_list[mname] = im.map_list[mname];
}
else
{
this.domain.map_list = this.map_list;
for (node = node.firstElement (); node; node = node.nextElement ())
{
- if (node.nodeName == 'state')
+ if (node.nodeName == 'xi:include')
+ {
+ var im = include (node);
+ if (! im)
+ alert ('inclusion fail');
+ for (var sname in im.state_list)
+ {
+ state = im.state_list[sname];
+ if (! this.initial_state)
+ this.initial_state = state;
+ this.state_list[sname] = state;
+ }
+ }
+ else if (node.nodeName == 'state')
{
var state = Xex.Term.Parse (this.domain, node);
if (! state.title)
ic.candidate_table.clear ();
ic.candidates = null;
ic.changed |= (MIM.ChangedStatus.Preedit | MIM.ChangedStatus.CursorPos
- | ChangedStatus.CandidateList
- | ChangedStatus.CandidateIndex
- | ChangedStatus.CandidateShow);
+ | MIM.ChangedStatus.CandidateList
+ | MIM.ChangedStatus.CandidateIndex
+ | MIM.ChangedStatus.CandidateShow);
}
function set_cursor (prefix, pos)
var sub = out.map;
Xex.Log ('handling ' + this.keys.val[this.key_head]
- + ' in ' + this.state.name + ':' + this.keymap.name);
+ + ' in ' + this.state.name + ':' + this.keymap.name, 0, true);
this.key_head = out.index;
if (sub != this.keymap)
{
-
+ Xex.Log (' with submap');
restore_state.call (this);
this.keymap = sub;
- Xex.Log ('submap found');
if (this.keymap.map_actions)
{
Xex.Log ('taking map actions:');
}
else
{
- Xex.Log ('no submap');
+ Xex.Log (' without submap');
var current_state = this.state;
var map = this.keymap;
this.state_var_values = {};
this.state_pos = 0;
this.key_head = 0;
- this.keys.val.length = 0;
+ this.commit_key_head = 0;
this.key_unhandled = false;
this.unhandled_key = null;
this.changed = MIM.ChangedStatus.None;
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.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.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);
}
}
{
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]+)$/))
- key = String.fromCharCode (parseInt (RegExp.$1, 16));
+ {
+ if (mod.length == 0)
+ return false;
+ key = String.fromCharCode (parseInt (RegExp.$1, 16));
+ }
else
key = key.toLowerCase ();
- if (event.shiftKey) key = "S-" + key ;
- if (event.altKey) key = "A-" + key ;
- if (event.metaKey) key = "M-" + key ;
- if (event.ctrlKey) key = "C-" + key ;
- if (key.length == 1)
- return false;
- return new MIM.Key (key);
+ if (event.shiftKey) mod += 'S-';
+ return new MIM.Key (mod + key);
}
else
{
}
};
+MIM.ignore_focus = false;
+
MIM.update = function (target, ic)
{
var text = target.value;
MIM.set_caret (target, ic);
};
-MIM.reset_ic = function (event)
+MIM.focus_in = function (event)
{
- if (event.target.mim_ic)
+ var target = event.target;
+ var ic = target.mim_ic;
+ if (ic)
{
- var target = event.target;
- var ic = target.mim_ic;
- if (ic.preedit.length > 0)
- event.target.setSelectionRange (ic.range[1], ic.range[1]);
- ic.reset ();
+ 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); }
+ }
+ }
+}
+
+MIM.cancel_ignore_focus = function ()
+{
+ if (MIM.focus_ignore_target)
+ {
+ MIM.focus_ignore_target.mim_ignore_focus_in = false;
+ MIM.focus_ignore_target.mim_ignore_focus_out = false;
+ }
+}
+
+MIM.focus_out = function (event)
+{
+ var target = event.target;
+ var ic = target.mim_ic;
+ if (ic)
+ {
+ 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);
+ 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.focus_ignore_target = target;
+ MIM.update (target, ic);
+ setTimeout (MIM.cancel_ignore_focus, 100);
+ }
}
};
return;
if (! (target.type == "text" || target.type == "textarea"))
return;
+ document.akey = event;
var ic = target.mim_ic;
if (! ic || ic.im != MIM.current)
if (ic.im.load_status != MIM.LoadStatus.Loaded)
return;
target.mim_ic = ic;
- MIM.add_event_listener (target, 'blur', MIM.reset_ic);
+ MIM.add_event_listener (target, 'focus', MIM.focus_in);
+ MIM.add_event_listener (target, 'blur', MIM.focus_out);
MIM.get_range (target, ic)
}
else
if (ic.key)
{
Xex.Log ("filtering " + ic.key);
- var result = ic.Filter (ic.key);
+ try {
+ var result = ic.Filter (ic.key);
+ } catch (e) {
+ Xex.Log ('Error' + e);
+ throw (e);
+ }
MIM.update (target, ic);
if (! ic.key_unhandled)
event.preventDefault ();
}
Xex.Log ("filtering " + ic.key);
- var result = ic.Filter (ic.key);
+ try {
+ var result = ic.Filter (ic.key);
+ } catch (e) {
+ Xex.Log ('Error;' + e);
+ throw (e);
+ }
MIM.update (target, ic);
if (! ic.key_unhandled)
event.preventDefault ();
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'];
};
}) ();