/** Animated TreeMenu script by Garrett Smith * * URL:http://dhtmlkitchen.com/ * email:admin@dhtmlkitchen.com * * Usage: see http://dhtmlkitchen.com/ * * [11/29/02] * TreeGlobals.browser has been replaced with * Browser utils.js */ TreeGlobals = { // don't change inited : false }; if(typeof window.TreeParams == "undefined") TreeParams = { // You will probably have to change these. /** TreeParams: * OPEN_MULTIPLE_MENUS -- Boolean. * if true, more than one menu can * be open at a time. Otherwise, * opening a new menu closes any * open menu. * * * * TIME_DELAY -- int. * How slowly a menuNode collapses * in milliseconds. (0 to 100). * * OPEN_WHILE_CLOSING -- Boolean. * If either OPEN_MULTIPLE_MENUS or * OPEN_WHILE_CLOSING will simultaneously * open a new menu while closing the * currently open menu. */ OPEN_MULTIPLE_MENUS : false, TIME_DELAY : 10, OPEN_WHILE_CLOSING : true, OPEN_MENU_ICON : "../images/open-menu.gif", CLOSED_MENU_ICON : "../images/closed-menu.gif" }; // Unless you really know what you are doing, // don't change anything below this line! //_________________________________________________________________________ /////////////////////////////////////////////////////////////////////////// function toggleMenu(el) { if(Browser.id.OP5 || Browser.id.NS4) return; var label = TreeFunctions.getLabel(el); if(label.menu.blocked) return; if(label.menu.container.menuToOpen != null) return; if(label.isDepressed) { if (TreeParams.OPEN_MULTIPLE_MENUS || label.menu.container.activeMenu == label.menu) { TreeFunctions.closeMenu(label.menu); label.menu.container.activeMenu = null; } } else{ // push it in. if(label.icon != null) label.icon.src = TreeParams.OPEN_MENU_ICON; label.menu.container.menuToOpen = label.menu; if(TreeParams.OPEN_MULTIPLE_MENUS || label.menu.container.activeMenu == null ) { TreeFunctions.openMenu(label.menu); } else { TreeFunctions.closeMenu(label.menu.container.activeMenu); if(TreeParams.OPEN_WHILE_CLOSING) TreeFunctions.openMenu(label.menu); else label.menu.container.activeMenu.menuInCue = label.menu; } label.menu.container.activeMenu = label.menu; } } /** Opens a menu. * Usually called with body onload handler. */ function activateMenu(sButtonId){ if(!window.toggleMenu || Browser.id.OP5) return; var button = document.getElementById(sButtonId); if(!button) return; var parentMenuEl = findAncestorWithClass(button, "menu"); if(parentMenuEl != null){ var bId = parentMenuEl.id.substring(0, parentMenuEl.id.indexOf("Menu")); activateMenu(bId); } var label = TreeFunctions.getLabel(getElementsWithClass(button, "*", "buttonlabel")[0]); if(!label.isDepressed) toggleMenu(label.el); } /** Button mouseover event handler. * Called with onmouseover handler. */ function buttonOver(el){ window.status = el.parentNode.id; label = TreeFunctions.getLabel(el); if(hasToken(label.el.className, "labelHover")) return; label.el.className += " labelHover"; } /** Button mouseover event handler. * Called with onmouseout handler. */ function buttonOff(label){ window.status = window.defaultStatus; removeClass(label, "labelHover"); } if(typeof document.getElementsByTagName == "undefined" || Browser.id.OP5) buttonOver = buttonOff = function(){}; /** Button constructor to be used privately. */ Button = function(el, category){ this.el = el; this.category = category; this.menu = new Menu(document.getElementById(this.category +"Menu"), this); var icons = el.getElementsByTagName("img"); this.icon = (icons.length > 0) ? icons[0] : null; this.isIcon = false; if(el.tagName == "IMG"){ this.isIcon = true; this.icon = el; } this.isDepressed = false; }; /** Menu constructor to be used privately. */ Menu = function(el, label) { this.ownerButton = label; this.id = label.category; // a short-cut reference to this.ownerButton.category. this.el = el; this.items = getChildNodesWithClass(el, "menuNode"); this.allItems = getElementsWithClass(el, "*", "menuNode"); this.cur = 0; this.blocked = false; this._root = null; // look for ancestor with class menu. // get that element's id minus "Menu" this.container = this.getContainer(); this.menuToOpen = null; this.activeMenu = null; this.menuInCue = null; }; /** Stupid debug function. */ function debug(s, obj){ var rv = ""; for(var x in obj) rv += s+"."+x+ " = "+ obj[x]; document.write(""+rv); } Menu.prototype = { open : function(){ this.itemsToOpen[this.cur].style.display = "block"; if(++this.cur == this.itemsToOpen.length) this.performActionEnd("block"); }, close : function(){ this.itemsToClose[this.cur].style.display = "none"; if(++this.cur == this.itemsToClose.length) this.performActionEnd("none"); }, performActionEnd : function(sDisplay) { this.el.style.display = sDisplay; this.performActionTimer = clearInterval(this.performActionTimer); if(sDisplay=='block') this.container.menuToOpen = null; else { TreeFunctions.setDefaultLabel(this.ownerButton); if(!TreeParams.OPEN_WHILE_CLOSING && this.menuInCue != null) TreeFunctions.openMenu(this.menuInCue); this.menuInCue = null; } // if(this._root.activeMenu) // setTimeout("repaintFix(TreeList[\""+this._root.id+"\"].activeMenu.el)", 50); this.blocked = false; }, root : function(){ if(this._root == null) { var rt = findAncestorWithClass(this.el, "AnimTree"); if(rt == null) rt = document.body; if(!rt.id) rt.id = "AnimTree_"+ Math.round(Math.random() * 100); if(TreeList[rt.id] != null){ this._root = TreeList[rt.id]; this._root.menus[this.id] = this; } else this._root = new Tree(rt, this); } return this._root; }, getContainer : function(){ var root = this.root(); var parentMenuElement = findAncestorWithClass(this.el,"menu"); if(parentMenuElement != null) return root.menus[parentMenuElement.id.replace(/Menu$/,"")]; return root; } }; /** Tree constructor to be used privately. */ Tree = function(el, menu) { this.el = el; this.activeMenu = null; this.menus[menu.id] = menu; this.menuToOpen = null; this.id = el.id; TreeList[this.id] = this; }; Tree.prototype.menus = new Object(); TreeList = {}; TreeFunctions = { /** TreeFunctions: * getLabel(el) -- called the very first time a buttonlabel is clicked or moused-over. * initMenu -- sets .menu and .menuNode to "display : none". * openMenu -- opens a menu. * closeMenu -- closes a menu. * setDefaultLabel -- sets the label to normal state. Called by toggleButton -> * closeMenu -> menu.performActionEnd -> setDefaultLabel * */ getLabel : function(el) { var m = findAncestorWithClass(el,"button"); var menuName = m.id; var b; for(var tree in TreeList) if(TreeList[tree].menus[menuName] != null) return TreeList[tree].menus[menuName].ownerButton; return new Button(el, menuName); }, initMenu : function(){ if(document.getElementById && !Browser.id.OP5 && !TreeGlobals.inited){ document.writeln("<style type='text/css'>", "/* <![CDATA[ */\n", ".menu, .menuNode{display: none;}\n", "/* ]]> */", "<"+"/style>"); TreeGlobals.inited = true; } }, openMenu : function(menu){ // because menuToOpen may change. menu.blocked = true; menu.cur = 0; menu.itemsToOpen = new Array(); menu.el.style.display = "block"; // if itemsToClose does not exist, the menu has not been closed. if(menu.itemsToClose && menu.itemsToClose.length > menu.items.length) menu.itemsToOpen = menu.itemsToClose.reverse(); else menu.itemsToOpen = menu.items; if(!menu.ownerButton.isIcon) menu.ownerButton.el.className += " labelDown"; if(menu.itemsToOpen.length == 0) menu.itemsToOpen[0] = menu.el; menu.performActionTimer = setInterval( "TreeList."+menu.root().id+".menus." + menu.id +".open()", TreeParams.TIME_DELAY); menu.ownerButton.isDepressed = true; }, closeMenu : function(menu) { menu.blocked = true; menu.cur = 0; menu.itemsToClose = new Array(); for(var i = menu.allItems.length-1,counter = 0; i > 0; i--) if(menu.allItems[i].style.display == "block") menu.itemsToClose[counter++] = menu.allItems[i]; menu.itemsToClose[menu.itemsToClose.length] = menu.el; menu.performActionTimer = setInterval( "TreeList."+menu.root().id+".menus." + menu.id +".close()", TreeParams.TIME_DELAY); menu.ownerButton.isDepressed = false; }, setDefaultLabel : function(button){ if(button.isIcon) return void( button.icon.src = TreeParams.CLOSED_MENU_ICON); removeClass(button.el, "labelHover"); removeClass(button.el, "labelDown"); if(button.icon != null) button.icon.src = TreeParams.CLOSED_MENU_ICON; } }; TreeFunctions.initMenu();