// Copyright 1999 Microsoft Corporation. All rights reserved. // Author: Steve Isaac, Microsoft Corporation // // DHTML Toolbar Package // // This file (along with the companion toolbars.css file) implements full featured // toolbars completely in DHTML. // // See tutorial.htm in the Doc directory for full info on how to use this package. // // //================================================================================================= // // Public Style Classes // -------------------- // tbToolbar: Toolbar // tbButton: Toolbar button // tbIcon: Toolbar or menu icon // tbSeparator: Toolbar or menu separator // tbMenu: Pulldown menu // tbMenuItem: Menu item // tbSubmenu: Submenu // tbGeneral: Arbitrary HTML element in a toolbar. // tbContentElement: Identifies an HTML element as the page body. One and only one // element on the page must have this class. The element must also have // its ID set to "tbContentElement". // // Public Attributes // ----------------- // TBTYPE: Special type of element. Possible values are: // Elements: toggle // radio // - Simple button // // Toolbars: noMouseOver // - Mouseover supported // // TBSTATE: State of the element. Possible values are: // Elements: gray (Disabled) // checked // unchecked // // Toolbars: dockedTop // dockedBottom // hidden // // tbOnMenuShow: Event handler that is called immediately prior to showing a menu or // submenu. Hosts use this to set the state of menu items. This attribute can either // be set on individual menus and submenus, or on a toolbar in which case it is // fired for every menu and submenu within that toolbar. The menu that is about // to be shown is given in tbEventSrcElement (see below). // // Public Functions // ---------------- // TBSetState(element, newState) // Sets the state of an element. // element: element to set. This is an object. // newState: state to set. This is a string, same values as TBSTATE. // // TBRebuildToolbar(toolbar, rebuildMenus) // Use this routine to change the contents of a toolbar on the fly. Make all changes // (adding, removing and modifying toolbar elements), then call this routine once. // This routine can also be used to add an entirely new toolbar. // toolbar: toolbar to rebuild. This is an object. // rebuildMenus: Should the menus in this toolbar also be rebuilt? Only set this // to true if there have been changes; its an expensive operation. // // TBRebuildMenu(menu, rebuildSubmenus) // Use this routine to change the contents of a menu or a submenu on the fly. Make all changes // (adding, removing and modifying menu items), then call this routine once. // menu: menu to rebuild. This is an object. // rebuildSubmenus: Should the submenus also be rebuilt? Only set this // to true if there have been changes; its expensive. // // Public Globals // -------------- // tbEventSrcElement: Contains the element that an event was fired on. The toolbar // package doesn't support the event object; this object performs a similar function. var tbEventSrcElement; // // Public Error Return Values // -------------------------- TB_STS_OK = "OK" // Success return TB_E_INVALID_CLASS = "Invalid class value" // An element has an unrecognized class attribute (probably a misspelling) TB_E_INVALID_TYPE = "Invalid TBTYPE value" TB_E_INVALID_STATE = "Invalid TBSTATE value" TB_E_NO_ID = "Element does not have an ID" // //================================================================================================= // // Private Attributes // ------------------ // TBTOOLBARWIDTH: Width of the toolbar (in px) // TBUSERONCLICK: Temporary storage of an element's original onclick handler // // Private Constants. These can be used along with toolbar.css to change the look of the toolbar package. // ----------------- TB_DISABLED_OPACITY_FILTER = "alpha(opacity=25)" TB_HANDLE_WIDTH = 10 TB_HANDLE = '
' + '
' TB_TOOLBAR_PADDING = 4 TB_SEPARATOR_PADDING = 5 TB_CLIENT_AREA_GAP = 0 // // Private Globals // --------------- var TBInitialized = false; // Set to true when the package has initialized. var tbToolbars = new Array(); // Array of all toolbars. var tbContentElementObject = null; // Content element. var tbContentElementTop = 0; // Y pixel coordinate of the top of the content element. var tbContentElementBottom = 0; // Y pixel coordinate of the bottom of the content element. var tbLastHeight = 0; // Previous client window height (before resize in process). var tbLastWidth = 0; // Previous client window width. var tbRaisedElement = null; // Current toolbar button that is being shown raised. var tbOnClickInProcess; // Executing user's onClick event. var tbMouseOutWhileInOnClick; // An onmouseout event occurred while executing the user's onClick event. // // Functions // // Public function for changing an element's state. function TBSetState(element, newState) { newState = newState.toLowerCase(); switch (element.className) { case "tbToolbar" : if ((newState != "dockedtop") && (newState != "dockedbottom") && (newState != "hidden")) { return TB_E_INVALID_STATE; } element.TBSTATE = newState; if (newState == "hidden") { element.style.visibility = "hidden"; } else { element.style.visibility = "visible"; } TBLayoutToolbars(); TBLayoutBodyElement(); break; case "tbButton" : case "tbButtonDown" : case "tbButtonMouseOverUp" : case "tbButtonMouseOverDown" : case "tbMenuItem" : if ((newState != "gray") && (newState != "checked") && (newState != "unchecked")) { return TB_E_INVALID_STATE; } currentState = element.TBSTATE; if (currentState == "") { currentState = "checked"; } if (newState == currentState) { return; } if (element.className != "tbMenuItem") { image = element.children.tags("IMG")[0]; // Going into disabled state if (newState == "gray") { element.className = "tbButton"; image.className = "tbIcon"; element.style.filter = TB_DISABLED_OPACITY_FILTER; } // Coming out of disabled state. Remove disabled look. if (currentState == "gray") { element.style.filter = ""; } if (newState == "checked") { element.className = "tbButtonDown"; image.className = "tbIconDown"; } else { //unchecked element.className = "tbButton"; image.className = "tbIcon"; } } if ((element.TBTYPE == "radio") && (newState == "checked")) { radioButtons = element.parentElement.children; for (i=0; i"); return TB_E_INVALID_CLASS; } } return TB_STS_OK; } // TBPopulateToolbar // Initialize a toolbar. function TBInitToolbar(tb) { var s1, tr; // Set up toolbar attributes if (tb.TBSTATE) { tb.TBSTATE = tb.TBSTATE.toLowerCase(); if ((tb.TBSTATE != "dockedtop") && (tb.TBSTATE != "dockedbottom") && (tb.TBSTATE != "hidden")) { return TB_E_INVALID_STATE; } } else { tb.TBSTATE = "dockedtop"; } if (tb.TBSTATE == "hidden") { tb.style.visibility = "hidden"; } if (tb.TBTYPE) { tb.TBTYPE = tb.TBTYPE.toLowerCase(); if (tb.TBTYPE != "nomouseover") { return TB_E_INVALID_TYPE; } } // Set initial size of toolbar to that of the handle tb.TBTOOLBARWIDTH = TB_HANDLE_WIDTH; // Populate the toolbar with its contents if ((s = TBPopulateToolbar(tb)) != TB_STS_OK) { return s; } // Set the toolbar width and put in the handle tb.style.posWidth = tb.TBTOOLBARWIDTH + TB_TOOLBAR_PADDING; tb.insertAdjacentHTML("AfterBegin", TB_HANDLE); return TB_STS_OK; } // TBInitToolbar // Lay out the docked toolbars function TBLayoutToolbars() { var x,y,i; x = 0; y = 0; // If no toolbars we're outta here if (tbToolbars.length == 0) { return; } // Lay out any dockedTop toolbars for (i=0; i 0) && (x + parseInt(tbToolbars[i].TBTOOLBARWIDTH) > document.body.offsetWidth)) { x=0; y += tbToolbars[i].offsetHeight; } tbToolbars[i].style.left = x; x += parseInt(tbToolbars[i].TBTOOLBARWIDTH) + TB_TOOLBAR_PADDING; tbToolbars[i].style.posTop = y; } } // Adjust the top of the bodyElement if there were dockedTop toolbars if ((x != 0) || (y !=0)) { tbContentElementTop = y + tbToolbars[0].offsetHeight + TB_CLIENT_AREA_GAP; } // Lay out any dockedBottom toolbars x = 0; y = document.body.clientHeight - tbToolbars[0].offsetHeight; for (i=tbToolbars.length - 1; i>=0; i--) { if (tbToolbars[i].TBSTATE == "dockedbottom") { if ((x > 0) && (x + parseInt(tbToolbars[i].TBTOOLBARWIDTH) > document.body.offsetWidth)) { x=0; y -= tbToolbars[i].offsetHeight; } tbToolbars[i].style.left = x; x += parseInt(tbToolbars[i].TBTOOLBARWIDTH) + TB_TOOLBAR_PADDING; tbToolbars[i].style.posTop = y; } } // Adjust the bottom of the bodyElement if there were dockedBottom toolbars if ((x != 0) || (y != (document.body.offsetHeight - tbToolbars[0].offsetHeight))) { tbContentElementBottom = document.body.offsetHeight - y + TB_CLIENT_AREA_GAP; } tbLastHeight = 0; tbLastWidth = 0; } // TBLayoutToolbars // Adjust the position and size of the body element and the bottom and right docked toolbars. function TBLayoutBodyElement() { tbContentElementObject.style.posTop = tbContentElementTop; tbContentElementObject.style.left = 0; tbContentElementObject.style.posHeight = document.body.offsetHeight - tbContentElementBottom - tbContentElementTop; tbContentElementObject.style.width = document.body.offsetWidth; // Update y position of any dockedBottom toolbars if (tbLastHeight != 0) { for (i=tbToolbars.length - 1; i>=0; i--) { if (tbToolbars[i].TBSTATE == "dockedbottom" && tbToolbars[i].style.visibility != "hidden") { tbToolbars[i].style.posTop += document.body.offsetHeight - tbLastHeight; } } } tbLastHeight = document.body.offsetHeight; tbLastWidth = document.body.offsetWidth; } // TBLayoutBodyElement // Initialize everything when the document is ready function document.onreadystatechange() { var i, s; if (TBInitialized) { return; } TBInitialized = true; document.body.scroll = "no"; // Add a that we will use this to measure the contents of menus if (typeof(tbMenu) != "undefined") { document.body.insertAdjacentHTML("BeforeEnd", ""); } // Find all the toolbars and initialize them. for (i=0; i TBContentElementMouseOver(); '); } // Rebuild toolbar; call after inserting or deleting items on toolbar. function TBRebuildToolbar(toolbar, rebuildMenus) { var toolbarFound = false; // Add a that we will use this to measure the contents of menus if (typeof(tbMenu) != "undefined") { document.body.insertAdjacentHTML("BeforeEnd", ""); } // Look through existing toolbars and see if we get a match for (i=0; i