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 const maxComposedNumber = 50; 
 37 const composerFieldTag = "composerfield_"; 
 38 
 39 var FireinputComposer = 
 40 {
 41     debug: 0, 
 42 
 43     composedNumber: 0, 
 44 
 45     composeEditorId: 0, 
 46 
 47     hasSet: function()
 48     {
 49        return this.composedNumber > 0; 
 50     }, 
 51  
 52     reset: function()
 53     {
 54        if(this.composedNumber <= 0)
 55           return; 
 56 
 57        var composerFieldsElement = document.getElementById("fireinputComposeField"); 
 58        FireinputLog.debug(this, "hidding all composed words"); 
 59        var wlist = composerFieldsElement.getElementsByTagName("hbox");
 60        FireinputLog.debug(this, "wlist.length: " + wlist.length);
 61        for(var i=0; i < wlist.length; i++)
 62        {
 63           wlist[i].style.display = "none";
 64        }
 65 
 66        this.composedNumber = 0; 
 67        Fireinput.enableComposeEditor(false);
 68        this.composeEditorId = 0; 
 69     }, 
 70 
 71     getLastAutoSelected: function()
 72     {
 73        if(this.composedNumber <= 0)
 74           return ""; 
 75  
 76        var composerFieldsElement = document.getElementById("fireinputComposeField"); 
 77        FireinputLog.debug(this, "getLastAutoSelected: this.composedNumber= " + this.composedNumber);
 78        var inputkeys = ""; 
 79        var needed = 0; 
 80        while(this.composedNumber > 0)
 81        {
 82           var hboxElement = document.getElementById(composerFieldTag + this.composedNumber);
 83           if(!hboxElement || hboxElement.style.display == "none")
 84           {
 85              this.composedNumber--; 
 86              continue;
 87           }
 88           else
 89           {
 90              // To make searching less expensive, only last autoselected value will be used 
 91              var editorBox = document.getElementById(composerFieldTag + this.composedNumber + "_textbox");
 92              if(editorBox.getAttribute("autoselected") == "true")
 93              {
 94                 this.composedNumber--; 
 95                 inputkeys = editorBox.getAttribute("hiddeninputkey") + inputkeys;
 96                 FireinputLog.debug(this, "getLastAutoSelected: inputkeys= " + inputkeys);
 97              }
 98 
 99              break; 
100           }
101        }
102        FireinputLog.debug(this, "getLastAutoSelected: inputkeys: " + inputkeys);
103        return needed ? inputkeys : ""; 
104     }, 
105 
106     removeLastFromPanel: function()
107     {
108        if(this.composedNumber <= 0)
109           return ""; 
110 
111        // we actually don't remove them here. Instead they will just be marked as hidden. 
112        // Removing is not thread-safe, as the function might be invoked more than one time 
113        // if the user is typing or removing input keys really quick.
114        var composerFieldsElement = document.getElementById("fireinputComposeField"); 
115        FireinputLog.debug(this, "removeLastFromPanel: this.composedNumber= " + this.composedNumber);
116        while(this.composedNumber > 0)
117        {
118           FireinputLog.debug(this, "removeLastFromPanel: this.composedNumber= " + this.composedNumber);
119           var hboxElement = document.getElementById(composerFieldTag + this.composedNumber);
120           if(!hboxElement || hboxElement.style.display == "none")
121           {
122              this.composedNumber--; 
123              continue;
124           }
125           else
126           {
127              var editorBox = document.getElementById(composerFieldTag + this.composedNumber + "_textbox");
128              this.composedNumber--; 
129              var inputkey = editorBox.getAttribute("hiddeninputkey");
130              hboxElement.style.display = "none"; 
131              return inputkey; 
132           }
133        }
134 
135        return "";
136     }, 
137 
138     addToPanel: function(autoselected, result)
139     {
140        FireinputLog.debug(this, "addToPanel: this.composeEditorId= " + this.composeEditorId);
141        if(this.composeEditorId != 0)
142        {
143           var editorBox = document.getElementById(composerFieldTag + this.composeEditorId + "_textbox");
144           if(editorBox)
145           {
146              this.hideComposeEditorWithValue(editorBox, autoselected, result);
147              return; 
148           }
149        }
150 
151        if(this.composedNumber >= maxComposedNumber)
152           return; 
153 
154        this.createComposePanel(autoselected, result);
155     },
156 
157     createComposePanel: function(autoselected, result)
158     {
159 
160        var composerFieldsElement = document.getElementById("fireinputComposeField"); 
161        var wlist = composerFieldsElement.getElementsByTagName("hbox");
162 
163        FireinputLog.debug(this, "this.composedNumber: " + this.composedNumber + ", wlist.length: " + wlist.length);
164        if(this.composedNumber >= wlist.length)
165        {
166           this.composedNumber++;
167           var thisId = composerFieldTag + this.composedNumber;    
168           
169           var hboxElement = document.createElement("hbox");
170           hboxElement.setAttribute("id", thisId);
171           hboxElement.setAttribute("cfindex", this.composedNumber);
172 
173           var element = document.createElement("textbox");
174           element.setAttribute("value",result.value);
175           element.setAttribute("hiddenvalue", result.value); 
176           element.setAttribute("hiddenkey", result.key);
177           element.setAttribute("hiddeninputkey", result.inputkey);
178           element.setAttribute("hiddenword", result.word);
179           element.setAttribute("tooltiptext", "键: " + result.key);
180           element.setAttribute("class", "composeeditorboxview");
181           element.setAttribute("id", thisId + "_textbox");
182           element.setAttribute("cfindex", this.composedNumber);
183           element.setAttribute("composeopened", "false");
184           element.setAttribute("autoselected", autoselected);
185 
186           element.style.width = 12 * result.value.length + "px"; 
187 
188           var self = this; 
189           element.onclick = function(event) { self.showWordEditor(event); }; 
190           element.addEventListener("blur", function(event) { self.hideWordEditor(event); }, true); 
191           element.addEventListener("focus", function(event) { self.showWordEditor(event); }, true); 
192           element.addEventListener("input", function(event) { self.updateWordEditor(event); } , true);
193 
194           hboxElement.appendChild(element);
195            
196           composerFieldsElement.appendChild(hboxElement); 
197        }
198        else
199        {
200           this.composedNumber++;
201           var thisId = composerFieldTag + this.composedNumber;
202 
203           var hboxElement = document.getElementById(thisId);
204 
205           var element = document.getElementById(thisId + "_textbox");
206           element.value =  result.value;
207           FireinputLog.debug(this, "element.value: " + element.value);
208           element.setAttribute("class", "composeeditorboxview");
209           element.setAttribute("hiddenkey", result.key);
210           element.setAttribute("hiddenvalue", result.value); 
211           element.setAttribute("tooltiptext", "键: " + result.key);
212           element.setAttribute("hiddeninputkey", result.inputkey);
213           element.setAttribute("hiddenword", result.word);
214           element.setAttribute("composeopened", "false");
215           element.setAttribute("autoselected", autoselected);
216 
217           element.style.width = 12 * result.value.length + "px"; 
218 
219           hboxElement.style.display = ""; 
220        }
221     },
222  
223     switchWordEditor: function(cfindex, flag)
224     {
225        var editorBox = document.getElementById(composerFieldTag + cfindex + "_textbox");
226        if(flag)
227        {
228           editorBox.style.display = ""; 
229        }
230        else
231        {
232           editorBox.style.display = "none"; 
233        }
234     }, 
235 
236     showWordEditor: function(e)
237     {
238        var target = e.target; 
239        if(target.getAttribute("composeopened") == "true")
240           return; 
241 
242        var cfindex = target.getAttribute("cfindex");
243 
244        target.setAttribute("composeopened", "true");
245        target.setAttribute("class", "composeeditorbox");
246        target.style.width = 12 * target.getAttribute("hiddeninputkey").length + "px";
247        target.value = target.getAttribute("hiddeninputkey"); 
248        FireinputLog.debug(this, "showWordEditor: " + target.value + ",cfindex=" + cfindex);
249           
250        this.composeEditorId = cfindex; 
251      
252        // enable compose mode 
253        Fireinput.enableComposeEditor(true); 
254 
255        Fireinput.findCharWithKey(target.value); 
256 
257     },
258 
259     updateWordEditor: function(e)
260     {
261        var target = e.target; 
262        FireinputLog.debug(this, "update target.value: " + target.value);
263        target.style.width = (12 * target.value.length < 20 ? 20 : 12 * target.value.length) + "px";
264        Fireinput.findCharWithKey(target.value); 
265     }, 
266 
267     hideWordEditor: function(e)
268     {
269        var target = e.target; 
270        // FIXME: I have seen at least one time the function was not invoked, thus leaving editorbox to be editable. 
271        // maybe the compseopened was reset somehow ? 
272 
273        if(target.getAttribute("composeopened") == "false")
274           return; 
275 
276        var cfindex = target.getAttribute("cfindex");
277 
278        target.setAttribute("composeopened", "false");
279        FireinputLog.debug(this, "hide word editor"); 
280        Fireinput.enableComposeEditor(false); 
281 
282        this.composeEditorId = 0; 
283 
284        target.setAttribute("class", "composeeditorboxview");
285        // hide if everything has been removed 
286        if(target.value.length <= 0)
287        {
288           var hboxElement = document.getElementById(composerFieldTag + cfindex);
289           hboxElement.style.display = "none"; 
290           return; 
291        }
292  
293        FireinputLog.debug(this, "target.value=" + target.value + "<=>" + target.getAttribute("hiddeninputkey"));
294        // no change            
295        if(target.value == target.getAttribute("hiddeninputkey"))
296        {
297           target.value = target.getAttribute("hiddenvalue"); 
298           target.style.width = 12 * target.getAttribute("hiddenvalue").length + "px";
299           return;
300        }
301  
302        var charResult = Fireinput.getCharByPos(1); 
303        if(!charResult)
304        {
305           target.value = target.getAttribute("hiddenvalue"); 
306           target.style.width = 12 * target.getAttribute("hiddenvalue").value.length + "px";
307           return; 
308        }
309 
310        target.value = charResult.value; 
311        target.style.width = 12 * charResult.value.length + "px";
312        target.setAttribute("hiddenvalue", charResult.value);
313        target.setAttribute("hiddenkey", charResult.key);
314        target.setAttribute("tooltiptext", "键: " + charResult.key);
315        target.setAttribute("hiddenword", charResult.word);
316        target.setAttribute("hiddeninputkey", charResult.inputkey);
317 
318     }, 
319 
320     hideComposeEditorWithValue: function(editorBox, autoselected, charResult)
321     {
322        FireinputLog.debug(this, "hide word editor with value");
323 
324        editorBox.setAttribute("class", "composeeditorboxview");
325        editorBox.setAttribute("composeopened", "false");
326 
327        editorBox.value = charResult.value;
328        editorBox.style.width = 12 * charResult.value.length + "px";
329        editorBox.setAttribute("hiddenkey", charResult.key);
330        editorBox.setAttribute("hiddenvalue", charResult.value);
331        editorBox.setAttribute("tooltiptext", "键: " + charResult.key);
332        editorBox.setAttribute("hiddeninputkey", charResult.inputkey);
333        editorBox.setAttribute("hiddenword", charResult.word);
334        editorBox.setAttribute("autoselected", autoselected);
335 
336        Fireinput.enableComposeEditor(false);
337        this.composeEditorId = 0;
338     }, 
339  
340     getComposeWord: function()
341     {
342        var composerFieldsElement = document.getElementById("fireinputComposeField"); 
343        var wlist = composerFieldsElement.getElementsByTagName("hbox");
344        var words = "";
345        var value = "";
346        var keys = ""; 
347        if(this.composedNumber <= 0)
348           return {key: keys, value:value, word: words}; 
349          
350        for(var i=0; i < wlist.length; i++)
351        {
352           if(wlist[i].style.display == "none") 
353              continue;
354           var cfindex = wlist[i].getAttribute("cfindex");
355           var editorBox = document.getElementById(composerFieldTag + cfindex + "_textbox"); 
356           if(!editorBox)
357              continue; 
358           words += editorBox.getAttribute("hiddenword"); 
359           value += editorBox.value; 
360           if(keys.length <= 0)
361              keys = editorBox.getAttribute("hiddenkey"); 
362           else
363              keys += " " + editorBox.getAttribute("hiddenkey");
364        }
365        return {key: keys, value: value, word: words}; 
366     }   
367 
368 
369 }; 


syntax highlighted by Code2HTML, v. 0.9.1