--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/includes/clientside/static/dropdown.js Wed Jun 13 16:07:17 2007 -0400
@@ -0,0 +1,508 @@
+/*
+ * The jBox menu system. Written by Dan Fuhry and licensed under the GPL.
+ */
+
+// Cache of DOM and event objects, used in setTimeout() calls due to scope rules
+var jBoxObjCache = new Object();
+
+// Cache of "correct" heights for unordered list objects used in submenus. Helps the animation routine know what height it's aiming for.
+var jBoxMenuHeights = new Object();
+
+// Blocks animations from running if there's already an animation going on the same object
+var jBoxSlideBlocker = new Object();
+
+// Speed at which the menus should slide open. 1 to 100 or -1 to disable.
+// Setting this higher than 100 will cause an infinite loop in the browser.
+// Default is 80 - anything higher than 90 means exponential speed increase
+var slide_speed = 80;
+
+// Inertia value to start with
+// Default is 0
+var inertia_base = 0;
+
+// Value added to inertia_base on each frame - generally 1 to 3 is good, with 1 being slowest animation
+// Default is 1
+var inertia_inc = 1;
+
+// Opacity that menus should fade to. 1 to 100 or -1 to disable fades. This only works if the slide effect is also enabled.
+// Default is 100
+var jBox_opacity = 100;
+
+// Adds the jBox CSS to the HTML header. Called on window onload.
+function jBoxInit()
+{
+ setTimeout('jBoxBatchSetup();', 200);
+}
+
+// Initializes each menu.
+function jBoxBatchSetup()
+{
+ var menus = document.getElementsByClassName('div', 'menu_nojs');
+ if ( menus.length > 0 )
+ {
+ for ( var i in menus )
+ {
+ if ( typeof(menus[i]) != 'object')
+ continue; // toJSONString() compatibility
+ jBoxSetup(menus[i]);
+ }
+ }
+}
+
+// Initializes a div with a jBox menu in it.
+function jBoxSetup(obj)
+{
+ $(obj).addClass('menu');
+ removeTextNodes(obj);
+ for ( var i in obj.childNodes )
+ {
+ /* normally this would be done in about 2 lines of code, but javascript is so picky..... */
+ if ( obj.childNodes[i] )
+ {
+ if ( obj.childNodes[i].tagName )
+ {
+ if ( obj.childNodes[i].tagName.toLowerCase() == 'a' )
+ {
+ if ( obj.childNodes[i].nextSibling.tagName )
+ {
+ if ( obj.childNodes[i].nextSibling.tagName.toLowerCase() == 'ul' || ( obj.childNodes[i].nextSibling.tagName.toLowerCase() == 'div' && obj.childNodes[i].nextSibling.className == 'submenu' ) )
+ {
+ // Calculate height
+ var ul = obj.childNodes[i].nextSibling;
+ domObjChangeOpac(0, ul);
+ ul.style.display = 'block';
+ var dim = fetch_dimensions(ul);
+ if ( !ul.id )
+ ul.id = 'jBoxmenuobj_' + Math.floor(Math.random() * 10000000);
+ jBoxMenuHeights[ul.id] = parseInt(dim['h']) - 2; // subtract 2px for border width
+ ul.style.display = 'none';
+ domObjChangeOpac(100, ul);
+
+ // Setup events
+ obj.childNodes[i].onmouseover = function() { jBoxOverHandler(this); };
+ obj.childNodes[i].onmouseout = function(e) { jBoxOutHandler(this, e); };
+ obj.childNodes[i].nextSibling.onmouseout = function(e) { jBoxOutHandler(this, e); };
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+// Called when user hovers mouse over a submenu
+function jBoxOverHandler(obj)
+{
+ // Random ID used to track the object to perform on
+ var seed = Math.floor(Math.random() * 1000000);
+ jBoxObjCache[seed] = obj;
+
+ // Sleep for a (little more than a tenth of a) second to see if the user really wants the menu to expand
+ setTimeout('if(isOverObj(jBoxObjCache['+seed+'], false, false)) jBoxOverHandlerBin(jBoxObjCache['+seed+']);', 150);
+}
+
+// Displays a menu.
+function jBoxOverHandlerBin(obj)
+{
+ var others = obj.parentNode.getElementsByTagName('ul');
+ for ( var i in others )
+ {
+ if(typeof(others[i]) == 'object')
+ {
+ others[i].style.display = 'none';
+ others[i].previousSibling.className = '';
+ }
+ }
+ var others = obj.parentNode.getElementsByTagName('div');
+ for ( var i in others )
+ {
+ if(typeof(others[i]) == 'object')
+ {
+ if ( others[i].className == 'submenu' )
+ {
+ others[i].style.display = 'none';
+ others[i].previousSibling.className = '';
+ }
+ }
+ }
+ if(obj.nextSibling.tagName.toLowerCase() == 'ul' || ( obj.nextSibling.tagName.toLowerCase() == 'div' && obj.nextSibling.className == 'submenu' ))
+ {
+ obj.className = 'liteselected';
+ var ul = obj.nextSibling;
+ var dim = fetch_dimensions(obj);
+ var off = fetch_offset(obj);
+ var dimh = parseInt(dim['h']);
+ var offtop = parseInt(off['top']);
+ var top = dimh + offtop;
+ left = off['left'];
+ ul.style.left = left + 'px';
+ ul.style.top = top + 'px';
+ domObjChangeOpac(0, ul);
+ ul.style.clip = 'rect(auto,auto,auto,auto)';
+ ul.style.overflow = 'visible';
+ ul.style.display = 'block';
+ slideOut(ul);
+ }
+}
+
+function jBoxOutHandler(obj, event)
+{
+ var seed = Math.floor(Math.random() * 1000000);
+ var seed2 = Math.floor(Math.random() * 1000000);
+ jBoxObjCache[seed] = obj;
+ jBoxObjCache[seed2] = event;
+ setTimeout('jBoxOutHandlerBin(jBoxObjCache['+seed+'], jBoxObjCache['+seed2+']);', 750);
+}
+
+function jBoxOutHandlerBin(obj, event)
+{
+ var caller = obj.tagName.toLowerCase();
+ if(caller == 'a')
+ {
+ a = obj;
+ ul = obj.nextSibling;
+ }
+ else if(caller == 'ul' || caller == 'div')
+ {
+ a = obj.previousSibling;
+ ul = obj;
+ }
+ else
+ {
+ return false;
+ }
+
+ if (!isOverObj(a, false, event) && !isOverObj(ul, true, event))
+ {
+ a.className = '';
+
+ slideIn(ul);
+
+ }
+
+ return true;
+}
+
+// Slide an element downwards until it is at full height.
+// First parameter should be a DOM object with style.display = block and opacity = 0.
+
+var sliderobj = new Object();
+
+function slideOut(obj)
+{
+ if ( jBoxSlideBlocker[obj.id] )
+ return false;
+
+ jBoxSlideBlocker[obj.id] = true;
+
+ if ( slide_speed == -1 )
+ {
+ obj.style.display = 'block';
+ return false;
+ }
+
+ var currentheight = 0;
+ var targetheight = jBoxMenuHeights[obj.id];
+ var inertiabase = inertia_base;
+ var inertiainc = inertia_inc;
+ slideStep(obj, 0);
+ domObjChangeOpac(100, obj);
+ obj.style.overflow = 'hidden';
+
+ // Don't edit past here
+ var timercnt = 0;
+
+ var seed = Math.floor(Math.random() * 1000000);
+ sliderobj[seed] = obj;
+
+ var framecnt = 0;
+
+ while(true)
+ {
+ framecnt++;
+ timercnt += ( 100 - slide_speed );
+ inertiabase += inertiainc;
+ currentheight += inertiabase;
+ if ( currentheight > targetheight )
+ currentheight = targetheight;
+ setTimeout('slideStep(sliderobj['+seed+'], '+currentheight+', '+targetheight+');', timercnt);
+ if ( currentheight >= targetheight )
+ break;
+ }
+ timercnt = timercnt + ( 100 - slide_speed );
+ setTimeout('jBoxSlideBlocker[sliderobj['+seed+'].id] = false;', timercnt);
+ var opacstep = jBox_opacity / framecnt;
+ var opac = 0;
+ var timerstep = 0;
+ domObjChangeOpac(0, obj);
+ while(true)
+ {
+ timerstep += ( 100 - slide_speed );
+ opac += opacstep;
+ setTimeout('domObjChangeOpac('+opac+', sliderobj['+seed+']);', timerstep);
+ if ( opac >= jBox_opacity )
+ break;
+ }
+}
+
+function slideIn(obj)
+{
+ if ( obj.style.display != 'block' )
+ return false;
+
+ if ( jBoxSlideBlocker[obj.id] )
+ return false;
+
+ jBoxSlideBlocker[obj.id] = true;
+
+ var targetheight = 0;
+ var dim = fetch_dimensions(obj);
+ var currentheight = jBoxMenuHeights[obj.id];
+ var origheight = currentheight;
+ var inertiabase = inertia_base;
+ var inertiainc = inertia_inc;
+ domObjChangeOpac(100, obj);
+ obj.style.overflow = 'hidden';
+
+ // Don't edit past here
+ var timercnt = 0;
+
+ var seed = Math.floor(Math.random() * 1000000);
+ sliderobj[seed] = obj;
+
+ var framecnt = 0;
+
+ for(var j = 0;j<100;j++) // while(true)
+ {
+ framecnt++;
+ timercnt = timercnt + ( 100 - slide_speed );
+ inertiabase = inertiabase + inertiainc;
+ currentheight = currentheight - inertiabase;
+ if ( currentheight < targetheight )
+ currentheight = targetheight;
+ setTimeout('slideStep(sliderobj['+seed+'], '+currentheight+');', timercnt);
+ if ( currentheight <= targetheight )
+ break;
+ }
+ timercnt += ( 100 - slide_speed );
+ setTimeout('sliderobj['+seed+'].style.display="none";sliderobj['+seed+'].style.height="'+origheight+'px";jBoxSlideBlocker[sliderobj['+seed+'].id] = false;', timercnt);
+
+ var opacstep = jBox_opacity / framecnt;
+ var opac = jBox_opacity;
+ var timerstep = 0;
+ domObjChangeOpac(100, obj);
+ while(true)
+ {
+ timerstep += ( 100 - slide_speed );
+ opac -= opacstep;
+ setTimeout('domObjChangeOpac('+opac+', sliderobj['+seed+']);', timerstep);
+ if ( opac <= 0 )
+ break;
+ }
+
+}
+
+function slideStep(obj, height, maxheight)
+{
+ obj.style.height = height + 'px';
+ //obj.style.clip = 'rect(3px,auto,'+maxheight+'px,auto)';
+ obj.style.overflow = 'hidden';
+ //obj.style.clip = 'rect('+height+'px,0px,'+maxheight+'px,auto);';
+}
+
+function isOverObj(obj, bias, event)
+{
+ var fieldUL = new Object();
+ var dim = fetch_dimensions(obj);
+ var off = fetch_offset(obj);
+ fieldUL['top'] = off['top'];
+ fieldUL['left'] = off['left'];
+ fieldUL['right'] = off['left'] + dim['w'];
+ fieldUL['bottom'] = off['top'] + dim['h'];
+
+ //document.getElementById('debug').innerHTML = '<br /><br /><br /><br /><br />Mouse: x: '+mouseX+', y:' + mouseY + '<br />'; // + document.getElementById('debug').innerHTML;
+
+ if(bias)
+ {
+ if ( ( mouseX < fieldUL['left'] + 2 || mouseX > fieldUL['right'] - 5 ) ||
+ ( mouseY < fieldUL['top'] - 2 || mouseY > fieldUL['bottom'] - 2 ) )
+ {
+ return false;
+ }
+ }
+ else
+ {
+ if ( ( mouseX < fieldUL['left'] || mouseX > fieldUL['right'] ) ||
+ ( mouseY < fieldUL['top'] || mouseY > fieldUL['bottom'] ) )
+ return false;
+ }
+
+ return true;
+
+ /*
+ var tgt = event.target;
+ if ( !tgt )
+ return false;
+ do {
+ if ( tgt == obj )
+ return true;
+ tgt = tgt.parentNode;
+ } while (tgt.tagName.toLowerCase() != 'body' );
+ return false;
+ */
+}
+
+function jBoxGarbageCollection(e)
+{
+ setMousePos(e);
+ var menus = document.getElementsByClassName('div', 'menu');
+ if ( menus.length > 0 )
+ {
+ for ( var i in menus )
+ {
+ if ( typeof(menus[i]) != 'object')
+ continue; // toJSONString() compatibility
+ var uls = menus[i].getElementsByTagName('ul');
+ if ( uls.length > 0 )
+ {
+ for ( var j = 0; j < uls.length; j++ )
+ {
+ if ( !isOverObj(uls[j], false, e) )
+ {
+ uls[j].previousSibling.className = '';
+ //uls[j].style.display = 'none';
+ slideIn(uls[j]);
+ }
+ }
+ }
+ var uls = getElementsByClassName(menus[i], 'divs', 'submenu');
+ if ( uls.length > 0 )
+ {
+ for ( var j = 0; j < uls.length; j++ )
+ {
+ if ( !isOverObj(uls[j], false, e) )
+ {
+ uls[j].previousSibling.className = '';
+ //uls[j].style.display = 'none';
+ slideIn(uls[j]);
+ }
+ }
+ }
+ }
+ }
+}
+
+document.onclick = jBoxGarbageCollection;
+
+function removeTextNodes(obj)
+{
+ if(obj)
+ {
+ if(typeof(obj.tagName) != 'string')
+ {
+ if ( obj.nodeType == 3 && obj.data.match(/^([\s]*)$/ig) )
+ {
+ obj.parentNode.removeChild(obj);
+ return;
+ }
+ }
+ if(obj.firstChild)
+ {
+ for(var i in obj.childNodes)
+ {
+ removeTextNodes(obj.childNodes[i]);
+ }
+ }
+ }
+}
+
+var getElementsByClassName = function(parent, type, cls) {
+ if(!type)
+ type = '*';
+ ret = new Array();
+ el = parent.getElementsByTagName(type);
+ for ( var i in el )
+ {
+ if ( typeof(el[i]) != 'object')
+ continue; // toJSONString() compatibility
+ if(el[i].className)
+ {
+ if(el[i].className.indexOf(' ') > 0)
+ {
+ classes = el[i].className.split(' ');
+ }
+ else
+ {
+ classes = new Array();
+ classes.push(el[i].className);
+ }
+ if ( in_array(cls, classes) )
+ ret.push(el[i]);
+ }
+ }
+ return ret;
+}
+
+document.getElementsByClassName = function(type, cls) {
+ return getElementsByClassName(document, type, cls);
+}
+
+function setMousePos(event)
+{
+ if(IE)
+ {
+ if(!event)
+ {
+ event = window.event;
+ }
+ clX = event.clientX;
+ sL = document.body.scrollLeft;
+ mouseX = clX + sL;
+ mouseY = event.clientY + document.body.scrollTop;
+ return;
+ }
+ if( typeof(event.clientX) == 'number' )
+ {
+ mouseX = event.clientX;
+ mouseY = event.clientY;
+ return;
+ }
+ else if( typeof(event.layerX) == 'number' )
+ {
+ mouseX = event.layerX;
+ mouseY = event.layerY;
+ return;
+ }
+ else if( typeof(event.offsetX) == 'number' )
+ {
+ mouseX = event.offsetX;
+ mouseY = event.offsetY;
+ return;
+ }
+ else if( typeof(event.screenX) == 'number' )
+ {
+ mouseX = event.screenX;
+ mouseY = event.screenY;
+ return;
+ }
+ else if( typeof(event.x) == 'number' )
+ {
+ mouseX = event.x;
+ mouseY = event.y;
+ return;
+ }
+}
+
+document.onmousemove = function(e)
+{
+ setMousePos(e);
+};
+
+function domObjChangeOpac(opacity, id) {
+ var object = id.style;
+ object.opacity = (opacity / 100);
+ object.MozOpacity = (opacity / 100);
+ object.KhtmlOpacity = (opacity / 100);
+ object.filter = "alpha(opacity=" + opacity + ")";
+}
+