X-Git-Url: http://git.chise.org/gitweb/?p=m17n%2Fm17n-lib-js.git;a=blobdiff_plain;f=xex.js;fp=xex.js;h=932d240409a495bd7e48d0cddc9e2aa0248eed84;hp=46d510fb983f1b53a16bde280ea016620f5a18ee;hb=43b75075bbdf179f99ce18d1f802ed2326912417;hpb=155d360b5274f5c9ec1e85a846ebdaf1f621bd9f diff --git a/xex.js b/xex.js index 46d510f..932d240 100644 --- a/xex.js +++ b/xex.js @@ -16,18 +16,23 @@ var Xex = { else { var node; - LogNodeLen++; - if (LogNodeLen >= 200) - node = Xex.LogNode.firstElement (); + if (cont) + Xex.LogNode.lastChild.innerText += arg; else - node = document.createElement ('div'); - if (indent != undefined) - node.style.textIndent = (indent + 1) + 'em'; - else - node.style.textIndent = '0px'; - node.innerText = LogNodeLen + ': ' + arg; - Xex.LogNode.appendChild (node); - Xex.LogNode.scrollTop = Xex.LogNode.scrollHeight; + { + LogNodeLen++; + if (LogNodeLen >= 1000) + node = Xex.LogNode.firstElement (); + else + node = document.createElement ('div'); + if (indent != undefined) + node.style.textIndent = (indent + 1) + 'em'; + else + node.style.textIndent = '0px'; + node.innerText = LogNodeLen + ': ' + arg; + Xex.LogNode.appendChild (node); + Xex.LogNode.scrollTop = Xex.LogNode.scrollHeight; + } } } }; @@ -444,7 +449,7 @@ Xex.Term.prototype = { Equals: function (obj) { return (this.type == obj.type - && this.val + && this.val != undefined && obj.val == this.val); }, Matches: function (obj) { return this.Equals (obj); }, @@ -916,7 +921,7 @@ Xex.LstTerm = function (list) { this.val = list; }; { var n = vari ? vari.val.Intval () : 1; for (var i = 0; i < args.length; i++) - n *= arg.Intval (); + n *= args[i].Intval (); return maybe_set_intvar (vari, n); } @@ -1088,7 +1093,7 @@ Xex.LstTerm = function (list) { this.val = list; }; function Fge (domain, vari, args) { var n = args[0].Intval (); - for (var i = 1; i < args.Length; i++) + for (var i = 1; i < args.length; i++) { var n1 = args[i].Intval (); if (n < n1) @@ -1121,7 +1126,7 @@ Xex.LstTerm = function (list) { this.val = list; }; if (result.IsTrue ()) return args[1].Eval (domain); if (args.length == 2) - return Zero; + return Xex.Zero; return args[2].Eval (domain); } @@ -1302,2446 +1307,3 @@ Xex.Load = function (server, file) obj.send (''); return obj.responseXML.firstChild; } - -var MIM = { - // URL of the input method server. - server: "http://www.m17n.org/common/mim-js", - // Boolean flag to tell if MIM is active or not. - enabled: true, - // Boolean flag to tell if MIM is running in debug mode or not. - debug: false, - // List of main input methods. - imlist: {}, - // List of extra input methods; - imextra: {}, - // Global input method data - im_global: null, - // Currently selected input method. - current: false, - - // enum - LoadStatus: { NotLoaded:0, Loading:1, Loaded:2, Error:-1 }, - ChangedStatus: { - None: 0x00, - StateTitle: 0x01, - PreeditText:0x02, - CursorPos: 0x04, - CandidateList:0x08, - CandidateIndex:0x10, - CandidateShow:0x20, - Preedit: 0x06, // PreeditText | CursorPos - Candidate: 0x38 // CandidateList | CandidateIndex | CandidateShow - }, - KeyModifier: { - SL: 0x00400000, - SR: 0x00800000, - S: 0x00C00000, - CL: 0x01000000, - CR: 0x02000000, - C: 0x03000000, - AL: 0x04000000, - AR: 0x08000000, - A: 0x0C000000, - ML: 0x04000000, - MR: 0x08000000, - M: 0x0C000000, - G: 0x10000000, - s: 0x20000000, - H: 0x40000000, - High: 0x70000000, - All: 0x7FC00000 - }, - Error: { - ParseError: "parse-error" - } -}; - -(function () { - var keysyms = new Array (); - keysyms["bs"] = "backspace"; - keysyms["lf"] = "linefeed"; - keysyms["cr"] = keysyms["enter"] = "return"; - keysyms["esc"] = "escape"; - keysyms["spc"] = "space"; - 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; - - for (i = 0; i < len - 1; i++) - if (! MIM.KeyModifier.hasOwnProperty (parts[i])) - return false; - var key = parts[len - 1]; - if (key.length > 1) - { - key = keysyms[key.toLowerCase ()]; - if (key) - { - if (len > 1) - { - str = parts[0]; - for (i = 1; i < len - 1; i++) - str += '-' + parts[i]; - str += '-' + key; - } - else - str = key; - } - } - if (has_modifier) - { - parts = new Array (); - parts.push (str); - return parts; - } - return str; - } - - MIM.Key = function (val) - { - this.key; - 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) - throw new Xex.ErrTerm (MIM.Error.ParseError, "Invalid key: " + val); - if (this.key instanceof Array) - { - this.key = this.key[0]; - this.has_modifier = true; - } - } - else if (typeof val == 'number' || val instanceof Number) - this.key = String.fromCharCode (val); - else - throw new Xex.ErrTerm (MIM.Error.ParseError, "Invalid key: " + val); - } - - 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 () { - MIM.KeySeq = function (seq) - { - this.val = new Array (); - - if (seq) - { - if (seq.IsList) - { - var len = seq.val.length; - for (var i = 0; i < len; i++) - { - 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); - this.val.push (key); - if (key.has_modifier) - this.has_modifier = true; - } - } - else if (seq.IsStr) - { - var len = seq.val.length; - for (var i = 0; i < len; i++) - this.val.push (new MIM.Key (seq.val.charCodeAt (i))); - } - else - throw new Xex.ErrTerm (MIM.Error.ParseError, "Invalid key: " + seq); - } - } - - var proto = new Xex.Term ('keyseq'); - proto.Clone = function () { return this; } - proto.Parser = function (domain, node) - { - var seq = new Array (); - for (node = node.firstChild; node; node = node.nextSibling) - if (node.nodeType == 1) - { - var term = Xex.Term.Parse (domain, node); - return new MIM.KeySeq (term); - } - throw new Xex.ErrTerm (MIM.Error.ParseError, "Invalid keyseq"); - } - proto.toString = function () - { - var len = this.val.length; - if (len == 0) - return ''; - var first = true; - var str = ''; - for (var i = 0; i < len; i++) - { - if (first) - first = false; - else if (this.has_modifier) - str += ' '; - str += this.val[i].toString (); - } - return str + ''; - } - - MIM.KeySeq.prototype = proto; -}) (); - -(function () { - MIM.Marker = function () { } - MIM.Marker.prototype = new Xex.Term ('marker'); - MIM.Marker.prototype.CharAt = function (ic) - { - var p = this.Position (ic); - if (p < 0 || p >= ic.preedit.length) - return 0; - return ic.preedit.charCodeAt (p); - } - - MIM.FloatingMarker = function (name) { this.val = name; }; - var proto = new MIM.Marker (); - MIM.FloatingMarker.prototype = proto; - proto.Position = function (ic) { return ic.marker_positions[this.val]; }; - proto.Mark = function (ic) { ic.marker_positions[this.val] = ic.cursor_pos; }; - - MIM.PredefinedMarker = function (name) { this.val = name; } - MIM.PredefinedMarker.prototype = new MIM.Marker (); - MIM.PredefinedMarker.prototype.Position = function (ic) - { - if (typeof this.pos == 'number') - return this.pos; - return this.pos (ic); - } - - var predefined = { } - - function def_predefined (name, position) - { - predefined[name] = new MIM.PredefinedMarker (name); - predefined[name].pos = position; - } - - def_predefined ('@<', 0); - def_predefined ('@>', function (ic) { return ic.preedit.length; }); - def_predefined ('@-', function (ic) { return ic.cursor_pos - 1; }); - def_predefined ('@+', function (ic) { return ic.cursor_pos + 1; }); - def_predefined ('@[', function (ic) { - if (ic.cursor_pos > 0) - { - var pos = ic.cursor_pos; - return ic.preedit.FindProp ('candidates', pos - 1).from; - } - return 0; - }); - def_predefined ('@]', function (ic) { - if (ic.cursor_pos < ic.preedit.length - 1) - { - var pos = ic.cursor_pos; - return ic.preedit.FindProp ('candidates', pos).to; - } - return ic.preedit.length; - }); - for (var i = 0; i < 10; i++) - def_predefined ("@" + i, i); - predefined['@first'] = predefined['@<']; - predefined['@last'] = predefined['@>']; - predefined['@previous'] = predefined['@-']; - predefined['@next'] = predefined['@+']; - predefined['@previous-candidate-change'] = predefined['@[']; - predefined['@next-candidate-change'] = predefined['@]']; - - MIM.SurroundMarker = function (name) - { - this.val = name; - this.distance = parseInt (name.slice (1)); - if (isNaN (this.distance)) - throw new Xex.ErrTerm (MIM.Error.ParseError, "Invalid marker: " + name); - } - MIM.SurroundMarker.prototype = new MIM.Marker (); - MIM.SurroundMarker.prototype.Position = function (ic) - { - return ic.cursor_pos + this.distance; - } - MIM.SurroundMarker.prototype.CharAt = function (ic) - { - if (this.val == '@-0') - return -1; - var p = this.Position (ic); - if (p < 0) - return ic.GetSurroundingChar (p); - else if (p >= ic.preedit.length) - return ic.GetSurroundingChar (p - ic.preedit.length); - return ic.preedit.charCodeAt (p); - } - - MIM.Marker.prototype.Parser = function (domain, node) - { - var name = node.firstChild.nodeValue; - if (name.charAt (0) == '@') - { - var n = predefined[name]; - if (n) - return n; - if (name.charAt (1) == '-' || name.charAt (1) == '+') - return new MIM.SurroundMarker (name); - throw new Xex.ErrTerm (MIM.Error.ParseError, - "Invalid marker: " + name); - } - return new MIM.FloatingMarker (name);; - } -}) (); - -MIM.Selector = function (name) -{ - this.val = name; -} -MIM.Selector.prototype = new Xex.Term ('selector'); - -(function () { - var selectors = {}; - selectors["@<"] = selectors["@first"] = new MIM.Selector ('@<'); - selectors["@="] = selectors["@current"] = new MIM.Selector ('@='); - selectors["@>"] = selectors["@last"] = new MIM.Selector ('@>'); - selectors["@-"] = selectors["@previous"] = new MIM.Selector ('@-'); - selectors["@+"] = selectors["@next"] = 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 name = node.firstChild.nodeValue; - var s = selectors[name]; - if (! s) - throw new Xex.ErrTerm (MIM.Error.ParseError, - "Invalid selector: " + name); - return s; - } -}) (); - -MIM.Rule = function (keyseq, actions) -{ - this.keyseq = keyseq; - if (actions) - this.actions = actions; -} -MIM.Rule.prototype = new Xex.Term ('rule'); -MIM.Rule.prototype.Parser = function (domain, node) -{ - var n; - for (n = node.firstChild; n && n.nodeType != 1; n = n.nextSibling); - if (! n) - throw new Xex.ErrTerm (MIM.Error.ParseError, "invalid rule:" + node); - var keyseq = Xex.Term.Parse (domain, n); - if (keyseq.type != 'keyseq') - throw new Xex.ErrTerm (MIM.Error.ParseError, "invalid rule:" + node); - var actions = null; - n = n.nextElement (); - if (n) - actions = Xex.Term.Parse (domain, n, null); - return new MIM.Rule (keyseq, actions); -} -MIM.Rule.prototype.toString = function () -{ - return ''; -} - -MIM.Map = function (name) -{ - this.name = name; - this.rules = new Array (); -}; - -(function () { - var proto = new Xex.Term ('map'); - - proto.Parser = function (domain, node) - { - var name = node.attributes['mname'].nodeValue; - if (! name) - throw new Xex.ErrTerm (MIM.Error.ParseError, "invalid map"); - var map = new MIM.Map (name); - for (var n = node.firstChild; n; n = n.nextSibling) - if (n.nodeType == 1) - map.rules.push (Xex.Term.Parse (domain, n)); - return map; - } - - proto.toString = function () - { - var str = ''; - var len = this.rules.length; - for (i = 0; i < len; i++) - str += this.rules[i]; - return str + ''; - } - - MIM.Map.prototype = proto; -}) (); - -Xex.CatchTag._mimtag = new Xex.SymTerm ('@mimtag'); - -MIM.Action = function (domain, terms) -{ - var args = new Array (); - args.push (Xex.CatchTag_.mimtag); - for (var i = 0; i < terms.length; i++) - args.push (terms[i]); - this.action = Xex.Funcall.prototype.New (domain, 'catch', null, args); -} - -MIM.Action.prototype.Run = function (domain) -{ - var result = this.action.Eval (domain); - if (result.type == 'error') - { - domain.context.Error = result.toString (); - return false; - } - return (result != Xex.CatchTag._mimtag); -} - -MIM.Keymap = function () -{ - this.name = 'TOP'; - this.submaps = null; -}; - -(function () { - var proto = {}; - - function add_rule (keymap, rule, branch_actions) - { - var keyseq = rule.keyseq; - var len = keyseq.val.length; - var name = ''; - - for (var i = 0; i < len; i++) - { - var key = keyseq.val[i]; - var sub = false; - - name += key.key; - if (! keymap.submaps) - keymap.submaps = {}; - else - sub = keymap.submaps[key.key]; - if (! sub) - keymap.submaps[key.key] = sub = new MIM.Keymap (); - keymap = sub; - keymap.name = name; - } - keymap.map_actions = rule.actions; - if (branch_actions) - keymap.branch_actions = branch_actions; - } - - proto.Add = function (map, branch_actions) - { - var rules = map.rules; - var len = rules.length; - - for (var i = 0; i < len; i++) - add_rule (this, rules[i], branch_actions); - } - proto.Lookup = function (keys, index) - { - 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++; - return sub.Lookup (keys, index); - } - return { map: this, index: index }; - } - - MIM.Keymap.prototype = proto; -}) (); - -MIM.State = function (name) -{ - this.name = name; - this.keymap = new MIM.Keymap (); -}; - -(function () { - var proto = new Xex.Term ('state'); - - proto.Parser = function (domain, node) - { - var map_list = domain.map_list; - var name = node.attributes['sname'].nodeValue; - if (! name) - throw new Xex.ErrTerm (MIM.Error.ParseError, "invalid map"); - var state = new MIM.State (name); - for (node = node.firstElement (); node; node = node.nextElement ()) - { - if (node.nodeName == 'title') - state.title = node.firstChild.nodeValue; - else - { - var n = node.firstElement (); - var branch_actions = n ? Xex.Term.Parse (domain, n, null) : null; - if (node.nodeName == 'branch') - state.keymap.Add (map_list[node.attributes['mname'].nodeValue], - branch_actions); - else if (node.nodeName == 'state-hook') - state.enter_actions = branch_actions; - else if (node.nodeName == 'catch-all-branch') - state.fallback_actions = branch_actions; - } - } - return state; - } - - proto.toString = function () - { - return '' + this.keymap + ''; - } - - MIM.State.prototype = proto; -}) (); - -(function () { - function Block (index, term) - { - this.Index = index; - if (term.IsStr) - this.Data = term.val; - else if (term.IsList) - { - this.Data = new Array (); - for (var i = 0; i < term.val.length; i++) - this.Data.push (term.val[i].val); - } - } - - Block.prototype.Count = function () { return this.Data.length; } - Block.prototype.get = function (i) - { - return (this.Data instanceof Array ? this.Data[i] : this.Data.charAt (i)); - } - - MIM.Candidates = function (ic, candidates, column) - { - this.ic = ic; - this.column = column; - this.row = 0; - this.index = 0; - this.total = 0; - this.blocks = new Array (); - - for (var i = 0; i < candidates.length; i++) - { - var block = new Block (this.total, candidates[i]); - this.blocks.push (block); - this.total += block.Count (); - } - } - - function get_col () - { - return (this.column > 0 ? this.index % this.column - : this.index - this.blocks[this.row].Index); - } - - function prev_group () - { - var col = get_col.call (this); - var nitems; - if (this.column > 0) - { - this.index -= this.column; - if (this.index >= 0) - nitems = this.column; - else - { - var lastcol = (this.total - 1) % this.column; - this.index = (col < lastcol ? this.total - lastcol + col - : this.total - 1); - this.row = this.blocks.length - 1; - nitems = lastcol + 1; - } - while (this.blocks[this.row].Index > this.index) - this.row--; - } - else - { - this.row = this.row > 0 ? this.row - 1 : this.blocks.length - 1; - nitems = this.blocks[this.row].Count (); - this.index = (this.blocks[this.row].Index - + (col < nitems ? col : nitems - 1)); - } - return nitems; - } - - function next_group () - { - var col = get_col.call (this); - var nitems; - if (this.column > 0) - { - this.index += this.column - col; - if (this.index < this.total) - { - if (this.index + col >= this.total) - { - nitems = this.total - this.index; - this.index = this.total - 1; - } - else - { - nitems = this.column; - this.index += col; - } - } - else - { - this.index = col; - this.row = 0; - } - while (this.blocks[this.row].Index + this.blocks[this.row].Count () - <= this.index) - this.row++; - } - else - { - this.row = this.row < this.blocks.length - 1 ? this.row + 1 : 0; - nitems = this.blocks[this.row].Count (); - this.index = (this.blocks[this.row].Index - + (col < nitems ? col : nitems - 1)); - } - return nitems; - } - - function prev () - { - if (this.index == 0) - { - this.index = this.total - 1; - this.row = this.blocks.length - 1; - } - else - { - this.index--; - if (this.blocks[this.row].Index > this.index) - this.row--; - } - } - - function next () - { - this.index++; - if (this.index == this.total) - { - this.index = 0; - this.row = 0; - } - else - { - var b = this.blocks[this.row]; - if (this.index == b.Index + b.Count ()) - this.row++; - } - } - - function first () - { - this.index -= get_col.call (this); - while (this.blocks[this.row].Index > this.index) - this.row--; - } - - function last () - { - var b = this.blocks[this.row]; - if (this.column > 0) - { - if (this.index + 1 < this.total) - { - this.index += this.column - get_col.call (this) + 1; - while (b.Index + b.Count () <= this.index) - b = this.blocks[++this.row]; - } - } - else - this.index = b.Index + b.Count () - 1; - } - - MIM.Candidates.prototype.Current = function () - { - var b = this.blocks[this.row]; - return b.get (this.index - b.Index); - } - - MIM.Candidates.prototype.Select = function (selector) - { - var idx = this.index; - var gidx = this.column > 0 ? idx / this.column : this.row; - if (selector.type == 'selector') - { - switch (selector.val) - { - case '@<': first.call (this); break; - case '@>': last.call (this); break; - case '@-': prev.call (this); break; - case '@+': next.call (this); break; - case '@[': prev_group.call (this); break; - case '@]': next_group.call (this); break; - default: break; - } - } - else - { - var col, start, end - if (this.column > 0) - { - col = this.index % this.column; - start = this.index - col; - end = start + this.column; - } - else - { - start = this.blocks[this.row].Index; - col = this.index - start; - end = start + this.blocks[this.row].Count; - } - if (end > this.total) - end = this.total; - this.index += selector.val - col; - if (this.index >= end) - this.index = end - 1; - if (this.column > 0) - { - if (selector.val > col) - while (this.blocks[this.row].Index + this.blocks[this.row].Count - < this.index) - this.row++; - else - while (this.blocks[this.row].Index > this.index) - this.row--; - } - } - var newgidx = this.column > 0 ? this.index / this.column : this.row; - if (this.index != idx) - this.ic.changed |= (gidx == newgidx - ? MIM.ChangedStatus.CandidateIndex - : MIM.ChangedStatus.CandidateList); - return this.Current (); - } - - MIM.Candidates.prototype.CurrentCol = function () - { - return get_col.call (this); - } - - MIM.Candidates.prototype.CurrentGroup = function () - { - var col, start, end, gnum, gidx; - if (this.column > 0) - { - gnum = Math.floor ((this.total - 1) / this.column) + 1; - col = this.index % this.column; - start = this.index - col; - gidx = start / this.column + 1; - end = start + this.column; - if (end > this.total) - end = this.total; - } - else - { - gnum = this.blocks.length; - gidx = this.row + 1; - start = this.blocks[this.row].Index; - col = this.index - start; - end = start + this.blocks[this.row].Count (); - } - var group = new Array (); - var indices = new Array (gnum, gidx, col); - group.push (indices); - var row = this.row; - var block = this.blocks[row++]; - while (start < end) - { - var c = block.get (start - block.Index); - group.push (c); - start++; - if (start == block.Index + block.Count ()) - block = this.blocks[row++]; - } - return group; - } -}) (); - -MIM.im_domain = new Xex.Domain ('input-method', null, null); -MIM.im_domain.DefType (MIM.KeySeq.prototype); -MIM.im_domain.DefType (MIM.Marker.prototype); -MIM.im_domain.DefType (MIM.Selector.prototype); -MIM.im_domain.DefType (MIM.Rule.prototype); -MIM.im_domain.DefType (MIM.Map.prototype); -MIM.im_domain.DefType (MIM.State.prototype); - -(function () { - var im_domain = MIM.im_domain; - - function Finsert (domain, vari, args) - { - var text; - if (args[0].type == 'integer') - text = String.fromCharCode (args[0].val); - else - text = args[0].val; - domain.context.ins (text, null); - return args[0]; - } - - function Finsert_candidates (domain, vari, args) - { - var ic = domain.context; - var gsize = domain.variables['candidates-group-size']; - var candidates = new MIM.Candidates (ic, args, - gsize ? gsize.val.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); - return new Xex.IntTerm (ic.del (pos)); - } - - function Fselect (domain, vari, args) - { - var ic = domain.context; - var can = ic.candidates; - - if (can) - { - var old_text = can.Current (); - var new_text = can.Select (args[0]); - ic.rep (old_text, new_text, can); - } - else - Xex.Log ('no candidates at ' + ic.cursor_pos + ' of ' + ic.candidate_table.table.length); - 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)); - } - - function Fmove (domain, vari, args) - { - var ic = domain.context; - var pos = args[0].IsInt ? args[0].val : args[0].Position (ic); - ic.move (pos); - return new Xex.IntTerm (pos); - } - - function Fmark (domain, vari, args) - { - args[0].Mark (domain.context); - return args[0]; - } - - function Fpushback (domain, vari, args) - { - var a = (args[0].IsInt ? args[0].Intval () - : args[0].IsStr ? new KeySeq (args[0]) - : args[0]); - domain.context.pushback (a); - 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.val.length + n, -n); - else - ic.keys.val.splice (n, ic.keys.val.length); - ic.reset (); - return Xex.nil; - } - - function Fcommit (domain, vari, args) - { - domain.context.commit (); - return Xex.nil; - } - - function Funhandle (domain, vari, args) - { - domain.context.commit (); - return Xex.Fthrow (domain, vari, Xex.CatchTag._mimtag); - } - - function Fshift (domain, vari, args) - { - var ic = domain.context; - var state_name = args[0].val; - var state = ic.im.state_list[state_name]; - if (! state) - throw ("Unknown state: " + state_name); - ic.shift (state); - 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, "insert", false, 1, 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 (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 (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 (Fchar_at, "char-at", false, 1, 1); - im_domain.DefSubr (Fkey_count, "key-count", false, 0, 0); - im_domain.DefSubr (Fsurrounding_flag, "surrounding-text-flag", false, 0, 0); -}) (); - - -(function () { - function get_global_var (vname) - { - if (MIM.im_global.load_status == MIM.LoadStatus.NotLoaded) - MIM.im_global.Load () - return MIM.im_global.domain.variables[vname]; - } - - function include (node) - { - node = node.firstElement (); - if (node.nodeName != 'tags') - return null; - - var lang = null, name = null, extra = null; - for (node = node.firstElement (); node; node = node.nextElement ()) - { - if (node.nodeName == 'language') - lang = node.firstChild.nodeValue; - else if (node.nodeName == 'name') - name = node.firstChild.nodeValue; - else if (node.nodeName == 'extra-id') - extra = node.firstChild.nodeValue; - } - if (! lang || ! MIM.imlist[lang]) - return null; - if (! extra) - { - if (! name || ! (im = MIM.imlist[lang][name])) - return null; - } - else - { - if (! (im = MIM.imextra[lang][extra])) - return null; - } - if (im.load_status != MIM.LoadStatus.Loaded - && (im.load_status != MIM.LoadStatus.NotLoaded || ! im.Load ())) - return null; - return im; - } - - var parsers = { }; - - parsers['description'] = function (node) - { - this.description = node.firstChild.nodeValue; - } - parsers['variable-list'] = function (node) - { - for (node = node.firstElement (); node; node = node.nextElement ()) - { - var vname = node.attributes['vname'].nodeValue; - if (this != MIM.im_global) - { - var vari = get_global_var (vname); - if (vari != null) - this.domain.Defvar (vname, vari.desc, vari.val, vari.range); - } - vname = Xex.Term.Parse (this.domain, node) - } - } - parsers['command-list'] = function (node) - { - } - parsers['macro-list'] = function (node) - { - for (var n = node.firstElement (); n; n = n.nextElement ()) - if (n.nodeName == 'xi:include') - { - var im = include (n); - if (! im) - alert ('inclusion fail'); - else - for (var macro in im.domain.functions) - { - var func = im.domain.functions[macro]; - if (func instanceof Xex.Macro) - im.domain.CopyFunc (this.domain, macro); - } - n = n.previousSibling; - node.removeChild (n.nextSibling); - } - Xex.Term.Parse (this.domain, node.firstElement (), null); - } - parsers['title'] = function (node) - { - this.title = node.firstChild.nodeValue; - } - parsers['map-list'] = function (node) - { - for (node = node.firstElement (); node; node = node.nextElement ()) - { - if (node.nodeName == 'xi:include') - { - var im = include (node); - if (! im) - { - alert ('inclusion fail'); - continue; - } - for (var mname in im.map_list) - this.map_list[mname] = im.map_list[mname]; - } - else - { - var map = Xex.Term.Parse (this.domain, node); - this.map_list[map.name] = map; - } - } - } - parsers['state-list'] = function (node) - { - this.domain.map_list = this.map_list; - for (node = node.firstElement (); node; node = node.nextElement ()) - { - 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) - state.title = this.title; - if (! this.initial_state) - this.initial_state = state; - this.state_list[state.name] = state; - } - } - delete this.domain.map_list; - } - - MIM.IM = function (lang, name, extra_id, file) - { - this.lang = lang; - this.name = name; - this.extra_id = extra_id; - this.file = file; - this.load_status = MIM.LoadStatus.NotLoaded; - this.domain = new Xex.Domain (this.lang + '-' - + (this.name != 'nil' - ? this.name : this.extra_id), - MIM.im_domain, null); - } - - var proto = { - Load: function () - { - var node = Xex.Load (null, this.file); - if (! node) - { - this.load_status = MIM.LoadStatus.Error; - return false; - } - this.map_list = {}; - this.initial_state = null; - this.state_list = {}; - for (node = node.firstElement (); node; node = node.nextElement ()) - { - var name = node.nodeName; - var parser = parsers[name]; - if (parser) - parser.call (this, node); - } - this.load_status = MIM.LoadStatus.Loaded; - return true; - } - } - - MIM.IM.prototype = proto; - - MIM.IC = function (im, target) - { - if (im.load_status == MIM.LoadStatus.NotLoaded) - im.Load (); - if (im.load_status != MIM.LoadStatus.Loaded) - alert ('im:' + im.name + ' error:' + im.load_status); - this.im = im; - this.target = target; - this.domain = new Xex.Domain ('context', im.domain, this); - this.active = true; - this.range = new Array (); - this.range[0] = this.range[1] = 0; - this.state = null; - this.initial_state = this.im.initial_state; - this.keys = new MIM.KeySeq (); - this.marker_positions = new Array (); - this.candidate_table = new MIM.CandidateTable (); - this.reset (); - } - - MIM.CandidateTable = function () - { - this.table = new Array (); - } - - MIM.CandidateTable.prototype.get = function (pos) - { - for (var i = 0; i < this.table.length; i++) - { - var elt = this.table[i]; - if (elt.from < pos && pos <= elt.to) - return elt.val; - } - } - - MIM.CandidateTable.prototype.put = function (from, to, candidates) - { - for (var i = 0; i < this.table.length; i++) - { - var elt = this.table[i]; - if (elt.from < to && elt.to > from) - { - elt.from = from; - elt.to = to; - elt.val = candidates; - return; - } - } - this.table.push ({ from: from, to: to, val: candidates }); - } - - MIM.CandidateTable.prototype.adjust = function (from, to, inserted) - { - var diff = inserted - (to - from); - if (diff == 0) - return; - for (var i = 0; i < this.table.length; i++) - { - var elt = this.table[i]; - if (elt.from >= to) - { - elt.from += diff; - elt.to += diff; - } - } - } - - MIM.CandidateTable.prototype.clear = function () - { - this.table.length = 0; - } - - function set_cursor (prefix, pos) - { - this.cursor_pos = pos; - var candidates = this.candidate_table.get (pos); - if (this.candidates != candidates) - { - this.candidates = candidates; - this.changed |= MIM.ChangedStatus.CandidateList; - } - } - - function save_state () - { - this.state_var_values = this.domain.SaveValues (); - this.state_preedit = this.preedit; - this.state_key_head = this.key_head; - this.state_pos = this.cursor_pos; - } - - function restore_state () - { - this.domain.RestoreValues (this.state_var_values); - this.preedit = this.state_preedit; - set_cursor.call (this, "restore", this.state_pos); - } - - function handle_key () - { - 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; - - if (out.index > this.key_head) - { - this.key_head = out.index; - Xex.Log (' with submap', false, true); - restore_state.call (this); - this.keymap = sub; - if (sub.map_actions) - { - Xex.Log ('taking map actions:'); - if (! this.take_actions (sub.map_actions)) - return false; - } - else if (sub.submaps) - { - Xex.Log ('no map actions'); - for (var i = this.state_key_head; i < this.key_head; i++) - { - Xex.Log ('inserting key:' + this.keys.val[i].key); - this.ins (this.keys.val[i].key, null); - } - } - if (! sub.submaps) - { - Xex.Log ('terminal:'); - if (this.keymap.branch_actions) - { - Xex.Log ('branch actions:'); - if (! this.take_actions (this.keymap.branch_actions)) - return false; - } - if (sub != this.state.keymap) - this.shift (this.state); - } - } - else - { - Xex.Log (' without submap', false, true); - this.keymap = sub; - var current_state = this.state; - var map = this.keymap; - - if (map.branch_actions) - { - Xex.Log ('branch actions:'); - if (! this.take_actions (map.branch_actions)) - return false; - } - - if (map == this.keymap) - { - Xex.Log ('no state change'); - if (map == this.initial_state.keymap - && this.key_head < this.keys.val.length) - { - Xex.Log ('unhandled'); - return false; - } - if (this.keymap != current_state.keymap) - this.shift (current_state); - else if (this.keymap.actions == null) - this.shift (this.initial_state); - } - } - return true; - } - - proto = { - reset: function () - { - this.cursor_pos = 0; - this.candidate_show = false; - this.prev_state = null; - this.title = this.initial_state.title; - this.state_preedit = ''; - this.state_key_head = 0; - 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; - this.error_message = ''; - this.title = this.initial_state.title; - this.produced = ''; - this.preedit = ''; - this.preedit_saved = ''; - this.candidate_table.clear (); - this.candidates = null; - this.candidate_show = false; - for (var elt in this.marker_positions) - this.marker_positions[elt] = 0; - this.shift (this.initial_state); - }, - - catch_args: new Array (Xex.CatchTag._mimtag, null), - - take_actions: function (actions) - { - if (actions.length == 0) - return true;; - var func_progn = this.domain.GetFunc ('progn'); - var func_catch = this.domain.GetFunc ('catch'); - this.catch_args[1] = new Xex.Funcall (func_progn, null, actions); - var term = new Xex.Funcall (func_catch, null, this.catch_args); - term = term.Eval (this.domain); - return (! term.IsSymbol || term.val != '@mimtag'); - }, - - GetSurroundingChar: function (pos) - { - if (pos < 0) - { - pos += this.range[0]; - if (pos < 0) - return 0; - } - else - { - pos += this.range[1]; - if (pos >= this.target.value.length) - return 0; - } - return this.target.value.charCodeAt (pos); - }, - - DelSurroundText: function (pos) - { - var text; - if (pos < 0) - { - pos += this.range[0]; - if (pos <= 0) - { - pos = 0; text = ''; - } - else - text = this.target.value.substring (0, pos); - if (this.range[0] < this.target.value.length) - text += this.target.value.substring (this.range[0]); - this.target.value = text; - this.range[1] -= this.range[0] - pos; - this.range[0] = pos; - } - else - { - pos += this.range[1]; - text = this.target.value.substring (0, this.range[1]); - if (pos >= this.target.value.length) - pos = this.target.value.length; - else - text += this.target.value.substring (pos); - this.target.value = text; - } - }, - - adjust_markers: function (from, to, inserted) - { - var diff = inserted - (to - from); - - for (var name in this.marker_positions) - { - var pos = this.marker_positions[name]; - if (pos > from) - { - if (pos >= to) - this.marker_positions[name] += diff; - else if (pos > from) - this.marker_positions[name] = from; - } - } - }, - - preedit_replace: function (from, to, text, candidates) - { - var newlen = text.length; - this.preedit = (this.preedit.substring (0, from) - + text + this.preedit.substring (to)); - this.changed |= MIM.ChangedStatus.Preedit | MIM.ChangedStatus.CursorPos; - this.adjust_markers (from, to, newlen); - this.candidate_table.adjust (from, to, newlen); - if (candidates) - this.candidate_table.put (from, from + newlen, candidates) - if (this.cursor_pos >= to) - set_cursor.call (this, 'adjust', this.cursor_pos + text.length - (to - from)); - else if (this.cursor_pos > from) - set_cursor.call (this, 'adjust', from) - }, - - ins: function (text, candidates) - { - this.preedit_replace (this.cursor_pos, this.cursor_pos, text, candidates); - }, - - rep: function (old_text, new_text, candidates) - { - this.preedit_replace (this.cursor_pos - old_text.length, - this.cursor_pos, new_text, candidates); - }, - - del: function (pos) - { - var deleted = pos - this.cursor_pos; - if (pos < this.cursor_pos) - { - if (pos < 0) - { - this.DelSurroundText (pos); - deleted = - this.cursor_pos; - pos = 0; - } - if (pos < this.cursor_pos) - this.preedit_replace (pos, this.cursor_pos, '', null); - } - else - { - if (pos > this.preedit.length) - { - this.DelSurroundText (pos - this.preedit.length); - deleted = this.preedit.length - this.cursor_pos; - pos = this.preedit.length; - } - if (pos > this.cursor_pos) - this.preedit_replace (this.cursor_pos, pos, '', null); - } - return deleted; - }, - - show: function () - { - this.candidate_show = true; - this.changed |= MIM.ChangedStatus.CandidateShow; - }, - - hide: function () - { - this.candidate_show = false; - this.changed |= MIM.ChangedStatus.CandidateShow; - }, - - move: function (pos) - { - if (pos < 0) - pos = 0; - else if (pos > this.preedit.length) - pos = this.preedit.length; - if (pos != this.cursor_pos) - { - set_cursor.call (this, 'move', pos); - this.changed |= MIM.ChangedStatus.Preedit; - } - }, - - pushback: function (n) - { - if (n instanceof MIM.KeySeq) - { - if (this.key_head > 0) - this.key_head--; - if (this.key_head < this.keys.val.length) - this.keys.val.splice (this.key_head, - this.keys.val.length - this.key_head); - for (var i = 0; i < n.val.length; i++) - this.keys.val.push (n.val[i]); - return; - } - if (n > 0) - { - this.key_head -= n; - if (this.key_head < 0) - this.key_head = 0; - } - else if (n == 0) - this.key_head = 0; - else - { - this.key_head = - n; - if (this.key_head > this.keys.val.length) - this.key_head = this.keys.val.length; - } - }, - - pop: function () - { - if (this.key_head < this.keys.val.length) - this.keys.val.splice (this.key_head, 1); - }, - - commit: function () - { - if (this.preedit.length > 0) - { - 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; - } - }, - - shift: function (state) - { - if (state == null) - { - if (this.prev_state == null) - return; - state = this.prev_state; - } - - if (state == this.initial_state) - { - if (this.state) - { - this.commit (); - this.keys.val.splice (0, this.key_head); - this.key_head = this.state_key_head = this.commit_key_head = 0; - this.prev_state = null; - } - } - else - { - if (state != this.state) - this.prev_state = this.state; - } - if (state != this.state && state.enter_actions) - this.take_actions (state.enter_actions); - if (! this.state || this.state.title != state.title) - this.changed |= MIM.ChangedStatus.StateTitle; - this.state = state; - this.keymap = state.keymap; - save_state.call (this); - }, - - Filter: function (key) - { - if (! this.active) - { - Xex.Log ("active = false"); - this.key_unhandled = true; - this.unhandled_key = key; - return false; - } - if (key.key == '_reload') - return true; - this.changed = MIM.ChangedStatus.None; - this.produced = ''; - this.key_unhandled = false; - this.keys.val.push (key); - var count = 0; - while (this.key_head < this.keys.val.length) - { - if (! handle_key.call (this)) - { - if (this.key_head < this.keys.val.length) - { - 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; - } - if (++count == 10) - { - this.reset (); - this.key_unhandled = true; - 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; - } - if (this.changed & MIM.ChangedStatus.Candidate) - { - if (this.candidate_show && this.candidates) - MIM.show (this); - else - MIM.hide (this); - } - return (! this.key_unhandled - && this.produced.length == 0); - } - } - - MIM.IC.prototype = proto; - - var node = Xex.Load (null, "imlist.xml"); - for (node = node.firstChild; node; node = node.nextSibling) - if (node.nodeName == 'input-method') - { - var lang = null, name = null, extra_id = null, file = null; - - for (var n = node.firstChild; n; n = n.nextSibling) - { - if (n.nodeName == 'language') - lang = n.firstChild.nodeValue; - else if (n.nodeName == 'name') - name = n.firstChild.nodeValue; - else if (n.nodeName == 'extra-id') - extra_id = n.firstChild.nodeValue; - else if (n.nodeName == 'filename') - file = n.firstChild.nodeValue; - } - if (name && name != 'nil') - { - if (! MIM.imlist[lang]) - MIM.imlist[lang] = {}; - MIM.imlist[lang][name] = new MIM.IM (lang, name, extra_id, file); - } - else if (extra_id && extra_id != 'nil') - { - if (! MIM.imextra[lang]) - MIM.imextra[lang] = {}; - MIM.imextra[lang][extra_id] = new MIM.IM (lang, name, extra_id, file); - } - } - if (MIM.imextra.t && MIM.imextra.t.global) - MIM.im_global = MIM.imextra.t.global; - else - { - MIM.im_global = new MIM.IM ('t', 'nil', 'global', null); - MIM.im_global.load_status = MIM.LoadStatus.Error; - } - node = undefined; -}) (); - -(function () { - var keys = new Array (); - keys[0x09] = 'tab'; - keys[0x08] = 'backspace'; - keys[0x0D] = 'return'; - keys[0x1B] = 'escape'; - keys[0x20] = 'space'; - keys[0x21] = 'pageup'; - keys[0x22] = 'pagedown'; - keys[0x23] = 'end'; - keys[0x24] = 'home'; - keys[0x25] = 'left'; - keys[0x26] = 'up'; - keys[0x27] = 'right'; - keys[0x28] = 'down'; - keys[0x2D] = 'insert'; - keys[0x2E] = 'delete'; - for (var i = 1; i <= 12; i++) - keys[111 + i] = "f" + i; - 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.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 false; - 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 ; - } - else - key = String.fromCharCode (key); - } - if (event.altKey) key = "A-" + key ; - if (event.ctrlKey) key = "C-" + key ; - return new MIM.Key (key); - } -}) (); - -MIM.add_event_listener - = (window.addEventListener - ? function (target, type, listener) { - target.addEventListener (type, listener, false); - } - : window.attachEvent - ? function (target, type, listener) { - target.attachEvent ('on' + type, - function() { - listener.call (target, window.event); - }); - } - : function (target, type, listener) { - target['on' + type] - = function (e) { listener.call (target, e || window.event); }; - }); - -MIM.debug_print = function (event, ic) -{ - if (! MIM.debug) - return; - if (! MIM.debug_nodes) - { - MIM.debug_nodes = new Array (); - 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'); - MIM.debug_nodes['preedit1'] = document.getElementById ('preedit1'); - } - var target = event.target; - var code = event.keyCode; - 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 + '/' + event.keyIdentifier; - index = (event.type == 'keydown' ? '0' : '1'); - if (ic) - MIM.debug_nodes['status' + index].innerHTML = ic.im.load_status; - else - MIM.debug_nodes['status' + index].innerHTML = 'no IM'; - MIM.debug_nodes['keymap' + index].innerHTML = ic.state.name; - MIM.debug_nodes['preedit' + index].innerHTML = ic.preedit; - if (index == 0) - { - MIM.debug_nodes.keypress.innerHTML = ''; - MIM.debug_nodes.status1.innerHTML = ''; - MIM.debug_nodes.keymap1.innerHTML = ''; - MIM.debug_nodes.preedit1.innerHTML = '' - } -}; - -MIM.get_range = function (target, ic) -{ - var from, to; - if (target.selectionStart != null) // for Mozilla - { - from = target.selectionStart; - to = target.selectionEnd; - } - else // for IE - { - var r = document.selection.createRange (); - var rr = r.duplicate (); - - rr.moveToElementText (target); - rr.setEndPoint ('EndToEnd', range); - from = rr.text.length - r.text.length; - to = rr.text.length; - } - if (from == to - && from == ic.range[0] + ic.cursor_pos - && (ic.preedit.length == 0 - || ic.preedit == target.value.substring (ic.range[0], ic.range[1]))) - return true; - Xex.Log ('reset ic'); - ic.reset (); - ic.range[0] = from; - ic.range[1] = to; - return false; -}; - -(function () { - var temp; - - 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.get_preedit_pos = function (target, ic) - { - if (! temp) - { - temp = document.createElement ('div'); - temp.style.visibility = 'hidden'; - temp.style.position = 'absolute'; - temp.appendChild (document.createElement ('span')); - temp.appendChild (document.createElement ('span')); - document.getElementsByTagName ('body')[0].appendChild (temp); - } - if (temp.ic != ic) - { - temp.ic = ic; - copy_style (target, temp); - ic.abs_top = 0; - ic.abs_left = 0; - for (var elm = target.offsetParent; elm; elm = elm.offsetParent) - { - ic.abs_top += elm.offsetTop; - ic.abs_left += elm.offsetLeft; - } - } - temp.firstChild.innerText = target.value.substr (0, ic.range[0]); - temp.lastChild.innerText = "." + target.value.substr (ic.range[0], ic.range[1]); - ic.abs_y = (ic.abs_top + temp.lastChild.offsetTop - + temp.lastChild.offsetHeight - target.scrollTop); - ic.abs_x0 = ic.abs_left + temp.lastChild.offsetLeft; - ic.abs_x1 = ic.abs_x0 + temp.lastChild.offsetWidth; - } -}) (); - -MIM.set_caret = function (target, ic) -{ - if (ic.preedit.length > 0) - { - MIM.get_preedit_pos (target, ic); - if (! ic.bar) - { - ic.bar = document.createElement ('div'); - ic.bar.style.position = 'absolute'; - ic.bar.style.backgroundColor = "black"; - ic.bar.style.minHeight = '1px'; - document.getElementsByTagName ('body')[0].appendChild (ic.bar); - } - ic.bar.style.display = 'block' - ic.bar.style.top = (ic.abs_y + 1) + 'px'; - ic.bar.style.left = ic.abs_x0 + 'px'; - ic.bar.style.minWidth = (ic.abs_x1 - ic.abs_x0) + 'px'; - } - else if (ic.bar) - ic.bar.style.display = 'none' -}; - -MIM.update = function (target, ic, for_focus_out) -{ - var text = target.value; - target.value = (text.substring (0, ic.range[0]) - + ic.produced - + ic.preedit - + text.substring (ic.range[1])); - ic.range[0] += ic.produced.length; - ic.range[1] = ic.range[0] + ic.preedit.length; - MIM.set_caret (target, ic); - if (! for_focus_out) - { - var pos = ic.range[0] + ic.cursor_pos; - if (target.setSelectionRange) // Mozilla - { - var scrollTop = target.scrollTop; - target.setSelectionRange (pos, pos); - target.scrollTop = scrollTop; - } - else // IE - { - var range = target.createTextRange (); - range.moveStart ('character', pos); - range.moveEnd ('character', pos); - range.select (); - } - } -}; - -(function () { - MIM.show = function (ic) - { - if (! ic.candidates) - return; - var target = ic.target; - MIM.get_preedit_pos (target, ic); - if (! ic.can_node) - { - ic.can_node = document.createElement ('table'); - ic.can_node.style.position = 'absolute'; - ic.can_node.style.display = 'none'; - ic.can_node.style.backgroundColor = "white"; - ic.can_node.style.border = "1px solid black"; - document.getElementsByTagName ('body')[0].appendChild (ic.can_node); - } - - if (ic.changed & MIM.ChangedStatus.CandidateList) - { - while (ic.can_node.childNodes.length > 0) - ic.can_node.removeChild (ic.can_node.firstChild); - var tr = document.createElement ('tr'); - var group = ic.candidates.CurrentGroup (); - var td = document.createElement ('td'); - td.innerHTML = group[0][1] + '/' + group[0][0]; - td.style.color = 'white'; - td.style.backgroundColor = 'black'; - tr.appendChild (td); - for (var i = 1; i < group.length; i++) - { - var td = document.createElement ('td'); - td.noWrap = true; - td.innerHTML = (i < 10 ? i : i == 10 ? '0' : String.fromCharCode (0x60 + (i - 10))) + '.' + group[i]; - if (i == group[0][2] + 1) - td.style.backgroundColor = 'lightblue'; - tr.appendChild (td); - } - ic.can_node.appendChild (tr); - ic.can_node.style.top = (ic.abs_y + 10) + 'px'; - ic.can_node.style.left = ic.abs_x0 + 'px'; - } - else - { - var td = ic.can_node.firstElement ().firstElement ().nextElement (); - var col = ic.candidates.CurrentCol (); - for (var i = 0; td; td = td.nextElement ()) - td.style.backgroundColor = (i++ == col ? 'lightblue' : 'white'); - } - ic.can_node.style.display = 'block'; - } - - MIM.hide = function (ic) - { - if (ic.can_node) - ic.can_node.style.display = 'none'; - } -}) (); - -MIM.focus_in = function (event) -{ - var target = event.target; - var ic = target.mim_ic; - Xex.Log ("Focus in " + target.tagName); - MIM.get_range (target, ic) - ic.Filter (MIM.Key.FocusIn); - setTimeout (function () { MIM.update (target, ic, false); }, 100); - return true; -} - -MIM.focus_out = function (event) -{ - var target = event.target; - var ic = target.mim_ic; - Xex.Log ("Focus out " + target.tagName); - ic.Filter (MIM.Key.FocusOut); - MIM.update (target, ic, true); - return true; -}; - -MIM.keydown = function (event) -{ - var target = event.target; - if (! (target.type == "text" || target.type == "textarea")) - return; - - var ic = target.mim_ic; - if (! ic || ic.im != MIM.current) - { - target.mim_ic = null; - Xex.Log ('creating IC'); - ic = new MIM.IC (MIM.current, target); - if (ic.im.load_status != MIM.LoadStatus.Loaded) - return true; - target.mim_ic = ic; - MIM.add_event_listener (target, 'focus', MIM.focus_in); - MIM.add_event_listener (target, 'blur', MIM.focus_out); - } - MIM.get_range (target, ic) - MIM.debug_print (event, ic); - ic.key = MIM.decode_key_event (event); - if (ic.key) - { - try { - var result = ic.Filter (ic.key); - } catch (e) { - Xex.Log ('Error' + e); - throw (e); - } - MIM.update (target, ic, false); - if (! ic.key_unhandled) - event.preventDefault (); - } -}; - -MIM.keypress = function (event) -{ - var target = event.target; - if (! (target.type == "text" || target.type == "textarea")) - return; - - var ic = target.mim_ic; - var i; - - try { - if (ic.im.load_status != MIM.LoadStatus.Loaded) - return; - if (! ic.key) - ic.key = MIM.decode_key_event (event); - if (! ic.key) - { - ic.reset (); - return; - } - - try { - var result = ic.Filter (ic.key); - } catch (e) { - Xex.Log ('Error:' + e); - throw (e); - } - MIM.update (target, ic, false); - if (! ic.key_unhandled) - event.preventDefault (); - } catch (e) { - Xex.Log ("error:" + e); - event.preventDefault (); - } finally { - MIM.debug_print (event, ic); - } - - return; -}; - -(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' }, - 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 = {}; - for (name in MIM.imlist[lang]) - list[name] = MIM.imlist[lang][name]; - } - if (! list) - for (name in MIM.imlist[lang]) - Xex.Log ('no category ' + lang + '-' + name); - } - } - - var destroy_timer; - var last_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); - } - } - - function destroy_menu () { - if (! destroy_timer) - destroy_timer = setTimeout (destroy, 1000); - return true; - } - - function show_submenu (event) - { - var target = event.target; - if (! target.menu_level) - { - if (! target.parentNode || ! target.parentNode.menu_level) - return true; - target = target.parentNode; - } - if (destroy_timer) - { - clearTimeout (destroy_timer); - destroy_timer = null; - } - if (last_target && target.parentLi != last_target) - { - last_target.style.backgroundColor = 'white'; - if (target.menu_level < last_target.menu_level) - { - last_target = last_target.parentLi; - last_target.style.backgroundColor = 'white'; - } - 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) - { - if (! target.parentNode || ! target.parentNode.menu_level) - { - event.preventDefault (); - return false; - } - target = target.parentNode; - } - 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; - var nobr = document.createElement ('nobr'); - nobr.innerHTML = text; - li.appendChild (nobr); - return li; - } - - var menu; - - 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.onmousedown = select_im; - menu.onmouseover = show_submenu; - menu.onmouseout = destroy_menu; - for (var catname in lang_category) - { - var cat = lang_category[catname]; - var li = create_li (1, catname); - var sub = create_ul ('hidden'); - for (var langname in cat) - { - 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.appendChild (sub); - menu.appendChild (li); - } - 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['zh']['py-gb']; - }; -}) (); - -MIM.test = function () -{ - var im = MIM.imlist['t']['latn-post']; - var ic = new MIM.IC (im, null); - - ic.Filter (new MIM.Key ('a')); - ic.Filter (new MIM.Key ("'")); - - if (true) - document.getElementById ('text').value = ic.produced + ic.preedit; - else { - try { - document.getElementById ('text').value - = Xex.Term.Parse (domain, body).Eval (domain).toString (); - } catch (e) { - if (e instanceof Xex.ErrTerm) - alert (e); - throw e; - } - } -} - - -MIM.init_debug = function () -{ - MIM.debug = true; - Xex.LogNode = document.getElementById ('xexlog'); - Xex.Log (null); - MIM.init (); -};