Changeset 309d2f4 in github
- Timestamp:
- May 1, 2009 3:27:36 PM (4 years ago)
- Branches:
- master, HEAD, courier-fix, dev-browser-capabilities, pdo, release-0.6, release-0.7, release-0.8
- Children:
- 87b18e9
- Parents:
- 1692499
- Files:
-
- 8 edited
-
program/js/app.js (modified) (4 diffs)
-
program/js/common.js (modified) (1 diff)
-
program/js/googiespell.js (modified) (30 diffs)
-
program/steps/mail/compose.inc (modified) (3 diffs)
-
skins/default/common.css (modified) (1 diff)
-
skins/default/googiespell.css (modified) (4 diffs)
-
skins/default/mail.css (modified) (3 diffs)
-
skins/default/templates/compose.html (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
-
program/js/app.js
rffa6c10 r309d2f4 904 904 else if (this.env.spellcheck && this.env.spellcheck.spellCheck && this.spellcheck_ready) { 905 905 this.env.spellcheck.spellCheck(); 906 this.set_spellcheck_state('checking'); 906 907 } 907 908 break; … … 2113 2114 { 2114 2115 if (this.env.spellcheck && !this.spellcheck_ready) { 2115 exec_event(this.env.spellcheck.check_link,'click');2116 $(this.env.spellcheck.spell_span).trigger('click'); 2116 2117 this.set_spellcheck_state('ready'); 2117 2118 } … … 2123 2124 // stop spellchecking process 2124 2125 if (!vis) 2125 this.stop_spellchecking(); 2126 2127 this.env.spellcheck.check_link.style.visibility = vis ? 'visible' : 'hidden'; 2128 this.env.spellcheck.switch_lan_pic.style.visibility = vis ? 'visible' : 'hidden'; 2126 this.stop_spellchecking(); 2127 2128 $(this.env.spellcheck.spell_container).css('visibility', vis ? 'visible' : 'hidden'); 2129 2129 } 2130 2130 }; … … 2132 2132 this.set_spellcheck_state = function(s) 2133 2133 { 2134 this.spellcheck_ready = (s =='check_spelling' || s=='spell_check' || s=='ready');2134 this.spellcheck_ready = (s == 'ready' || s == 'no_error_found'); 2135 2135 this.enable_command('spellcheck', this.spellcheck_ready); 2136 2136 }; -
program/js/common.js
rcc97ea0 r309d2f4 635 635 } 636 636 } 637 638 639 // Fire event on specified element640 function exec_event(element,event)641 {642 if (document.createEventObject) {643 // dispatch for IE644 var evt = document.createEventObject();645 return element.fireEvent('on'+event,evt)646 }647 else {648 // dispatch for firefox + others649 var evt = document.createEvent("HTMLEvents");650 evt.initEvent(event, true, true); // event type,bubbling,cancelable651 return !element.dispatchEvent(evt);652 }653 } -
program/js/googiespell.js
rffa6c10 r309d2f4 1 1 /* 2 Last Modified: 29/04/07 18:44:48 3 4 AJS JavaScript library 5 A very small library with a lot of functionality 6 AUTHOR 7 4mir Salihefendic (http://amix.dk) - amix@amix.dk 8 LICENSE 9 Copyright (c) 2006 Amir Salihefendic. All rights reserved. 10 Copyright (c) 2005 Bob Ippolito. All rights reserved. 11 http://www.opensource.org/licenses/mit-license.php 12 VERSION 13 4.0 14 SITE 15 http://orangoo.com/AmiNation/AJS 16 **/ 17 if(!AJS) { 18 var AJS = { 19 BASE_URL: "", 20 21 drag_obj: null, 22 drag_elm: null, 23 _drop_zones: [], 24 _drag_zones: [], 25 _cur_pos: null, 26 27 ajaxErrorHandler: null, 28 29 //// 30 // General accessor functions 31 //// 32 getQueryArgument: function(var_name) { 33 var query = window.location.search.substring(1); 34 var vars = query.split("&"); 35 for (var i=0;i<vars.length;i++) { 36 var pair = vars[i].split("="); 37 if (pair[0] == var_name) { 38 return pair[1]; 39 } 40 } 41 return null; 42 }, 43 44 isIe: function() { 45 return (navigator.userAgent.toLowerCase().indexOf("msie") != -1 && navigator.userAgent.toLowerCase().indexOf("opera") == -1); 46 }, 47 isNetscape7: function() { 48 return (navigator.userAgent.toLowerCase().indexOf("netscape") != -1 && navigator.userAgent.toLowerCase().indexOf("7.") != -1); 49 }, 50 isSafari: function() { 51 return (navigator.userAgent.toLowerCase().indexOf("khtml") != -1); 52 }, 53 isOpera: function() { 54 return (navigator.userAgent.toLowerCase().indexOf("opera") != -1); 55 }, 56 isMozilla: function() { 57 return (navigator.userAgent.toLowerCase().indexOf("gecko") != -1 && navigator.productSub >= 20030210); 58 }, 59 isMac: function() { 60 return (navigator.userAgent.toLowerCase().indexOf('macintosh') != -1); 61 }, 62 63 64 //// 65 // Array functions 66 //// 67 //Shortcut: AJS.$A 68 createArray: function(v) { 69 if(AJS.isArray(v) && !AJS.isString(v)) 70 return v; 71 else if(!v) 72 return []; 73 else 74 return [v]; 75 }, 76 77 forceArray: function(args) { 78 var r = []; 79 AJS.map(args, function(elm) { 80 r.push(elm); 81 }); 82 return r; 83 }, 84 85 join: function(delim, list) { 86 try { 87 return list.join(delim); 88 } 89 catch(e) { 90 var r = list[0] || ''; 91 AJS.map(list, function(elm) { 92 r += delim + elm; 93 }, 1); 94 return r + ''; 95 } 96 }, 97 98 isIn: function(elm, list) { 99 var i = AJS.getIndex(elm, list); 100 if(i != -1) 101 return true; 102 else 103 return false; 104 }, 105 106 getIndex: function(elm, list/*optional*/, eval_fn) { 107 for(var i=0; i < list.length; i++) 108 if(eval_fn && eval_fn(list[i]) || elm == list[i]) 109 return i; 110 return -1; 111 }, 112 113 getFirst: function(list) { 114 if(list.length > 0) 115 return list[0]; 116 else 117 return null; 118 }, 119 120 getLast: function(list) { 121 if(list.length > 0) 122 return list[list.length-1]; 123 else 124 return null; 125 }, 126 127 update: function(l1, l2) { 128 for(var i in l2) 129 l1[i] = l2[i]; 130 return l1; 131 }, 132 133 flattenList: function(list) { 134 var r = []; 135 var _flatten = function(r, l) { 136 AJS.map(l, function(o) { 137 if(o == null) {} 138 else if (AJS.isArray(o)) 139 _flatten(r, o); 140 else 141 r.push(o); 142 }); 143 } 144 _flatten(r, list); 145 return r; 146 }, 147 148 149 //// 150 // Functional programming 151 //// 152 map: function(list, fn,/*optional*/ start_index, end_index) { 153 var i = 0, l = list.length; 154 if(start_index) 155 i = start_index; 156 if(end_index) 157 l = end_index; 158 for(i; i < l; i++) { 159 var val = fn.apply(null, [list[i], i]); 160 if(val != undefined) 161 return val; 162 } 163 }, 164 165 rmap: function(list, fn) { 166 var i = list.length-1, l = 0; 167 for(i; i >= l; i--) { 168 var val = fn.apply(null, [list[i], i]); 169 if(val != undefined) 170 return val; 171 } 172 }, 173 174 filter: function(list, fn, /*optional*/ start_index, end_index) { 175 var r = []; 176 AJS.map(list, function(elm) { 177 if(fn(elm)) 178 r.push(elm); 179 }, start_index, end_index); 180 return r; 181 }, 182 183 partial: function(fn) { 184 var args = AJS.$FA(arguments); 185 args.shift(); 186 return function() { 187 args = args.concat(AJS.$FA(arguments)); 188 return fn.apply(window, args); 189 } 190 }, 191 192 193 //// 194 // DOM functions 195 //// 196 //Shortcut: AJS.$ 197 getElement: function(id) { 198 if(AJS.isString(id) || AJS.isNumber(id)) 199 return document.getElementById(id); 200 else 201 return id; 202 }, 203 204 //Shortcut: AJS.$$ 205 getElements: function(/*id1, id2, id3*/) { 206 var args = AJS.forceArray(arguments); 207 var elements = new Array(); 208 for (var i = 0; i < args.length; i++) { 209 var element = AJS.getElement(args[i]); 210 elements.push(element); 211 } 212 return elements; 213 }, 214 215 //Shortcut: AJS.$bytc 216 getElementsByTagAndClassName: function(tag_name, class_name, /*optional*/ parent) { 217 var class_elements = []; 218 if(!AJS.isDefined(parent)) 219 parent = document; 220 if(!AJS.isDefined(tag_name)) 221 tag_name = '*'; 222 223 var els = parent.getElementsByTagName(tag_name); 224 var els_len = els.length; 225 var pattern = new RegExp("(^|\\s)" + class_name + "(\\s|$)"); 226 227 for (i = 0, j = 0; i < els_len; i++) { 228 if ( pattern.test(els[i].className) || class_name == null ) { 229 class_elements[j] = els[i]; 230 j++; 231 } 232 } 233 return class_elements; 234 }, 235 236 _nodeWalk: function(elm, tag_name, class_name, fn_next_elm) { 237 var p = fn_next_elm(elm); 238 239 var checkFn; 240 if(tag_name && class_name) { 241 checkFn = function(p) { 242 return AJS.nodeName(p) == tag_name && AJS.hasClass(p, class_name); 243 } 244 } 245 else if(tag_name) { 246 checkFn = function(p) { return AJS.nodeName(p) == tag_name; } 247 } 248 else { 249 checkFn = function(p) { return AJS.hasClass(p, class_name); } 250 } 251 252 while(p) { 253 if(checkFn(p)) 254 return p; 255 p = fn_next_elm(p); 256 } 257 return null; 258 }, 259 260 getParentBytc: function(elm, tag_name, class_name) { 261 return AJS._nodeWalk(elm, tag_name, class_name, function(m) { return m.parentNode; }); 262 }, 263 264 getPreviousSiblingBytc: function(elm, tag_name, class_name) { 265 return AJS._nodeWalk(elm, tag_name, class_name, function(m) { return m.previousSibling; }); 266 }, 267 268 getNextSiblingBytc: function(elm, tag_name, class_name) { 269 return AJS._nodeWalk(elm, tag_name, class_name, function(m) { return m.nextSibling; }); 270 }, 271 272 //Shortcut: AJS.$f 273 getFormElement: function(form, name) { 274 form = AJS.$(form); 275 var r = null; 276 AJS.map(form.elements, function(elm) { 277 if(elm.name && elm.name == name) 278 r = elm; 279 }); 280 return r; 281 }, 282 283 formContents: function(form) { 284 var form = AJS.$(form); 285 var r = {}; 286 var fn = function(elms) { 287 AJS.map(elms, function(e) { 288 if(e.name) 289 r[e.name] = e.value || ''; 290 }); 291 } 292 fn(AJS.$bytc('input', null, form)); 293 fn(AJS.$bytc('textarea', null, form)); 294 return r; 295 }, 296 297 getBody: function() { 298 return AJS.$bytc('body')[0] 299 }, 300 301 nodeName: function(elm) { 302 return elm.nodeName.toLowerCase(); 303 }, 304 305 hasParent: function(elm, parent_to_consider, max_look_up) { 306 if(elm == parent_to_consider) 307 return true; 308 if(max_look_up == 0) 309 return false; 310 return AJS.hasParent(elm.parentNode, parent_to_consider, max_look_up-1); 311 }, 312 313 isElementHidden: function(elm) { 314 return ((elm.style.display == "none") || (elm.style.visibility == "hidden")); 315 }, 316 317 //Shortcut: AJS.DI 318 documentInsert: function(elm) { 319 if(typeof(elm) == 'string') 320 elm = AJS.HTML2DOM(elm); 321 document.write('<span id="dummy_holder"></span>'); 322 AJS.swapDOM(AJS.$('dummy_holder'), elm); 323 }, 324 325 cloner: function(element) { 326 return function() { 327 return element.cloneNode(true); 328 } 329 }, 330 331 appendToTop: function(elm/*, elms...*/) { 332 var args = AJS.forceArray(arguments).slice(1); 333 if(args.length >= 1) { 334 var first_child = elm.firstChild; 335 if(first_child) { 336 while(true) { 337 var t_elm = args.shift(); 338 if(t_elm) 339 AJS.insertBefore(t_elm, first_child); 340 else 341 break; 342 } 343 } 344 else { 345 AJS.ACN.apply(null, arguments); 346 } 347 } 348 return elm; 349 }, 350 351 //Shortcut: AJS.ACN 352 appendChildNodes: function(elm/*, elms...*/) { 353 if(arguments.length >= 2) { 354 AJS.map(arguments, function(n) { 355 if(AJS.isString(n)) 356 n = AJS.TN(n); 357 if(AJS.isDefined(n)) 358 elm.appendChild(n); 359 }, 1); 360 } 361 return elm; 362 }, 363 364 //Shortcut: AJS.RCN 365 replaceChildNodes: function(elm/*, elms...*/) { 366 var child; 367 while ((child = elm.firstChild)) 368 elm.removeChild(child); 369 if (arguments.length < 2) 370 return elm; 371 else 372 return AJS.appendChildNodes.apply(null, arguments); 373 return elm; 374 }, 375 376 insertAfter: function(elm, reference_elm) { 377 reference_elm.parentNode.insertBefore(elm, reference_elm.nextSibling); 378 return elm; 379 }, 380 381 insertBefore: function(elm, reference_elm) { 382 reference_elm.parentNode.insertBefore(elm, reference_elm); 383 return elm; 384 }, 385 386 showElement: function(/*elms...*/) { 387 var args = AJS.forceArray(arguments); 388 AJS.map(args, function(elm) { elm.style.display = ''}); 389 }, 390 391 hideElement: function(elm) { 392 var args = AJS.forceArray(arguments); 393 AJS.map(args, function(elm) { elm.style.display = 'none'}); 394 }, 395 396 swapDOM: function(dest, src) { 397 dest = AJS.getElement(dest); 398 var parent = dest.parentNode; 399 if (src) { 400 src = AJS.getElement(src); 401 parent.replaceChild(src, dest); 402 } else { 403 parent.removeChild(dest); 404 } 405 return src; 406 }, 407 408 removeElement: function(/*elm1, elm2...*/) { 409 var args = AJS.forceArray(arguments); 410 AJS.map(args, function(elm) { AJS.swapDOM(elm, null); }); 411 }, 412 413 createDOM: function(name, attrs) { 414 var i=0, attr; 415 elm = document.createElement(name); 416 417 if(AJS.isDict(attrs[i])) { 418 for(k in attrs[0]) { 419 attr = attrs[0][k]; 420 if(k == "style") 421 elm.style.cssText = attr; 422 else if(k == "class" || k == 'className') 423 elm.className = attr; 424 else { 425 elm.setAttribute(k, attr); 426 } 427 } 428 i++; 429 } 430 431 if(attrs[0] == null) 432 i = 1; 433 434 AJS.map(attrs, function(n) { 435 if(n) { 436 if(AJS.isString(n) || AJS.isNumber(n)) 437 n = AJS.TN(n); 438 elm.appendChild(n); 439 } 440 }, i); 441 return elm; 442 }, 443 444 _createDomShortcuts: function() { 445 var elms = [ 446 "ul", "li", "td", "tr", "th", 447 "tbody", "table", "input", "span", "b", 448 "a", "div", "img", "button", "h1", 449 "h2", "h3", "br", "textarea", "form", 450 "p", "select", "option", "optgroup", "iframe", "script", 451 "center", "dl", "dt", "dd", "small", 452 "pre" 453 ]; 454 var extends_ajs = function(elm) { 455 AJS[elm.toUpperCase()] = function() { 456 return AJS.createDOM.apply(null, [elm, arguments]); 457 }; 458 } 459 AJS.map(elms, extends_ajs); 460 AJS.TN = function(text) { return document.createTextNode(text) }; 461 }, 462 463 getCssDim: function(dim) { 464 if(AJS.isString(dim)) 465 return dim; 466 else 467 return dim + "px"; 468 }, 469 getCssProperty: function(elm, prop) { 470 elm = AJS.$(elm); 471 var y; 472 if(elm.currentStyle) 473 y = elm.currentStyle[prop]; 474 else if (window.getComputedStyle) 475 y = document.defaultView.getComputedStyle(elm,null).getPropertyValue(prop); 476 return y; 477 }, 478 479 setStyle: function(/*elm1, elm2..., property, new_value*/) { 480 var args = AJS.forceArray(arguments); 481 var new_val = args.pop(); 482 var property = args.pop(); 483 AJS.map(args, function(elm) { 484 elm.style[property] = AJS.getCssDim(new_val); 485 }); 486 }, 487 488 setWidth: function(/*elm1, elm2..., width*/) { 489 var args = AJS.forceArray(arguments); 490 args.splice(args.length-1, 0, 'width'); 491 AJS.setStyle.apply(null, args); 492 }, 493 setHeight: function(/*elm1, elm2..., height*/) { 494 var args = AJS.forceArray(arguments); 495 args.splice(args.length-1, 0, 'height'); 496 AJS.setStyle.apply(null, args); 497 }, 498 setLeft: function(/*elm1, elm2..., left*/) { 499 var args = AJS.forceArray(arguments); 500 args.splice(args.length-1, 0, 'left'); 501 AJS.setStyle.apply(null, args); 502 }, 503 setTop: function(/*elm1, elm2..., top*/) { 504 var args = AJS.forceArray(arguments); 505 args.splice(args.length-1, 0, 'top'); 506 AJS.setStyle.apply(null, args); 507 }, 508 setClass: function(/*elm1, elm2..., className*/) { 509 var args = AJS.forceArray(arguments); 510 var c = args.pop(); 511 AJS.map(args, function(elm) { elm.className = c}); 512 }, 513 addClass: function(/*elm1, elm2..., className*/) { 514 var args = AJS.forceArray(arguments); 515 var cls = args.pop(); 516 var add_class = function(o) { 517 if(!new RegExp("(^|\\s)" + cls + "(\\s|$)").test(o.className)) 518 o.className += (o.className ? " " : "") + cls; 519 }; 520 AJS.map(args, function(elm) { add_class(elm); }); 521 }, 522 hasClass: function(elm, cls) { 523 if(!elm.className) 524 return false; 525 return elm.className == cls || 526 elm.className.search(new RegExp(" " + cls + "|^" + cls)) != -1 527 }, 528 removeClass: function(/*elm1, elm2..., className*/) { 529 var args = AJS.forceArray(arguments); 530 var cls = args.pop(); 531 var rm_class = function(o) { 532 o.className = o.className.replace(new RegExp("\\s?" + cls, 'g'), ""); 533 }; 534 AJS.map(args, function(elm) { rm_class(elm); }); 535 }, 536 537 setHTML: function(elm, html) { 538 elm.innerHTML = html; 539 return elm; 540 }, 541 542 RND: function(tmpl, ns, scope) { 543 scope = scope || window; 544 var fn = function(w, g) { 545 g = g.split("|"); 546 var cnt = ns[g[0]]; 547 for(var i=1; i < g.length; i++) 548 cnt = scope[g[i]](cnt); 549 if(cnt == '') 550 return ''; 551 if(cnt == 0 || cnt == -1) 552 cnt += ''; 553 return cnt || w; 554 }; 555 return tmpl.replace(/%\(([A-Za-z0-9_|.]*)\)/g, fn); 556 }, 557 558 HTML2DOM: function(html,/*optional*/ first_child) { 559 var d = AJS.DIV(); 560 d.innerHTML = html; 561 if(first_child) 562 return d.childNodes[0]; 563 else 564 return d; 565 }, 566 567 preloadImages: function(/*img_src1, ..., img_srcN*/) { 568 AJS.AEV(window, 'load', AJS.$p(function(args) { 569 AJS.map(args, function(src) { 570 var pic = new Image(); 571 pic.src = src; 572 }); 573 }, arguments)); 574 }, 575 576 577 //// 578 // Effects 579 //// 580 setOpacity: function(elm, p) { 581 elm.style.opacity = p; 582 elm.style.filter = "alpha(opacity="+ p*100 +")"; 583 }, 584 585 resetOpacity: function(elm) { 586 elm.style.opacity = 1; 587 elm.style.filter = ""; 588 }, 589 590 //// 591 // Ajax functions 592 //// 593 getXMLHttpRequest: function() { 594 var try_these = [ 595 function () { return new XMLHttpRequest(); }, 596 function () { return new ActiveXObject('Msxml2.XMLHTTP'); }, 597 function () { return new ActiveXObject('Microsoft.XMLHTTP'); }, 598 function () { return new ActiveXObject('Msxml2.XMLHTTP.4.0'); }, 599 function () { throw "Browser does not support XMLHttpRequest"; } 600 ]; 601 for (var i = 0; i < try_these.length; i++) { 602 var func = try_these[i]; 603 try { 604 return func(); 605 } catch (e) { 606 } 607 } 608 }, 609 610 getRequest: function(url, data, type) { 611 if(!type) 612 type = "POST"; 613 var req = AJS.getXMLHttpRequest(); 614 615 if(url.indexOf("http://") == -1) { 616 if(AJS.BASE_URL != '') { 617 if(AJS.BASE_URL.lastIndexOf('/') != AJS.BASE_URL.length-1) 618 AJS.BASE_URL += '/'; 619 url = AJS.BASE_URL + url; 620 } 621 } 622 623 req.open(type, url, true); 624 if(type == "POST") 625 req.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); 626 return AJS._sendXMLHttpRequest(req); 627 }, 628 629 _sendXMLHttpRequest: function(req, data) { 630 var d = new AJSDeferred(req); 631 632 var onreadystatechange = function () { 633 if (req.readyState == 4) { 634 var status = ''; 635 try { 636 status = req.status; 637 } 638 catch(e) {}; 639 if(status == 200 || status == 304 || req.responseText == null) { 640 d.callback(); 641 } 642 else { 643 if(d.errbacks.length == 0) { 644 if(AJS.ajaxErrorHandler) 645 AJS.ajaxErrorHandler(req.responseText, req); 646 } 647 else 648 d.errback(); 649 } 650 } 651 } 652 req.onreadystatechange = onreadystatechange; 653 return d; 654 }, 655 656 _reprString: function(o) { 657 return ('"' + o.replace(/(["\\])/g, '\\$1') + '"' 658 ).replace(/[\f]/g, "\\f" 659 ).replace(/[\b]/g, "\\b" 660 ).replace(/[\n]/g, "\\n" 661 ).replace(/[\t]/g, "\\t" 662 ).replace(/[\r]/g, "\\r"); 663 }, 664 665 _reprDate: function(db) { 666 var year = db.getFullYear(); 667 var dd = db.getDate(); 668 var mm = db.getMonth()+1; 669 670 var hh = db.getHours(); 671 var mins = db.getMinutes(); 672 673 function leadingZero(nr) { 674 if (nr < 10) nr = "0" + nr; 675 return nr; 676 } 677 if(hh == 24) hh = '00'; 678 679 var time = leadingZero(hh) + ':' + leadingZero(mins); 680 return '"' + year + '-' + mm + '-' + dd + 'T' + time + '"'; 681 }, 682 683 serializeJSON: function(o) { 684 var objtype = typeof(o); 685 if (objtype == "undefined") { 686 return "undefined"; 687 } else if (objtype == "number" || objtype == "boolean") { 688 return o + ""; 689 } else if (o === null) { 690 return "null"; 691 } 692 if (objtype == "string") { 693 return AJS._reprString(o); 694 } 695 if(objtype == 'object' && o.getFullYear) { 696 return AJS._reprDate(o); 697 } 698 var me = arguments.callee; 699 if (objtype != "function" && typeof(o.length) == "number") { 700 var res = []; 701 for (var i = 0; i < o.length; i++) { 702 var val = me(o[i]); 703 if (typeof(val) != "string") { 704 val = "undefined"; 705 } 706 res.push(val); 707 } 708 return "[" + res.join(",") + "]"; 709 } 710 // it's a function with no adapter, bad 711 if (objtype == "function") 712 return null; 713 res = []; 714 for (var k in o) { 715 var useKey; 716 if (typeof(k) == "number") { 717 useKey = '"' + k + '"'; 718 } else if (typeof(k) == "string") { 719 useKey = AJS._reprString(k); 720 } else { 721 // skip non-string or number keys 722 continue; 723 } 724 val = me(o[k]); 725 if (typeof(val) != "string") { 726 // skip non-serializable values 727 continue; 728 } 729 res.push(useKey + ":" + val); 730 } 731 return "{" + res.join(",") + "}"; 732 }, 733 734 loadJSONDoc: function(url) { 735 var d = AJS.getRequest(url); 736 var eval_req = function(data, req) { 737 var text = req.responseText; 738 if(text == "Error") 739 d.errback(req); 740 else 741 return AJS.evalTxt(text); 742 }; 743 d.addCallback(eval_req); 744 return d; 745 }, 746 747 evalTxt: function(txt) { 748 try { 749 return eval('('+ txt + ')'); 750 } 751 catch(e) { 752 return eval(txt); 753 } 754 }, 755 756 evalScriptTags: function(html) { 757 var script_data = html.match(/<script.*?>((\n|\r|.)*?)<\/script>/g); 758 if(script_data != null) { 759 for(var i=0; i < script_data.length; i++) { 760 var script_only = script_data[i].replace(/<script.*?>/g, ""); 761 script_only = script_only.replace(/<\/script>/g, ""); 762 eval(script_only); 763 } 764 } 765 }, 766 767 queryArguments: function(data) { 768 var post_data = []; 769 for(k in data) 770 post_data.push(k + "=" + AJS.urlencode(data[k])); 771 return post_data.join("&"); 772 }, 773 774 775 //// 776 // Position and size 777 //// 778 getMousePos: function(e) { 779 var posx = 0; 780 var posy = 0; 781 if (!e) var e = window.event; 782 if (e.pageX || e.pageY) { 783 posx = e.pageX; 784 posy = e.pageY; 785 } 786 else if (e.clientX || e.clientY) { 787 posx = e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft; 788 posy = e.clientY + document.body.scrollTop + document.documentElement.scrollTop; 789 } 790 return {x: posx, y: posy}; 791 }, 792 793 getScrollTop: function() { 794 //From: http://www.quirksmode.org/js/doctypes.html 795 var t; 796 if (document.documentElement && document.documentElement.scrollTop) 797 t = document.documentElement.scrollTop; 798 else if (document.body) 799 t = document.body.scrollTop; 800 return t; 801 }, 802 803 absolutePosition: function(elm) { 804 var posObj = {'x': elm.offsetLeft, 'y': elm.offsetTop}; 805 806 if(elm.offsetParent) { 807 var next = elm.offsetParent; 808 while(next) { 809 posObj.x += next.offsetLeft; 810 posObj.y += next.offsetTop; 811 next = next.offsetParent; 812 } 813 } 814 // safari bug 815 if (AJS.isSafari() && elm.style.position == 'absolute' ) { 816 posObj.x -= document.body.offsetLeft; 817 posObj.y -= document.body.offsetTop; 818 } 819 return posObj; 820 }, 821 822 getWindowSize: function(doc) { 823 doc = doc || document; 824 var win_w, win_h; 825 if (self.innerHeight) { 826 win_w = self.innerWidth; 827 win_h = self.innerHeight; 828 } else if (doc.documentElement && doc.documentElement.clientHeight) { 829 win_w = doc.documentElement.clientWidth; 830 win_h = doc.documentElement.clientHeight; 831 } else if (doc.body) { 832 win_w = doc.body.clientWidth; 833 win_h = doc.body.clientHeight; 834 } 835 return {'w': win_w, 'h': win_h}; 836 }, 837 838 isOverlapping: function(elm1, elm2) { 839 var pos_elm1 = AJS.absolutePosition(elm1); 840 var pos_elm2 = AJS.absolutePosition(elm2); 841 842 var top1 = pos_elm1.y; 843 var left1 = pos_elm1.x; 844 var right1 = left1 + elm1.offsetWidth; 845 var bottom1 = top1 + elm1.offsetHeight; 846 var top2 = pos_elm2.y; 847 var left2 = pos_elm2.x; 848 var right2 = left2 + elm2.offsetWidth; 849 var bottom2 = top2 + elm2.offsetHeight; 850 var getSign = function(v) { 851 if(v > 0) return "+"; 852 else if(v < 0) return "-"; 853 else return 0; 854 } 855 856 if ((getSign(top1 - bottom2) != getSign(bottom1 - top2)) && 857 (getSign(left1 - right2) != getSign(right1 - left2))) 858 return true; 859 return false; 860 }, 861 862 863 //// 864 // Events 865 //// 866 getEventElm: function(e) { 867 if(e && !e.type && !e.keyCode) 868 return e 869 var targ; 870 if (!e) var e = window.event; 871 if (e.target) targ = e.target; 872 else if (e.srcElement) targ = e.srcElement; 873 if (targ.nodeType == 3) // defeat Safari bug 874 targ = targ.parentNode; 875 return targ; 876 }, 877 878 _getRealScope: function(fn, /*optional*/ extra_args) { 879 extra_args = AJS.$A(extra_args); 880 var scope = fn._cscope || window; 881 882 return function() { 883 var args = AJS.$FA(arguments).concat(extra_args); 884 return fn.apply(scope, args); 885 }; 886 }, 887 888 _unloadListeners: function() { 889 if(AJS.listeners) 890 AJS.map(AJS.listeners, function(elm, type, fn) { AJS.REV(elm, type, fn) }); 891 AJS.listeners = []; 892 }, 893 894 setEventKey: function(e) { 895 e.key = e.keyCode ? e.keyCode : e.charCode; 896 897 if(window.event) { 898 e.ctrl = window.event.ctrlKey; 899 e.shift = window.event.shiftKey; 900 } 901 else { 902 e.ctrl = e.ctrlKey; 903 e.shift = e.shiftKey; 904 } 905 switch(e.key) { 906 case 63232: 907 e.key = 38; 908 break; 909 case 63233: 910 e.key = 40; 911 break; 912 case 63235: 913 e.key = 39; 914 break; 915 case 63234: 916 e.key = 37; 917 break; 918 } 919 }, 920 921 //Shortcut: AJS.AEV 922 addEventListener: function(elm, type, fn, /*optional*/listen_once, cancle_bubble) { 923 if(!cancle_bubble) 924 cancle_bubble = false; 925 926 var elms = AJS.$A(elm); 927 AJS.map(elms, function(elmz) { 928 if(listen_once) 929 fn = AJS._listenOnce(elmz, type, fn); 930 931 //Hack since it does not work in all browsers 932 if(AJS.isIn(type, ['submit', 'load', 'scroll', 'resize'])) { 933 var old = elm['on' + type]; 934 elm['on' + type] = function() { 935 if(old) { 936 fn(arguments); 937 return old(arguments); 938 } 939 else 940 return fn(arguments); 941 }; 942 return; 943 } 944 945 //Fix keyCode 946 if(AJS.isIn(type, ['keypress', 'keydown', 'keyup', 'click'])) { 947 var old_fn = fn; 948 fn = function(e) { 949 AJS.setEventKey(e); 950 return old_fn.apply(null, arguments); 951 } 952 } 953 954 if (elmz.attachEvent) { 955 //FIXME: We ignore cancle_bubble for IE... could be a problem? 956 elmz.attachEvent("on" + type, fn); 957 } 958 else if(elmz.addEventListener) 959 elmz.addEventListener(type, fn, cancle_bubble); 960 961 AJS.listeners = AJS.$A(AJS.listeners); 962 AJS.listeners.push([elmz, type, fn]); 963 }); 964 }, 965 966 //Shortcut: AJS.REV 967 removeEventListener: function(elm, type, fn, /*optional*/cancle_bubble) { 968 if(!cancle_bubble) 969 cancle_bubble = false; 970 if(elm.removeEventListener) { 971 elm.removeEventListener(type, fn, cancle_bubble); 972 if(AJS.isOpera()) 973 elm.removeEventListener(type, fn, !cancle_bubble); 974 } 975 else if(elm.detachEvent) 976 elm.detachEvent("on" + type, fn); 977 }, 978 979 //Shortcut: AJS.$b 980 bind: function(fn, scope, /*optional*/ extra_args) { 981 fn._cscope = scope; 982 return AJS._getRealScope(fn, extra_args); 983 }, 984 985 bindMethods: function(self) { 986 for (var k in self) { 987 var func = self[k]; 988 if (typeof(func) == 'function') { 989 self[k] = AJS.$b(func, self); 990 } 991 } 992 }, 993 994 _listenOnce: function(elm, type, fn) { 995 var r_fn = function() { 996 AJS.removeEventListener(elm, type, r_fn); 997 fn(arguments); 998 } 999 return r_fn; 1000 }, 1001 1002 callLater: function(fn, interval) { 1003 var fn_no_send = function() { 1004 fn(); 1005 }; 1006 window.setTimeout(fn_no_send, interval); 1007 }, 1008 1009 preventDefault: function(e) { 1010 if(AJS.isIe()) 1011 window.event.returnValue = false; 1012 else 1013 e.preventDefault(); 1014 }, 1015 1016 1017 //// 1018 // Drag and drop 1019 //// 1020 dragAble: function(elm, /*optional*/ handler, args) { 1021 if(!args) 1022 args = {}; 1023 if(!AJS.isDefined(args['move_x'])) 1024 args['move_x'] = true; 1025 if(!AJS.isDefined(args['move_y'])) 1026 args['move_y'] = true; 1027 if(!AJS.isDefined(args['moveable'])) 1028 args['moveable'] = false; 1029 if(!AJS.isDefined(args['hide_on_move'])) 1030 args['hide_on_move'] = true; 1031 if(!AJS.isDefined(args['on_mouse_up'])) 1032 args['on_mouse_up'] = null; 1033 if(!AJS.isDefined(args['cursor'])) 1034 args['cursor'] = 'move'; 1035 if(!AJS.isDefined(args['max_move'])) 1036 args['max_move'] = {'top': null, 'left': null}; 1037 1038 elm = AJS.$(elm); 1039 1040 if(!handler) 1041 handler = elm; 1042 1043 handler = AJS.$(handler); 1044 var old_cursor = handler.style.cursor; 1045 handler.style.cursor = args['cursor']; 1046 elm.style.position = 'relative'; 1047 1048 AJS.addClass(handler, '_ajs_handler'); 1049 handler._args = args; 1050 handler._elm = elm; 1051 AJS.AEV(handler, 'mousedown', AJS._dragStart); 1052 }, 1053 1054 _dragStart: function(e) { 1055 var handler = AJS.getEventElm(e); 1056 if(!AJS.hasClass(handler, '_ajs_handler')) { 1057 handler = AJS.getParentBytc(handler, null, '_ajs_handler'); 1058 } 1059 if(handler) 1060 AJS._dragInit(e, handler._elm, handler._args); 1061 }, 1062 1063 dropZone: function(elm, args) { 1064 elm = AJS.$(elm); 1065 var item = {elm: elm}; 1066 AJS.update(item, args); 1067 AJS._drop_zones.push(item); 1068 }, 1069 1070 removeDragAble: function(elm) { 1071 AJS.REV(elm, 'mousedown', AJS._dragStart); 1072 elm.style.cursor = ''; 1073 }, 1074 1075 removeDropZone: function(elm) { 1076 var i = AJS.getIndex(elm, AJS._drop_zones, function(item) { 1077 if(item.elm == elm) return true; 1078 }); 1079 if(i != -1) { 1080 AJS._drop_zones.splice(i, 1); 1081 } 1082 }, 1083 1084 _dragInit: function(e, click_elm, args) { 1085 AJS.drag_obj = new Object(); 1086 AJS.drag_obj.args = args; 1087 1088 AJS.drag_obj.click_elm = click_elm; 1089 AJS.drag_obj.mouse_pos = AJS.getMousePos(e); 1090 AJS.drag_obj.click_elm_pos = AJS.absolutePosition(click_elm); 1091 1092 AJS.AEV(document, 'mousemove', AJS._dragMove, false, true); 1093 AJS.AEV(document, 'mouseup', AJS._dragStop, false, true); 1094 1095 if (AJS.isIe()) 1096 window.event.cancelBubble = true; 1097 AJS.preventDefault(e); 1098 }, 1099 1100 _initDragElm: function(elm) { 1101 if(AJS.drag_elm && AJS.drag_elm.style.display == 'none') 1102 AJS.removeElement(AJS.drag_elm); 1103 1104 if(!AJS.drag_elm) { 1105 AJS.drag_elm = AJS.DIV(); 1106 var d = AJS.drag_elm; 1107 AJS.insertBefore(d, AJS.getBody().firstChild); 1108 AJS.setHTML(d, elm.innerHTML); 1109 1110 d.className = elm.className; 1111 d.style.cssText = elm.style.cssText; 1112 1113 d.style.position = 'absolute'; 1114 d.style.zIndex = 10000; 1115 1116 var t = AJS.absolutePosition(elm); 1117 AJS.setTop(d, t.y); 1118 AJS.setLeft(d, t.x); 1119 1120 if(AJS.drag_obj.args.on_init) { 1121 AJS.drag_obj.args.on_init(elm); 1122 } 1123 } 1124 }, 1125 1126 _dragMove: function(e) { 1127 var drag_obj = AJS.drag_obj; 1128 var click_elm = drag_obj.click_elm; 1129 1130 AJS._initDragElm(click_elm); 1131 var drag_elm = AJS.drag_elm; 1132 1133 if(drag_obj.args['hide_on_move']) 1134 click_elm.style.visibility = 'hidden'; 1135 1136 var cur_pos = AJS.getMousePos(e); 1137 1138 var mouse_pos = drag_obj.mouse_pos; 1139 1140 var click_elm_pos = drag_obj.click_elm_pos; 1141 1142 var p_x, p_y; 1143 p_x = cur_pos.x - (mouse_pos.x - click_elm_pos.x); 1144 p_y = cur_pos.y - (mouse_pos.y - click_elm_pos.y); 1145 1146 AJS.map(AJS._drop_zones, function(d_z) { 1147 if(AJS.isOverlapping(d_z['elm'], drag_elm)) { 1148 if(d_z['elm'] != drag_elm) { 1149 var on_hover = d_z['on_hover']; 1150 if(on_hover) 1151 on_hover(d_z['elm'], click_elm, drag_elm); 1152 } 1153 } 1154 }); 1155 1156 if(drag_obj.args['on_drag']) 1157 drag_obj.args['on_drag'](click_elm, e); 1158 1159 var max_move_top = drag_obj.args['max_move']['top']; 1160 var max_move_left = drag_obj.args['max_move']['left']; 1161 if(drag_obj.args['move_x']) { 1162 if(max_move_left == null || max_move_left <= p) 1163 AJS.setLeft(elm, p_x); 1164 } 1165 1166 if(drag_obj.args['move_y']) { 1167 if(max_move_top == null || max_move_top <= p_y) 1168 AJS.setTop(elm, p_y); 1169 } 1170 if(AJS.isIe()) { 1171 window.event.cancelBubble = true; 1172 window.event.returnValue = false; 1173 } 1174 else 1175 e.preventDefault(); 1176 1177 //Moving scroll to the top, should move the scroll up 1178 var sc_top = AJS.getScrollTop(); 1179 var sc_bottom = sc_top + AJS.getWindowSize().h; 1180 var d_e_top = AJS.absolutePosition(drag_elm).y; 1181 var d_e_bottom = drag_elm.offsetTop + drag_elm.offsetHeight; 1182 1183 if(d_e_top <= sc_top + 20) { 1184 window.scrollBy(0, -15); 1185 } 1186 else if(d_e_bottom >= sc_bottom - 20) { 1187 window.scrollBy(0, 15); 1188 } 1189 }, 1190 1191 _dragStop: function(e) { 1192 var drag_obj = AJS.drag_obj; 1193 var drag_elm = AJS.drag_elm; 1194 var click_elm = drag_obj.click_elm; 1195 1196 AJS.REV(document, "mousemove", AJS._dragMove, true); 1197 AJS.REV(document, "mouseup", AJS._dragStop, true); 1198 1199 var dropped = false; 1200 AJS.map(AJS._drop_zones, function(d_z) { 1201 if(AJS.isOverlapping(d_z['elm'], click_elm)) { 1202 if(d_z['elm'] != click_elm) { 1203 var on_drop = d_z['on_drop']; 1204 if(on_drop) { 1205 dropped = true; 1206 on_drop(d_z['elm'], click_elm); 1207 } 1208 } 1209 } 1210 }); 1211 1212 if(drag_obj.args['moveable']) { 1213 var t = parseInt(click_elm.style.top) || 0; 1214 var l = parseInt(click_elm.style.left) || 0; 1215 var drag_elm_xy = AJS.absolutePosition(drag_elm); 1216 var click_elm_xy = AJS.absolutePosition(click_elm); 1217 AJS.setTop(click_elm, t + drag_elm_xy.y - click_elm_xy.y); 1218 AJS.setLeft(click_elm, l + drag_elm_xy.x - click_elm_xy.x); 1219 } 1220 1221 if(!dropped && drag_obj.args['on_mouse_up']) 1222 drag_obj.args['on_mouse_up'](click_elm, e); 1223 1224 if(drag_obj.args['hide_on_move']) 1225 drag_obj.click_elm.style.visibility = 'visible'; 1226 1227 if(drag_obj.args.on_end) { 1228 drag_obj.args.on_end(click_elm); 1229 } 1230 1231 AJS._dragObj = null; 1232 if(drag_elm) 1233 AJS.hideElement(drag_elm); 1234 AJS.drag_elm = null; 1235 }, 1236 1237 1238 //// 1239 // Misc. 1240 //// 1241 keys: function(obj) { 1242 var rval = []; 1243 for (var prop in obj) { 1244 rval.push(prop); 1245 } 1246 return rval; 1247 }, 1248 1249 values: function(obj) { 1250 var rval = []; 1251 for (var prop in obj) { 1252 rval.push(obj[prop]); 1253 } 1254 return rval; 1255 }, 1256 1257 urlencode: function(str) { 1258 return encodeURIComponent(str.toString()); 1259 }, 1260 1261 isDefined: function(o) { 1262 return (o != "undefined" && o != null) 1263 }, 1264 1265 isArray: function(obj) { 1266 return obj instanceof Array; 1267 }, 1268 1269 isString: function(obj) { 1270 return (typeof obj == 'string'); 1271 }, 1272 1273 isNumber: function(obj) { 1274 return (typeof obj == 'number'); 1275 }, 1276 1277 isObject: function(obj) { 1278 return (typeof obj == 'object'); 1279 }, 1280 1281 isFunction: function(obj) { 1282 return (typeof obj == 'function'); 1283 }, 1284 1285 isDict: function(o) { 1286 var str_repr = String(o); 1287 return str_repr.indexOf(" Object") != -1; 1288 }, 1289 1290 exportToGlobalScope: function() { 1291 for(e in AJS) 1292 window[e] = AJS[e]; 1293 }, 1294 1295 log: function(o) { 1296 if(window.console) 1297 console.log(o); 1298 else { 1299 var div = AJS.$('ajs_logger'); 1300 if(!div) { 1301 div = AJS.DIV({id: 'ajs_logger', 'style': 'color: green; position: absolute; left: 0'}); 1302 div.style.top = AJS.getScrollTop() + 'px'; 1303 AJS.ACN(AJS.getBody(), div); 1304 } 1305 AJS.setHTML(div, ''+o); 1306 } 1307 } 1308 1309 } 1310 1311 AJS.Class = function(members) { 1312 var fn = function() { 1313 if(arguments[0] != 'no_init') { 1314 return this.init.apply(this, arguments); 1315 } 1316 } 1317 fn.prototype = members; 1318 AJS.update(fn, AJS.Class.prototype); 1319 return fn; 1320 } 1321 AJS.Class.prototype = { 1322 extend: function(members) { 1323 var parent = new this('no_init'); 1324 for(k in members) { 1325 var prev = parent[k]; 1326 var cur = members[k]; 1327 if (prev && prev != cur && typeof cur == 'function') { 1328 cur = this._parentize(cur, prev); 1329 } 1330 parent[k] = cur; 1331 } 1332 return new AJS.Class(parent); 1333 }, 1334 1335 implement: function(members) { 1336 AJS.update(this.prototype, members); 1337 }, 1338 1339 _parentize: function(cur, prev) { 1340 return function(){ 1341 this.parent = prev; 1342 return cur.apply(this, arguments); 1343 } 1344 } 1345 }; 1346 1347 //Shortcuts 1348 AJS.$ = AJS.getElement; 1349 AJS.$$ = AJS.getElements; 1350 AJS.$f = AJS.getFormElement; 1351 AJS.$b = AJS.bind; 1352 AJS.$p = AJS.partial; 1353 AJS.$FA = AJS.forceArray; 1354 AJS.$A = AJS.createArray; 1355 AJS.DI = AJS.documentInsert; 1356 AJS.ACN = AJS.appendChildNodes; 1357 AJS.RCN = AJS.replaceChildNodes; 1358 AJS.AEV = AJS.addEventListener; 1359 AJS.REV = AJS.removeEventListener; 1360 AJS.$bytc = AJS.getElementsByTagAndClassName; 1361 1362 AJSDeferred = function(req) { 1363 this.callbacks = []; 1364 this.errbacks = []; 1365 this.req = req; 1366 } 1367 AJSDeferred.prototype = { 1368 excCallbackSeq: function(req, list) { 1369 var data = req.responseText; 1370 while (list.length > 0) { 1371 var fn = list.pop(); 1372 var new_data = fn(data, req); 1373 if(new_data) 1374 data = new_data; 1375 } 1376 }, 1377 1378 callback: function () { 1379 this.excCallbackSeq(this.req, this.callbacks); 1380 }, 1381 1382 errback: function() { 1383 if(this.errbacks.length == 0) 1384 alert("Error encountered:\n" + this.req.responseText); 1385 1386 this.excCallbackSeq(this.req, this.errbacks); 1387 }, 1388 1389 addErrback: function(fn) { 1390 this.errbacks.unshift(fn); 1391 }, 1392 1393 addCallback: function(fn) { 1394 this.callbacks.unshift(fn); 1395 }, 1396 1397 abort: function() { 1398 this.req.abort(); 1399 }, 1400 1401 addCallbacks: function(fn1, fn2) { 1402 this.addCallback(fn1); 1403 this.addErrback(fn2); 1404 }, 1405 1406 sendReq: function(data) { 1407 if(AJS.isObject(data)) { 1408 this.req.send(AJS.queryArguments(data)); 1409 } 1410 else if(AJS.isDefined(data)) 1411 this.req.send(data); 1412 else { 1413 this.req.send(""); 1414 } 1415 } 1416 }; 1417 1418 //Prevent memory-leaks 1419 AJS.addEventListener(window, 'unload', AJS._unloadListeners); 1420 AJS._createDomShortcuts() 1421 } 1422 1423 script_loaded = true; 1424 1425 /**** 1426 Last Modified: 13/05/07 00:25:28 1427 1428 GoogieSpell 1429 Google spell checker for your own web-apps :) 2 SpellCheck 3 jQuery'fied spell checker based on GoogieSpell 4.0 1430 4 Copyright Amir Salihefendic 2006 5 Copyright Aleksander Machniak 2009 1431 6 LICENSE 1432 GPL (see gpl.txt for more information) 1433 This basically means that you can't use this script with/in proprietary software! 1434 There is another license that permits you to use this script with proprietary software. Check out:... for more info. 1435 AUTHOR 7 GPL 8 AUTHORS 1436 9 4mir Salihefendic (http://amix.dk) - amix@amix.dk 1437 VERSION 1438 4.0 1439 ****/ 1440 var GOOGIE_CUR_LANG = null;1441 var GOOGIE_DEFAULT_LANG = "en";10 Aleksander Machniak - alec [at] alec.pl 11 */ 12 13 var SPELL_CUR_LANG = null; 14 var GOOGIE_DEFAULT_LANG = 'en'; 1442 15 1443 16 function GoogieSpell(img_dir, server_url) { 1444 var cookie_value; 1445 var lang; 1446 cookie_value = getCookie('language'); 1447 1448 if(cookie_value != null) 1449 GOOGIE_CUR_LANG = cookie_value; 1450 else 1451 GOOGIE_CUR_LANG = GOOGIE_DEFAULT_LANG; 17 var ref = this; 18 19 this.array_keys = function(arr) { 20 var res = []; 21 for (var key in arr) { res.push([key]); } 22 return res; 23 } 24 25 var cookie_value = getCookie('language'); 26 GOOGIE_CUR_LANG = cookie_value != null ? cookie_value : GOOGIE_DEFAULT_LANG; 1452 27 1453 28 this.img_dir = img_dir; 1454 29 this.server_url = server_url; 1455 30 1456 this.org_lang_to_word = {"da": "Dansk", "de": "Deutsch", "en": "English", 1457 "es": "Español", "fr": "Français", "it": "Italiano", 1458 "nl": "Nederlands", "pl": "Polski", "pt": "Português", 1459 "fi": "Suomi", "sv": "Svenska"}; 31 this.org_lang_to_word = { 32 "da": "Dansk", "de": "Deutsch", "en": "English", 33 "es": "Español", "fr": "Français", "it": "Italiano", 34 "nl": "Nederlands", "pl": "Polski", "pt": "Português", 35 "fi": "Suomi", "sv": "Svenska" 36 }; 1460 37 this.lang_to_word = this.org_lang_to_word; 1461 this.langlist_codes = AJS.keys(this.lang_to_word); 1462 38 this.langlist_codes = this.array_keys(this.lang_to_word); 1463 39 this.show_change_lang_pic = true; 1464 this.change_lang_pic_placement = "left"; 1465 40 this.change_lang_pic_placement = 'right'; 1466 41 this.report_state_change = true; 1467 42 … … 1476 51 this.lang_no_suggestions = "No suggestions"; 1477 52 1478 this.show_spell_img = false; // modified by roundcube53 this.show_spell_img = false; // roundcube mod. 1479 54 this.decoration = true; 1480 55 this.use_close_btn = true; … … 1505 80 this.cnt_errors = 0; 1506 81 this.cnt_errors_fixed = 0; 1507 82 1508 83 //Set document on click to hide the language and error menu 1509 var fn = function(e) { 1510 var elm = AJS.getEventElm(e); 1511 if(elm.googie_action_btn != "1" && this.isLangWindowShown()) 1512 this.hideLangWindow(); 1513 if(elm.googie_action_btn != "1" && this.isErrorWindowShown()) 1514 this.hideErrorWindow(); 1515 }; 1516 AJS.AEV(document, "click", AJS.$b(fn, this)); 1517 } 1518 1519 GoogieSpell.prototype.decorateTextarea = function(id) { 1520 if(typeof(id) == "string") 1521 this.text_area = AJS.$(id); 1522 else 1523 this.text_area = id; 1524 1525 var r_width, r_height; 1526 1527 if(this.text_area != null) { 1528 if(!AJS.isDefined(this.spell_container) && this.decoration) { 1529 var table = AJS.TABLE(); 1530 var tbody = AJS.TBODY(); 1531 var tr = AJS.TR(); 1532 if(AJS.isDefined(this.force_width)) 1533 r_width = this.force_width; 1534 else 1535 r_width = this.text_area.offsetWidth + "px"; 1536 1537 if(AJS.isDefined(this.force_height)) 1538 r_height = this.force_height; 1539 else 1540 r_height = ""; 1541 1542 var spell_container = AJS.TD(); 84 $(document).bind('click', function(e) { 85 if($(e.target).attr('googie_action_btn') != '1' && ref.isLangWindowShown()) 86 ref.hideLangWindow(); 87 if($(e.target).attr('googie_action_btn') != '1' && ref.isErrorWindowShown()) 88 ref.hideErrorWindow(); 89 }); 90 91 92 this.decorateTextarea = function(id) { 93 this.text_area = typeof(id) == 'string' ? document.getElementById(id) : id; 94 95 if (this.text_area) { 96 if (!this.spell_container && this.decoration) { 97 var table = document.createElement('TABLE'); 98 var tbody = document.createElement('TBODY'); 99 var tr = document.createElement('TR'); 100 var spell_container = document.createElement('TD'); 101 102 var r_width = this.isDefined(this.force_width) ? this.force_width : this.text_area.offsetWidth; 103 var r_height = this.isDefined(this.force_height) ? this.force_height : 16; 104 105 tr.appendChild(spell_container); 106 tbody.appendChild(tr); 107 $(table).append(tbody).insertBefore(this.text_area).width('100%').height(r_height); 108 $(spell_container).height(r_height).width(r_width).css('text-align', 'right'); 109 1543 110 this.spell_container = spell_container; 1544 1545 tr.appendChild(spell_container);1546 1547 tbody.appendChild(tr);1548 table.appendChild(tbody);1549 1550 AJS.insertBefore(table, this.text_area);1551 1552 //Set width1553 AJS.setHeight(table, spell_container, r_height);1554 AJS.setWidth(table, spell_container, '100%'); // modified by roundcube (old: r_width)1555 1556 spell_container.style.textAlign = "right";1557 111 } 1558 112 … … 1560 114 } 1561 115 else 1562 if (this.report_ta_not_found)1563 alert( "Text area not found");116 if (this.report_ta_not_found) 117 alert('Text area not found'); 1564 118 } 1565 119 … … 1567 121 // API Functions (the ones that you can call) 1568 122 ///// 1569 GoogieSpell.prototype.setSpellContainer = function(elm) { 1570 this.spell_container = AJS.$(elm); 1571 } 1572 1573 GoogieSpell.prototype.setLanguages = function(lang_dict) { 123 this.setSpellContainer = function(id) { 124 this.spell_container = typeof(id) == 'string' ? document.getElementById(id) : id; 125 126 } 127 128 this.setLanguages = function(lang_dict) { 1574 129 this.lang_to_word = lang_dict; 1575 this.langlist_codes = AJS.keys(lang_dict); 1576 } 1577 1578 GoogieSpell.prototype.setForceWidthHeight = function(width, height) { 1579 /*** 1580 Set to null if you want to use one of them 1581 ***/ 130 this.langlist_codes = this.array_keys(lang_dict); 131 } 132 133 this.setCurrentLanguage = function(lan_code) { 134 GOOGIE_CUR_LANG = lan_code; 135 136 //Set cookie 137 var now = new Date(); 138 now.setTime(now.getTime() + 365 * 24 * 60 * 60 * 1000); 139 setCookie('language', lan_code, now); 140 } 141 142 this.setForceWidthHeight = function(width, height) { 143 // Set to null if you want to use one of them 1582 144 this.force_width = width; 1583 145 this.force_height = height; 1584 146 } 1585 147 1586 GoogieSpell.prototype.setDecoration = function(bool) {148 this.setDecoration = function(bool) { 1587 149 this.decoration = bool; 1588 150 } 1589 151 1590 GoogieSpell.prototype.dontUseCloseButtons = function() {152 this.dontUseCloseButtons = function() { 1591 153 this.use_close_btn = false; 1592 154 } 1593 155 1594 GoogieSpell.prototype.appendNewMenuItem = function(name, call_back_fn, checker) {156 this.appendNewMenuItem = function(name, call_back_fn, checker) { 1595 157 this.extra_menu_items.push([name, call_back_fn, checker]); 1596 158 } 1597 159 1598 GoogieSpell.prototype.appendCustomMenuBuilder = function(eval, builder) {160 this.appendCustomMenuBuilder = function(eval, builder) { 1599 161 this.custom_menu_builder.push([eval, builder]); 1600 162 } 1601 163 1602 GoogieSpell.prototype.setFocus = function() {164 this.setFocus = function() { 1603 165 try { 1604 166 this.focus_link_b.focus(); … … 1611 173 } 1612 174 1613 GoogieSpell.prototype.getValue = function(ta) {1614 return ta.value;1615 }1616 1617 GoogieSpell.prototype.setValue = function(ta, value) {1618 ta.value = value;1619 }1620 1621 175 1622 176 ////// 1623 177 // Set functions (internal) 1624 178 ///// 1625 GoogieSpell.prototype.setStateChanged = function(current_state) {179 this.setStateChanged = function(current_state) { 1626 180 this.state = current_state; 1627 if (this.spelling_state_observer != null && this.report_state_change)181 if (this.spelling_state_observer != null && this.report_state_change) 1628 182 this.spelling_state_observer(current_state, this); 1629 183 } 1630 184 1631 GoogieSpell.prototype.setReportStateChange = function(bool) {185 this.setReportStateChange = function(bool) { 1632 186 this.report_state_change = bool; 1633 187 } … … 1637 191 // Request functions 1638 192 ///// 1639 GoogieSpell.prototype.getGoogleUrl = function() {193 this.getUrl = function() { 1640 194 return this.server_url + GOOGIE_CUR_LANG; 1641 195 } 1642 196 1643 GoogieSpell.escapeSepcial = function(val) {197 this.escapeSpecial = function(val) { 1644 198 return val.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">"); 1645 199 } 1646 200 1647 GoogieSpell.createXMLReq = function (text) {1648 return '<?xml version="1.0" encoding="utf-8" ?> <spellrequest textalreadyclipped="0" ignoredups="0" ignoredigits="1" ignoreallcaps="1"><text>' + text + '</text></spellrequest>';1649 } 1650 1651 GoogieSpell.prototype.spellCheck = function(ignore) { 1652 var me = this; 1653 201 this.createXMLReq = function (text) { 202 return '<?xml version="1.0" encoding="utf-8" ?>' 203 + '<spellrequest textalreadyclipped="0" ignoredups="0" ignoredigits="1" ignoreallcaps="1">' 204 + '<text>' + text + '</text></spellrequest>'; 205 } 206 207 this.spellCheck = function(ignore) { 1654 208 this.cnt_errors_fixed = 0; 1655 209 this.cnt_errors = 0; 1656 this.setStateChanged( "checking_spell");1657 1658 if (this.main_controller)210 this.setStateChanged('checking_spell'); 211 212 if (this.main_controller) 1659 213 this.appendIndicator(this.spell_span); 1660 214 1661 215 this.error_links = []; 1662 216 this.ta_scroll_top = this.text_area.scrollTop; 1663 1664 try { this.hideLangWindow(); }1665 catch(e) {}1666 1667 217 this.ignore = ignore; 1668 1669 if(this.getValue(this.text_area) == '' || ignore) { 1670 if(!me.custom_no_spelling_error) 1671 me.flashNoSpellingErrorState(); 218 this.hideLangWindow(); 219 220 if ($(this.text_area).val() == '' || ignore) { 221 if (!this.custom_no_spelling_error) 222 this.flashNoSpellingErrorState(); 1672 223 else 1673 me.custom_no_spelling_error(me);1674 me.removeIndicator();1675 return ;224 this.custom_no_spelling_error(this); 225 this.removeIndicator(); 226 return; 1676 227 } 1677 228 1678 229 this.createEditLayer(this.text_area.offsetWidth, this.text_area.offsetHeight); 1679 1680 230 this.createErrorWindow(); 1681 AJS.getBody().appendChild(this.error_window);231 $('body').append(this.error_window); 1682 232 1683 233 try { netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserRead"); } 1684 234 catch (e) { } 1685 235 1686 if(this.main_controller) 1687 this.spell_span.onclick = null; 1688 1689 this.orginal_text = this.getValue(this.text_area); 1690 1691 //Create request 1692 var d = AJS.getRequest(this.getGoogleUrl()); 1693 var reqdone = function(res_txt) { 1694 var r_text = res_txt; 1695 me.results = me.parseResult(r_text); 1696 1697 if(r_text.match(/<c.*>/) != null) { 1698 //Before parsing be sure that errors were found 1699 me.showErrorsInIframe(); 1700 me.resumeEditingState(); 1701 } 1702 else { 1703 if(!me.custom_no_spelling_error) 1704 me.flashNoSpellingErrorState(); 1705 else 1706 me.custom_no_spelling_error(me); 1707 } 1708 me.removeIndicator(); 1709 }; 1710 1711 d.addCallback(reqdone); 1712 reqdone = null; 1713 1714 var reqfailed = function(res_txt, req) { 1715 if(me.custom_ajax_error) 1716 me.custom_ajax_error(req); 1717 else 1718 alert("An error was encountered on the server. Please try again later."); 1719 1720 if(me.main_controller) { 1721 AJS.removeElement(me.spell_span); 1722 me.removeIndicator(); 1723 } 1724 me.checkSpellingState(); 1725 }; 1726 d.addErrback(reqfailed); 1727 reqfailed = null; 1728 1729 var req_text = GoogieSpell.escapeSepcial(this.orginal_text); 1730 d.sendReq(GoogieSpell.createXMLReq(req_text)); 236 if (this.main_controller) 237 $(this.spell_span).unbind('click'); 238 239 this.orginal_text = $(this.text_area).val(); 240 var req_text = this.escapeSpecial(this.orginal_text); 241 var ref = this; 242 243 $.ajax({ type: 'POST', url: this.getUrl(), 244 data: this.createXMLReq(req_text), dataType: 'text', 245 error: function(o) { 246 if (ref.custom_ajax_error) 247 ref.custom_ajax_error(ref); 248 else 249 alert('An error was encountered on the server. Please try again later.'); 250 if (ref.main_controller) { 251 $(ref.spell_span).remove(); 252 ref.removeIndicator(); 253 } 254 ref.checkSpellingState(); 255 }, 256 success: function(data) { 257 var r_text = data; 258 ref.results = ref.parseResult(r_text); 259 if (r_text.match(/<c.*>/) != null) { 260 //Before parsing be sure that errors were found 261 ref.showErrorsInIframe(); 262 ref.resumeEditingState(); 263 } else { 264 if (!ref.custom_no_spelling_error) 265 ref.flashNoSpellingErrorState(); 266 else 267 ref.custom_no_spelling_error(ref); 268 } 269 ref.removeIndicator(); 270 } 271 }); 1731 272 } 1732 273 … … 1735 276 // Spell checking functions 1736 277 ///// 1737 GoogieSpell.prototype.parseResult = function(r_text) { 1738 /*** 1739 Retunrs an array 1740 result[item] -> ['attrs'], ['suggestions'] 1741 ***/ 278 this.parseResult = function(r_text) { 279 // Returns an array: result[item] -> ['attrs'], ['suggestions'] 1742 280 var re_split_attr_c = /\w+="(\d+|true)"/g; 1743 281 var re_split_text = /\t/g; … … 1746 284 var results = new Array(); 1747 285 1748 if (matched_c == null)286 if (matched_c == null) 1749 287 return results; 1750 288 1751 for (var i=0; i < matched_c.length; i++) {289 for (var i=0; i < matched_c.length; i++) { 1752 290 var item = new Array(); 1753 291 this.errorFound(); … … 1756 294 item['attrs'] = new Array(); 1757 295 var split_c = matched_c[i].match(re_split_attr_c); 1758 for (var j=0; j < split_c.length; j++) {296 for (var j=0; j < split_c.length; j++) { 1759 297 var c_attr = split_c[j].split(/=/); 1760 298 var val = c_attr[1].replace(/"/g, ''); 1761 if(val != "true") 1762 item['attrs'][c_attr[0]] = parseInt(val); 1763 else { 1764 item['attrs'][c_attr[0]] = val; 1765 } 299 item['attrs'][c_attr[0]] = val != 'true' ? parseInt(val) : val; 1766 300 } 1767 301 1768 302 //Get suggestions 1769 303 item['suggestions'] = new Array(); 1770 var only_text = matched_c[i].replace(/<[^>]*>/g, "");304 var only_text = matched_c[i].replace(/<[^>]*>/g, ''); 1771 305 var split_t = only_text.split(re_split_text); 1772 for (var k=0; k < split_t.length; k++) {1773 if(split_t[k] != "")1774 item['suggestions'].push(split_t[k]);1775 }306 for (var k=0; k < split_t.length; k++) { 307 if(split_t[k] != '') 308 item['suggestions'].push(split_t[k]); 309 } 1776 310 results.push(item); 1777 311 } … … 1779 313 } 1780 314 1781 //////1782 // Counters1783 /////1784 GoogieSpell.prototype.errorFixed = function() {1785 this.cnt_errors_fixed++;1786 if(this.all_errors_fixed_observer)1787 if(this.cnt_errors_fixed == this.cnt_errors) {1788 this.hideErrorWindow();1789 this.all_errors_fixed_observer();1790 }1791 }1792 GoogieSpell.prototype.errorFound = function() { this.cnt_errors++; }1793 315 1794 316 ////// 1795 317 // Error menu functions 1796 318 ///// 1797 GoogieSpell.prototype.createErrorWindow = function() { 1798 this.error_window = AJS.DIV(); 1799 this.error_window.className = "googie_window"; 1800 this.error_window.googie_action_btn = "1"; 1801 } 1802 1803 GoogieSpell.prototype.isErrorWindowShown = function() { 1804 return this.error_window != null && this.error_window.style.visibility == "visible"; 1805 } 1806 1807 GoogieSpell.prototype.hideErrorWindow = function() { 1808 try { 1809 this.error_window.style.visibility = "hidden"; 1810 if(this.error_window_iframe) 1811 this.error_window_iframe.style.visibility = "hidden"; 1812 } 1813 catch(e) {} 1814 } 1815 1816 GoogieSpell.prototype.updateOrginalText = function(offset, old_value, new_value, id) { 319 this.createErrorWindow = function() { 320 this.error_window = document.createElement('DIV'); 321 $(this.error_window).addClass('googie_window').attr('googie_action_btn', '1'); 322 } 323 324 this.isErrorWindowShown = function() { 325 return $(this.error_window).is(':visible'); 326 } 327 328 this.hideErrorWindow = function() { 329 $(this.error_window).css('visibility', 'hidden'); 330 $(this.error_window_iframe).css('visibility', 'hidden'); 331 } 332 333 this.updateOrginalText = function(offset, old_value, new_value, id) { 1817 334 var part_1 = this.orginal_text.substring(0, offset); 1818 335 var part_2 = this.orginal_text.substring(offset+old_value.length); 1819 336 this.orginal_text = part_1 + new_value + part_2; 1820 this.setValue(this.text_area,this.orginal_text);337 $(this.text_area).val(this.orginal_text); 1821 338 var add_2_offset = new_value.length - old_value.length; 1822 for (var j=0; j < this.results.length; j++) {339 for (var j=0; j < this.results.length; j++) { 1823 340 //Don't edit the offset of the current item 1824 if (j != id && j > id){341 if (j != id && j > id) 1825 342 this.results[j]['attrs']['o'] += add_2_offset; 1826 } 1827 } 1828 } 1829 1830 GoogieSpell.prototype.saveOldValue = function(elm, old_value) { 343 } 344 } 345 346 this.saveOldValue = function(elm, old_value) { 1831 347 elm.is_changed = true; 1832 348 elm.old_value = old_value; 1833 349 } 1834 350 1835 GoogieSpell.prototype.createListSeparator = function() {1836 var e_col = AJS.TD(" ");1837 e_col.googie_action_btn = "1";1838 e_col.style.cursor = "default"; 1839 e_col.style.fontSize = "3px";1840 e_col.style.borderTop = "1px solid #ccc";1841 e_col.style.paddingTop = "3px";1842 1843 return AJS.TR(e_col);1844 } 1845 1846 GoogieSpell.prototype.correctError = function(id, elm, l_elm, /*optional*/rm_pre_space) {351 this.createListSeparator = function() { 352 var td = document.createElement('TD'); 353 var tr = document.createElement('TR'); 354 355 $(td).html(' ').attr('googie_action_btn', '1') 356 .css({'cursor': 'default', 'font-size': '3px', 'border-top': '1px solid #ccc', 'padding-top': '3px'}); 357 tr.appendChild(td); 358 359 return tr; 360 } 361 362 this.correctError = function(id, elm, l_elm, rm_pre_space) { 1847 363 var old_value = elm.innerHTML; 1848 364 var new_value = l_elm.innerHTML; 1849 365 var offset = this.results[id]['attrs']['o']; 1850 366 1851 if (rm_pre_space) {367 if (rm_pre_space) { 1852 368 var pre_length = elm.previousSibling.innerHTML; 1853 369 elm.previousSibling.innerHTML = pre_length.slice(0, pre_length.length-1); … … 1857 373 1858 374 this.hideErrorWindow(); 1859 1860 375 this.updateOrginalText(offset, old_value, new_value, id); 1861 376 1862 elm.innerHTML = new_value; 1863 1864 elm.style.color = "green"; 1865 elm.is_corrected = true; 377 $(elm).html(new_value).css('color', 'green').attr('is_corrected', true); 1866 378 1867 379 this.results[id]['attrs']['l'] = new_value.length; 1868 380 1869 if (!AJS.isDefined(elm.old_value))381 if (!this.isDefined(elm.old_value)) 1870 382 this.saveOldValue(elm, old_value); 1871 383 … … 1873 385 } 1874 386 1875 GoogieSpell.prototype.showErrorWindow = function(elm, id) {1876 if (this.show_menu_observer)387 this.showErrorWindow = function(elm, id) { 388 if (this.show_menu_observer) 1877 389 this.show_menu_observer(this); 1878 var me = this; 1879 1880 var abs_pos = AJS.absolutePosition(elm); 1881 abs_pos.y -= this.edit_layer.scrollTop; 1882 this.error_window.style.visibility = "visible"; 1883 1884 AJS.setTop(this.error_window, (abs_pos.y+20)); 1885 AJS.setLeft(this.error_window, (abs_pos.x)); 1886 1887 this.error_window.innerHTML = ""; 1888 1889 var table = AJS.TABLE({'class': 'googie_list'}); 1890 table.googie_action_btn = "1"; 1891 var list = AJS.TBODY(); 390 391 var ref = this; 392 var pos = $(elm).offset(); 393 pos.top -= this.edit_layer.scrollTop; 394 395 $(this.error_window).css({'visibility': 'visible', 396 'top': (pos.top+20)+'px', 'left': (pos.left)+'px'}).html(''); 397 398 var table = document.createElement('TABLE'); 399 var list = document.createElement('TBODY'); 400 401 $(table).addClass('googie_list').attr('googie_action_btn', '1'); 1892 402 1893 403 //Check if we should use custom menu builder, if not we use the default 1894 404 var changed = false; 1895 if (this.custom_menu_builder != []) {1896 for (var k=0; k<this.custom_menu_builder.length; k++) {405 if (this.custom_menu_builder != []) { 406 for (var k=0; k<this.custom_menu_builder.length; k++) { 1897 407 var eb = this.custom_menu_builder[k]; 1898 408 if(eb[0]((this.results[id]))){ … … 1902 412 } 1903 413 } 1904 if (!changed) {414 if (!changed) { 1905 415 //Build up the result list 1906 416 var suggestions = this.results[id]['suggestions']; … … 1908 418 var len = this.results[id]['attrs']['l']; 1909 419 1910 if(suggestions.length == 0) { 1911 var row = AJS.TR(); 1912 var item = AJS.TD({'style': 'cursor: default;'}); 1913 var dummy = AJS.SPAN(); 1914 dummy.innerHTML = this.lang_no_suggestions; 1915 AJS.ACN(item, AJS.TN(dummy.innerHTML)); 1916 item.googie_action_btn = "1"; 420 if (suggestions.length == 0) { 421 var row = document.createElement('TR'); 422 var item = document.createElement('TD'); 423 var dummy = document.createElement('SPAN'); 424 425 $(dummy).text(this.lang_no_suggestions); 426 $(item).attr('googie_action_btn', '1').css('cursor', 'default'); 427 428 item.appendChild(dummy); 1917 429 row.appendChild(item); 1918 430 list.appendChild(row); 1919 431 } 1920 432 1921 for (i=0; i < suggestions.length; i++) {1922 var row = AJS.TR();1923 var item = AJS.TD();1924 var dummy = AJS.SPAN();1925 dummy.innerHTML = suggestions[i]; 1926 item.appendChild(AJS.TN(dummy.innerHTML));433 for (i=0; i < suggestions.length; i++) { 434 var row = document.createElement('TR'); 435 var item = document.createElement('TD'); 436 var dummy = document.createElement('SPAN'); 437 438 $(dummy).html(suggestions[i]); 1927 439 1928 var fn = function(e) { 1929 var l_elm = AJS.getEventElm(e); 1930 this.correctError(id, elm, l_elm); 1931 }; 1932 1933 AJS.AEV(item, "click", AJS.$b(fn, this)); 1934 1935 item.onmouseover = GoogieSpell.item_onmouseover; 1936 item.onmouseout = GoogieSpell.item_onmouseout; 440 $(item).bind('mouseover', this.item_onmouseover) 441 .bind('mouseout', this.item_onmouseout) 442 .bind('click', function(e) { ref.correctError(id, elm, e.target.firstChild) }); 443 444 item.appendChild(dummy); 1937 445 row.appendChild(item); 1938 446 list.appendChild(row); … … 1940 448 1941 449 //The element is changed, append the revert 1942 if (elm.is_changed && elm.innerHTML != elm.old_value) {450 if (elm.is_changed && elm.innerHTML != elm.old_value) { 1943 451 var old_value = elm.old_value; 1944 var revert_row = AJS.TR(); 1945 var revert = AJS.TD(); 1946 1947 revert.onmouseover = GoogieSpell.item_onmouseover; 1948 revert.onmouseout = GoogieSpell.item_onmouseout; 1949 var rev_span = AJS.SPAN({'class': 'googie_list_revert'}); 1950 rev_span.innerHTML = this.lang_revert + " " + old_value; 452 var revert_row = document.createElement('TR'); 453 var revert = document.createElement('TD'); 454 var rev_span = document.createElement('SPAN'); 455 456 $(rev_span).addClass('googie_list_revert').html(this.lang_revert + ' ' + old_value); 457 458 $(revert).bind('mouseover', this.item_onmouseover) 459 .bind('mouseout', this.item_onmouseout) 460 .bind('click', function(e) { 461 ref.updateOrginalText(offset, elm.innerHTML, old_value, id); 462 $(elm).attr('is_corrected', true).css('color', '#b91414').html(old_value); 463 ref.hideErrorWindow(); 464 }); 465 1951 466 revert.appendChild(rev_span); 1952 1953 var fn = function(e) {1954 this.updateOrginalText(offset, elm.innerHTML, old_value, id);1955 elm.is_corrected = true;1956 elm.style.color = "#b91414";1957 elm.innerHTML = old_value;1958 this.hideErrorWindow();1959 };1960 AJS.AEV(revert, "click", AJS.$b(fn, this));1961 1962 467 revert_row.appendChild(revert); 1963 468 list.appendChild(revert_row); … … 1965 470 1966 471 //Append the edit box 1967 var edit_row = AJS.TR();1968 var edit = AJS.TD({'style': 'cursor: default'});1969 1970 var edit_input = AJS.INPUT({'style': 'width: 120px; margin:0; padding:0', 'value': elm.innerHTML});1971 edit_input.googie_action_btn = "1";472 var edit_row = document.createElement('TR'); 473 var edit = document.createElement('TD'); 474 var edit_input = document.createElement('INPUT'); 475 var ok_pic = document.createElement('IMG'); 476 var edit_form = document.createElement('FORM'); 1972 477 1973 478 var onsub = function () { 1974 if(edit_input.value != "") { 1975 if(!AJS.isDefined(elm.old_value)) 1976 this.saveOldValue(elm, elm.innerHTML); 1977 1978 this.updateOrginalText(offset, elm.innerHTML, edit_input.value, id); 1979 elm.style.color = "green" 1980 elm.is_corrected = true; 1981 elm.innerHTML = edit_input.value; 1982 1983 this.hideErrorWindow(); 479 if (edit_input.value != '') { 480 if (!ref.isDefined(elm.old_value)) 481 ref.saveOldValue(elm, elm.innerHTML); 482 483 ref.updateOrginalText(offset, elm.innerHTML, edit_input.value, id); 484 $(elm).attr('is_corrected', true).css('color', 'green').html(edit_input.value); 485 ref.hideErrorWindow(); 1984 486 } 1985 487 return false; 1986 488 }; 1987 onsub = AJS.$b(onsub, this); 489 490 $(edit_input).width(120).css({'margin': 0, 'padding': 0}); 491 $(edit_input).val(elm.innerHTML).attr('googie_action_btn', '1'); 492 $(edit).css('cursor', 'default').attr('googie_action_btn', '1'); 493 494 $(ok_pic).attr('src', this.img_dir + 'ok.gif') 495 .width(32).height(16) 496 .css({'cursor': 'pointer', 'margin-left': '2px', 'margin-right': '2px'}) 497 .bind('click', onsub); 498 499 $(edit_form).attr('googie_action_btn', '1') 500 .css({'margin': 0, 'padding': 0, 'cursor': 'default', 'white-space': 'nowrap'}) 501 .bind('submit', onsub); 1988 502 1989 var ok_pic = AJS.IMG({'src': this.img_dir + "ok.gif", 'style': 'width: 32px; height: 16px; margin-left: 2px; margin-right: 2px; cursor: pointer;'}); 1990 var edit_form = AJS.FORM({'style': 'margin: 0; padding: 0; cursor: default;'}, edit_input, ok_pic); 1991 1992 edit_form.googie_action_btn = "1"; 1993 edit.googie_action_btn = "1"; 1994 1995 AJS.AEV(edit_form, "submit", onsub); 1996 AJS.AEV(ok_pic, "click", onsub); 1997 503 edit_form.appendChild(edit_input); 504 edit_form.appendChild(ok_pic); 1998 505 edit.appendChild(edit_form); 1999 506 edit_row.appendChild(edit); … … 2001 508 2002 509 //Append extra menu items 2003 if (this.extra_menu_items.length > 0)2004 AJS.ACN(list,this.createListSeparator());2005 510 if (this.extra_menu_items.length > 0) 511 list.appendChild(this.createListSeparator()); 512 2006 513 var loop = function(i) { 2007 if(i < me.extra_menu_items.length) { 2008 var e_elm = me.extra_menu_items[i]; 2009 2010 if(!e_elm[2] || e_elm[2](elm, me)) { 2011 var e_row = AJS.TR(); 2012 var e_col = AJS.TD(e_elm[0]); 2013 2014 e_col.onmouseover = GoogieSpell.item_onmouseover; 2015 e_col.onmouseout = GoogieSpell.item_onmouseout; 2016 2017 var fn = function() { 2018 return e_elm[1](elm, me); 2019 }; 2020 AJS.AEV(e_col, "click", fn); 2021 2022 AJS.ACN(e_row, e_col); 2023 AJS.ACN(list, e_row); 2024 514 if (i < ref.extra_menu_items.length) { 515 var e_elm = ref.extra_menu_items[i]; 516 517 if (!e_elm[2] || e_elm[2](elm, ref)) { 518 var e_row = document.createElement('TR'); 519 var e_col = document.createElement('TD'); 520 521 $(e_col).html(e_elm[0]) 522 .bind('mouseover', ref.item_onmouseover) 523 .bind('mouseout', ref.item_onmouseout) 524 .bind('click', function() { return e_elm[1](elm, ref) }); 525 526 e_row.appendChild(e_col); 527 list.appendChild(e_row); 2025 528 } 2026 529 loop(i+1); 2027 530 } 2028 531 } 532 2029 533 loop(0); 2030 534 loop = null; 2031 535 2032 536 //Close button 2033 if (this.use_close_btn) {2034 AJS.ACN(list,this.createCloseButton(this.hideErrorWindow));537 if (this.use_close_btn) { 538 list.appendChild(this.createCloseButton(this.hideErrorWindow)); 2035 539 } 2036 540 } … … 2040 544 2041 545 //Dummy for IE - dropdown bug fix 2042 if(AJS.isIe() && !this.error_window_iframe) { 2043 var iframe = AJS.IFRAME({'style': 'position: absolute; z-index: 0;'}); 2044 AJS.ACN(AJS.getBody(), iframe); 2045 this.error_window_iframe = iframe; 2046 } 2047 if(AJS.isIe()) { 2048 var iframe = this.error_window_iframe; 2049 AJS.setTop(iframe, this.error_window.offsetTop); 2050 AJS.setLeft(iframe, this.error_window.offsetLeft); 2051 2052 AJS.setWidth(iframe, this.error_window.offsetWidth); 2053 AJS.setHeight(iframe, this.error_window.offsetHeight); 2054 2055 iframe.style.visibility = "visible"; 2056 } 2057 2058 //Set focus on the last element 2059 var link = this.createFocusLink('link'); 2060 list.appendChild(AJS.TR(AJS.TD({'style': 'text-align: right; font-size: 1px; height: 1px; margin: 0; padding: 0;'}, link))); 2061 link.focus(); 546 if ($.browser.msie) { 547 if (!this.error_window_iframe) { 548 var iframe = $('<iframe>').css('position', 'absolute').css('z-index', 0); 549 $('body').append(iframe); 550 this.error_window_iframe = iframe; 551 } 552 553 $(this.error_window_iframe).css({'visibility': 'visible', 554 'top': this.error_window.offsetTop, 'left': this.error_window.offsetLeft, 555 'width': this.error_window.offsetWidth, 'height': this.error_window.offsetHeight}); 556 } 2062 557 } 2063 558 … … 2066 561 // Edit layer (the layer where the suggestions are stored) 2067 562 ////// 2068 GoogieSpell.prototype.createEditLayer = function(width, height) { 2069 this.edit_layer = AJS.DIV({'class': 'googie_edit_layer'}); 2070 2071 //Set the style so it looks like edit areas 2072 this.edit_layer.className = this.text_area.className; 2073 this.edit_layer.style.border = "1px solid #999"; 2074 this.edit_layer.style.backgroundColor = "#F1EDFE"; // modified by roundcube 2075 this.edit_layer.style.padding = "3px"; 2076 this.edit_layer.style.margin = "0px"; 2077 2078 AJS.setWidth(this.edit_layer, (width-8)); 2079 2080 if(AJS.nodeName(this.text_area) != "input" || this.getValue(this.text_area) == "") { 2081 this.edit_layer.style.overflow = "auto"; 2082 AJS.setHeight(this.edit_layer, (height-6)); 2083 } 2084 else { 2085 this.edit_layer.style.overflow = "hidden"; 2086 } 2087 2088 if(this.edit_layer_dbl_click) { 2089 var me = this; 2090 var fn = function(e) { 2091 if(AJS.getEventElm(e).className != "googie_link" && !me.isErrorWindowShown()) { 2092 me.resumeEditing(); 563 this.createEditLayer = function(width, height) { 564 this.edit_layer = document.createElement('DIV'); 565 $(this.edit_layer).addClass('googie_edit_layer').width(width-10).height(height); 566 567 if (this.text_area.nodeName != 'INPUT' || $(this.text_area).val() == '') { 568 $(this.edit_layer).css('overflow', 'auto').height(height-4); 569 } else { 570 $(this.edit_layer).css('overflow', 'hidden'); 571 } 572 573 var ref = this; 574 if (this.edit_layer_dbl_click) { 575 $(this.edit_layer).bind('click', function(e) { 576 if (e.target.className != 'googie_link' && !ref.isErrorWindowShown()) { 577 ref.resumeEditing(); 2093 578 var fn1 = function() { 2094 me.text_area.focus();579 $(ref.text_area).focus(); 2095 580 fn1 = null; 2096 581 }; 2097 AJS.callLater(fn1, 10);582 window.setTimeout(fn1, 10); 2098 583 } 2099 584 return false; 2100 }; 2101 this.edit_layer.ondblclick = fn; 2102 fn = null; 2103 } 2104 } 2105 2106 GoogieSpell.prototype.resumeEditing = function() { 2107 this.setStateChanged("spell_check"); 2108 this.switch_lan_pic.style.display = "inline"; 2109 2110 if(this.edit_layer) 585 }); 586 } 587 } 588 589 this.resumeEditing = function() { 590 this.setStateChanged('ready'); 591 592 if (this.edit_layer) 2111 593 this.el_scroll_top = this.edit_layer.scrollTop; 2112 594 2113 595 this.hideErrorWindow(); 2114 596 2115 if(this.main_controller) 2116 this.spell_span.className = "googie_no_style"; 2117 2118 if(!this.ignore) { 2119 //Remove the EDIT_LAYER 2120 try { 2121 this.edit_layer.parentNode.removeChild(this.edit_layer); 2122 if(this.use_focus) { 2123 AJS.removeElement(this.focus_link_t); 2124 AJS.removeElement(this.focus_link_b); 2125 } 2126 } 2127 catch(e) { 2128 } 2129 2130 AJS.showElement(this.text_area); 2131 2132 if(this.el_scroll_top != undefined) 597 if (this.main_controller) 598 $(this.spell_span).removeClass().addClass('googie_no_style'); 599 600 if (!this.ignore) { 601 if (this.use_focus) { 602 $(this.focus_link_t).remove(); 603 $(this.focus_link_b).remove(); 604 } 605 606 $(this.edit_layer).remove(); 607 $(this.text_area).show(); 608 609 if (this.el_scroll_top != undefined) 2133 610 this.text_area.scrollTop = this.el_scroll_top; 2134 611 } 2135 2136 612 this.checkSpellingState(false); 2137 613 } 2138 614 2139 GoogieSpell.prototype.createErrorLink = function(text, id) {2140 var elm = AJS.SPAN({'class': 'googie_link'});2141 var me= this;615 this.createErrorLink = function(text, id) { 616 var elm = document.createElement('SPAN'); 617 var ref = this; 2142 618 var d = function (e) { 2143 me.showErrorWindow(elm, id);2144 d = null;2145 return false;619 ref.showErrorWindow(elm, id); 620 d = null; 621 return false; 2146 622 }; 2147 AJS.AEV(elm, "click", d); 2148 2149 elm.googie_action_btn = "1"; 2150 elm.g_id = id; 2151 elm.is_corrected = false; 2152 elm.oncontextmenu = d; 2153 elm.innerHTML = text; 623 624 $(elm).html(text).addClass('googie_link').bind('click', d) 625 .attr({'googie_action_btn' : '1', 'g_id' : id, 'is_corrected' : false}); 626 2154 627 return elm; 2155 628 } 2156 629 2157 GoogieSpell.createPart = function(txt_part) { 2158 if(txt_part == " ") 2159 return AJS.TN(" "); 2160 var result = AJS.SPAN(); 2161 2162 var is_first = true; 2163 var is_safari = (navigator.userAgent.toLowerCase().indexOf("safari") != -1); 2164 2165 var part = AJS.SPAN(); 2166 txt_part = GoogieSpell.escapeSepcial(txt_part); 630 this.createPart = function(txt_part) { 631 if (txt_part == " ") 632 return document.createTextNode(" "); 633 634 txt_part = this.escapeSpecial(txt_part); 2167 635 txt_part = txt_part.replace(/\n/g, "<br>"); 2168 636 txt_part = txt_part.replace(/ /g, " "); … … 2170 638 txt_part = txt_part.replace(/ $/g, " "); 2171 639 2172 part.innerHTML = txt_part; 2173 2174 return part; 2175 } 2176 2177 GoogieSpell.prototype.showErrorsInIframe = function() { 2178 var output = AJS.DIV(); 2179 output.style.textAlign = "left"; 640 var span = document.createElement('SPAN'); 641 $(span).html(txt_part); 642 return span; 643 } 644 645 this.showErrorsInIframe = function() { 646 var output = document.createElement('DIV') 2180 647 var pointer = 0; 2181 648 var results = this.results; 2182 649 2183 if (results.length > 0) {2184 for (var i=0; i < results.length; i++) {650 if (results.length > 0) { 651 for (var i=0; i < results.length; i++) { 2185 652 var offset = results[i]['attrs']['o']; 2186 653 var len = results[i]['attrs']['l']; 2187 2188 654 var part_1_text = this.orginal_text.substring(pointer, offset); 2189 var part_1 = GoogieSpell.createPart(part_1_text); 655 var part_1 = this.createPart(part_1_text); 656 2190 657 output.appendChild(part_1); 2191 658 pointer += offset - pointer; … … 2199 666 //Insert the rest of the orginal text 2200 667 var part_2_text = this.orginal_text.substr(pointer, this.orginal_text.length); 2201 2202 var part_2 = GoogieSpell.createPart(part_2_text); 668 var part_2 = this.createPart(part_2_text); 669 2203 670 output.appendChild(part_2); 2204 671 } … … 2206 673 output.innerHTML = this.orginal_text; 2207 674 675 $(output).css('text-align', 'left'); 676 2208 677 var me = this; 2209 if (this.custom_item_evaulator)2210 AJS.map(this.error_links, function(elm){me.custom_item_evaulator(me, elm)});678 if (this.custom_item_evaulator) 679 $.map(this.error_links, function(elm){me.custom_item_evaulator(me, elm)}); 2211 680 2212 AJS.ACN(this.edit_layer, output); 2213 2214 //Hide text area 2215 this.text_area_bottom = this.text_area.offsetTop + this.text_area.offsetHeight; 2216 2217 AJS.hideElement(this.text_area); 2218 2219 AJS.insertBefore(this.edit_layer, this.text_area); 2220 2221 if(this.use_focus) { 681 $(this.edit_layer).append(output); 682 683 //Hide text area and show edit layer 684 $(this.text_area).hide(); 685 $(this.edit_layer).insertBefore(this.text_area); 686 687 if (this.use_focus) { 2222 688 this.focus_link_t = this.createFocusLink('focus_t'); 2223 689 this.focus_link_b = this.createFocusLink('focus_b'); 2224 690 2225 AJS.insertBefore(this.focus_link_t,this.edit_layer);2226 AJS.insertAfter(this.focus_link_b,this.edit_layer);2227 } 2228 2229 this.edit_layer.scrollTop = this.ta_scroll_top;691 $(this.focus_link_t).insertBefore(this.edit_layer); 692 $(this.focus_link_b).insertAfter(this.edit_layer); 693 } 694 695 // this.edit_layer.scrollTop = this.ta_scroll_top; 2230 696 } 2231 697 … … 2234 700 // Choose language menu 2235 701 ////// 2236 GoogieSpell.prototype.createLangWindow = function() { 2237 this.language_window = AJS.DIV({'class': 'googie_window'}); 2238 AJS.setWidth(this.language_window, 100); 2239 2240 this.language_window.googie_action_btn = "1"; 702 this.createLangWindow = function() { 703 this.language_window = document.createElement('DIV'); 704 $(this.language_window).addClass('googie_window') 705 .width(100).attr('googie_action_btn', '1'); 2241 706 2242 707 //Build up the result list 2243 var table = AJS.TABLE({'class': 'googie_list'}); 2244 AJS.setWidth(table, "100%"); 2245 var list = AJS.TBODY(); 2246 708 var table = document.createElement('TABLE'); 709 var list = document.createElement('TBODY'); 710 var ref = this; 711 712 $(table).addClass('googie_list').width('100%'); 2247 713 this.lang_elms = new Array(); 2248 714 2249 for(i=0; i < this.langlist_codes.length; i++) { 2250 var row = AJS.TR(); 2251 var item = AJS.TD(); 2252 item.googieId = this.langlist_codes[i]; 715 for (i=0; i < this.langlist_codes.length; i++) { 716 var row = document.createElement('TR'); 717 var item = document.createElement('TD'); 718 var span = document.createElement('SPAN'); 719 720 $(span).text(this.lang_to_word[this.langlist_codes[i]]); 2253 721 this.lang_elms.push(item); 2254 var lang_span = AJS.SPAN(); 2255 lang_span.innerHTML = this.lang_to_word[this.langlist_codes[i]]; 2256 item.appendChild(AJS.TN(lang_span.innerHTML)); 2257 2258 var fn = function(e) { 2259 var elm = AJS.getEventElm(e); 2260 this.deHighlightCurSel(); 2261 2262 this.setCurrentLanguage(elm.googieId); 2263 2264 if(this.lang_state_observer != null) { 2265 this.lang_state_observer(); 2266 } 2267 2268 this.highlightCurSel(); 2269 this.hideLangWindow(); 2270 }; 2271 AJS.AEV(item, "click", AJS.$b(fn, this)); 2272 2273 item.onmouseover = function(e) { 2274 var i_it = AJS.getEventElm(e); 2275 if(i_it.className != "googie_list_selected") 2276 i_it.className = "googie_list_onhover"; 2277 }; 2278 item.onmouseout = function(e) { 2279 var i_it = AJS.getEventElm(e); 2280 if(i_it.className != "googie_list_selected") 2281 i_it.className = "googie_list_onout"; 2282 }; 2283 722 723 $(item).attr('googieId', this.langlist_codes[i]) 724 .bind('click', function(e) { 725 ref.deHighlightCurSel(); 726 ref.setCurrentLanguage($(this).attr('googieId')); 727 728 if (ref.lang_state_observer != null) { 729 ref.lang_state_observer(); 730 } 731 732 ref.highlightCurSel(); 733 ref.hideLangWindow(); 734 }) 735 .bind('mouseover', function(e) { 736 if (this.className != "googie_list_selected") 737 this.className = "googie_list_onhover"; 738 }) 739 .bind('mouseout', function(e) { 740 if (this.className != "googie_list_selected") 741 this.className = "googie_list_onout"; 742 }); 743 744 item.appendChild(span); 2284 745 row.appendChild(item); 2285 746 list.appendChild(row); … … 2287 748 2288 749 //Close button 2289 if (this.use_close_btn) {2290 list.appendChild(this.createCloseButton( this.hideLangWindow));750 if (this.use_close_btn) { 751 list.appendChild(this.createCloseButton(function () { ref.hideLangWindow.apply(ref) })); 2291 752 } 2292 753 … … 2297 758 } 2298 759 2299 GoogieSpell.prototype.setCurrentLanguage = function(lan_code) { 2300 GOOGIE_CUR_LANG = lan_code; 2301 2302 //Set cookie 2303 var now = new Date(); 2304 now.setTime(now.getTime() + 365 * 24 * 60 * 60 * 1000); 2305 setCookie('language', lan_code, now); 2306 } 2307 2308 GoogieSpell.prototype.isLangWindowShown = function() { 2309 return this.language_window != null && this.language_window.style.visibility == "visible"; 2310 } 2311 2312 GoogieSpell.prototype.hideLangWindow = function() { 2313 try { 2314 this.language_window.style.visibility = "hidden"; 2315 this.switch_lan_pic.className = "googie_lang_3d_on"; 2316 } 2317 catch(e) {} 2318 } 2319 2320 GoogieSpell.prototype.deHighlightCurSel = function() { 2321 this.lang_cur_elm.className = "googie_list_onout"; 2322 } 2323 2324 GoogieSpell.prototype.highlightCurSel = function() { 2325 if(GOOGIE_CUR_LANG == null) 760 this.isLangWindowShown = function() { 761 return $(this.language_window).is(':hidden'); 762 } 763 764 this.hideLangWindow = function() { 765 $(this.language_window).css('visibility', 'hidden'); 766 $(this.switch_lan_pic).removeClass().addClass('googie_lang_3d_on'); 767 } 768 769 this.deHighlightCurSel = function() { 770 $(this.lang_cur_elm).removeClass().addClass('googie_list_onout'); 771 } 772 773 this.highlightCurSel = function() { 774 if (GOOGIE_CUR_LANG == null) 2326 775 GOOGIE_CUR_LANG = GOOGIE_DEFAULT_LANG; 2327 for (var i=0; i < this.lang_elms.length; i++) {2328 if (this.lang_elms[i].googieId== GOOGIE_CUR_LANG) {776 for (var i=0; i < this.lang_elms.length; i++) { 777 if ($(this.lang_elms[i]).attr('googieId') == GOOGIE_CUR_LANG) { 2329 778 this.lang_elms[i].className = "googie_list_selected"; 2330 779 this.lang_cur_elm = this.lang_elms[i]; … … 2336 785 } 2337 786 2338 GoogieSpell.prototype.showLangWindow = function(elm, ofst_top, ofst_left) {2339 if (this.show_menu_observer)787 this.showLangWindow = function(elm) { 788 if (this.show_menu_observer) 2340 789 this.show_menu_observer(this); 2341 if(!AJS.isDefined(ofst_top))2342 ofst_top = 18; // modified by roundcube2343 if(!AJS.isDefined(ofst_left))2344 ofst_left = 22; // modified by roundcube2345 790 2346 791 this.createLangWindow(); 2347 AJS.getBody().appendChild(this.language_window); 2348 2349 var abs_pos = AJS.absolutePosition(elm); 2350 AJS.showElement(this.language_window); 2351 AJS.setTop(this.language_window, (abs_pos.y+ofst_top)); 2352 AJS.setLeft(this.language_window, (abs_pos.x+ofst_left-this.language_window.offsetWidth)); 792 $('body').append(this.language_window); 793 794 var pos = $(elm).offset(); 795 var top = pos.top + $(elm).height(); 796 var left = this.change_lang_pic_placement == 'right' ? 797 pos.left - 100 + $(elm).width() : pos.left + $(elm).width(); 798 799 $(this.language_window).css({'visibility': 'visible', 'top' : top+'px','left' : left+'px'}); 2353 800 2354 801 this.highlightCurSel(); 2355 this.language_window.style.visibility = "visible"; 2356 } 2357 2358 GoogieSpell.prototype.createChangeLangPic = function() { 2359 var img = AJS.IMG({'src': this.img_dir + 'change_lang.gif', 'alt': "Change language"});2360 img.googie_action_btn = "1"; 2361 var switch_lan = AJS.SPAN({'class': 'googie_lang_3d_on', 'style': 'padding-left: 6px;'}, img);2362 2363 var fn = function(e) { 2364 var elm = AJS.getEventElm(e);2365 if(AJS.nodeName(elm) == 'img')2366 elm = elm.parentNode; 2367 if(elm.className == "googie_lang_3d_click") {2368 elm.className = "googie_lang_3d_on";2369 this.hideLangWindow();2370 }2371 else {2372 elm.className = "googie_lang_3d_click";2373 this.showLangWindow(switch_lan);2374 }2375 }2376 2377 AJS.AEV(switch_lan, "click", AJS.$b(fn, this)); 802 } 803 804 this.createChangeLangPic = function() { 805 var img = $('<img>') 806 .attr({src: this.img_dir + 'change_lang.gif', 'alt': 'Change language', 'googie_action_btn': '1'}); 807 808 var switch_lan = document.createElement('SPAN'); 809 var ref = this; 810 811 $(switch_lan).addClass('googie_lang_3d_on') 812 .append(img) 813 .bind('click', function(e) { 814 var elm = this.tagName == 'IMG' ? this.parentNode : this; 815 if($(elm).hasClass('googie_lang_3d_click')) { 816 elm.className = 'googie_lang_3d_on'; 817 ref.hideLangWindow(); 818 } 819 else { 820 elm.className = 'googie_lang_3d_click'; 821 ref.showLangWindow(elm); 822 } 823 }); 824 2378 825 return switch_lan; 2379 826 } 2380 827 2381 GoogieSpell.prototype.createSpellDiv = function() { 2382 var chk_spell = AJS.SPAN({'class': 'googie_check_spelling_link'}); 2383 2384 chk_spell.innerHTML = this.lang_chck_spell; 2385 var spell_img = null; 2386 if(this.show_spell_img) 2387 spell_img = AJS.IMG({'src': this.img_dir + "spellc.gif"}); 2388 return AJS.SPAN(spell_img, " ", chk_spell); 828 this.createSpellDiv = function() { 829 var span = document.createElement('SPAN'); 830 831 $(span).addClass('googie_check_spelling_link').text(this.lang_chck_spell); 832 833 if (this.show_spell_img) { 834 $(span).append(' ').append($('<img>').attr('src', this.img_dir + 'spellc.gif')); 835 } 836 return span; 2389 837 } 2390 838 … … 2393 841 // State functions 2394 842 ///// 2395 GoogieSpell.prototype.flashNoSpellingErrorState = function(on_finish) { 2396 var no_spell_errors; 2397 2398 if(on_finish) { 2399 var fn = function() { 2400 on_finish(); 2401 this.checkSpellingState(); 2402 }; 2403 no_spell_errors = fn; 2404 } 2405 else 2406 no_spell_errors = this.checkSpellingState; 2407 2408 this.setStateChanged("no_error_found"); 2409 2410 if(this.main_controller) { 2411 AJS.hideElement(this.switch_lan_pic); 2412 2413 var dummy = AJS.IMG({'src': this.img_dir + "blank.gif", 'style': 'height: 16px; width: 1px;'}); 2414 var rsm = AJS.SPAN(); 2415 rsm.innerHTML = this.lang_no_error_found; 2416 2417 AJS.RCN(this.spell_span, AJS.SPAN(dummy, rsm)); 2418 2419 this.spell_span.className = "googie_check_spelling_ok"; 2420 this.spell_span.style.textDecoration = "none"; 2421 this.spell_span.style.cursor = "default"; 2422 2423 AJS.callLater(AJS.$b(no_spell_errors, this), 1200, [false]); 2424 } 2425 } 2426 2427 GoogieSpell.prototype.resumeEditingState = function() { 2428 this.setStateChanged("resume_editing"); 843 this.flashNoSpellingErrorState = function(on_finish) { 844 this.setStateChanged('no_error_found'); 845 846 var ref = this; 847 if (this.main_controller) { 848 var no_spell_errors; 849 if (on_finish) { 850 var fn = function() { 851 on_finish(); 852 ref.checkSpellingState(); 853 }; 854 no_spell_errors = fn; 855 } 856 else 857 no_spell_errors = function () { ref.checkSpellingState() }; 858 859 var rsm = $('<span>').text(this.lang_no_error_found); 860 861 $(this.switch_lan_pic).hide(); 862 $(this.spell_span).empty().append(rsm) 863 .removeClass().addClass('googie_check_spelling_ok'); 864 865 window.setTimeout(no_spell_errors, 1000); 866 } 867 } 868 869 this.resumeEditingState = function() { 870 this.setStateChanged('resume_editing'); 2429 871 2430 872 //Change link text to resume 2431 if(this.main_controller) { 2432 AJS.hideElement(this.switch_lan_pic); 2433 var dummy = AJS.IMG({'src': this.img_dir + "blank.gif", 'style': 'height: 16px; width: 1px;'}); 2434 var rsm = AJS.SPAN(); 2435 rsm.innerHTML = this.lang_rsm_edt; 2436 AJS.RCN(this.spell_span, AJS.SPAN(dummy, rsm)); 2437 2438 var fn = function(e) { 2439 this.resumeEditing(); 2440 } 2441 this.spell_span.onclick = AJS.$b(fn, this); 2442 2443 this.spell_span.className = "googie_resume_editing"; 873 if (this.main_controller) { 874 var rsm = $('<span>').text(this.lang_rsm_edt); 875 var ref = this; 876 877 $(this.switch_lan_pic).hide(); 878 $(this.spell_span).empty().unbind().append(rsm) 879 .bind('click', function() { ref.resumeEditing() }) 880 .removeClass().addClass('googie_resume_editing'); 2444 881 } 2445 882 2446 883 try { this.edit_layer.scrollTop = this.ta_scroll_top; } 2447 catch (e) { }2448 } 2449 2450 GoogieSpell.prototype.checkSpellingState = function(fire) {2451 if (!AJS.isDefined(fire) ||fire)2452 this.setStateChanged( "spell_check");2453 2454 if (this.show_change_lang_pic)884 catch (e) {}; 885 } 886 887 this.checkSpellingState = function(fire) { 888 if (fire) 889 this.setStateChanged('ready'); 890 891 if (this.show_change_lang_pic) 2455 892 this.switch_lan_pic = this.createChangeLangPic(); 2456 893 else 2457 this.switch_lan_pic = AJS.SPAN();894 this.switch_lan_pic = document.createElement('SPAN'); 2458 895 2459 896 var span_chck = this.createSpellDiv(); 2460 var fn = function() { 2461 this.spellCheck(); 2462 }; 2463 2464 if(this.custom_spellcheck_starter) 2465 span_chck.onclick = this.custom_spellcheck_starter; 897 var ref = this; 898 899 if (this.custom_spellcheck_starter) 900 $(span_chck).bind('click', function(e) { ref.custom_spellcheck_starter() }); 2466 901 else { 2467 span_chck.onclick = AJS.$b(fn, this); 902 $(span_chck).bind('click', function(e) { ref.spellCheck() }); 903 } 904 905 if (this.main_controller) { 906 if (this.change_lang_pic_placement == 'left') { 907 $(this.spell_container).empty().append(this.switch_lan_pic).append(' ').append(span_chck); 908 } else { 909 $(this.spell_container).empty().append(span_chck).append(' ').append(this.switch_lan_pic); 910 } 2468 911 } 2469 912 2470 913 this.spell_span = span_chck; 2471 if(this.main_controller) {2472 if(this.change_lang_pic_placement == "left")2473 AJS.RCN(this.spell_container, span_chck, " ", this.switch_lan_pic);2474 else2475 AJS.RCN(this.spell_container, this.switch_lan_pic, " ", span_chck);2476 }2477 // modified by roundcube2478 this.check_link = span_chck;2479 914 } 2480 915 … … 2483 918 // Misc. functions 2484 919 ///// 2485 GoogieSpell.item_onmouseover = function(e) { 2486 var elm = AJS.getEventElm(e); 2487 if(elm.className != "googie_list_revert" && elm.className != "googie_list_close") 2488 elm.className = "googie_list_onhover"; 2489 else 2490 elm.parentNode.className = "googie_list_onhover"; 2491 } 2492 GoogieSpell.item_onmouseout = function(e) { 2493 var elm = AJS.getEventElm(e); 2494 if(elm.className != "googie_list_revert" && elm.className != "googie_list_close") 2495 elm.className = "googie_list_onout"; 2496 else 2497 elm.parentNode.className = "googie_list_onout"; 2498 } 2499 2500 GoogieSpell.prototype.createCloseButton = function(c_fn) { 2501 return this.createButton(this.lang_close, 'googie_list_close', AJS.$b(c_fn, this)); 2502 } 2503 2504 GoogieSpell.prototype.createButton = function(name, css_class, c_fn) { 2505 var btn_row = AJS.TR(); 2506 var btn = AJS.TD(); 2507 2508 btn.onmouseover = GoogieSpell.item_onmouseover; 2509 btn.onmouseout = GoogieSpell.item_onmouseout; 2510 920 this.isDefined = function(o) { 921 return (o != 'undefined' && o != null) 922 } 923 924 this.errorFixed = function() { 925 this.cnt_errors_fixed++; 926 if (this.all_errors_fixed_observer) 927 if (this.cnt_errors_fixed == this.cnt_errors) { 928 this.hideErrorWindow(); 929 this.all_errors_fixed_observer(); 930 } 931 } 932 933 this.errorFound = function() { 934 this.cnt_errors++; 935 } 936 937 this.createCloseButton = function(c_fn) { 938 return this.createButton(this.lang_close, 'googie_list_close', c_fn); 939 } 940 941 this.createButton = function(name, css_class, c_fn) { 942 var btn_row = document.createElement('TR'); 943 var btn = document.createElement('TD'); 2511 944 var spn_btn; 2512 if(css_class != "") { 2513 spn_btn = AJS.SPAN({'class': css_class}); 2514 spn_btn.innerHTML = name; 2515 } 2516 else { 2517 spn_btn = AJS.TN(name); 2518 } 945 946 if (css_class) { 947 spn_btn = document.createElement('SPAN'); 948 $(spn_btn).addClass(css_class).html(name); 949 } else { 950 spn_btn = document.createTextNode(name); 951 } 952 953 $(btn).bind('click', c_fn) 954 .bind('mouseover', this.item_onmouseover) 955 .bind('mouseout', this.item_onmouseout); 956 2519 957 btn.appendChild(spn_btn); 2520 AJS.AEV(btn, "click", c_fn);2521 958 btn_row.appendChild(btn); 2522 959 … … 2524 961 } 2525 962 2526 GoogieSpell.prototype.removeIndicator = function(elm) { 963 this.removeIndicator = function(elm) { 964 //$(this.indicator).remove(); 965 // roundcube mod. 966 if (window.rcmail) 967 rcmail.set_busy(false); 968 } 969 970 this.appendIndicator = function(elm) { 2527 971 // modified by roundcube 2528 972 if (window.rcmail) 2529 rcmail.set_busy(false); 2530 //try { AJS.removeElement(this.indicator); } 2531 //catch(e) {} 2532 } 2533 2534 GoogieSpell.prototype.appendIndicator = function(elm) { 2535 // modified by roundcube 2536 if (window.rcmail) 2537 rcmail.set_busy(true, 'checking'); 2538 /* 2539 var img = AJS.IMG({'src': this.img_dir + 'indicator.gif', 'style': 'margin-right: 5px;'}); 2540 AJS.setWidth(img, 16); 2541 AJS.setHeight(img, 16); 2542 this.indicator = img; 2543 img.style.textDecoration = "none"; 2544 try { 2545 AJS.insertBefore(img, elm); 2546 } 2547 catch(e) {} 2548 */ 2549 } 2550 2551 GoogieSpell.prototype.createFocusLink = function(name) { 2552 return AJS.A({'href': 'javascript:;', name: name}); 2553 } 973 rcmail.set_busy(true, 'checking'); 974 /* 975 this.indicator = document.createElement('IMG'); 976 $(this.indicator).attr('src', this.img_dir + 'indicator.gif') 977 .css({'margin-right': '5px', 'text-decoration': 'none'}).width(16).height(16); 978 979 if (elm) 980 $(this.indicator).insertBefore(elm); 981 else 982 $('body').append(this.indicator); 983 */ 984 } 985 986 this.createFocusLink = function(name) { 987 var link = document.createElement('A'); 988 $(link).attr({'href': 'javascript:;', 'name': name}); 989 return link; 990 } 991 992 this.item_onmouseover = function(e) { 993 if (this.className != "googie_list_revert" && this.className != "googie_list_close") 994 this.className = "googie_list_onhover"; 995 else 996 this.parentNode.className = "googie_list_onhover"; 997 } 998 this.item_onmouseout = function(e) { 999 if (this.className != "googie_list_revert" && this.className != "googie_list_close") 1000 this.className = "googie_list_onout"; 1001 else 1002 this.parentNode.className = "googie_list_onout"; 1003 } 1004 1005 1006 }; -
program/steps/mail/compose.inc
r1fb5874 r309d2f4 434 434 "googie.setLanguages(%s);\n". 435 435 "googie.setCurrentLanguage('%s');\n". 436 "googie.setSpellContainer('spellcheck-control');\n". 436 437 "googie.decorateTextarea('%s');\n". 437 438 "%s.set_env('spellcheck', googie);", … … 835 836 global $CONFIG, $MESSAGE, $compose_mode; 836 837 837 $choices = array(838 'html' => 'htmltoggle',839 'plain' => 'plaintoggle'840 );841 842 838 // determine whether HTML or plain text should be checked 843 839 $useHtml = $CONFIG['htmleditor'] ? true : false; … … 846 842 $useHtml = ($useHtml && $MESSAGE->has_html_part()); 847 843 848 $editorid = empty($attrib['editorid']) ? 'rcmComposeMessage' : $attrib['editorid']; 849 850 $selector = ''; 851 $chosenvalue = $useHtml ? 'html' : 'plain'; 852 $radio = new html_radiobutton(array('name' => '_editorSelect', 853 'onclick' => "return rcmail_toggle_editor(this.value=='html', '$editorid', '_is_html')")); 844 if (empty($attrib['editorid'])) 845 $attrib['editorid'] = 'rcmComposeMessage'; 846 847 if (empty($attrib['name'])) 848 $attrib['name'] = 'editorSelect'; 849 850 $attrib['onchange'] = "return rcmail_toggle_editor(this.value=='html', '".$attrib['editorid']."', '_is_html')"; 851 852 $select = new html_select($attrib); 853 854 $select->add(Q(rcube_label('htmltoggle')), 'html'); 855 $select->add(Q(rcube_label('plaintoggle')), 'plain'); 856 857 return $select->show($useHtml ? 'html' : 'plain'); 854 858 855 859 foreach ($choices as $value => $text) -
skins/default/common.css
rf055b12 r309d2f4 287 287 } 288 288 289 .radios-left label290 {291 padding-left: 0.3em;292 }293 294 289 /***** common table settings ******/ 295 290 -
skins/default/googiespell.css
rffa6c10 r309d2f4 11 11 position: absolute; 12 12 visibility: hidden; 13 } 14 15 .googie_edit_layer { 16 border: 1px solid #666666; 17 background-color: #ffffff; 18 padding: 1px 4px; 19 margin: 1px 0px; 20 font-size: 9pt; 21 font-family: "Courier New", Courier, monospace; 22 } 23 24 .googie_edit_layer span { 25 font-size: 9pt; 26 font-family: "Courier New", Courier, monospace; 13 27 } 14 28 … … 63 77 } 64 78 65 .googie_resume_editing, 66 .googie_check_spelling_link { 79 .googie_check_spelling_link { 67 80 color: #CC0000; 68 81 font-size: 11px; … … 71 84 } 72 85 73 .googie_resume_editing:hover,74 86 .googie_check_spelling_link:hover { 75 87 text-decoration: underline; 76 }77 78 .googie_resume_editing {79 color: green;80 88 } 81 89 … … 84 92 } 85 93 86 .googie_check_spelling_ok { 94 .googie_check_spelling_ok, 95 .googie_resume_editing { 87 96 color: green; 88 97 font-size: 11px; 98 cursor: pointer; 99 } 100 101 .googie_check_spelling_ok:hover, 102 .googie_resume_editing:hover { 89 103 text-decoration: underline; 90 cursor: pointer;91 104 } 92 105 -
skins/default/mail.css
r1fb5874 r309d2f4 20 20 } 21 21 22 #messagetoolbar select 22 #messagetoolbar select, 23 #compose-container select 23 24 { 24 25 font-family: "Lucida Grande", Verdana, Arial, Helvetica, sans-serif; 25 26 font-size: 11px; 26 27 color: #333333; 28 height: 21px; 27 29 } 28 30 … … 914 916 { 915 917 padding-left: 30px; 918 white-space: nowrap; 916 919 } 917 920 … … 929 932 } 930 933 934 #spellcheck-control 935 { 936 text-align: right; 937 padding-top: 3px; 938 } 939 940 #editor-select 941 { 942 float: left; 943 } 944 931 945 #compose-div 932 946 { 933 947 position: absolute; 934 top: 1 10px;935 bottom: 40px;948 top: 130px; 949 bottom: 30px; 936 950 width: 100%; 937 951 vertical-align: top; 952 padding-top: 2px; 938 953 } 939 954 -
skins/default/templates/compose.html
r1a76227 r309d2f4 67 67 <td class="title"><label for="compose-subject"><roundcube:label name="subject" /></label></td> 68 68 <td><roundcube:object name="composeSubject" id="compose-subject" form="form" tabindex="6" /></td> 69 </tr><tr> 70 <td class="title"><roundcube:label name="editortype" /></td> 71 <td> 72 <div id="editor-select"><roundcube:object name="editorSelector" editorid="compose-body" tabindex="7" /></div> 73 <div id="spellcheck-control"></div> 74 </td> 69 75 </tr> 70 76 </tbody> … … 72 78 </div> 73 79 <div id="compose-div"> 74 <roundcube:object name="composeBody" id="compose-body" form="form" cols="70" rows="20" tabindex=" 7" />80 <roundcube:object name="composeBody" id="compose-body" form="form" cols="70" rows="20" tabindex="8" /> 75 81 <table border="0" cellspacing="0" summary="" style="width:100%; margin-top: 5px;"><tbody> 76 82 <tr> … … 79 85 <roundcube:button type="input" command="list" class="button" label="cancel" tabindex="9" /> 80 86 </td> 81 <td style="text-align:center; white-space: nowrap"> 82 <label><roundcube:label name="savesentmessagein" />: <roundcube:object name="storetarget" maxlength="30" /></label> 83 </td> 84 <td style="text-align:right; white-space:nowrap"> 85 <roundcube:label name="editortype" />: 86 <span class="radios-left"><roundcube:object name="editorSelector" editorid="compose-body" tabindex="10" /></span> 87 <td style="text-align:right; white-space: nowrap"> 88 <label><roundcube:label name="savesentmessagein" />: <roundcube:object name="storetarget" maxlength="30" tabindex="10" /></label> 87 89 </td> 88 90 </tr>
Note: See TracChangeset
for help on using the changeset viewer.
