X-Git-Url: http://git.chise.org/gitweb/?a=blobdiff_plain;f=xex.js;h=46d510fb983f1b53a16bde280ea016620f5a18ee;hb=155d360b5274f5c9ec1e85a846ebdaf1f621bd9f;hp=e97c17edbfa6ef220fba125e0efb47a98a7904e4;hpb=983c711cb17bf83071915faabaff92698ff1e0e2;p=m17n%2Fm17n-lib-js.git diff --git a/xex.js b/xex.js index e97c17e..46d510f 100644 --- a/xex.js +++ b/xex.js @@ -2,19 +2,31 @@ var Xex = { LogNode: null, - Log: function (arg, indent) + LogNodeLen: 0, + Log: function (arg, indent, cont) { if (! Xex.LogNode) return; if (! arg) - Xex.LogNode.value = ''; + { + while (Xex.LogNode.childNodes.length > 0) + Xex.LogNode.removeChild (Xex.LogNode.firstChild); + LogNodeLen = 0; + } else { - var str = ''; + var node; + LogNodeLen++; + if (LogNodeLen >= 200) + node = Xex.LogNode.firstElement (); + else + node = document.createElement ('div'); if (indent != undefined) - for (var i = 0; i <= indent; i++) - str += ' '; - Xex.LogNode.value += "\n" + str + arg; + 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; } } @@ -471,7 +483,7 @@ Node.prototype.nextElement = function () if (! name) throw new Xex.ErrTerm (Xex.Error.NoVariableName, node, ''); var vari = domain.variables[name]; - var desc, val, range; + var desc, val = null, range; if (vari) { desc = vari.description; @@ -519,7 +531,7 @@ Node.prototype.nextElement = function () range.push (pval); } } - if (! val) + if (val == null) val = Xex.Zero; domain.Defvar (name, desc, val, range); return name; @@ -685,8 +697,7 @@ Xex.Funcall = function (func, vname, args) proto.Eval = function (domain) { - if (! (this.func instanceof Xex.Subrountine)) - Xex.Log (this, domain.depth); + Xex.Log (this, domain.depth); var vari; if (this.vname) vari = domain.GetVarCreate (this.vname); @@ -695,7 +706,8 @@ Xex.Funcall = function (func, vname, args) try { result = this.func.Call (domain, vari, this.args); } finally { - Xex.Log (this + ' => ' + result, --domain.depth); + Xex.Log (' => ' + result, --domain.depth, + this.func instanceof Xex.Subrountine); } return result; } @@ -718,8 +730,8 @@ Xex.Funcall = function (func, vname, args) var arglist = '' var len = this.args.length; var str = '<' + this.func.name; - if (this.vari) - str += ' vname="' + this.vari.name + '"'; + if (this.vname) + str += ' vname="' + this.vname + '"'; if (len == 0) return str + '/>'; if (this.func instanceof Xex.Subrountine) @@ -1605,10 +1617,8 @@ MIM.Selector.prototype = new Xex.Term ('selector'); 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) { @@ -1624,7 +1634,8 @@ MIM.Selector.prototype = new Xex.Term ('selector'); MIM.Rule = function (keyseq, actions) { this.keyseq = keyseq; - this.actions = actions; + if (actions) + this.actions = actions; } MIM.Rule.prototype = new Xex.Term ('rule'); MIM.Rule.prototype.Parser = function (domain, node) @@ -1636,7 +1647,10 @@ MIM.Rule.prototype.Parser = function (domain, node) var keyseq = Xex.Term.Parse (domain, n); if (keyseq.type != 'keyseq') throw new Xex.ErrTerm (MIM.Error.ParseError, "invalid rule:" + node); - var actions = Xex.Term.Parse (domain, n.nextElement (), null); + 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 () @@ -1730,7 +1744,8 @@ MIM.Keymap = function () keymap.name = name; } keymap.map_actions = rule.actions; - keymap.branch_actions = branch_actions; + if (branch_actions) + keymap.branch_actions = branch_actions; } proto.Add = function (map, branch_actions) @@ -1787,13 +1802,14 @@ MIM.State = function (name) 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], - Xex.Term.Parse (domain, n, null)); + branch_actions); else if (node.nodeName == 'state-hook') - state.enter_actions = Xex.Term.Parse (domain, n, null); + state.enter_actions = branch_actions; else if (node.nodeName == 'catch-all-branch') - state.fallback_actions = Xex.Term.Parse (domain, n, null); + state.fallback_actions = branch_actions; } } return state; @@ -1827,8 +1843,9 @@ MIM.State = function (name) return (this.Data instanceof Array ? this.Data[i] : this.Data.charAt (i)); } - MIM.Candidates = function (candidates, column) + MIM.Candidates = function (ic, candidates, column) { + this.ic = ic; this.column = column; this.row = 0; this.index = 0; @@ -1904,7 +1921,8 @@ MIM.State = function (name) this.index = col; this.row = 0; } - while (this.blocks[this.row].Index > this.index) + while (this.blocks[this.row].Index + this.blocks[this.row].Count () + <= this.index) this.row++; } else @@ -1979,6 +1997,8 @@ MIM.State = function (name) 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) @@ -1988,40 +2008,89 @@ MIM.State = function (name) case '@-': prev.call (this); break; case '@+': next.call (this); break; case '@[': prev_group.call (this); break; - case '@]': next_group.cal (this); break; + case '@]': next_group.call (this); break; default: break; } - return this.Current (); } - var col, start, end + 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; + 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) + 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) { - 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 c = block.get (start - block.Index); + group.push (c); + start++; + if (start == block.Index + block.Count ()) + block = this.blocks[row++]; } - return this.Current (); + return group; } }) (); @@ -2050,8 +2119,9 @@ MIM.im_domain.DefType (MIM.State.prototype); function Finsert_candidates (domain, vari, args) { var ic = domain.context; - var gsize = domain.variables['candidates_group_size']; - var candidates = new MIM.Candidates (args, gsize ? gsize.Intval () : 0); + 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]; } @@ -2259,7 +2329,7 @@ MIM.im_domain.DefType (MIM.State.prototype); { var vari = get_global_var (vname); if (vari != null) - this.domain.Defvar (vname); + this.domain.Defvar (vname, vari.desc, vari.val, vari.range); } vname = Xex.Term.Parse (this.domain, node) } @@ -2455,20 +2525,15 @@ MIM.im_domain.DefType (MIM.State.prototype); this.table.length = 0; } - function detach_candidates (ic) - { - ic.candidate_table.clear (); - ic.candidates = null; - ic.changed |= (MIM.ChangedStatus.Preedit | MIM.ChangedStatus.CursorPos - | MIM.ChangedStatus.CandidateList - | MIM.ChangedStatus.CandidateIndex - | MIM.ChangedStatus.CandidateShow); - } - function set_cursor (prefix, pos) { this.cursor_pos = pos; - this.candidates = this.candidate_table.get (pos); + var candidates = this.candidate_table.get (pos); + if (this.candidates != candidates) + { + this.candidates = candidates; + this.changed |= MIM.ChangedStatus.CandidateList; + } } function save_state () @@ -2498,7 +2563,7 @@ MIM.im_domain.DefType (MIM.State.prototype); if (out.index > this.key_head) { this.key_head = out.index; - Xex.Log (' with submap for ' + this.key_head + 'keys'); + Xex.Log (' with submap', false, true); restore_state.call (this); this.keymap = sub; if (sub.map_actions) @@ -2519,7 +2584,7 @@ MIM.im_domain.DefType (MIM.State.prototype); if (! sub.submaps) { Xex.Log ('terminal:'); - if (this.keymap.branch_actions != null) + if (this.keymap.branch_actions) { Xex.Log ('branch actions:'); if (! this.take_actions (this.keymap.branch_actions)) @@ -2531,14 +2596,14 @@ MIM.im_domain.DefType (MIM.State.prototype); } else { - Xex.Log (' without submap'); + 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'); + Xex.Log ('branch actions:'); if (! this.take_actions (map.branch_actions)) return false; } @@ -2594,6 +2659,8 @@ MIM.im_domain.DefType (MIM.State.prototype); 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); @@ -2664,33 +2731,33 @@ MIM.im_domain.DefType (MIM.State.prototype); this.marker_positions[name] = from; } } - if (this.cursor_pos >= to) - set_cursor.call (this, 'adjust', this.cursor_pos + diff); - else if (this.cursor_pos > from) - set_cursor.call (this, 'adjust', 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.adjust_markers (from, to, text.length); - this.candidate_table.adjust (from, to, text.length); + 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 + text.length, 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); - this.changed = MIM.ChangedStatus.Preedit | MIM.ChangedStatus.CursorPos; }, rep: function (old_text, new_text, candidates) { this.preedit_replace (this.cursor_pos - old_text.length, this.cursor_pos, new_text, candidates); - this.changed = MIM.ChangedStatus.Preedit | MIM.ChangedStatus.CursorPos; }, del: function (pos) @@ -2718,8 +2785,6 @@ MIM.im_domain.DefType (MIM.State.prototype); if (pos > this.cursor_pos) this.preedit_replace (this.cursor_pos, pos, '', null); } - if (deleted != 0) - this.changed = MIM.ChangedStatus.Preedit | MIM.ChangedStatus.CursorPos; return deleted; }, @@ -2775,7 +2840,6 @@ MIM.im_domain.DefType (MIM.State.prototype); 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 () @@ -2812,7 +2876,7 @@ MIM.im_domain.DefType (MIM.State.prototype); { 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; } } @@ -2834,6 +2898,7 @@ MIM.im_domain.DefType (MIM.State.prototype); { if (! this.active) { + Xex.Log ("active = false"); this.key_unhandled = true; this.unhandled_key = key; return false; @@ -2875,17 +2940,7 @@ MIM.im_domain.DefType (MIM.State.prototype); { this.keys.val.splice (0, this.commit_key_head); this.key_head -= this.commit_key_head; - if (this.key_head < 0) - { - Xex.Log ('RECOVER key_head'); - this.key_head = 0; - } this.state_key_head -= this.commit_key_head; - if (this.state_key_head < 0) - { - Xex.Log ('RECOVER state_key_head'); - this.state_key_head = 0; - } this.commit_key_head = 0; } if (this.key_unhandled) @@ -2894,6 +2949,13 @@ MIM.im_domain.DefType (MIM.State.prototype); //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); } @@ -2964,12 +3026,12 @@ MIM.im_domain.DefType (MIM.State.prototype); 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'; + 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; @@ -2999,8 +3061,8 @@ MIM.im_domain.DefType (MIM.State.prototype); return false; key = String.fromCharCode (parseInt (RegExp.$1, 16)); } - else - key = key.toLowerCase (); + //else + //key = key.toLowerCase (); if (event.shiftKey) mod += 'S-'; return new MIM.Key (mod + key); } @@ -3101,34 +3163,108 @@ MIM.get_range = function (target, ic) from = rr.text.length - r.text.length; to = rr.text.length; } - if (ic.range[0] == from && ic.range[1] == to - && (to == from || target.value.substring (from, to) == ic.preedit)) + 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 (target.setSelectionRange) // Mozilla - { - var scrollTop = target.scrollTop; - target.setSelectionRange (ic.range[0], ic.range[1]); - target.scrollTop = scrollTop; - } - else // IE + if (ic.preedit.length > 0) { - var range = target.createTextRange (); - range.moveStart ('character', ic.range[0]); - range.moveEnd ('character', ic.range[1]); - range.select (); + 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.ignore_focus = false; - -MIM.update = function (target, ic) +MIM.update = function (target, ic, for_focus_out) { var text = target.value; target.value = (text.substring (0, ic.range[0]) @@ -3138,67 +3274,109 @@ MIM.update = function (target, ic) 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); - target.removeEventListener (''); - setTimeout (MIM.update (target, ic); - // Ignore further focus-in caused by setSelectionRange (). - target.mim_ignore_focus_in = true; - } - } -} - -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; - } + setTimeout (function () { MIM.update (target, ic, false); }, 100); + return true; } 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); - } - } + 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.id == 'log') - return; if (! (target.type == "text" || target.type == "textarea")) return; - document.akey = event; var ic = target.mim_ic; if (! ic || ic.im != MIM.current) @@ -3207,29 +3385,23 @@ MIM.keydown = function (event) Xex.Log ('creating IC'); ic = new MIM.IC (MIM.current, target); if (ic.im.load_status != MIM.LoadStatus.Loaded) - return; + 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) - } - else - { - if (! MIM.get_range (target, ic)) - ic.reset (); } + MIM.get_range (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); } catch (e) { Xex.Log ('Error' + e); throw (e); } - MIM.update (target, ic); + MIM.update (target, ic, false); if (! ic.key_unhandled) event.preventDefault (); } @@ -3238,8 +3410,6 @@ MIM.keydown = function (event) MIM.keypress = function (event) { var target = event.target; - if (target.id == 'log') - return; if (! (target.type == "text" || target.type == "textarea")) return; @@ -3257,14 +3427,13 @@ MIM.keypress = function (event) return; } - Xex.Log ("filtering " + ic.key); try { var result = ic.Filter (ic.key); } catch (e) { Xex.Log ('Error:' + e); throw (e); } - MIM.update (target, ic); + MIM.update (target, ic, false); if (! ic.key_unhandled) event.preventDefault (); } catch (e) { @@ -3273,6 +3442,7 @@ MIM.keypress = function (event) } finally { MIM.debug_print (event, ic); } + return; }; @@ -3294,7 +3464,6 @@ MIM.keypress = function (event) sk: { name: 'Slovak' }, sr: { name: 'Serbian' }, sv: { name: 'Swedish' }, - vi: { name: 'Vietnamese' }, yi: { name: 'Yiddish' } }, MiddleEast: { ar: { name: 'Arabic' }, @@ -3361,12 +3530,10 @@ MIM.keypress = function (event) 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); } @@ -3395,18 +3562,23 @@ MIM.keypress = function (event) 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; } - var target = event.target; - if (! target.menu_level) - return; if (last_target && target.parentLi != last_target) { last_target.style.backgroundColor = 'white'; @@ -3432,6 +3604,15 @@ MIM.keypress = function (event) 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; @@ -3464,7 +3645,9 @@ MIM.keypress = function (event) 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; } @@ -3484,7 +3667,7 @@ MIM.keypress = function (event) menu.style.fontFamily = 'sans-serif'; menu.style.fontWeight = 'bold'; menu.id = 'mim-menu'; - menu.onclick = select_im; + menu.onmousedown = select_im; menu.onmouseover = show_submenu; menu.onmouseout = destroy_menu; for (var catname in lang_category) @@ -3514,7 +3697,6 @@ MIM.keypress = function (event) li.appendChild (sub); menu.appendChild (li); } - document.mimmenu = menu; lang_category = null; } menu.style.left = (event.clientX - 10) + "px"; @@ -3529,7 +3711,7 @@ MIM.keypress = function (event) 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']['tonepy']; + MIM.current = MIM.imlist['zh']['py-gb']; }; }) (); @@ -3559,7 +3741,7 @@ MIM.test = function () MIM.init_debug = function () { MIM.debug = true; - Xex.LogNode = document.getElementById ('log'); + Xex.LogNode = document.getElementById ('xexlog'); Xex.Log (null); MIM.init (); };