X-Git-Url: http://git.chise.org/gitweb/?p=m17n%2Fm17n-lib-js.git;a=blobdiff_plain;f=xex.js;h=4f567b07a32cb0dfeaa83f02e39299e670c2b1c3;hp=542e94de70f8c6e5bac754fe09402c3644e5faa7;hb=5f52f0727ea07f445b9fa556ca0fbef034adb541;hpb=a4d2683fd40c0a21a1dad228da5f09e78d659196 diff --git a/xex.js b/xex.js index 542e94d..4f567b0 100644 --- a/xex.js +++ b/xex.js @@ -2,23 +2,22 @@ var Xex = { LogNode: null, - LogSuspended: '', - Log: function (arg, indent, suspend) + Log: function (arg, indent, cont) { if (! Xex.LogNode) return; if (! arg) Xex.LogNode.value = ''; - else if (suspend) - Xex.LogSuspended += arg; else { - var str = Xex.LogSuspended; - Xex.LogSuspended = ''; + var str = ''; if (indent != undefined) for (var i = 0; i <= indent; i++) str += ' '; - Xex.LogNode.value = str + arg + "\n" + Xex.LogNode.value; + if (! cont) + Xex.LogNode.value += "\n"; + Xex.LogNode.value += str + arg; + Xex.LogNode.scrollTop = Xex.LogNode.scrollHeight; } } }; @@ -1395,7 +1394,6 @@ var MIM = { MIM.Key = function (val) { this.key; - this.has_modifier = false; if (val instanceof Xex.Term) this.key = val.val; else if (typeof val == 'string' || val instanceof String) @@ -1426,7 +1424,6 @@ var MIM = { MIM.KeySeq = function (seq) { this.val = new Array (); - this.has_modifier = false; if (seq) { @@ -1610,10 +1607,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) { @@ -1751,6 +1746,13 @@ MIM.Keymap = function () 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++; @@ -2021,6 +2023,38 @@ MIM.State = function (name) } return this.Current (); } + + MIM.Candidates.prototype.CurrentGroup = function (selector) + { + var col, start, end + if (this.column > 0) + { + col = this.index % this.column; + start = this.index - col; + end = start + this.column; + if (end > this.total) + end = this.total; + } + else + { + start = this.blocks[this.row].Index; + col = this.index - start; + end = start + this.blocks[this.row].Count (); + } + var group = new Array (); + group.push (col); + 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); @@ -2486,24 +2520,26 @@ MIM.im_domain.DefType (MIM.State.prototype); function handle_key () { - var out = this.keymap.Lookup (this.keys, this.key_head); + Xex.Log ('Key(' + this.key_head + ') "' + this.keys.val[this.key_head] + + '" in ' + this.state.name + ':' + this.keymap.name + + " key/state/commit-head/len:" + + this.key_head + '/' + this.state_key_head + '/' + this.commit_key_head + '/' + this.keys.val.length); + var out = this.state.keymap.Lookup (this.keys, this.state_key_head); var sub = out.map; - Xex.Log ('handling ' + this.keys.val[this.key_head] - + ' in ' + this.state.name + ':' + this.keymap.name, 0, true); - this.key_head = out.index; - if (sub != this.keymap) + if (out.index > this.key_head) { - Xex.Log (' with submap'); + this.key_head = out.index; + Xex.Log (' with submap for ' + this.key_head + 'keys', false, true); restore_state.call (this); this.keymap = sub; - if (this.keymap.map_actions) + if (sub.map_actions) { Xex.Log ('taking map actions:'); - if (! this.take_actions (this.keymap.map_actions)) + if (! this.take_actions (sub.map_actions)) return false; } - else if (this.keymap.submaps) + else if (sub.submaps) { Xex.Log ('no map actions'); for (var i = this.state_key_head; i < this.key_head; i++) @@ -2512,7 +2548,7 @@ MIM.im_domain.DefType (MIM.State.prototype); this.ins (this.keys.val[i].key, null); } } - if (! this.keymap.submaps) + if (! sub.submaps) { Xex.Log ('terminal:'); if (this.keymap.branch_actions != null) @@ -2521,13 +2557,14 @@ MIM.im_domain.DefType (MIM.State.prototype); if (! this.take_actions (this.keymap.branch_actions)) return false; } - if (this.keymap != this.state.keymap) + if (sub != this.state.keymap) this.shift (this.state); } } else { - Xex.Log (' without submap'); + Xex.Log (' without submap', false, true); + this.keymap = sub; var current_state = this.state; var map = this.keymap; @@ -2679,6 +2716,7 @@ MIM.im_domain.DefType (MIM.State.prototype); { this.preedit_replace (this.cursor_pos, this.cursor_pos, text, candidates); this.changed = MIM.ChangedStatus.Preedit | MIM.ChangedStatus.CursorPos; + this.candidates = candidates; }, rep: function (old_text, new_text, candidates) @@ -2770,6 +2808,7 @@ 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 () @@ -2806,7 +2845,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; } } @@ -2821,7 +2860,6 @@ MIM.im_domain.DefType (MIM.State.prototype); this.changed |= MIM.ChangedStatus.StateTitle; this.state = state; this.keymap = state.keymap; - this.state_key_head = this.key_head; save_state.call (this); }, @@ -2829,6 +2867,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; @@ -2876,8 +2915,17 @@ MIM.im_domain.DefType (MIM.State.prototype); 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; } + MIM.show (this); + if (false && (this.changed & MIM.ChangedStatus.Candidate)) + { + if (this.candidate_show) + MIM.show (this); + else + MIM.hide (this); + } return (! this.key_unhandled && this.produced.length == 0); } @@ -3110,8 +3158,6 @@ MIM.set_caret = function (target, ic) } }; -MIM.ignore_focus = false; - MIM.update = function (target, ic) { var text = target.value; @@ -3124,69 +3170,126 @@ MIM.update = function (target, ic) MIM.set_caret (target, ic); }; +(function () { + var style_props = { + width: 'width', + height: 'height', + padingLeft: 'padding-left', + paddingRight: 'padding-right', + paddingTop: 'padding-top', + paddintBottom: 'padding-bottom', + borderLeftStyle: 'border-left-style', + borderRightStyle: 'border-right-style', + borderTopStyle: 'border-top-style', + borderBottomStyle: 'border-bottom-style', + borderLeftWidth: 'border-left-width', + borderRightWidth: 'border-right-width', + borderTopWidth: 'border-top-width', + borderBottomWidth: 'border-bottom-width', + fontFamily: 'font-family', + fontSize: 'font-size', + lineHeight: 'line-height', + letterSpacing: 'letter-spacing', + wordSpacing: 'word-spacing' }; + + function copy_style (from, to) + { + var from_style = getComputedStyle(from,''); + for(var name in style_props) + to.style[name] = from_style.getPropertyValue (style_props[name]); + to.style.left = from.offsetLeft + 'px'; + to.style.top = from.offsetTop + 'px'; + to.style.width = from.offsetWidth; + to.style.height = from.offsetHeight; + } + + MIM.show = function (ic) + { + Xex.Log ('show:' + ic.candidates); + if (! ic.candidates) + return; + var target = ic.target; + if (! ic.div_node) + { + ic.target_top = 0; + ic.target_left = 0; + for (var elm = ic.target.offsetParent; elm; elm = elm.offsetParent) + { + ic.target_top += elm.offsetTop; + ic.target_left += elm.offsetLeft; + } + ic.div_node = document.createElement ('div'); + copy_style (target, ic.div_node); + ic.div_node.style.visibility="hidden"; + ic.div_node.style.position = "absolute"; + document.getElementsByTagName ('body')[0].appendChild (ic.div_node); + ic.div_node_first = document.createElement ('span'); + ic.div_node_last = document.createElement('span'); + ic.div_node_last.innerHTML = '.'; + ic.div_node.appendChild (ic.div_node_first); + ic.div_node.appendChild (ic.div_node_last); + 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); + } + + ic.can_node.innerHTML = ''; + var tr = document.createElement ('tr'); + ic.can_node.appendChild (tr); + var group = ic.candidates.CurrentGroup (); + for (var i = 1; i < group.length; i++) + { + var td = document.createElement ('td'); + td.nowrap = true; + td.innerHTML = i + '.' + group[i]; + if (i == group[0] + 1) + td.style.backgroundColor = 'lightblue'; + ic.can_node.appendChild (td); + } + ic.div_node_first.innerHTML = target.value.substr (0, ic.range[0]); + var x = ic.target_left + ic.div_node.lastChild.offsetLeft; + var y = (ic.target_top + ic.div_node.lastChild.offsetTop + + ic.div_node.lastChild.offsetHeight - target.scrollTop + 10); + ic.can_node.style.left = x + 'px'; + ic.can_node.style.top = y + 'px'; + ic.can_node.style.display = 'block'; + } +}) (); + MIM.focus_in = function (event) { var target = event.target; var ic = target.mim_ic; - if (ic) - { - 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) + if (ic.wait_update == true) { - MIM.focus_ignore_target.mim_ignore_focus_in = false; - MIM.focus_ignore_target.mim_ignore_focus_out = false; + Xex.Log ("Focus in " + target.tagName + ' IGNORED'); + event.preventDefault (); + return false; } + Xex.Log ("Focus in " + target.tagName); + ic.Filter (MIM.Key.FocusIn); + MIM.update (target, ic); } MIM.focus_out = function (event) { var target = event.target; var ic = target.mim_ic; - if (ic) + function reset_update () { ic.wait_update = false; }; + if (ic.wait_update == true) { - if (target.mim_ignore_focus_out) - { - Xex.Log ('ignore focus_out in ' + target.tagName); - // Ignore this event which is caused by setSelectionRange (). - target.mim_ignore_focus_out = false; - event.preventDefault (); - } - else - { - Xex.Log ('focus_out in ' + target.tagName); - 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 + ' IGNORED'); + event.preventDefault (); + return false; } + Xex.Log ("Focus out " + target.tagName); + ic.Filter (MIM.Key.FocusOut); + ic.wait_update = true; + MIM.update (target, ic, true); + setTimeout (reset_update, 1000); }; MIM.keydown = function (event) @@ -3196,7 +3299,6 @@ MIM.keydown = function (event) return; if (! (target.type == "text" || target.type == "textarea")) return; - document.akey = event; var ic = target.mim_ic; if (! ic || ic.im != MIM.current) @@ -3216,6 +3318,7 @@ MIM.keydown = function (event) if (! MIM.get_range (target, ic)) ic.reset (); } + //MIM.show (target, ic); MIM.debug_print (event, ic); ic.key = MIM.decode_key_event (event); if (ic.key) @@ -3259,7 +3362,7 @@ MIM.keypress = function (event) try { var result = ic.Filter (ic.key); } catch (e) { - Xex.Log ('Error;' + e); + Xex.Log ('Error:' + e); throw (e); } MIM.update (target, ic); @@ -3271,6 +3374,7 @@ MIM.keypress = function (event) } finally { MIM.debug_print (event, ic); } + return; }; @@ -3292,7 +3396,6 @@ MIM.keypress = function (event) sk: { name: 'Slovak' }, sr: { name: 'Serbian' }, sv: { name: 'Swedish' }, - vi: { name: 'Vietnamese' }, yi: { name: 'Yiddish' } }, MiddleEast: { ar: { name: 'Arabic' }, @@ -3359,12 +3462,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); } @@ -3462,7 +3563,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; } @@ -3512,7 +3615,6 @@ MIM.keypress = function (event) li.appendChild (sub); menu.appendChild (li); } - document.mimmenu = menu; lang_category = null; } menu.style.left = (event.clientX - 10) + "px";