1 /* ***** BEGIN LICENSE BLOCK *****
  2  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
  3  *
  4  * The contents of this file are subject to the Mozilla Public License Version
  5  * 1.1 (the "License"); you may not use this file except in compliance with
  6  * the License. You may obtain a copy of the License at
  7  * http://www.mozilla.org/MPL/
  8  *
  9  * Software distributed under the License is distributed on an "AS IS" basis,
 10  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 11  * for the specific language governing rights and limitations under the
 12  * License.
 13  *
 14  * The Initial Developer of the Original Code is Fireinput Inc.
 15  *
 16  * Portions created by the Initial Developer are Copyright (C) 2007
 17  * the Initial Developer. All Rights Reserved.
 18  *
 19  * Contributor(s):
 20  *     Olly Ja <ollyja@gmail.com>
 21  *
 22  * Alternatively, the contents of this file may be used under the terms of
 23  * either the GNU General Public License Version 2 or later (the "GPL"), or
 24  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 25  * in which case the provisions of the GPL or the LGPL are applicable instead
 26  * of those above. If you wish to allow use of your version of this file only
 27  * under the terms of either the GPL or the LGPL, and not to allow others to
 28  * use your version of this file under the terms of the MPL, indicate your
 29  * decision by deleting the provisions above and replace them with the notice
 30  * and other provisions required by the GPL or the LGPL. If you do not delete
 31  * the provisions above, a recipient may use your version of this file under
 32  * the terms of any one of the MPL, the GPL or the LGPL.
 33  *
 34  * ***** END LICENSE BLOCK ***** 
 35  */
 36 
 37 const PinyinInitials = [ "b", "c", "ch", "d", "f", "g", "h", "j", "k", "l", "m",
 38                           "n", "p","q", "r", "s", "sh", "t", "w", "x", "y", "z", "zh"];
 39 
 40 const PinyinFinals = ["a","ai", "an", "ang", "ao", "e", "ei", "en", "eng", "er",
 41                        "i", "ia", "ian", "iang", "iao", "ie", "in", "ing", "io", "ion", "iong",
 42                        "iou", "iu", "o", "on", "ong", "ou", "u", "ua", "uai", "uan",
 43                        "uang", "ue", "uei", "uen", "ueng", "ui", "un", "uo", "v", "van",
 44                        "ve", "vn"];
 45 const PinyinTones = ["ā", "á", "ă", "à", "ō", "ó", "ǒ", "ò", "ū", "ú", "ǔ", "ù", 
 46                      "ī", "í", "ǐ", "ì", "ē", "é", "ě", "è", "ǖ", "ǘ", "ǚ", "ǜ"]; 
 47 
 48 var KeyInput = function() { this.init(); };
 49 
 50 KeyInput.prototype = 
 51 {
 52     pinyinInitials: [],
 53     pinyinFinals: [],
 54     pinyinTones: [], 
 55     init: function()
 56     {
 57       for(var i=0; i<PinyinInitials.length; i++)
 58          this.pinyinInitials[PinyinInitials[i]] = PinyinInitials[i];
 59 
 60        for(var i=0; i<PinyinFinals.length; i++)
 61          this.pinyinFinals[PinyinFinals[i]] = PinyinFinals[i];
 62 
 63        for(var i=0; i<PinyinTones.length; i++)
 64          this.pinyinTones[PinyinTones[i]] = PinyinTones[i];
 65     }
 66 }
 67 
 68 var PinyinInput = function()  { };
 69 
 70 PinyinInput.prototype = extend(new KeyInput(), 
 71 {
 72     getAllowedInputKey: function()
 73     {
 74        return "abcdefghijklmnopqrstuvwxyzāáăàōóǒòūúǔùīíǐìēéěèǖǘǚǜü";
 75     },
 76 
 77     validateInputKey: function(inputkey)
 78     {
 79        for(var i = inputkey.length -1; i > 0; i--)
 80        {
 81           var s = inputkey.substr(i, 1); 
 82            
 83           if((typeof(this.pinyinFinals[s]) == 'undefined' && 
 84              typeof(this.pinyinInitials[s]) == 'undefined' && 
 85              typeof(this.pinyinTones[s]) == 'undefined') && 
 86              s != ' ' && s != "'")
 87           {
 88              return false; 
 89           }
 90        }
 91 
 92        return true; 
 93     }, 
 94 
 95     parseOneKey: function (keyInitial, keyFinal)
 96     {
 97        var keyInitialLen = keyInitial.length;
 98 
 99        if(typeof(this.pinyinFinals[keyFinal]) != 'undefined')
100        {
101          var pinyinKey = {};
102          pinyinKey.key = keyInitial + keyFinal;
103          pinyinKey.type = keyInitialLen>0 ? KEY_FULL : KEY_FINAL;
104          pinyinKey.pos = keyInitialLen + keyFinal.length;
105          return pinyinKey;
106        }
107        else
108        {
109           for(var i=keyFinal.length-1; i>0; i--)
110           {
111              var subFinal = keyFinal.substring(0, i);
112              if(typeof(this.pinyinFinals[subFinal]) != 'undefined')
113              {
114                 var pinyinKey = {};
115                 pinyinKey.key = keyInitial + subFinal;
116                 pinyinKey.type = keyInitialLen>0 ? KEY_FULL : KEY_FINAL;
117                 pinyinKey.pos = keyInitialLen + i;
118                 return pinyinKey;
119              }
120           }
121        }
122 
123        return ({key: keyInitial, type: KEY_INITIAL, pos: keyInitialLen});
124     },
125 
126     parseKeys: function(inputchar)
127     {
128        var keys = new Array();
129        // the space is from updateFrequency. Treat them as single quot
130        var keyList = inputchar.replace(/\s+/g, "'");
131 
132        // if there are single quot delimiters, process them first
133        if(keyList.search(/\'/) != null)
134        {
135            var keyListArray = keyList.split("'");
136            var keyListArrayLength = keyListArray.length;
137            for(var i=0; i<keyListArrayLength; i++)
138            {
139               var retArray = this.parseKeySteps(keyListArray[i]);
140 
141               if(retArray != null)
142                  arrayInsert(keys, keys.length, retArray.slice(0, retArray.length));
143            }
144 
145            return keys;
146         }
147         return this.parseKeySteps(keyList);
148     },
149 
150     parseKeySteps: function(keyList)
151     {
152        var keys = new Array();
153 
154        var keyListLength = keyList.length;
155 
156        for(var i=0; i< keyListLength;)
157        {
158           var key1 = keyList.substr(i, 1);
159           var key2 = keyList.substr(i, 2);
160 
161           if(typeof(this.pinyinInitials[key2]) != 'undefined')
162           {
163               var finals = keyList.substr(i+2, 4);
164               if(finals.length <= 0)
165               {
166                     keys.push({key: key2, type: KEY_INITIAL});
167 
168                  break;
169               }
170               var pinyinKey = this.parseOneKey(key2, finals);
171               if(pinyinKey.type == KEY_INITIAL)
172               {
173                  // No finals. Store them each one as Initial
174                     keys.push({key: key2, type: KEY_INITIAL});
175               }
176               else
177               {
178                  keys.push({key: pinyinKey.key, type: pinyinKey.type});
179               }
180 
181               i += pinyinKey.pos;
182           }
183           else if(typeof(this.pinyinInitials[key1]) != 'undefined')
184           {
185               var finals = keyList.substr(i+1, 4);
186               if(finals.length <= 0)
187               {
188                  keys.push({key: key1, type: KEY_INITIAL});
189                  break;
190               }
191               var pinyinKey = this.parseOneKey(key1, finals);
192 
193               keys.push({key: pinyinKey.key, type: pinyinKey.type});
194               i += pinyinKey.pos;
195           }
196           else
197           {
198               var finals = keyList.substr(i, 4);
199               if(finals.length <= 0)
200               {
201                  // we don't know what kind of key it's              
202                  break;
203               }
204               var pinyinKey = this.parseOneKey("", finals);
205               if(pinyinKey.pos <= 0)
206               {
207                  // some invalid chars, ignore it by increase position by 1
208                  i++;
209               }
210               else
211               {
212                  keys.push({key: pinyinKey.key, type: KEY_FINAL});
213                  i += pinyinKey.pos;
214               }
215           }
216        }
217        return keys;
218     }
219               
220 }); 
221 
222 var WubiInput = function() { }; 
223 
224 WubiInput.prototype = extend(new KeyInput(),
225 {
226     validateInputKey: function(inputkey)
227     {
228        var allowedkeys = "abcdefghijklmnopqrstuvwxy"; 
229        for(i = inputkey.length -1; i > 0; i--)
230        {
231           var s = inputkey.substr(i, 1);
232           if(!allowedkeys.indexOf(s))
233               return false; 
234        }
235        return true;
236     },
237 
238     parseKeys: function(inputchar)
239     {
240        if(inputchar.length > 4 || inputchar.length <= 0)
241           return null; 
242        return inputchar; 
243     }
244 });
245 
246 var Cangjie5Input = function() { };
247 
248 Cangjie5Input.prototype = extend(new KeyInput(),
249 {
250     validateInputKey: function(inputkey)
251     {
252        var allowedkeys = "abcdefghijklmnopqrstuvwxyz"; 
253        for(i = inputkey.length -1; i > 0; i--)
254        {
255           var s = inputkey.substr(i, 1);
256           if(!allowedkeys.indexOf(s))
257               return false; 
258        }
259        return true;
260     },
261 
262     parseKeys: function(inputchar)
263     {
264        if(inputchar.length > 5 || inputchar.length <= 0)
265           return null; 
266        return inputchar;
267     }
268 });
269 
270 
271 var FireinputTableMgr = 
272 {
273     imageFileValid: false, 
274 
275     selectedpage: 0, 
276 
277     init: function()
278     {
279        FireinputServerLogin.checkUserLogon(); 
280        this.initAutomaticUpdateInteval();
281        this.getLastUpdate();   
282        this.initObserver(); 
283        this.imeSelect(); 
284     }, 
285 
286     initTab: function(tabid)
287     {
288 
289     }, 
290 
291     initObserver: function()
292     {
293        FireinputPref.addObserver(this, false);
294     }, 
295 
296     observe: function(subject, topic, data)
297     {
298        if(topic == "nsPref:changed" && typeof(prefDomain) != 'undefined')
299        {
300           var name = data.substr(prefDomain.length+1);
301           if(name == 'lastTableUpdate')
302           {
303              $('#lastTableUpdate').html('自动更新完成...');
304              $('#updateNowButton').css("display", ""); 
305              $('#updateNowImg').css("display", "none"); 
306 
307              setTimeout(function() { FireinputTableMgr.getLastUpdate(); }, 2000);  
308           }
309    
310           if(name == 'defaultInputMethod')
311           {
312              this.imeSelect(); 
313           } 
314        }
315 
316     }, 
317    
318     
319     changeAutomaticUpdateInterval: function(interval)
320     {
321        fireinputPrefSave('tableUpdateInterval', interval); 
322     }, 
323    
324     initAutomaticUpdateInteval: function()
325     {
326        var intervalInHour = fireinputPrefGetDefault("tableUpdateInterval");
327        options = document.getElementById('tableUpdateInterval'); 
328        for (var i = 0; i < options.length; i++)
329        {
330          if(options[i].value == intervalInHour)
331          {
332             options[i].selected = true; 
333             break; 
334          }
335        }
336     }, 
337 
338     getLastUpdate: function()
339     {
340        var lastupdate = fireinputPrefGetDefault("lastTableUpdate");
341        if(lastupdate.length <= 0)
342        { 
343           $('#lastTableUpdate').html('自动更新还没被执行过'); 
344           return; 
345        } 
346 
347        var current = new Date(lastupdate);
348        var year  = current.getFullYear();
349        var month = current.getMonth();
350        var day =  current.getDate();
351        var hour =  current.getHours();
352        var minute =  current.getMinutes();
353 
354        var lastupdatestr = year + "年" + (month+1) + "月" + day + "日 " + hour + "点" + minute + "分";
355 
356        $('#lastTableUpdate').html(lastupdatestr);
357     }, 
358 
359     updateTableNow: function(button)
360     {
361        // enable running icon 
362        $('#lastTableUpdate').html('更新中...'); 
363        
364        button.style.display = "none";
365        $('#updateNowImg').css("display", ""); 
366        FireinputUtils.notify(null, "fireinput-table-update-request", null);
367     }, 
368 
369     uploadFrame: function(cb) 
370     {
371        var n = 'f' + Math.floor(Math.random() * 99999);
372        var d = document.createElement('div');
373        d.innerHTML = '<iframe style="display:none" src="about:blank" id="'+n+'" name="'+n+'" onload="TableMgr.uploadLoaded(\''+n+'\')"></iframe>';
374        document.body.appendChild(d);
375        var i = document.getElementById(n);
376        if (cb && typeof(cb.onComplete) == 'function') {
377            i.onComplete = cb.onComplete;
378        }
379 
380        return n;
381     },
382 
383     uploadForm: function(targetForm, name)
384     {
385        targetForm.setAttribute('target', name); 
386     }, 
387 
388     uploadFile: function(targetForm)
389     {
390        if(!this.imageFileValid)
391        { 
392           this.showAddFileMessage(false, "图案还没有成功显示或不合法的图像文件"); 
393           return false; 
394        }
395 
396        var self = this; 
397 
398        var cb = { 
399            onStart: function() { self.uploadFileCheckImage(); }, 
400            onComplete: function(p) { self.uploadFileComplete(p); }
401        }; 
402 
403        this.uploadForm(targetForm, this.uploadFrame(cb)); 
404        if (cb && typeof(cb.onStart) == 'function') {
405             return cb.onStart();
406         } else {
407             return true;
408         } 
409     }, 
410 
411     uploadLoaded : function(id) 
412     {
413         var i = document.getElementById(id);
414         if (i.contentDocument) {
415             var d = i.contentDocument;
416         } else if (i.contentWindow) {
417             var d = i.contentWindow.document;
418         } else {
419             var d = window.frames[id].document;
420         }
421         if (d.location.href == "about:blank") {
422             return;
423         }
424 
425         if (typeof(i.onComplete) == 'function') {
426             i.onComplete(d.body.innerHTML);
427         }
428     },
429 
430 
431     /********** all functions for adding add new word *********/
432 
433     imeSelect: function()
434     {
435         var schema = fireinputPrefGetDefault("defaultInputMethod");
436         options = document.newWordForm.imetype; 
437         switch(schema)
438         { 
439            case CANGJIE_5:
440            case WUBI_98:
441            case WUBI_86:
442              $("#newWordForm").fadeOut("fast", function() { 
443                         $("#newWordError").fadeIn("fast"); 
444              }); 
445            break; 
446            case SMART_PINYIN: 
447              $("#newWordError").hide();
448              $("#newWordForm").show();
449              for (var i = 0; i < options.length; i++)  
450              {
451                if(options[i].value == schema)
452                   options[i].selected = true; 
453              }
454            break; 
455         } 
456     }, 
457 
458     imeChange: function(sel)
459     {
460         // clear error fist 
461         this.showError("&nbsp");
462         if(sel.value != SMART_PINYIN)
463         {
464            $("#keySuggestion").hide(); 
465            $("#keyConfirm").hide(); 
466         }
467 
468         $("#inputkey").show(); 
469         $("#inputword").attr("defvalue", ""); 
470 
471         $("#freqData").hide(); 
472         $("#addNew").removeAttr("disabled"); 
473     }, 
474  
475     checkkey: function(inputkey, imetype)
476     {
477         var parser = null; 
478 
479         switch(imetype)
480         {
481            case SMART_PINYIN: 
482               parser = new PinyinInput(); 
483            break; 
484            case WUBI_86: 
485            case WUBI_98:
486               parser = new WubiInput(); 
487            break; 
488            case CANGJIE_5:
489               parser = new Canjie5Input(); 
490            break; 
491            default: 
492               this.showError("对不起,不支持此输入法");
493               return false; 
494         }
495    
496        if(!parser.validateInputKey(inputkey))
497        {
498            this.showError("输入键含有不合法的字母");
499            return false; 
500        }
501  
502        var list = parser.parseKeys(inputkey); 
503        if(!list)
504        {
505            errstr = "读入输入键失败"; 
506            if(imetype == WUBI_86 || imetype == WUBI_98)
507              errstr += ", 五笔输入键最多是四键";
508 
509            this.showError(errstr);
510            return false; 
511        }
512  
513        if(typeof(list) == 'string')
514            return list; 
515    
516        var s = "";
517        for(var i=0; i<list.length; i++)
518        {
519           s += list[i].key + " ";
520        }
521        return s; 
522     }, 
523 
524     showError: function(error)
525     {
526        $("#formError").html(error);
527     },
528 
529     checkWord: function()
530     {
531        var inputword = document.newWordForm.inputword.value; 
532        var inputkey = document.newWordForm.inputkey.value; 
533 
534        // clear error fist 
535        this.showError("&nbsp");
536        if(!inputword)
537        {
538           this.showError("词组不能是空");
539           return false; 
540        }
541 
542        if(inputword.length < 2)
543        {
544           this.showError("词组必须至少两个字");
545           return false; 
546        }
547 
548        if(inputkey.length <= 0)
549        {
550           this.showError("输入键不能是空");
551           return false; 
552        }
553 
554 
555        return true; 
556     }, 
557 
558     addToLocal: function()
559     {
560         var imetype = document.newWordForm.imetype.value; 
561         var inputword = document.newWordForm.inputword.value; 
562         var inputkey = document.newWordForm.inputkey.value; 
563         var hiddennumtoneinputkey = document.newWordForm.hiddennumtoneinputkey.value; 
564         var hiddenchartoneinputkey = document.newWordForm.hiddenchartoneinputkey.value; 
565 
566         if(!this.checkWord())
567            return false; 
568 
569         var schema = fireinputPrefGetDefault("defaultInputMethod");
570         var notification = 0; 
571         switch(imetype)
572         {
573            case CANGJIE_5:
574              notification = (schema == imetype) ? 1 : 0; 
575            case WUBI_98:
576            case WUBI_86:
577              notification = (schema == imetype) ? 1 : 0; 
578            break;
579            case SMART_PINYIN: 
580              notification = (schema <= SMARTABC_SHUANGPIN) ? 1 : 0; 
581            break; 
582         }
583 
584         // we need to see whether user has modify the input keys 
585         inputkey = FireinputUtils.trimString(inputkey); 
586         if(inputkey.length <= 0)
587         {
588            this.showError("输入键不能是空");
589            return false; 
590         }
591 
592         // choose user input if there is a change 
593         if(inputkey == hiddenchartoneinputkey)
594            inputkey = hiddennumtoneinputkey; 
595 
596         // valid and send notification 
597         if(notification)
598         {
599            FireinputUtils.notify(null, "fireinput-add-new-phrase", inputword + "0:" + inputkey);
600         }
601 
602         this.showError("<div style='margin-left: 8px; color: green'>成功加入</div>");
603     }, 
604 
605 
606     addToServer: function()
607     {
608         var imetype = document.newWordForm.imetype.value; 
609         var inputword = document.newWordForm.inputword.value; 
610         var keyconfirmvalue = document.newWordForm.keyconfirmvalue; 
611         var hiddennumtoneinputkey = document.newWordForm.hiddennumtoneinputkey.value; 
612 
613         if(!this.checkWord()) 
614            return false; 
615 
616         // take keyconfirmvalue #keyConfirm is displayed 
617         // other use inputkey as real one 
618         var result = ($("#keyConfirm").css("display") != "none" && keyconfirmvalue) ? keyconfirmvalue.value : hiddennumtoneinputkey; 
619         if(!result || result.length <= 0)
620         {
621            this.showError("输入键不能是空"); 
622            return false; 
623         }
624 
625         // check whether username and email are given after keyconfirmvalue is provided 
626         if($("#keyConfirm").css("display") != "none" && $("#userInfoData").css("display") != "none")
627         {
628            var guestname = document.newWordForm.realname.value; 
629            var email = document.newWordForm.email.value; 
630            if(guestname.length <= 0 || email.length <= 0)
631            {
632               this.showError("你还没有登录, 请提供笔名和邮箱"); 
633               return; 
634            }
635 
636            var guestdefname = document.newWordForm.realname.defvalue; 
637            var defemail = document.newWordForm.email.defvalue; 
638 
639            // keep it in pref for later reuse. 
640            if(guestdefname != guestname)
641              fireinputPrefSave("serverGuestName", guestname); 
642            if(email != defemail)
643              fireinputPrefSave("serverGuestId", email); 
644 
645            this.addWordServer(inputword, imetype, result, guestname, email);
646            return; 
647        }
648 
649        // send to server 
650        this.addWordServer(inputword, imetype, result);
651 
652        return true; 
653     },
654 
655 
656     addWordServer: function(inputword, imetype, inputkey, guestname, email)
657     {
658        var params = "inputword="+encodeURIComponent(inputword) + "&inputkey="+encodeURIComponent(inputkey) + "&imetype=" + imetype;
659        if(guestname && email)
660        {
661           params += "&name=" + encodeURIComponent(guestname) + "&email=" + encodeURIComponent(email);
662        }
663 
664        var url = "/table/addnew.php";
665        var ajax = new Ajax();
666        var self = this; 
667        ajax.setOptions(
668         {
669           method: 'post',
670           postBody: params,
671           contentType: 'application/x-www-form-urlencoded',
672           onSuccess: function(p) { self.addWordServerSuccess(p); self.disableButton("addNewServer", false);},
673           onFailure: function(p) { self.addWordServerFailure(p); self.disableButton("addNewServer", false);}
674         });
675 
676        this.disableButton("addNewServer", true);
677        ajax.request(SERVER_URL + url);
678    },
679 
680    addWordServerSuccess: function(p)
681    {
682        try 
683        {
684          var jsonMsg = JSON.parse(p.responseText);
685          switch(jsonMsg.step)
686          {
687             case '1': 
688               // success 
689               this.showError("<div style='margin-left: 8px; color: green'>成功加入</div>");
690 
691               // just leave inputword in place 
692               var inputword = $("#inputword").val(); 
693               $("#inputword").val('');
694               this.showKeySuggestion(); 
695               $("#inputword").val(inputword);
696             break; 
697             case '2': 
698             case '3': 
699                this.showConfirmForm(jsonMsg); 
700             break; 
701          }
702        }
703        catch(e) { this.showError(e);}
704 
705    },
706 
707    addWordServerFailure: function(p)
708    {
709        try 
710        {
711          var jsonMsg = JSON.parse(p.responseText); 
712          if(jsonMsg.errCode == 1)
713          {
714             this.showError(jsonMsg.errMsg); 
715          }
716          else if (jsonMsg.errCode == 2)
717          {
718             // the word exists
719             this.showError("词组已存在"); 
720          }
721        }
722        catch(e) { this.showError(e); }
723    },
724 
725    showConfirmForm: function(data)
726    {
727        $("#keySuggestion").hide();
728        $("#keyConfirmData").html("");
729        $("#freqData").hide(); 
730        $("#addNew").removeAttr("disabled"); 
731        $("#toggleKeySuggestion").hide(); 
732 
733        if(typeof(data.mnumtone) != 'undefined' && typeof(data.nmnumtone) == 'undefined')
734        {
735          // only match 
736          var html = "<table cellspacing=3 cellpadding=3>";
737          html += "<tr><td valign='center'><span>" + data.mchartone +
738                   "</span></td><td><input value='" + data.mnumtone + "' name='keyconfirmvalue' type='hidden'></td></tr>";
739          $("#keyConfirmData").html(html); 
740          $("#confirmChoose").html("选择的输入键:"); 
741        }
742        else if(typeof(data.mnumtone) != 'undefined' && typeof(data.nmnumtone) != 'undefined')
743        {
744 
745           var charToneKeyList = data.nmchartone.split(",");
746           var numToneKeyList =  data.nmnumtone.split(",");
747           var html = "<table cellspacing=3 cellpadding=3>";
748 
749           html += "<tr><td colspan=2 valign='center'><span><select name='keyconfirmvalue'>";
750           for(var i=0; i<charToneKeyList.length; i++)
751           {
752              if(data.mchartone == charToneKeyList[i])
753              {
754                 html += "<option value='" + numToneKeyList[i] +
755                   "' selected>" + charToneKeyList[i] + "</option>";
756              }
757              else 
758                 html += "<option value='" + numToneKeyList[i] +
759                   "'>" + charToneKeyList[i] + "</option>";
760 
761           }
762           data += "</select></td></tr>";
763 
764           html += "</table>";
765           $("#keyConfirmData").html(html);
766           $("#confirmChoose").html("请选择正确的键:"); 
767         }
768 
769         // user information form is displayed 
770         if(data.step == 2)
771         {
772            document.newWordForm.realname.value = fireinputPrefGetDefault("serverGuestName"); 
773            document.newWordForm.realname.defvalue = document.newWordForm.realname.value; 
774            document.newWordForm.email.value = fireinputPrefGetDefault("serverGuestId"); 
775            document.newWordForm.email.defvalue = document.newWordForm.email.value; 
776            $("#userInfoData").show(); 
777         }
778         else 
779            $("#userInfoData").hide(); 
780 
781         $("#keyConfirm").show();   
782         $("#inputkey").hide();   
783    },
784 
785    showKeySuggestion: function()
786    {
787        var inputword = document.newWordForm.inputword.value; 
788        var imetype = document.newWordForm.imetype.value; 
789 
790        // only do key suggestion for pinyin 
791        if(imetype != SMART_PINYIN)
792           return false; 
793  
794        if($("#inputword").attr("defvalue") == inputword)
795           return; 
796  
797        if(this.ischecking == true)
798           return;
799    
800        this.ischecking = true; 
801 
802        $("#freqData").hide();
803        $("#addNew").removeAttr("disabled"); 
804        $("#keyConfirm").hide(); 
805        $("#keySuggestion").hide(); 
806        $("#inputkey").show(); 
807 
808        // reset input key to prepare for suggestion keys 
809        document.newWordForm.inputkey.value = ''; 
810 
811        // reset defvalue to to use new inputword 
812        $("#inputword").attr("defvalue", ''); 
813 
814        //keep key suggestion silent 
815        if(!inputword || inputword.length < 2)
816        {
817           this.ischecking = false; 
818           return false; 
819        }
820 
821        // query the key suggestion 
822        var url = "/table/getpinyinkey.php";
823 
824        var params = "inputword="+encodeURIComponent(inputword);
825        var ajax = new Ajax();
826        var self = this; 
827        ajax.setOptions(
828         {
829           method: 'post',
830           postBody: params,
831           contentType: 'application/x-www-form-urlencoded',
832           onSuccess: function(p) { FireinputTableMgr.addKeySuggestion(p); self.ischecking = false;},
833           onFailure: function(p) { alert(p.responseText);  $("#inputword").attr("defvalue", ""); self.ischecking = false;},
834         });
835 
836        ajax.request(SERVER_URL + url);
837 
838    },
839 
840 
841    addKeySuggestion: function(p)
842    {
843        if(p.responseText.length <= 0)
844           return; 
845 
846        var inputword = document.newWordForm.inputword.value; 
847        $("#inputword").attr("defvalue", inputword); 
848        try {
849           var jsonMsg = JSON.parse(p.responseText); 
850           var charToneKeyList = jsonMsg.chartone.split(","); 
851           var numToneKeyList = jsonMsg.numtone.split(","); 
852           var fcharTone = jsonMsg.fchartone; 
853           var fnumTone = jsonMsg.fnumtone; 
854           if(!fcharTone || !fnumTone)
855           {
856              fnumTone = numToneKeyList[0]; 
857              fcharTone = charToneKeyList[0]; 
858           }
859 
860           var data = "<table cellspacing=3 cellpadding=3>"; 
861 
862           if(charToneKeyList.length > 1)
863           {
864             data += "<tr><td colspan=2 valign='center'><span><select id='myselect' onchange='FireinputTableMgr.keySuggestionChange(this)'>"; 
865             for(var i=0; i<charToneKeyList.length; i++)
866             {
867                data += "<option value='" + numToneKeyList[i] + 
868                   "'>" + charToneKeyList[i] + "</option>"; 
869             }
870             data += "</select></td></tr>";
871           }
872 
873           data += "</table>"; 
874           $("#keySuggestionData").html(data); 
875      
876           // add suggestion into inputkey textbox 
877           document.newWordForm.inputkey.value = fcharTone; 
878           document.newWordForm.hiddennumtoneinputkey.value = fnumTone;
879           document.newWordForm.hiddenchartoneinputkey.value = fcharTone;
880           if(charToneKeyList.length > 1)
881           {
882              $("#toggleKeySuggestion").show(); 
883           }
884           else 
885           {
886              $("#toggleKeySuggestion").hide(); 
887           }
888 
889         }
890         catch(e) {dump(e + "\n");}
891 
892    },
893 
894    keySuggestionChange: function(option)
895    {
896         document.newWordForm.inputkey.value = option.options[option.selectedIndex].text;
897         document.newWordForm.hiddennumtoneinputkey.value = option.value; 
898         document.newWordForm.hiddenchartoneinputkey.value = document.newWordForm.inputkey.value; 
899    },
900 
901    disableButton: function(button, flag)
902    {
903        var id = document.getElementById(button); 
904        if(flag)
905        {
906          id.setAttribute("oldtype", id.type); 
907          id.type = "image"; 
908          id.src="chrome://fireinput/skin/loading.gif"; 
909          id.disabled = true; 
910        }
911        else
912        {
913          id.type = id.hasAttribute("oldtype") ? id.getAttribute("oldtype") : "button"; 
914          id.disabled = false; 
915        }
916    }
917 
918 }; 


syntax highlighted by Code2HTML, v. 0.9.1