includes/clientside/static/misc.js
changeset 582 a38876c0793c
parent 581 5e8fd89c02ea
child 583 c97d5f0d6636
equal deleted inserted replaced
581:5e8fd89c02ea 582:a38876c0793c
     1 // Some additional DHTML functions
       
     2 
       
     3 function fetch_offset(obj) {
       
     4   var left_offset = obj.offsetLeft;
       
     5   var top_offset = obj.offsetTop;
       
     6   while ((obj = obj.offsetParent) != null) {
       
     7     left_offset += obj.offsetLeft;
       
     8     top_offset += obj.offsetTop;
       
     9   }
       
    10   return { 'left' : left_offset, 'top' : top_offset };
       
    11 }
       
    12 
       
    13 function fetch_dimensions(o) {
       
    14   var w = o.offsetWidth;
       
    15   var h = o.offsetHeight;
       
    16   return { 'w' : w, 'h' : h };
       
    17 }
       
    18 
       
    19 function findParentForm(o)
       
    20 {
       
    21   if ( o.tagName == 'FORM' )
       
    22     return o;
       
    23   while(true)
       
    24   {
       
    25     o = o.parentNode;
       
    26     if ( !o )
       
    27       return false;
       
    28     if ( o.tagName == 'FORM' )
       
    29       return o;
       
    30   }
       
    31   return false;
       
    32 }
       
    33 
       
    34 function ajaxReverseDNS(o, text)
       
    35 {
       
    36   if(text) var ipaddr = text;
       
    37   else var ipaddr = o.innerHTML;
       
    38   rDnsObj = o;
       
    39   rDnsBannerObj = bannerOn('Retrieving reverse DNS info...');
       
    40   ajaxGet(stdAjaxPrefix+'&_mode=rdns&ip='+ipaddr, function() {
       
    41       if ( ajax.readyState == 4 && ajax.status == 200 )
       
    42       {
       
    43         off = fetch_offset(rDnsObj);
       
    44         dim = fetch_dimensions(rDnsObj);
       
    45         right = off['left'] + dim['w'];
       
    46         top = off['top'] + dim['h'];
       
    47         var thediv = document.createElement('div');
       
    48         thediv.className = 'info-box';
       
    49         thediv.style.margin = '0';
       
    50         thediv.style.position = 'absolute';
       
    51         thediv.style.top  = top  + 'px';
       
    52         thediv.style.display = 'none';
       
    53         thediv.style.zIndex = getHighestZ() + 2;
       
    54         thediv.id = 'mdgDynamic_rDnsInfoDiv_'+Math.floor(Math.random() * 1000000);
       
    55         thediv.innerHTML = '<b>Reverse DNS:</b><br />'+ajax.responseText+' <a href="#" onclick="elem = document.getElementById(\''+thediv.id+'\'); elem.innerHTML = \'\'; elem.style.display = \'none\';return false;">Close</a>';
       
    56         var body = document.getElementsByTagName('body');
       
    57         body = body[0];
       
    58         bannerOff(rDnsBannerObj);
       
    59         body.appendChild(thediv);
       
    60         thediv.style.display = 'block';
       
    61         left = fetch_dimensions(thediv);
       
    62         thediv.style.display = 'none';
       
    63         left = right - left['w'];
       
    64         thediv.style.left = left + 'px';
       
    65         thediv.style.display = 'block';
       
    66         fadeInfoBoxes();
       
    67       }
       
    68     });
       
    69 }
       
    70 
       
    71 function bannerOn(text)
       
    72 {
       
    73   darken(true);
       
    74   var thediv = document.createElement('div');
       
    75   thediv.className = 'mdg-comment';
       
    76   thediv.style.padding = '0';
       
    77   thediv.style.marginLeft = '0';
       
    78   thediv.style.position = 'absolute';
       
    79   thediv.style.display = 'none';
       
    80   thediv.style.padding = '4px';
       
    81   thediv.style.fontSize = '14pt';
       
    82   thediv.id = 'mdgDynamic_bannerDiv_'+Math.floor(Math.random() * 1000000);
       
    83   thediv.innerHTML = text;
       
    84   
       
    85   var body = document.getElementsByTagName('body');
       
    86   body = body[0];
       
    87   body.appendChild(thediv);
       
    88   body.style.cursor = 'wait';
       
    89   
       
    90   thediv.style.display = 'block';
       
    91   dim = fetch_dimensions(thediv);
       
    92   thediv.style.display = 'none';
       
    93   bdim = { 'w' : getWidth(), 'h' : getHeight() };
       
    94   so = getScrollOffset();
       
    95   
       
    96   var left = (bdim['w'] / 2) - ( dim['w'] / 2 );
       
    97   
       
    98   var top  = (bdim['h'] / 2);
       
    99   top  = top - ( dim['h'] / 2 );
       
   100   
       
   101   top = top + so;
       
   102   
       
   103   thediv.style.top  = top  + 'px';
       
   104   thediv.style.left = left + 'px';
       
   105   
       
   106   thediv.style.display = 'block';
       
   107   
       
   108   return thediv.id;
       
   109 }
       
   110 
       
   111 function bannerOff(id)
       
   112 {
       
   113   e = document.getElementById(id);
       
   114   if(!e) return;
       
   115   e.innerHTML = '';
       
   116   e.style.display = 'none';
       
   117   var body = document.getElementsByTagName('body');
       
   118   body = body[0];
       
   119   body.style.cursor = 'default';
       
   120   enlighten(true);
       
   121 }
       
   122 
       
   123 function disableUnload(message)
       
   124 {
       
   125   if(typeof message != 'string') message = 'You may want to save your changes first.';
       
   126   window._unloadmsg = message;
       
   127   window.onbeforeunload = function(e)
       
   128   {
       
   129     if ( !e )
       
   130       e = window.event;
       
   131     e.returnValue = window._unloadmsg;
       
   132   }
       
   133 }
       
   134 
       
   135 function enableUnload()
       
   136 {
       
   137   window._unloadmsg = null;
       
   138   window.onbeforeunload = null;
       
   139 }
       
   140 
       
   141 /**
       
   142  * Gets the highest z-index of all divs in the document
       
   143  * @return integer
       
   144  */
       
   145 function getHighestZ()
       
   146 {
       
   147   z = 0;
       
   148   var divs = document.getElementsByTagName('div');
       
   149   for(var i = 0; i < divs.length; i++)
       
   150   {
       
   151     if(divs[i].style.zIndex > z) z = divs[i].style.zIndex;
       
   152   }
       
   153   return z;
       
   154 }
       
   155 
       
   156 function isKeyPressed(event)
       
   157 {
       
   158   if (event.shiftKey==1)
       
   159   {
       
   160     shift = true;
       
   161   }
       
   162   else
       
   163   {
       
   164     shift = false;
       
   165   }
       
   166 }
       
   167 
       
   168 function moveDiv(div, newparent)
       
   169 {
       
   170   var backup = div;
       
   171   var oldparent = div.parentNode;
       
   172   oldparent.removeChild(div);
       
   173   newparent.appendChild(backup);
       
   174 }
       
   175 
       
   176 function readCookie(name) {var nameEQ = name + "=";var ca = document.cookie.split(';');for(var i=0;i < ca.length;i++){var c = ca[i];while (c.charAt(0)==' ') c = c.substring(1,c.length);if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);}return null;}
       
   177 function createCookie(name,value,days){if (days){var date = new Date();date.setTime(date.getTime()+(days*24*60*60*1000));var expires = "; expires="+date.toGMTString();}else var expires = "";document.cookie = name+"="+value+expires+"; path=/";}
       
   178 function eraseCookie(name) {createCookie(name,"",-1);}
       
   179 
       
   180 var busyBannerID;
       
   181 function goBusy(msg)
       
   182 {
       
   183   if(!msg) msg = 'Please wait...';
       
   184   body = document.getElementsByTagName('body');
       
   185   body = body[0];
       
   186   body.style.cursor = 'wait';
       
   187   busyBannerID = bannerOn(msg);
       
   188 }
       
   189 
       
   190 function unBusy()
       
   191 {
       
   192   body = document.getElementsByTagName('body');
       
   193   body = body[0];
       
   194   body.style.cursor = 'default';
       
   195   bannerOff(busyBannerID);
       
   196 }
       
   197 
       
   198 function setAjaxLoading()
       
   199 {
       
   200   if ( document.getElementById('ajaxloadicon') )
       
   201   {
       
   202     document.getElementById('ajaxloadicon').src=ajax_load_icon;
       
   203   }
       
   204 }
       
   205 
       
   206 function unsetAjaxLoading()
       
   207 {
       
   208   if ( document.getElementById('ajaxloadicon') )
       
   209   {
       
   210     document.getElementById('ajaxloadicon').src=scriptPath + '/images/spacer.gif';
       
   211   }
       
   212 }
       
   213 
       
   214 /*
       
   215  * AJAX login box (experimental)
       
   216  * Moved / rewritten in login.js
       
   217  */
       
   218 
       
   219 // Included only for API-compatibility
       
   220 function ajaxPromptAdminAuth(call_on_ok, level)
       
   221 {
       
   222   ajaxLogonInit(call_on_ok, level);
       
   223 }
       
   224 
       
   225 // This code is in the public domain. Feel free to link back to http://jan.moesen.nu/
       
   226 function sprintf()
       
   227 {
       
   228   if (!arguments || arguments.length < 1 || !RegExp)
       
   229   {
       
   230     return;
       
   231   }
       
   232   var str = arguments[0];
       
   233   var re = /([^%]*)%('.|0|\x20)?(-)?(\d+)?(\.\d+)?(%|b|c|d|u|f|o|s|x|X)(.*)/;
       
   234   var a = b = [], numSubstitutions = 0, numMatches = 0;
       
   235   while (a = re.exec(str))
       
   236   {
       
   237     var leftpart = a[1], pPad = a[2], pJustify = a[3], pMinLength = a[4];
       
   238     var pPrecision = a[5], pType = a[6], rightPart = a[7];
       
   239     
       
   240     //alert(a + '\n' + [a[0], leftpart, pPad, pJustify, pMinLength, pPrecision);
       
   241 
       
   242     numMatches++;
       
   243     if (pType == '%')
       
   244     {
       
   245       subst = '%';
       
   246     }
       
   247     else
       
   248     {
       
   249       numSubstitutions++;
       
   250       if (numSubstitutions >= arguments.length)
       
   251       {
       
   252         alert('Error! Not enough function arguments (' + (arguments.length - 1) + ', excluding the string)\nfor the number of substitution parameters in string (' + numSubstitutions + ' so far).');
       
   253       }
       
   254       var param = arguments[numSubstitutions];
       
   255       var pad = '';
       
   256              if (pPad && pPad.substr(0,1) == "'") pad = leftpart.substr(1,1);
       
   257         else if (pPad) pad = pPad;
       
   258       var justifyRight = true;
       
   259              if (pJustify && pJustify === "-") justifyRight = false;
       
   260       var minLength = -1;
       
   261              if (pMinLength) minLength = parseInt(pMinLength);
       
   262       var precision = -1;
       
   263              if (pPrecision && pType == 'f') precision = parseInt(pPrecision.substring(1));
       
   264       var subst = param;
       
   265              if (pType == 'b') subst = parseInt(param).toString(2);
       
   266         else if (pType == 'c') subst = String.fromCharCode(parseInt(param));
       
   267         else if (pType == 'd') subst = parseInt(param) ? parseInt(param) : 0;
       
   268         else if (pType == 'u') subst = Math.abs(param);
       
   269         else if (pType == 'f') subst = (precision > -1) ? Math.round(parseFloat(param) * Math.pow(10, precision)) / Math.pow(10, precision): parseFloat(param);
       
   270         else if (pType == 'o') subst = parseInt(param).toString(8);
       
   271         else if (pType == 's') subst = param;
       
   272         else if (pType == 'x') subst = ('' + parseInt(param).toString(16)).toLowerCase();
       
   273         else if (pType == 'X') subst = ('' + parseInt(param).toString(16)).toUpperCase();
       
   274     }
       
   275     str = leftpart + subst + rightPart;
       
   276   }
       
   277   return str;
       
   278 }
       
   279 
       
   280 /**
       
   281  * Insert a DOM object _after_ the specified child.
       
   282  * @param object Parent node
       
   283  * @param object Node to insert
       
   284  * @param object Node to insert after
       
   285  */
       
   286 
       
   287 function insertAfter(parent, baby, bigsister)
       
   288 {
       
   289   try
       
   290   {
       
   291     if ( parent.childNodes[parent.childNodes.length-1] == bigsister )
       
   292       parent.appendChild(baby);
       
   293     else
       
   294       parent.insertBefore(baby, bigsister.nextSibling);
       
   295   }
       
   296   catch(e)
       
   297   {
       
   298     alert(e.toString());
       
   299     if ( window.console )
       
   300     {
       
   301       // Firebug support
       
   302       window.console.warn(e);
       
   303     }
       
   304   }
       
   305 }
       
   306 
       
   307 /**
       
   308  * Validates an e-mail address.
       
   309  * @param string E-mail address
       
   310  * @return bool
       
   311  */
       
   312 
       
   313 function validateEmail(email)
       
   314 {
       
   315   return ( email.match(/^(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t]*)*(?:(?:[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff])|"[^\\\x80-\xff\n\015"]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015"]*)*")[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t]*)*(?:\.[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t]*)*(?:[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff])|"[^\\\x80-\xff\n\015"]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015"]*)*")[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t]*)*)*@[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t]*)*(?:[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff])|\[(?:[^\\\x80-\xff\n\015\[\]]|\\[^\x80-\xff])*\])[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t]*)*(?:\.[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t]*)*(?:[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff])|\[(?:[^\\\x80-\xff\n\015\[\]]|\\[^\x80-\xff])*\])[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t]*)*)*|(?:[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff])|"[^\\\x80-\xff\n\015"]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015"]*)*")[^()<>@,;:".\\\[\]\x80-\xff\000-\010\012-\037]*(?:(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)|"[^\\\x80-\xff\n\015"]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015"]*)*")[^()<>@,;:".\\\[\]\x80-\xff\000-\010\012-\037]*)*<[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t]*)*(?:@[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t]*)*(?:[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff])|\[(?:[^\\\x80-\xff\n\015\[\]]|\\[^\x80-\xff])*\])[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t]*)*(?:\.[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t]*)*(?:[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff])|\[(?:[^\\\x80-\xff\n\015\[\]]|\\[^\x80-\xff])*\])[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t]*)*)*(?:,[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t]*)*@[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t]*)*(?:[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff])|\[(?:[^\\\x80-\xff\n\015\[\]]|\\[^\x80-\xff])*\])[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t]*)*(?:\.[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t]*)*(?:[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff])|\[(?:[^\\\x80-\xff\n\015\[\]]|\\[^\x80-\xff])*\])[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t]*)*)*)*:[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t]*)*)?(?:[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff])|"[^\\\x80-\xff\n\015"]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015"]*)*")[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t]*)*(?:\.[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t]*)*(?:[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff])|"[^\\\x80-\xff\n\015"]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015"]*)*")[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t]*)*)*@[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t]*)*(?:[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff])|\[(?:[^\\\x80-\xff\n\015\[\]]|\\[^\x80-\xff])*\])[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t]*)*(?:\.[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t]*)*(?:[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff])|\[(?:[^\\\x80-\xff\n\015\[\]]|\\[^\x80-\xff])*\])[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t]*)*)*>)$/) ) ? true : false;
       
   316 }
       
   317 
       
   318 /**
       
   319  * Validates a username.
       
   320  * @param string Username to test
       
   321  * @return bool
       
   322  */
       
   323 
       
   324 function validateUsername(username)
       
   325 {
       
   326   var regex = new RegExp('^[^<>&\?\'"%\n\r/]+$', '');
       
   327   return ( username.match(regex) ) ? true : false;
       
   328 }
       
   329 
       
   330 /**
       
   331  * Equivalent of PHP's time()
       
   332  * @return int
       
   333  */
       
   334 
       
   335 function unix_time()
       
   336 {
       
   337   return parseInt((new Date()).getTime()/1000);
       
   338 }
       
   339 
       
   340 /*
       
   341  * Utility functions, moved from windows.js
       
   342  */
       
   343  
       
   344 // getElementWidth() and getElementHeight()
       
   345 // Source: http://www.aspandjavascript.co.uk/javascript/javascript_api/get_element_width_height.asp
       
   346 
       
   347 function getElementHeight(Elem) {
       
   348   if (ns4) 
       
   349   {
       
   350     var elem = getObjNN4(document, Elem);
       
   351     return elem.clip.height;
       
   352   } 
       
   353   else
       
   354   {
       
   355     if(document.getElementById) 
       
   356     {
       
   357       var elem = document.getElementById(Elem);
       
   358     }
       
   359     else if (document.all)
       
   360     {
       
   361       var elem = document.all[Elem];
       
   362     }
       
   363     if (op5) 
       
   364     { 
       
   365       xPos = elem.style.pixelHeight;
       
   366     }
       
   367     else
       
   368     {
       
   369       xPos = elem.offsetHeight;
       
   370     }
       
   371     return xPos;
       
   372   } 
       
   373 }
       
   374 
       
   375 function getElementWidth(Elem) {
       
   376   if (ns4) {
       
   377     var elem = getObjNN4(document, Elem);
       
   378     return elem.clip.width;
       
   379   } else {
       
   380     if(document.getElementById) {
       
   381       var elem = document.getElementById(Elem);
       
   382     } else if (document.all){
       
   383       var elem = document.all[Elem];
       
   384     }
       
   385     if (op5) {
       
   386       xPos = elem.style.pixelWidth;
       
   387     } else {
       
   388       xPos = elem.offsetWidth;
       
   389     }
       
   390     return xPos;
       
   391   }
       
   392 }
       
   393 
       
   394 function getHeight() {
       
   395   var myHeight = 0;
       
   396   if( typeof( window.innerWidth ) == 'number' ) {
       
   397     myHeight = window.innerHeight;
       
   398   } else if( document.documentElement &&
       
   399       ( document.documentElement.clientWidth || document.documentElement.clientHeight ) ) {
       
   400     myHeight = document.documentElement.clientHeight;
       
   401   } else if( document.body && ( document.body.clientWidth || document.body.clientHeight ) ) {
       
   402     myHeight = document.body.clientHeight;
       
   403   }
       
   404   return myHeight;
       
   405 }
       
   406 
       
   407 function getWidth() {
       
   408   var myWidth = 0;
       
   409   if( typeof( window.innerWidth ) == 'number' ) {
       
   410     myWidth = window.innerWidth;
       
   411   } else if( document.documentElement &&
       
   412       ( document.documentElement.clientWidth || document.documentElement.clientWidth ) ) {
       
   413     myWidth = document.documentElement.clientWidth;
       
   414   } else if( document.body && ( document.body.clientWidth || document.body.clientWidth ) ) {
       
   415     myWidth = document.body.clientWidth;
       
   416   }
       
   417   return myWidth;
       
   418 }
       
   419 
       
   420 /**
       
   421  * Sanitizes a page URL string so that it can safely be stored in the database.
       
   422  * @param string Page ID to sanitize
       
   423  * @return string Cleaned text
       
   424  */
       
   425 
       
   426 function sanitize_page_id(page_id)
       
   427 {
       
   428   // Remove character escapes
       
   429   page_id = dirtify_page_id(page_id);
       
   430 
       
   431   var regex = new RegExp('[A-Za-z0-9\\[\\]\./:;\(\)@_-]', 'g');
       
   432   pid_clean = page_id.replace(regex, 'X');
       
   433   var pid_dirty = [];
       
   434   for ( var i = 0; i < pid_clean.length; i++ )
       
   435     pid_dirty[i] = pid_clean.substr(i, 1);
       
   436 
       
   437   for ( var i = 0; i < pid_dirty.length; i++ )
       
   438   {
       
   439     var chr = pid_dirty[i];
       
   440     if ( chr == 'X' )
       
   441       continue;
       
   442     var cid = chr.charCodeAt(0);
       
   443     cid = cid.toString(16).toUpperCase();
       
   444     if ( cid.length < 2 )
       
   445     {
       
   446       cid = '0' + cid;
       
   447     }
       
   448     pid_dirty[i] = "." + cid;
       
   449   }
       
   450   
       
   451   var pid_chars = [];
       
   452   for ( var i = 0; i < page_id.length; i++ )
       
   453     pid_chars[i] = page_id.substr(i, 1);
       
   454   
       
   455   var page_id_cleaned = '';
       
   456 
       
   457   for ( var id in pid_chars )
       
   458   {
       
   459     var chr = pid_chars[id];
       
   460     if ( pid_dirty[id] == 'X' )
       
   461       page_id_cleaned += chr;
       
   462     else
       
   463       page_id_cleaned += pid_dirty[id];
       
   464   }
       
   465   
       
   466   return page_id_cleaned;
       
   467 }
       
   468 
       
   469 /**
       
   470  * Removes character escapes in a page ID string
       
   471  * @param string Page ID string to dirty up
       
   472  * @return string
       
   473  */
       
   474 
       
   475 function dirtify_page_id(page_id)
       
   476 {
       
   477   // First, replace spaces with underscores
       
   478   page_id = page_id.replace(/ /g, '_');
       
   479 
       
   480   var matches = page_id.match(/\.[A-Fa-f0-9][A-Fa-f0-9]/g);
       
   481   
       
   482   if ( matches != null )
       
   483   {
       
   484     for ( var i = 0; i < matches.length; i++ )
       
   485     {
       
   486       var match = matches[i];
       
   487       var byt = (match.substr(1)).toUpperCase();
       
   488       var code = eval("0x" + byt);
       
   489       var regex = new RegExp('\\.' + byt, 'g');
       
   490       page_id = page_id.replace(regex, String.fromCharCode(code));
       
   491     }
       
   492   }
       
   493   
       
   494   return page_id;
       
   495 }
       
   496 
       
   497 /*
       
   498  * Expandable fieldsets
       
   499  */
       
   500 
       
   501 var expander_onload = function()
       
   502 {
       
   503   var sets = document.getElementsByTagName('fieldset');
       
   504   if ( sets.length < 1 )
       
   505     return false;
       
   506   var init_us = [];
       
   507   for ( var index = 0; index < sets.length; index++ )
       
   508   {
       
   509     var mode = sets[index].getAttribute('enano:expand');
       
   510     if ( mode == 'closed' || mode == 'open' )
       
   511     {
       
   512       init_us.push(sets[index]);
       
   513     }
       
   514   }
       
   515   for ( var k = 0; k < init_us.length; k++ )
       
   516   {
       
   517     expander_init_element(init_us[k]);
       
   518   }
       
   519 }
       
   520 
       
   521 function expander_init_element(el)
       
   522 {
       
   523   // get the legend tag
       
   524   var legend = el.getElementsByTagName('legend')[0];
       
   525   if ( !legend )
       
   526     return false;
       
   527   // existing content
       
   528   var existing_inner = legend.innerHTML;
       
   529   // blank the innerHTML and replace it with a link
       
   530   legend.innerHTML = '';
       
   531   var button = document.createElement('a');
       
   532   button.className = 'expander expander-open';
       
   533   button.innerHTML = existing_inner;
       
   534   button.href = '#';
       
   535   
       
   536   legend.appendChild(button);
       
   537   
       
   538   button.onclick = function()
       
   539   {
       
   540     try
       
   541     {
       
   542       expander_handle_click(this);
       
   543     }
       
   544     catch(e)
       
   545     {
       
   546       console.debug('Exception caught: ', e);
       
   547     }
       
   548     return false;
       
   549   }
       
   550   
       
   551   if ( el.getAttribute('enano:expand') == 'closed' )
       
   552   {
       
   553     expander_close(el);
       
   554   }
       
   555 }
       
   556 
       
   557 function expander_handle_click(el)
       
   558 {
       
   559   if ( el.parentNode.parentNode.tagName != 'FIELDSET' )
       
   560     return false;
       
   561   var parent = el.parentNode.parentNode;
       
   562   if ( parent.getAttribute('enano:expand') == 'closed' )
       
   563   {
       
   564     expander_open(parent);
       
   565   }
       
   566   else
       
   567   {
       
   568     expander_close(parent);
       
   569   }
       
   570 }
       
   571 
       
   572 function expander_close(el)
       
   573 {
       
   574   var children = el.childNodes;
       
   575   for ( var i = 0; i < children.length; i++ )
       
   576   {
       
   577     var child = children[i];
       
   578     if ( child.tagName == 'LEGEND' )
       
   579     {
       
   580       var a = child.getElementsByTagName('a')[0];
       
   581       $(a).rmClass('expander-open');
       
   582       $(a).addClass('expander-closed');
       
   583       continue;
       
   584     }
       
   585     if ( child.style )
       
   586     {
       
   587       child.expander_meta_old_state = child.style.display;
       
   588       child.style.display = 'none';
       
   589     }
       
   590   }
       
   591   el.expander_meta_padbak = el.style.padding;
       
   592   el.setAttribute('enano:expand', 'closed');
       
   593 }
       
   594 
       
   595 function expander_open(el)
       
   596 {
       
   597   var children = el.childNodes;
       
   598   for ( var i = 0; i < children.length; i++ )
       
   599   {
       
   600     var child = children[i];
       
   601     if ( child.tagName == 'LEGEND' )
       
   602     {
       
   603       var a = child.getElementsByTagName('a')[0];
       
   604       $(a).rmClass('expander-closed');
       
   605       $(a).addClass('expander-open');
       
   606       continue;
       
   607     }
       
   608     if ( child.expander_meta_old_state && child.style )
       
   609     {
       
   610       child.style.display = child.expander_meta_old_state;
       
   611       child.expander_meta_old_state = null;
       
   612     }
       
   613     else
       
   614     {
       
   615       if ( child.style )
       
   616       {
       
   617         child.style.display = null;
       
   618       }
       
   619     }
       
   620   }
       
   621   if ( el.expander_meta_padbak )
       
   622   {
       
   623     el.style.padding = el.expander_meta_padbak;
       
   624     el.expander_meta_padbak = null;
       
   625   }
       
   626   else
       
   627   {
       
   628     el.style.padding = null;
       
   629   }
       
   630   el.setAttribute('enano:expand', 'open');
       
   631 }
       
   632 
       
   633 /**
       
   634  * Equivalent to PHP's explode function.
       
   635  */
       
   636 
       
   637 function explode(needle, haystack)
       
   638 {
       
   639   return haystack.split(needle);
       
   640 }
       
   641 
       
   642 /**
       
   643  * Equivalent to PHP's in_array function.
       
   644  */
       
   645 
       
   646 function in_array(needle, haystack)
       
   647 {
       
   648   for(var i in haystack)
       
   649   {
       
   650     if(haystack[i] == needle) return i;
       
   651   }
       
   652   return false;
       
   653 }
       
   654 
       
   655 addOnloadHook(expander_onload);