X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=program%2Fjs%2Fgoogiespell.js;h=8b9d1cc716cb33b5c653cbfccb0b7e235dc044ec;hb=1213c6e65f2bab1e140369839a9d0f6db28a9492;hp=eb103e7acef938d3753c7a3b40b8b52874d8fc96;hpb=3adad46e27086084a8b28a32fc4fbc953dbfef6c;p=roundcube.git diff --git a/program/js/googiespell.js b/program/js/googiespell.js index eb103e7..8b9d1cc 100644 --- a/program/js/googiespell.js +++ b/program/js/googiespell.js @@ -1,983 +1,1308 @@ -var AJS={getElement:function(id){ -if(typeof (id)=="string"){ -return document.getElementById(id); -}else{ -return id; -} -},getElements:function(){ -var _2=new Array(); -for(var i=0;i=2){ -for(var i=1;i= 2) { + for(var i=1; i < arguments.length; i++) { + var n = arguments[i]; + if(typeof(n) == "string") + n = document.createTextNode(n); + if(this.isDefined(n)) + node.appendChild(n); + } + } + return node; + }, + + /** + * Replaces a nodes children with another node(s) + */ + replaceChildNodes: function(node/*, nodes...*/) { + var child; + while ((child = node.firstChild)) { + node.removeChild(child); + } + if (arguments.length < 2) { + return node; + } else { + return this.appendChildNodes.apply(this, arguments); + } + }, + + /** + * Insert a node after another node + */ + insertAfter: function(node, referenceNode) { + referenceNode.parentNode.insertBefore(node, referenceNode.nextSibling); + }, + + /** + * Insert a node before another node + */ + insertBefore: function(node, referenceNode) { + referenceNode.parentNode.insertBefore(node, referenceNode); + }, + + /** + * Shows the element + */ + showElement: function(elm) { + elm.style.display = ''; + }, + + /** + * Hides the element + */ + hideElement: function(elm) { + elm.style.display = 'none'; + }, + + isElementHidden: function(elm) { + return elm.style.visibility == "hidden"; + }, + + /** + * Swaps one element with another. To delete use swapDOM(elm, null) + */ + swapDOM: function(dest, src) { + dest = this.getElement(dest); + var parent = dest.parentNode; + if (src) { + src = this.getElement(src); + parent.replaceChild(src, dest); + } else { + parent.removeChild(dest); + } + return src; + }, + + /** + * Removes an element from the world + */ + removeElement: function(elm) { + this.swapDOM(elm, null); + }, + + /** + * @returns Is an object a dictionary? + */ + isDict: function(o) { + var str_repr = String(o); + return str_repr.indexOf(" Object") != -1; + }, + + /** + * Creates a DOM element + * @param {String} name The elements DOM name + * @param {Dict} attrs Attributes sent to the function + */ + createDOM: function(name, attrs) { + var i=0; + elm = document.createElement(name); + + if(this.isDict(attrs[i])) { + for(k in attrs[0]) { + if(k == "style") + elm.style.cssText = attrs[0][k]; + else if(k == "class") + elm.className = attrs[0][k]; + else + elm.setAttribute(k, attrs[0][k]); + } + i++; + } + + if(attrs[0] == null) + i = 1; + + for(i; i < attrs.length; i++) { + var n = attrs[i]; + if(this.isDefined(n)) { + if(typeof(n) == "string") + n = document.createTextNode(n); + elm.appendChild(n); + } + } + return elm; + }, + + UL: function() { return this.createDOM.apply(this, ["ul", arguments]); }, + LI: function() { return this.createDOM.apply(this, ["li", arguments]); }, + TD: function() { return this.createDOM.apply(this, ["td", arguments]); }, + TR: function() { return this.createDOM.apply(this, ["tr", arguments]); }, + TH: function() { return this.createDOM.apply(this, ["th", arguments]); }, + TBODY: function() { return this.createDOM.apply(this, ["tbody", arguments]); }, + TABLE: function() { return this.createDOM.apply(this, ["table", arguments]); }, + INPUT: function() { return this.createDOM.apply(this, ["input", arguments]); }, + SPAN: function() { return this.createDOM.apply(this, ["span", arguments]); }, + B: function() { return this.createDOM.apply(this, ["b", arguments]); }, + A: function() { return this.createDOM.apply(this, ["a", arguments]); }, + DIV: function() { return this.createDOM.apply(this, ["div", arguments]); }, + IMG: function() { return this.createDOM.apply(this, ["img", arguments]); }, + BUTTON: function() { return this.createDOM.apply(this, ["button", arguments]); }, + H1: function() { return this.createDOM.apply(this, ["h1", arguments]); }, + H2: function() { return this.createDOM.apply(this, ["h2", arguments]); }, + H3: function() { return this.createDOM.apply(this, ["h3", arguments]); }, + BR: function() { return this.createDOM.apply(this, ["br", arguments]); }, + TEXTAREA: function() { return this.createDOM.apply(this, ["textarea", arguments]); }, + FORM: function() { return this.createDOM.apply(this, ["form", arguments]); }, + P: function() { return this.createDOM.apply(this, ["p", arguments]); }, + SELECT: function() { return this.createDOM.apply(this, ["select", arguments]); }, + OPTION: function() { return this.createDOM.apply(this, ["option", arguments]); }, + TN: function(text) { return document.createTextNode(text); }, + IFRAME: function() { return this.createDOM.apply(this, ["iframe", arguments]); }, + SCRIPT: function() { return this.createDOM.apply(this, ["script", arguments]); }, + +//// +// Ajax functions +//// + /** + * @returns A new XMLHttpRequest object + */ + getXMLHttpRequest: function() { + var try_these = [ + function () { return new XMLHttpRequest(); }, + function () { return new ActiveXObject('Msxml2.XMLHTTP'); }, + function () { return new ActiveXObject('Microsoft.XMLHTTP'); }, + function () { return new ActiveXObject('Msxml2.XMLHTTP.4.0'); }, + function () { throw "Browser does not support XMLHttpRequest"; } + ]; + for (var i = 0; i < try_these.length; i++) { + var func = try_these[i]; + try { + return func(); + } catch (e) { + } + } + }, + + /** + * Use this function to do a simple HTTP Request + */ + doSimpleXMLHttpRequest: function(url) { + var req = this.getXMLHttpRequest(); + req.open("GET", url, true); + return this.sendXMLHttpRequest(req); + }, + + getRequest: function(url, data) { + var req = this.getXMLHttpRequest(); + req.open("POST", url, true); + req.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); + return this.sendXMLHttpRequest(req); + }, + + /** + * Send a XMLHttpRequest + */ + sendXMLHttpRequest: function(req, data) { + var d = new AJSDeferred(req); + + var onreadystatechange = function () { + if (req.readyState == 4) { + try { + var status = req.status; + } + catch(e) {}; + if(status == 200 || status == 304 || req.responseText == null) { + d.callback(req, data); + } + else { + d.errback(); + } + } + } + req.onreadystatechange = onreadystatechange; + return d; + }, + + /** + * Represent an object as a string + */ + reprString: function(o) { + return ('"' + o.replace(/(["\\])/g, '\\$1') + '"' + ).replace(/[\f]/g, "\\f" + ).replace(/[\b]/g, "\\b" + ).replace(/[\n]/g, "\\n" + ).replace(/[\t]/g, "\\t" + ).replace(/[\r]/g, "\\r"); + }, + + /** + * Serialize an object to JSON notation + */ + serializeJSON: function(o) { + var objtype = typeof(o); + if (objtype == "undefined") { + return "undefined"; + } else if (objtype == "number" || objtype == "boolean") { + return o + ""; + } else if (o === null) { + return "null"; + } + if (objtype == "string") { + return this.reprString(o); + } + var me = arguments.callee; + var newObj; + if (typeof(o.__json__) == "function") { + newObj = o.__json__(); + if (o !== newObj) { + return me(newObj); + } + } + if (typeof(o.json) == "function") { + newObj = o.json(); + if (o !== newObj) { + return me(newObj); + } + } + if (objtype != "function" && typeof(o.length) == "number") { + var res = []; + for (var i = 0; i < o.length; i++) { + var val = me(o[i]); + if (typeof(val) != "string") { + val = "undefined"; + } + res.push(val); + } + return "[" + res.join(",") + "]"; + } + res = []; + for (var k in o) { + var useKey; + if (typeof(k) == "number") { + useKey = '"' + k + '"'; + } else if (typeof(k) == "string") { + useKey = this.reprString(k); + } else { + // skip non-string or number keys + continue; + } + val = me(o[k]); + if (typeof(val) != "string") { + // skip non-serializable values + continue; + } + res.push(useKey + ":" + val); + } + return "{" + res.join(",") + "}"; + }, + + /** + * Send and recive JSON using GET + */ + loadJSONDoc: function(url) { + var d = this.getRequest(url); + var eval_req = function(req) { + var text = req.responseText; + return eval('(' + text + ')'); + }; + d.addCallback(eval_req); + return d; + }, + + +//// +// Misc. +//// + /** + * Alert the objects key attrs + */ + keys: function(obj) { + var rval = []; + for (var prop in obj) { + rval.push(prop); + } + return rval; + }, + + urlencode: function(str) { + return encodeURIComponent(str.toString()); + }, + + /** + * @returns True if the object is defined, otherwise false + */ + isDefined: function(o) { + return (o != "undefined" && o != null) + }, + + /** + * @returns True if an object is a array, false otherwise + */ + isArray: function(obj) { + try { return (typeof(obj.length) == "undefined") ? false : true; } + catch(e) + { return false; } + }, + + isObject: function(obj) { + return (obj && typeof obj == 'object'); + }, + + /** + * Export DOM elements to the global namespace + */ + exportDOMElements: function() { + UL = this.UL; + LI = this.LI; + TD = this.TD; + TR = this.TR; + TH = this.TH; + TBODY = this.TBODY; + TABLE = this.TABLE; + INPUT = this.INPUT; + SPAN = this.SPAN; + B = this.B; + A = this.A; + DIV = this.DIV; + IMG = this.IMG; + BUTTON = this.BUTTON; + H1 = this.H1; + H2 = this.H2; + H3 = this.H3; + BR = this.BR; + TEXTAREA = this.TEXTAREA; + FORM = this.FORM; + P = this.P; + SELECT = this.SELECT; + OPTION = this.OPTION; + TN = this.TN; + IFRAME = this.IFRAME; + SCRIPT = this.SCRIPT; + }, + + /** + * Export AmiJS functions to the global namespace + */ + exportToGlobalScope: function() { + getElement = this.getElement; + getQueryArgument = this.getQueryArgument; + isIe = this.isIe; + $ = this.getElement; + getElements = this.getElements; + getBody = this.getBody; + getElementsByTagAndClassName = this.getElementsByTagAndClassName; + appendChildNodes = this.appendChildNodes; + ACN = appendChildNodes; + replaceChildNodes = this.replaceChildNodes; + RCN = replaceChildNodes; + insertAfter = this.insertAfter; + insertBefore = this.insertBefore; + showElement = this.showElement; + hideElement = this.hideElement; + isElementHidden = this.isElementHidden; + swapDOM = this.swapDOM; + removeElement = this.removeElement; + isDict = this.isDict; + createDOM = this.createDOM; + this.exportDOMElements(); + getXMLHttpRequest = this.getXMLHttpRequest; + doSimpleXMLHttpRequest = this.doSimpleXMLHttpRequest; + getRequest = this.getRequest; + sendXMLHttpRequest = this.sendXMLHttpRequest; + reprString = this.reprString; + serializeJSON = this.serializeJSON; + loadJSONDoc = this.loadJSONDoc; + keys = this.keys; + isDefined = this.isDefined; + isArray = this.isArray; + } } + + + +AJSDeferred = function(req) { + this.callbacks = []; + this.req = req; + + this.callback = function (res) { + while (this.callbacks.length > 0) { + var fn = this.callbacks.pop(); + res = fn(res); + } + }; + + this.errback = function(e){ + alert("Error encountered:\n" + e); + }; + + this.addErrback = function(fn) { + this.errback = fn; + }; + + this.addCallback = function(fn) { + this.callbacks.unshift(fn); + }; + + this.addCallbacks = function(fn1, fn2) { + this.addCallback(fn1); + this.addErrback(fn2); + }; + + this.sendReq = function(data) { + if(AJS.isObject(data)) { + var post_data = []; + for(k in data) { + post_data.push(k + "=" + AJS.urlencode(data[k])); + } + post_data = post_data.join("&"); + this.req.send(post_data); + } + else if(AJS.isDefined(data)) + this.req.send(data); + else { + this.req.send(""); + } + }; }; -req.onreadystatechange=_33; -return d; -},reprString:function(o){ -return ("\""+o.replace(/(["\\])/g,"\\$1")+"\"").replace(/[\f]/g,"\\f").replace(/[\b]/g,"\\b").replace(/[\n]/g,"\\n").replace(/[\t]/g,"\\t").replace(/[\r]/g,"\\r"); -},serializeJSON:function(o){ -var _37=typeof (o); -if(_37=="undefined"){ -return "undefined"; -}else{ -if(_37=="number"||_37=="boolean"){ -return o+""; -}else{ -if(o===null){ -return "null"; -} -} -} -if(_37=="string"){ -return this.reprString(o); -} -var me=arguments.callee; -var _39; -if(typeof (o.__json__)=="function"){ -_39=o.__json__(); -if(o!==_39){ -return me(_39); -} -} -if(typeof (o.json)=="function"){ -_39=o.json(); -if(o!==_39){ -return me(_39); -} -} -if(_37!="function"&&typeof (o.length)=="number"){ -var res=[]; -for(var i=0;i0){ -var fn=this.callbacks.pop(); -res=fn(res); +AJSDeferred.prototype = new AJSDeferred(); + + + + + + +/**** +Last Modified: 28/04/06 15:26:06 + + GoogieSpell + Google spell checker for your own web-apps :) + Copyright Amir Salihefendic 2006 + LICENSE + GPL (see gpl.txt for more information) + This basically means that you can't use this script with/in proprietary software! + There is another license that permits you to use this script with proprietary software. Check out:... for more info. + AUTHOR + 4mir Salihefendic (http://amix.dk) - amix@amix.dk + VERSION + 3.22 +****/ +var GOOGIE_CUR_LANG = "en"; + +function GoogieSpell(img_dir, server_url) { + var cookie_value; + var lang; + cookie_value = getCookie('language'); + + if(cookie_value != null) + GOOGIE_CUR_LANG = cookie_value; + + this.img_dir = img_dir; + this.server_url = server_url; + + this.lang_to_word = {"da": "Dansk", "de": "Deutsch", "en": "English", + "es": "Español", "fr": "Français", "it": "Italiano", + "nl": "Nederlands", "pl": "Polski", "pt": "Português", + "fi": "Suomi", "sv": "Svenska"}; + this.langlist_codes = AJS.keys(this.lang_to_word); + + this.show_change_lang_pic = true; + + this.lang_state_observer = null; + + this.spelling_state_observer = null; + + this.request = null; + this.error_window = null; + this.language_window = null; + this.edit_layer = null; + this.orginal_text = null; + this.results = null; + this.text_area = null; + this.gselm = null; + this.ta_scroll_top = 0; + this.el_scroll_top = 0; + + this.lang_chck_spell = "Check spelling"; + this.lang_rsm_edt = "Resume editing"; + this.lang_close = "Close"; + this.lang_no_error_found = "No spelling errors found"; + this.lang_revert = "Revert to"; + this.show_spell_img = false; // modified by roundcube } -}; -this.errback=function(e){ -alert("Error encountered:\n"+e); -}; -this.addErrback=function(fn){ -this.errback=fn; -}; -this.addCallback=function(fn){ -this.callbacks.unshift(fn); -}; -this.addCallbacks=function(fn1,fn2){ -this.addCallback(fn1); -this.addErrback(fn2); -}; -this.sendReq=function(_53){ -if(AJS.isObject(_53)){ -var _54=[]; -for(k in _53){ -_54.push(k+"="+AJS.urlencode(_53[k])); + +GoogieSpell.prototype.setStateChanged = function(current_state) { + if(this.spelling_state_observer != null) + this.spelling_state_observer(current_state); } -_54=_54.join("&"); -this.req.send(_54); -}else{ -if(AJS.isDefined(_53)){ -this.req.send(_53); -}else{ -this.req.send(""); + +GoogieSpell.item_onmouseover = function(e) { + var elm = GoogieSpell.getEventElm(e); + if(elm.className != "googie_list_close" && elm.className != "googie_list_revert") + elm.className = "googie_list_onhover"; + else + elm.parentNode.className = "googie_list_onhover"; } + +GoogieSpell.item_onmouseout = function(e) { + var elm = GoogieSpell.getEventElm(e); + if(elm.className != "googie_list_close" && elm.className != "googie_list_revert") + elm.className = "googie_list_onout"; + else + elm.parentNode.className = "googie_list_onout"; } -}; -}; -AJSDeferred.prototype=new AJSDeferred(); -var GOOGIE_CUR_LANG="en"; -function GoogieSpell(_55,_56){ -var _57; -var _58; -_57=getCookie("language"); -if(_57!=null){ -GOOGIE_CUR_LANG=_57; -} -this.img_dir=_55; -this.server_url=_56; -this.lang_to_word={"da":"Dansk","de":"Deutsch","en":"English","es":"Español","fr":"Français","it":"Italiano","nl":"Nederlands","pl":"Polski","pt":"Português","fi":"Suomi","sv":"Svenska"}; -this.langlist_codes=AJS.keys(this.lang_to_word); -this.show_change_lang_pic=true; -this.lang_state_observer=null; -this.spelling_state_observer=null; -this.request=null; -this.error_window=null; -this.language_window=null; -this.edit_layer=null; -this.orginal_text=null; -this.results=null; -this.text_area=null; -this.gselm=null; -this.ta_scroll_top=0; -this.el_scroll_top=0; -this.lang_chck_spell="Check spelling"; -this.lang_rsm_edt="Resume editing"; -this.lang_close="Close"; -this.lang_no_error_found="No spelling errors found"; -this.lang_revert="Revert to"; -this.show_spell_img=false; -}; -GoogieSpell.prototype.setStateChanged=function(_59){ -if(this.spelling_state_observer!=null){ -this.spelling_state_observer(_59); + +GoogieSpell.prototype.getGoogleUrl = function() { + return this.server_url + GOOGIE_CUR_LANG; } -}; -GoogieSpell.item_onmouseover=function(e){ -var elm=GoogieSpell.getEventElm(e); -if(elm.className!="googie_list_close"&&elm.className!="googie_list_revert"){ -elm.className="googie_list_onhover"; -}else{ -elm.parentNode.className="googie_list_onhover"; + +GoogieSpell.prototype.spellCheck = function(elm, name) { + this.ta_scroll_top = this.text_area.scrollTop; + + this.appendIndicator(elm); + + try { + this.hideLangWindow(); + } + catch(e) {} + + this.gselm = elm; + + this.createEditLayer(this.text_area.offsetWidth, this.text_area.offsetHeight); + + this.createErrorWindow(); + AJS.getBody().appendChild(this.error_window); + + try { netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserRead"); } + catch (e) { } + + this.gselm.onclick = null; + + this.orginal_text = this.text_area.value; + var me = this; + + //Create request + var d = AJS.getRequest(this.getGoogleUrl()); + var reqdone = function(req) { + var r_text = req.responseText; + if(r_text.match(//) != null) { + var results = GoogieSpell.parseResult(r_text); + //Before parsing be sure that errors were found + me.results = results; + me.showErrorsInIframe(results); + me.resumeEditingState(); + } + else { + me.flashNoSpellingErrorState(); + } + me.removeIndicator(); + }; + + var reqfailed = function(req) { + alert("An error was encountered on the server. Please try again later."); + AJS.removeElement(me.gselm); + me.checkSpellingState(); + me.removeIndicator(); + }; + + d.addCallback(reqdone); + d.addErrback(reqfailed); + + var req_text = GoogieSpell.escapeSepcial(this.orginal_text); + d.sendReq(GoogieSpell.createXMLReq(req_text)); } -}; -GoogieSpell.item_onmouseout=function(e){ -var elm=GoogieSpell.getEventElm(e); -if(elm.className!="googie_list_close"&&elm.className!="googie_list_revert"){ -elm.className="googie_list_onout"; -}else{ -elm.parentNode.className="googie_list_onout"; + +GoogieSpell.escapeSepcial = function(val) { + return val.replace(/&/g, "&").replace(//g, ">"); } -}; -GoogieSpell.prototype.getGoogleUrl=function(){ -return this.server_url+GOOGIE_CUR_LANG; -}; -GoogieSpell.prototype.spellCheck=function(elm,_5f){ -this.ta_scroll_top=this.text_area.scrollTop; -this.appendIndicator(elm); -try{ -this.hideLangWindow(); -} -catch(e){ -} -this.gselm=elm; -this.createEditLayer(this.text_area.offsetWidth,this.text_area.offsetHeight); -this.createErrorWindow(); -AJS.getBody().appendChild(this.error_window); -try{ -netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserRead"); -} -catch(e){ -} -this.gselm.onclick=null; -this.orginal_text=this.text_area.value; -var me=this; -var d=AJS.getRequest(this.getGoogleUrl()); -var _62=function(req){ -var _64=req.responseText; -if(_64.match(//)!=null){ -var _65=GoogieSpell.parseResult(_64); -me.results=_65; -me.showErrorsInIframe(_65); -me.resumeEditingState(); -}else{ -me.flashNoSpellingErrorState(); -} -me.removeIndicator(); -}; -var _66=function(req){ -alert("An error was encountered on the server. Please try again later."); -AJS.removeElement(me.gselm); -me.checkSpellingState(); -me.removeIndicator(); -}; -d.addCallback(_62); -d.addErrback(_66); -var _68=GoogieSpell.escapeSepcial(this.orginal_text); -d.sendReq(GoogieSpell.createXMLReq(_68)); -}; -GoogieSpell.escapeSepcial=function(val){ -return val.replace(/&/g,"&").replace(//g,">"); -}; -GoogieSpell.createXMLReq=function(_6a){ -return ""+_6a+""; -}; -GoogieSpell.parseResult=function(_6b){ -var _6c=/\w="\d+"/g; -var _6d=/\t/g; -var _6e=_6b.match(/]*>[^<]*<\/c>/g); -var _6f=new Array(); -for(var i=0;i<_6e.length;i++){ -var _71=new Array(); -_71["attrs"]=new Array(); -var _72=_6e[i].match(_6c); -for(var j=0;j<_72.length;j++){ -var _74=_72[j].split(/=/); -_71["attrs"][_74[0]]=parseInt(_74[1].replace("\"","")); -} -_71["suggestions"]=new Array(); -var _75=_6e[i].replace(/<[^>]*>/g,""); -var _76=_75.split(_6d); -for(var k=0;k<_76.length;k++){ -if(_76[k]!=""){ -_71["suggestions"].push(_76[k]); -} -} -_6f.push(_71); -} -return _6f; -}; -GoogieSpell.prototype.createErrorWindow=function(){ -this.error_window=AJS.DIV(); -this.error_window.className="googie_window"; -}; -GoogieSpell.prototype.hideErrorWindow=function(){ -this.error_window.style.visibility="hidden"; -}; -GoogieSpell.prototype.updateOrginalText=function(_78,_79,_7a,id){ -var _7c=this.orginal_text.substring(0,_78); -var _7d=this.orginal_text.substring(_78+_79.length); -this.orginal_text=_7c+_7a+_7d; -var _7e=_7a.length-_79.length; -for(var j=0;jid){ -this.results[j]["attrs"]["o"]+=_7e; + +GoogieSpell.createXMLReq = function (text) { + return '' + text + ''; } + +//Retunrs an array +//result[item] -> ['attrs'] +// ['suggestions'] +GoogieSpell.parseResult = function(r_text) { + var re_split_attr_c = /\w="\d+"/g; + var re_split_text = /\t/g; + + var matched_c = r_text.match(/]*>[^<]*<\/c>/g); + var results = new Array(); + + for(var i=0; i < matched_c.length; i++) { + var item = new Array(); + + //Get attributes + item['attrs'] = new Array(); + var split_c = matched_c[i].match(re_split_attr_c); + for(var j=0; j < split_c.length; j++) { + var c_attr = split_c[j].split(/=/); + item['attrs'][c_attr[0]] = parseInt(c_attr[1].replace('"', '')); + } + + //Get suggestions + item['suggestions'] = new Array(); + var only_text = matched_c[i].replace(/<[^>]*>/g, ""); + var split_t = only_text.split(re_split_text); + for(var k=0; k < split_t.length; k++) { + if(split_t[k] != "") + item['suggestions'].push(split_t[k]); + } + results.push(item); + } + return results; } -}; -GoogieSpell.prototype.saveOldValue=function(id,_81){ -this.results[id]["is_changed"]=true; -this.results[id]["old_value"]=_81; -}; -GoogieSpell.prototype.showErrorWindow=function(elm,id){ -var me=this; -var _85=GoogieSpell.absolutePosition(elm); -_85.y-=this.edit_layer.scrollTop; -this.error_window.style.visibility="visible"; -this.error_window.style.top=(_85.y+20)+"px"; -this.error_window.style.left=(_85.x)+"px"; -this.error_window.innerHTML=""; -var _86=AJS.TABLE({"class":"googie_list"}); -var _87=AJS.TBODY(); -var _88=this.results[id]["suggestions"]; -var _89=this.results[id]["attrs"]["o"]; -var len=this.results[id]["attrs"]["l"]; -if(_88.length==0){ -var row=AJS.TR(); -var _8c=AJS.TD(); -var _8d=AJS.SPAN(); -_8c.appendChild(AJS.TN("No suggestions :(")); -row.appendChild(_8c); -_87.appendChild(row); -} -for(i=0;i<_88.length;i++){ -var row=AJS.TR(); -var _8c=AJS.TD(); -var _8d=AJS.SPAN(); -_8d.innerHTML=_88[i]; -_8c.appendChild(AJS.TN(_8d.innerHTML)); -_8c.onclick=function(e){ -var _8f=GoogieSpell.getEventElm(e); -var _90=elm.innerHTML; -var _91=_8f.innerHTML; -elm.style.color="green"; -elm.innerHTML=_8f.innerHTML; -me.hideErrorWindow(); -me.updateOrginalText(_89,_90,_91,id); -me.results[id]["attrs"]["l"]=_91.length; -me.saveOldValue(id,_90); -}; -_8c.onmouseover=GoogieSpell.item_onmouseover; -_8c.onmouseout=GoogieSpell.item_onmouseout; -row.appendChild(_8c); -_87.appendChild(row); -} -if(this.results[id]["is_changed"]){ -var _92=this.results[id]["old_value"]; -var _89=this.results[id]["attrs"]["o"]; -var _93=AJS.TR(); -var _94=AJS.TD(); -_94.onmouseover=GoogieSpell.item_onmouseover; -_94.onmouseout=GoogieSpell.item_onmouseout; -var _95=AJS.SPAN({"class":"googie_list_revert"}); -_95.innerHTML=this.lang_revert+" "+_92; -_94.appendChild(_95); -_94.onclick=function(e){ -me.updateOrginalText(_89,elm.innerHTML,_92,id); -elm.style.color="#b91414"; -elm.innerHTML=_92; -me.hideErrorWindow(); -}; -_93.appendChild(_94); -_87.appendChild(_93); -} -var _97=AJS.TR(); -var _98=AJS.TD(); -var _99=AJS.INPUT({"style":"width: 120px; margin:0; padding:0"}); -var _9a=function(){ -if(_99.value!=""){ -me.saveOldValue(id,elm.innerHTML); -me.updateOrginalText(_89,elm.innerHTML,_99.value,id); -elm.style.color="green"; -elm.innerHTML=_99.value; -me.hideErrorWindow(); -return false; + +/**** + Error window (the drop-down window) +****/ +GoogieSpell.prototype.createErrorWindow = function() { + this.error_window = AJS.DIV(); + this.error_window.className = "googie_window"; } -}; -var _9b=AJS.IMG({"src":this.img_dir+"ok.gif","style":"width: 32px; height: 16px; margin-left: 2px; margin-right: 2px;"}); -var _9c=AJS.FORM({"style":"margin: 0; padding: 0"},_99,_9b); -_9b.onclick=_9a; -_9c.onsubmit=_9a; -_98.appendChild(_9c); -_97.appendChild(_98); -_87.appendChild(_97); -var _9d=AJS.TR(); -var _9e=AJS.TD(); -_9e.onmouseover=GoogieSpell.item_onmouseover; -_9e.onmouseout=GoogieSpell.item_onmouseout; -var _9f=AJS.SPAN({"class":"googie_list_close"}); -_9f.innerHTML=this.lang_close; -_9e.appendChild(_9f); -_9e.onclick=function(){ -me.hideErrorWindow(); -}; -_9d.appendChild(_9e); -_87.appendChild(_9d); -_86.appendChild(_87); -this.error_window.appendChild(_86); -}; -GoogieSpell.prototype.createEditLayer=function(_a0,_a1){ -this.edit_layer=AJS.DIV({"class":"googie_edit_layer"}); -this.edit_layer.className=this.text_area.className; -this.edit_layer.style.border="1px solid #999"; -this.edit_layer.style.overflow="auto"; -this.edit_layer.style.backgroundColor="#F1EDFE"; -this.edit_layer.style.padding="3px"; -this.edit_layer.style.width=(_a0-8)+"px"; -this.edit_layer.style.height=_a1+"px"; -}; -GoogieSpell.prototype.resumeEditing=function(e,me){ -this.setStateChanged("check_spelling"); -me.switch_lan_pic.style.display="inline"; -this.el_scroll_top=me.edit_layer.scrollTop; -var elm=GoogieSpell.getEventElm(e); -AJS.replaceChildNodes(elm,this.createSpellDiv()); -elm.onclick=function(e){ -me.spellCheck(elm,me.text_area.id); -}; -me.hideErrorWindow(); -me.edit_layer.parentNode.removeChild(me.edit_layer); -me.text_area.value=me.orginal_text; -AJS.showElement(me.text_area); -me.gselm.className="googie_no_style"; -me.text_area.scrollTop=this.el_scroll_top; -elm.onmouseout=null; -}; -GoogieSpell.prototype.createErrorLink=function(_a6,id){ -var elm=AJS.SPAN({"class":"googie_link"}); -var me=this; -elm.onclick=function(){ -me.showErrorWindow(elm,id); -}; -elm.innerHTML=_a6; -return elm; -}; -GoogieSpell.createPart=function(_aa){ -if(_aa==" "){ -return AJS.TN(" "); -} -var _ab=AJS.SPAN(); -var _ac=true; -var _ad=(navigator.userAgent.toLowerCase().indexOf("safari")!=-1); -var _ae=AJS.SPAN(); -_aa=GoogieSpell.escapeSepcial(_aa); -_aa=_aa.replace(/\n/g,"
"); -_aa=_aa.replace(/ /g,"  "); -_aa=_aa.replace(/^ /g," "); -_aa=_aa.replace(/ $/g," "); -_ae.innerHTML=_aa; -return _ae; -}; -GoogieSpell.prototype.showErrorsInIframe=function(_af){ -var _b0=AJS.DIV(); -_b0.style.textAlign="left"; -var _b1=0; -for(var i=0;i<_af.length;i++){ -var _b3=_af[i]["attrs"]["o"]; -var len=_af[i]["attrs"]["l"]; -var _b5=this.orginal_text.substring(_b1,_b3); -var _b6=GoogieSpell.createPart(_b5); -_b0.appendChild(_b6); -_b1+=_b3-_b1; -_b0.appendChild(this.createErrorLink(this.orginal_text.substr(_b3,len),i)); -_b1+=len; -} -var _b7=this.orginal_text.substr(_b1,this.orginal_text.length); -var _b8=GoogieSpell.createPart(_b7); -_b0.appendChild(_b8); -this.edit_layer.appendChild(_b0); -AJS.hideElement(this.text_area); -this.text_area.parentNode.insertBefore(this.edit_layer,this.text_area.nextSibling); -this.edit_layer.scrollTop=this.ta_scroll_top; -}; -GoogieSpell.Position=function(x,y){ -this.x=x; -this.y=y; -}; -GoogieSpell.absolutePosition=function(_bb){ -var _bc=new GoogieSpell.Position(_bb.offsetLeft,_bb.offsetTop); -if(_bb.offsetParent){ -var _bd=GoogieSpell.absolutePosition(_bb.offsetParent); -_bc.x+=_bd.x; -_bc.y+=_bd.y; -} -return _bc; -}; -GoogieSpell.getEventElm=function(e){ -var _bf; -if(!e){ -var e=window.event; + +GoogieSpell.prototype.hideErrorWindow = function() { + this.error_window.style.visibility = "hidden"; +} + +GoogieSpell.prototype.updateOrginalText = function(offset, old_value, new_value, id) { + var part_1 = this.orginal_text.substring(0, offset); + var part_2 = this.orginal_text.substring(offset+old_value.length); + this.orginal_text = part_1 + new_value + part_2; + var add_2_offset = new_value.length - old_value.length; + for(var j=0; j < this.results.length; j++) { + //Don't edit the offset of the current item + if(j != id && j > id){ + this.results[j]['attrs']['o'] += add_2_offset; + } + } +} + +GoogieSpell.prototype.saveOldValue = function (id, old_value) { + this.results[id]['is_changed'] = true; + this.results[id]['old_value'] = old_value; } -if(e.target){ -_bf=e.target; -}else{ -if(e.srcElement){ -_bf=e.srcElement; + +GoogieSpell.prototype.showErrorWindow = function(elm, id) { + var me = this; + + var abs_pos = GoogieSpell.absolutePosition(elm); + abs_pos.y -= this.edit_layer.scrollTop; + this.error_window.style.visibility = "visible"; + this.error_window.style.top = (abs_pos.y+20) + "px"; + this.error_window.style.left = (abs_pos.x) + "px"; + this.error_window.innerHTML = ""; + + //Build up the result list + var table = AJS.TABLE({'class': 'googie_list'}); + var list = AJS.TBODY(); + + var suggestions = this.results[id]['suggestions']; + var offset = this.results[id]['attrs']['o']; + var len = this.results[id]['attrs']['l']; + + if(suggestions.length == 0) { + var row = AJS.TR(); + var item = AJS.TD(); + var dummy = AJS.SPAN(); + item.appendChild(AJS.TN("No suggestions :(")); + row.appendChild(item); + list.appendChild(row); + } + + for(i=0; i < suggestions.length; i++) { + var row = AJS.TR(); + var item = AJS.TD(); + var dummy = AJS.SPAN(); + dummy.innerHTML = suggestions[i]; + item.appendChild(AJS.TN(dummy.innerHTML)); + + item.onclick = function(e) { + var l_elm = GoogieSpell.getEventElm(e); + var old_value = elm.innerHTML; + var new_value = l_elm.innerHTML; + + elm.style.color = "green"; + elm.innerHTML = l_elm.innerHTML; + me.hideErrorWindow(); + + me.updateOrginalText(offset, old_value, new_value, id); + + //Update to the new length + me.results[id]['attrs']['l'] = new_value.length; + me.saveOldValue(id, old_value); + }; + item.onmouseover = GoogieSpell.item_onmouseover; + item.onmouseout = GoogieSpell.item_onmouseout; + row.appendChild(item); + list.appendChild(row); + } + + //The element is changed, append the revert + if(this.results[id]['is_changed']) { + var old_value = this.results[id]['old_value']; + var offset = this.results[id]['attrs']['o']; + var revert_row = AJS.TR(); + var revert = AJS.TD(); + + revert.onmouseover = GoogieSpell.item_onmouseover; + revert.onmouseout = GoogieSpell.item_onmouseout; + var rev_span = AJS.SPAN({'class': 'googie_list_revert'}); + rev_span.innerHTML = this.lang_revert + " " + old_value; + revert.appendChild(rev_span); + + revert.onclick = function(e) { + me.updateOrginalText(offset, elm.innerHTML, old_value, id); + elm.style.color = "#b91414"; + elm.innerHTML = old_value; + me.hideErrorWindow(); + }; + + revert_row.appendChild(revert); + list.appendChild(revert_row); + } + + //Append the edit box + var edit_row = AJS.TR(); + var edit = AJS.TD(); + + var edit_input = AJS.INPUT({'style': 'width: 120px; margin:0; padding:0'}); + + var onsub = function () { + if(edit_input.value != "") { + me.saveOldValue(id, elm.innerHTML); + me.updateOrginalText(offset, elm.innerHTML, edit_input.value, id); + elm.style.color = "green" + elm.innerHTML = edit_input.value; + + me.hideErrorWindow(); + return false; + } + }; + + var ok_pic = AJS.IMG({'src': this.img_dir + "ok.gif", 'style': 'width: 32px; height: 16px; margin-left: 2px; margin-right: 2px;'}); + var edit_form = AJS.FORM({'style': 'margin: 0; padding: 0'}, edit_input, ok_pic); + ok_pic.onclick = onsub; + edit_form.onsubmit = onsub; + + edit.appendChild(edit_form); + edit_row.appendChild(edit); + list.appendChild(edit_row); + + //Close button + var close_row = AJS.TR(); + var close = AJS.TD(); + + close.onmouseover = GoogieSpell.item_onmouseover; + close.onmouseout = GoogieSpell.item_onmouseout; + + var spn_close = AJS.SPAN({'class': 'googie_list_close'}); + spn_close.innerHTML = this.lang_close; + close.appendChild(spn_close); + close.onclick = function() { me.hideErrorWindow()}; + close_row.appendChild(close); + list.appendChild(close_row); + + table.appendChild(list); + this.error_window.appendChild(table); } + + +/**** + Edit layer (the layer where the suggestions are stored) +****/ +GoogieSpell.prototype.createEditLayer = function(width, height) { + this.edit_layer = AJS.DIV({'class': 'googie_edit_layer'}); + + //Set the style so it looks like edit areas + this.edit_layer.className = this.text_area.className; + this.edit_layer.style.border = "1px solid #999"; + this.edit_layer.style.overflow = "auto"; + this.edit_layer.style.backgroundColor = "#F1EDFE"; + this.edit_layer.style.padding = "3px"; + + this.edit_layer.style.width = (width-8) + "px"; + this.edit_layer.style.height = height + "px"; } -if(_bf.nodeType==3){ -_bf=_bf.parentNode; + +GoogieSpell.prototype.resumeEditing = function(e, me) { + this.setStateChanged("check_spelling"); + me.switch_lan_pic.style.display = "inline"; + + this.el_scroll_top = me.edit_layer.scrollTop; + + var elm = GoogieSpell.getEventElm(e); + AJS.replaceChildNodes(elm, this.createSpellDiv()); + + elm.onclick = function(e) { + me.spellCheck(elm, me.text_area.id); + }; + me.hideErrorWindow(); + + //Remove the EDIT_LAYER + me.edit_layer.parentNode.removeChild(me.edit_layer); + + me.text_area.value = me.orginal_text; + AJS.showElement(me.text_area); + me.gselm.className = "googie_no_style"; + + me.text_area.scrollTop = this.el_scroll_top; + + elm.onmouseout = null; } -return _bf; -}; -GoogieSpell.prototype.removeIndicator=function(elm){ -if(window.rcube_webmail_client){ -rcube_webmail_client.set_busy(false); + +GoogieSpell.prototype.createErrorLink = function(text, id) { + var elm = AJS.SPAN({'class': 'googie_link'}); + var me = this; + elm.onclick = function () { + me.showErrorWindow(elm, id); + }; + elm.innerHTML = text; + return elm; } -}; -GoogieSpell.prototype.appendIndicator=function(elm){ -if(window.rcube_webmail_client){ -rcube_webmail_client.set_busy(true,"checking"); + +GoogieSpell.createPart = function(txt_part) { + if(txt_part == " ") + return AJS.TN(" "); + var result = AJS.SPAN(); + + var is_first = true; + var is_safari = (navigator.userAgent.toLowerCase().indexOf("safari") != -1); + + var part = AJS.SPAN(); + txt_part = GoogieSpell.escapeSepcial(txt_part); + txt_part = txt_part.replace(/\n/g, "
"); + txt_part = txt_part.replace(/ /g, "  "); + txt_part = txt_part.replace(/^ /g, " "); + txt_part = txt_part.replace(/ $/g, " "); + + part.innerHTML = txt_part; + + return part; } -}; -GoogieSpell.prototype.createLangWindow=function(){ -this.language_window=AJS.DIV({"class":"googie_window"}); -this.language_window.style.width="130px"; -var _c2=AJS.TABLE({"class":"googie_list"}); -var _c3=AJS.TBODY(); -this.lang_elms=new Array(); -for(i=0;i