/* GNU通用公共许可证(GPL) 这是一个自由软件,任何人或机构都可以在遵守GPL守则下使用该软件。 原 作 者 :亦會編程(万码论坛注册 http://www.suoai.com/88988/) 修 改 者 :阿勤(仓颉之友。马来西亚 http://www.chinesecj.com)丶FXAM 版 本  :0.61 浏览器 :支持IE丶Netscape 及 Mozilla 最新版本 推出日期 :2003-7-30 修改日期 :2003-8-23 */ // Gecko = Netscape 7.x & Mozilla 1.4+ LastNo=0; SPACECHAR=" "; // 空白字元。 CandChinesePart=new Array(); //侯选字,中文字部份 CandCompPart=new Array(); //侯选字, 后码部份,如“我o”里的o AsciiStr="a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z"; //定义使用的编码。 AsciiStr=AsciiStr.split(','); CodeList=CodeList.split(','); CtrlDown=false; CancelKey=false; //==KeyCode 33..47 //Symbol1 = "!"#$%&'()*+,-。/"; //==KeyCode 58..64 //Symbol2 = ":;<=>?@"; //==KeyCode 91..96 //Symbol3 = "[、}^_`"; //==KeyCode 123..126 //Symbol4 = "{|]~"; Punct2 = new Array(';','=',',','-','。','/','`'); Punct3 = new Array('[','、',']','''); //==按SHIFT输出的符号 SPunct1 = new Array(')','!','@','#','$','%','^','&','*','('); SPunct2 = new Array(':','+','<','_','>','?','~'); SPunct3 = new Array('{','|','}','"'); //==全形数字和字母 FullShape_No=new Array("0","1","2","3","4","5","6","7","8","9"); FullShape_BigAZ=new Array("A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T", "U","V","W","X","Y","Z"); FullShape_SmallAZ=new Array('a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'); // 二分搜索法 function FindIn(s) { var find=-1,low=0,mid=0,high=CodeList.length; var sEng=""; while(low0){ sEng=CodeList[find-1]; if(sEng.indexOf(s,0)==0){find--;}else{break;} } return(find); } function GetStr(No, s){ var sTmp="",sChi=""; for(i=0;i<=9;i++){ if(No+i>=CodeList.length-1){break;} sTmp=CodeList[No+i]; if(sTmp.indexOf(s)>=0){ sChi=CodeList[No+i]; CandCompPart[i]=sChi.substring(s.length,sChi.indexOf(SPACECHAR)); CandChinesePart[i]=sChi.substr(sChi.lastIndexOf(SPACECHAR)+1); if(i<=8){IME.Cand.value+=(i+1)+"."+CandChinesePart[i]+CandCompPart[i]+'\n';} else{IME.Cand.value+=(0)+"."+CandChinesePart[i]+CandCompPart[i]+'\n';} LastNo=No+i; }else{LastNo=-1;} } } function Grep(s){ var No=-1; for(i=0;i<=9;i++){CandChinesePart[i]="";} if(s!=""){ No=FindIn(s); if(No>=0){GetStr(No, s);} } //==自动上字 if( IME.AutoUp.checked==true && CandChinesePart[0]!="" && CandChinesePart[1]=="" && CandCompPart[0]=="" ) { SendCand(0); } } // 送候选字到输入区 function SendCand(n){ if ( n>=0 && n<=9 ) { SendStr(CandChinesePart[n]); IME.Comp.value=""; IME.Cand.value=""; } } // 设选区:暂时无用 function setSelectionRange(input, selectionStart, selectionEnd) { if (input.setSelectionRange) { input.focus(); input.setSelectionRange(selectionStart, selectionEnd); } else if (input.createTextRange) { var range = input.createTextRange(); range.collapse(true); range.moveEnd('character', selectionEnd); range.moveStart('character', selectionStart); range.select(); } } // 设光标位置:暂时无用 function setCaretToEnd (input) { setSelectionRange(input, input.value.length, input.value.length); } function setCaretToBegin (input) { setSelectionRange(input, 0, 0); } function setCaretToPos (input, pos) { setSelectionRange(input, pos, pos); } // 送字串到输入区 function SendStr(s) { if (s=="") { return } switch (browser) { case 1: // IE var r=document.selection.createRange(); r.text=s; r.select(); // 不知何故,此码可取消选区。 break; case 2: // Gecko /* -simulate keypress *simulate scroll -change outputString -use createRange, setStart, setEnd */ var obj = IME.InputArea; var selectionStart = obj.selectionStart; var selectionEnd = obj.selectionEnd; var oldScrollTop = obj.scrollTop; //因Gecko不会滚到该滚的地方。 var oldScrollHeight = obj.scrollHeight; var oldLen = obj.value.length; obj.value = obj.value.substring(0, selectionStart) + s + obj.value.substring(selectionEnd); // 这时Gecko会将scrollTop改成0 obj.selectionStart = obj.selectionEnd = selectionStart + s.length; if (obj.value.length == oldLen) { // 如果用户在后面输入,就直接滚到后面。 obj.scrollTop = obj.scrollHeight; } else if (obj.scrollHeight > oldScrollHeight) { // 如果TextArea增加了高度,就滚下一点点 obj.scrollTop = oldScrollTop + obj.scrollHeight - oldScrollHeight; } else { // 其它情形就滚回之前的地方 obj.scrollTop = oldScrollTop; } break; default: // 其它,就在后面加字算了 IME.InputArea.value += s; } } // 将半形字母换成全形字母 function ToFullShapeLetter(aStr) { var s=""; for (i=0;i=65 && c<=90) { s += FullShape_BigAZ[c-65]; } else if (c>=97 && c<=122) { s += FullShape_SmallAZ[c-97]; } else { s += aStr.charAt(i); } } return s; } function ImeKeyDown(e) { var s=""; var key = e.which ? e.which : e.keyCode; CtrlDown=false; switch (key) { //==Backspace case 8: if (IME.Comp.value!="") { s=IME.Comp.value; IME.Comp.value = s.substr(0, s.length-1); IME.Cand.value = ""; Grep(IME.Comp.value); //TODO: how to cancel KeyDown in Opera 7.11? Hack it? CancelKey = true; return (false); } return (true); //==Tab case 9: SendStr(' '); CancelKey = true; return (false); //==Esc case 27: IME.Comp.value=""; IME.Cand.value=""; CancelKey = true; return (false); //Esc会把全部文字删除,故禁止 Esc键 起任何作用。 //==PageUp case 33: case 57383: // Opera 7.11 s=IME.Comp.value; if (s!="") { IME.Cand.value=""; if((LastNo-19)>FindIn(s)){ LastNo=LastNo-19;GetStr(LastNo, s); } else { GetStr(FindIn(s), s); } CancelKey = true; return(false); } return(true); //==PageDown case 34: case 57384: // Opera 7.11 s=IME.Comp.value; if ( s!="" && LastNo!=-1 ) { IME.Cand.value=""; GetStr(LastNo+1, s); CancelKey = true; return(false); } return(true); //==Space case 32: if(IME.Comp.value!="") { //TODO: sound if nothing in Cand SendCand(0); CancelKey = true; return(false); } return(true); //==Enter case 13: if (IME.Comp.value!="") { SendStr( IME.FullShape.checked ? ToFullShapeLetter(IME.Comp.value) : IME.Comp.value); IME.Comp.value=""; IME.Cand.value=""; CancelKey = true; return(false); } return(true); //==F12 case 123: case 57356: // Opera 7.11 IME.FullShape.checked = !IME.FullShape.checked; CancelKey = true; return (false); //==Ctrl case 17: case 57402: // Opera 7.11 CtrlDown=true; break; } if (e.ctrlKey) { return (true) }; //==数字和符号 if (key>=48 && key<=57) { if (e.shiftKey) { // 0-9???? if (IME.FullShape.checked || !IME.EnglishMode.checked) { SendStr(SPunct1[key-48]); CancelKey = true; return (false); } } else { // ?? if (IME.Comp.value=="") { if (IME.FullShape.checked || !IME.EnglishMode.checked) { SendStr(FullShape_No[key-48]); CancelKey = true; return (false); } } else { if (!IME.EnglishMode.checked) { SendCand( key==48 ? 9 : (key-49) ); CancelKey = true; return (false); } } } return (true); } //==其它符号 if (IME.FullShape.checked || !IME.EnglishMode.checked) { if (key>=186 && key<=192) { SendStr( e.shiftKey ? SPunct2[key-186] : Punct2[key-186] ); CancelKey = true; return (false); } if (key>=219 && key<=222) { SendStr( e.shiftKey ? SPunct3[key-219] : Punct3[key-219] ); CancelKey = true; return (false); } } if (browser==2) { if (IME.FullShape.checked || !IME.EnglishMode.checked) { switch (key) { case 59: // "Gecko 之分号和冒号" 的 keyCode 是 59 SendStr( e.shiftKey ? SPunct2[0] : Punct2[0] ); CancelKey = true; return (false); case 61: SendStr( e.shiftKey ? SPunct2[1] : Punct2[1] ); CancelKey = true; return (false); case 109: SendStr( e.shiftKey ? SPunct2[3] : Punct2[3] ); CancelKey = true; return (false); } } } return(true); } function ImeKeyPress(e) { var key = e.which ? e.which : e.keyCode; // Gecko 虽不能于 OnKeyDown 取消键,但它却是在 OnKeyPress 之后才执行键的动作,故于 OnKeyPress 取消键亦无所谓。 // 但 Opera 在 OnKeyPress 之前已执行键的动作,故仍未能取消 Backspace 等键。 // 为什么不连IE也在此取消多一次?即在OnKeyDown取消,在OnKeyPress再取消。因会出现一个问题:快速输入文字时,第一个字会被取消。原因未知。 if (browser==2 || browser==3) { if (CancelKey) { CancelKey = false; return (false); } } if (e.ctrlKey) { return (true); } // 为何不将A-Z的处理放在OnKeyDown ? 因无从知道Caps Lock的状况。 //==A-Z if ( key>=65 && key<=90 ) { if (IME.FullShape.checked) { SendStr(FullShape_BigAZ[key-65]); return (false); } return (true); } //==a-z if (key>=97 && key<=122) { if (IME.EnglishMode.checked) { if (IME.FullShape.checked) { SendStr( FullShape_SmallAZ[key-97] ); return (false); } return (true); } else { s=IME.Comp.value; if (s.length<\/SCRIPT>"); }