commit | author | age
|
dd53e2
|
1 |
/* |
T |
2 |
Last Modified: 28/04/06 16:28:09 |
|
3 |
|
|
4 |
AmiJs library |
|
5 |
A very small library with DOM and Ajax functions. |
|
6 |
For a much larger script look on http://www.mochikit.com/ |
|
7 |
AUTHOR |
|
8 |
4mir Salihefendic (http://amix.dk) - amix@amix.dk |
|
9 |
LICENSE |
|
10 |
Copyright (c) 2006 Amir Salihefendic. All rights reserved. |
|
11 |
Copyright (c) 2005 Bob Ippolito. All rights reserved. |
|
12 |
http://www.opensource.org/licenses/mit-license.php |
|
13 |
VERSION |
|
14 |
2.1 |
|
15 |
SITE |
|
16 |
http://amix.dk/amijs |
|
17 |
**/ |
|
18 |
|
|
19 |
var AJS = { |
|
20 |
//// |
|
21 |
// Accessor functions |
|
22 |
//// |
|
23 |
/** |
|
24 |
* @returns The element with the id |
|
25 |
*/ |
|
26 |
getElement: function(id) { |
|
27 |
if(typeof(id) == "string") |
|
28 |
return document.getElementById(id); |
|
29 |
else |
|
30 |
return id; |
|
31 |
}, |
|
32 |
|
|
33 |
/** |
|
34 |
* @returns The elements with the ids |
|
35 |
*/ |
|
36 |
getElements: function(/*id1, id2, id3*/) { |
|
37 |
var elements = new Array(); |
|
38 |
for (var i = 0; i < arguments.length; i++) { |
|
39 |
var element = this.getElement(arguments[i]); |
|
40 |
elements.push(element); |
|
41 |
} |
|
42 |
return elements; |
|
43 |
}, |
|
44 |
|
|
45 |
/** |
|
46 |
* @returns The GET query argument |
|
47 |
*/ |
|
48 |
getQueryArgument: function(var_name) { |
|
49 |
var query = window.location.search.substring(1); |
|
50 |
var vars = query.split("&"); |
|
51 |
for (var i=0;i<vars.length;i++) { |
|
52 |
var pair = vars[i].split("="); |
|
53 |
if (pair[0] == var_name) { |
|
54 |
return pair[1]; |
|
55 |
} |
|
56 |
} |
|
57 |
return null; |
|
58 |
}, |
|
59 |
|
|
60 |
/** |
|
61 |
* @returns If the browser is Internet Explorer |
|
62 |
*/ |
|
63 |
isIe: function() { |
|
64 |
return (navigator.userAgent.toLowerCase().indexOf("msie") != -1 && navigator.userAgent.toLowerCase().indexOf("opera") == -1); |
|
65 |
}, |
|
66 |
|
|
67 |
/** |
|
68 |
* @returns The document body |
|
69 |
*/ |
|
70 |
getBody: function() { |
|
71 |
return this.getElementsByTagAndClassName('body')[0] |
|
72 |
}, |
|
73 |
|
|
74 |
/** |
|
75 |
* @returns All the elements that have a specific tag name or class name |
|
76 |
*/ |
|
77 |
getElementsByTagAndClassName: function(tag_name, class_name, /*optional*/ parent) { |
|
78 |
var class_elements = new Array(); |
|
79 |
if(!this.isDefined(parent)) |
|
80 |
parent = document; |
|
81 |
if(!this.isDefined(tag_name)) |
|
82 |
tag_name = '*'; |
|
83 |
|
|
84 |
var els = parent.getElementsByTagName(tag_name); |
|
85 |
var els_len = els.length; |
|
86 |
var pattern = new RegExp("(^|\\s)" + class_name + "(\\s|$)"); |
|
87 |
|
|
88 |
for (i = 0, j = 0; i < els_len; i++) { |
|
89 |
if ( pattern.test(els[i].className) || class_name == null ) { |
|
90 |
class_elements[j] = els[i]; |
|
91 |
j++; |
|
92 |
} |
|
93 |
} |
|
94 |
return class_elements; |
|
95 |
}, |
|
96 |
|
|
97 |
|
|
98 |
//// |
|
99 |
// DOM manipulation |
|
100 |
//// |
|
101 |
/** |
|
102 |
* Appends some nodes to a node |
|
103 |
*/ |
|
104 |
appendChildNodes: function(node/*, nodes...*/) { |
|
105 |
if(arguments.length >= 2) { |
|
106 |
for(var i=1; i < arguments.length; i++) { |
|
107 |
var n = arguments[i]; |
|
108 |
if(typeof(n) == "string") |
|
109 |
n = document.createTextNode(n); |
|
110 |
if(this.isDefined(n)) |
|
111 |
node.appendChild(n); |
|
112 |
} |
|
113 |
} |
|
114 |
return node; |
|
115 |
}, |
|
116 |
|
|
117 |
/** |
|
118 |
* Replaces a nodes children with another node(s) |
|
119 |
*/ |
|
120 |
replaceChildNodes: function(node/*, nodes...*/) { |
|
121 |
var child; |
|
122 |
while ((child = node.firstChild)) { |
|
123 |
node.removeChild(child); |
|
124 |
} |
|
125 |
if (arguments.length < 2) { |
|
126 |
return node; |
|
127 |
} else { |
|
128 |
return this.appendChildNodes.apply(this, arguments); |
|
129 |
} |
|
130 |
}, |
|
131 |
|
|
132 |
/** |
|
133 |
* Insert a node after another node |
|
134 |
*/ |
|
135 |
insertAfter: function(node, referenceNode) { |
|
136 |
referenceNode.parentNode.insertBefore(node, referenceNode.nextSibling); |
|
137 |
}, |
|
138 |
|
|
139 |
/** |
|
140 |
* Insert a node before another node |
|
141 |
*/ |
|
142 |
insertBefore: function(node, referenceNode) { |
|
143 |
referenceNode.parentNode.insertBefore(node, referenceNode); |
|
144 |
}, |
|
145 |
|
|
146 |
/** |
|
147 |
* Shows the element |
|
148 |
*/ |
|
149 |
showElement: function(elm) { |
|
150 |
elm.style.display = ''; |
|
151 |
}, |
|
152 |
|
|
153 |
/** |
|
154 |
* Hides the element |
|
155 |
*/ |
|
156 |
hideElement: function(elm) { |
|
157 |
elm.style.display = 'none'; |
|
158 |
}, |
|
159 |
|
|
160 |
isElementHidden: function(elm) { |
|
161 |
return elm.style.visibility == "hidden"; |
|
162 |
}, |
|
163 |
|
|
164 |
/** |
|
165 |
* Swaps one element with another. To delete use swapDOM(elm, null) |
|
166 |
*/ |
|
167 |
swapDOM: function(dest, src) { |
|
168 |
dest = this.getElement(dest); |
|
169 |
var parent = dest.parentNode; |
|
170 |
if (src) { |
|
171 |
src = this.getElement(src); |
|
172 |
parent.replaceChild(src, dest); |
|
173 |
} else { |
|
174 |
parent.removeChild(dest); |
|
175 |
} |
|
176 |
return src; |
|
177 |
}, |
|
178 |
|
|
179 |
/** |
|
180 |
* Removes an element from the world |
|
181 |
*/ |
|
182 |
removeElement: function(elm) { |
|
183 |
this.swapDOM(elm, null); |
|
184 |
}, |
|
185 |
|
|
186 |
/** |
|
187 |
* @returns Is an object a dictionary? |
|
188 |
*/ |
|
189 |
isDict: function(o) { |
|
190 |
var str_repr = String(o); |
|
191 |
return str_repr.indexOf(" Object") != -1; |
|
192 |
}, |
|
193 |
|
|
194 |
/** |
|
195 |
* Creates a DOM element |
|
196 |
* @param {String} name The elements DOM name |
|
197 |
* @param {Dict} attrs Attributes sent to the function |
|
198 |
*/ |
|
199 |
createDOM: function(name, attrs) { |
|
200 |
var i=0; |
|
201 |
elm = document.createElement(name); |
|
202 |
|
|
203 |
if(this.isDict(attrs[i])) { |
|
204 |
for(k in attrs[0]) { |
|
205 |
if(k == "style") |
|
206 |
elm.style.cssText = attrs[0][k]; |
|
207 |
else if(k == "class") |
|
208 |
elm.className = attrs[0][k]; |
|
209 |
else |
|
210 |
elm.setAttribute(k, attrs[0][k]); |
|
211 |
} |
|
212 |
i++; |
|
213 |
} |
|
214 |
|
|
215 |
if(attrs[0] == null) |
|
216 |
i = 1; |
|
217 |
|
|
218 |
for(i; i < attrs.length; i++) { |
|
219 |
var n = attrs[i]; |
|
220 |
if(this.isDefined(n)) { |
|
221 |
if(typeof(n) == "string") |
|
222 |
n = document.createTextNode(n); |
|
223 |
elm.appendChild(n); |
|
224 |
} |
|
225 |
} |
|
226 |
return elm; |
|
227 |
}, |
|
228 |
|
|
229 |
UL: function() { return this.createDOM.apply(this, ["ul", arguments]); }, |
|
230 |
LI: function() { return this.createDOM.apply(this, ["li", arguments]); }, |
|
231 |
TD: function() { return this.createDOM.apply(this, ["td", arguments]); }, |
|
232 |
TR: function() { return this.createDOM.apply(this, ["tr", arguments]); }, |
|
233 |
TH: function() { return this.createDOM.apply(this, ["th", arguments]); }, |
|
234 |
TBODY: function() { return this.createDOM.apply(this, ["tbody", arguments]); }, |
|
235 |
TABLE: function() { return this.createDOM.apply(this, ["table", arguments]); }, |
|
236 |
INPUT: function() { return this.createDOM.apply(this, ["input", arguments]); }, |
|
237 |
SPAN: function() { return this.createDOM.apply(this, ["span", arguments]); }, |
|
238 |
B: function() { return this.createDOM.apply(this, ["b", arguments]); }, |
|
239 |
A: function() { return this.createDOM.apply(this, ["a", arguments]); }, |
|
240 |
DIV: function() { return this.createDOM.apply(this, ["div", arguments]); }, |
|
241 |
IMG: function() { return this.createDOM.apply(this, ["img", arguments]); }, |
|
242 |
BUTTON: function() { return this.createDOM.apply(this, ["button", arguments]); }, |
|
243 |
H1: function() { return this.createDOM.apply(this, ["h1", arguments]); }, |
|
244 |
H2: function() { return this.createDOM.apply(this, ["h2", arguments]); }, |
|
245 |
H3: function() { return this.createDOM.apply(this, ["h3", arguments]); }, |
|
246 |
BR: function() { return this.createDOM.apply(this, ["br", arguments]); }, |
|
247 |
TEXTAREA: function() { return this.createDOM.apply(this, ["textarea", arguments]); }, |
|
248 |
FORM: function() { return this.createDOM.apply(this, ["form", arguments]); }, |
|
249 |
P: function() { return this.createDOM.apply(this, ["p", arguments]); }, |
|
250 |
SELECT: function() { return this.createDOM.apply(this, ["select", arguments]); }, |
|
251 |
OPTION: function() { return this.createDOM.apply(this, ["option", arguments]); }, |
|
252 |
TN: function(text) { return document.createTextNode(text); }, |
|
253 |
IFRAME: function() { return this.createDOM.apply(this, ["iframe", arguments]); }, |
|
254 |
SCRIPT: function() { return this.createDOM.apply(this, ["script", arguments]); }, |
|
255 |
|
|
256 |
//// |
|
257 |
// Ajax functions |
|
258 |
//// |
|
259 |
/** |
|
260 |
* @returns A new XMLHttpRequest object |
|
261 |
*/ |
|
262 |
getXMLHttpRequest: function() { |
|
263 |
var try_these = [ |
|
264 |
function () { return new XMLHttpRequest(); }, |
|
265 |
function () { return new ActiveXObject('Msxml2.XMLHTTP'); }, |
|
266 |
function () { return new ActiveXObject('Microsoft.XMLHTTP'); }, |
|
267 |
function () { return new ActiveXObject('Msxml2.XMLHTTP.4.0'); }, |
|
268 |
function () { throw "Browser does not support XMLHttpRequest"; } |
|
269 |
]; |
|
270 |
for (var i = 0; i < try_these.length; i++) { |
|
271 |
var func = try_these[i]; |
|
272 |
try { |
|
273 |
return func(); |
|
274 |
} catch (e) { |
|
275 |
} |
|
276 |
} |
|
277 |
}, |
|
278 |
|
|
279 |
/** |
|
280 |
* Use this function to do a simple HTTP Request |
|
281 |
*/ |
|
282 |
doSimpleXMLHttpRequest: function(url) { |
|
283 |
var req = this.getXMLHttpRequest(); |
|
284 |
req.open("GET", url, true); |
|
285 |
return this.sendXMLHttpRequest(req); |
|
286 |
}, |
|
287 |
|
|
288 |
getRequest: function(url, data) { |
|
289 |
var req = this.getXMLHttpRequest(); |
|
290 |
req.open("POST", url, true); |
|
291 |
req.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); |
|
292 |
return this.sendXMLHttpRequest(req); |
|
293 |
}, |
|
294 |
|
|
295 |
/** |
|
296 |
* Send a XMLHttpRequest |
|
297 |
*/ |
|
298 |
sendXMLHttpRequest: function(req, data) { |
|
299 |
var d = new AJSDeferred(req); |
|
300 |
|
|
301 |
var onreadystatechange = function () { |
|
302 |
if (req.readyState == 4) { |
|
303 |
try { |
bb76bc
|
304 |
var status = req.status; |
dd53e2
|
305 |
} |
T |
306 |
catch(e) {}; |
|
307 |
if(status == 200 || status == 304 || req.responseText == null) { |
|
308 |
d.callback(req, data); |
|
309 |
} |
|
310 |
else { |
|
311 |
d.errback(); |
|
312 |
} |
|
313 |
} |
|
314 |
} |
|
315 |
req.onreadystatechange = onreadystatechange; |
|
316 |
return d; |
|
317 |
}, |
|
318 |
|
|
319 |
/** |
|
320 |
* Represent an object as a string |
|
321 |
*/ |
|
322 |
reprString: function(o) { |
|
323 |
return ('"' + o.replace(/(["\\])/g, '\\$1') + '"' |
|
324 |
).replace(/[\f]/g, "\\f" |
|
325 |
).replace(/[\b]/g, "\\b" |
|
326 |
).replace(/[\n]/g, "\\n" |
|
327 |
).replace(/[\t]/g, "\\t" |
|
328 |
).replace(/[\r]/g, "\\r"); |
|
329 |
}, |
|
330 |
|
|
331 |
/** |
|
332 |
* Serialize an object to JSON notation |
|
333 |
*/ |
|
334 |
serializeJSON: function(o) { |
|
335 |
var objtype = typeof(o); |
|
336 |
if (objtype == "undefined") { |
|
337 |
return "undefined"; |
|
338 |
} else if (objtype == "number" || objtype == "boolean") { |
|
339 |
return o + ""; |
|
340 |
} else if (o === null) { |
|
341 |
return "null"; |
|
342 |
} |
|
343 |
if (objtype == "string") { |
|
344 |
return this.reprString(o); |
|
345 |
} |
|
346 |
var me = arguments.callee; |
|
347 |
var newObj; |
|
348 |
if (typeof(o.__json__) == "function") { |
|
349 |
newObj = o.__json__(); |
|
350 |
if (o !== newObj) { |
|
351 |
return me(newObj); |
|
352 |
} |
|
353 |
} |
|
354 |
if (typeof(o.json) == "function") { |
|
355 |
newObj = o.json(); |
|
356 |
if (o !== newObj) { |
|
357 |
return me(newObj); |
|
358 |
} |
|
359 |
} |
|
360 |
if (objtype != "function" && typeof(o.length) == "number") { |
|
361 |
var res = []; |
|
362 |
for (var i = 0; i < o.length; i++) { |
|
363 |
var val = me(o[i]); |
|
364 |
if (typeof(val) != "string") { |
|
365 |
val = "undefined"; |
|
366 |
} |
|
367 |
res.push(val); |
|
368 |
} |
|
369 |
return "[" + res.join(",") + "]"; |
|
370 |
} |
|
371 |
res = []; |
|
372 |
for (var k in o) { |
|
373 |
var useKey; |
|
374 |
if (typeof(k) == "number") { |
|
375 |
useKey = '"' + k + '"'; |
|
376 |
} else if (typeof(k) == "string") { |
|
377 |
useKey = this.reprString(k); |
|
378 |
} else { |
|
379 |
// skip non-string or number keys |
|
380 |
continue; |
|
381 |
} |
|
382 |
val = me(o[k]); |
|
383 |
if (typeof(val) != "string") { |
|
384 |
// skip non-serializable values |
|
385 |
continue; |
|
386 |
} |
|
387 |
res.push(useKey + ":" + val); |
|
388 |
} |
|
389 |
return "{" + res.join(",") + "}"; |
|
390 |
}, |
|
391 |
|
|
392 |
/** |
|
393 |
* Send and recive JSON using GET |
|
394 |
*/ |
|
395 |
loadJSONDoc: function(url) { |
|
396 |
var d = this.getRequest(url); |
|
397 |
var eval_req = function(req) { |
|
398 |
var text = req.responseText; |
|
399 |
return eval('(' + text + ')'); |
|
400 |
}; |
|
401 |
d.addCallback(eval_req); |
|
402 |
return d; |
|
403 |
}, |
|
404 |
|
|
405 |
|
|
406 |
//// |
|
407 |
// Misc. |
|
408 |
//// |
|
409 |
/** |
|
410 |
* Alert the objects key attrs |
|
411 |
*/ |
|
412 |
keys: function(obj) { |
|
413 |
var rval = []; |
|
414 |
for (var prop in obj) { |
|
415 |
rval.push(prop); |
|
416 |
} |
|
417 |
return rval; |
|
418 |
}, |
|
419 |
|
|
420 |
urlencode: function(str) { |
|
421 |
return encodeURIComponent(str.toString()); |
|
422 |
}, |
|
423 |
|
|
424 |
/** |
|
425 |
* @returns True if the object is defined, otherwise false |
|
426 |
*/ |
|
427 |
isDefined: function(o) { |
|
428 |
return (o != "undefined" && o != null) |
|
429 |
}, |
|
430 |
|
|
431 |
/** |
|
432 |
* @returns True if an object is a array, false otherwise |
|
433 |
*/ |
|
434 |
isArray: function(obj) { |
|
435 |
try { return (typeof(obj.length) == "undefined") ? false : true; } |
|
436 |
catch(e) |
|
437 |
{ return false; } |
|
438 |
}, |
|
439 |
|
|
440 |
isObject: function(obj) { |
|
441 |
return (obj && typeof obj == 'object'); |
|
442 |
}, |
|
443 |
|
|
444 |
/** |
|
445 |
* Export DOM elements to the global namespace |
|
446 |
*/ |
|
447 |
exportDOMElements: function() { |
|
448 |
UL = this.UL; |
|
449 |
LI = this.LI; |
|
450 |
TD = this.TD; |
|
451 |
TR = this.TR; |
|
452 |
TH = this.TH; |
|
453 |
TBODY = this.TBODY; |
|
454 |
TABLE = this.TABLE; |
|
455 |
INPUT = this.INPUT; |
|
456 |
SPAN = this.SPAN; |
|
457 |
B = this.B; |
|
458 |
A = this.A; |
|
459 |
DIV = this.DIV; |
|
460 |
IMG = this.IMG; |
|
461 |
BUTTON = this.BUTTON; |
|
462 |
H1 = this.H1; |
|
463 |
H2 = this.H2; |
|
464 |
H3 = this.H3; |
|
465 |
BR = this.BR; |
|
466 |
TEXTAREA = this.TEXTAREA; |
|
467 |
FORM = this.FORM; |
|
468 |
P = this.P; |
|
469 |
SELECT = this.SELECT; |
|
470 |
OPTION = this.OPTION; |
|
471 |
TN = this.TN; |
|
472 |
IFRAME = this.IFRAME; |
|
473 |
SCRIPT = this.SCRIPT; |
|
474 |
}, |
|
475 |
|
|
476 |
/** |
|
477 |
* Export AmiJS functions to the global namespace |
|
478 |
*/ |
|
479 |
exportToGlobalScope: function() { |
|
480 |
getElement = this.getElement; |
|
481 |
getQueryArgument = this.getQueryArgument; |
|
482 |
isIe = this.isIe; |
|
483 |
$ = this.getElement; |
|
484 |
getElements = this.getElements; |
|
485 |
getBody = this.getBody; |
|
486 |
getElementsByTagAndClassName = this.getElementsByTagAndClassName; |
|
487 |
appendChildNodes = this.appendChildNodes; |
|
488 |
ACN = appendChildNodes; |
|
489 |
replaceChildNodes = this.replaceChildNodes; |
|
490 |
RCN = replaceChildNodes; |
|
491 |
insertAfter = this.insertAfter; |
|
492 |
insertBefore = this.insertBefore; |
|
493 |
showElement = this.showElement; |
|
494 |
hideElement = this.hideElement; |
|
495 |
isElementHidden = this.isElementHidden; |
|
496 |
swapDOM = this.swapDOM; |
|
497 |
removeElement = this.removeElement; |
|
498 |
isDict = this.isDict; |
|
499 |
createDOM = this.createDOM; |
|
500 |
this.exportDOMElements(); |
|
501 |
getXMLHttpRequest = this.getXMLHttpRequest; |
|
502 |
doSimpleXMLHttpRequest = this.doSimpleXMLHttpRequest; |
|
503 |
getRequest = this.getRequest; |
|
504 |
sendXMLHttpRequest = this.sendXMLHttpRequest; |
|
505 |
reprString = this.reprString; |
|
506 |
serializeJSON = this.serializeJSON; |
|
507 |
loadJSONDoc = this.loadJSONDoc; |
|
508 |
keys = this.keys; |
|
509 |
isDefined = this.isDefined; |
|
510 |
isArray = this.isArray; |
|
511 |
} |
|
512 |
} |
|
513 |
|
|
514 |
|
|
515 |
|
|
516 |
AJSDeferred = function(req) { |
|
517 |
this.callbacks = []; |
|
518 |
this.req = req; |
|
519 |
|
|
520 |
this.callback = function (res) { |
|
521 |
while (this.callbacks.length > 0) { |
|
522 |
var fn = this.callbacks.pop(); |
|
523 |
res = fn(res); |
|
524 |
} |
|
525 |
}; |
|
526 |
|
|
527 |
this.errback = function(e){ |
|
528 |
alert("Error encountered:\n" + e); |
|
529 |
}; |
|
530 |
|
|
531 |
this.addErrback = function(fn) { |
|
532 |
this.errback = fn; |
|
533 |
}; |
|
534 |
|
|
535 |
this.addCallback = function(fn) { |
|
536 |
this.callbacks.unshift(fn); |
|
537 |
}; |
|
538 |
|
|
539 |
this.addCallbacks = function(fn1, fn2) { |
|
540 |
this.addCallback(fn1); |
|
541 |
this.addErrback(fn2); |
|
542 |
}; |
|
543 |
|
|
544 |
this.sendReq = function(data) { |
|
545 |
if(AJS.isObject(data)) { |
|
546 |
var post_data = []; |
|
547 |
for(k in data) { |
|
548 |
post_data.push(k + "=" + AJS.urlencode(data[k])); |
|
549 |
} |
|
550 |
post_data = post_data.join("&"); |
|
551 |
this.req.send(post_data); |
|
552 |
} |
|
553 |
else if(AJS.isDefined(data)) |
|
554 |
this.req.send(data); |
|
555 |
else { |
|
556 |
this.req.send(""); |
|
557 |
} |
|
558 |
}; |
|
559 |
}; |
|
560 |
AJSDeferred.prototype = new AJSDeferred(); |
|
561 |
|
|
562 |
|
|
563 |
|
|
564 |
|
|
565 |
|
|
566 |
|
|
567 |
/**** |
|
568 |
Last Modified: 28/04/06 15:26:06 |
|
569 |
|
|
570 |
GoogieSpell |
|
571 |
Google spell checker for your own web-apps :) |
|
572 |
Copyright Amir Salihefendic 2006 |
|
573 |
LICENSE |
|
574 |
GPL (see gpl.txt for more information) |
|
575 |
This basically means that you can't use this script with/in proprietary software! |
|
576 |
There is another license that permits you to use this script with proprietary software. Check out:... for more info. |
|
577 |
AUTHOR |
|
578 |
4mir Salihefendic (http://amix.dk) - amix@amix.dk |
|
579 |
VERSION |
|
580 |
3.22 |
|
581 |
****/ |
|
582 |
var GOOGIE_CUR_LANG = "en"; |
|
583 |
|
|
584 |
function GoogieSpell(img_dir, server_url) { |
|
585 |
var cookie_value; |
|
586 |
var lang; |
|
587 |
cookie_value = getCookie('language'); |
|
588 |
|
|
589 |
if(cookie_value != null) |
|
590 |
GOOGIE_CUR_LANG = cookie_value; |
|
591 |
|
|
592 |
this.img_dir = img_dir; |
|
593 |
this.server_url = server_url; |
|
594 |
|
|
595 |
this.lang_to_word = {"da": "Dansk", "de": "Deutsch", "en": "English", |
|
596 |
"es": "Español", "fr": "Français", "it": "Italiano", |
|
597 |
"nl": "Nederlands", "pl": "Polski", "pt": "Português", |
|
598 |
"fi": "Suomi", "sv": "Svenska"}; |
|
599 |
this.langlist_codes = AJS.keys(this.lang_to_word); |
|
600 |
|
|
601 |
this.show_change_lang_pic = true; |
|
602 |
|
|
603 |
this.lang_state_observer = null; |
|
604 |
|
|
605 |
this.spelling_state_observer = null; |
|
606 |
|
|
607 |
this.request = null; |
|
608 |
this.error_window = null; |
|
609 |
this.language_window = null; |
|
610 |
this.edit_layer = null; |
|
611 |
this.orginal_text = null; |
|
612 |
this.results = null; |
|
613 |
this.text_area = null; |
|
614 |
this.gselm = null; |
|
615 |
this.ta_scroll_top = 0; |
|
616 |
this.el_scroll_top = 0; |
|
617 |
|
|
618 |
this.lang_chck_spell = "Check spelling"; |
|
619 |
this.lang_rsm_edt = "Resume editing"; |
|
620 |
this.lang_close = "Close"; |
|
621 |
this.lang_no_error_found = "No spelling errors found"; |
|
622 |
this.lang_revert = "Revert to"; |
|
623 |
this.show_spell_img = false; // modified by roundcube |
|
624 |
} |
|
625 |
|
|
626 |
GoogieSpell.prototype.setStateChanged = function(current_state) { |
|
627 |
if(this.spelling_state_observer != null) |
|
628 |
this.spelling_state_observer(current_state); |
|
629 |
} |
|
630 |
|
|
631 |
GoogieSpell.item_onmouseover = function(e) { |
|
632 |
var elm = GoogieSpell.getEventElm(e); |
|
633 |
if(elm.className != "googie_list_close" && elm.className != "googie_list_revert") |
|
634 |
elm.className = "googie_list_onhover"; |
|
635 |
else |
|
636 |
elm.parentNode.className = "googie_list_onhover"; |
|
637 |
} |
|
638 |
|
|
639 |
GoogieSpell.item_onmouseout = function(e) { |
|
640 |
var elm = GoogieSpell.getEventElm(e); |
|
641 |
if(elm.className != "googie_list_close" && elm.className != "googie_list_revert") |
|
642 |
elm.className = "googie_list_onout"; |
|
643 |
else |
|
644 |
elm.parentNode.className = "googie_list_onout"; |
|
645 |
} |
|
646 |
|
|
647 |
GoogieSpell.prototype.getGoogleUrl = function() { |
|
648 |
return this.server_url + GOOGIE_CUR_LANG; |
|
649 |
} |
|
650 |
|
|
651 |
GoogieSpell.prototype.spellCheck = function(elm, name) { |
|
652 |
this.ta_scroll_top = this.text_area.scrollTop; |
|
653 |
|
|
654 |
this.appendIndicator(elm); |
|
655 |
|
|
656 |
try { |
|
657 |
this.hideLangWindow(); |
|
658 |
} |
|
659 |
catch(e) {} |
|
660 |
|
|
661 |
this.gselm = elm; |
|
662 |
|
|
663 |
this.createEditLayer(this.text_area.offsetWidth, this.text_area.offsetHeight); |
|
664 |
|
|
665 |
this.createErrorWindow(); |
|
666 |
AJS.getBody().appendChild(this.error_window); |
|
667 |
|
|
668 |
try { netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserRead"); } |
|
669 |
catch (e) { } |
|
670 |
|
|
671 |
this.gselm.onclick = null; |
|
672 |
|
|
673 |
this.orginal_text = this.text_area.value; |
|
674 |
var me = this; |
|
675 |
|
|
676 |
//Create request |
|
677 |
var d = AJS.getRequest(this.getGoogleUrl()); |
|
678 |
var reqdone = function(req) { |
|
679 |
var r_text = req.responseText; |
|
680 |
if(r_text.match(/<c.*>/) != null) { |
|
681 |
var results = GoogieSpell.parseResult(r_text); |
|
682 |
//Before parsing be sure that errors were found |
|
683 |
me.results = results; |
|
684 |
me.showErrorsInIframe(results); |
|
685 |
me.resumeEditingState(); |
|
686 |
} |
|
687 |
else { |
|
688 |
me.flashNoSpellingErrorState(); |
|
689 |
} |
|
690 |
me.removeIndicator(); |
|
691 |
}; |
|
692 |
|
|
693 |
var reqfailed = function(req) { |
|
694 |
alert("An error was encountered on the server. Please try again later."); |
|
695 |
AJS.removeElement(me.gselm); |
|
696 |
me.checkSpellingState(); |
|
697 |
me.removeIndicator(); |
|
698 |
}; |
|
699 |
|
|
700 |
d.addCallback(reqdone); |
|
701 |
d.addErrback(reqfailed); |
|
702 |
|
|
703 |
var req_text = GoogieSpell.escapeSepcial(this.orginal_text); |
|
704 |
d.sendReq(GoogieSpell.createXMLReq(req_text)); |
|
705 |
} |
|
706 |
|
|
707 |
GoogieSpell.escapeSepcial = function(val) { |
|
708 |
return val.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">"); |
|
709 |
} |
|
710 |
|
|
711 |
GoogieSpell.createXMLReq = function (text) { |
|
712 |
return '<?xml version="1.0" encoding="utf-8" ?><spellrequest textalreadyclipped="0" ignoredups="0" ignoredigits="1" ignoreallcaps="1"><text>' + text + '</text></spellrequest>'; |
|
713 |
} |
|
714 |
|
|
715 |
//Retunrs an array |
|
716 |
//result[item] -> ['attrs'] |
|
717 |
// ['suggestions'] |
|
718 |
GoogieSpell.parseResult = function(r_text) { |
|
719 |
var re_split_attr_c = /\w="\d+"/g; |
|
720 |
var re_split_text = /\t/g; |
|
721 |
|
|
722 |
var matched_c = r_text.match(/<c[^>]*>[^<]*<\/c>/g); |
|
723 |
var results = new Array(); |
|
724 |
|
|
725 |
for(var i=0; i < matched_c.length; i++) { |
|
726 |
var item = new Array(); |
|
727 |
|
|
728 |
//Get attributes |
|
729 |
item['attrs'] = new Array(); |
|
730 |
var split_c = matched_c[i].match(re_split_attr_c); |
|
731 |
for(var j=0; j < split_c.length; j++) { |
|
732 |
var c_attr = split_c[j].split(/=/); |
|
733 |
item['attrs'][c_attr[0]] = parseInt(c_attr[1].replace('"', '')); |
|
734 |
} |
|
735 |
|
|
736 |
//Get suggestions |
|
737 |
item['suggestions'] = new Array(); |
|
738 |
var only_text = matched_c[i].replace(/<[^>]*>/g, ""); |
|
739 |
var split_t = only_text.split(re_split_text); |
|
740 |
for(var k=0; k < split_t.length; k++) { |
|
741 |
if(split_t[k] != "") |
|
742 |
item['suggestions'].push(split_t[k]); |
|
743 |
} |
|
744 |
results.push(item); |
|
745 |
} |
|
746 |
return results; |
|
747 |
} |
|
748 |
|
|
749 |
/**** |
|
750 |
Error window (the drop-down window) |
|
751 |
****/ |
|
752 |
GoogieSpell.prototype.createErrorWindow = function() { |
|
753 |
this.error_window = AJS.DIV(); |
|
754 |
this.error_window.className = "googie_window"; |
|
755 |
} |
|
756 |
|
|
757 |
GoogieSpell.prototype.hideErrorWindow = function() { |
|
758 |
this.error_window.style.visibility = "hidden"; |
|
759 |
} |
|
760 |
|
|
761 |
GoogieSpell.prototype.updateOrginalText = function(offset, old_value, new_value, id) { |
|
762 |
var part_1 = this.orginal_text.substring(0, offset); |
|
763 |
var part_2 = this.orginal_text.substring(offset+old_value.length); |
|
764 |
this.orginal_text = part_1 + new_value + part_2; |
|
765 |
var add_2_offset = new_value.length - old_value.length; |
|
766 |
for(var j=0; j < this.results.length; j++) { |
|
767 |
//Don't edit the offset of the current item |
|
768 |
if(j != id && j > id){ |
|
769 |
this.results[j]['attrs']['o'] += add_2_offset; |
|
770 |
} |
|
771 |
} |
|
772 |
} |
|
773 |
|
|
774 |
GoogieSpell.prototype.saveOldValue = function (id, old_value) { |
|
775 |
this.results[id]['is_changed'] = true; |
|
776 |
this.results[id]['old_value'] = old_value; |
|
777 |
} |
|
778 |
|
|
779 |
GoogieSpell.prototype.showErrorWindow = function(elm, id) { |
|
780 |
var me = this; |
|
781 |
|
|
782 |
var abs_pos = GoogieSpell.absolutePosition(elm); |
|
783 |
abs_pos.y -= this.edit_layer.scrollTop; |
|
784 |
this.error_window.style.visibility = "visible"; |
|
785 |
this.error_window.style.top = (abs_pos.y+20) + "px"; |
|
786 |
this.error_window.style.left = (abs_pos.x) + "px"; |
|
787 |
this.error_window.innerHTML = ""; |
|
788 |
|
|
789 |
//Build up the result list |
|
790 |
var table = AJS.TABLE({'class': 'googie_list'}); |
|
791 |
var list = AJS.TBODY(); |
|
792 |
|
|
793 |
var suggestions = this.results[id]['suggestions']; |
|
794 |
var offset = this.results[id]['attrs']['o']; |
|
795 |
var len = this.results[id]['attrs']['l']; |
|
796 |
|
|
797 |
if(suggestions.length == 0) { |
|
798 |
var row = AJS.TR(); |
|
799 |
var item = AJS.TD(); |
|
800 |
var dummy = AJS.SPAN(); |
|
801 |
item.appendChild(AJS.TN("No suggestions :(")); |
|
802 |
row.appendChild(item); |
|
803 |
list.appendChild(row); |
|
804 |
} |
|
805 |
|
|
806 |
for(i=0; i < suggestions.length; i++) { |
|
807 |
var row = AJS.TR(); |
|
808 |
var item = AJS.TD(); |
|
809 |
var dummy = AJS.SPAN(); |
|
810 |
dummy.innerHTML = suggestions[i]; |
|
811 |
item.appendChild(AJS.TN(dummy.innerHTML)); |
|
812 |
|
|
813 |
item.onclick = function(e) { |
|
814 |
var l_elm = GoogieSpell.getEventElm(e); |
|
815 |
var old_value = elm.innerHTML; |
|
816 |
var new_value = l_elm.innerHTML; |
|
817 |
|
|
818 |
elm.style.color = "green"; |
|
819 |
elm.innerHTML = l_elm.innerHTML; |
|
820 |
me.hideErrorWindow(); |
|
821 |
|
|
822 |
me.updateOrginalText(offset, old_value, new_value, id); |
|
823 |
|
|
824 |
//Update to the new length |
|
825 |
me.results[id]['attrs']['l'] = new_value.length; |
|
826 |
me.saveOldValue(id, old_value); |
|
827 |
}; |
|
828 |
item.onmouseover = GoogieSpell.item_onmouseover; |
|
829 |
item.onmouseout = GoogieSpell.item_onmouseout; |
|
830 |
row.appendChild(item); |
|
831 |
list.appendChild(row); |
|
832 |
} |
|
833 |
|
|
834 |
//The element is changed, append the revert |
|
835 |
if(this.results[id]['is_changed']) { |
|
836 |
var old_value = this.results[id]['old_value']; |
|
837 |
var offset = this.results[id]['attrs']['o']; |
|
838 |
var revert_row = AJS.TR(); |
|
839 |
var revert = AJS.TD(); |
|
840 |
|
|
841 |
revert.onmouseover = GoogieSpell.item_onmouseover; |
|
842 |
revert.onmouseout = GoogieSpell.item_onmouseout; |
|
843 |
var rev_span = AJS.SPAN({'class': 'googie_list_revert'}); |
|
844 |
rev_span.innerHTML = this.lang_revert + " " + old_value; |
|
845 |
revert.appendChild(rev_span); |
|
846 |
|
|
847 |
revert.onclick = function(e) { |
|
848 |
me.updateOrginalText(offset, elm.innerHTML, old_value, id); |
|
849 |
elm.style.color = "#b91414"; |
|
850 |
elm.innerHTML = old_value; |
|
851 |
me.hideErrorWindow(); |
|
852 |
}; |
|
853 |
|
|
854 |
revert_row.appendChild(revert); |
|
855 |
list.appendChild(revert_row); |
|
856 |
} |
|
857 |
|
|
858 |
//Append the edit box |
|
859 |
var edit_row = AJS.TR(); |
|
860 |
var edit = AJS.TD(); |
|
861 |
|
|
862 |
var edit_input = AJS.INPUT({'style': 'width: 120px; margin:0; padding:0'}); |
|
863 |
|
|
864 |
var onsub = function () { |
|
865 |
if(edit_input.value != "") { |
|
866 |
me.saveOldValue(id, elm.innerHTML); |
|
867 |
me.updateOrginalText(offset, elm.innerHTML, edit_input.value, id); |
|
868 |
elm.style.color = "green" |
|
869 |
elm.innerHTML = edit_input.value; |
|
870 |
|
|
871 |
me.hideErrorWindow(); |
|
872 |
return false; |
|
873 |
} |
|
874 |
}; |
|
875 |
|
|
876 |
var ok_pic = AJS.IMG({'src': this.img_dir + "ok.gif", 'style': 'width: 32px; height: 16px; margin-left: 2px; margin-right: 2px;'}); |
|
877 |
var edit_form = AJS.FORM({'style': 'margin: 0; padding: 0'}, edit_input, ok_pic); |
|
878 |
ok_pic.onclick = onsub; |
|
879 |
edit_form.onsubmit = onsub; |
|
880 |
|
|
881 |
edit.appendChild(edit_form); |
|
882 |
edit_row.appendChild(edit); |
|
883 |
list.appendChild(edit_row); |
|
884 |
|
|
885 |
//Close button |
|
886 |
var close_row = AJS.TR(); |
|
887 |
var close = AJS.TD(); |
|
888 |
|
|
889 |
close.onmouseover = GoogieSpell.item_onmouseover; |
|
890 |
close.onmouseout = GoogieSpell.item_onmouseout; |
|
891 |
|
|
892 |
var spn_close = AJS.SPAN({'class': 'googie_list_close'}); |
|
893 |
spn_close.innerHTML = this.lang_close; |
|
894 |
close.appendChild(spn_close); |
|
895 |
close.onclick = function() { me.hideErrorWindow()}; |
|
896 |
close_row.appendChild(close); |
|
897 |
list.appendChild(close_row); |
|
898 |
|
|
899 |
table.appendChild(list); |
|
900 |
this.error_window.appendChild(table); |
|
901 |
} |
|
902 |
|
|
903 |
|
|
904 |
/**** |
|
905 |
Edit layer (the layer where the suggestions are stored) |
|
906 |
****/ |
|
907 |
GoogieSpell.prototype.createEditLayer = function(width, height) { |
|
908 |
this.edit_layer = AJS.DIV({'class': 'googie_edit_layer'}); |
|
909 |
|
|
910 |
//Set the style so it looks like edit areas |
|
911 |
this.edit_layer.className = this.text_area.className; |
|
912 |
this.edit_layer.style.border = "1px solid #999"; |
|
913 |
this.edit_layer.style.overflow = "auto"; |
|
914 |
this.edit_layer.style.backgroundColor = "#F1EDFE"; |
|
915 |
this.edit_layer.style.padding = "3px"; |
|
916 |
|
|
917 |
this.edit_layer.style.width = (width-8) + "px"; |
|
918 |
this.edit_layer.style.height = height + "px"; |
|
919 |
} |
|
920 |
|
|
921 |
GoogieSpell.prototype.resumeEditing = function(e, me) { |
|
922 |
this.setStateChanged("check_spelling"); |
|
923 |
me.switch_lan_pic.style.display = "inline"; |
|
924 |
|
|
925 |
this.el_scroll_top = me.edit_layer.scrollTop; |
|
926 |
|
|
927 |
var elm = GoogieSpell.getEventElm(e); |
|
928 |
AJS.replaceChildNodes(elm, this.createSpellDiv()); |
|
929 |
|
|
930 |
elm.onclick = function(e) { |
|
931 |
me.spellCheck(elm, me.text_area.id); |
|
932 |
}; |
|
933 |
me.hideErrorWindow(); |
|
934 |
|
|
935 |
//Remove the EDIT_LAYER |
|
936 |
me.edit_layer.parentNode.removeChild(me.edit_layer); |
|
937 |
|
|
938 |
me.text_area.value = me.orginal_text; |
|
939 |
AJS.showElement(me.text_area); |
|
940 |
me.gselm.className = "googie_no_style"; |
|
941 |
|
|
942 |
me.text_area.scrollTop = this.el_scroll_top; |
|
943 |
|
|
944 |
elm.onmouseout = null; |
|
945 |
} |
|
946 |
|
|
947 |
GoogieSpell.prototype.createErrorLink = function(text, id) { |
|
948 |
var elm = AJS.SPAN({'class': 'googie_link'}); |
|
949 |
var me = this; |
|
950 |
elm.onclick = function () { |
|
951 |
me.showErrorWindow(elm, id); |
|
952 |
}; |
|
953 |
elm.innerHTML = text; |
|
954 |
return elm; |
|
955 |
} |
|
956 |
|
|
957 |
GoogieSpell.createPart = function(txt_part) { |
|
958 |
if(txt_part == " ") |
|
959 |
return AJS.TN(" "); |
|
960 |
var result = AJS.SPAN(); |
|
961 |
|
|
962 |
var is_first = true; |
|
963 |
var is_safari = (navigator.userAgent.toLowerCase().indexOf("safari") != -1); |
|
964 |
|
|
965 |
var part = AJS.SPAN(); |
|
966 |
txt_part = GoogieSpell.escapeSepcial(txt_part); |
|
967 |
txt_part = txt_part.replace(/\n/g, "<br>"); |
|
968 |
txt_part = txt_part.replace(/ /g, " "); |
|
969 |
txt_part = txt_part.replace(/^ /g, " "); |
|
970 |
txt_part = txt_part.replace(/ $/g, " "); |
|
971 |
|
|
972 |
part.innerHTML = txt_part; |
|
973 |
|
|
974 |
return part; |
|
975 |
} |
|
976 |
|
|
977 |
GoogieSpell.prototype.showErrorsInIframe = function(results) { |
|
978 |
var output = AJS.DIV(); |
|
979 |
output.style.textAlign = "left"; |
|
980 |
var pointer = 0; |
|
981 |
for(var i=0; i < results.length; i++) { |
|
982 |
var offset = results[i]['attrs']['o']; |
|
983 |
var len = results[i]['attrs']['l']; |
|
984 |
|
|
985 |
var part_1_text = this.orginal_text.substring(pointer, offset); |
|
986 |
var part_1 = GoogieSpell.createPart(part_1_text); |
|
987 |
output.appendChild(part_1); |
|
988 |
pointer += offset - pointer; |
|
989 |
|
|
990 |
//If the last child was an error, then insert some space |
|
991 |
output.appendChild(this.createErrorLink(this.orginal_text.substr(offset, len), i)); |
|
992 |
pointer += len; |
|
993 |
} |
|
994 |
//Insert the rest of the orginal text |
|
995 |
var part_2_text = this.orginal_text.substr(pointer, this.orginal_text.length); |
|
996 |
|
|
997 |
var part_2 = GoogieSpell.createPart(part_2_text); |
|
998 |
output.appendChild(part_2); |
|
999 |
|
|
1000 |
this.edit_layer.appendChild(output); |
|
1001 |
|
|
1002 |
//Hide text area |
|
1003 |
AJS.hideElement(this.text_area); |
|
1004 |
this.text_area.parentNode.insertBefore(this.edit_layer, this.text_area.nextSibling); |
|
1005 |
this.edit_layer.scrollTop = this.ta_scroll_top; |
|
1006 |
} |
|
1007 |
|
|
1008 |
GoogieSpell.Position = function(x, y) { |
|
1009 |
this.x = x; |
|
1010 |
this.y = y; |
|
1011 |
} |
|
1012 |
|
|
1013 |
//Get the absolute position of menu_slide |
|
1014 |
GoogieSpell.absolutePosition = function(element) { |
|
1015 |
//Create a new object that has elements y and x pos... |
|
1016 |
var posObj = new GoogieSpell.Position(element.offsetLeft, element.offsetTop); |
|
1017 |
|
|
1018 |
//Check if the element has an offsetParent - if it has .. loop until it has not |
|
1019 |
if(element.offsetParent) { |
|
1020 |
var temp_pos = GoogieSpell.absolutePosition(element.offsetParent); |
|
1021 |
posObj.x += temp_pos.x; |
|
1022 |
posObj.y += temp_pos.y; |
|
1023 |
} |
|
1024 |
return posObj; |
|
1025 |
} |
|
1026 |
|
|
1027 |
GoogieSpell.getEventElm = function(e) { |
|
1028 |
var targ; |
|
1029 |
if (!e) var e = window.event; |
|
1030 |
if (e.target) targ = e.target; |
|
1031 |
else if (e.srcElement) targ = e.srcElement; |
|
1032 |
if (targ.nodeType == 3) // defeat Safari bug |
|
1033 |
targ = targ.parentNode; |
|
1034 |
return targ; |
|
1035 |
} |
|
1036 |
|
|
1037 |
GoogieSpell.prototype.removeIndicator = function(elm) { |
ed5d29
|
1038 |
// modified by roundcube |
T |
1039 |
if (window.rcube_webmail_client) |
|
1040 |
rcube_webmail_client.set_busy(false); |
|
1041 |
//AJS.removeElement(this.indicator); |
dd53e2
|
1042 |
} |
T |
1043 |
|
|
1044 |
GoogieSpell.prototype.appendIndicator = function(elm) { |
ed5d29
|
1045 |
// modified by roundcube |
T |
1046 |
if (window.rcube_webmail_client) |
|
1047 |
rcube_webmail_client.set_busy(true, 'checking'); |
|
1048 |
/* |
dd53e2
|
1049 |
var img = AJS.IMG({'src': this.img_dir + 'indicator.gif', 'style': 'margin-right: 5px;'}); |
T |
1050 |
img.style.width = "16px"; |
|
1051 |
img.style.height = "16px"; |
|
1052 |
this.indicator = img; |
|
1053 |
img.style.textDecoration = "none"; |
|
1054 |
AJS.insertBefore(img, elm); |
ed5d29
|
1055 |
*/ |
dd53e2
|
1056 |
} |
T |
1057 |
|
|
1058 |
/**** |
|
1059 |
Choose language |
|
1060 |
****/ |
|
1061 |
GoogieSpell.prototype.createLangWindow = function() { |
|
1062 |
this.language_window = AJS.DIV({'class': 'googie_window'}); |
|
1063 |
this.language_window.style.width = "130px"; |
|
1064 |
|
|
1065 |
//Build up the result list |
|
1066 |
var table = AJS.TABLE({'class': 'googie_list'}); |
|
1067 |
var list = AJS.TBODY(); |
|
1068 |
|
|
1069 |
this.lang_elms = new Array(); |
|
1070 |
|
|
1071 |
for(i=0; i < this.langlist_codes.length; i++) { |
|
1072 |
var row = AJS.TR(); |
|
1073 |
var item = AJS.TD(); |
|
1074 |
item.googieId = this.langlist_codes[i]; |
|
1075 |
this.lang_elms.push(item); |
|
1076 |
var lang_span = AJS.SPAN(); |
|
1077 |
lang_span.innerHTML = this.lang_to_word[this.langlist_codes[i]]; |
|
1078 |
item.appendChild(AJS.TN(lang_span.innerHTML)); |
|
1079 |
|
|
1080 |
var me = this; |
|
1081 |
|
|
1082 |
item.onclick = function(e) { |
|
1083 |
var elm = GoogieSpell.getEventElm(e); |
|
1084 |
me.deHighlightCurSel(); |
|
1085 |
|
|
1086 |
me.setCurrentLanguage(elm.googieId); |
|
1087 |
|
|
1088 |
if(me.lang_state_observer != null) { |
|
1089 |
me.lang_state_observer(); |
|
1090 |
} |
|
1091 |
|
|
1092 |
me.highlightCurSel(); |
|
1093 |
me.hideLangWindow(); |
|
1094 |
}; |
|
1095 |
|
|
1096 |
item.onmouseover = function(e) { |
|
1097 |
var i_it = GoogieSpell.getEventElm(e); |
|
1098 |
if(i_it.className != "googie_list_selected") |
|
1099 |
i_it.className = "googie_list_onhover"; |
|
1100 |
}; |
|
1101 |
item.onmouseout = function(e) { |
|
1102 |
var i_it = GoogieSpell.getEventElm(e); |
|
1103 |
if(i_it.className != "googie_list_selected") |
|
1104 |
i_it.className = "googie_list_onout"; |
|
1105 |
}; |
|
1106 |
|
|
1107 |
row.appendChild(item); |
|
1108 |
list.appendChild(row); |
|
1109 |
} |
|
1110 |
|
|
1111 |
this.highlightCurSel(); |
|
1112 |
|
|
1113 |
//Close button |
|
1114 |
var close_row = AJS.TR(); |
|
1115 |
var close = AJS.TD(); |
|
1116 |
close.onmouseover = GoogieSpell.item_onmouseover; |
|
1117 |
close.onmouseout = GoogieSpell.item_onmouseout; |
|
1118 |
var spn_close = AJS.SPAN({'class': 'googie_list_close'}); |
|
1119 |
spn_close.innerHTML = this.lang_close; |
|
1120 |
close.appendChild(spn_close); |
|
1121 |
var me = this; |
|
1122 |
close.onclick = function(e) { |
|
1123 |
me.hideLangWindow(); GoogieSpell.item_onmouseout(e); |
|
1124 |
}; |
|
1125 |
close_row.appendChild(close); |
|
1126 |
list.appendChild(close_row); |
|
1127 |
|
|
1128 |
table.appendChild(list); |
|
1129 |
this.language_window.appendChild(table); |
|
1130 |
} |
|
1131 |
|
|
1132 |
GoogieSpell.prototype.setCurrentLanguage = function(lan_code) { |
|
1133 |
GOOGIE_CUR_LANG = lan_code; |
|
1134 |
|
|
1135 |
//Set cookie |
|
1136 |
var now = new Date(); |
|
1137 |
now.setTime(now.getTime() + 365 * 24 * 60 * 60 * 1000); |
|
1138 |
setCookie('language', lan_code, now); |
|
1139 |
} |
|
1140 |
|
|
1141 |
GoogieSpell.prototype.hideLangWindow = function() { |
|
1142 |
this.language_window.style.visibility = "hidden"; |
|
1143 |
this.switch_lan_pic.className = "googie_lang_3d_on"; |
|
1144 |
} |
|
1145 |
|
|
1146 |
GoogieSpell.prototype.deHighlightCurSel = function() { |
|
1147 |
this.lang_cur_elm.className = "googie_list_onout"; |
|
1148 |
} |
|
1149 |
|
|
1150 |
GoogieSpell.prototype.highlightCurSel = function() { |
|
1151 |
for(var i=0; i < this.lang_elms.length; i++) { |
|
1152 |
if(this.lang_elms[i].googieId == GOOGIE_CUR_LANG) { |
|
1153 |
this.lang_elms[i].className = "googie_list_selected"; |
|
1154 |
this.lang_cur_elm = this.lang_elms[i]; |
|
1155 |
} |
|
1156 |
else { |
|
1157 |
this.lang_elms[i].className = "googie_list_onout"; |
|
1158 |
} |
|
1159 |
} |
|
1160 |
} |
|
1161 |
|
|
1162 |
GoogieSpell.prototype.showLangWindow = function(elm, ofst_top, ofst_left) { |
|
1163 |
if(!AJS.isDefined(ofst_top)) |
|
1164 |
ofst_top = 20; |
|
1165 |
if(!AJS.isDefined(ofst_left)) |
|
1166 |
ofst_left = 50; |
|
1167 |
|
|
1168 |
this.createLangWindow(); |
|
1169 |
AJS.getBody().appendChild(this.language_window); |
|
1170 |
|
|
1171 |
var abs_pos = GoogieSpell.absolutePosition(elm); |
|
1172 |
AJS.showElement(this.language_window); |
|
1173 |
this.language_window.style.top = (abs_pos.y+ofst_top) + "px"; |
|
1174 |
this.language_window.style.left = (abs_pos.x+ofst_left-this.language_window.offsetWidth) + "px"; |
|
1175 |
this.highlightCurSel(); |
|
1176 |
this.language_window.style.visibility = "visible"; |
|
1177 |
} |
|
1178 |
|
|
1179 |
GoogieSpell.prototype.flashNoSpellingErrorState = function() { |
|
1180 |
this.setStateChanged("no_error_found"); |
|
1181 |
var me = this; |
|
1182 |
AJS.hideElement(this.switch_lan_pic); |
|
1183 |
this.gselm.innerHTML = this.lang_no_error_found; |
|
1184 |
this.gselm.className = "googie_check_spelling_ok"; |
|
1185 |
this.gselm.style.textDecoration = "none"; |
|
1186 |
this.gselm.style.cursor = "default"; |
|
1187 |
var fu = function() { |
|
1188 |
AJS.removeElement(me.gselm); |
|
1189 |
me.checkSpellingState(); |
|
1190 |
}; |
|
1191 |
setTimeout(fu, 1000); |
|
1192 |
} |
|
1193 |
|
|
1194 |
GoogieSpell.prototype.resumeEditingState = function() { |
|
1195 |
this.setStateChanged("resume_editing"); |
|
1196 |
var me = this; |
|
1197 |
AJS.hideElement(me.switch_lan_pic); |
|
1198 |
|
|
1199 |
//Change link text to resume |
|
1200 |
me.gselm.innerHTML = this.lang_rsm_edt; |
|
1201 |
me.gselm.onclick = function(e) { |
|
1202 |
me.resumeEditing(e, me); |
|
1203 |
} |
|
1204 |
me.gselm.className = "googie_check_spelling_ok"; |
|
1205 |
me.edit_layer.scrollTop = me.ta_scroll_top; |
|
1206 |
} |
|
1207 |
|
|
1208 |
GoogieSpell.prototype.createChangeLangPic = function() { |
|
1209 |
var switch_lan = AJS.A({'class': 'googie_lang_3d_on', 'style': 'padding-left: 6px;'}, AJS.IMG({'src': this.img_dir + 'change_lang.gif', 'alt': "Change language"})); |
|
1210 |
switch_lan.onmouseover = function() { |
|
1211 |
if(this.className != "googie_lang_3d_click") |
|
1212 |
this.className = "googie_lang_3d_on"; |
|
1213 |
} |
|
1214 |
|
|
1215 |
var me = this; |
|
1216 |
switch_lan.onclick = function() { |
|
1217 |
if(this.className == "googie_lang_3d_click") { |
|
1218 |
me.hideLangWindow(); |
|
1219 |
} |
|
1220 |
else { |
|
1221 |
me.showLangWindow(switch_lan); |
|
1222 |
this.className = "googie_lang_3d_click"; |
|
1223 |
} |
|
1224 |
} |
|
1225 |
return switch_lan; |
|
1226 |
} |
|
1227 |
|
|
1228 |
GoogieSpell.prototype.createSpellDiv = function() { |
|
1229 |
var chk_spell = AJS.SPAN({'class': 'googie_check_spelling_link'}); |
|
1230 |
chk_spell.innerHTML = this.lang_chck_spell; |
|
1231 |
var spell_img = null; |
|
1232 |
if(this.show_spell_img) |
|
1233 |
spell_img = AJS.IMG({'src': this.img_dir + "spellc.gif"}); |
|
1234 |
return AJS.SPAN(spell_img, " ", chk_spell); |
|
1235 |
} |
|
1236 |
|
|
1237 |
GoogieSpell.prototype.checkSpellingState = function() { |
|
1238 |
this.setStateChanged("check_spelling"); |
|
1239 |
var me = this; |
|
1240 |
if(this.show_change_lang_pic) |
|
1241 |
this.switch_lan_pic = this.createChangeLangPic(); |
|
1242 |
else |
|
1243 |
this.switch_lan_pic = AJS.SPAN(); |
|
1244 |
|
|
1245 |
var span_chck = this.createSpellDiv(); |
|
1246 |
span_chck.onclick = function() { |
|
1247 |
me.spellCheck(span_chck); |
|
1248 |
} |
|
1249 |
AJS.appendChildNodes(this.spell_container, span_chck, " ", this.switch_lan_pic); |
ed5d29
|
1250 |
// modified by roundcube |
T |
1251 |
this.check_link = span_chck; |
dd53e2
|
1252 |
} |
T |
1253 |
|
|
1254 |
GoogieSpell.prototype.setLanguages = function(lang_dict) { |
|
1255 |
this.lang_to_word = lang_dict; |
|
1256 |
this.langlist_codes = AJS.keys(lang_dict); |
|
1257 |
} |
|
1258 |
|
|
1259 |
GoogieSpell.prototype.decorateTextarea = function(id, /*optional*/spell_container_id, force_width) { |
|
1260 |
var me = this; |
2c6337
|
1261 |
|
dd53e2
|
1262 |
if(typeof(id) == "string") |
T |
1263 |
this.text_area = AJS.getElement(id); |
|
1264 |
else |
|
1265 |
this.text_area = id; |
|
1266 |
|
|
1267 |
var r_width; |
|
1268 |
|
|
1269 |
if(this.text_area != null) { |
|
1270 |
if(AJS.isDefined(spell_container_id)) { |
|
1271 |
if(typeof(spell_container_id) == "string") |
|
1272 |
this.spell_container = AJS.getElement(spell_container_id); |
|
1273 |
else |
|
1274 |
this.spell_container = spell_container_id; |
|
1275 |
} |
|
1276 |
else { |
|
1277 |
var table = AJS.TABLE(); |
|
1278 |
var tbody = AJS.TBODY(); |
|
1279 |
var tr = AJS.TR(); |
|
1280 |
if(AJS.isDefined(force_width)) { |
|
1281 |
r_width = force_width; |
|
1282 |
} |
|
1283 |
else { |
|
1284 |
r_width = this.text_area.offsetWidth + "px"; |
|
1285 |
} |
|
1286 |
|
|
1287 |
var spell_container = AJS.TD(); |
|
1288 |
this.spell_container = spell_container; |
|
1289 |
|
|
1290 |
tr.appendChild(spell_container); |
|
1291 |
|
|
1292 |
tbody.appendChild(tr); |
|
1293 |
table.appendChild(tbody); |
|
1294 |
|
|
1295 |
AJS.insertBefore(table, this.text_area); |
|
1296 |
|
|
1297 |
//Set width |
|
1298 |
table.style.width = '100%'; // modified by roundcube (old: r_width) |
|
1299 |
spell_container.style.width = r_width; |
|
1300 |
spell_container.style.textAlign = "right"; |
|
1301 |
} |
|
1302 |
|
|
1303 |
this.checkSpellingState(); |
|
1304 |
} |
|
1305 |
else { |
|
1306 |
alert("Text area not found"); |
|
1307 |
} |
|
1308 |
} |