RoundCube Webmail
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

441 lines
13 KiB

20 years ago
20 years ago
20 years ago
20 years ago
20 years ago
20 years ago
20 years ago
20 years ago
20 years ago
  1. /*
  2. +-----------------------------------------------------------------------+
  3. | RoundCube common js library |
  4. | |
  5. | This file is part of the RoundCube web development suite |
  6. | Copyright (C) 2005, RoundCube Dev, - Switzerland |
  7. | Licensed under the GNU GPL |
  8. | |
  9. +-----------------------------------------------------------------------+
  10. | Author: Thomas Bruederli <roundcube@gmail.com> |
  11. +-----------------------------------------------------------------------+
  12. $Id$
  13. */
  14. // default browsercheck
  15. function roundcube_browser()
  16. {
  17. this.ver = parseFloat(navigator.appVersion);
  18. this.appver = navigator.appVersion;
  19. this.agent = navigator.userAgent;
  20. this.name = navigator.appName;
  21. this.vendor = navigator.vendor ? navigator.vendor : '';
  22. this.vendver = navigator.vendorSub ? parseFloat(navigator.vendorSub) : 0;
  23. this.product = navigator.product ? navigator.product : '';
  24. this.platform = String(navigator.platform).toLowerCase();
  25. this.lang = (navigator.language) ? navigator.language.substring(0,2) :
  26. (navigator.browserLanguage) ? navigator.browserLanguage.substring(0,2) :
  27. (navigator.systemLanguage) ? navigator.systemLanguage.substring(0,2) : 'en';
  28. this.win = (this.platform.indexOf('win')>=0) ? true : false;
  29. this.mac = (this.platform.indexOf('mac')>=0) ? true : false;
  30. this.linux = (this.platform.indexOf('linux')>=0) ? true : false;
  31. this.unix = (this.platform.indexOf('unix')>=0) ? true : false;
  32. this.dom = document.getElementById ? true : false;
  33. this.dom2 = (document.addEventListener && document.removeEventListener);
  34. this.ie = (document.all) ? true : false;
  35. this.ie4 = (this.ie && !this.dom);
  36. this.ie5 = (this.dom && this.appver.indexOf('MSIE 5')>0);
  37. this.ie6 = (this.dom && this.appver.indexOf('MSIE 6')>0);
  38. this.mz = (this.dom && this.ver>=5); // (this.dom && this.product=='Gecko')
  39. this.ns = ((this.ver<5 && this.name=='Netscape') || (this.ver>=5 && this.vendor.indexOf('Netscape')>=0));
  40. this.ns4 = (this.ns && parseInt(this.ver)==4);
  41. this.ns6 = (this.ns && parseInt(this.vendver)==6); // (this.mz && this.ns) ? true : false;
  42. this.ns7 = (this.ns && parseInt(this.vendver)==7); // this.agent.indexOf('Netscape/7')>0);
  43. this.safari = (this.agent.toLowerCase().indexOf('safari')>0 || this.agent.toLowerCase().indexOf('applewebkit')>0);
  44. this.konq = (this.agent.toLowerCase().indexOf('konqueror')>0);
  45. this.opera = (window.opera) ? true : false;
  46. this.opera5 = (this.opera5 && this.agent.indexOf('Opera 5')>0) ? true : false;
  47. this.opera6 = (this.opera && this.agent.indexOf('Opera 6')>0) ? true : false;
  48. this.opera7 = (this.opera && this.agent.indexOf('Opera 7')>0) ? true : false;
  49. if(this.opera && window.RegExp)
  50. this.vendver = (/opera(\s|\/)([0-9\.]+)/i.test(navigator.userAgent)) ? parseFloat(RegExp.$2) : -1;
  51. else if(!this.vendver && this.safari)
  52. this.vendver = (/(safari|applewebkit)\/([0-9]+)/i.test(this.agent)) ? parseInt(RegExp.$2) : 0;
  53. else if((!this.vendver && this.mz) || this.agent.indexOf('Camino')>0)
  54. this.vendver = (/rv:([0-9\.]+)/.test(this.agent)) ? parseFloat(RegExp.$1) : 0;
  55. else if(this.ie && window.RegExp)
  56. this.vendver = (/msie\s+([0-9\.]+)/i.test(this.agent)) ? parseFloat(RegExp.$1) : 0;
  57. else if(this.konq && window.RegExp)
  58. this.vendver = (/khtml\/([0-9\.]+)/i.test(this.agent)) ? parseFloat(RegExp.$1) : 0;
  59. // get real language out of safari's user agent
  60. if(this.safari && (/;\s+([a-z]{2})-[a-z]{2}\)/i.test(this.agent)))
  61. this.lang = RegExp.$1;
  62. this.dhtml = ((this.ie4 && this.win) || this.ie5 || this.ie6 || this.ns4 || this.mz);
  63. this.layers = this.ns4; // (document.layers);
  64. this.div = (this.ie4 || this.dom);
  65. this.vml = (this.win && this.ie && this.dom && !this.opera);
  66. this.linkborder = (this.ie || this.mz);
  67. this.rollover = (this.ver>=4 || (this.ns && this.ver>=3)); // (document.images) ? true : false;
  68. this.pngalpha = (this.mz || (this.opera && this.vendver>=6) || (this.ie && this.mac && this.vendver>=5) ||
  69. (this.ie && this.win && this.vendver>=5.5) || this.safari);
  70. this.opacity = (this.mz || (this.ie && this.vendver>=5.5 && !this.opera) || (this.safari && this.vendver>=100));
  71. this.cookies = navigator.cookieEnabled;
  72. // test for XMLHTTP support
  73. this.xmlhttp_test = function()
  74. {
  75. var activeX_test = new Function("try{var o=new ActiveXObject('Microsoft.XMLHTTP');return true;}catch(err){return false;}");
  76. this.xmlhttp = (window.XMLHttpRequest || (window.ActiveXObject && activeX_test())) ? true : false;
  77. return this.xmlhttp;
  78. }
  79. }
  80. var rcube_layer_objects = new Array();
  81. function rcube_layer(id, attributes)
  82. {
  83. this.name = id;
  84. // create a new layer in the current document
  85. this.create = function(arg)
  86. {
  87. var l = (arg.x) ? arg.x : 0;
  88. var t = (arg.y) ? arg.y : 0;
  89. var w = arg.width;
  90. var h = arg.height;
  91. var z = arg.zindex;
  92. var vis = arg.vis;
  93. var parent = arg.parent;
  94. var obj;
  95. obj = document.createElement('DIV');
  96. with(obj)
  97. {
  98. id = this.name;
  99. with(style)
  100. {
  101. position = 'absolute';
  102. visibility = (vis) ? (vis==2) ? 'inherit' : 'visible' : 'hidden';
  103. left = l+'px';
  104. top = t+'px';
  105. if(w) width = w+'px';
  106. if(h) height = h+'px';
  107. if(z) zIndex = z;
  108. }
  109. }
  110. if(parent) parent.appendChild(obj);
  111. else document.body.appendChild(obj);
  112. this.elm = obj;
  113. };
  114. // create new layer
  115. if(attributes!=null)
  116. {
  117. this.create(attributes);
  118. this.name = this.elm.id;
  119. }
  120. else // just refer to the object
  121. this.elm = document.getElementById(id);
  122. if(!this.elm)
  123. return false;
  124. // ********* layer object properties *********
  125. this.css = this.elm.style;
  126. this.event = this.elm;
  127. this.width = this.elm.offsetWidth;
  128. this.height = this.elm.offsetHeight;
  129. this.x = parseInt(this.elm.offsetLeft);
  130. this.y = parseInt(this.elm.offsetTop);
  131. this.visible = (this.css.visibility=='visible' || this.css.visibility=='show' || this.css.visibility=='inherit') ? true : false;
  132. this.id = rcube_layer_objects.length;
  133. this.obj = 'rcube_layer_objects['+this.id+']';
  134. rcube_layer_objects[this.id] = this;
  135. // ********* layer object methods *********
  136. // move the layer to a specific position
  137. this.move = function(x, y)
  138. {
  139. this.x = x;
  140. this.y = y;
  141. this.css.left = Math.round(this.x)+'px';
  142. this.css.top = Math.round(this.y)+'px';
  143. }
  144. // move the layer for a specific step
  145. this.shift = function(x,y)
  146. {
  147. x = Math.round(x*100)/100;
  148. y = Math.round(y*100)/100;
  149. this.move(this.x+x, this.y+y);
  150. }
  151. // change the layers width and height
  152. this.resize = function(w,h)
  153. {
  154. this.css.width = w+'px';
  155. this.css.height = h+'px';
  156. this.width = w;
  157. this.height = h;
  158. }
  159. // cut the layer (top,width,height,left)
  160. this.clip = function(t,w,h,l)
  161. {
  162. this.css.clip='rect('+t+' '+w+' '+h+' '+l+')';
  163. this.clip_height = h;
  164. this.clip_width = w;
  165. }
  166. // show or hide the layer
  167. this.show = function(a)
  168. {
  169. if(a==1)
  170. {
  171. this.css.visibility = 'visible';
  172. this.visible = true;
  173. }
  174. else if(a==2)
  175. {
  176. this.css.visibility = 'inherit';
  177. this.visible = true;
  178. }
  179. else
  180. {
  181. this.css.visibility = 'hidden';
  182. this.visible = false;
  183. }
  184. }
  185. // write new content into a Layer
  186. this.write = function(cont)
  187. {
  188. this.elm.innerHTML = cont;
  189. }
  190. // set the given color to the layer background
  191. this.set_bgcolor = function(c)
  192. {
  193. if(!c || c=='#')
  194. c = 'transparent';
  195. this.css.backgroundColor = c;
  196. }
  197. // set the opacity of a layer to the given ammount (in %)
  198. this.set_opacity = function(v)
  199. {
  200. if(!bw.opacity)
  201. return;
  202. var op = v<=1 ? Math.round(v*100) : parseInt(v);
  203. if(bw.ie)
  204. this.css.filter = 'alpha(opacity:'+op+')';
  205. else if(bw.safari)
  206. {
  207. this.css.opacity = op/100;
  208. this.css.KhtmlOpacity = op/100;
  209. }
  210. else if(bw.mz)
  211. this.css.MozOpacity = op/100;
  212. }
  213. }
  214. // check if input is a valid email address
  215. // By Cal Henderson <cal@iamcal.com>
  216. // http://code.iamcal.com/php/rfc822/
  217. function rcube_check_email(input, inline)
  218. {
  219. if (input && window.RegExp)
  220. {
  221. var no_ws_ctl = "[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x7f]";
  222. var alpha = "[\\x41-\\x5a\\x61-\\x7a]";
  223. var digit = "[\\x30-\\x39]";
  224. var cr = "\\x0d";
  225. var lf = "\\x0a";
  226. var crlf = "(" + cr + lf + ")";
  227. var obs_char = "[\\x00-\\x09\\x0b\\x0c\\x0e-\\x7f]";
  228. var obs_text = "("+lf+"*"+cr+"*("+obs_char+lf+"*"+cr+"*)*)";
  229. var text = "([\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f]|"+obs_text+")";
  230. var obs_qp = "(\\x5c[\\x00-\\x7f])";
  231. var quoted_pair = "(\\x5c"+text+"|"+obs_qp+")";
  232. var wsp = "[\\x20\\x09]";
  233. var obs_fws = "("+wsp+"+("+crlf+wsp+"+)*)";
  234. var fws = "((("+wsp+"*"+crlf+")?"+wsp+"+)|"+obs_fws+")";
  235. var ctext = "("+no_ws_ctl+"|[\\x21-\\x27\\x2A-\\x5b\\x5d-\\x7e])";
  236. var ccontent = "("+ctext+"|"+quoted_pair+")";
  237. var comment = "(\\x28("+fws+"?"+ccontent+")*"+fws+"?\\x29)";
  238. var cfws = "(("+fws+"?"+comment+")*("+fws+"?"+comment+"|"+fws+"))";
  239. var cfws = fws+"*";
  240. var atext = "("+alpha+"|"+digit+"|[\\x21\\x23-\\x27\\x2a\\x2b\\x2d\\x2e\\x3d\\x3f\\x5e\\x5f\\x60\\x7b-\\x7e])";
  241. var atom = "("+cfws+"?"+atext+"+"+cfws+"?)";
  242. var qtext = "("+no_ws_ctl+"|[\\x21\\x23-\\x5b\\x5d-\\x7e])";
  243. var qcontent = "("+qtext+"|"+quoted_pair+")";
  244. var quoted_string = "("+cfws+"?\\x22("+fws+"?"+qcontent+")*"+fws+"?\\x22"+cfws+"?)";
  245. var word = "("+atom+"|"+quoted_string+")";
  246. var obs_local_part = "("+word+"(\\x2e"+word+")*)";
  247. var obs_domain = "("+atom+"(\\x2e"+atom+")*)";
  248. var dot_atom_text = "("+atext+"+(\\x2e"+atext+"+)*)";
  249. var dot_atom = "("+cfws+"?"+dot_atom_text+cfws+"?)";
  250. var dtext = "("+no_ws_ctl+"|[\\x21-\\x5a\\x5e-\\x7e])";
  251. var dcontent = "("+dtext+"|"+quoted_pair+")";
  252. var domain_literal = "("+cfws+"?\\x5b("+fws+"?"+dcontent+")*"+fws+"?\\x5d"+cfws+"?)";
  253. var local_part = "("+dot_atom+"|"+quoted_string+"|"+obs_local_part+")";
  254. var domain = "("+dot_atom+"|"+domain_literal+"|"+obs_domain+")";
  255. var addr_spec = "("+local_part+"\\x40"+domain+")";
  256. var reg1 = inline ? new RegExp(addr_spec, 'i') : new RegExp('^'+addr_spec+'$', 'i');
  257. return reg1.test(input) ? true : false;
  258. }
  259. return false;
  260. }
  261. // find a value in a specific array and returns the index
  262. function find_in_array()
  263. {
  264. var args = find_in_array.arguments;
  265. if(!args.length) return -1;
  266. var haystack = typeof(args[0])=='object' ? args[0] : args.length>1 && typeof(args[1])=='object' ? args[1] : new Array();
  267. var needle = typeof(args[0])!='object' ? args[0] : args.length>1 && typeof(args[1])!='object' ? args[1] : '';
  268. var nocase = args.length==3 ? args[2] : false;
  269. if(!haystack.length) return -1;
  270. for(var i=0; i<haystack.length; i++)
  271. if(nocase && haystack[i].toLowerCase()==needle.toLowerCase())
  272. return i;
  273. else if(haystack[i]==needle)
  274. return i;
  275. return -1;
  276. }
  277. // get any type of html objects by id/name
  278. function rcube_find_object(id, d)
  279. {
  280. var n, f, obj, e;
  281. if(!d) d = document;
  282. if(d.getElementsByName && (e = d.getElementsByName(id)))
  283. obj = e[0];
  284. if(!obj && d.getElementById)
  285. obj = d.getElementById(id);
  286. if(!obj && d.all)
  287. obj = d.all[id];
  288. if(!obj && d.images.length)
  289. obj = d.images[id];
  290. if(!obj && d.forms.length)
  291. for(f=0; f<d.forms.length; f++)
  292. {
  293. if(d.forms[f].name == id)
  294. obj = d.forms[f];
  295. else if(d.forms[f].elements[id])
  296. obj = d.forms[f].elements[id];
  297. }
  298. if(!obj && d.layers)
  299. {
  300. if(d.layers[id]) obj = d.layers[id];
  301. for(n=0; !obj && n<d.layers.length; n++)
  302. obj = nex_get_object(id, d.layers[n].document);
  303. }
  304. return obj;
  305. }
  306. // return the absolute position of an object within the document
  307. function rcube_get_object_pos(obj)
  308. {
  309. if(typeof(obj)=='string')
  310. obj = nex_get_object(obj);
  311. if(!obj) return {x:0, y:0};
  312. var iX = (bw.layers) ? obj.x : obj.offsetLeft;
  313. var iY = (bw.layers) ? obj.y : obj.offsetTop;
  314. if(bw.ie || bw.mz)
  315. {
  316. var elm = obj.offsetParent;
  317. while(elm && elm!=null)
  318. {
  319. iX += elm.offsetLeft;
  320. iY += elm.offsetTop;
  321. elm = elm.offsetParent;
  322. }
  323. }
  324. if(bw.mac && bw.ie5) iX += document.body.leftMargin;
  325. if(bw.mac && bw.ie5) iY += document.body.topMargin;
  326. return {x:iX, y:iY};
  327. }
  328. // cookie functions by GoogieSpell
  329. function setCookie(name, value, expires, path, domain, secure)
  330. {
  331. var curCookie = name + "=" + escape(value) +
  332. (expires ? "; expires=" + expires.toGMTString() : "") +
  333. (path ? "; path=" + path : "") +
  334. (domain ? "; domain=" + domain : "") +
  335. (secure ? "; secure" : "");
  336. document.cookie = curCookie;
  337. }
  338. function getCookie(name)
  339. {
  340. var dc = document.cookie;
  341. var prefix = name + "=";
  342. var begin = dc.indexOf("; " + prefix);
  343. if (begin == -1)
  344. {
  345. begin = dc.indexOf(prefix);
  346. if (begin != 0) return null;
  347. }
  348. else
  349. begin += 2;
  350. var end = document.cookie.indexOf(";", begin);
  351. if (end == -1)
  352. end = dc.length;
  353. return unescape(dc.substring(begin + prefix.length, end));
  354. }
  355. var bw = new roundcube_browser();