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