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 
 46 const PinyinAMBInitials  = ["zh z","ch c","sh s"];
 47 const PinyinAMBFinals  = ["an ang", "en eng","in ing"];
 48 
 49 const ZiGuangShuangPinInitials = [
 50        { key: "a", initials: "ch"      },
 51        { key: "b", initials: "b"       },
 52        { key: "c", initials: "c"       },
 53        { key: "d", initials: "d"       },
 54        { key: "f", initials: "f"       },
 55        { key: "g", initials: "g"       },
 56        { key: "h", initials: "h"       },
 57        { key: "i", initials: "sh"      },
 58        { key: "j", initials: "j"       },
 59        { key: "k", initials: "k"       },
 60        { key: "l", initials: "l"       },
 61        { key: "m", initials: "m"       },
 62        { key: "n", initials: "n"       },
 63        { key: "p", initials: "p"       },
 64        { key: "q", initials: "q"       },
 65        { key: "r", initials: "r"       },
 66        { key: "s", initials: "s"       },
 67        { key: "t", initials: "t"       },
 68        { key: "u", initials: "zh"      },
 69        { key: "w", initials: "w"       },
 70        { key: "x", initials: "x"       },
 71        { key: "y", initials: "y"       },
 72        { key: "z", initials: "z"       }
 73     ]; 
 74 
 75 const ZiGuangShuangPinFinals = [
 76        { key: "a", finals: "a"         },
 77        { key: "b", finals: "iao"       },
 78        { key: "c", finals: "ing"       },
 79        { key: "d", finals: "ie"        },
 80        { key: "e", finals: "e"         },
 81        { key: "f", finals: "ian"       },
 82        { key: "g", finals: "uang,iang" },
 83        { key: "h", finals: "ong,iong"  },
 84        { key: "i", finals: "i"         },
 85        { key: "j", finals: "iu,er"     },
 86        { key: "k", finals: "ei"        },
 87        { key: "l", finals: "uan"       },
 88        { key: "m", finals: "un"        },
 89        { key: "n", finals: "ui,ue"     },
 90        { key: "o", finals: "uo,o"      },
 91        { key: "p", finals: "ai"        },
 92        { key: "q", finals: "ao"        },
 93        { key: "r", finals: "an"        },
 94        { key: "s", finals: "ang"       },
 95        { key: "t", finals: "ng,eng"    },
 96        { key: "u", finals: "u"         },
 97        { key: "v", finals: "v"         },
 98        { key: "w", finals: "en"        },
 99        { key: "x", finals: "ia,ua"     },
100        { key: "y", finals: "in,uai"    },
101        { key: "z", finals: "ou"        }
102     ]; 
103    
104 const MSShuangPinInitials = [
105        { key: "b", initials: "b"       },
106        { key: "c", initials: "c"       },
107        { key: "d", initials: "d"       },
108        { key: "f", initials: "f"       },
109        { key: "g", initials: "g"       },
110        { key: "h", initials: "h"       },
111        { key: "i", initials: "ch"      },
112        { key: "j", initials: "j"       },
113        { key: "k", initials: "k"       },
114        { key: "l", initials: "l"       },
115        { key: "m", initials: "m"       },
116        { key: "n", initials: "n"       },
117        { key: "p", initials: "p"       },
118        { key: "q", initials: "q"       },
119        { key: "r", initials: "r"       },
120        { key: "s", initials: "s"       },
121        { key: "t", initials: "t"       },
122        { key: "u", initials: "sh"      },
123        { key: "v", initials: "zh"      },
124        { key: "w", initials: "w"       },
125        { key: "x", initials: "x"       },
126        { key: "y", initials: "y"       },
127        { key: "z", initials: "z"       }
128     ];
129  
130 const MSShuangPinFinals = [
131        { key: "a", finals: "a"         },
132        { key: "b", finals: "ou"        },
133        { key: "c", finals: "iao"       },
134        { key: "d", finals: "uang,iang" },  
135        { key: "e", finals: "e"         },
136        { key: "f", finals: "en"        },
137        { key: "g", finals: "ng,eng"    },
138        { key: "h", finals: "ang"       },
139        { key: "i", finals: "i"         },
140        { key: "j", finals: "an"        },
141        { key: "k", finals: "ao"        },
142        { key: "l", finals: "ai"        },
143        { key: "m", finals: "ian"       },
144        { key: "n", finals: "in"        },
145        { key: "o", finals: "o,uo"      },
146        { key: "p", finals: "un"        },
147        { key: "q", finals: "iu"        },
148        { key: "r", finals: "uan,er"    },
149        { key: "s", finals: "ong,iong"  },
150        { key: "t", finals: "ue"        },
151        { key: "u", finals: "u"         },
152        { key: "v", finals: "v,ui"      },
153        { key: "w", finals: "ia,ua"     },
154        { key: "x", finals: "ie"        },
155        { key: "y", finals: "uai"       },
156        { key: "z", finals: "ei"        },
157        { key: ";", finals: "ing"       }
158     ]; 
159 
160 const ChineseStarShuangPinInitials = [
161        { key: "b", initials: "b"       },
162        { key: "c", initials: "c"       },
163        { key: "d", initials: "d"       },
164        { key: "f", initials: "f"       },
165        { key: "g", initials: "g"       },
166        { key: "h", initials: "h"       },
167        { key: "i", initials: "sh"      },
168        { key: "j", initials: "j"       },
169        { key: "k", initials: "k"       },
170        { key: "l", initials: "l"       },
171        { key: "m", initials: "m"       },
172        { key: "n", initials: "n"       },
173        { key: "p", initials: "p"       },
174        { key: "q", initials: "q"       },
175        { key: "r", initials: "r"       },
176        { key: "s", initials: "s"       },
177        { key: "t", initials: "t"       },
178        { key: "u", initials: "ch"      },
179        { key: "v", initials: "zh"      },
180        { key: "w", initials: "w"       },
181        { key: "x", initials: "x"       },
182        { key: "y", initials: "y"       },
183        { key: "z", initials: "z"       }
184     ];
185   
186 const ChineseStarShuangPinFinals = [
187        { key: "a", finals: "a"         },
188        { key: "b", finals: "ia,ua"     },
189        { key: "c", finals: "uan"       },
190        { key: "d", finals: "ao"        },
191        { key: "e", finals: "e"         },
192        { key: "f", finals: "an"        },
193        { key: "g", finals: "ang"       },
194        { key: "h", finals: "uang,iang" },
195        { key: "i", finals: "i"         },
196        { key: "j", finals: "ian"       },
197        { key: "k", finals: "iao"       },
198        { key: "l", finals: "in"        },
199        { key: "m", finals: "ie"        },
200        { key: "n", finals: "iu"        },
201        { key: "o", finals: "uo,o"      },
202        { key: "p", finals: "ou"        },
203        { key: "q", finals: "ing,er"    },
204        { key: "r", finals: "en"        },
205        { key: "s", finals: "ai"        },
206        { key: "t", finals: "ng,eng"    },
207        { key: "u", finals: "u"         },
208        { key: "v", finals: "v,ui"      },
209        { key: "w", finals: "ei"        },
210        { key: "x", finals: "uai,ue"    },
211        { key: "y", finals: "ong,iong"  },
212        { key: "z", finals: "un"        }
213     ];
214 
215 const SmartABCShuangPinInitials = [
216        { key: "a", initials: "zh"      },
217        { key: "b", initials: "b"       },
218        { key: "c", initials: "c"       },
219        { key: "d", initials: "d"       },
220        { key: "e", initials: "ch"      },
221        { key: "f", initials: "f"       },
222        { key: "g", initials: "g"       },
223        { key: "h", initials: "h"       },
224        { key: "j", initials: "j"       },
225        { key: "k", initials: "k"       },
226        { key: "l", initials: "l"       },
227        { key: "m", initials: "m"       },
228        { key: "n", initials: "n"       },
229        { key: "p", initials: "p"       },
230        { key: "q", initials: "q"       },
231        { key: "r", initials: "r"       },
232        { key: "s", initials: "s"       },
233        { key: "t", initials: "t"       },
234        { key: "v", initials: "sh"      },
235        { key: "w", initials: "w"       },
236        { key: "x", initials: "x"       },
237        { key: "y", initials: "y"       },
238        { key: "z", initials: "z"       }
239     ];
240 
241 const SmartABCShuangPinFinals = [
242        { key: "a", finals: "a"         },
243        { key: "b", finals: "ou"        },
244        { key: "c", finals: "in,uai"    },
245        { key: "d", finals: "ia,ua"     },
246        { key: "e", finals: "e"         },
247        { key: "f", finals: "en"        },
248        { key: "g", finals: "ng,eng"    },
249        { key: "h", finals: "ang"       },
250        { key: "i", finals: "i"         },
251        { key: "j", finals: "an"        },
252        { key: "k", finals: "ao"        },
253        { key: "l", finals: "ai"        },
254        { key: "m", finals: "ui,ue"     },
255        { key: "n", finals: "un"        },
256        { key: "o", finals: "uo,o"      },
257        { key: "p", finals: "uan"       },
258        { key: "q", finals: "ei"        },
259        { key: "r", finals: "iu,er"     },
260        { key: "s", finals: "ong,iong"  },
261        { key: "t", finals: "uang,iang" },
262        { key: "u", finals: "u"         },
263        { key: "v", finals: "v"         },
264        { key: "w", finals: "ian"       },
265        { key: "x", finals: "ie"        },
266        { key: "y", finals: "ing"       },
267        { key: "z", finals: "iao"       }
268     ];
269 
270  
271 var PinyinSchema = function() {}; 
272 
273 PinyinSchema.prototype = 
274 {
275     debug: 0, 
276     pinyinInitials: null,
277     pinyinFinals: null,
278     pinyinAMBInitialHash: null, 
279     pinyinAMBFinalHash: null, 
280     pinyinSchema: SMART_PINYIN, 
281     enableAMBZh: false, 
282     enableAMBSh: false, 
283     enableAMBCh: false, 
284     enableAMBAng: false, 
285     enableAMBEng: false, 
286     enableAMBIng: false, 
287 
288     setSchema: function(schema)
289     {
290        this.pinyinInitials = new FireinputHash(); 
291        this.pinyinFinals = new FireinputHash(); 
292        this.pinyinSchema = schema; 
293 
294        switch(schema)
295        {
296           case ZIGUANG_SHUANGPIN: 
297              for(var i=ZiGuangShuangPinInitials.length-1; i>=0; i--)
298              {
299                 this.pinyinInitials.setItem(ZiGuangShuangPinInitials[i].key, 
300                                        ZiGuangShuangPinInitials[i].initials); 
301              }
302              for(var i=ZiGuangShuangPinFinals.length-1; i>=0; i--)
303              {
304                 this.pinyinFinals.setItem(ZiGuangShuangPinFinals[i].key, 
305                                        ZiGuangShuangPinFinals[i].finals); 
306              }
307           break; 
308 
309           case MS_SHUANGPIN: 
310              for(var i=MSShuangPinInitials.length-1; i>=0; i--)
311              {
312                 this.pinyinInitials.setItem(MSShuangPinInitials[i].key, 
313                                        MSShuangPinInitials[i].initials);
314              }
315              for(var i=MSShuangPinFinals.length-1; i>=0; i--)
316              {
317                 this.pinyinFinals.setItem(MSShuangPinFinals[i].key, 
318                                        MSShuangPinFinals[i].finals);
319              }
320           break;
321 
322           case CHINESESTAR_SHUANGPIN: 
323              for(var i=ChineseStarShuangPinInitials.length-1; i>=0; i--)
324              {
325                 this.pinyinInitials.setItem(ChineseStarShuangPinInitials[i].key, 
326                                        ChineseStarShuangPinInitials[i].initials);
327              }
328              for(var i=ChineseStarShuangPinFinals.length-1; i>=0; i--)
329              {
330                 this.pinyinFinals.setItem(ChineseStarShuangPinFinals[i].key, 
331                                        ChineseStarShuangPinFinals[i].finals);
332              }
333           break;
334 
335           case SMARTABC_SHUANGPIN: 
336              for(var i=SmartABCShuangPinInitials.length-1; i>=0; i--)
337              {
338                 this.pinyinInitials.setItem(SmartABCShuangPinInitials[i].key, 
339                                        SmartABCShuangPinInitials[i].initials);
340              }
341              for(var i=SmartABCShuangPinFinals.length-1; i>=0; i--)
342              {
343                 this.pinyinFinals.setItem(SmartABCShuangPinFinals[i].key, 
344                                        SmartABCShuangPinFinals[i].finals);
345              }
346           break;
347 
348           default: 
349              this.pinyinSchema = SMART_PINYIN; 
350           break;
351        }
352 
353        this.initAMB(); 
354     },
355 
356     initAMB: function()
357     {
358        if(this.pinyinAMBInitialHash != null)
359           return; 
360 
361        this.setAMBOption();
362        FireinputPref.addObserver(this, false);	
363        this.pinyinAMBInitialHash = new FireinputHash(); 
364        this.pinyinAMBFinalHash = new FireinputHash(); 
365 
366        //FIXME: should be based on configuration 
367        for(var i=0; i<PinyinAMBInitials.length; i++)
368        {
369           var strArray = PinyinAMBInitials[i].split(' ');
370           if(strArray.length < 2) 
371              continue; 
372           for(var j=0; j<PinyinFinals.length; j++)
373           {
374                this.pinyinAMBInitialHash.setItem(strArray[0]+PinyinFinals[j], strArray[1]+PinyinFinals[j]); 
375           }
376        }
377 
378        for(var i=0; i<PinyinAMBFinals.length; i++)
379        {
380           var strArray = PinyinAMBFinals[i].split(' ');
381           if(strArray.length < 2) 
382              continue; 
383           for(var j=0; j<PinyinInitials.length; j++)
384           {
385                this.pinyinAMBFinalHash.setItem(PinyinInitials[j]+strArray[0], PinyinInitials[j]+strArray[1]); 
386           }
387           // put final in as well 
388           this.pinyinAMBFinalHash.setItem(strArray[0], strArray[1]); 
389        }
390     }, 
391 
392     getAllowedKeys: function()
393     {
394        var allowedKeys = ""; 
395        var self  =  this; 
396        this.pinyinInitials.foreach ( function(k, v) { allowedKeys += k; }); 
397        this.pinyinFinals.foreach ( function(k, v) { if(!self.pinyinInitials.hasItem(k)) {allowedKeys += k; }}); 
398 
399        // smart pinyin by default 
400        if(allowedKeys.length <= 0)
401           allowedKeys = "abcdefghijklmnopqrstuvwxyz"; 
402 
403        return allowedKeys; 
404 
405     }, 
406 
407     observe: function(subject, topic, data)
408     {
409         var name = data.substr(prefDomain.length+1);
410         this.setAMBOption(name);
411     },
412      
413     setAMBOption: function(option)
414     {
415 
416        if(!option || option == "fireinputAMBZh")
417          this.enableAMBZh = FireinputPrefDefault.getAMBOption("fireinputAMBZh");
418 
419        if(!option || option == "fireinputAMBSh")
420          this.enableAMBSh = FireinputPrefDefault.getAMBOption("fireinputAMBSh");
421 
422        if(!option || option == "fireinputAMBCh")
423          this.enableAMBCh = FireinputPrefDefault.getAMBOption("fireinputAMBCh");
424 
425        if(!option || option == "fireinputAMBAng")
426          this.enableAMBAng = FireinputPrefDefault.getAMBOption("fireinputAMBAng");
427 
428        if(!option || option == "fireinputAMBEng")
429          this.enableAMBEng = FireinputPrefDefault.getAMBOption("fireinputAMBEng");
430 
431        if(!option || option == "fireinputAMBIng")
432          this.enableAMBIng = FireinputPrefDefault.getAMBOption("fireinputAMBIng");
433     },
434  
435     // ikey/mkey should be: 
436     //    zan => zhang: final hash
437     //    zan =>zhan: initial hash 
438     //
439     compareAMB: function(ikey, mkey)
440     {
441        if(ikey == mkey)
442           return true; 
443 
444        if((this.enableAMBZh && /^z/.test(ikey)) || 
445           (this.enableAMBSh && /^s/.test(ikey)) ||
446           (this.enableAMBCh && /^c/.test(ikey)))
447        {
448           if(this.pinyinAMBInitialHash.hasItem(ikey))
449           {
450              if (this.pinyinAMBInitialHash.getItem(ikey) == mkey) 
451                 return true; 
452              // mapping such as zen -> zheng 
453              if(this.compareAMBFinal(this.pinyinAMBInitialHash.getItem(ikey), mkey))
454                 return true; 
455 
456              return false; 
457           }
458           else if(this.pinyinAMBInitialHash.hasItem(mkey))
459           {
460              if (this.pinyinAMBInitialHash.getItem(mkey) == ikey)
461                 return true; 
462 
463              // mapping such as zen -> zheng 
464              if(this.compareAMBFinal(this.pinyinAMBInitialHash.getItem(mkey), ikey))
465                 return true; 
466 
467              return false; 
468           }
469        }
470 
471        return this.compareAMBFinal(ikey, mkey);  
472     }, 
473 
474     compareAMBFinal: function(ikey, mkey)
475     {
476        if((this.enableAMBAng && (/an$/.test(ikey) || /ang$/.test(ikey))) || 
477           (this.enableAMBEng && (/en$/.test(ikey) || /eng$/.test(ikey))) || 
478           (this.enableAMBIng && (/in$/.test(ikey) || /ing$/.test(ikey))))
479        {
480           if(this.pinyinAMBFinalHash.hasItem(ikey))
481           {
482              return (this.pinyinAMBFinalHash.getItem(ikey) == mkey); 
483           }
484           else if(this.pinyinAMBFinalHash.hasItem(mkey))
485           {
486              return (this.pinyinAMBFinalHash.getItem(mkey) == ikey); 
487           }
488        }
489 
490        return false; 
491     }, 
492 
493     getKeyByFormat: function(keys, format)
494     {
495        var keyArray = new Array(); 
496        var keySet = new Array();
497        var k;
498        var useFormat = ""; 
499 
500        for(var i=0; i<format.length;)
501        {
502           var fkey = format.substr(i, 1); 
503           var ykey = format.substr(i+1, 1); 
504           if(fkey == "s")
505           {
506              // it's initial 
507              var c1 = keys.substr(i,1);
508              if(this.pinyinInitials.hasItem(c1) || c1 == "o")
509              {
510                 var firstKey = ""; 
511                 if(c1 != "o")
512                 {
513                    firstKey = this.pinyinInitials.getItem(c1);
514                 }
515                 else 
516                 {
517                    if(ykey == 's') 
518                       ykey = "y"; 
519                    firstKey = "o"; 
520                 }
521  
522                 // if keyArray has saved a list of keys, append the new key to each of them
523                 // otherwise just add to keySet only 
524                 if(ykey != "y")
525                 {
526                    if(keyArray.length > 0)
527                    {
528                       for (var ii=0; ii<keyArray.length; ii++)
529                       {
530                          keyArray[ii].push({key: firstKey, type: KEY_INITIAL}); 
531                       }
532                    }
533                    else
534                       keySet.push({key: firstKey, type: KEY_INITIAL}); 
535                 }
536                 else if(ykey == "y")
537                 {
538                   
539                    // it's final 
540                    var c2 = keys.substr(i+1,1);
541                    if(firstKey == "o")
542                       firstKey = ""; 
543 
544                    var keyType = firstKey.length>0 ? KEY_FULL : KEY_FINAL; 
545                    if(this.pinyinFinals.hasItem(c2))
546                    {
547                       var finalArray = this.pinyinFinals.getItem(c2).split(",");
548                       if(keyArray.length > 0)
549                       {
550                           for(var ii=0; ii<keyArray.length; ii++)  
551                           {
552                            keyArray[ii].push({key: firstKey+finalArray[0], type: keyType}); 
553                           }
554                       }
555                       else 
556                           keySet.push({key: firstKey+finalArray[0], type: keyType}); 
557 
558                       // multiple finals. We have save the previous keyset and create a matrix table here 
559                       // to list all possibilities 
560                       if(finalArray.length > 1)
561                       {
562                          if(keyArray.length > 0)
563                          {
564                             var keyArrayCloned = cloneArray(keyArray); 
565                             for(var jj=0; jj<keyArrayCloned.length; jj++)
566                             {
567                                keyArrayCloned[jj].pop(); 
568                                keyArrayCloned[jj].push({key: firstKey+finalArray[1], type: keyType}); 
569                                keyArray.push(keyArrayCloned[jj]); 
570                             }
571                          }   
572                          else
573                          {
574                             keyArray.push(keySet); 
575                             var keySetCloned = cloneArray(keySet); 
576                             keySetCloned.pop(); 
577                             keySetCloned.push({key: firstKey+finalArray[1], type: keyType}); 
578                             keyArray.push(keySetCloned); 
579                          }
580                       }
581                    } /* if in finals */   
582                 } /* else */
583              } 
584           } /* first has to be s */
585 
586           // save format 
587           useFormat += fkey; 
588 
589           if(ykey == "y")
590           {
591              useFormat += ykey; 
592              i += 2; 
593           }
594           else
595              i++; 
596 
597             
598        }
599 
600        // FireinputLog.debug(this, "format: " + format + ", Return format: " + useFormat); 
601        return {format: useFormat, keyset: keyArray.length > 0 ? keyArray: keySet, mkey: keyArray.length > 0 ? 1:0}; 
602     }, 
603 
604 
605     getComposeKey: function(keys, useDefaultSchema)
606     {
607        var keyArray = new Array(); 
608        // 两字词:输入两字的双拼码 (SY);
609        // 三字词:输入前两个字的声码和第三个字的双拼码,共4码 (SSSY);
610        // 四字词:输入每个字的声码,共4码 (SSSS);
611        // 五字词:输入前三个字和第五个字的声码,共4码 (SSSSS)。 FIXME: how ? 
612        
613        // upper level asks to use default schema: pingyin 
614        if(useDefaultSchema)
615           return keys; 
616 
617        switch(this.pinyinSchema)
618        {
619           case ZIGUANG_SHUANGPIN: 
620           case MS_SHUANGPIN: 
621           case CHINESESTAR_SHUANGPIN: 
622           case SMARTABC_SHUANGPIN: 
623              if(keys.length == 1)
624              {
625                 var keySet = new Array(); 
626                 if(this.pinyinInitials.hasItem(keys))
627                    keySet.push({key: this.pinyinInitials.getItem(keys), type: KEY_INITIAL}); 
628                 else
629                    keySet.push({key: keys, type: KEY_INITIAL}); 
630                 keyArray.push(keySet); 
631                 return keyArray; 
632              }
633              else if (keys.length == 2)
634              {
635                 var keySet = this.getKeyByFormat(keys, "sy"); 
636                 if(keySet.mkey)
637                    keyArray = keySet.keyset; 
638                 else
639                    keyArray.push(keySet.keyset); 
640 
641                 return keyArray; 
642              }
643              else if(keys.length == 3)
644              {
645                 // s -sy
646                 var keySet = this.getKeyByFormat(keys, "sss"); 
647                 if(keySet.mkey)
648                    keyArray = keySet.keyset; 
649                 else
650                    keyArray.push(keySet.keyset); 
651 
652                 var useFormat = keySet.format; 
653                 if(useFormat != "ssy")
654                 {
655                    keySet = this.getKeyByFormat(keys, "ssy"); 
656                    if(keySet.mkey)
657                       arrayInsert(keyArray, keyArray.length, keySet.keyset); 
658                    else
659                       keyArray.push(keySet.keyset); 
660                 }
661 
662                 if(useFormat != "sys")
663                 {
664                    keySet = this.getKeyByFormat(keys, "sys"); 
665                    if(keySet.mkey)
666                       arrayInsert(keyArray, keyArray.length, keySet.keyset); 
667                    else
668                       keyArray.push(keySet.keyset); 
669                 }
670 
671                 return keyArray; 
672              } 
673              else if(keys.length == 4)
674              {
675                 // s s s s 
676                 var keySet = this.getKeyByFormat(keys, "ssss"); 
677                 if(keySet.mkey)
678                    keyArray = keySet.keyset; 
679                 else
680                    keyArray.push(keySet.keyset); 
681 
682                 var useFormat = keySet.format; 
683 		// if ssss -> sysy, the keys will be in format as sysy, and cannot be in other formats 
684 		// if ssss -> sssy, then syss will be same as sysy
685 		// if ssss -> syss, then sssy will be same as sysy
686                 if(useFormat == "sysy")
687                    return keyArray; 
688 
689                 // if format changed, in any case only sysy will be valid format 
690                 if(useFormat != "ssss")
691                 {
692                    keySet = this.getKeyByFormat(keys, "sysy"); 
693                    if(keySet.mkey)
694                       arrayInsert(keyArray, keyArray.length, keySet.keyset); 
695                    else
696                       keyArray.push(keySet.keyset); 
697                    return keyArray; 
698                    
699                 }
700                 else 
701                 {
702                    keySet = this.getKeyByFormat(keys, "sssy"); 
703                    if(keySet.mkey)
704                       arrayInsert(keyArray, keyArray.length, keySet.keyset); 
705                    else
706                       keyArray.push(keySet.keyset); 
707 
708                    keySet = this.getKeyByFormat(keys, "sysy"); 
709                    if(keySet.mkey)
710                       arrayInsert(keyArray, keyArray.length, keySet.keyset); 
711                    else
712                       keyArray.push(keySet.keyset); 
713 
714                    keySet = this.getKeyByFormat(keys, "syss"); 
715                    if(keySet.mkey)
716                       arrayInsert(keyArray, keyArray.length, keySet.keyset); 
717                    else
718                       keyArray.push(keySet.keyset); 
719 
720                    return keyArray; 
721                 }
722              }
723              else
724              {
725                 // s s s s s
726                 var fs = ""; 
727                 for(var i=0; i<keys.length; i++)
728                    fs = fs + "s"; 
729 
730                 var keySet = this.getKeyByFormat(keys, fs); 
731                 if(keySet.mkey)
732                    keyArray = keySet.keyset; 
733                 else
734                    keyArray.push(keySet.keyset); 
735 
736                 return keyArray; 
737              }
738           break; 
739 
740           case SMART_PINYIN: 
741           default: 
742              return keys; 
743           break; 
744        }
745 
746        return keyArray; 
747     } 
748 
749     
750 }; 


syntax highlighted by Code2HTML, v. 0.9.1