diff options
Diffstat (limited to '')
| -rw-r--r-- | webmail/program/js/common.js | 30 | ||||
| -rw-r--r-- | webmail/program/js/common.js.src | 835 |
2 files changed, 865 insertions, 0 deletions
diff --git a/webmail/program/js/common.js b/webmail/program/js/common.js new file mode 100644 index 0000000..fbb7887 --- /dev/null +++ b/webmail/program/js/common.js @@ -0,0 +1,30 @@ +var CONTROL_KEY=1,SHIFT_KEY=2,CONTROL_SHIFT_KEY=3; +function roundcube_browser(){var a=navigator;this.ver=parseFloat(a.appVersion);this.appver=a.appVersion;this.agent=a.userAgent;this.agent_lc=a.userAgent.toLowerCase();this.name=a.appName;this.vendor=a.vendor?a.vendor:"";this.vendver=a.vendorSub?parseFloat(a.vendorSub):0;this.product=a.product?a.product:"";this.platform=String(a.platform).toLowerCase();this.lang=a.language?a.language.substring(0,2):a.browserLanguage?a.browserLanguage.substring(0,2):a.systemLanguage?a.systemLanguage.substring(0,2): +"en";this.win=0<=this.platform.indexOf("win");this.mac=0<=this.platform.indexOf("mac");this.linux=0<=this.platform.indexOf("linux");this.unix=0<=this.platform.indexOf("unix");this.dom=document.getElementById?!0:!1;this.dom2=document.addEventListener&&document.removeEventListener;this.ie4=(this.ie=document.all&&!window.opera)&&!this.dom;this.ie5=this.dom&&0<this.appver.indexOf("MSIE 5");this.ie8=this.dom&&0<this.appver.indexOf("MSIE 8");this.ie9=this.dom&&0<this.appver.indexOf("MSIE 9");this.ie7=this.dom&& +0<this.appver.indexOf("MSIE 7");this.ie6=this.dom&&!this.ie8&&!this.ie7&&0<this.appver.indexOf("MSIE 6");this.ns=5>this.ver&&"Netscape"==this.name||5<=this.ver&&0<=this.vendor.indexOf("Netscape");this.chrome=0<this.agent_lc.indexOf("chrome");this.safari=!this.chrome&&(0<this.agent_lc.indexOf("safari")||0<this.agent_lc.indexOf("applewebkit"));this.konq=0<this.agent_lc.indexOf("konqueror");this.mz=this.dom&&!this.ie&&!this.ns&&!this.chrome&&!this.safari&&!this.konq&&0<=this.agent.indexOf("Mozilla"); +this.iphone=this.safari&&(0<this.agent_lc.indexOf("iphone")||0<this.agent_lc.indexOf("ipod"));this.ipad=this.safari&&0<this.agent_lc.indexOf("ipad");(this.opera=window.opera?!0:!1)&&window.RegExp?this.vendver=/opera(\s|\/)([0-9\.]+)/.test(this.agent_lc)?parseFloat(RegExp.$2):-1:this.chrome&&window.RegExp?this.vendver=/chrome\/([0-9\.]+)/.test(this.agent_lc)?parseFloat(RegExp.$1):0:!this.vendver&&this.safari?this.vendver=/(safari|applewebkit)\/([0-9]+)/.test(this.agent_lc)?parseInt(RegExp.$2):0:!this.vendver&& +this.mz||0<this.agent.indexOf("Camino")?this.vendver=/rv:([0-9\.]+)/.test(this.agent)?parseFloat(RegExp.$1):0:this.ie&&window.RegExp?this.vendver=/msie\s+([0-9\.]+)/.test(this.agent_lc)?parseFloat(RegExp.$1):0:this.konq&&window.RegExp&&(this.vendver=/khtml\/([0-9\.]+)/.test(this.agent_lc)?parseFloat(RegExp.$1):0);this.safari&&/;\s+([a-z]{2})-[a-z]{2}\)/.test(this.agent_lc)&&(this.lang=RegExp.$1);this.tablet=/ipad|android|xoom|sch-i800|playbook|tablet|kindle/i.test(this.agent_lc);this.touch=(this.mobile= +/iphone|ipod|blackberry|iemobile|opera mini|opera mobi|mobile/i.test(this.agent_lc))||this.tablet;this.dhtml=this.ie4&&this.win||this.ie5||this.ie6||this.ns4||this.mz;this.vml=this.win&&this.ie&&this.dom&&!this.opera;this.pngalpha=this.mz||this.opera&&6<=this.vendver||this.ie&&this.mac&&5<=this.vendver||this.ie&&this.win&&5.5<=this.vendver||this.safari;this.opacity=this.mz||this.ie&&5.5<=this.vendver&&!this.opera||this.safari&&100<=this.vendver;this.cookies=a.cookieEnabled;this.xmlhttp_test=function(){var a= +new Function("try{var o=new ActiveXObject('Microsoft.XMLHTTP');return true;}catch(err){return false;}");return this.xmlhttp=window.XMLHttpRequest||window.ActiveXObject&&a()};this.set_html_class=function(){var a=" js";this.ie?a+=" ie ie"+parseInt(this.vendver):this.opera?a+=" opera":this.konq?a+=" konqueror":this.safari?a+=" chrome":this.chrome?a+=" chrome":this.mz&&(a+=" mozilla");if(this.iphone)a+=" iphone";else if(this.ipad)a+=" ipad";else if(this.safari||this.chrome)a+=" webkit";this.mobile&&(a+= +" mobile");this.tablet&&(a+=" tablet");document.documentElement&&(document.documentElement.className+=a)}} +var rcube_event={get_target:function(a){return(a=a||window.event)&&a.target?a.target:a.srcElement},get_keycode:function(a){return(a=a||window.event)&&a.keyCode?a.keyCode:a&&a.which?a.which:0},get_button:function(a){return(a=a||window.event)&&void 0!==a.button?a.button:a&&a.which?a.which:0},get_modifier:function(a){var b=0;a=a||window.event;bw.mac&&a?b+=(a.metaKey&&CONTROL_KEY)+(a.shiftKey&&SHIFT_KEY):a&&(b+=(a.ctrlKey&&CONTROL_KEY)+(a.shiftKey&&SHIFT_KEY));return b},get_mouse_pos:function(a){a||(a= +window.event);var b=a.pageX?a.pageX:a.clientX,c=a.pageY?a.pageY:a.clientY;document.body&&document.all&&(b+=document.body.scrollLeft,c+=document.body.scrollTop);a._offset&&(b+=a._offset.left,c+=a._offset.top);return{x:b,y:c}},add_listener:function(a){if(a.object&&a.method){a.element||(a.element=document);a.object._rc_events||(a.object._rc_events=[]);var b=a.event+"*"+a.method;a.object._rc_events[b]||(a.object._rc_events[b]=function(c){return a.object[a.method](c)});a.element.addEventListener?a.element.addEventListener(a.event, +a.object._rc_events[b],!1):a.element.attachEvent?(a.element.detachEvent("on"+a.event,a.object._rc_events[b]),a.element.attachEvent("on"+a.event,a.object._rc_events[b])):a.element["on"+a.event]=a.object._rc_events[b]}},remove_listener:function(a){a.element||(a.element=document);var b=a.event+"*"+a.method;a.object&&a.object._rc_events&&a.object._rc_events[b]&&(a.element.removeEventListener?a.element.removeEventListener(a.event,a.object._rc_events[b],!1):a.element.detachEvent?a.element.detachEvent("on"+ +a.event,a.object._rc_events[b]):a.element["on"+a.event]=null)},cancel:function(a){a=a?a:window.event;a.preventDefault&&a.preventDefault();a.stopPropagation&&a.stopPropagation();a.cancelBubble=!0;return a.returnValue=!1},touchevent:function(a){return{pageX:a.pageX,pageY:a.pageY,offsetX:a.pageX-a.target.offsetLeft,offsetY:a.pageY-a.target.offsetTop,target:a.target,istouch:!0}}};function rcube_event_engine(){this._events={}} +rcube_event_engine.prototype={addEventListener:function(a,b,c){this._events||(this._events={});this._events[a]||(this._events[a]=[]);this._events[a][this._events[a].length]={func:b,obj:c?c:window}},removeEventListener:function(a,b,c){void 0===c&&(c=window);for(var d,e=0;this._events&&this._events[a]&&e<this._events[a].length;e++)(d=this._events[a][e])&&d.func==b&&d.obj==c&&(this._events[a][e]=null)},triggerEvent:function(a,b){var c,d;void 0===b?b=this:"object"===typeof b&&(b.event=a);if(this._events&& +this._events[a]&&!this._event_exec){this._event_exec=!0;for(var e=0;e<this._events[a].length;e++)if(d=this._events[a][e])if("function"===typeof d.func?c=d.func.call?d.func.call(d.obj,b):d.func(b):"function"===typeof d.obj[d.func]&&(c=d.obj[d.func](b)),void 0!==c&&!c)break;if(c&&c.event)try{delete c.event}catch(f){$(c).removeAttr("event")}}this._event_exec=!1;if(b.event)try{delete b.event}catch(h){$(b).removeAttr("event")}return c}}; +function rcube_layer(a,b){this.name=a;this.create=function(a){var b=a.x?a.x:0,e=a.y?a.y:0,f=a.width,h=a.height,k=a.zindex,g=a.vis;a=a.parent;var l=document.createElement("DIV");l.id=this.name;l.style.position="absolute";l.style.visibility=g?2==g?"inherit":"visible":"hidden";l.style.left=b+"px";l.style.top=e+"px";f&&(l.style.width=f.toString().match(/\%$/)?f:f+"px");h&&(l.style.height=h.toString().match(/\%$/)?h:h+"px");k&&(l.style.zIndex=k);a?a.appendChild(l):document.body.appendChild(l);this.elm= +l};null!=b?(this.create(b),this.name=this.elm.id):this.elm=document.getElementById(a);if(!this.elm)return!1;this.css=this.elm.style;this.event=this.elm;this.width=this.elm.offsetWidth;this.height=this.elm.offsetHeight;this.x=parseInt(this.elm.offsetLeft);this.y=parseInt(this.elm.offsetTop);this.visible="visible"==this.css.visibility||"show"==this.css.visibility||"inherit"==this.css.visibility?!0:!1;this.move=function(a,b){this.x=a;this.y=b;this.css.left=Math.round(this.x)+"px";this.css.top=Math.round(this.y)+ +"px"};this.resize=function(a,b){this.css.width=a+"px";this.css.height=b+"px";this.width=a;this.height=b};this.show=function(a){1==a?(this.css.visibility="visible",this.visible=!0):2==a?(this.css.visibility="inherit",this.visible=!0):(this.css.visibility="hidden",this.visible=!1)};this.write=function(a){this.elm.innerHTML=a}} +function rcube_check_email(a,b){return a&&window.RegExp?(b?RegExp("(^|<|[,;s\n])((([^\\x00-\\x20\\x22\\x28\\x29\\x2c\\x2e\\x3a-\\x3c\\x3e\\x40\\x5b-\\x5d\\x7f-\\xff]+|\\x22([^\\x0d\\x22\\x5c\\x80-\\xff]|\\x5c[\\x00-\\x7f])*\\x22)(\\x2e([^\\x00-\\x20\\x22\\x28\\x29\\x2c\\x2e\\x3a-\\x3c\\x3e\\x40\\x5b-\\x5d\\x7f-\\xff]+|\\x22([^\\x0d\\x22\\x5c\\x80-\\xff]|\\x5c[\\x00-\\x7f])*\\x22))*\\x40(((\\[(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])(.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])){3}\\])|(\\[IPv6:[0-9a-f:.]+\\]))|(([^@\\x2e]+\\x2e)+([^\\x00-\\x40\\x5b-\\x60\\x7b-\\x7f]{2,}|xn--[a-z0-9]{2,}))))|(mailtest\\x40(\\u0645\\u062b\\u0627\\u0644\\x2e\\u0625\\u062e\\u062a\\u0628\\u0627\\u0631|\\u4f8b\\u5b50\\x2e\\u6d4b\\u8bd5|\\u4f8b\\u5b50\\x2e\\u6e2c\\u8a66|\\u03c0\\u03b1\\u03c1\\u03ac\\u03b4\\u03b5\\u03b9\\u03b3\\u03bc\\u03b1\\x2e\\u03b4\\u03bf\\u03ba\\u03b9\\u03bc\\u03ae|\\u0909\\u0926\\u093e\\u0939\\u0930\\u0923\\x2e\\u092a\\u0930\\u0940\\u0915\\u094d\\u0937\\u093e|\\u4f8b\\u3048\\x2e\\u30c6\\u30b9\\u30c8|\\uc2e4\\ub840\\x2e\\ud14c\\uc2a4\\ud2b8|\\u0645\\u062b\\u0627\\u0644\\x2e\\u0622\\u0632\\u0645\\u0627\\u06cc\\u0634\u06cc|\\u043f\\u0440\\u0438\\u043c\\u0435\\u0440\\x2e\\u0438\\u0441\\u043f\\u044b\\u0442\\u0430\\u043d\\u0438\\u0435|\\u0b89\\u0ba4\\u0bbe\\u0bb0\\u0ba3\\u0bae\\u0bcd\\x2e\\u0baa\\u0bb0\\u0bbf\\u0b9f\\u0bcd\\u0b9a\\u0bc8|\\u05d1\\u05f2\\u05b7\\u05e9\\u05e4\\u05bc\\u05d9\\u05dc\\x2e\\u05d8\\u05e2\\u05e1\\u05d8)))($|>|[,;s\n])","i"): +RegExp("^((([^\\x00-\\x20\\x22\\x28\\x29\\x2c\\x2e\\x3a-\\x3c\\x3e\\x40\\x5b-\\x5d\\x7f-\\xff]+|\\x22([^\\x0d\\x22\\x5c\\x80-\\xff]|\\x5c[\\x00-\\x7f])*\\x22)(\\x2e([^\\x00-\\x20\\x22\\x28\\x29\\x2c\\x2e\\x3a-\\x3c\\x3e\\x40\\x5b-\\x5d\\x7f-\\xff]+|\\x22([^\\x0d\\x22\\x5c\\x80-\\xff]|\\x5c[\\x00-\\x7f])*\\x22))*\\x40(((\\[(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])(.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])){3}\\])|(\\[IPv6:[0-9a-f:.]+\\]))|(([^@\\x2e]+\\x2e)+([^\\x00-\\x40\\x5b-\\x60\\x7b-\\x7f]{2,}|xn--[a-z0-9]{2,}))))|(mailtest\\x40(\\u0645\\u062b\\u0627\\u0644\\x2e\\u0625\\u062e\\u062a\\u0628\\u0627\\u0631|\\u4f8b\\u5b50\\x2e\\u6d4b\\u8bd5|\\u4f8b\\u5b50\\x2e\\u6e2c\\u8a66|\\u03c0\\u03b1\\u03c1\\u03ac\\u03b4\\u03b5\\u03b9\\u03b3\\u03bc\\u03b1\\x2e\\u03b4\\u03bf\\u03ba\\u03b9\\u03bc\\u03ae|\\u0909\\u0926\\u093e\\u0939\\u0930\\u0923\\x2e\\u092a\\u0930\\u0940\\u0915\\u094d\\u0937\\u093e|\\u4f8b\\u3048\\x2e\\u30c6\\u30b9\\u30c8|\\uc2e4\\ub840\\x2e\\ud14c\\uc2a4\\ud2b8|\\u0645\\u062b\\u0627\\u0644\\x2e\\u0622\\u0632\\u0645\\u0627\\u06cc\\u0634\u06cc|\\u043f\\u0440\\u0438\\u043c\\u0435\\u0440\\x2e\\u0438\\u0441\\u043f\\u044b\\u0442\\u0430\\u043d\\u0438\\u0435|\\u0b89\\u0ba4\\u0bbe\\u0bb0\\u0ba3\\u0bae\\u0bcd\\x2e\\u0baa\\u0bb0\\u0bbf\\u0b9f\\u0bcd\\u0b9a\\u0bc8|\\u05d1\\u05f2\\u05b7\\u05e9\\u05e4\\u05bc\\u05d9\\u05dc\\x2e\\u05d8\\u05e2\\u05e1\\u05d8)))$", +"i")).test(a)?!0:!1:!1}function rcube_clone_object(a){var b={},c;for(c in a)b[c]=a[c]&&"object"===typeof a[c]?clone_object(a[c]):a[c];return b}function urlencode(a){return window.encodeURIComponent?encodeURIComponent(a).replace("*","%2A"):escape(a).replace("+","%2B").replace("*","%2A").replace("/","%2F").replace("@","%40")} +function rcube_find_object(a,b){var c,d;b||(b=document);b.getElementsByName&&(c=b.getElementsByName(a))&&(d=c[0]);!d&&b.getElementById&&(d=b.getElementById(a));!d&&b.all&&(d=b.all[a]);!d&&b.images.length&&(d=b.images[a]);if(!d&&b.forms.length)for(c=0;c<b.forms.length;c++)b.forms[c].name==a?d=b.forms[c]:b.forms[c].elements[a]&&(d=b.forms[c].elements[a]);if(!d&&b.layers)for(b.layers[a]&&(d=b.layers[a]),c=0;!d&&c<b.layers.length;c++)d=rcube_find_object(a,b.layers[c].document);return d} +function rcube_mouse_is_over(a,b){var c=rcube_event.get_mouse_pos(a),d=$(b).offset();return c.x>=d.left&&c.x<d.left+b.offsetWidth&&c.y>=d.top&&c.y<d.top+b.offsetHeight}function setCookie(a,b,c,d,e,f){a=a+"="+escape(b)+(c?"; expires="+c.toGMTString():"")+(d?"; path="+d:"")+(e?"; domain="+e:"")+(f?"; secure":"");document.cookie=a} +function getCookie(a){var b=document.cookie;a+="=";var c=b.indexOf("; "+a);if(-1==c){if(c=b.indexOf(a),0!=c)return null}else c+=2;var d=b.indexOf(";",c);-1==d&&(d=b.length);return unescape(b.substring(c+a.length,d))}roundcube_browser.prototype.set_cookie=setCookie;roundcube_browser.prototype.get_cookie=getCookie; +function rcube_console(){this.log=function(a){var b=rcube_find_object("dbgconsole");b&&(a="\n"==a.charAt(a.length-1)?a+"--------------------------------------\n":a+"\n--------------------------------------\n",bw.konq?(b.innerText+=a,b.value=b.innerText):b.value+=a)};this.reset=function(){var a=rcube_find_object("dbgconsole");a&&(a.innerText=a.value="")}}var bw=new roundcube_browser;bw.set_html_class();RegExp.escape=function(a){return String(a).replace(/([.*+?^=!:${}()|[\]\/\\])/g,"\\$1")}; +Date.prototype.getStdTimezoneOffset=function(){for(var a=12,b=new Date(null,a,1),c=b.getTimezoneOffset();--a;)if(b.setUTCMonth(a),c!=b.getTimezoneOffset())return Math.max(c,b.getTimezoneOffset());return c};bw.ie&&(document._getElementById=document.getElementById,document.getElementById=function(a){var b=0,c=document._getElementById(a);if(c&&c.id!=a)for(;(c=document.all[b])&&c.id!=a;)b++;return c}); +jQuery.fn.placeholder=function(a){return this.each(function(){var b=!1,c=$(this);this.title=a;if("placeholder"in this)c.attr("placeholder",a);else{this._placeholder=a;c.blur(function(b){""==$.trim(c.val())&&c.val(a);c.triggerHandler("change")}).focus(function(b){$.trim(c.val())==a&&c.val("");c.triggerHandler("change")}).change(function(b){b=c.val()==a;c[b?"addClass":"removeClass"]("placeholder").attr("spellcheck",b)});try{b=this==document.activeElement}catch(d){}b||c.blur()}})}; +var Base64=function(){return{encode:function(a){if("function"===typeof window.btoa)return btoa(a);var b,c,d,e,f,h,k=0,g="",l=a.length;do b=a.charCodeAt(k++),c=a.charCodeAt(k++),d=a.charCodeAt(k++),e=b>>2,b=(b&3)<<4|c>>4,f=(c&15)<<2|d>>6,h=d&63,isNaN(c)?f=h=64:isNaN(d)&&(h=64),g=g+"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".charAt(e)+"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".charAt(b)+"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".charAt(f)+ +"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".charAt(h);while(k<l);return g},decode:function(a){if("function"===typeof window.atob)return atob(a);var b,c,d,e,f,h,k=0,g="";a=a.replace(/[^A-Za-z0-9\+\/\=]/g,"");h=a.length;do b="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".indexOf(a.charAt(k++)),c="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".indexOf(a.charAt(k++)),e="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".indexOf(a.charAt(k++)), +f="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".indexOf(a.charAt(k++)),b=b<<2|c>>4,c=(c&15)<<4|e>>2,d=(e&3)<<6|f,g+=String.fromCharCode(b),64!=e&&(g+=String.fromCharCode(c)),64!=f&&(g+=String.fromCharCode(d));while(k<h);return g}}}(); diff --git a/webmail/program/js/common.js.src b/webmail/program/js/common.js.src new file mode 100644 index 0000000..18a1928 --- /dev/null +++ b/webmail/program/js/common.js.src @@ -0,0 +1,835 @@ +/* + +-----------------------------------------------------------------------+ + | Roundcube common js library | + | | + | This file is part of the Roundcube web development suite | + | Copyright (C) 2005-2012, The Roundcube Dev Team | + | | + | Licensed under the GNU General Public License version 3 or | + | any later version with exceptions for skins & plugins. | + | See the README file for a full license statement. | + | | + +-----------------------------------------------------------------------+ + | Author: Thomas Bruederli <roundcube@gmail.com> | + +-----------------------------------------------------------------------+ +*/ + +// Constants +var CONTROL_KEY = 1; +var SHIFT_KEY = 2; +var CONTROL_SHIFT_KEY = 3; + + +/** + * Default browser check class + * @constructor + */ +function roundcube_browser() +{ + var n = navigator; + + this.ver = parseFloat(n.appVersion); + this.appver = n.appVersion; + this.agent = n.userAgent; + this.agent_lc = n.userAgent.toLowerCase(); + this.name = n.appName; + this.vendor = n.vendor ? n.vendor : ''; + this.vendver = n.vendorSub ? parseFloat(n.vendorSub) : 0; + this.product = n.product ? n.product : ''; + this.platform = String(n.platform).toLowerCase(); + this.lang = (n.language) ? n.language.substring(0,2) : + (n.browserLanguage) ? n.browserLanguage.substring(0,2) : + (n.systemLanguage) ? n.systemLanguage.substring(0,2) : 'en'; + + this.win = (this.platform.indexOf('win') >= 0); + this.mac = (this.platform.indexOf('mac') >= 0); + this.linux = (this.platform.indexOf('linux') >= 0); + this.unix = (this.platform.indexOf('unix') >= 0); + + this.dom = document.getElementById ? true : false; + this.dom2 = (document.addEventListener && document.removeEventListener); + + this.ie = (document.all && !window.opera); + this.ie4 = (this.ie && !this.dom); + this.ie5 = (this.dom && this.appver.indexOf('MSIE 5')>0); + this.ie8 = (this.dom && this.appver.indexOf('MSIE 8')>0); + this.ie9 = (this.dom && this.appver.indexOf('MSIE 9')>0); + this.ie7 = (this.dom && this.appver.indexOf('MSIE 7')>0); + this.ie6 = (this.dom && !this.ie8 && !this.ie7 && this.appver.indexOf('MSIE 6')>0); + + this.ns = ((this.ver < 5 && this.name == 'Netscape') || (this.ver >= 5 && this.vendor.indexOf('Netscape') >= 0)); + this.chrome = (this.agent_lc.indexOf('chrome') > 0); + this.safari = (!this.chrome && (this.agent_lc.indexOf('safari') > 0 || this.agent_lc.indexOf('applewebkit') > 0)); + this.konq = (this.agent_lc.indexOf('konqueror') > 0); + this.mz = (this.dom && !this.ie && !this.ns && !this.chrome && !this.safari && !this.konq && this.agent.indexOf('Mozilla') >= 0); + this.iphone = (this.safari && (this.agent_lc.indexOf('iphone') > 0 || this.agent_lc.indexOf('ipod') > 0)); + this.ipad = (this.safari && this.agent_lc.indexOf('ipad') > 0); + this.opera = window.opera ? true : false; + + if (this.opera && window.RegExp) + this.vendver = (/opera(\s|\/)([0-9\.]+)/.test(this.agent_lc)) ? parseFloat(RegExp.$2) : -1; + else if (this.chrome && window.RegExp) + this.vendver = (/chrome\/([0-9\.]+)/.test(this.agent_lc)) ? parseFloat(RegExp.$1) : 0; + else if (!this.vendver && this.safari) + this.vendver = (/(safari|applewebkit)\/([0-9]+)/.test(this.agent_lc)) ? parseInt(RegExp.$2) : 0; + else if ((!this.vendver && this.mz) || this.agent.indexOf('Camino')>0) + this.vendver = (/rv:([0-9\.]+)/.test(this.agent)) ? parseFloat(RegExp.$1) : 0; + else if (this.ie && window.RegExp) + this.vendver = (/msie\s+([0-9\.]+)/.test(this.agent_lc)) ? parseFloat(RegExp.$1) : 0; + else if (this.konq && window.RegExp) + this.vendver = (/khtml\/([0-9\.]+)/.test(this.agent_lc)) ? parseFloat(RegExp.$1) : 0; + + // get real language out of safari's user agent + if (this.safari && (/;\s+([a-z]{2})-[a-z]{2}\)/.test(this.agent_lc))) + this.lang = RegExp.$1; + + this.tablet = /ipad|android|xoom|sch-i800|playbook|tablet|kindle/i.test(this.agent_lc); + this.mobile = /iphone|ipod|blackberry|iemobile|opera mini|opera mobi|mobile/i.test(this.agent_lc); + this.touch = this.mobile || this.tablet; + this.dhtml = ((this.ie4 && this.win) || this.ie5 || this.ie6 || this.ns4 || this.mz); + this.vml = (this.win && this.ie && this.dom && !this.opera); + this.pngalpha = (this.mz || (this.opera && this.vendver >= 6) || (this.ie && this.mac && this.vendver >= 5) || + (this.ie && this.win && this.vendver >= 5.5) || this.safari); + this.opacity = (this.mz || (this.ie && this.vendver >= 5.5 && !this.opera) || (this.safari && this.vendver >= 100)); + this.cookies = n.cookieEnabled; + + // test for XMLHTTP support + this.xmlhttp_test = function() + { + var activeX_test = new Function("try{var o=new ActiveXObject('Microsoft.XMLHTTP');return true;}catch(err){return false;}"); + this.xmlhttp = (window.XMLHttpRequest || (window.ActiveXObject && activeX_test())); + return this.xmlhttp; + }; + + // set class names to html tag according to the current user agent detection + // this allows browser-specific css selectors like "html.chrome .someclass" + this.set_html_class = function() + { + var classname = ' js'; + + if (this.ie) + classname += ' ie ie'+parseInt(this.vendver); + else if (this.opera) + classname += ' opera'; + else if (this.konq) + classname += ' konqueror'; + else if (this.safari) + classname += ' chrome'; + else if (this.chrome) + classname += ' chrome'; + else if (this.mz) + classname += ' mozilla'; + + if (this.iphone) + classname += ' iphone'; + else if (this.ipad) + classname += ' ipad'; + else if (this.safari || this.chrome) + classname += ' webkit'; + + if (this.mobile) + classname += ' mobile'; + if (this.tablet) + classname += ' tablet'; + + if (document.documentElement) + document.documentElement.className += classname; + }; +}; + + +// static functions for DOM event handling +var rcube_event = { + +/** + * returns the event target element + */ +get_target: function(e) +{ + e = e || window.event; + return e && e.target ? e.target : e.srcElement; +}, + +/** + * returns the event key code + */ +get_keycode: function(e) +{ + e = e || window.event; + return e && e.keyCode ? e.keyCode : (e && e.which ? e.which : 0); +}, + +/** + * returns the event key code + */ +get_button: function(e) +{ + e = e || window.event; + return e && e.button !== undefined ? e.button : (e && e.which ? e.which : 0); +}, + +/** + * returns modifier key (constants defined at top of file) + */ +get_modifier: function(e) +{ + var opcode = 0; + e = e || window.event; + + if (bw.mac && e) + opcode += (e.metaKey && CONTROL_KEY) + (e.shiftKey && SHIFT_KEY); + else if (e) + opcode += (e.ctrlKey && CONTROL_KEY) + (e.shiftKey && SHIFT_KEY); + + return opcode; +}, + +/** + * Return absolute mouse position of an event + */ +get_mouse_pos: function(e) +{ + if (!e) e = window.event; + var mX = (e.pageX) ? e.pageX : e.clientX, + mY = (e.pageY) ? e.pageY : e.clientY; + + if (document.body && document.all) { + mX += document.body.scrollLeft; + mY += document.body.scrollTop; + } + + if (e._offset) { + mX += e._offset.left; + mY += e._offset.top; + } + + return { x:mX, y:mY }; +}, + +/** + * Add an object method as event listener to a certain element + */ +add_listener: function(p) +{ + if (!p.object || !p.method) // not enough arguments + return; + if (!p.element) + p.element = document; + + if (!p.object._rc_events) + p.object._rc_events = []; + + var key = p.event + '*' + p.method; + if (!p.object._rc_events[key]) + p.object._rc_events[key] = function(e){ return p.object[p.method](e); }; + + if (p.element.addEventListener) + p.element.addEventListener(p.event, p.object._rc_events[key], false); + else if (p.element.attachEvent) { + // IE allows multiple events with the same function to be applied to the same object + // forcibly detach the event, then attach + p.element.detachEvent('on'+p.event, p.object._rc_events[key]); + p.element.attachEvent('on'+p.event, p.object._rc_events[key]); + } + else + p.element['on'+p.event] = p.object._rc_events[key]; +}, + +/** + * Remove event listener + */ +remove_listener: function(p) +{ + if (!p.element) + p.element = document; + + var key = p.event + '*' + p.method; + if (p.object && p.object._rc_events && p.object._rc_events[key]) { + if (p.element.removeEventListener) + p.element.removeEventListener(p.event, p.object._rc_events[key], false); + else if (p.element.detachEvent) + p.element.detachEvent('on'+p.event, p.object._rc_events[key]); + else + p.element['on'+p.event] = null; + } +}, + +/** + * Prevent event propagation and bubbeling + */ +cancel: function(evt) +{ + var e = evt ? evt : window.event; + if (e.preventDefault) + e.preventDefault(); + if (e.stopPropagation) + e.stopPropagation(); + + e.cancelBubble = true; + e.returnValue = false; + return false; +}, + +touchevent: function(e) +{ + return { pageX:e.pageX, pageY:e.pageY, offsetX:e.pageX - e.target.offsetLeft, offsetY:e.pageY - e.target.offsetTop, target:e.target, istouch:true }; +} + +}; + + +/** + * rcmail objects event interface + */ +function rcube_event_engine() +{ + this._events = {}; +}; + +rcube_event_engine.prototype = { + +/** + * Setter for object event handlers + * + * @param {String} Event name + * @param {Function} Handler function + * @return Listener ID (used to remove this handler later on) + */ +addEventListener: function(evt, func, obj) +{ + if (!this._events) + this._events = {}; + if (!this._events[evt]) + this._events[evt] = []; + + var e = {func:func, obj:obj ? obj : window}; + this._events[evt][this._events[evt].length] = e; +}, + +/** + * Removes a specific event listener + * + * @param {String} Event name + * @param {Int} Listener ID to remove + */ +removeEventListener: function(evt, func, obj) +{ + if (obj === undefined) + obj = window; + + for (var h,i=0; this._events && this._events[evt] && i < this._events[evt].length; i++) + if ((h = this._events[evt][i]) && h.func == func && h.obj == obj) + this._events[evt][i] = null; +}, + +/** + * This will execute all registered event handlers + * + * @param {String} Event to trigger + * @param {Object} Event object/arguments + */ +triggerEvent: function(evt, e) +{ + var ret, h; + if (e === undefined) + e = this; + else if (typeof e === 'object') + e.event = evt; + + if (this._events && this._events[evt] && !this._event_exec) { + this._event_exec = true; + for (var i=0; i < this._events[evt].length; i++) { + if ((h = this._events[evt][i])) { + if (typeof h.func === 'function') + ret = h.func.call ? h.func.call(h.obj, e) : h.func(e); + else if (typeof h.obj[h.func] === 'function') + ret = h.obj[h.func](e); + + // cancel event execution + if (ret !== undefined && !ret) + break; + } + } + if (ret && ret.event) { + try { + delete ret.event; + } catch (err) { + // IE6-7 doesn't support deleting HTMLFormElement attributes (#1488017) + $(ret).removeAttr('event'); + } + } + } + + this._event_exec = false; + if (e.event) { + try { + delete e.event; + } catch (err) { + // IE6-7 doesn't support deleting HTMLFormElement attributes (#1488017) + $(e).removeAttr('event'); + } + } + + return ret; +} + +}; // end rcube_event_engine.prototype + + + +/** + * Roundcube generic layer (floating box) class + * + * @constructor + */ +function rcube_layer(id, attributes) +{ + this.name = id; + + // create a new layer in the current document + this.create = function(arg) + { + var l = (arg.x) ? arg.x : 0, + t = (arg.y) ? arg.y : 0, + w = arg.width, + h = arg.height, + z = arg.zindex, + vis = arg.vis, + parent = arg.parent, + obj = document.createElement('DIV'); + + obj.id = this.name; + obj.style.position = 'absolute'; + obj.style.visibility = (vis) ? (vis==2) ? 'inherit' : 'visible' : 'hidden'; + obj.style.left = l+'px'; + obj.style.top = t+'px'; + if (w) + obj.style.width = w.toString().match(/\%$/) ? w : w+'px'; + if (h) + obj.style.height = h.toString().match(/\%$/) ? h : h+'px'; + if (z) + obj.style.zIndex = z; + + if (parent) + parent.appendChild(obj); + else + document.body.appendChild(obj); + + this.elm = obj; + }; + + // create new layer + if (attributes != null) { + this.create(attributes); + this.name = this.elm.id; + } + else // just refer to the object + this.elm = document.getElementById(id); + + if (!this.elm) + return false; + + + // ********* layer object properties ********* + + this.css = this.elm.style; + this.event = this.elm; + this.width = this.elm.offsetWidth; + this.height = this.elm.offsetHeight; + this.x = parseInt(this.elm.offsetLeft); + this.y = parseInt(this.elm.offsetTop); + this.visible = (this.css.visibility=='visible' || this.css.visibility=='show' || this.css.visibility=='inherit') ? true : false; + + + // ********* layer object methods ********* + + // move the layer to a specific position + this.move = function(x, y) + { + this.x = x; + this.y = y; + this.css.left = Math.round(this.x)+'px'; + this.css.top = Math.round(this.y)+'px'; + }; + + // change the layers width and height + this.resize = function(w,h) + { + this.css.width = w+'px'; + this.css.height = h+'px'; + this.width = w; + this.height = h; + }; + + // show or hide the layer + this.show = function(a) + { + if(a == 1) { + this.css.visibility = 'visible'; + this.visible = true; + } + else if(a == 2) { + this.css.visibility = 'inherit'; + this.visible = true; + } + else { + this.css.visibility = 'hidden'; + this.visible = false; + } + }; + + // write new content into a Layer + this.write = function(cont) + { + this.elm.innerHTML = cont; + }; + +}; + + +// check if input is a valid email address +// By Cal Henderson <cal@iamcal.com> +// http://code.iamcal.com/php/rfc822/ +function rcube_check_email(input, inline) +{ + if (input && window.RegExp) { + var qtext = '[^\\x0d\\x22\\x5c\\x80-\\xff]', + dtext = '[^\\x0d\\x5b-\\x5d\\x80-\\xff]', + atom = '[^\\x00-\\x20\\x22\\x28\\x29\\x2c\\x2e\\x3a-\\x3c\\x3e\\x40\\x5b-\\x5d\\x7f-\\xff]+', + quoted_pair = '\\x5c[\\x00-\\x7f]', + quoted_string = '\\x22('+qtext+'|'+quoted_pair+')*\\x22', + ipv4 = '\\[(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])(\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])){3}\\]', + ipv6 = '\\[IPv6:[0-9a-f:.]+\\]', + ip_addr = '(' + ipv4 + ')|(' + ipv6 + ')', + // Use simplified domain matching, because we need to allow Unicode characters here + // So, e-mail address should be validated also on server side after idn_to_ascii() use + //domain_literal = '\\x5b('+dtext+'|'+quoted_pair+')*\\x5d', + //sub_domain = '('+atom+'|'+domain_literal+')', + // allow punycode/unicode top-level domain + domain = '(('+ip_addr+')|(([^@\\x2e]+\\x2e)+([^\\x00-\\x40\\x5b-\\x60\\x7b-\\x7f]{2,}|xn--[a-z0-9]{2,})))', + // ICANN e-mail test (http://idn.icann.org/E-mail_test) + icann_domains = [ + '\\u0645\\u062b\\u0627\\u0644\\x2e\\u0625\\u062e\\u062a\\u0628\\u0627\\u0631', + '\\u4f8b\\u5b50\\x2e\\u6d4b\\u8bd5', + '\\u4f8b\\u5b50\\x2e\\u6e2c\\u8a66', + '\\u03c0\\u03b1\\u03c1\\u03ac\\u03b4\\u03b5\\u03b9\\u03b3\\u03bc\\u03b1\\x2e\\u03b4\\u03bf\\u03ba\\u03b9\\u03bc\\u03ae', + '\\u0909\\u0926\\u093e\\u0939\\u0930\\u0923\\x2e\\u092a\\u0930\\u0940\\u0915\\u094d\\u0937\\u093e', + '\\u4f8b\\u3048\\x2e\\u30c6\\u30b9\\u30c8', + '\\uc2e4\\ub840\\x2e\\ud14c\\uc2a4\\ud2b8', + '\\u0645\\u062b\\u0627\\u0644\\x2e\\u0622\\u0632\\u0645\\u0627\\u06cc\\u0634\u06cc', + '\\u043f\\u0440\\u0438\\u043c\\u0435\\u0440\\x2e\\u0438\\u0441\\u043f\\u044b\\u0442\\u0430\\u043d\\u0438\\u0435', + '\\u0b89\\u0ba4\\u0bbe\\u0bb0\\u0ba3\\u0bae\\u0bcd\\x2e\\u0baa\\u0bb0\\u0bbf\\u0b9f\\u0bcd\\u0b9a\\u0bc8', + '\\u05d1\\u05f2\\u05b7\\u05e9\\u05e4\\u05bc\\u05d9\\u05dc\\x2e\\u05d8\\u05e2\\u05e1\\u05d8' + ], + icann_addr = 'mailtest\\x40('+icann_domains.join('|')+')', + word = '('+atom+'|'+quoted_string+')', + delim = '[,;\s\n]', + local_part = word+'(\\x2e'+word+')*', + addr_spec = '(('+local_part+'\\x40'+domain+')|('+icann_addr+'))', + reg1 = inline ? new RegExp('(^|<|'+delim+')'+addr_spec+'($|>|'+delim+')', 'i') : new RegExp('^'+addr_spec+'$', 'i'); + + return reg1.test(input) ? true : false; + } + + return false; +}; + +// recursively copy an object +function rcube_clone_object(obj) +{ + var out = {}; + + for (var key in obj) { + if (obj[key] && typeof obj[key] === 'object') + out[key] = clone_object(obj[key]); + else + out[key] = obj[key]; + } + + return out; +}; + +// make a string URL safe (and compatible with PHP's rawurlencode()) +function urlencode(str) +{ + if (window.encodeURIComponent) + return encodeURIComponent(str).replace('*', '%2A'); + + return escape(str) + .replace('+', '%2B') + .replace('*', '%2A') + .replace('/', '%2F') + .replace('@', '%40'); +}; + + +// get any type of html objects by id/name +function rcube_find_object(id, d) +{ + var n, f, obj, e; + if(!d) d = document; + + if(d.getElementsByName && (e = d.getElementsByName(id))) + obj = e[0]; + if(!obj && d.getElementById) + obj = d.getElementById(id); + if(!obj && d.all) + obj = d.all[id]; + + if(!obj && d.images.length) + obj = d.images[id]; + + if (!obj && d.forms.length) { + for (f=0; f<d.forms.length; f++) { + if(d.forms[f].name == id) + obj = d.forms[f]; + else if(d.forms[f].elements[id]) + obj = d.forms[f].elements[id]; + } + } + + if (!obj && d.layers) { + if (d.layers[id]) obj = d.layers[id]; + for (n=0; !obj && n<d.layers.length; n++) + obj = rcube_find_object(id, d.layers[n].document); + } + + return obj; +}; + +// determine whether the mouse is over the given object or not +function rcube_mouse_is_over(ev, obj) +{ + var mouse = rcube_event.get_mouse_pos(ev), + pos = $(obj).offset(); + + return ((mouse.x >= pos.left) && (mouse.x < (pos.left + obj.offsetWidth)) && + (mouse.y >= pos.top) && (mouse.y < (pos.top + obj.offsetHeight))); +}; + + +// cookie functions by GoogieSpell +function setCookie(name, value, expires, path, domain, secure) +{ + var curCookie = name + "=" + escape(value) + + (expires ? "; expires=" + expires.toGMTString() : "") + + (path ? "; path=" + path : "") + + (domain ? "; domain=" + domain : "") + + (secure ? "; secure" : ""); + document.cookie = curCookie; +}; + +function getCookie(name) +{ + var dc = document.cookie, + prefix = name + "=", + begin = dc.indexOf("; " + prefix); + + if (begin == -1) { + begin = dc.indexOf(prefix); + if (begin != 0) + return null; + } + else { + begin += 2; + } + + var end = dc.indexOf(";", begin); + if (end == -1) + end = dc.length; + + return unescape(dc.substring(begin + prefix.length, end)); +}; + +// deprecated aliases, to be removed, use rcmail.set_cookie/rcmail.get_cookie +roundcube_browser.prototype.set_cookie = setCookie; +roundcube_browser.prototype.get_cookie = getCookie; + +// tiny replacement for Firebox functionality +function rcube_console() +{ + this.log = function(msg) + { + var box = rcube_find_object('dbgconsole'); + + if (box) { + if (msg.charAt(msg.length-1)=='\n') + msg += '--------------------------------------\n'; + else + msg += '\n--------------------------------------\n'; + + // Konqueror doesn't allow to just change the value of hidden element + if (bw.konq) { + box.innerText += msg; + box.value = box.innerText; + } else + box.value += msg; + } + }; + + this.reset = function() + { + var box = rcube_find_object('dbgconsole'); + if (box) + box.innerText = box.value = ''; + }; +}; + +var bw = new roundcube_browser(); +bw.set_html_class(); + + +// Add escape() method to RegExp object +// http://dev.rubyonrails.org/changeset/7271 +RegExp.escape = function(str) +{ + return String(str).replace(/([.*+?^=!:${}()|[\]\/\\])/g, '\\$1'); +}; + +// Extend Date prototype to detect Standard timezone without DST +// from http://www.michaelapproved.com/articles/timezone-detect-and-ignore-daylight-saving-time-dst/ +Date.prototype.getStdTimezoneOffset = function() +{ + var m = 12, + d = new Date(null, m, 1), + tzo = d.getTimezoneOffset(); + + while (--m) { + d.setUTCMonth(m); + if (tzo != d.getTimezoneOffset()) { + return Math.max(tzo, d.getTimezoneOffset()); + } + } + + return tzo; +} + +// Make getElementById() case-sensitive on IE +if (bw.ie) { + document._getElementById = document.getElementById; + document.getElementById = function(id) { + var i = 0, obj = document._getElementById(id); + + if (obj && obj.id != id) + while ((obj = document.all[i]) && obj.id != id) + i++; + + return obj; + } +} + +// jQuery plugin to emulate HTML5 placeholder attributes on input elements +jQuery.fn.placeholder = function(text) { + return this.each(function() { + var active = false, elem = $(this); + this.title = text; + + // Try HTML5 placeholder attribute first + if ('placeholder' in this) { + elem.attr('placeholder', text); + } + // Fallback to Javascript emulation of placeholder + else { + this._placeholder = text; + elem.blur(function(e) { + if ($.trim(elem.val()) == "") + elem.val(text); + elem.triggerHandler('change'); + }) + .focus(function(e) { + if ($.trim(elem.val()) == text) + elem.val(""); + elem.triggerHandler('change'); + }) + .change(function(e) { + var active = elem.val() == text; + elem[(active ? 'addClass' : 'removeClass')]('placeholder').attr('spellcheck', active); + }); + + // Do not blur currently focused element (catch exception: #1489008) + try { active = this == document.activeElement; } catch(e) {} + if (!active) + elem.blur(); + } + }); +}; + + +// This code was written by Tyler Akins and has been placed in the +// public domain. It would be nice if you left this header intact. +// Base64 code from Tyler Akins -- http://rumkin.com +var Base64 = (function () { + var keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; + + var obj = { + /** + * Encodes a string in base64 + * @param {String} input The string to encode in base64. + */ + encode: function (input) { + if (typeof(window.btoa) === 'function') + return btoa(input); + + var chr1, chr2, chr3, enc1, enc2, enc3, enc4, i = 0, output = '', len = input.length; + + do { + chr1 = input.charCodeAt(i++); + chr2 = input.charCodeAt(i++); + chr3 = input.charCodeAt(i++); + + enc1 = chr1 >> 2; + enc2 = ((chr1 & 3) << 4) | (chr2 >> 4); + enc3 = ((chr2 & 15) << 2) | (chr3 >> 6); + enc4 = chr3 & 63; + + if (isNaN(chr2)) + enc3 = enc4 = 64; + else if (isNaN(chr3)) + enc4 = 64; + + output = output + + keyStr.charAt(enc1) + keyStr.charAt(enc2) + + keyStr.charAt(enc3) + keyStr.charAt(enc4); + } while (i < len); + + return output; + }, + + /** + * Decodes a base64 string. + * @param {String} input The string to decode. + */ + decode: function (input) { + if (typeof(window.atob) === 'function') + return atob(input); + + var chr1, chr2, chr3, enc1, enc2, enc3, enc4, len, i = 0, output = ''; + + // remove all characters that are not A-Z, a-z, 0-9, +, /, or = + input = input.replace(/[^A-Za-z0-9\+\/\=]/g, ""); + len = input.length; + + do { + enc1 = keyStr.indexOf(input.charAt(i++)); + enc2 = keyStr.indexOf(input.charAt(i++)); + enc3 = keyStr.indexOf(input.charAt(i++)); + enc4 = keyStr.indexOf(input.charAt(i++)); + + chr1 = (enc1 << 2) | (enc2 >> 4); + chr2 = ((enc2 & 15) << 4) | (enc3 >> 2); + chr3 = ((enc3 & 3) << 6) | enc4; + + output = output + String.fromCharCode(chr1); + + if (enc3 != 64) + output = output + String.fromCharCode(chr2); + if (enc4 != 64) + output = output + String.fromCharCode(chr3); + } while (i < len); + + return output; + } + }; + + return obj; +})(); |
