Index: openacs-4/packages/ajaxhelper/www/resources/yui/menu/menu-debug.js =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ajaxhelper/www/resources/yui/menu/menu-debug.js,v diff -u -r1.1 -r1.2 --- openacs-4/packages/ajaxhelper/www/resources/yui/menu/menu-debug.js 21 Oct 2006 06:14:59 -0000 1.1 +++ openacs-4/packages/ajaxhelper/www/resources/yui/menu/menu-debug.js 25 Dec 2006 16:40:03 -0000 1.2 @@ -2,169 +2,249 @@ Copyright (c) 2006, Yahoo! Inc. All rights reserved. Code licensed under the BSD License: http://developer.yahoo.com/yui/license.txt -Version: 0.11.3 +version: 0.12.1 */ /** -* @class The superclass of all menu containers. -* @constructor -* @extends YAHOO.widget.Overlay -* @base YAHOO.widget.Overlay -* @param {String or HTMLElement} p_oElement String id or HTMLElement -* (either HTMLSelectElement or HTMLDivElement) of the source HTMLElement node. -* @param {Object} p_oConfig Optional. The configuration object literal -* containing the configuration for a MenuModule instance. See -* configuration class documentation for more details. +* @module menu +* @description

The Menu Library features a collection of widgets that make +* it easy to add menus to your website or web application. With the Menu +* Library you can create website fly-out menus, customized context menus, or +* application-style menu bars with just a small amount of scripting.

+* +* @title Menu Library +* @namespace YAHOO.widget +* @requires Event, Dom, Container */ -YAHOO.widget.MenuModule = function(p_oElement, p_oConfig) { +(function() { - YAHOO.widget.MenuModule.superclass.constructor.call( - this, - p_oElement, - p_oConfig - ); +var Dom = YAHOO.util.Dom, + Event = YAHOO.util.Event; -}; +/** +* Singleton that manages a collection of all menus and menu items. Listens for +* DOM events at the document level and dispatches the events to the +* corresponding menu or menu item. +* +* @namespace YAHOO.widget +* @class MenuManager +* @static +*/ +YAHOO.widget.MenuManager = function() { -YAHOO.extend(YAHOO.widget.MenuModule, YAHOO.widget.Overlay); + // Private member variables -// Private globals + // Flag indicating if the DOM event handlers have been attached -/** -* Private global flag indicating if the DOM event handlers have been attached -* @private -* @type {Boolean} -*/ -YAHOO.widget.MenuModule._initEventHandlers = true; + var m_bInitializedEventHandlers = false, -/** -* Private global collection of menus -* @private -* @type {Object} -*/ -YAHOO.widget.MenuModule._menus = {}; + // Collection of menus + m_oMenus = {}, -/** -* Private global collection of menu items -* @private -* @type {Object} -*/ -YAHOO.widget.MenuModule._menuItems = {}; + // Collection of menu items -/** -* Generic, global event handler for all of a menu's DOM-based events. This -* listens for events against the document object. If the target of a given -* event is a member of a menu or menu item's DOM, the instance's corresponding -* Custom Event is fired. -* @private -* @param {Event} p_oEvent Event object passed back by the event -* utility (YAHOO.util.Event). -*/ -YAHOO.widget.MenuModule._onDOMEvent = function(p_oEvent) { + m_oItems = {}, - // Create references to the DOM and Event utilities + // Collection of visible menus - var Dom = YAHOO.util.Dom; - var Event = YAHOO.util.Event; + m_oVisibleMenus = {}, - // The target node of the DOM event + // Logger - var oTarget = Event.getTarget(p_oEvent); + m_oLogger = new YAHOO.widget.LogWriter(this.toString()), - // A reference to the root LI node of a menu item + me = this; - var oMenuItemRootElement; + // Private methods + /** - * Finds the root DIV node of a menu and the root LI node of a menu item + * @method addItem + * @description Adds an item to the collection of known menu items. * @private - * @param {HTMLElement} p_oElement An HTML element + * @param {YAHOO.widget.MenuItem} p_oItem Object specifying the MenuItem + * instance to be added. */ + function addItem(p_oItem) { + + var sYUIId = Dom.generateId(); + + if(p_oItem && m_oItems[sYUIId] != p_oItem) { + + p_oItem.element.setAttribute("yuiid", sYUIId); + + m_oItems[sYUIId] = p_oItem; + + p_oItem.destroyEvent.subscribe(onItemDestroy, p_oItem); + + m_oLogger.log("Item: " + + p_oItem.toString() + " successfully registered."); + + } + + } + + + /** + * @method removeItem + * @description Removes an item from the collection of known menu items. + * @private + * @param {YAHOO.widget.MenuItem} p_oItem Object specifying the MenuItem + * instance to be removed. + */ + function removeItem(p_oItem) { + + var sYUIId = p_oItem.element.getAttribute("yuiid"); + + if(sYUIId && m_oItems[sYUIId]) { + + delete m_oItems[sYUIId]; + + m_oLogger.log("Item: " + + p_oItem.toString() + " successfully unregistered."); + + } + + } + + + /** + * @method getMenuRootElement + * @description Finds the root DIV node of a menu or the root LI node of a + * menu item. + * @private + * @param {HTMLElement} p_oElement Object specifying + * an HTML element. + */ function getMenuRootElement(p_oElement) { var oParentNode; - switch(p_oElement.tagName) { + if(p_oElement && p_oElement.tagName) { - case "DIV": + switch(p_oElement.tagName.toUpperCase()) { - oParentNode = p_oElement.parentNode; + case "DIV": - // Check if the DIV is the inner "body" node of a menu - if( - Dom.hasClass(p_oElement, "bd") && - oParentNode && - oParentNode.tagName == "DIV" - ) { + oParentNode = p_oElement.parentNode; - return oParentNode; + // Check if the DIV is the inner "body" node of a menu - } - else { + if( + Dom.hasClass(p_oElement, "bd") && + oParentNode && + oParentNode.tagName && + oParentNode.tagName.toUpperCase() == "DIV" + ) { - return p_oElement; + return oParentNode; - } + } + else { - break; + return p_oElement; - case "LI": + } - /* - Capture the root LI node of the menu item and allow - fall through to keep climbing up to find the item's parent - root DIV - */ + break; - oMenuItemRootElement = p_oElement; + case "LI": - default: + return p_oElement; - oParentNode = p_oElement.parentNode; + default: - if(oParentNode) { + oParentNode = p_oElement.parentNode; - return getMenuRootElement(oParentNode); + if(oParentNode) { - } + return getMenuRootElement(oParentNode); - break; + } + break; + + } + } } - // The root DIV node of a menu - var oMenuRootElement = getMenuRootElement(oTarget); + // Private event handlers - if(oMenuRootElement && oMenuRootElement.id) { + /** + * @method onDOMEvent + * @description Generic, global event handler for all of a menu's DOM-based + * events. This listens for events against the document object. If the + * target of a given event is a member of a menu or menu item's DOM, the + * instance's corresponding Custom Event is fired. + * @private + * @param {Event} p_oEvent Object representing the DOM event object passed + * back by the event utility (YAHOO.util.Event). + */ + function onDOMEvent(p_oEvent) { - var oMenuItem; - var oMenu = YAHOO.widget.MenuModule._menus[oMenuRootElement.id]; + // Get the target node of the DOM event - if(oMenuItemRootElement) { + var oTarget = Event.getTarget(p_oEvent), - var sYUIId = oMenuItemRootElement.getAttribute("yuiid"); - if(sYUIId) { + // See if the target of the event was a menu, or a menu item - oMenuItem = YAHOO.widget.MenuModule._menuItems[sYUIId]; + oElement = getMenuRootElement(oTarget), + oMenuItem, + oMenu; + + if(oElement) { + + var sTagName = oElement.tagName.toUpperCase(); + + if(sTagName == "LI") { + + var sYUIId = oElement.getAttribute("yuiid"); + + if(sYUIId) { + + oMenuItem = m_oItems[sYUIId]; + oMenu = oMenuItem.parent; + + } + } + else if(sTagName == "DIV") { + if(oElement.id) { + + oMenu = m_oMenus[oElement.id]; + + } + + } + } if(oMenu) { @@ -180,2264 +260,7465 @@ "keydown": "keyDownEvent", "keyup": "keyUpEvent", "keypress": "keyPressEvent" - }; + }, - var sCustomEventType = oEventTypes[p_oEvent.type]; + sCustomEventType = oEventTypes[p_oEvent.type]; - switch(p_oEvent.type) { - case "mouseover": + // Fire the Custom Even that corresponds the current DOM event - if( - !oMenu._bFiredMouseOverEvent && - ( - oTarget == oMenu.element || - Dom.isAncestor(oMenu.element, oTarget) - ) - ) { + if(oMenuItem && !oMenuItem.cfg.getProperty("disabled")) { - oMenu.mouseOverEvent.fire(p_oEvent); + oMenuItem[sCustomEventType].fire(p_oEvent); - oMenu._bFiredMouseOverEvent = true; - oMenu._bFiredMouseOutEvent = false; + } - } + oMenu[sCustomEventType].fire(p_oEvent, oMenuItem); + } + else if(p_oEvent.type == "mousedown") { + + /* + If the target of the event wasn't a menu, hide all + dynamically positioned menus + */ + + var oActiveItem; + + for(var i in m_oMenus) { + + if(m_oMenus.hasOwnProperty(i)) { + + oMenu = m_oMenus[i]; + if( - oMenuItem && - !oMenuItem._bFiredMouseOverEvent && - ( - oTarget == oMenuItem.element || - Dom.isAncestor(oMenuItem.element, oTarget) - ) && - !oMenuItem.cfg.getProperty("disabled") + oMenu.cfg.getProperty("clicktohide") && + oMenu.cfg.getProperty("position") == "dynamic" ) { - oMenuItem.mouseOverEvent.fire(p_oEvent); + oMenu.hide(); - oMenuItem._bFiredMouseOverEvent = true; - oMenuItem._bFiredMouseOutEvent = false; + } + else { + oMenu.clearActiveItem(true); + } - break; + } - case "mouseout": + } - var oRelatedTarget = Event.getRelatedTarget(p_oEvent); - var bMovingToSubmenu = false; + } - if(oMenuItem) { + } - var oSubmenu = oMenuItem.cfg.getProperty("submenu"); - if( - oSubmenu && - ( - oRelatedTarget == oSubmenu.element || - Dom.isAncestor(oSubmenu.element, oRelatedTarget) - ) - ) { + /** + * @method onMenuDestroy + * @description "destroy" event handler for a menu. + * @private + * @param {String} p_sType String representing the name of the event that + * was fired. + * @param {Array} p_aArgs Array of arguments sent when the event was fired. + * @param {YAHOO.widget.Menu} p_oMenu Object representing the menu that + * fired the event. + */ + function onMenuDestroy(p_sType, p_aArgs, p_oMenu) { - bMovingToSubmenu = true; + if(p_oMenu && m_oMenus[p_oMenu.id]) { - } + delete m_oMenus[p_oMenu.id]; - } + m_oLogger.log("Menu: " + + p_oMenu.toString() + " successfully unregistered."); + } - if( - oMenuItem && - !oMenuItem._bFiredMouseOutEvent && - ( - ( - oRelatedTarget != oMenuItem.element && - !Dom.isAncestor( - oMenuItem.element, - oRelatedTarget - ) - ) || bMovingToSubmenu - ) && - !oMenuItem.cfg.getProperty("disabled") - ) { + } - // Fire the "mouseout" Custom Event for the item - oMenuItem.mouseOutEvent.fire(p_oEvent); + /** + * @method onItemDestroy + * @description "destroy" event handler for a MenuItem instance. + * @private + * @param {String} p_sType String representing the name of the event that + * was fired. + * @param {Array} p_aArgs Array of arguments sent when the event was fired. + * @param {YAHOO.widget.MenuItem} p_oItem Object representing the menu item + * that fired the event. + */ + function onItemDestroy(p_sType, p_aArgs, p_oItem) { - oMenuItem._bFiredMouseOutEvent = true; - oMenuItem._bFiredMouseOverEvent = false; + var sYUIId = p_oItem.element.getAttribute("yuiid"); - } + if(sYUIId) { + delete m_oItems[sYUIId]; - if( - !oMenu._bFiredMouseOutEvent && - ( - ( - oRelatedTarget != oMenu.element && - !Dom.isAncestor(oMenu.element, oRelatedTarget) - ) - || bMovingToSubmenu - ) - ) { + } - oMenu.mouseOutEvent.fire(p_oEvent); + } - oMenu._bFiredMouseOutEvent = true; - oMenu._bFiredMouseOverEvent = false; - } + /** + * @method onMenuVisibleConfigChange + * @description Event handler for when the "visible" configuration property + * of a Menu instance changes. + * @private + * @param {String} p_sType String representing the name of the event that + * was fired. + * @param {Array} p_aArgs Array of arguments sent when the event was fired. + * @param {YAHOO.widget.Menu} p_oMenu Object representing the menu that + * fired the event. + */ + function onMenuVisibleConfigChange(p_sType, p_aArgs, p_oMenu) { - break; + var bVisible = p_aArgs[0]; - default: + if(bVisible) { - if(oMenuItem && !oMenuItem.cfg.getProperty("disabled")) { + m_oVisibleMenus[p_oMenu.id] = p_oMenu; - oMenuItem[sCustomEventType].fire(p_oEvent); + m_oLogger.log("Menu: " + + p_oMenu.toString() + + " registered with the collection of visible menus."); + } + else if(m_oVisibleMenus[p_oMenu.id]) { + + delete m_oVisibleMenus[p_oMenu.id]; + + m_oLogger.log("Menu: " + + p_oMenu.toString() + + " unregistered from the collection of visible menus."); + + } + + } + + + /** + * @method onItemAdded + * @description "itemadded" event handler for a Menu instance. + * @private + * @param {String} p_sType String representing the name of the event that + * was fired. + * @param {Array} p_aArgs Array of arguments sent when the event was fired. + */ + function onItemAdded(p_sType, p_aArgs) { + + addItem(p_aArgs[0]); + + } + + + /** + * @method onItemRemoved + * @description "itemremoved" event handler for a Menu instance. + * @private + * @param {String} p_sType String representing the name of the event that + * was fired. + * @param {Array} p_aArgs Array of arguments sent when the event was fired. + */ + function onItemRemoved(p_sType, p_aArgs) { + + removeItem(p_aArgs[0]); + + } + + + + return { + + // Privileged methods + + + /** + * @method addMenu + * @description Adds a menu to the collection of known menus. + * @param {YAHOO.widget.Menu} p_oMenu Object specifying the Menu + * instance to be added. + */ + addMenu: function(p_oMenu) { + + if(p_oMenu && p_oMenu.id && !m_oMenus[p_oMenu.id]) { + + m_oMenus[p_oMenu.id] = p_oMenu; + + + if(!m_bInitializedEventHandlers) { + + var oDoc = document; + + Event.addListener(oDoc, "mouseover", onDOMEvent, me, true); + Event.addListener(oDoc, "mouseout", onDOMEvent, me, true); + Event.addListener(oDoc, "mousedown", onDOMEvent, me, true); + Event.addListener(oDoc, "mouseup", onDOMEvent, me, true); + Event.addListener(oDoc, "click", onDOMEvent, me, true); + Event.addListener(oDoc, "keydown", onDOMEvent, me, true); + Event.addListener(oDoc, "keyup", onDOMEvent, me, true); + Event.addListener(oDoc, "keypress", onDOMEvent, me, true); + + m_bInitializedEventHandlers = true; + + m_oLogger.log("DOM event handlers initialized."); + + } + + p_oMenu.destroyEvent.subscribe(onMenuDestroy, p_oMenu, me); + + p_oMenu.cfg.subscribeToConfigEvent( + "visible", + onMenuVisibleConfigChange, + p_oMenu + ); + + p_oMenu.itemAddedEvent.subscribe(onItemAdded); + p_oMenu.itemRemovedEvent.subscribe(onItemRemoved); + + m_oLogger.log("Menu: " + + p_oMenu.toString() + " successfully registered."); + + } + + }, + + + /** + * @method removeMenu + * @description Removes a menu from the collection of known menus. + * @param {YAHOO.widget.Menu} p_oMenu Object specifying the Menu + * instance to be removed. + */ + removeMenu: function(p_oMenu) { + + if(p_oMenu && m_oMenus[p_oMenu.id]) { + + delete m_oMenus[p_oMenu.id]; + + m_oLogger.log("Menu: " + + p_oMenu.toString() + " successfully unregistered."); + + } + + }, + + + /** + * @method hideVisible + * @description Hides all visible, dynamically positioned menus. + */ + hideVisible: function() { + + var oMenu; + + for(var i in m_oVisibleMenus) { + + if(m_oVisibleMenus.hasOwnProperty(i)) { + + oMenu = m_oVisibleMenus[i]; + + if(oMenu.cfg.getProperty("position") == "dynamic") { + + oMenu.hide(); + } - oMenu[sCustomEventType].fire(p_oEvent); + } - break; + } + }, + + + /** + * @method getMenus + * @description Returns an array of all menus registered with the + * menu manger. + * @return {Array} + */ + getMenus: function() { + + return m_oMenus; + + }, + + + /** + * @method getMenu + * @description Returns a menu with the specified id. + * @param {String} p_sId String specifying the id of the menu to + * be retrieved. + * @return {YAHOO.widget.Menu} + */ + getMenu: function(p_sId) { + + if(m_oMenus[p_sId]) { + + return m_oMenus[p_sId]; + } + }, + + + /** + * @method toString + * @description Returns a string representing the menu manager. + * @return {String} + */ + toString: function() { + + return ("MenuManager"); + } - } + }; -}; +}(); +})(); + -// Constants + +(function() { -/** -* Constant representing the CSS class(es) to be applied to the root -* HTMLDivElement of the MenuModule instance. -* @final -* @type String -*/ -YAHOO.widget.MenuModule.prototype.CSS_CLASS_NAME = "yuimenu"; + +var Dom = YAHOO.util.Dom, -/** -* Constant representing the type of item to instantiate and add when parsing -* the child nodes (either HTMLLIElement, HTMLOptGroupElement or -* HTMLOptionElement) of a menu's DOM. The default -* is YAHOO.widget.MenuModuleItem. -* @final -* @type YAHOO.widget.MenuModuleItem -*/ -YAHOO.widget.MenuModule.prototype.ITEM_TYPE = null; + Event = YAHOO.util.Event; + -/** -* Constant representing the tagname of the HTMLElement used to title -* a group of items. -* @final -* @type String -*/ -YAHOO.widget.MenuModule.prototype.GROUP_TITLE_TAG_NAME = "H6"; + +/** +* The Menu class creates a container that holds a vertical list representing -// Private properties +* a set of options or commands. Menu is the base class for all +* menu containers. -/** -* The current state of a MenuModule instance's "mouseover" event -* @private -* @type {Boolean} -*/ -YAHOO.widget.MenuModule.prototype._bFiredMouseOverEvent = false; +* @param {String} p_oElement String specifying the id attribute of the +* <div> element of the menu. -/** -* The current state of a MenuModule instance's "mouseout" event -* @private -* @type {Boolean} -*/ -YAHOO.widget.MenuModule.prototype._bFiredMouseOutEvent = false; +* @param {String} p_oElement String specifying the id attribute of the +* <select> element to be used as the data source -/** -* Array of HTMLElements used to title groups of items. -* @private -* @type {Array} -*/ -YAHOO.widget.MenuModule.prototype._aGroupTitleElements = null; +* for the menu. +* @param {HTMLDivElement} p_oElement Object +* specifying the <div> element of the menu. -/** -* An array of HTMLUListElements, each of which is the parent node of each -* items's HTMLLIElement node. -* @private -* @type {Array} -*/ -YAHOO.widget.MenuModule.prototype._aListElements = null; +* @param {HTMLSelectElement} p_oElement -/** -* Reference to the Event utility singleton. -* @private -* @type {YAHOO.util.Event} -*/ -YAHOO.widget.MenuModule.prototype._oEventUtil = YAHOO.util.Event; +* Object specifying the <select> element to be used as +* the data source for the menu. -/** -* Reference to the Dom utility singleton. -* @private -* @type {YAHOO.util.Dom} -*/ -YAHOO.widget.MenuModule.prototype._oDom = YAHOO.util.Dom; +* @param {Object} p_oConfig Optional. Object literal specifying the +* configuration for the menu. See configuration class documentation for +* more details. -// Public properties +* @namespace YAHOO.widget -/** -* Reference to the item that has focus. -* @private -* @type {YAHOO.widget.MenuModuleItem} -*/ -YAHOO.widget.MenuModule.prototype.activeItem = null; +* @class Menu +* @constructor -/** -* Returns a MenuModule instance's parent object. -* @type {YAHOO.widget.MenuModuleItem} -*/ -YAHOO.widget.MenuModule.prototype.parent = null; +* @extends YAHOO.widget.Overlay +*/ -/** -* Returns the HTMLElement (either HTMLSelectElement or HTMLDivElement) -* used create the MenuModule instance. -* @type {HTMLSelectElement/HTMLDivElement} -*/ -YAHOO.widget.MenuModule.prototype.srcElement = null; +YAHOO.widget.Menu = function(p_oElement, p_oConfig) { + + if(p_oConfig) { -// Events + -/** -* Fires when the mouse has entered a MenuModule instance. Passes back the -* DOM Event object as an argument. -* @type {YAHOO.util.CustomEvent} -* @see YAHOO.util.CustomEvent -*/ -YAHOO.widget.MenuModule.prototype.mouseOverEvent = null; + this.parent = p_oConfig.parent; + -/** -* Fires when the mouse has left a MenuModule instance. Passes back the DOM -* Event object as an argument. -* @type {YAHOO.util.CustomEvent} -* @see YAHOO.util.CustomEvent -*/ -YAHOO.widget.MenuModule.prototype.mouseOutEvent = null; + this.lazyLoad = p_oConfig.lazyLoad || p_oConfig.lazyload; + -/** -* Fires when the user mouses down on a MenuModule instance. Passes back the -* DOM Event object as an argument. -* @type {YAHOO.util.CustomEvent} -* @see YAHOO.util.CustomEvent -*/ -YAHOO.widget.MenuModule.prototype.mouseDownEvent = null; + this.itemData = p_oConfig.itemData || p_oConfig.itemdata; + -/** -* Fires when the user releases a mouse button while the mouse is over -* a MenuModule instance. Passes back the DOM Event object as an argument. -* @type {YAHOO.util.CustomEvent} -* @see YAHOO.util.CustomEvent -*/ -YAHOO.widget.MenuModule.prototype.mouseUpEvent = null; + } + -/** -* Fires when the user clicks the on a MenuModule instance. Passes back the -* DOM Event object as an argument. -* @type {YAHOO.util.CustomEvent} -* @see YAHOO.util.CustomEvent -*/ -YAHOO.widget.MenuModule.prototype.clickEvent = null; + + YAHOO.widget.Menu.superclass.constructor.call( -/** -* Fires when the user presses an alphanumeric key. Passes back the -* DOM Event object as an argument. -* @type {YAHOO.util.CustomEvent} -* @see YAHOO.util.CustomEvent -*/ -YAHOO.widget.MenuModule.prototype.keyPressEvent = null; + this, + p_oElement, -/** -* Fires when the user presses a key. Passes back the DOM Event -* object as an argument. -* @type {YAHOO.util.CustomEvent} -* @see YAHOO.util.CustomEvent -*/ -YAHOO.widget.MenuModule.prototype.keyDownEvent = null; + p_oConfig + ); -/** -* Fires when the user releases a key. Passes back the DOM Event -* object as an argument. -* @type {YAHOO.util.CustomEvent} -* @see YAHOO.util.CustomEvent -*/ -YAHOO.widget.MenuModule.prototype.keyUpEvent = null; + +}; -/** -* The MenuModule class's initialization method. This method is automatically -* called by the constructor, and sets up all DOM references for -* pre-existing markup, and creates required markup if it is not already present. -* @param {String or HTMLElement} p_oElement String id or HTMLElement -* (either HTMLSelectElement or HTMLDivElement) of the source HTMLElement node. -* @param {Object} p_oConfig Optional. The configuration object literal -* containing the configuration for a MenuModule instance. See -* configuration class documentation for more details. -*/ -YAHOO.widget.MenuModule.prototype.init = function(p_oElement, p_oConfig) { + - var Dom = this._oDom; - var Event = this._oEventUtil; +YAHOO.extend(YAHOO.widget.Menu, YAHOO.widget.Overlay, { + - if(!this.ITEM_TYPE) { + - this.ITEM_TYPE = YAHOO.widget.MenuModuleItem; + - } +// Constants + - this._aItemGroups = []; - this._aListElements = []; - this._aGroupTitleElements = []; + +/** - var oElement; +* @property CSS_CLASS_NAME - if(typeof p_oElement == "string") { +* @description String representing the CSS class(es) to be applied to the - oElement = document.getElementById(p_oElement); +* menu's <div> element. - } - else if(p_oElement.tagName) { +* @default "yuimenu" - oElement = p_oElement; +* @final - } +* @type String +*/ - if(oElement) { +CSS_CLASS_NAME: "yuimenu", - switch(oElement.tagName) { + - case "DIV": + - this.srcElement = oElement; +/** - /* - Note: we don't pass the user config in here yet - because we only want it executed once, at the lowest - subclass level. - */ +* @property ITEM_TYPE - YAHOO.widget.MenuModule.superclass.init.call(this, oElement); +* @description Object representing the type of menu item to instantiate and - this.beforeInitEvent.fire(YAHOO.widget.MenuModule); +* add when parsing the child nodes (either <li> element, +* <optgroup> element or <option>) - /* - Populate the collection of item groups and item - group titles - */ +* of the menu's source HTML element. - var oNode = this.body.firstChild; - var i = 0; +* @default YAHOO.widget.MenuItem - do { +* @final - switch(oNode.tagName) { +* @type YAHOO.widget.MenuItem - case this.GROUP_TITLE_TAG_NAME: +*/ - this._aGroupTitleElements[i] = oNode; +ITEM_TYPE: null, - break; + - case "UL": + - this._aListElements[i] = oNode; - this._aItemGroups[i] = []; - i++; +/** - break; +* @property GROUP_TITLE_TAG_NAME - } +* @description String representing the tagname of the HTML element used to - } - while((oNode = oNode.nextSibling)); +* title the menu's item groups. +* @default H6 - /* - Apply the "first-of-type" class to the first UL to mimic - the "first-of-type" CSS3 psuedo class. - */ +* @final - if(this._aListElements[0]) { +* @type String - Dom.addClass(this._aListElements[0], "first-of-type"); +*/ - } +GROUP_TITLE_TAG_NAME: "h6", - this.logger = new YAHOO.widget.LogWriter(this.toString()); + - this.logger.log("Source element: " + this.srcElement.tagName); + - break; + - case "SELECT": +// Private properties - this.srcElement = oElement; + + - /* - The source element is not something that we can use - outright, so we need to create a new Overlay - */ +/** - var sId = Dom.generateId(); +* @property _nHideDelayId - /* - Note: we don't pass the user config in here yet - because we only want it executed once, at the lowest - subclass level. - */ +* @description Number representing the time-out setting used to cancel the - YAHOO.widget.MenuModule.superclass.init.call(this, sId); +* hiding of a menu. - this.beforeInitEvent.fire(YAHOO.widget.MenuModule); +* @default null - this.logger = new YAHOO.widget.LogWriter(this.toString()); +* @private - this.logger.log("Source element: " + this.srcElement.tagName); +* @type Number - break; +*/ - } +_nHideDelayId: null, - } - else { + - /* - Note: we don't pass the user config in here yet - because we only want it executed once, at the lowest - subclass level. - */ + - YAHOO.widget.MenuModule.superclass.init.call(this, p_oElement); +/** - this.beforeInitEvent.fire(YAHOO.widget.MenuModule); +* @property _nShowDelayId - this.logger = new YAHOO.widget.LogWriter(this.toString()); +* @description Number representing the time-out setting used to cancel the - this.logger.log("No source element found. " + - "Created element with id: " + this.id); +* showing of a menu. - } +* @default null +* @private - if(this.element) { +* @type Number - var oEl = this.element; - var CustomEvent = YAHOO.util.CustomEvent; +*/ - Dom.addClass(oEl, this.CSS_CLASS_NAME); +_nShowDelayId: null, - // Assign DOM event handlers + - if(YAHOO.widget.MenuModule._initEventHandlers) { + - var oDoc = document; - var onDOMEvent = YAHOO.widget.MenuModule._onDOMEvent; +/** - Event.addListener(oDoc, "mouseover", onDOMEvent); - Event.addListener(oDoc, "mouseout", onDOMEvent); - Event.addListener(oDoc, "mousedown", onDOMEvent); - Event.addListener(oDoc, "mouseup", onDOMEvent); - Event.addListener(oDoc, "click", onDOMEvent); - Event.addListener(oDoc, "keydown", onDOMEvent); - Event.addListener(oDoc, "keyup", onDOMEvent); - Event.addListener(oDoc, "keypress", onDOMEvent); +* @property _hideDelayEventHandlersAssigned - YAHOO.widget.MenuModule._initEventHandlers = false; +* @description Boolean indicating if the "mouseover" and "mouseout" event - } +* handlers used for hiding the menu via a call to "window.setTimeout" have +* already been assigned. - // Create custom events +* @default false - this.mouseOverEvent = new CustomEvent("mouseOverEvent", this); - this.mouseOutEvent = new CustomEvent("mouseOutEvent", this); - this.mouseDownEvent = new CustomEvent("mouseDownEvent", this); - this.mouseUpEvent = new CustomEvent("mouseUpEvent", this); - this.clickEvent = new CustomEvent("clickEvent", this); - this.keyPressEvent = new CustomEvent("keyPressEvent", this); - this.keyDownEvent = new CustomEvent("keyDownEvent", this); - this.keyUpEvent = new CustomEvent("keyUpEvent", this); +* @private +* @type Boolean - // Subscribe to Custom Events +*/ - this.initEvent.subscribe(this._onInit, this, true); - this.beforeRenderEvent.subscribe(this._onBeforeRender, this, true); - this.renderEvent.subscribe(this._onRender, this, true); - this.showEvent.subscribe(this._onShow, this, true); - this.beforeHideEvent.subscribe(this._onBeforeHide, this, true); +_hideDelayEventHandlersAssigned: false, + - if(p_oConfig) { + - this.cfg.applyConfig(p_oConfig, true); +/** - } +* @property _bHandledMouseOverEvent +* @description Boolean indicating the current state of the menu's - this.cfg.queueProperty("visible", false); +* "mouseover" event. +* @default false - if(this.srcElement) { +* @private - this._initSubTree(); +* @type Boolean - } +*/ - YAHOO.widget.MenuModule._menus[oEl.id] = this; +_bHandledMouseOverEvent: false, - } + + - this.initEvent.fire(YAHOO.widget.MenuModule); +/** -}; +* @property _bHandledMouseOutEvent +* @description Boolean indicating the current state of the menu's -// Private methods +* "mouseout" event. -/** -* Iterates the source element's childNodes collection and uses the child -* nodes to instantiate MenuModule and MenuModuleItem instances. -* @private -*/ -YAHOO.widget.MenuModule.prototype._initSubTree = function() { +* @default false - var oNode; +* @private - this.logger.log("Searching DOM for items to initialize."); +* @type Boolean - switch(this.srcElement.tagName) { +*/ - case "DIV": +_bHandledMouseOutEvent: false, - if(this._aListElements.length > 0) { + - this.logger.log("Found " + - this._aListElements.length + " item groups to initialize."); + - var i = this._aListElements.length - 1; +/** - do { +* @property _aGroupTitleElements - oNode = this._aListElements[i].firstChild; +* @description Array of HTML element used to title groups of menu items. - this.logger.log("Scanning " + - this._aListElements[i].childNodes.length + - " child nodes for items to initialize."); +* @default [] - do { +* @private - switch(oNode.tagName) { +* @type Array - case "LI": +*/ - this.logger.log("Initializing " + - oNode.tagName + " node."); +_aGroupTitleElements: null, - this.addItem(new this.ITEM_TYPE(oNode), i); + - break; + - } +/** - } - while((oNode = oNode.nextSibling)); +* @property _aItemGroups - } - while(i--); +* @description Array of menu items. - } +* @default [] - break; +* @private - case "SELECT": +* @type Array - this.logger.log("Scanning " + this.srcElement.childNodes.length + - " child nodes for items to initialize."); +*/ - oNode = this.srcElement.firstChild; +_aItemGroups: null, - do { + - switch(oNode.tagName) { + - case "OPTGROUP": - case "OPTION": +/** - this.logger.log("Initializing " + - oNode.tagName + " node."); +* @property _aListElements - this.addItem(new this.ITEM_TYPE(oNode)); +* @description Array of <ul> elements, each of which is - break; +* the parent node for each item's <li> element. - } +* @default [] - } - while((oNode = oNode.nextSibling)); +* @private - break; +* @type Array - } +*/ -}; +_aListElements: null, + -/** -* Returns the first enabled item in a menu instance. -* @return Returns a MenuModuleItem instance. -* @type YAHOO.widget.MenuModuleItem -* @private -*/ -YAHOO.widget.MenuModule.prototype._getFirstEnabledItem = function() { + - var nGroups = this._aItemGroups.length; - var oItem; - var aItemGroup; + - for(var i=0; i= aGroup.length); +*/ +parent: null, - if(aGroup[p_nItemIndex]) { + - aGroup.splice(p_nItemIndex, 0, oItem); + - } - else { +/** - aGroup[p_nItemIndex] = oItem; +* @property srcElement - } +* @description Object reference to the HTML element (either +* <select> or <div>) used to - oGroupItem = aGroup[p_nItemIndex]; +* create the menu. - if(oGroupItem) { +* @default null - if( - bAppend && - ( - !oGroupItem.element.parentNode || - oGroupItem.element.parentNode.nodeType == 11 - ) - ) { +* @type HTMLSelectElement|HTMLDivElement - /** - * Returns the next sibling of an item in an array - * @param {p_aArray} An array - * @param {p_nStartIndex} The index to start searching - * the array - * @ignore - * @return Returns an item in an array - * @type Object - */ - function getNextItemSibling(p_aArray, p_nStartIndex) { +*/ - return ( - p_aArray[p_nStartIndex] || - getNextItemSibling( - p_aArray, - (p_nStartIndex+1) - ) - ); +srcElement: null, - } + + - var oNextItemSibling = - getNextItemSibling(aGroup, (p_nItemIndex+1)); + - if( - oNextItemSibling && - ( - !oGroupItem.element.parentNode || - oGroupItem.element.parentNode.nodeType == 11 - ) - ) { +// Events - this._aListElements[nGroupIndex].insertBefore( - oGroupItem.element, - oNextItemSibling.element - ); + - } + - } +/** +* @event mouseOverEvent - oGroupItem.parent = this; +* @description Fires when the mouse has entered the menu. Passes back - this._subscribeToItemEvents(oGroupItem); +* the DOM Event object as an argument. - this._configureItemSubmenuModule(oGroupItem); +*/ - this._updateItemProperties(nGroupIndex); +mouseOverEvent: null, - this.logger.log("Item inserted." + - " Text: " + oGroupItem.cfg.getProperty("text") + ", " + - " Index: " + oGroupItem.index + ", " + - " Group Index: " + oGroupItem.groupIndex); + - return oGroupItem; + - } +/** - } - else { +* @event mouseOutEvent - var nItemIndex = aGroup.length; +* @description Fires when the mouse has left the menu. Passes back the DOM - aGroup[nItemIndex] = oItem; +* Event object as an argument. +* @type YAHOO.util.CustomEvent - oGroupItem = aGroup[nItemIndex]; +*/ - if(oGroupItem) { +mouseOutEvent: null, - if( - !Dom.isAncestor( - this._aListElements[nGroupIndex], - oGroupItem.element - ) - ) { + - this._aListElements[nGroupIndex].appendChild( - oGroupItem.element - ); + - } +/** - oGroupItem.element.setAttribute("groupindex", nGroupIndex); - oGroupItem.element.setAttribute("index", nItemIndex); +* @event mouseDownEvent - oGroupItem.parent = this; +* @description Fires when the user mouses down on the menu. Passes back the - oGroupItem.index = nItemIndex; - oGroupItem.groupIndex = nGroupIndex; +* DOM Event object as an argument. - this._subscribeToItemEvents(oGroupItem); +* @type YAHOO.util.CustomEvent - this._configureItemSubmenuModule(oGroupItem); +*/ - if(nItemIndex === 0) { +mouseDownEvent: null, - Dom.addClass(oGroupItem.element, "first-of-type"); + - } + - this.logger.log("Item added." + - " Text: " + oGroupItem.cfg.getProperty("text") + ", " + - " Index: " + oGroupItem.index + ", " + - " Group Index: " + oGroupItem.groupIndex); +/** - return oGroupItem; +* @event mouseUpEvent - } +* @description Fires when the user releases a mouse button while the mouse is - } +* over the menu. Passes back the DOM Event object as an argument. - } +* @type YAHOO.util.CustomEvent - }; +*/ +mouseUpEvent: null, -/** -* Removes an item from a group by index. -* @private -* @param {Number} p_nGroupIndex Number indicating the group to which -* the item belongs. -* @param {Number} p_nItemIndex Number indicating the index of the item to -* be removed. -* @return The item that was removed. -* @type YAHOO.widget.MenuModuleItem -*/ -YAHOO.widget.MenuModule.prototype._removeItemFromGroupByIndex = + - function(p_nGroupIndex, p_nItemIndex) { + - var nGroupIndex = typeof p_nGroupIndex == "number" ? p_nGroupIndex : 0; - var aGroup = this._getItemGroup(nGroupIndex); +/** - if(aGroup) { +* @event clickEvent - var aArray = aGroup.splice(p_nItemIndex, 1); - var oItem = aArray[0]; +* @description Fires when the user clicks the on the menu. Passes back the - if(oItem) { +* DOM Event object as an argument. - // Update the index and className properties of each member +* @type YAHOO.util.CustomEvent - this._updateItemProperties(nGroupIndex); +*/ - if(aGroup.length === 0) { +clickEvent: null, - // Remove the UL + - var oUL = this._aListElements[nGroupIndex]; + - if(this.body && oUL) { +/** - this.body.removeChild(oUL); +* @event keyPressEvent - } +* @description Fires when the user presses an alphanumeric key when one of the - // Remove the group from the array of items +* menu's items has focus. Passes back the DOM Event object as an argument. - this._aItemGroups.splice(nGroupIndex, 1); +* @type YAHOO.util.CustomEvent +*/ - // Remove the UL from the array of ULs +keyPressEvent: null, - this._aListElements.splice(nGroupIndex, 1); + + - /* - Assign the "first-of-type" class to the new first UL - in the collection - */ +/** - oUL = this._aListElements[0]; +* @event keyDownEvent - if(oUL) { +* @description Fires when the user presses a key when one of the menu's items - this._oDom.addClass(oUL, "first-of-type"); +* has focus. Passes back the DOM Event object as an argument. - } +* @type YAHOO.util.CustomEvent - } +*/ +keyDownEvent: null, - // Return a reference to the item that was removed + - return oItem; + - } +/** - } +* @event keyUpEvent - }; +* @description Fires when the user releases a key when one of the menu's items +* has focus. Passes back the DOM Event object as an argument. -/** -* Removes a item from a group by reference. -* @private -* @param {Number} p_nGroupIndex Number indicating the group to which -* the item belongs. -* @param {YAHOO.widget.MenuModuleItem} p_oItem The item to be removed. -* @return The item that was removed. -* @type YAHOO.widget.MenuModuleItem -*/ -YAHOO.widget.MenuModule.prototype._removeItemFromGroupByValue = +* @type YAHOO.util.CustomEvent - function(p_nGroupIndex, p_oItem) { +*/ - var aGroup = this._getItemGroup(p_nGroupIndex); +keyUpEvent: null, - if(aGroup) { + - var nItems = aGroup.length; - var nItemIndex = -1; + - if(nItems > 0) { +/** - var i = nItems-1; +* @event itemAddedEvent - do { +* @description Fires when an item is added to the menu. - if(aGroup[i] == p_oItem) { +* @type YAHOO.util.CustomEvent - nItemIndex = i; - break; +*/ - } +itemAddedEvent: null, - } - while(i--); + - if(nItemIndex > -1) { + - return this._removeItemFromGroupByIndex( - p_nGroupIndex, - nItemIndex - ); +/** - } +* @event itemRemovedEvent - } +* @description Fires when an item is removed to the menu. - } +* @type YAHOO.util.CustomEvent - }; +*/ +itemRemovedEvent: null, -/** -* Updates the index, groupindex, and className properties of the items -* in the specified group. -* @private -* @param {Number} p_nGroupIndex Number indicating the group of items to update. -*/ -YAHOO.widget.MenuModule.prototype._updateItemProperties = + - function(p_nGroupIndex) { + - var aGroup = this._getItemGroup(p_nGroupIndex); - var nItems = aGroup.length; +/** - if(nItems > 0) { +* @method init - var Dom = this._oDom; - var i = nItems - 1; - var oItem; - var oLI; +* @description The Menu class's initialization method. This method is - // Update the index and className properties of each member +* automatically called by the constructor, and sets up all DOM references - do { +* for pre-existing markup, and creates required markup if it is not - oItem = aGroup[i]; +* already present. - if(oItem) { +* @param {String} p_oElement String specifying the id attribute of the - oLI = oItem.element; +* <div> element of the menu. - oItem.index = i; - oItem.groupIndex = p_nGroupIndex; +* @param {String} p_oElement String specifying the id attribute of the - oLI.setAttribute("groupindex", p_nGroupIndex); - oLI.setAttribute("index", i); +* <select> element to be used as the data source - Dom.removeClass(oLI, "first-of-type"); +* for the menu. - } +* @param {HTMLDivElement} p_oElement Object +* specifying the <div> element of the menu. - if(oLI) { +* @param {HTMLSelectElement} p_oElement - } +* Object specifying the <select> element to be used as - } +* the data source for the menu. - }; +* @param {Object} p_oConfig Optional. Object literal specifying the +* configuration for the menu. See configuration class documentation for -/** -* Creates a new item group (array) and it's associated HTMLUlElement node -* @private -* @param {Number} p_nIndex Number indicating the group to create. -* @return An item group. -* @type Array -*/ -YAHOO.widget.MenuModule.prototype._createItemGroup = function(p_nIndex) { +* more details. - if(!this._aItemGroups[p_nIndex]) { +*/ - this._aItemGroups[p_nIndex] = []; +init: function(p_oElement, p_oConfig) { - var oUL = document.createElement("ul"); + - this._aListElements[p_nIndex] = oUL; + this._aItemGroups = []; - return this._aItemGroups[p_nIndex]; + this._aListElements = []; - } + this._aGroupTitleElements = []; -}; + + -/** -* Returns the item group at the specified index. -* @private -* @param {Number} p_nIndex Number indicating the index of the item group to -* be retrieved. -* @return An array of items. -* @type Array -*/ -YAHOO.widget.MenuModule.prototype._getItemGroup = function(p_nIndex) { + if(!this.ITEM_TYPE) { - var nIndex = ((typeof p_nIndex == "number") ? p_nIndex : 0); + - return this._aItemGroups[nIndex]; + this.ITEM_TYPE = YAHOO.widget.MenuItem; -}; + + } -/** -* Subscribe's a MenuModule instance to it's parent MenuModule instance's events. -* @private -* @param {YAHOO.widget.MenuModuleItem} p_oItem The item to listen -* for events on. -*/ -YAHOO.widget.MenuModule.prototype._configureItemSubmenuModule = + - function(p_oItem) { + - var oSubmenu = p_oItem.cfg.getProperty("submenu"); + var oElement; - if(oSubmenu) { + - /* - Listen for configuration changes to the parent MenuModule - instance so they they can be applied to the submenu. - */ + if(typeof p_oElement == "string") { - this.cfg.configChangedEvent.subscribe( - this._onParentMenuModuleConfigChange, - oSubmenu, - true - ); + - this.renderEvent.subscribe( - this._onParentMenuModuleRender, - oSubmenu, - true - ); + oElement = document.getElementById(p_oElement); - oSubmenu.beforeShowEvent.subscribe( - this._onSubmenuBeforeShow, - oSubmenu, - true - ); + - oSubmenu.showEvent.subscribe(this._onSubmenuShow, oSubmenu, true); + } - oSubmenu.hideEvent.subscribe(this._onSubmenuHide, oSubmenu, true); + else if(p_oElement.tagName) { - } + -}; + oElement = p_oElement; + -/** -* Subscribes a MenuModule instance to the specified item's Custom Events. -* @private -* @param {YAHOO.widget.MenuModuleItem} p_oItem The item to listen for events on. -*/ -YAHOO.widget.MenuModule.prototype._subscribeToItemEvents = function(p_oItem) { + } - var aArguments = [this, p_oItem]; + - p_oItem.focusEvent.subscribe(this._onItemFocus, aArguments); + - p_oItem.blurEvent.subscribe(this._onItemBlur, aArguments); + if(oElement && oElement.tagName) { - p_oItem.cfg.configChangedEvent.subscribe( - this._onItemConfigChange, - aArguments - ); + -}; + switch(oElement.tagName.toUpperCase()) { + -/** -* Returns the offset width of a MenuModule instance. -* @private -*/ -YAHOO.widget.MenuModule.prototype._getOffsetWidth = function() { + case "DIV": - var oClone = this.element.cloneNode(true); + - this._oDom.setStyle(oClone, "width", ""); + this.srcElement = oElement; - document.body.appendChild(oClone); + - var sWidth = oClone.offsetWidth; + if(!oElement.id) { - document.body.removeChild(oClone); + - return sWidth; + oElement.setAttribute("id", Dom.generateId()); -}; + + } -// Private Custom Event handlers + -/** -* "init" Custom Event handler for a MenuModule instance. -* @private -* @param {String} p_sType The name of the event that was fired. -* @param {Array} p_aArgs Collection of arguments sent when the event -* was fired. -* @param {YAHOO.widget.MenuModule} p_oMenuModule The MenuModule instance that -* fired the event. -*/ -YAHOO.widget.MenuModule.prototype._onInit = + - function(p_sType, p_aArgs, p_oMenuModule) { + /* - var sCSSPosition = (this.cfg.getProperty("position") == "static") ? - "static" : "absolute"; + Note: we don't pass the user config in here yet - this._oDom.setStyle(this.element, "position", sCSSPosition); + because we only want it executed once, at the lowest - }; + subclass level. + */ -/** -* "beforerender" Custom Event handler for a MenuModule instance. Appends all -* of the HTMLUListElement (<UL<s) nodes (and their child -* HTMLLIElement (<LI<)) nodes and their accompanying title nodes to -* the body of the MenuModule instance. -* @private -* @param {String} p_sType The name of the event that was fired. -* @param {Array} p_aArgs Collection of arguments sent when the event -* was fired. -* @param {YAHOO.widget.MenuModule} p_oMenuModule The MenuModule instance that -* fired the event. -*/ -YAHOO.widget.MenuModule.prototype._onBeforeRender = + - function(p_sType, p_aArgs, p_oMenuModule) { + YAHOO.widget.Menu.superclass.init.call(this, oElement); - var Dom = this._oDom; - var oConfig = this.cfg; - var oEl = this.element; - var nListElements = this._aListElements.length; + + this.beforeInitEvent.fire(YAHOO.widget.Menu); - if(oConfig.getProperty("position") == "static") { + - oConfig.queueProperty("iframe", false); - oConfig.queueProperty("visible", true); + this.logger = new YAHOO.widget.LogWriter(this.toString()); - } + + this.logger.log("Source element: " + this.srcElement.tagName); - if(nListElements > 0) { + - var i = 0; - var bFirstList = true; - var oUL; - var oGroupTitle; + break; + - do { + case "SELECT": - oUL = this._aListElements[i]; + - if(oUL) { + this.srcElement = oElement; - if(bFirstList) { + - Dom.addClass(oUL, "first-of-type"); - bFirstList = false; + - } + /* + The source element is not something that we can use - if(!Dom.isAncestor(oEl, oUL)) { + outright, so we need to create a new Overlay - this.appendToBody(oUL); + - } + Note: we don't pass the user config in here yet + because we only want it executed once, at the lowest - oGroupTitle = this._aGroupTitleElements[i]; + subclass level. - if(oGroupTitle) { + */ - if(!Dom.isAncestor(oEl, oGroupTitle)) { + - oUL.parentNode.insertBefore(oGroupTitle, oUL); + YAHOO.widget.Menu.superclass.init.call(this, Dom.generateId()); - } + + this.beforeInitEvent.fire(YAHOO.widget.Menu); - Dom.addClass(oUL, "hastitle"); + - } + this.logger = new YAHOO.widget.LogWriter(this.toString()); - } + - i++; + this.logger.log("Source element: " + this.srcElement.tagName); - } - while(i < nListElements); + - } + break; - }; + + } -/** -* "render" Custom Event handler for a MenuModule instance. -* @private -* @param {String} p_sType The name of the event that was fired. -* @param {Array} p_aArgs Collection of arguments sent when the event -* was fired. -* @param {YAHOO.widget.MenuModule} p_oMenuModule The MenuModule instance that -* fired the event. -*/ -YAHOO.widget.MenuModule.prototype._onRender = + - function(p_sType, p_aArgs, p_oMenuModule) { + } - if(this.cfg.getProperty("position") == "dynamic") { + else { - var sWidth = this.element.parentNode.tagName == "BODY" ? - this.element.offsetWidth : this._getOffsetWidth(); + - this.cfg.setProperty("width", (sWidth + "px")); + /* - } + Note: we don't pass the user config in here yet - }; + because we only want it executed once, at the lowest + subclass level. -/** -* "show" Custom Event handler for a MenuModule instance. -* @private -* @param {String} p_sType The name of the event that was fired. -* @param {Array} p_aArgs Collection of arguments sent when the event -* was fired. -* @param {YAHOO.widget.MenuModule} p_oMenuModule The MenuModule instance that -* fired the event. -*/ -YAHOO.widget.MenuModule.prototype._onShow = + */ - function(p_sType, p_aArgs, p_oMenuModule) { + - /* - Setting focus to an item in the newly visible submenu alerts the - contents of the submenu to the screen reader. - */ + YAHOO.widget.Menu.superclass.init.call(this, p_oElement); - this.setInitialFocus(); + - }; + this.beforeInitEvent.fire(YAHOO.widget.Menu); + -/** -* "hide" Custom Event handler for a MenuModule instance. -* @private -* @param {String} p_sType The name of the event that was fired. -* @param {Array} p_aArgs Collection of arguments sent when the event -* was fired. -* @param {YAHOO.widget.MenuModule} p_oMenuModule The MenuModule instance that -* fired the event. -*/ -YAHOO.widget.MenuModule.prototype._onBeforeHide = + this.logger = new YAHOO.widget.LogWriter(this.toString()); - function(p_sType, p_aArgs, p_oMenuModule) { + - var oActiveItem = this.activeItem; + this.logger.log("No source element found. " + - if(oActiveItem) { + "Created element with id: " + this.id); - oActiveItem.blur(); + - if(oActiveItem.cfg.getProperty("selected")) { + } - oActiveItem.cfg.setProperty("selected", false); + - } + - var oSubmenu = oActiveItem.cfg.getProperty("submenu"); + if(this.element) { - if(oSubmenu && oSubmenu.cfg.getProperty("visible")) { + - oSubmenu.hide(); + var oEl = this.element; - } + - } + Dom.addClass(oEl, this.CSS_CLASS_NAME); - }; + + -/** -* "configchange" Custom Event handler for a submenu. -* @private -* @param {String} p_sType The name of the event that was fired. -* @param {Array} p_aArgs Collection of arguments sent when the event -* was fired. -* @param {YAHOO.widget.MenuModule} p_oSubmenu The submenu that subscribed -* to the event. -*/ -YAHOO.widget.MenuModule.prototype._onParentMenuModuleConfigChange = + // Subscribe to Custom Events - function(p_sType, p_aArgs, p_oSubmenu) { + - var sPropertyName = p_aArgs[0][0]; - var oPropertyValue = p_aArgs[0][1]; + this.initEvent.subscribe(this._onInit, this, true); - switch(sPropertyName) { + this.beforeRenderEvent.subscribe(this._onBeforeRender, this, true); - case "iframe": - case "constraintoviewport": + this.renderEvent.subscribe(this._onRender, this, true); - p_oSubmenu.cfg.setProperty(sPropertyName, oPropertyValue); + this.beforeShowEvent.subscribe(this._onBeforeShow, this, true); - break; + this.showEvent.subscribe(this._onShow, this, true); - } + this.beforeHideEvent.subscribe(this._onBeforeHide, this, true); - }; + this.mouseOverEvent.subscribe(this._onMouseOver, this, true); + this.mouseOutEvent.subscribe(this._onMouseOut, this, true); -/** -* "render" Custom Event handler for a MenuModule instance. Renders a -* submenu in response to the firing of it's parent's "render" event. -* @private -* @param {String} p_sType The name of the event that was fired. -* @param {Array} p_aArgs Collection of arguments sent when the event -* was fired. -* @param {YAHOO.widget.MenuModule} p_oSubmenu The submenu that subscribed -* to the event. -*/ -YAHOO.widget.MenuModule.prototype._onParentMenuModuleRender = + this.clickEvent.subscribe(this._onClick, this, true); - function(p_sType, p_aArgs, p_oSubmenu) { + this.keyDownEvent.subscribe(this._onKeyDown, this, true); - /* - Set the "constraintoviewport" configuration - property to match the parent MenuModule - */ + - var oParentMenu = p_oSubmenu.parent.parent; + YAHOO.widget.Module.textResizeEvent.subscribe( - var oConfig = { + this._onTextResize, - constraintoviewport: - oParentMenu.cfg.getProperty("constraintoviewport"), + this, - xy: [0,0] + true - }; + ); + - /* - Only sync the "iframe" configuration property if the parent - MenuModule instance's position is of the same value - */ + - if( - this.cfg.getProperty("position") == - oParentMenu.cfg.getProperty("position") - ) { + if(p_oConfig) { - oConfig.iframe = oParentMenu.cfg.getProperty("iframe"); + - } + this.cfg.applyConfig(p_oConfig, true); + - p_oSubmenu.cfg.applyConfig(oConfig); + } + - if(this._oDom.inDocument(this.element)) { + - this.render(); + // Register the Menu instance with the MenuManager - } - else { + - this.render(this.parent.element); + YAHOO.widget.MenuManager.addMenu(this); - } + - }; + + this.initEvent.fire(YAHOO.widget.Menu); -/** -* "beforeshow" Custom Event handler for a submenu. -* @private -* @param {String} p_sType The name of the event that was fired. -* @param {Array} p_aArgs Collection of arguments sent when the event -* was fired. -* @param {YAHOO.widget.MenuModule} p_oSubmenu The submenu that fired -* the event. -*/ -YAHOO.widget.MenuModule.prototype._onSubmenuBeforeShow = + - function(p_sType, p_aArgs, p_oSubmenu) { + } - var oParent = this.parent; - var aAlignment = oParent.parent.cfg.getProperty("submenualignment"); + - this.cfg.setProperty( - "context", - [ - oParent.element, - aAlignment[0], - aAlignment[1] - ] - ); +}, - oParent.submenuIndicator.alt = - oParent.EXPANDED_SUBMENU_INDICATOR_ALT_TEXT; + - }; + + -/** -* "show" Custom Event handler for a submenu. -* @private -* @param {String} p_sType The name of the event that was fired. -* @param {Array} p_aArgs Collection of arguments sent when the event -* was fired. -* @param {YAHOO.widget.MenuModule} p_oSubmenu The submenu that fired -* the event. -*/ -YAHOO.widget.MenuModule.prototype._onSubmenuShow = +// Private methods - function(p_sType, p_aArgs, p_oSubmenu) { + - var oParent = this.parent; + - oParent.submenuIndicator.alt = - oParent.EXPANDED_SUBMENU_INDICATOR_ALT_TEXT; +/** - }; +* @method _initSubTree +* @description Iterates the childNodes of the source element to find nodes -/** -* "hide" Custom Event handler for a submenu. -* @private -* @param {String} p_sType The name of the event that was fired. -* @param {Array} p_aArgs Collection of arguments sent when the event -* was fired. -* @param {YAHOO.widget.MenuModule} p_oSubmenu The submenu that fired -* the event. -*/ -YAHOO.widget.MenuModule.prototype._onSubmenuHide = +* used to instantiate menu and menu items. - function(p_sType, p_aArgs, p_oSubmenu) { +* @private - var oParent = this.parent; +*/ - if(oParent.parent.cfg.getProperty("visible")) { +_initSubTree: function() { - oParent.cfg.setProperty("selected", false); + - oParent.focus(); + var oNode; - } + - oParent.submenuIndicator.alt = - oParent.COLLAPSED_SUBMENU_INDICATOR_ALT_TEXT; + if(this.srcElement.tagName == "DIV") { - }; + + /* -/** -* "focus" YAHOO.util.CustomEvent handler for a MenuModule instance's items. -* @private -* @param {String} p_sType The name of the event that was fired. -* @param {Array} p_aArgs Collection of arguments sent when the event -* was fired. -* @param {Array} p_aObjects Array containing the current MenuModule instance -* and the item that fired the event. -*/ -YAHOO.widget.MenuModule.prototype._onItemFocus = + Populate the collection of item groups and item - function(p_sType, p_aArgs, p_aObjects) { + group titles - var me = p_aObjects[0]; - var oItem = p_aObjects[1]; + */ - me.activeItem = oItem; + - }; + oNode = this.body.firstChild; + -/** -* "blur" YAHOO.util.CustomEvent handler for a MenuModule instance's items. -* @private -* @param {String} p_sType The name of the event that was fired. -* @param {Array} p_aArgs Collection of arguments sent when the event -* was fired. -* @param {Array} p_aObjects Array containing the current MenuModule instance -* and the item that fired the event. -*/ -YAHOO.widget.MenuModule.prototype._onItemBlur = + var nGroup = 0, - function(p_sType, p_aArgs, p_aObjects) { + sGroupTitleTagName = this.GROUP_TITLE_TAG_NAME.toUpperCase(); - var me = p_aObjects[0]; - var oItem = p_aObjects[1]; - var oSubmenu = oItem.cfg.getProperty("submenu"); + - if(!oSubmenu || (oSubmenu && !oSubmenu.cfg.getProperty("visible"))) { + do { - me.activeItem = null; + - } + if(oNode && oNode.tagName) { - }; + + switch(oNode.tagName.toUpperCase()) { -/** -* "configchange" YAHOO.util.CustomEvent handler for the MenuModule -* instance's items. -* @private -* @param {String} p_sType The name of the event that was fired. -* @param {Array} p_aArgs Collection of arguments sent when the -* event was fired. -* @param {Array} p_aObjects Array containing the current MenuModule instance -* and the item that fired the event. -*/ -YAHOO.widget.MenuModule.prototype._onItemConfigChange = + - function(p_sType, p_aArgs, p_aObjects) { + case sGroupTitleTagName: - var me = p_aObjects[0]; - var sProperty = p_aArgs[0][0]; - var oItem = p_aObjects[1]; + - switch(sProperty) { + this._aGroupTitleElements[nGroup] = oNode; - case "submenu": + - var oSubmenu = p_aArgs[0][1]; + break; - if(oSubmenu) { + - me._configureItemSubmenuModule(oItem); + case "UL": - } + - break; + this._aListElements[nGroup] = oNode; - case "text": - case "helptext": + this._aItemGroups[nGroup] = []; - /* - A change to an item's "text" or "helptext" - configuration properties requires the width of the parent - MenuModule instance to be recalculated. - */ + nGroup++; - if(me.element.style.width) { + - var sWidth = me._getOffsetWidth() + "px"; + break; - me._oDom.setStyle(me.element, "width", sWidth); + - } + } - break; + - } + } - }; + + } -/** -* The default event handler executed when the moveEvent is fired, if the -* "constraintoviewport" configuration property is set to true. -*/ -YAHOO.widget.MenuModule.prototype.enforceConstraints = + while((oNode = oNode.nextSibling)); - function(type, args, obj) { + - var Dom = this._oDom; - var oConfig = this.cfg; + - var pos = args[0]; + /* - var x = pos[0]; - var y = pos[1]; + Apply the "first-of-type" class to the first UL to mimic - var bod = document.getElementsByTagName('body')[0]; - var htm = document.getElementsByTagName('html')[0]; + the "first-of-type" CSS3 psuedo class. - var bodyOverflow = Dom.getStyle(bod, "overflow"); - var htmOverflow = Dom.getStyle(htm, "overflow"); + */ - var offsetHeight = this.element.offsetHeight; - var offsetWidth = this.element.offsetWidth; + - var viewPortWidth = Dom.getClientWidth(); - var viewPortHeight = Dom.getClientHeight(); + if(this._aListElements[0]) { - var scrollX = window.scrollX || document.body.scrollLeft; - var scrollY = window.scrollY || document.body.scrollTop; + - var topConstraint = scrollY + 10; - var leftConstraint = scrollX + 10; - var bottomConstraint = scrollY + viewPortHeight - offsetHeight - 10; - var rightConstraint = scrollX + viewPortWidth - offsetWidth - 10; + Dom.addClass(this._aListElements[0], "first-of-type"); - var aContext = oConfig.getProperty("context"); - var oContextElement = aContext ? aContext[0] : null; + + } - if (x < 10) { + - x = leftConstraint; + } - } else if ((x + offsetWidth) > viewPortWidth) { + - if( - oContextElement && - ((x - oContextElement.offsetWidth) > offsetWidth) - ) { + - x = (x - (oContextElement.offsetWidth + offsetWidth)); + oNode = null; - } - else { + - x = rightConstraint; + this.logger.log("Searching DOM for items to initialize."); - } + - } + if(this.srcElement.tagName) { - if (y < 10) { + - y = topConstraint; + var sSrcElementTagName = this.srcElement.tagName.toUpperCase(); - } else if (y > bottomConstraint) { + - if(oContextElement && (y > offsetHeight)) { + - y = ((y + oContextElement.offsetHeight) - offsetHeight); + switch(sSrcElementTagName) { - } - else { + - y = bottomConstraint; + case "DIV": - } + - } + if(this._aListElements.length > 0) { - oConfig.setProperty("x", x, true); - oConfig.setProperty("y", y, true); + - }; + this.logger.log("Found " + + this._aListElements.length + -// Event handlers for configuration properties + " item groups to initialize."); -/** -* Event handler for when the "position" configuration property of a -* MenuModule changes. -* @param {String} p_sType The name of the event that was fired. -* @param {Array} p_aArgs Collection of arguments sent when the event -* was fired. -* @param {YAHOO.widget.MenuModule} p_oMenuModule The MenuModule instance fired -* the event. -*/ -YAHOO.widget.MenuModule.prototype.configPosition = + - function(p_sType, p_aArgs, p_oMenuModule) { + var i = this._aListElements.length - 1; - var sCSSPosition = p_aArgs[0] == "static" ? "static" : "absolute"; + - this._oDom.setStyle(this.element, "position", sCSSPosition); + do { - }; + + oNode = this._aListElements[i].firstChild; -/** -* Event handler for when the "iframe" configuration property of a -* MenuModule changes. -* @param {String} p_sType The name of the event that was fired. -* @param {Array} p_aArgs Collection of arguments sent when the event -* was fired. -* @param {YAHOO.widget.MenuModule} p_oMenuModule The MenuModule instance fired -* the event. -* @see YAHOO.widget.Overlay#configIframe -*/ -YAHOO.widget.MenuModule.prototype.configIframe = + - function(p_sType, p_aArgs, p_oMenuModule) { + this.logger.log("Scanning " + - if(this.cfg.getProperty("position") == "dynamic") { + this._aListElements[i].childNodes.length + - YAHOO.widget.MenuModule.superclass.configIframe.call( - this, - p_sType, - p_aArgs, - p_oMenuModule - ); + " child nodes for items to initialize."); - } + - }; + do { -// Public methods + -YAHOO.widget.MenuModule.prototype.toString = function() { + if( - return ("Menu " + this.id); + oNode && -}; + oNode.tagName && + oNode.tagName.toUpperCase() == "LI" -/** -* Sets the title of a group of items. -* @param {String} p_sGroupTitle The title of the group. -* @param {Number} p_nGroupIndex Optional. Number indicating the group to which -* the title belongs. -*/ -YAHOO.widget.MenuModule.prototype.setItemGroupTitle = + ) { - function(p_sGroupTitle, p_nGroupIndex) { + - if(typeof p_sGroupTitle == "string" && p_sGroupTitle.length > 0) { + this.logger.log("Initializing " + - var Dom = this._oDom; + oNode.tagName + " node."); - var nGroupIndex = - typeof p_nGroupIndex == "number" ? p_nGroupIndex : 0; + - var oTitle = this._aGroupTitleElements[nGroupIndex]; + this.addItem( + new this.ITEM_TYPE( - if(oTitle) { + oNode, - oTitle.innerHTML = p_sGroupTitle; + { parent: this } - } - else { + ), - oTitle = document.createElement(this.GROUP_TITLE_TAG_NAME); + i - oTitle.innerHTML = p_sGroupTitle; + ); - this._aGroupTitleElements[nGroupIndex] = oTitle; + - } + } + - var i = this._aGroupTitleElements.length - 1; - var nFirstIndex; + } - do { + while((oNode = oNode.nextSibling)); - if(this._aGroupTitleElements[i]) { + - Dom.removeClass( - this._aGroupTitleElements[i], - "first-of-type" - ); + } - nFirstIndex = i; + while(i--); - } + - } - while(i--); + } + - if(nFirstIndex !== null) { + break; - Dom.addClass( - this._aGroupTitleElements[nFirstIndex], - "first-of-type" - ); + - } + case "SELECT": - } + - }; + this.logger.log("Scanning " + + this.srcElement.childNodes.length + -/** -* Appends the specified item to a MenuModule instance. -* @param {YAHOO.widget.MenuModuleItem} p_oItem The item to be added. -* @param {Number} p_nGroupIndex Optional. Number indicating the group to which -* the item belongs. -* @return The item that was added to the MenuModule. -* @type YAHOO.widget.MenuModuleItem -*/ -YAHOO.widget.MenuModule.prototype.addItem = function(p_oItem, p_nGroupIndex) { + " child nodes for items to initialize."); - if(p_oItem) { + - return this._addItemToGroup(p_nGroupIndex, p_oItem); + oNode = this.srcElement.firstChild; - } + -}; + do { + -/** -* Inserts an item into a MenuModule instance at the specified index. -* @param {YAHOO.widget.MenuModuleItem} p_oItem The item to be inserted. -* @param {Number} p_nItemIndex Number indicating the ordinal position -* at which the item should be added. -* @param {Number} p_nGroupIndex Optional. Number indicating the group to which -* the item belongs. -* @return The item that was inserted into the MenuModule. -* @type YAHOO.widget.MenuModuleItem -*/ -YAHOO.widget.MenuModule.prototype.insertItem = + if(oNode && oNode.tagName) { - function(p_oItem, p_nItemIndex, p_nGroupIndex) { + - if(p_oItem) { + switch(oNode.tagName.toUpperCase()) { - return this._addItemToGroup(p_nGroupIndex, p_oItem, p_nItemIndex); + - } + case "OPTGROUP": - }; + case "OPTION": + -/** -* Removes the specified item from a MenuModule instance. -* @param {YAHOO.widget.MenuModuleItem/Number} p_oObject The item or index of -* the item to be removed. -* @param {Number} p_nGroupIndex Optional. Number indicating the group to which -* the item belongs. -* @return The item that was removed from the MenuModule. -* @type YAHOO.widget.MenuModuleItem -*/ -YAHOO.widget.MenuModule.prototype.removeItem = + this.logger.log("Initializing " + - function(p_oObject, p_nGroupIndex) { + oNode.tagName + " node."); - if(typeof p_oObject != "undefined") { + - var oItem; + this.addItem( - if(p_oObject instanceof YAHOO.widget.MenuModuleItem) { + new this.ITEM_TYPE( - oItem = - this._removeItemFromGroupByValue(p_nGroupIndex, p_oObject); + oNode, - } - else if(typeof p_oObject == "number") { + { parent: this } - oItem = - this._removeItemFromGroupByIndex(p_nGroupIndex, p_oObject); + ) - } + ); - if(oItem) { + - oItem.destroy(); + break; - this.logger.log("Item removed." + - " Text: " + oItem.cfg.getProperty("text") + ", " + - " Index: " + oItem.index + ", " + - " Group Index: " + oItem.groupIndex); + - return oItem; + } - } + - } + } - }; + + } -/** -* Returns a multi-dimensional array of all of a MenuModule's items. -* @return An array of items. -* @type Array -*/ -YAHOO.widget.MenuModule.prototype.getItemGroups = function() { + while((oNode = oNode.nextSibling)); - return this._aItemGroups; + -}; + break; + -/** -* Returns the item at the specified index. -* @param {Number} p_nItemIndex Number indicating the ordinal position of the -* item to be retrieved. -* @param {Number} p_nGroupIndex Optional. Number indicating the group to which -* the item belongs. -* @return An item. -* @type YAHOO.widget.MenuModuleItem -*/ -YAHOO.widget.MenuModule.prototype.getItem = + } - function(p_nItemIndex, p_nGroupIndex) { + - if(typeof p_nItemIndex == "number") { + } - var aGroup = this._getItemGroup(p_nGroupIndex); + - if(aGroup) { +}, - return aGroup[p_nItemIndex]; + - } + - } +/** - }; +* @method _getFirstEnabledItem +* @description Returns the first enabled item in the menu. -/** -* Removes the MenuModule instance's element from the DOM and sets all child -* elements to null. -*/ -YAHOO.widget.MenuModule.prototype.destroy = function() { +* @return {YAHOO.widget.MenuItem} +* @private - // Remove Custom Event listeners +*/ - this.mouseOverEvent.unsubscribeAll(); - this.mouseOutEvent.unsubscribeAll(); - this.mouseDownEvent.unsubscribeAll(); - this.mouseUpEvent.unsubscribeAll(); - this.clickEvent.unsubscribeAll(); - this.keyPressEvent.unsubscribeAll(); - this.keyDownEvent.unsubscribeAll(); - this.keyUpEvent.unsubscribeAll(); +_getFirstEnabledItem: function() { + - var nItemGroups = this._aItemGroups.length; - var nItems; - var oItemGroup; - var oItem; - var i; - var n; + var nGroups = this._aItemGroups.length, + oItem, - // Remove all items + aItemGroup; - if(nItemGroups > 0) { + - i = nItemGroups - 1; + for(var i=0; i 0) { + - n = nItems - 1; + var nItems = aItemGroup.length; - do { + - oItem = this._aItemGroups[i][n]; + for(var n=0; n= aGroup.length); + + + + + + if(aGroup[p_nItemIndex]) { + + + + aGroup.splice(p_nItemIndex, 0, oItem); + + + + } + + else { + + + + aGroup[p_nItemIndex] = oItem; + + + + } + + + + + + oGroupItem = aGroup[p_nItemIndex]; + + + + if(oGroupItem) { + + + + if( + + bAppend && + + ( + + !oGroupItem.element.parentNode || + + oGroupItem.element.parentNode.nodeType == 11 + + ) + + ) { + + + + this._aListElements[nGroupIndex].appendChild( + + oGroupItem.element + + ); + + + + } + + else { + + + + + + /** + + * Returns the next sibling of an item in an array. + + * @private + + * @param {p_aArray} Array to search. + + * @param {p_nStartIndex} Number indicating the index to + + * start searching the array. + + * @return {Object} + + */ + + function getNextItemSibling(p_aArray, p_nStartIndex) { + + + + return ( + + p_aArray[p_nStartIndex] || + + getNextItemSibling( + + p_aArray, + + (p_nStartIndex+1) + + ) + + ); + + + + } + + + + + + var oNextItemSibling = + + getNextItemSibling(aGroup, (p_nItemIndex+1)); + + + + if( + + oNextItemSibling && + + ( + + !oGroupItem.element.parentNode || + + oGroupItem.element.parentNode.nodeType == 11 + + ) + + ) { + + + + this._aListElements[nGroupIndex].insertBefore( + + oGroupItem.element, + + oNextItemSibling.element + + ); + + + + } + + + + } + + + + + + oGroupItem.parent = this; + + + + this._subscribeToItemEvents(oGroupItem); + + + + this._configureSubmenu(oGroupItem); + + + + this._updateItemProperties(nGroupIndex); + + + + this.logger.log("Item inserted." + + + " Text: " + oGroupItem.cfg.getProperty("text") + ", " + + + " Index: " + oGroupItem.index + ", " + + + " Group Index: " + oGroupItem.groupIndex); + + + + this.itemAddedEvent.fire(oGroupItem); + + + + return oGroupItem; + + + + } + + + + } + + else { + + + + var nItemIndex = aGroup.length; + + + + aGroup[nItemIndex] = oItem; + + + + oGroupItem = aGroup[nItemIndex]; + + + + + + if(oGroupItem) { + + + + if( + + !Dom.isAncestor( + + this._aListElements[nGroupIndex], + + oGroupItem.element + + ) + + ) { + + + + this._aListElements[nGroupIndex].appendChild( + + oGroupItem.element + + ); + + + + } + + + + oGroupItem.element.setAttribute("groupindex", nGroupIndex); + + oGroupItem.element.setAttribute("index", nItemIndex); + + + + oGroupItem.parent = this; + + + + oGroupItem.index = nItemIndex; + + oGroupItem.groupIndex = nGroupIndex; + + + + this._subscribeToItemEvents(oGroupItem); + + + + this._configureSubmenu(oGroupItem); + + + + if(nItemIndex === 0) { + + + + Dom.addClass(oGroupItem.element, "first-of-type"); + + + + } + + + + this.logger.log("Item added." + + + " Text: " + oGroupItem.cfg.getProperty("text") + ", " + + + " Index: " + oGroupItem.index + ", " + + + " Group Index: " + oGroupItem.groupIndex); + + + + + + this.itemAddedEvent.fire(oGroupItem); + + + + return oGroupItem; + + + + } + + + + } + + + + } + + + +}, + + + + + +/** + +* @method _removeItemFromGroupByIndex + +* @description Removes a menu item from a group by index. Returns the menu + +* item that was removed. + +* @private + +* @param {Number} p_nGroupIndex Number indicating the group to which the menu + +* item belongs. + +* @param {Number} p_nItemIndex Number indicating the index of the menu item + +* to be removed. + +* @return {YAHOO.widget.MenuItem} + +*/ + +_removeItemFromGroupByIndex: function(p_nGroupIndex, p_nItemIndex) { + + + + var nGroupIndex = typeof p_nGroupIndex == "number" ? p_nGroupIndex : 0, + + aGroup = this._getItemGroup(nGroupIndex); + + + + if(aGroup) { + + + + var aArray = aGroup.splice(p_nItemIndex, 1), + + oItem = aArray[0]; + + + + if(oItem) { + + + + // Update the index and className properties of each member + + + + this._updateItemProperties(nGroupIndex); + + + + if(aGroup.length === 0) { + + + + // Remove the UL + + + + var oUL = this._aListElements[nGroupIndex]; + + + + if(this.body && oUL) { + + + + this.body.removeChild(oUL); + + + + } + + + + // Remove the group from the array of items + + + + this._aItemGroups.splice(nGroupIndex, 1); + + + + + + // Remove the UL from the array of ULs + + + + this._aListElements.splice(nGroupIndex, 1); + + + + + + /* + + Assign the "first-of-type" class to the new first UL + + in the collection + + */ + + + + oUL = this._aListElements[0]; + + + + if(oUL) { + + + + Dom.addClass(oUL, "first-of-type"); + + + + } + + + + } + + + + + + this.itemRemovedEvent.fire(oItem); + + + + + + // Return a reference to the item that was removed + + + + return oItem; + + + + } + + + + } + + + +}, + + + + + +/** + +* @method _removeItemFromGroupByValue + +* @description Removes a menu item from a group by reference. Returns the + +* menu item that was removed. + +* @private + +* @param {Number} p_nGroupIndex Number indicating the group to which the + +* menu item belongs. + +* @param {YAHOO.widget.MenuItem} p_oItem Object reference for the MenuItem + +* instance to be removed. + +* @return {YAHOO.widget.MenuItem} + +*/ + +_removeItemFromGroupByValue: function(p_nGroupIndex, p_oItem) { + + + + var aGroup = this._getItemGroup(p_nGroupIndex); + + + + if(aGroup) { + + + + var nItems = aGroup.length, + + nItemIndex = -1; + + + + if(nItems > 0) { + + + + var i = nItems-1; + + + + do { + + + + if(aGroup[i] == p_oItem) { + + + + nItemIndex = i; + + break; + + + + } + + + + } + + while(i--); + + + + if(nItemIndex > -1) { + + + + return this._removeItemFromGroupByIndex( + + p_nGroupIndex, + + nItemIndex + + ); + + + + } + + + + } + + + + } + + + +}, + + + + + +/** + +* @method _updateItemProperties + +* @description Updates the "index," "groupindex," and "className" properties + +* of the menu items in the specified group. + +* @private + +* @param {Number} p_nGroupIndex Number indicating the group of items to update. + +*/ + +_updateItemProperties: function(p_nGroupIndex) { + + + + var aGroup = this._getItemGroup(p_nGroupIndex), + + nItems = aGroup.length; + + + + if(nItems > 0) { + + + + var i = nItems - 1, + + oItem, + + oLI; + + + + // Update the index and className properties of each member + + + + do { + + + + oItem = aGroup[i]; + + + + if(oItem) { + + + + oLI = oItem.element; + + + + oItem.index = i; + + oItem.groupIndex = p_nGroupIndex; + + + + oLI.setAttribute("groupindex", p_nGroupIndex); + + oLI.setAttribute("index", i); + + + + Dom.removeClass(oLI, "first-of-type"); + + + + } + + + + } + + while(i--); + + + + + + if(oLI) { + + + + Dom.addClass(oLI, "first-of-type"); + + + + } + + + + } + + + +}, + + + + + +/** + +* @method _createItemGroup + +* @description Creates a new menu item group (array) and its associated + +* <ul> element. Returns an aray of menu item groups. + +* @private + +* @param {Number} p_nIndex Number indicating the group to create. + +* @return {Array} + +*/ + +_createItemGroup: function(p_nIndex) { + + + + if(!this._aItemGroups[p_nIndex]) { + + + + this._aItemGroups[p_nIndex] = []; + + + + var oUL = document.createElement("ul"); + + + + this._aListElements[p_nIndex] = oUL; + + + + return this._aItemGroups[p_nIndex]; + + + + } + + + +}, + + + + + +/** + +* @method _getItemGroup + +* @description Returns the menu item group at the specified index. + +* @private + +* @param {Number} p_nIndex Number indicating the index of the menu item group + +* to be retrieved. + +* @return {Array} + +*/ + +_getItemGroup: function(p_nIndex) { + + + + var nIndex = ((typeof p_nIndex == "number") ? p_nIndex : 0); + + + + return this._aItemGroups[nIndex]; + + + +}, + + + + + +/** + +* @method _configureSubmenu + +* @description Subscribes the menu item's submenu to its parent menu's events. + +* @private + +* @param {YAHOO.widget.MenuItem} p_oItem Object reference for the MenuItem + +* instance with the submenu to be configured. + +*/ + +_configureSubmenu: function(p_oItem) { + + + + var oSubmenu = p_oItem.cfg.getProperty("submenu"); + + + + if(oSubmenu) { + + + + /* + + Listen for configuration changes to the parent menu + + so they they can be applied to the submenu. + + */ + + + + this.cfg.configChangedEvent.subscribe( + + this._onParentMenuConfigChange, + + oSubmenu, + + true + + ); + + + + this.renderEvent.subscribe( + + this._onParentMenuRender, + + oSubmenu, + + true + + ); + + + + oSubmenu.beforeShowEvent.subscribe( + + this._onSubmenuBeforeShow, + + oSubmenu, + + true + + ); + + + + oSubmenu.showEvent.subscribe( + + this._onSubmenuShow, + + oSubmenu, + + true + + ); + + + + oSubmenu.hideEvent.subscribe( + + this._onSubmenuHide, + + oSubmenu, + + true + + ); + + + + } + + + +}, + + + + + +/** + +* @method _subscribeToItemEvents + +* @description Subscribes a menu to a menu item's event. + +* @private + +* @param {YAHOO.widget.MenuItem} p_oItem Object reference for the MenuItem + +* instance whose events should be subscribed to. + +*/ + +_subscribeToItemEvents: function(p_oItem) { + + + + p_oItem.focusEvent.subscribe(this._onMenuItemFocus, p_oItem, this); + + + + p_oItem.blurEvent.subscribe(this._onMenuItemBlur, this, true); + + + + p_oItem.cfg.configChangedEvent.subscribe( + + this._onMenuItemConfigChange, + + p_oItem, + + this + + ); + + + +}, + + + + + +/** + +* @method _getOffsetWidth + +* @description Returns the offset width of the menu's + +* <div> element. + +* @private + +*/ + +_getOffsetWidth: function() { + + + + var oClone = this.element.cloneNode(true); + + + + Dom.setStyle(oClone, "width", ""); + + + + document.body.appendChild(oClone); + + + + var sWidth = oClone.offsetWidth; + + + + document.body.removeChild(oClone); + + + + return sWidth; + + + +}, + + + + + +/** + +* @method _cancelHideDelay + +* @description Cancels the call to "hideMenu." + +* @private + +*/ + +_cancelHideDelay: function() { + + + + var oRoot = this.getRoot(); + + + + if(oRoot._nHideDelayId) { + + + + window.clearTimeout(oRoot._nHideDelayId); + + + + } + + + +}, + + + + + +/** + +* @method _execHideDelay + +* @description Hides the menu after the number of milliseconds specified by + +* the "hidedelay" configuration property. + +* @private + +*/ + +_execHideDelay: function() { + + + + this._cancelHideDelay(); + + + + var oRoot = this.getRoot(), + + me = this; + + + + function hideMenu() { + + + + if(oRoot.activeItem) { + + + + oRoot.clearActiveItem(); + + + + } + + + + if(oRoot == me && me.cfg.getProperty("position") == "dynamic") { + + + + me.hide(); + + + + } + + + + } + + + + + + oRoot._nHideDelayId = + + window.setTimeout(hideMenu, oRoot.cfg.getProperty("hidedelay")); + + + +}, + + + + + +/** + +* @method _cancelShowDelay + +* @description Cancels the call to the "showMenu." + +* @private + +*/ + +_cancelShowDelay: function() { + + + + var oRoot = this.getRoot(); + + + + if(oRoot._nShowDelayId) { + + + + window.clearTimeout(oRoot._nShowDelayId); + + + + } + + + +}, + + + + + +/** + +* @method _execShowDelay + +* @description Shows the menu after the number of milliseconds specified by + +* the "showdelay" configuration property have ellapsed. + +* @private + +* @param {YAHOO.widget.Menu} p_oMenu Object specifying the menu that should + +* be made visible. + +*/ + +_execShowDelay: function(p_oMenu) { + + + + var oRoot = this.getRoot(); + + + + function showMenu() { + + + + p_oMenu.show(); + + + + } + + + + + + oRoot._nShowDelayId = + + window.setTimeout(showMenu, oRoot.cfg.getProperty("showdelay")); + + + +}, + + + + + + + +// Protected methods + + + + + +/** + +* @method _onMouseOver + +* @description "mouseover" event handler for the menu. + +* @protected + +* @param {String} p_sType String representing the name of the event that + +* was fired. + +* @param {Array} p_aArgs Array of arguments sent when the event was fired. + +* @param {YAHOO.widget.Menu} p_oMenu Object representing the menu that + +* fired the event. + +*/ + +_onMouseOver: function(p_sType, p_aArgs, p_oMenu) { + + + + var oEvent = p_aArgs[0], + + oItem = p_aArgs[1], + + oTarget = Event.getTarget(oEvent); + + + + + + if( + + !this._bHandledMouseOverEvent && + + (oTarget == this.element || Dom.isAncestor(this.element, oTarget)) + + ) { + + + + this.clearActiveItem(); + + + + this._bHandledMouseOverEvent = true; + + this._bHandledMouseOutEvent = false; + + + + } + + + + + + if( + + oItem && !oItem.handledMouseOverEvent && + + !oItem.cfg.getProperty("disabled") && + + (oTarget == oItem.element || Dom.isAncestor(oItem.element, oTarget)) + + ) { + + + + var nShowDelay = this.cfg.getProperty("showdelay"), + + bShowDelay = (nShowDelay > 0); + + + + + + if(bShowDelay) { + + + + this._cancelShowDelay(); + + + + } + + + + + + var oActiveItem = this.activeItem; + + + + if(oActiveItem) { + + + + oActiveItem.cfg.setProperty("selected", false); + + + + var oActiveSubmenu = oActiveItem.cfg.getProperty("submenu"); + + + + if(oActiveSubmenu) { + + + + oActiveSubmenu.hide(); + + + + } + + + + } + + + + + + var oItemCfg = oItem.cfg; + + + + // Select and focus the current menu item + + + + oItemCfg.setProperty("selected", true); + + oItem.focus(); + + + + + + if(this.cfg.getProperty("autosubmenudisplay")) { + + + + // Show the submenu this menu item + + + + var oSubmenu = oItemCfg.getProperty("submenu"); + + + + if(oSubmenu) { + + + + if(bShowDelay) { + + + + this._execShowDelay(oSubmenu); + + + + } + + else { + + + + oSubmenu.show(); + + + + } + + + + } + + + + } + + + + oItem.handledMouseOverEvent = true; + + oItem.handledMouseOutEvent = false; + + + + } + + + +}, + + + + + +/** + +* @method _onMouseOut + +* @description "mouseout" event handler for the menu. + +* @protected + +* @param {String} p_sType String representing the name of the event that + +* was fired. + +* @param {Array} p_aArgs Array of arguments sent when the event was fired. + +* @param {YAHOO.widget.Menu} p_oMenu Object representing the menu that + +* fired the event. + +*/ + +_onMouseOut: function(p_sType, p_aArgs, p_oMenu) { + + + + var oEvent = p_aArgs[0], + + oItem = p_aArgs[1], + + oRelatedTarget = Event.getRelatedTarget(oEvent), + + bMovingToSubmenu = false; + + + + + + if(oItem && !oItem.cfg.getProperty("disabled")) { + + + + var oItemCfg = oItem.cfg, + + oSubmenu = oItemCfg.getProperty("submenu"); + + + + + + if( + + oSubmenu && + + ( + + oRelatedTarget == oSubmenu.element || + + Dom.isAncestor(oSubmenu.element, oRelatedTarget) + + ) + + ) { + + + + bMovingToSubmenu = true; + + + + } + + + + + + if( + + !oItem.handledMouseOutEvent && + + ( + + ( + + oRelatedTarget != oItem.element && + + !Dom.isAncestor(oItem.element, oRelatedTarget) + + ) || bMovingToSubmenu + + ) + + ) { + + + + if( + + !oSubmenu || + + (oSubmenu && !oSubmenu.cfg.getProperty("visible")) + + ) { + + + + oItem.cfg.setProperty("selected", false); + + + + if( + + oSubmenu && + + oSubmenu.cfg.getProperty("showdelay") && + + !oSubmenu.cfg.getProperty("visible") + + ) { + + + + this._cancelShowDelay(); + + + + } + + + + } + + + + + + oItem.handledMouseOutEvent = true; + + oItem.handledMouseOverEvent = false; + + + + } + + + + } + + + + + + if( + + !this._bHandledMouseOutEvent && + + ( + + ( + + oRelatedTarget != this.element && + + !Dom.isAncestor(this.element, oRelatedTarget) + + ) + + || bMovingToSubmenu + + ) + + ) { + + + + this._bHandledMouseOutEvent = true; + + this._bHandledMouseOverEvent = false; + + + + } + + + +}, + + + + + +/** + +* @method _onClick + +* @description "click" event handler for the menu. + +* @protected + +* @param {String} p_sType String representing the name of the event that + +* was fired. + +* @param {Array} p_aArgs Array of arguments sent when the event was fired. + +* @param {YAHOO.widget.Menu} p_oMenu Object representing the menu that + +* fired the event. + +*/ + +_onClick: function(p_sType, p_aArgs, p_oMenu) { + + + + var oEvent = p_aArgs[0], + + oItem = p_aArgs[1], + + oTarget = Event.getTarget(oEvent); + + + + if(oItem && !oItem.cfg.getProperty("disabled")) { + + + + var oItemCfg = oItem.cfg, + + oSubmenu = oItemCfg.getProperty("submenu"); + + + + + + /* + + ACCESSIBILITY FEATURE FOR SCREEN READERS: + + Expand/collapse the submenu when the user clicks + + on the submenu indicator image. + + */ + + + + if(oTarget == oItem.submenuIndicator && oSubmenu) { + + + + if(oSubmenu.cfg.getProperty("visible")) { + + + + oSubmenu.hide(); + + + + } + + else { + + + + this.clearActiveItem(); + + + + this.activeItem = oItem; + + + + oItem.cfg.setProperty("selected", true); + + + + oSubmenu.show(); + + + + } + + + + } + + else { + + + + var sURL = oItemCfg.getProperty("url"), + + bCurrentPageURL = (sURL.substr((sURL.length-1),1) == "#"), + + sTarget = oItemCfg.getProperty("target"), + + bHasTarget = (sTarget && sTarget.length > 0); + + + + /* + + Prevent the browser from following links + + equal to "#" + + */ + + + + if( + + oTarget.tagName.toUpperCase() == "A" && + + bCurrentPageURL && !bHasTarget + + ) { + + + + Event.preventDefault(oEvent); + + + + } + + + + if( + + oTarget.tagName.toUpperCase() != "A" && + + !bCurrentPageURL && !bHasTarget + + ) { + + + + /* + + Follow the URL of the item regardless of + + whether or not the user clicked specifically + + on the anchor element. + + */ + + + + document.location = sURL; + + + + } + + + + + + /* + + If the item doesn't navigate to a URL and it doesn't have + + a submenu, then collapse the menu tree. + + */ + + + + if(bCurrentPageURL && !oSubmenu) { + + + + var oRoot = this.getRoot(); + + + + if(oRoot.cfg.getProperty("position") == "static") { + + + + oRoot.clearActiveItem(); + + + + } + + else { + + + + oRoot.hide(); + + + + } + + + + } + + + + } + + + + } + + + +}, + + + + + +/** + +* @method _onKeyDown + +* @description "keydown" event handler for the menu. + +* @protected + +* @param {String} p_sType String representing the name of the event that + +* was fired. + +* @param {Array} p_aArgs Array of arguments sent when the event was fired. + +* @param {YAHOO.widget.Menu} p_oMenu Object representing the menu that + +* fired the event. + +*/ + +_onKeyDown: function(p_sType, p_aArgs, p_oMenu) { + + + + var oEvent = p_aArgs[0], + + oItem = p_aArgs[1], + + oSubmenu; + + + + if(oItem && !oItem.cfg.getProperty("disabled")) { + + + + var oItemCfg = oItem.cfg, + + oParentItem = this.parent, + + oRoot, + + oNextItem; + + + + + + switch(oEvent.keyCode) { + + + + case 38: // Up arrow + + case 40: // Down arrow + + + + if( + + oItem == this.activeItem && + + !oItemCfg.getProperty("selected") + + ) { + + + + oItemCfg.setProperty("selected", true); + + + + } + + else { + + + + oNextItem = (oEvent.keyCode == 38) ? + + oItem.getPreviousEnabledSibling() : + + oItem.getNextEnabledSibling(); + + + + if(oNextItem) { + + + + this.clearActiveItem(); + + + + oNextItem.cfg.setProperty("selected", true); + + oNextItem.focus(); + + + + } + + + + } + + + + Event.preventDefault(oEvent); + + + + break; + + + + + + case 39: // Right arrow + + + + oSubmenu = oItemCfg.getProperty("submenu"); + + + + if(oSubmenu) { + + + + if(!oItemCfg.getProperty("selected")) { + + + + oItemCfg.setProperty("selected", true); + + + + } + + + + oSubmenu.show(); + + + + oSubmenu.setInitialSelection(); + + + + } + + else { + + + + oRoot = this.getRoot(); + + + + if(oRoot instanceof YAHOO.widget.MenuBar) { + + + + oNextItem = oRoot.activeItem.getNextEnabledSibling(); + + + + if(oNextItem) { + + + + oRoot.clearActiveItem(); + + + + oNextItem.cfg.setProperty("selected", true); + + + + oSubmenu = oNextItem.cfg.getProperty("submenu"); + + + + if(oSubmenu) { + + + + oSubmenu.show(); + + + + } + + + + oNextItem.focus(); + + + + } + + + + } + + + + } + + + + + + Event.preventDefault(oEvent); + + + + break; + + + + + + case 37: // Left arrow + + + + if(oParentItem) { + + + + var oParentMenu = oParentItem.parent; + + + + if(oParentMenu instanceof YAHOO.widget.MenuBar) { + + + + oNextItem = + + oParentMenu.activeItem.getPreviousEnabledSibling(); + + + + if(oNextItem) { + + + + oParentMenu.clearActiveItem(); + + + + oNextItem.cfg.setProperty("selected", true); + + + + oSubmenu = oNextItem.cfg.getProperty("submenu"); + + + + if(oSubmenu) { + + + + oSubmenu.show(); + + + + } + + + + oNextItem.focus(); + + + + } + + + + } + + else { + + + + this.hide(); + + + + oParentItem.focus(); + + + + } + + + + } + + + + Event.preventDefault(oEvent); + + + + break; + + + + } + + + + + + } + + + + + + if(oEvent.keyCode == 27) { // Esc key + + + + if(this.cfg.getProperty("position") == "dynamic") { + + + + this.hide(); + + + + if(this.parent) { + + + + this.parent.focus(); + + + + } + + + + } + + else if(this.activeItem) { + + + + oSubmenu = this.activeItem.cfg.getProperty("submenu"); + + + + if(oSubmenu && oSubmenu.cfg.getProperty("visible")) { + + + + oSubmenu.hide(); + + this.activeItem.focus(); + + + + } + + else { + + + + this.activeItem.cfg.setProperty("selected", false); + + this.activeItem.blur(); + + + + } + + + + } + + + + + + Event.preventDefault(oEvent); + + + + } + + + +}, + + + + + +/** + +* @method _onTextResize + +* @description "textresize" event handler for the menu. + +* @protected + +* @param {String} p_sType String representing the name of the event that + +* was fired. + +* @param {Array} p_aArgs Array of arguments sent when the event was fired. + +* @param {YAHOO.widget.Menu} p_oMenu Object representing the menu that + +* fired the event. + +*/ + +_onTextResize: function(p_sType, p_aArgs, p_oMenu) { + + + + if(this.browser == "gecko" && !this._handleResize) { + + + + this._handleResize = true; + + return; + + + + } + + + + + + var oConfig = this.cfg; + + + + if(oConfig.getProperty("position") == "dynamic") { + + + + oConfig.setProperty("width", (this._getOffsetWidth() + "px")); + + + + } + + + +}, + + + + + + + +// Private methods + + + + + +/** + +* @method _onInit + +* @description "init" event handler for the menu. + +* @private + +* @param {String} p_sType String representing the name of the event that + +* was fired. + +* @param {Array} p_aArgs Array of arguments sent when the event was fired. + +* @param {YAHOO.widget.Menu} p_oMenu Object representing the menu that + +* fired the event. + +*/ + +_onInit: function(p_sType, p_aArgs, p_oMenu) { + + + + if( + + ( + + (this.parent && !this.lazyLoad) || + + (!this.parent && this.cfg.getProperty("position") == "static") || + + ( + + !this.parent && + + !this.lazyLoad && + + this.cfg.getProperty("position") == "dynamic" + + ) + + ) && + + this.getItemGroups().length === 0 + + ) { + + + + if(this.srcElement) { + + + + this._initSubTree(); + + + + } + + + + + + if(this.itemData) { + + + + this.addItems(this.itemData); + + + + } + + + + } + + else if(this.lazyLoad) { + + + + this.cfg.fireQueue(); + + + + } + + + +}, + + + + + +/** + +* @method _onBeforeRender + +* @description "beforerender" event handler for the menu. Appends all of the + +* <ul>, <li> and their accompanying + +* title elements to the body element of the menu. + +* @private + +* @param {String} p_sType String representing the name of the event that + +* was fired. + +* @param {Array} p_aArgs Array of arguments sent when the event was fired. + +* @param {YAHOO.widget.Menu} p_oMenu Object representing the menu that + +* fired the event. + +*/ + +_onBeforeRender: function(p_sType, p_aArgs, p_oMenu) { + + + + var oConfig = this.cfg, + + oEl = this.element, + + nListElements = this._aListElements.length; + + + + + + if(nListElements > 0) { + + + + var i = 0, + + bFirstList = true, + + oUL, + + oGroupTitle; + + + + + + do { + + + + oUL = this._aListElements[i]; + + + + if(oUL) { + + + + if(bFirstList) { + + + + Dom.addClass(oUL, "first-of-type"); + + bFirstList = false; + + + + } + + + + + + if(!Dom.isAncestor(oEl, oUL)) { + + + + this.appendToBody(oUL); + + + + } + + + + + + oGroupTitle = this._aGroupTitleElements[i]; + + + + if(oGroupTitle) { + + + + if(!Dom.isAncestor(oEl, oGroupTitle)) { + + + + oUL.parentNode.insertBefore(oGroupTitle, oUL); + + + + } + + + + + + Dom.addClass(oUL, "hastitle"); + + + + } + + + + } + + + + i++; + + + + } + + while(i < nListElements); + + + + } + + + +}, + + + + + +/** + +* @method _onRender + +* @description "render" event handler for the menu. + +* @private + +* @param {String} p_sType String representing the name of the event that + +* was fired. + +* @param {Array} p_aArgs Array of arguments sent when the event was fired. + +* @param {YAHOO.widget.Menu} p_oMenu Object representing the menu that + +* fired the event. + +*/ + +_onRender: function(p_sType, p_aArgs, p_oMenu) { + + + + if(this.cfg.getProperty("position") == "dynamic") { + + + + var sWidth = + + this.element.parentNode.tagName.toUpperCase() == "BODY" ? + + this.element.offsetWidth : this._getOffsetWidth(); + + + + this.cfg.setProperty("width", (sWidth + "px")); + + + + } + + + +}, + + + + + +/** + +* @method _onBeforeShow + +* @description "beforeshow" event handler for the menu. + +* @private + +* @param {String} p_sType String representing the name of the event that + +* was fired. + +* @param {Array} p_aArgs Array of arguments sent when the event was fired. + +* @param {YAHOO.widget.Menu} p_oMenu Object representing the menu that + +* fired the event. + +*/ + +_onBeforeShow: function(p_sType, p_aArgs, p_oMenu) { + + + + if(this.lazyLoad && this.getItemGroups().length === 0) { + + + + if(this.srcElement) { + + + + this._initSubTree(); + + + + } + + + + + + if(this.itemData) { + + + + if( + + this.parent && this.parent.parent && + + this.parent.parent.srcElement && + + this.parent.parent.srcElement.tagName.toUpperCase() == "SELECT" + + ) { + + + + var nOptions = this.itemData.length; + + + + for(var n=0; n viewPortWidth) { + + + + if( + + oContextElement && + + ((x - oContextElement.offsetWidth) > offsetWidth) + + ) { + + + + x = (x - (oContextElement.offsetWidth + offsetWidth)); + + + + } + + else { + + + + x = rightConstraint; + + + + } + + + + } + + + + if (y < 10) { + + + + y = topConstraint; + + + + } else if (y > bottomConstraint) { + + + + if(oContextElement && (y > offsetHeight)) { + + + + y = ((y + oContextElement.offsetHeight) - offsetHeight); + + + + } + + else { + + + + y = bottomConstraint; + + + + } + + + + } + + + + oConfig.setProperty("x", x, true); + + oConfig.setProperty("y", y, true); + + oConfig.setProperty("xy", [x,y], true); + + + +}, + + + + + +/** + +* @method configVisible + +* @description Event handler for when the "visible" configuration property + +* the menu changes. + +* @param {String} p_sType String representing the name of the event that + +* was fired. + +* @param {Array} p_aArgs Array of arguments sent when the event was fired. + +* @param {YAHOO.widget.Menu} p_oMenu Object representing the menu that + +* fired the event. + +*/ + +configVisible: function(p_sType, p_aArgs, p_oMenu) { + + + + if(this.cfg.getProperty("position") == "dynamic") { + + + + YAHOO.widget.Menu.superclass.configVisible.call( + + this, + + p_sType, + + p_aArgs, + + p_oMenu + + ); + + + + } + + else { + + + + var bVisible = p_aArgs[0], + + sDisplay = Dom.getStyle(this.element, "display"); + + + + if(bVisible) { + + + + if(sDisplay != "block") { + + this.beforeShowEvent.fire(); + + Dom.setStyle(this.element, "display", "block"); + + this.showEvent.fire(); + + } + + + + } + + else { + + + + if(sDisplay == "block") { + + this.beforeHideEvent.fire(); + + Dom.setStyle(this.element, "display", "none"); + + this.hideEvent.fire(); + + } + + + + } + + + + } + + + +}, + + + + + +/** + +* @method configPosition + +* @description Event handler for when the "position" configuration property + +* of the menu changes. + +* @param {String} p_sType String representing the name of the event that + +* was fired. + +* @param {Array} p_aArgs Array of arguments sent when the event was fired. + +* @param {YAHOO.widget.Menu} p_oMenu Object representing the menu that + +* fired the event. + +*/ + +configPosition: function(p_sType, p_aArgs, p_oMenu) { + + + + var sCSSPosition = p_aArgs[0] == "static" ? "static" : "absolute", + + oCfg = this.cfg; + + + + Dom.setStyle(this.element, "position", sCSSPosition); + + + + + + if(sCSSPosition == "static") { + + + + /* + + Remove the iframe for statically positioned menus since it will + + intercept mouse events. + + */ + + + + oCfg.setProperty("iframe", false); + + + + + + // Statically positioned menus are visible by default + + + + Dom.setStyle(this.element, "display", "block"); + + + + oCfg.setProperty("visible", true); + + + + } + + else { + + + + /* + + Even though the "visible" property is queued to + + "false" by default, we need to set the "visibility" property to + + "hidden" since Overlay's "configVisible" implementation checks the + + element's "visibility" style property before deciding whether + + or not to show an Overlay instance. + + */ + + + + Dom.setStyle(this.element, "visibility", "hidden"); + + + + } + + + + + + if(sCSSPosition == "absolute") { + + + + var nZIndex = oCfg.getProperty("zindex"); + + + + if(!nZIndex || nZIndex === 0) { + + + + nZIndex = this.parent ? + + (this.parent.parent.cfg.getProperty("zindex") + 1) : 1; + + + + oCfg.setProperty("zindex", nZIndex); + + + + } + + + + } + + + +}, + + + + + +/** + +* @method configIframe + +* @description Event handler for when the "iframe" configuration property of + +* the menu changes. + +* @param {String} p_sType String representing the name of the event that + +* was fired. + +* @param {Array} p_aArgs Array of arguments sent when the event was fired. + +* @param {YAHOO.widget.Menu} p_oMenu Object representing the menu that + +* fired the event. + +*/ + +configIframe: function(p_sType, p_aArgs, p_oMenu) { + + + + if(this.cfg.getProperty("position") == "dynamic") { + + + + YAHOO.widget.Menu.superclass.configIframe.call( + + this, + + p_sType, + + p_aArgs, + + p_oMenu + + ); + + + + } + + + +}, + + + + + +/** + +* @method configHideDelay + +* @description Event handler for when the "hidedelay" configuration property + +* of the menu changes. + +* @param {String} p_sType String representing the name of the event that + +* was fired. + +* @param {Array} p_aArgs Array of arguments sent when the event was fired. + +* @param {YAHOO.widget.Menu} p_oMenu Object representing the menu that + +* fired the event. + +*/ + +configHideDelay: function(p_sType, p_aArgs, p_oMenu) { + + + + var nHideDelay = p_aArgs[0], + + oMouseOutEvent = this.mouseOutEvent, + + oMouseOverEvent = this.mouseOverEvent, + + oKeyDownEvent = this.keyDownEvent; + + + + if(nHideDelay > 0) { + + + + /* + + Only assign event handlers once. This way the user change + + the value for the hidedelay as many times as they want. + + */ + + + + if(!this._hideDelayEventHandlersAssigned) { + + + + oMouseOutEvent.subscribe(this._execHideDelay, true); + + oMouseOverEvent.subscribe(this._cancelHideDelay, this, true); + + oKeyDownEvent.subscribe(this._cancelHideDelay, this, true); + + + + this._hideDelayEventHandlersAssigned = true; + + + + } + + + + } + + else { + + + + oMouseOutEvent.unsubscribe(this._execHideDelay, this); + + oMouseOverEvent.unsubscribe(this._cancelHideDelay, this); + + oKeyDownEvent.unsubscribe(this._cancelHideDelay, this); + + + + this._hideDelayEventHandlersAssigned = false; + + + + } + + + +}, + + + + + +/** + +* @method configContainer + +* @description Event handler for when the "container" configuration property + +of the menu changes. + +* @param {String} p_sType String representing the name of the event that + +* was fired. + +* @param {Array} p_aArgs Array of arguments sent when the event was fired. + +* @param {YAHOO.widget.Menu} p_oMenu Object representing the menu that + +* fired the event. + +*/ + +configContainer: function(p_sType, p_aArgs, p_oMenu) { + + + + var oElement = p_aArgs[0]; + + + + if(typeof oElement == 'string') { + + + + this.cfg.setProperty( + + "container", + + document.getElementById(oElement), + + true + + ); + + + + } + + + +}, + + + + + + + +// Public methods + + + + + +/** + +* @method initEvents + +* @description Initializes the custom events for the menu. + +*/ + +initEvents: function() { + + + + YAHOO.widget.Menu.superclass.initEvents.call(this); + + + + // Create custom events + + + + var CustomEvent = YAHOO.util.CustomEvent; + + + + this.mouseOverEvent = new CustomEvent("mouseOverEvent", this); + + this.mouseOutEvent = new CustomEvent("mouseOutEvent", this); + + this.mouseDownEvent = new CustomEvent("mouseDownEvent", this); + + this.mouseUpEvent = new CustomEvent("mouseUpEvent", this); + + this.clickEvent = new CustomEvent("clickEvent", this); + + this.keyPressEvent = new CustomEvent("keyPressEvent", this); + + this.keyDownEvent = new CustomEvent("keyDownEvent", this); + + this.keyUpEvent = new CustomEvent("keyUpEvent", this); + + this.itemAddedEvent = new CustomEvent("itemAddedEvent", this); + + this.itemRemovedEvent = new CustomEvent("itemRemovedEvent", this); + + + +}, + + + + + +/** + +* @method getRoot + +* @description Finds the menu's root menu. + +*/ + +getRoot: function() { + + + + var oItem = this.parent; + + + + if(oItem) { + + + + var oParentMenu = oItem.parent; + + + + return oParentMenu ? oParentMenu.getRoot() : this; + + + + } + + else { + + + + return this; + + + + } + + + +}, + + + + + +/** + +* @method toString + +* @description Returns a string representing the menu. + +* @return {String} + +*/ + +toString: function() { + + + + return ("Menu " + this.id); + + + +}, + + + + + +/** + +* @method setItemGroupTitle + +* @description Sets the title of a group of menu items. + +* @param {String} p_sGroupTitle String specifying the title of the group. + +* @param {Number} p_nGroupIndex Optional. Number specifying the group to which + +* the title belongs. + +*/ + +setItemGroupTitle: function(p_sGroupTitle, p_nGroupIndex) { + + + + if(typeof p_sGroupTitle == "string" && p_sGroupTitle.length > 0) { + + + + var nGroupIndex = typeof p_nGroupIndex == "number" ? p_nGroupIndex : 0, + + oTitle = this._aGroupTitleElements[nGroupIndex]; + + + + + + if(oTitle) { + + + + oTitle.innerHTML = p_sGroupTitle; + + + + } + + else { + + + + oTitle = document.createElement(this.GROUP_TITLE_TAG_NAME); + + + + oTitle.innerHTML = p_sGroupTitle; + + + + this._aGroupTitleElements[nGroupIndex] = oTitle; + + + + } + + + + + + var i = this._aGroupTitleElements.length - 1, + + nFirstIndex; + + + + do { + + + + if(this._aGroupTitleElements[i]) { + + + + Dom.removeClass(this._aGroupTitleElements[i], "first-of-type"); + + + + nFirstIndex = i; + + + + } + + + + } + + while(i--); + + + + + + if(nFirstIndex !== null) { + + + + Dom.addClass( + + this._aGroupTitleElements[nFirstIndex], + + "first-of-type" + + ); + + + + } + + + + } + + + +}, + + + + + + + +/** + +* @method addItem + +* @description Appends an item to the menu. + +* @param {YAHOO.widget.MenuItem} p_oItem Object reference for the MenuItem + +* instance to be added to the menu. + +* @param {String} p_oItem String specifying the text of the item to be added + +* to the menu. + +* @param {Object} p_oItem Object literal containing a set of menu item + +* configuration properties. + +* @param {Number} p_nGroupIndex Optional. Number indicating the group to + +* which the item belongs. + +* @return {YAHOO.widget.MenuItem} + +*/ + +addItem: function(p_oItem, p_nGroupIndex) { + + + + if(p_oItem) { + + + + return this._addItemToGroup(p_nGroupIndex, p_oItem); + + + + } + + + +}, + + + + + +/** + +* @method addItems + +* @description Adds an array of items to the menu. + +* @param {Array} p_aItems Array of items to be added to the menu. The array + +* can contain strings specifying the text for each item to be created, object + +* literals specifying each of the menu item configuration properties, + +* or MenuItem instances. + +* @param {Number} p_nGroupIndex Optional. Number specifying the group to + +* which the items belongs. + +* @return {Array} + +*/ + +addItems: function(p_aItems, p_nGroupIndex) { + + + + function isArray(p_oValue) { + + + + return (typeof p_oValue == "object" && p_oValue.constructor == Array); + + + + } + + + + + + if(isArray(p_aItems)) { + + + + var nItems = p_aItems.length, + + aItems = [], + + oItem; + + + + + + for(var i=0; i<div> element + +* (and accompanying child nodes) from the document. + +*/ + +destroy: function() { + + + + // Remove Custom Event listeners + + + + this.mouseOverEvent.unsubscribeAll(); + + this.mouseOutEvent.unsubscribeAll(); + + this.mouseDownEvent.unsubscribeAll(); + + this.mouseUpEvent.unsubscribeAll(); + + this.clickEvent.unsubscribeAll(); + + this.keyPressEvent.unsubscribeAll(); + + this.keyDownEvent.unsubscribeAll(); + + this.keyUpEvent.unsubscribeAll(); + + this.itemAddedEvent.unsubscribeAll(); + + this.itemRemovedEvent.unsubscribeAll(); + + + + var nItemGroups = this._aItemGroups.length, + + nItems, + + oItemGroup, + + oItem, + + i, + + n; + + + + + + // Remove all items + + + + if(nItemGroups > 0) { + + + + i = nItemGroups - 1; + + + + do { + + + + oItemGroup = this._aItemGroups[i]; + + + + if(oItemGroup) { + + + + nItems = oItemGroup.length; + + + + if(nItems > 0) { + + + + n = nItems - 1; + + + + do { + + + + oItem = this._aItemGroups[i][n]; + + + + if(oItem) { + + + + oItem.destroy(); + + } + + + + } + + while(n--); + + + + } + + + + } + + + + } + + while(i--); + + + + } + + + + + + // Continue with the superclass implementation of this method + + + + YAHOO.widget.Menu.superclass.destroy.call(this); + + + + this.logger.log("Destroyed."); + + + +}, + + + + + +/** + +* @method setInitialFocus + +* @description Sets focus to the menu's first enabled item. + +*/ + +setInitialFocus: function() { + + + + var oItem = this._getFirstEnabledItem(); + + + + if(oItem) { + + + + oItem.focus(); + + } + + + +}, + + + + + +/** + +* @method setInitialSelection + +* @description Sets the "selected" configuration property of the menu's first + +* enabled item to "true." + +*/ + +setInitialSelection: function() { + + + + var oItem = this._getFirstEnabledItem(); + + + + if(oItem) { + + + + oItem.cfg.setProperty("selected", true); + + } + + + +}, + + + + + +/** + +* @method clearActiveItem + +* @description Sets the "selected" configuration property of the menu's active + +* item to "false" and hides the item's submenu. + +* @param {Boolean} p_bBlur Boolean indicating if the menu's active item + +* should be blurred. + +*/ + +clearActiveItem: function(p_bBlur) { + + + + if(this.cfg.getProperty("showdelay") > 0) { + + + + this._cancelShowDelay(); + + + + } + + + + + + var oActiveItem = this.activeItem; + + + + if(oActiveItem) { + + + + var oConfig = oActiveItem.cfg; + + + + oConfig.setProperty("selected", false); + + + + var oSubmenu = oConfig.getProperty("submenu"); + + + + if(oSubmenu) { + + + + oSubmenu.hide(); + + + + } + + + + if(p_bBlur) { + + + + oActiveItem.blur(); + + + + } + + + + } + + + +}, + + + + + +/** + +* @description Initializes the class's configurable properties which can be + +* changed using the menu's Config object ("cfg"). + +* @method initDefaultConfig + +*/ + +initDefaultConfig: function() { + + + + YAHOO.widget.Menu.superclass.initDefaultConfig.call(this); + + + + var oConfig = this.cfg; + + + + // Add configuration properties + + + + /* + + Change the default value for the "visible" configuration + + property to "false" by re-adding the property. + + */ + + + + /** + + * @config visible + + * @description Boolean indicating whether or not the menu is visible. If + + * the menu's "position" configuration property is set to "dynamic" (the + + * default), this property toggles the menu's <div> + + * element's "visibility" style property between "visible" (true) or + + * "hidden" (false). If the menu's "position" configuration property is + + * set to "static" this property toggles the menu's + + * <div> element's "display" style property + + * between "block" (true) or "none" (false). + + * @default false + + * @type Boolean + + */ + + oConfig.addProperty( + + "visible", + + { + + value:false, + + handler:this.configVisible, + + validator:this.cfg.checkBoolean + + } + + ); + + + + + + /* + + Change the default value for the "constraintoviewport" configuration + + property to "true" by re-adding the property. + + */ + + + + /** + + * @config constraintoviewport + + * @description Boolean indicating if the menu will try to remain inside + + * the boundaries of the size of viewport. + + * @default true + + * @type Boolean + + */ + + oConfig.addProperty( + + "constraintoviewport", + + { + + value:true, + + handler:this.configConstrainToViewport, + + validator:this.cfg.checkBoolean, + + supercedes:["iframe","x","y","xy"] + + } + + ); + + + + + + /** + + * @config position + + * @description String indicating how a menu should be positioned on the + + * screen. Possible values are "static" and "dynamic." Static menus are + + * visible by default and reside in the normal flow of the document + + * (CSS position: static). Dynamic menus are hidden by default, reside + + * out of the normal flow of the document (CSS position: absolute), and + + * can overlay other elements on the screen. + + * @default dynamic + + * @type String + + */ + + oConfig.addProperty( + + "position", + + { + + value: "dynamic", + + handler: this.configPosition, + + validator: this._checkPosition, + + supercedes: ["visible"] + + } + + ); + + + + + + /** + + * @config submenualignment + + * @description Array defining how submenus should be aligned to their + + * parent menu item. The format is: [itemCorner, submenuCorner]. By default + + * a submenu's top left corner is aligned to its parent menu item's top + + * right corner. + + * @default ["tl","tr"] + + * @type Array + + */ + + oConfig.addProperty("submenualignment", { value: ["tl","tr"] } ); + + + + + + /** + + * @config autosubmenudisplay + + * @description Boolean indicating if submenus are automatically made + + * visible when the user mouses over the menu's items. + + * @default true + + * @type Boolean + + */ + + oConfig.addProperty( + + "autosubmenudisplay", + + { + + value: true, + + validator: oConfig.checkBoolean + + } + + ); + + + + + + /** + + * @config showdelay + + * @description Number indicating the time (in milliseconds) that should + + * expire before a submenu is made visible when the user mouses over + + * the menu's items. + + * @default 0 + + * @type Number + + */ + + oConfig.addProperty( + + "showdelay", + + { + + value: 0, + + validator: oConfig.checkNumber + + } + + ); + + + + + + /** + + * @config hidedelay + + * @description Number indicating the time (in milliseconds) that should + + * expire before the menu is hidden. + + * @default 0 + + * @type Number + + */ + + oConfig.addProperty( + + "hidedelay", + + { + + value: 0, + + validator: oConfig.checkNumber, + + handler: this.configHideDelay, + + suppressEvent: true + + } + + ); + + + + + + /** + + * @config clicktohide + + * @description Boolean indicating if the menu will automatically be + + * hidden if the user clicks outside of it. + + * @default true + + * @type Boolean + + */ + + oConfig.addProperty( + + "clicktohide", + + { + + value: true, + + validator: oConfig.checkBoolean + + } + + ); + + + + + + /** + + * @config container + + * @description HTML element reference or string specifying the id + + * attribute of the HTML element that the menu's markup should be rendered into. + + * @type HTMLElement|String + + * @default document.body + + */ + + this.cfg.addProperty( + + "container", + + { value:document.body, handler:this.configContainer } + + ); + + + +} + + + +}); // END YAHOO.extend + + + +})(); + + /** -* @class The MenuModuleItem class allows you to create and modify an item for a -* MenuModule instance. +* The base class for all menuing containers. +* +* @param {String} p_oElement String specifying the id attribute of the +* <div> element of the menu module. +* @param {String} p_oElement String specifying the id attribute of the +* <select> element to be used as the data source for the +* menu module. +* @param {HTMLDivElement} p_oElement Object +* specifying the <div> element of the menu module. +* @param {HTMLSelectElement} p_oElement Object +* specifying the <select> element to be used as the data +* source for the menu module. +* @param {Object} p_oConfig Optional. Object literal specifying the +* configuration for the menu module. See configuration class documentation for +* more details. +* @class MenuModule * @constructor -* @param {String or HTMLElement} p_oObject String or HTMLElement -* (either HTMLLIElement, HTMLOptGroupElement or HTMLOptionElement) of the -* source HTMLElement node. -* @param {Object} p_oConfig The configuration object literal containing -* the configuration for a MenuModuleItem instance. See the configuration -* class documentation for more details. +* @extends YAHOO.widget.Overlay +* @deprecated As of version 0.12, all MenuModule functionality has been +* implemented directly in YAHOO.widget.Menu, making YAHOO.widget.Menu the base +* class for all menuing containers. */ -YAHOO.widget.MenuModuleItem = function(p_oObject, p_oConfig) { +YAHOO.widget.MenuModule = YAHOO.widget.Menu; + +(function() { + +var Dom = YAHOO.util.Dom, + Module = YAHOO.widget.Module, + Menu = YAHOO.widget.Menu; + + +/** +* Creates an item for a menu. +* +* @param {String} p_oObject String specifying the text of the menu item. +* @param {HTMLLIElement} p_oObject Object specifying +* the <li> element of the menu item. +* @param {HTMLOptGroupElement} p_oObject Object +* specifying the <optgroup> element of the menu item. +* @param {HTMLOptionElement} p_oObject Object +* specifying the <option> element of the menu item. +* @param {Object} p_oConfig Optional. Object literal specifying the +* configuration for the menu item. See configuration class documentation +* for more details. +* @class MenuItem +* @constructor +*/ +YAHOO.widget.MenuItem = function(p_oObject, p_oConfig) { + if(p_oObject) { + if(p_oConfig) { + + this.parent = p_oConfig.parent; + this.value = p_oConfig.value; + + } + this.init(p_oObject, p_oConfig); } }; -YAHOO.widget.MenuModuleItem.prototype = { +YAHOO.widget.MenuItem.prototype = { // Constants /** - * Constant representing the path to the image to be used for the submenu - * arrow indicator. + * @property SUBMENU_INDICATOR_IMAGE_PATH + * @description String representing the path to the image to be used for the + * menu item's submenu arrow indicator. + * @default "nt/ic/ut/alt1/menuarorght8_nrm_1.gif" * @final * @type String */ SUBMENU_INDICATOR_IMAGE_PATH: "nt/ic/ut/alt1/menuarorght8_nrm_1.gif", /** - * Constant representing the path to the image to be used for the submenu - * arrow indicator when a MenuModuleItem instance is selected. + * @property SELECTED_SUBMENU_INDICATOR_IMAGE_PATH + * @description String representing the path to the image to be used for the + * submenu arrow indicator when the menu item is selected. + * @default "nt/ic/ut/alt1/menuarorght8_hov_1.gif" * @final * @type String */ @@ -2446,8 +7727,10 @@ /** - * Constant representing the path to the image to be used for the submenu - * arrow indicator when a MenuModuleItem instance is disabled. + * @property DISABLED_SUBMENU_INDICATOR_IMAGE_PATH + * @description String representing the path to the image to be used for the + * submenu arrow indicator when the menu item is disabled. + * @default "nt/ic/ut/alt1/menuarorght8_dim_1.gif" * @final * @type String */ @@ -2456,332 +7739,431 @@ /** - * Constant representing the alt text for the image to be used for the - * submenu arrow indicator. + * @property COLLAPSED_SUBMENU_INDICATOR_ALT_TEXT + * @description String representing the alt text for the image to be used + * for the submenu arrow indicator. + * @default "Collapsed. Click to expand." * @final * @type String */ COLLAPSED_SUBMENU_INDICATOR_ALT_TEXT: "Collapsed. Click to expand.", /** - * Constant representing the alt text for the image to be used for the - * submenu arrow indicator when the submenu is visible. + * @property EXPANDED_SUBMENU_INDICATOR_ALT_TEXT + * @description String representing the alt text for the image to be used + * for the submenu arrow indicator when the submenu is visible. + * @default "Expanded. Click to collapse." * @final * @type String */ EXPANDED_SUBMENU_INDICATOR_ALT_TEXT: "Expanded. Click to collapse.", /** - * Constant representing the alt text for the image to be used for the - * submenu arrow indicator when a MenuModuleItem instance is disabled. + * @property DISABLED_SUBMENU_INDICATOR_ALT_TEXT + * @description String representing the alt text for the image to be used + * for the submenu arrow indicator when the menu item is disabled. + * @default "Disabled." * @final * @type String */ DISABLED_SUBMENU_INDICATOR_ALT_TEXT: "Disabled.", /** - * Constant representing the CSS class(es) to be applied to the root - * HTMLLIElement of the MenuModuleItem. + * @property CHECKED_IMAGE_PATH + * @description String representing the path to the image to be used for + * the checked state. + * @default "nt/ic/ut/bsc/menuchk8_nrm_1.gif" * @final * @type String */ - CSS_CLASS_NAME: "yuimenuitem", + CHECKED_IMAGE_PATH: "nt/ic/ut/bsc/menuchk8_nrm_1.gif", /** - * Constant representing the type of menu to instantiate when creating - * submenu instances from parsing the child nodes (either HTMLSelectElement - * or HTMLDivElement) of the item's DOM. The default - * is YAHOO.widget.MenuModule. + * @property SELECTED_CHECKED_IMAGE_PATH + * @description String representing the path to the image to be used for + * the selected checked state. + * @default "nt/ic/ut/bsc/menuchk8_hov_1.gif" * @final - * @type YAHOO.widget.MenuModule + * @type String */ - SUBMENU_TYPE: null, + SELECTED_CHECKED_IMAGE_PATH: "nt/ic/ut/bsc/menuchk8_hov_1.gif", /** - * Constant representing the type of item to instantiate when - * creating item instances from parsing the child nodes (either - * HTMLLIElement, HTMLOptGroupElement or HTMLOptionElement) of the - * submenu's DOM. - * The default is YAHOO.widget.MenuModuleItem. + * @property DISABLED_CHECKED_IMAGE_PATH + * @description String representing the path to the image to be used for + * the disabled checked state. + * @default "nt/ic/ut/bsc/menuchk8_dim_1.gif" * @final - * @type YAHOO.widget.MenuModuleItem + * @type String */ - SUBMENU_ITEM_TYPE: null, + DISABLED_CHECKED_IMAGE_PATH: "nt/ic/ut/bsc/menuchk8_dim_1.gif", /** - * Constant representing the prefix path to use for non-secure images - * @type string + * @property CHECKED_IMAGE_ALT_TEXT + * @description String representing the alt text for the image to be used + * for the checked image. + * @default "Checked." + * @final + * @type String */ - IMG_ROOT: "http://us.i1.yimg.com/us.yimg.com/i/", + CHECKED_IMAGE_ALT_TEXT: "Checked.", /** - * Constant representing the prefix path to use for securely served images - * @type string + * @property DISABLED_CHECKED_IMAGE_ALT_TEXT + * @description String representing the alt text for the image to be used + * for the checked image when the item is disabled. + * @default "Checked. (Item disabled.)" + * @final + * @type String */ - IMG_ROOT_SSL: "https://a248.e.akamai.net/sec.yimg.com/i/", + DISABLED_CHECKED_IMAGE_ALT_TEXT: "Checked. (Item disabled.)", - // Private member variables + /** + * @property CSS_CLASS_NAME + * @description String representing the CSS class(es) to be applied to the + * <li> element of the menu item. + * @default "yuimenuitem" + * @final + * @type String + */ + CSS_CLASS_NAME: "yuimenuitem", + /** - * Reference to the HTMLAnchorElement of the MenuModuleItem's core internal - * DOM structure. - * @private - * @type {HTMLAnchorElement} + * @property SUBMENU_TYPE + * @description Object representing the type of menu to instantiate and + * add when parsing the child nodes of the menu item's source HTML element. + * @final + * @type YAHOO.widget.Menu */ - _oAnchor: null, + SUBMENU_TYPE: null, /** - * Reference to the text node of the MenuModuleItem's core internal - * DOM structure. - * @private - * @type {Text} + * @property IMG_ROOT + * @description String representing the prefix path to use for + * non-secure images. + * @default "http://us.i1.yimg.com/us.yimg.com/i/" + * @type String */ - _oText: null, + IMG_ROOT: "http://us.i1.yimg.com/us.yimg.com/i/", /** - * Reference to the HTMLElement (<EM<) used to create the optional - * help text for a MenuModuleItem instance. + * @property IMG_ROOT_SSL + * @description String representing the prefix path to use for securely + * served images. + * @default "https://a248.e.akamai.net/sec.yimg.com/i/" + * @type String + */ + IMG_ROOT_SSL: "https://a248.e.akamai.net/sec.yimg.com/i/", + + + + // Private member variables + + /** + * @property _oAnchor + * @description Object reference to the menu item's + * <a> element. + * @default null * @private - * @type {HTMLElement} + * @type HTMLAnchorElement */ - _oHelpTextEM: null, + _oAnchor: null, /** - * Reference to the submenu for a MenuModuleItem instance. + * @property _oText + * @description Object reference to the menu item's text node. + * @default null * @private - * @type {YAHOO.widget.MenuModule} + * @type TextNode */ - _oSubmenu: null, + _oText: null, /** - * Reference to the Dom utility singleton. + * @property _oHelpTextEM + * @description Object reference to the menu item's help text + * <em> element. + * @default null * @private - * @type {YAHOO.util.Dom} + * @type HTMLElement */ - _oDom: YAHOO.util.Dom, + _oHelpTextEM: null, /** - * The current state of a MenuModuleItem instance's "mouseover" event + * @property _oSubmenu + * @description Object reference to the menu item's submenu. + * @default null * @private - * @type {Boolean} + * @type YAHOO.widget.Menu */ - _bFiredMouseOverEvent: false, + _oSubmenu: null, /** - * The current state of a MenuModuleItem instance's "mouseout" event + * @property _checkImage + * @description Object reference to the menu item's checkmark image. + * @default null * @private - * @type {Boolean} + * @type HTMLImageElement */ - _bFiredMouseOutEvent: false, + _checkImage: null, + // Public properties /** - * The class's constructor function - * @type YAHOO.widget.MenuModuleItem + * @property constructor + * @description Object reference to the menu item's constructor function. + * @default YAHOO.widget.MenuItem + * @type YAHOO.widget.MenuItem */ - constructor: YAHOO.widget.MenuModuleItem, + constructor: YAHOO.widget.MenuItem, /** - * The string representing the image root - * @type string + * @property imageRoot + * @description String representing the root path for all of the menu + * item's images. + * @type String */ imageRoot: null, /** - * Boolean representing whether or not the current browsing context - * is secure (https) - * @type boolean + * @property isSecure + * @description Boolean representing whether or not the current browsing + * context is secure (HTTPS). + * @type Boolean */ - isSecure: YAHOO.widget.Module.prototype.isSecure, + isSecure: Module.prototype.isSecure, /** - * Returns the ordinal position of a MenuModuleItem instance in a group. + * @property index + * @description Number indicating the ordinal position of the menu item in + * its group. + * @default null * @type Number */ index: null, /** - * Returns the index of the group to which a MenuModuleItem instance belongs. + * @property groupIndex + * @description Number indicating the index of the group to which the menu + * item belongs. + * @default null * @type Number */ groupIndex: null, /** - * Returns the parent object for a MenuModuleItem instance. - * @type {YAHOO.widget.MenuModule} + * @property parent + * @description Object reference to the menu item's parent menu. + * @default null + * @type YAHOO.widget.Menu */ parent: null, /** - * Returns the HTMLLIElement for a MenuModuleItem instance. - * @type {HTMLLIElement} + * @property element + * @description Object reference to the menu item's + * <li> element. + * @default HTMLLIElement + * @type HTMLLIElement */ element: null, /** - * Returns the HTMLElement (either HTMLLIElement, HTMLOptGroupElement or - * HTMLOptionElement) used create the MenuModuleItem instance. - * @type {HTMLLIElement/HTMLOptGroupElement/HTMLOptionElement} + * @property srcElement + * @description Object reference to the HTML element (either + * <li>, <optgroup> or + * <option>) used create the menu item. + * @default HTMLLIElement|HTMLOptGroupElement|HTMLOptionElement + * @type HTMLLIElement| + * HTMLOptGroupElement|HTMLOptionElement */ srcElement: null, /** - * Specifies an arbitrary value for a MenuModuleItem instance. - * @type {Object} + * @property value + * @description Object reference to the menu item's value. + * @default null + * @type Object */ value: null, /** - * Reference to the HTMLImageElement used to create the submenu - * indicator for a MenuModuleItem instance. - * @type {HTMLImageElement} + * @property submenuIndicator + * @description Object reference to the <img> element + * used to create the submenu indicator for the menu item. + * @default HTMLImageElement + * @type HTMLImageElement */ submenuIndicator: null, /** - * String representing the browser - * @type string + * @property browser + * @description String representing the browser. + * @type String */ - browser: YAHOO.widget.Module.prototype.browser, + browser: Module.prototype.browser, + // Events + /** - * Fires when a MenuModuleItem instances's HTMLLIElement is removed from - * it's parent HTMLUListElement node. - * @type {YAHOO.util.CustomEvent} - * @see YAHOO.util.CustomEvent + * @event destroyEvent + * @description Fires when the menu item's <li> + * element is removed from its parent <ul> element. + * @type YAHOO.util.CustomEvent */ destroyEvent: null, /** - * Fires when the mouse has entered a MenuModuleItem instance. Passes + * @event mouseOverEvent + * @description Fires when the mouse has entered the menu item. Passes * back the DOM Event object as an argument. - * @type {YAHOO.util.CustomEvent} - * @see YAHOO.util.CustomEvent + * @type YAHOO.util.CustomEvent */ mouseOverEvent: null, /** - * Fires when the mouse has left a MenuModuleItem instance. Passes back + * @event mouseOutEvent + * @description Fires when the mouse has left the menu item. Passes back * the DOM Event object as an argument. - * @type {YAHOO.util.CustomEvent} - * @see YAHOO.util.CustomEvent + * @type YAHOO.util.CustomEvent */ mouseOutEvent: null, /** - * Fires when the user mouses down on a MenuModuleItem instance. Passes + * @event mouseDownEvent + * @description Fires when the user mouses down on the menu item. Passes * back the DOM Event object as an argument. - * @type {YAHOO.util.CustomEvent} - * @see YAHOO.util.CustomEvent + * @type YAHOO.util.CustomEvent */ mouseDownEvent: null, /** - * Fires when the user releases a mouse button while the mouse is - * over a MenuModuleItem instance. Passes back the DOM Event object as - * an argument. - * @type {YAHOO.util.CustomEvent} - * @see YAHOO.util.CustomEvent + * @event mouseUpEvent + * @description Fires when the user releases a mouse button while the mouse + * is over the menu item. Passes back the DOM Event object as an argument. + * @type YAHOO.util.CustomEvent */ mouseUpEvent: null, /** - * Fires when the user clicks the on a MenuModuleItem instance. Passes + * @event clickEvent + * @description Fires when the user clicks the on the menu item. Passes * back the DOM Event object as an argument. - * @type {YAHOO.util.CustomEvent} - * @see YAHOO.util.CustomEvent + * @type YAHOO.util.CustomEvent */ clickEvent: null, /** - * Fires when the user presses an alphanumeric key. Passes back the - * DOM Event object as an argument. - * @type {YAHOO.util.CustomEvent} - * @see YAHOO.util.CustomEvent + * @event keyPressEvent + * @description Fires when the user presses an alphanumeric key when the + * menu item has focus. Passes back the DOM Event object as an argument. + * @type YAHOO.util.CustomEvent */ keyPressEvent: null, /** - * Fires when the user presses a key. Passes back the DOM Event - * object as an argument. - * @type {YAHOO.util.CustomEvent} - * @see YAHOO.util.CustomEvent + * @event keyDownEvent + * @description Fires when the user presses a key when the menu item has + * focus. Passes back the DOM Event object as an argument. + * @type YAHOO.util.CustomEvent */ keyDownEvent: null, /** - * Fires when the user releases a key. Passes back the DOM Event - * object as an argument. - * @type {YAHOO.util.CustomEvent} - * @see YAHOO.util.CustomEvent + * @event keyUpEvent + * @description Fires when the user releases a key when the menu item has + * focus. Passes back the DOM Event object as an argument. + * @type YAHOO.util.CustomEvent */ keyUpEvent: null, /** - * Fires when a MenuModuleItem instance receives focus. - * @type {YAHOO.util.CustomEvent} - * @see YAHOO.util.CustomEvent + * @event focusEvent + * @description Fires when the menu item receives focus. + * @type YAHOO.util.CustomEvent */ focusEvent: null, /** - * Fires when a MenuModuleItem instance loses the input focus. - * @type {YAHOO.util.CustomEvent} - * @see YAHOO.util.CustomEvent + * @event blurEvent + * @description Fires when the menu item loses the input focus. + * @type YAHOO.util.CustomEvent */ blurEvent: null, /** - * The MenuModuleItem class's initialization method. This method is + * @method init + * @description The MenuItem class's initialization method. This method is * automatically called by the constructor, and sets up all DOM references * for pre-existing markup, and creates required markup if it is not * already present. - * @param {String or HTMLElement} p_oObject String or HTMLElement - * (either HTMLLIElement, HTMLOptGroupElement or HTMLOptionElement) of the - * source HTMLElement node. - * @param {Object} p_oConfig The configuration object literal containing - * the configuration for a MenuModuleItem instance. See the configuration - * class documentation for more details. + * @param {String} p_oObject String specifying the text of the menu item. + * @param {HTMLLIElement} p_oObject Object specifying + * the <li> element of the menu item. + * @param {HTMLOptGroupElement} p_oObject Object + * specifying the <optgroup> element of the menu item. + * @param {HTMLOptionElement} p_oObject Object + * specifying the <option> element of the menu item. + * @param {Object} p_oConfig Optional. Object literal specifying the + * configuration for the menu item. See configuration class documentation + * for more details. */ init: function(p_oObject, p_oConfig) { @@ -2790,17 +8172,11 @@ if(!this.SUBMENU_TYPE) { - this.SUBMENU_TYPE = YAHOO.widget.MenuModule; + this.SUBMENU_TYPE = Menu; } - if(!this.SUBMENU_ITEM_TYPE) { - this.SUBMENU_ITEM_TYPE = YAHOO.widget.MenuModuleItem; - - } - - // Create the config object this.cfg = new YAHOO.util.Config(this); @@ -2819,7 +8195,7 @@ } else if(this._checkDOMNode(p_oObject)) { - switch(p_oObject.tagName) { + switch(p_oObject.tagName.toUpperCase()) { case "OPTION": @@ -2847,10 +8223,10 @@ // Get the anchor node (if it exists) - var oAnchor = this._getFirstElement(p_oObject, "A"); - var sURL = "#"; - var sTarget = null; - var sText = null; + var oAnchor = this._getFirstElement(p_oObject, "A"), + sURL = "#", + sTarget, + sText; // Capture the "text" and/or the "URL" @@ -2898,19 +8274,19 @@ this._oAnchor = oAnchor; - // Check if emphasis has been applied to the MenuModuleItem + // Check if emphasis has been applied to the MenuItem - var oEmphasisNode = this._getFirstElement(oAnchor); - var bEmphasis = false; - var bStrongEmphasis = false; + var oEmphasisNode = this._getFirstElement(oAnchor), + bEmphasis = false, + bStrongEmphasis = false; if(oEmphasisNode) { // Set a reference to the text node this._oText = oEmphasisNode.firstChild; - switch(oEmphasisNode.tagName) { + switch(oEmphasisNode.tagName.toUpperCase()) { case "EM": @@ -2964,7 +8340,7 @@ if(this.element) { - this._oDom.addClass(this.element, this.CSS_CLASS_NAME); + Dom.addClass(this.element, this.CSS_CLASS_NAME); // Create custom events @@ -2984,11 +8360,6 @@ this.blurEvent = new CustomEvent("blurEvent", this); - // Subscribe to custom event - - this.clickEvent.subscribe(this._onMenuModuleItemClick, this, true); - - if(p_oConfig) { oConfig.applyConfig(p_oConfig); @@ -3002,15 +8373,20 @@ }, + // Private methods /** - * Returns an HTMLElement's first HTMLElement node + * @method _getFirstElement + * @description Returns an HTML element's first HTML element node. * @private - * @param {HTMLElement} p_oElement The element to be evaluated. - * @param {String} p_sTagName Optional. The tagname of the element. - * @return Returns an HTMLElement node. - * @type Boolean + * @param {HTMLElement} p_oElement Object + * reference specifying the element to be evaluated. + * @param {String} p_sTagName Optional. String specifying the tagname of + * the element to be retrieved. + * @return {HTMLElement} */ _getFirstElement: function(p_oElement, p_sTagName) { @@ -3034,7 +8410,7 @@ if(p_sTagName) { - return (oElement && oElement.tagName == p_sTagName) ? + return (oElement && oElement.tagName.toUpperCase() == p_sTagName) ? oElement : false; } @@ -3045,11 +8421,11 @@ /** - * Determines if an object is a string + * @method _checkString + * @description Determines if an object is a string. * @private - * @param {Object} p_oObject The object to be evaluated. - * @return Returns true if the object is a string. - * @type Boolean + * @param {Object} p_oObject Object to be evaluated. + * @return {Boolean} */ _checkString: function(p_oObject) { @@ -3059,11 +8435,11 @@ /** - * Determines if an object is an HTMLElement. + * @method _checkDOMNode + * @description Determines if an object is an HTML element. * @private - * @param {Object} p_oObject The object to be evaluated. - * @return Returns true if the object is an HTMLElement. - * @type Boolean + * @param {Object} p_oObject Object to be evaluated. + * @return {Boolean} */ _checkDOMNode: function(p_oObject) { @@ -3073,7 +8449,8 @@ /** - * Creates the core DOM structure for a MenuModuleItem instance. + * @method _createRootNodeStructure + * @description Creates the core DOM structure for the menu item. * @private */ _createRootNodeStructure: function () { @@ -3093,160 +8470,123 @@ /** - * Iterates the source element's childNodes collection and uses the - * child nodes to instantiate other menus. + * @method _initSubTree + * @description Iterates the source element's childNodes collection and uses + * the child nodes to instantiate other menus. * @private */ _initSubTree: function() { - var Menu = this.SUBMENU_TYPE; - var MenuModuleItem = this.SUBMENU_ITEM_TYPE; - var oSrcEl = this.srcElement; - var oConfig = this.cfg; + var oSrcEl = this.srcElement, + oConfig = this.cfg; if(oSrcEl.childNodes.length > 0) { - var oNode = oSrcEl.firstChild; - var aOptions = []; + if( + this.parent.lazyLoad && + this.parent.srcElement && + this.parent.srcElement.tagName.toUpperCase() == "SELECT" + ) { - do { + oConfig.setProperty( + "submenu", + { id: Dom.generateId(), itemdata: oSrcEl.childNodes } + ); - switch(oNode.tagName) { + } + else { - case "DIV": + var oNode = oSrcEl.firstChild, + aOptions = []; - oConfig.setProperty("submenu", (new Menu(oNode))); + do { - break; + if(oNode && oNode.tagName) { - case "OPTION": + switch(oNode.tagName.toUpperCase()) { - aOptions[aOptions.length] = oNode; + case "DIV": - break; + oConfig.setProperty("submenu", oNode); - } + break; - } - while((oNode = oNode.nextSibling)); + case "OPTION": + aOptions[aOptions.length] = oNode; - var nOptions = aOptions.length; + break; - if(nOptions > 0) { + } - oConfig.setProperty( - "submenu", - (new Menu(this._oDom.generateId())) - ); + } - for(var n=0; n 0) { + var oMenu = new this.SUBMENU_TYPE(Dom.generateId()); - /** - * "click" event handler for a MenuModuleItem - * @private - * @param {String} p_sType The name of the event that was fired. - * @param {Array} p_aArgs Collection of arguments sent when the event - * was fired. - * @param {YAHOO.widget.MenuItem} p_oMenuModuleItem The MenuModule instance - * that fired the event. - */ - _onMenuModuleItemClick: function(p_sType, p_aArgs, p_oMenuModuleItem) { + oConfig.setProperty("submenu", oMenu); - var Event = YAHOO.util.Event; - var oEvent = p_aArgs[0]; - var oTarget = Event.getTarget(oEvent); - var oSubmenu = this.cfg.getProperty("submenu"); + for(var n=0; n 0); - // Prevent the browser from following links equal to "#" + /** + * @method _preloadImage + * @description Preloads an image by creating an image element from the + * specified path and appending the image to the body of the document. + * @private + * @param {String} p_sPath String specifying the path to the image. + */ + _preloadImage: function(p_sPath) { - if(oTarget.tagName == "A" && bCurrentPageURL && !bHasTarget) { + var sPath = this.imageRoot + p_sPath; - Event.preventDefault(oEvent); + if(!document.images[sPath]) { - } + var oImage = document.createElement("img"); + oImage.src = sPath; + oImage.name = sPath; + oImage.id = sPath; + oImage.style.display = "none"; - if(oTarget.tagName != "A" && !bCurrentPageURL && !bHasTarget) { + document.body.appendChild(oImage); - /* - Follow the URL of the item regardless of whether or - not the user clicked specifically on the - HTMLAnchorElement (<A<) node. - */ - - document.location = sURL; - - } - } }, + // Event handlers for configuration properties + /** - * Event handler for when the "text" configuration property of - * a MenuModuleItem instance changes. - * @param {String} p_sType The name of the event that was fired. - * @param {Array} p_aArgs Collection of arguments sent when the - * event was fired. - * @param {YAHOO.widget.MenuModuleItem} p_oItem The MenuModuleItem instance + * @method configText + * @description Event handler for when the "text" configuration property of + * the menu item changes. + * @param {String} p_sType String representing the name of the event that + * was fired. + * @param {Array} p_aArgs Array of arguments sent when the event was fired. + * @param {YAHOO.widget.MenuItem} p_oItem Object representing the menu item * that fired the event. */ configText: function(p_sType, p_aArgs, p_oItem) { @@ -3264,29 +8604,29 @@ /** - * Event handler for when the "helptext" configuration property of - * a MenuModuleItem instance changes. - * @param {String} p_sType The name of the event that was fired. - * @param {Array} p_aArgs Collection of arguments sent when the - * event was fired. - * @param {YAHOO.widget.MenuModuleItem} p_oItem The MenuModuleItem instance + * @method configHelpText + * @description Event handler for when the "helptext" configuration property + * of the menu item changes. + * @param {String} p_sType String representing the name of the event that + * was fired. + * @param {Array} p_aArgs Array of arguments sent when the event was fired. + * @param {YAHOO.widget.MenuItem} p_oItem Object representing the menu item * that fired the event. */ configHelpText: function(p_sType, p_aArgs, p_oItem) { - var me = this; - var Dom = this._oDom; - var oHelpText = p_aArgs[0]; - var oEl = this.element; - var oConfig = this.cfg; - var aNodes = [oEl, this._oAnchor]; - var oImg = this.submenuIndicator; + var me = this, + oHelpText = p_aArgs[0], + oEl = this.element, + oConfig = this.cfg, + aNodes = [oEl, this._oAnchor], + oImg = this.submenuIndicator; /** * Adds the "hashelptext" class to the necessary nodes and refires the - * "selected" and "disabled" configuration events - * @ignore + * "selected" and "disabled" configuration events. + * @private */ function initHelpText() { @@ -3308,8 +8648,8 @@ /** - * Removes the "hashelptext" class and corresponding DOM element (EM) - * @ignore + * Removes the "hashelptext" class and corresponding DOM element (EM). + * @private */ function removeHelpText() { @@ -3376,12 +8716,13 @@ /** - * Event handler for when the "url" configuration property of - * a MenuModuleItem instance changes. - * @param {String} p_sType The name of the event that was fired. - * @param {Array} p_aArgs Collection of arguments sent when the - * event was fired. - * @param {YAHOO.widget.MenuModuleItem} p_oItem The MenuModuleItem instance + * @method configURL + * @description Event handler for when the "url" configuration property of + * the menu item changes. + * @param {String} p_sType String representing the name of the event that + * was fired. + * @param {Array} p_aArgs Array of arguments sent when the event was fired. + * @param {YAHOO.widget.MenuItem} p_oItem Object representing the menu item * that fired the event. */ configURL: function(p_sType, p_aArgs, p_oItem) { @@ -3400,18 +8741,19 @@ /** - * Event handler for when the "target" configuration property of - * a MenuModuleItem instance changes. - * @param {String} p_sType The name of the event that was fired. - * @param {Array} p_aArgs Collection of arguments sent when the - * event was fired. - * @param {YAHOO.widget.MenuModuleItem} p_oItem The MenuModuleItem instance + * @method configTarget + * @description Event handler for when the "target" configuration property + * of the menu item changes. + * @param {String} p_sType String representing the name of the event that + * was fired. + * @param {Array} p_aArgs Array of arguments sent when the event was fired. + * @param {YAHOO.widget.MenuItem} p_oItem Object representing the menu item * that fired the event. */ configTarget: function(p_sType, p_aArgs, p_oItem) { - var sTarget = p_aArgs[0]; - var oAnchor = this._oAnchor; + var sTarget = p_aArgs[0], + oAnchor = this._oAnchor; if(sTarget && sTarget.length > 0) { @@ -3428,21 +8770,22 @@ /** - * Event handler for when the "emphasis" configuration property of - * a MenuModuleItem instance changes. - * @param {String} p_sType The name of the event that was fired. - * @param {Array} p_aArgs Collection of arguments sent when the - * event was fired. - * @param {YAHOO.widget.MenuModuleItem} p_oItem The MenuModuleItem instance + * @method configEmphasis + * @description Event handler for when the "emphasis" configuration property + * of the menu item changes. + * @param {String} p_sType String representing the name of the event that + * was fired. + * @param {Array} p_aArgs Array of arguments sent when the event was fired. + * @param {YAHOO.widget.MenuItem} p_oItem Object representing the menu item * that fired the event. */ configEmphasis: function(p_sType, p_aArgs, p_oItem) { - var bEmphasis = p_aArgs[0]; - var oAnchor = this._oAnchor; - var oText = this._oText; - var oConfig = this.cfg; - var oEM; + var bEmphasis = p_aArgs[0], + oAnchor = this._oAnchor, + oText = this._oText, + oConfig = this.cfg, + oEM; if(bEmphasis && oConfig.getProperty("strongemphasis")) { @@ -3466,9 +8809,13 @@ oEM = this._getFirstElement(oAnchor, "EM"); - oAnchor.removeChild(oEM); - oAnchor.appendChild(oText); + if(oEM) { + oAnchor.removeChild(oEM); + oAnchor.appendChild(oText); + + } + } } @@ -3477,21 +8824,22 @@ /** - * Event handler for when the "strongemphasis" configuration property of - * a MenuModuleItem instance changes. - * @param {String} p_sType The name of the event that was fired. - * @param {Array} p_aArgs Collection of arguments sent when the - * event was fired. - * @param {YAHOO.widget.MenuModuleItem} p_oItem The MenuModuleItem instance + * @method configStrongEmphasis + * @description Event handler for when the "strongemphasis" configuration + * property of the menu item changes. + * @param {String} p_sType String representing the name of the event that + * was fired. + * @param {Array} p_aArgs Array of arguments sent when the event was fired. + * @param {YAHOO.widget.MenuItem} p_oItem Object representing the menu item * that fired the event. */ configStrongEmphasis: function(p_sType, p_aArgs, p_oItem) { - var bStrongEmphasis = p_aArgs[0]; - var oAnchor = this._oAnchor; - var oText = this._oText; - var oConfig = this.cfg; - var oStrong; + var bStrongEmphasis = p_aArgs[0], + oAnchor = this._oAnchor, + oText = this._oText, + oConfig = this.cfg, + oStrong; if(bStrongEmphasis && oConfig.getProperty("emphasis")) { @@ -3513,9 +8861,13 @@ oStrong = this._getFirstElement(oAnchor, "STRONG"); - oAnchor.removeChild(oStrong); - oAnchor.appendChild(oText); + if(oStrong) { + oAnchor.removeChild(oStrong); + oAnchor.appendChild(oText); + + } + } } @@ -3524,25 +8876,105 @@ /** - * Event handler for when the "disabled" configuration property of - * a MenuModuleItem instance changes. - * @param {String} p_sType The name of the event that was fired. - * @param {Array} p_aArgs Collection of arguments sent when the - * event was fired. - * @param {YAHOO.widget.MenuModuleItem} p_oItem The MenuModuleItem instance + * @method configChecked + * @description Event handler for when the "checked" configuration property + * of the menu item changes. + * @param {String} p_sType String representing the name of the event that + * was fired. + * @param {Array} p_aArgs Array of arguments sent when the event was fired. + * @param {YAHOO.widget.MenuItem} p_oItem Object representing the menu item * that fired the event. */ + configChecked: function(p_sType, p_aArgs, p_oItem) { + + var bChecked = p_aArgs[0], + oEl = this.element, + oConfig = this.cfg, + oImg; + + + if(bChecked) { + + this._preloadImage(this.CHECKED_IMAGE_PATH); + this._preloadImage(this.SELECTED_CHECKED_IMAGE_PATH); + this._preloadImage(this.DISABLED_CHECKED_IMAGE_PATH); + + + oImg = document.createElement("img"); + oImg.src = (this.imageRoot + this.CHECKED_IMAGE_PATH); + oImg.alt = this.CHECKED_IMAGE_ALT_TEXT; + + var oSubmenu = this.cfg.getProperty("submenu"); + + if(oSubmenu) { + + oEl.insertBefore(oImg, oSubmenu.element); + + } + else { + + oEl.appendChild(oImg); + + } + + + Dom.addClass([oEl, oImg], "checked"); + + this._checkImage = oImg; + + if(oConfig.getProperty("disabled")) { + + oConfig.refireEvent("disabled"); + + } + + if(oConfig.getProperty("selected")) { + + oConfig.refireEvent("selected"); + + } + + } + else { + + oImg = this._checkImage; + + Dom.removeClass([oEl, oImg], "checked"); + + if(oImg) { + + oEl.removeChild(oImg); + + } + + this._checkImage = null; + + } + + }, + + + + /** + * @method configDisabled + * @description Event handler for when the "disabled" configuration property + * of the menu item changes. + * @param {String} p_sType String representing the name of the event that + * was fired. + * @param {Array} p_aArgs Array of arguments sent when the event was fired. + * @param {YAHOO.widget.MenuItem} p_oItem Object representing the menu item + * that fired the event. + */ configDisabled: function(p_sType, p_aArgs, p_oItem) { - var bDisabled = p_aArgs[0]; - var Dom = this._oDom; - var oAnchor = this._oAnchor; - var aNodes = [this.element, oAnchor]; - var oEM = this._oHelpTextEM; - var oConfig = this.cfg; - var oImg = this.submenuIndicator; - var sImageSrc; - var sImageAlt; + var bDisabled = p_aArgs[0], + oAnchor = this._oAnchor, + aNodes = [this.element, oAnchor], + oEM = this._oHelpTextEM, + oConfig = this.cfg, + oImg, + sImgSrc, + sImgAlt; if(oEM) { @@ -3551,6 +8983,28 @@ } + + if(this.cfg.getProperty("checked")) { + + sImgAlt = this.CHECKED_IMAGE_ALT_TEXT; + sImgSrc = this.CHECKED_IMAGE_PATH; + oImg = this._checkImage; + + if(bDisabled) { + + sImgAlt = this.DISABLED_CHECKED_IMAGE_ALT_TEXT; + sImgSrc = this.DISABLED_CHECKED_IMAGE_PATH; + + } + + oImg.src = document.images[(this.imageRoot + sImgSrc)].src; + oImg.alt = sImgAlt; + + } + + + oImg = this.submenuIndicator; + if(bDisabled) { if(oConfig.getProperty("selected")) { @@ -3563,8 +9017,8 @@ Dom.addClass(aNodes, "disabled"); - sImageSrc = this.DISABLED_SUBMENU_INDICATOR_IMAGE_PATH; - sImageAlt = this.DISABLED_SUBMENU_INDICATOR_ALT_TEXT; + sImgSrc = this.DISABLED_SUBMENU_INDICATOR_IMAGE_PATH; + sImgAlt = this.DISABLED_SUBMENU_INDICATOR_ALT_TEXT; } else { @@ -3573,41 +9027,41 @@ Dom.removeClass(aNodes, "disabled"); - sImageSrc = this.SUBMENU_INDICATOR_IMAGE_PATH; - sImageAlt = this.COLLAPSED_SUBMENU_INDICATOR_ALT_TEXT; + sImgSrc = this.SUBMENU_INDICATOR_IMAGE_PATH; + sImgAlt = this.COLLAPSED_SUBMENU_INDICATOR_ALT_TEXT; } if(oImg) { - oImg.src = this.imageRoot + sImageSrc; - oImg.alt = sImageAlt; + oImg.src = this.imageRoot + sImgSrc; + oImg.alt = sImgAlt; } }, /** - * Event handler for when the "selected" configuration property of - * a MenuModuleItem instance changes. - * @param {String} p_sType The name of the event that was fired. - * @param {Array} p_aArgs Collection of arguments sent when the - * event was fired. - * @param {YAHOO.widget.MenuModuleItem} p_oItem The MenuModuleItem instance + * @method configSelected + * @description Event handler for when the "selected" configuration property + * of the menu item changes. + * @param {String} p_sType String representing the name of the event that + * was fired. + * @param {Array} p_aArgs Array of arguments sent when the event was fired. + * @param {YAHOO.widget.MenuItem} p_oItem Object representing the menu item * that fired the event. */ configSelected: function(p_sType, p_aArgs, p_oItem) { if(!this.cfg.getProperty("disabled")) { - var Dom = this._oDom; - var bSelected = p_aArgs[0]; - var oEM = this._oHelpTextEM; - var aNodes = [this.element, this._oAnchor]; - var oImg = this.submenuIndicator; - var sImageSrc; + var bSelected = p_aArgs[0], + oEM = this._oHelpTextEM, + aNodes = [this.element, this._oAnchor], + oImg = this.submenuIndicator, + sImgSrc; if(oEM) { @@ -3622,22 +9076,33 @@ } + + if(this.cfg.getProperty("checked")) { + + sImgSrc = this.imageRoot + (bSelected ? + this.SELECTED_CHECKED_IMAGE_PATH : this.CHECKED_IMAGE_PATH); + + this._checkImage.src = document.images[sImgSrc].src; + + } + + if(bSelected) { Dom.addClass(aNodes, "selected"); - sImageSrc = this.SELECTED_SUBMENU_INDICATOR_IMAGE_PATH; + sImgSrc = this.SELECTED_SUBMENU_INDICATOR_IMAGE_PATH; } else { Dom.removeClass(aNodes, "selected"); - sImageSrc = this.SUBMENU_INDICATOR_IMAGE_PATH; + sImgSrc = this.SUBMENU_INDICATOR_IMAGE_PATH; } if(oImg) { - oImg.src = document.images[(this.imageRoot + sImageSrc)].src; + oImg.src = document.images[(this.imageRoot + sImgSrc)].src; } @@ -3647,80 +9112,112 @@ /** - * Event handler for when the "submenu" configuration property of - * a MenuModuleItem instance changes. - * @param {String} p_sType The name of the event that was fired. - * @param {Array} p_aArgs Collection of arguments sent when the - * event was fired. - * @param {YAHOO.widget.MenuModuleItem} p_oItem The MenuModuleItem instance + * @method configSubmenu + * @description Event handler for when the "submenu" configuration property + * of the menu item changes. + * @param {String} p_sType String representing the name of the event that + * was fired. + * @param {Array} p_aArgs Array of arguments sent when the event was fired. + * @param {YAHOO.widget.MenuItem} p_oItem Object representing the menu item * that fired the event. */ configSubmenu: function(p_sType, p_aArgs, p_oItem) { - var Dom = this._oDom; - var oEl = this.element; - var oSubmenu = p_aArgs[0]; - var oImg = this.submenuIndicator; - var oConfig = this.cfg; - var aNodes = [this.element, this._oAnchor]; + var oEl = this.element, + oSubmenu = p_aArgs[0], + oImg = this.submenuIndicator, + oConfig = this.cfg, + aNodes = [this.element, this._oAnchor], + oMenu, + bLazyLoad = this.parent && this.parent.lazyLoad; if(oSubmenu) { - // Set the submenu's parent to this MenuModuleItem instance + if(oSubmenu instanceof Menu) { - oSubmenu.parent = this; + oMenu = oSubmenu; + oMenu.parent = this; + oMenu.lazyLoad = bLazyLoad; - this._oSubmenu = oSubmenu; + } + else if( + typeof oSubmenu == "object" && + oSubmenu.id && + !oSubmenu.nodeType + ) { + var sSubmenuId = oSubmenu.id, + oSubmenuConfig = oSubmenu; - if(!oImg) { + oSubmenuConfig.lazyload = bLazyLoad; + oSubmenuConfig.parent = this; - var me = this; + oMenu = new this.SUBMENU_TYPE(sSubmenuId, oSubmenuConfig); - function preloadImage(p_sPath) { - var sPath = me.imageRoot + p_sPath; + // Set the value of the property to the Menu instance - if(!document.images[sPath]) { + this.cfg.setProperty("submenu", oMenu, true); - var oImage = document.createElement("img"); - oImage.src = sPath; - oImage.name = sPath; - oImage.id = sPath; - oImage.style.display = "none"; + } + else { - document.body.appendChild(oImage); + oMenu = new this.SUBMENU_TYPE( + oSubmenu, + { lazyload: bLazyLoad, parent: this } + ); - } - } + // Set the value of the property to the Menu instance - preloadImage(this.SUBMENU_INDICATOR_IMAGE_PATH); - preloadImage(this.SELECTED_SUBMENU_INDICATOR_IMAGE_PATH); - preloadImage(this.DISABLED_SUBMENU_INDICATOR_IMAGE_PATH); + this.cfg.setProperty("submenu", oMenu, true); - oImg = document.createElement("img"); - oImg.src = (this.imageRoot + this.SUBMENU_INDICATOR_IMAGE_PATH); - oImg.alt = this.COLLAPSED_SUBMENU_INDICATOR_ALT_TEXT; + } - oEl.appendChild(oImg); - this.submenuIndicator = oImg; + if(oMenu) { - Dom.addClass(aNodes, "hassubmenu"); + this._oSubmenu = oMenu; - if(oConfig.getProperty("disabled")) { + if(!oImg) { - oConfig.refireEvent("disabled"); + this._preloadImage(this.SUBMENU_INDICATOR_IMAGE_PATH); + this._preloadImage( + this.SELECTED_SUBMENU_INDICATOR_IMAGE_PATH + ); - } + this._preloadImage( + this.DISABLED_SUBMENU_INDICATOR_IMAGE_PATH + ); - if(oConfig.getProperty("selected")) { + oImg = document.createElement("img"); - oConfig.refireEvent("selected"); + oImg.src = + (this.imageRoot + this.SUBMENU_INDICATOR_IMAGE_PATH); + oImg.alt = this.COLLAPSED_SUBMENU_INDICATOR_ALT_TEXT; + + oEl.appendChild(oImg); + + this.submenuIndicator = oImg; + + Dom.addClass(aNodes, "hassubmenu"); + + + if(oConfig.getProperty("disabled")) { + + oConfig.refireEvent("disabled"); + + } + + if(oConfig.getProperty("selected")) { + + oConfig.refireEvent("selected"); + + } + } } @@ -3750,16 +9247,25 @@ // Public methods /** - * Initializes an item's configurable properties. + * @method initDefaultConfig + * @description Initializes an item's configurable properties. */ initDefaultConfig : function() { - var oConfig = this.cfg; - var CheckBoolean = oConfig.checkBoolean; + var oConfig = this.cfg, + CheckBoolean = oConfig.checkBoolean; // Define the config properties + /** + * @config text + * @description String specifying the text label for the menu item. + * When building a menu from existing HTML the value of this property + * will be interpreted from the menu's markup. + * @default "" + * @type String + */ oConfig.addProperty( "text", { @@ -3770,18 +9276,58 @@ } ); + + /** + * @config helptext + * @description String specifying additional instructional text to + * accompany the text for the nenu item. + * @default null + * @type String| + * HTMLElement + */ oConfig.addProperty("helptext", { handler: this.configHelpText }); + + /** + * @config url + * @description String specifying the URL for the menu item's anchor's + * "href" attribute. When building a menu from existing HTML the value + * of this property will be interpreted from the menu's markup. + * @default "#" + * @type String + */ oConfig.addProperty( "url", { value: "#", handler: this.configURL, suppressEvent: true } ); + + /** + * @config target + * @description String specifying the value for the "target" attribute + * of the menu item's anchor element. Specifying a target will + * require the user to click directly on the menu item's anchor node in + * order to cause the browser to navigate to the specified URL. + * When building a menu from existing HTML the value of this property + * will be interpreted from the menu's markup. + * @default null + * @type String + */ oConfig.addProperty( "target", { handler: this.configTarget, suppressEvent: true } ); + + /** + * @config emphasis + * @description Boolean indicating if the text of the menu item will be + * rendered with emphasis. When building a menu from existing HTML the + * value of this property will be interpreted from the menu's markup. + * @default false + * @type Boolean + */ oConfig.addProperty( "emphasis", { @@ -3792,6 +9338,16 @@ } ); + + /** + * @config strongemphasis + * @description Boolean indicating if the text of the menu item will be + * rendered with strong emphasis. When building a menu from existing + * HTML the value of this property will be interpreted from the + * menu's markup. + * @default false + * @type Boolean + */ oConfig.addProperty( "strongemphasis", { @@ -3802,7 +9358,35 @@ } ); + + /** + * @config checked + * @description Boolean indicating if the menu item should be rendered + * with a checkmark. + * @default false + * @type Boolean + */ oConfig.addProperty( + "checked", + { + value: false, + handler: this.configChecked, + validator: this.cfg.checkBoolean, + suppressEvent: true, + supercedes:["disabled"] + } + ); + + + /** + * @config disabled + * @description Boolean indicating if the menu item should be disabled. + * (Disabled menu items are dimmed and will not respond to user input + * or fire events.) + * @default false + * @type Boolean + */ + oConfig.addProperty( "disabled", { value: false, @@ -3812,6 +9396,14 @@ } ); + + /** + * @config selected + * @description Boolean indicating if the menu item should + * be highlighted. + * @default false + * @type Boolean + */ oConfig.addProperty( "selected", { @@ -3822,29 +9414,46 @@ } ); + + /** + * @config submenu + * @description Object specifying the submenu to be appended to the + * menu item. The value can be one of the following:
  • Object + * specifying a Menu instance.
  • Object literal specifying the + * menu to be created. Format: { id: [menu id], itemdata: + * [array of values for + * items] }.
  • String specifying the id attribute + * of the <div> element of the menu.
  • + * Object specifying the <div> element of the + * menu.
+ * @default null + * @type Menu|String|Object| + * HTMLElement + */ oConfig.addProperty("submenu", { handler: this.configSubmenu }); }, /** - * Finds the next enabled MenuModuleItem instance in a MenuModule instance - * @return Returns a MenuModuleItem instance. - * @type YAHOO.widget.MenuModuleItem + * @method getNextEnabledSibling + * @description Finds the menu item's next enabled sibling. + * @return YAHOO.widget.MenuItem */ getNextEnabledSibling: function() { - if(this.parent instanceof YAHOO.widget.MenuModule) { + if(this.parent instanceof Menu) { var nGroupIndex = this.groupIndex; /** - * Returns the next item in an array - * @param {p_aArray} An array - * @param {p_nStartIndex} The index to start searching the array - * @ignore - * @return Returns an item in an array - * @type Object + * Finds the next item in an array. + * @private + * @param {p_aArray} Array to search. + * @param {p_nStartIndex} Number indicating the index to + * start searching the array. + * @return {Object} */ function getNextArrayItem(p_aArray, p_nStartIndex) { @@ -3854,8 +9463,8 @@ } - var aItemGroups = this.parent.getItemGroups(); - var oNextItem; + var aItemGroups = this.parent.getItemGroups(), + oNextItem; if(this.index < (aItemGroups[nGroupIndex].length - 1)) { @@ -3883,7 +9492,7 @@ var aNextGroup = getNextArrayItem(aItemGroups, nNextGroupIndex); - // Retrieve the first MenuModuleItem instance in the next group + // Retrieve the first menu item in the next group oNextItem = getNextArrayItem(aNextGroup, 0); @@ -3901,24 +9510,23 @@ /** - * Finds the previous enabled MenuModuleItem instance in a - * MenuModule instance - * @return Returns a MenuModuleItem instance. - * @type YAHOO.widget.MenuModuleItem + * @method getPreviousEnabledSibling + * @description Finds the menu item's previous enabled sibling. + * @return {YAHOO.widget.MenuItem} */ getPreviousEnabledSibling: function() { - if(this.parent instanceof YAHOO.widget.MenuModule) { + if(this.parent instanceof Menu) { var nGroupIndex = this.groupIndex; /** * Returns the previous item in an array - * @param {p_aArray} An array - * @param {p_nStartIndex} The index to start searching the array - * @ignore - * @return Returns an item in an array - * @type Object + * @private + * @param {p_aArray} Array to search. + * @param {p_nStartIndex} Number indicating the index to + * start searching the array. + * @return {Object} */ function getPreviousArrayItem(p_aArray, p_nStartIndex) { @@ -3930,11 +9538,11 @@ /** * Get the index of the first item in an array - * @param {p_aArray} An array - * @param {p_nStartIndex} The index to start searching the array - * @ignore - * @return Returns an item in an array - * @type Object + * @private + * @param {p_aArray} Array to search. + * @param {p_nStartIndex} Number indicating the index to + * start searching the array. + * @return {Object} */ function getFirstItemIndex(p_aArray, p_nStartIndex) { @@ -3944,8 +9552,8 @@ } - var aItemGroups = this.parent.getItemGroups(); - var oPreviousItem; + var aItemGroups = this.parent.getItemGroups(), + oPreviousItem; if( this.index > getFirstItemIndex(aItemGroups[nGroupIndex], 0) @@ -3996,15 +9604,31 @@ /** - * Causes a MenuModuleItem instance to receive the focus and fires the + * @method focus + * @description Causes the menu item to receive the focus and fires the * focus event. */ focus: function() { - var oParent = this.parent; - var oAnchor = this._oAnchor; - var oActiveItem = oParent.activeItem; + var oParent = this.parent, + oAnchor = this._oAnchor, + oActiveItem = oParent.activeItem; + + function setFocus() { + + try { + + oAnchor.focus(); + + } + catch(e) { + + } + + } + + if( !this.cfg.getProperty("disabled") && oParent && @@ -4018,8 +9642,15 @@ } - oAnchor.focus(); + /* + Setting focus via a timer fixes a race condition in Firefox, IE + and Opera where the browser viewport jumps as it trys to + position and focus the menu. + */ + + window.setTimeout(setFocus, 0); + this.focusEvent.fire(); } @@ -4028,7 +9659,9 @@ /** - * Causes a MenuModuleItem instance to lose focus and fires the onblur event. + * @method blur + * @description Causes the menu item to lose focus and fires the + * onblur event. */ blur: function() { @@ -4037,7 +9670,7 @@ if( !this.cfg.getProperty("disabled") && oParent && - this._oDom.getStyle(oParent.element, "visibility") == "visible" + Dom.getStyle(oParent.element, "visibility") == "visible" ) { this._oAnchor.blur(); @@ -4050,15 +9683,28 @@ /** - * Removes a MenuModuleItem instance's HTMLLIElement from it's parent - * HTMLUListElement node. + * @method destroy + * @description Removes the menu item's <li> element + * from its parent <ul> element. */ destroy: function() { var oEl = this.element; if(oEl) { + + // If the item has a submenu, destroy it first + + var oSubmenu = this.cfg.getProperty("submenu"); + + if(oSubmenu) { + + oSubmenu.destroy(); + + } + + // Remove CustomEvent listeners this.mouseOverEvent.unsubscribeAll(); @@ -4090,916 +9736,594 @@ } - } + }, -}; + /** + * @method toString + * @description Returns a string representing the menu item. + * @return {String} + */ + toString: function() { -/** -* @class Extends YAHOO.widget.MenuModule to provide a set of default mouse and -* key event behaviors. -* @constructor -* @extends YAHOO.widget.MenuModule -* @base YAHOO.widget.MenuModule -* @param {String or HTMLElement} p_oElement String id or HTMLElement -* (either HTMLSelectElement or HTMLDivElement) of the source HTMLElement node. -* @param {Object} p_oConfig Optional. The configuration object literal -* containing the configuration for a Menu instance. See -* configuration class documentation for more details. -*/ -YAHOO.widget.Menu = function(p_oElement, p_oConfig) { + return ("MenuItem: " + this.cfg.getProperty("text")); - YAHOO.widget.Menu.superclass.constructor.call( - this, - p_oElement, - p_oConfig - ); + } }; -YAHOO.extend(YAHOO.widget.Menu, YAHOO.widget.MenuModule); +})(); /** -* The Menu class's initialization method. This method is automatically -* called by the constructor, and sets up all DOM references for pre-existing -* markup, and creates required markup if it is not already present. -* @param {String or HTMLElement} p_oElement String id or HTMLElement -* (either HTMLSelectElement or HTMLDivElement) of the source HTMLElement node. -* @param {Object} p_oConfig Optional. The configuration object literal -* containing the configuration for a Menu instance. See -* configuration class documentation for more details. +* Creates an item for a menu module. +* +* @param {String} p_oObject String specifying the text of the menu module item. +* @param {HTMLLIElement} p_oObject Object specifying the +* <li> element of the menu module item. +* @param {HTMLOptGroupElement} p_oObject Object specifying +* the <optgroup> element of the menu module item. +* @param {HTMLOptionElement} p_oObject Object specifying the +* <option> element of the menu module item. +* @param {Object} p_oConfig Optional. Object literal specifying the +* configuration for the menu module item. See configuration class documentation +* for more details. +* @class MenuModuleItem +* @constructor +* @deprecated As of version 0.12, all MenuModuleItem functionality has been +* implemented directly in YAHOO.widget.MenuItem, making YAHOO.widget.MenuItem +* the base class for all menu items. */ -YAHOO.widget.Menu.prototype.init = function(p_oElement, p_oConfig) { +YAHOO.widget.MenuModuleItem = YAHOO.widget.MenuItem; - if(!this.ITEM_TYPE) { - this.ITEM_TYPE = YAHOO.widget.MenuItem; - - } - - - // Call the init of the superclass (YAHOO.widget.Menu) - - YAHOO.widget.Menu.superclass.init.call(this, p_oElement); - - - this.beforeInitEvent.fire(YAHOO.widget.Menu); - - - // Add event handlers - - this.showEvent.subscribe(this._onMenuShow, this, true); - this.mouseOverEvent.subscribe(this._onMenuMouseOver, this, true); - this.keyDownEvent.subscribe(this._onMenuKeyDown, this, true); - - - if(p_oConfig) { - - this.cfg.applyConfig(p_oConfig, true); - - } - - this.initEvent.fire(YAHOO.widget.Menu); - -}; - - -// Private event handlers - /** -* "show" Custom Event handler for a menu. -* @private -* @param {String} p_sType The name of the event that was fired. -* @param {Array} p_aArgs Collection of arguments sent when the event -* was fired. -* @param {YAHOO.widget.Menu} p_oMenu The menu that fired the event. +* Creates a list of options or commands which are made visible in response to +* an HTML element's "contextmenu" event ("mousedown" for Opera). +* +* @param {String} p_oElement String specifying the id attribute of the +* <div> element of the context menu. +* @param {String} p_oElement String specifying the id attribute of the +* <select> element to be used as the data source for the +* context menu. +* @param {HTMLDivElement} p_oElement Object specifying the +* <div> element of the context menu. +* @param {HTMLSelectElement} p_oElement Object specifying +* the <select> element to be used as the data source for +* the context menu. +* @param {Object} p_oConfig Optional. Object literal specifying the +* configuration for the context menu. See configuration class documentation +* for more details. +* @class ContextMenu +* @constructor +* @extends YAHOO.widget.Menu +* @namespace YAHOO.widget */ -YAHOO.widget.Menu.prototype._onMenuShow = +YAHOO.widget.ContextMenu = function(p_oElement, p_oConfig) { - function(p_sType, p_aArgs, p_oMenu) { + YAHOO.widget.ContextMenu.superclass.constructor.call( + this, + p_oElement, + p_oConfig + ); - var oParent = this.parent; +}; - if(oParent && oParent.parent instanceof YAHOO.widget.Menu) { - var aAlignment = oParent.parent.cfg.getProperty("submenualignment"); +YAHOO.extend(YAHOO.widget.ContextMenu, YAHOO.widget.Menu, { - this.cfg.setProperty( - "submenualignment", - [ aAlignment[0], aAlignment[1] ] - ); - } - }; +// Private properties /** -* "mouseover" Custom Event handler for a Menu instance. +* @property _oTrigger +* @description Object reference to the current value of the "trigger" +* configuration property. +* @default null * @private -* @param {String} p_sType The name of the event that was fired. -* @param {Array} p_aArgs Collection of arguments sent when the event -* was fired. -* @param {YAHOO.widget.Menu} p_oMenu The Menu instance that fired the event. +* @type String|HTMLElement|Array */ -YAHOO.widget.Menu.prototype._onMenuMouseOver = +_oTrigger: null, - function(p_sType, p_aArgs, p_oMenu) { - /* - If the menu is a submenu, then select the menu's parent - MenuItem instance - */ - if(this.parent) { +// Public properties - this.parent.cfg.setProperty("selected", true); - } - - }; - - /** -* "mouseover" Custom Event handler for a Menu instance. -* @private -* @param {String} p_sType The name of the event that was fired. -* @param {Array} p_aArgs Collection of arguments sent when the event -* was fired. -* @param {YAHOO.widget.Menu} p_oMenu The Menu instance that fired the event. +* @property contextEventTarget +* @description Object reference for the HTML element that was the target of the +* "contextmenu" DOM event ("mousedown" for Opera) that triggered the display of +* the context menu. +* @default null +* @type HTMLElement */ -YAHOO.widget.Menu.prototype._onMenuKeyDown = +contextEventTarget: null, - function(p_sType, p_aArgs, p_oMenu) { - if(this.cfg.getProperty("position") == "dynamic") { - - var oDOMEvent = p_aArgs[0]; - var oParent = this.parent; - - if(oDOMEvent.keyCode == 27) { // Esc key - - this.hide(); - - // Set focus to the parent MenuItem if one exists - - if(oParent) { - - oParent.focus(); - - if(oParent.parent instanceof YAHOO.widget.Menu) { - - oParent.cfg.setProperty("selected", true); - - } - - YAHOO.util.Event.preventDefault(oDOMEvent); - - } - - } - - } - - }; - - -// Public event handlers - /** -* Event handler fired when the resize monitor element is resized. +* @method init +* @description The ContextMenu class's initialization method. This method is +* automatically called by the constructor, and sets up all DOM references for +* pre-existing markup, and creates required markup if it is not already present. +* @param {String} p_oElement String specifying the id attribute of the +* <div> element of the context menu. +* @param {String} p_oElement String specifying the id attribute of the +* <select> element to be used as the data source for +* the context menu. +* @param {HTMLDivElement} p_oElement Object specifying the +* <div> element of the context menu. +* @param {HTMLSelectElement} p_oElement Object specifying +* the <select> element to be used as the data source for +* the context menu. +* @param {Object} p_oConfig Optional. Object literal specifying the +* configuration for the context menu. See configuration class documentation +* for more details. */ -YAHOO.widget.Menu.prototype.onDomResize = function(e, obj) { +init: function(p_oElement, p_oConfig) { - if(!this._handleResize) { + if(!this.ITEM_TYPE) { - this._handleResize = true; - return; + this.ITEM_TYPE = YAHOO.widget.ContextMenuItem; } - this.logger.log("Browser font sized changed."); - var me = this; - var oConfig = this.cfg; + // Call the init of the superclass (YAHOO.widget.Menu) - if(oConfig.getProperty("position") == "dynamic") { + YAHOO.widget.ContextMenu.superclass.init.call(this, p_oElement); - oConfig.setProperty("width", (this._getOffsetWidth() + "px")); - if(this.parent && oConfig.getProperty("visible")) { + this.beforeInitEvent.fire(YAHOO.widget.ContextMenu); - function align() { - me.align(); + if(p_oConfig) { - } + this.cfg.applyConfig(p_oConfig, true); - window.setTimeout(align, 0); - - } - } - YAHOO.widget.Menu.superclass.onDomResize.call(this, e, obj); -}; + this.initEvent.fire(YAHOO.widget.ContextMenu); +}, -/** -* @class The MenuItem class allows you to create and modify an item for a -* Menu instance. MenuItem extends YAHOO.widget.MenuModuleItem to provide a -* set of default mouse and key event behaviors. -* @constructor -* @extends YAHOO.widget.MenuModuleItem -* @base YAHOO.widget.MenuModuleItem -* @param {String or HTMLElement} p_oObject String or HTMLElement -* (either HTMLLIElement, HTMLOptGroupElement or HTMLOptionElement) of the -* source HTMLElement node. -* @param {Object} p_oConfig The configuration object literal containing -* the configuration for a MenuItem instance. See the configuration -* class documentation for more details. -*/ -YAHOO.widget.MenuItem = function(p_oObject, p_oConfig) { - YAHOO.widget.MenuItem.superclass.constructor.call( - this, - p_oObject, - p_oConfig - ); -}; +// Private methods -YAHOO.extend(YAHOO.widget.MenuItem, YAHOO.widget.MenuModuleItem); - /** -* The MenuItem class's initialization method. This method is automatically -* called by the constructor, and sets up all DOM references for -* pre-existing markup, and creates required markup if it is not -* already present. -* @param {String or HTMLElement} p_oObject String or HTMLElement -* (either HTMLLIElement, HTMLOptGroupElement or HTMLOptionElement) of the -* source HTMLElement node. -* @param {Object} p_oConfig The configuration object literal containing -* the configuration for a MenuItem instance. See the configuration -* class documentation for more details. +* @method _removeEventHandlers +* @description Removes all of the DOM event handlers from the HTML element(s) +* whose "context menu" event ("click" for Opera) trigger the display of +* the context menu. +* @private */ -YAHOO.widget.MenuItem.prototype.init = function(p_oObject, p_oConfig) { +_removeEventHandlers: function() { - if(!this.SUBMENU_TYPE) { + var Event = YAHOO.util.Event, + oTrigger = this._oTrigger, + bOpera = (this.browser == "opera"); - this.SUBMENU_TYPE = YAHOO.widget.Menu; - } + // Remove the event handlers from the trigger(s) - if(!this.SUBMENU_ITEM_TYPE) { + Event.removeListener( + oTrigger, + (bOpera ? "mousedown" : "contextmenu"), + this._onTriggerContextMenu + ); - this.SUBMENU_ITEM_TYPE = YAHOO.widget.MenuItem; + if(bOpera) { - } + Event.removeListener(oTrigger, "click", this._onTriggerClick); - - /* - Call the init of the superclass (YAHOO.widget.MenuModuleItem) - Note: We don't pass the user config in here yet - because we only want it executed once, at the lowest - subclass level. - */ - - YAHOO.widget.MenuItem.superclass.init.call(this, p_oObject); - - - // Add event handlers to each "MenuItem" instance - - this.keyDownEvent.subscribe(this._onKeyDown, this, true); - this.mouseOverEvent.subscribe(this._onMouseOver, this, true); - this.mouseOutEvent.subscribe(this._onMouseOut, this, true); - this.clickEvent.subscribe(this._onClick, this, true); - - - var oConfig = this.cfg; - - if(p_oConfig) { - - oConfig.applyConfig(p_oConfig, true); - } - oConfig.fireQueue(); +}, -}; -// Constants +// Private event handlers -/** -* Constant representing the path to the image to be used for the checked state. -* @final -* @type String -*/ -YAHOO.widget.MenuItem.prototype.CHECKED_IMAGE_PATH = - "nt/ic/ut/bsc/menuchk8_nrm_1.gif"; /** -* Constant representing the path to the image to be used for the selected -* checked state. -* @final -* @type String +* @method _onTriggerClick +* @description "click" event handler for the HTML element(s) identified as the +* "trigger" for the context menu. Used to cancel default behaviors in Opera. +* @private +* @param {Event} p_oEvent Object representing the DOM event object passed back +* by the event utility (YAHOO.util.Event). +* @param {YAHOO.widget.ContextMenu} p_oMenu Object representing the context +* menu that is handling the event. */ -YAHOO.widget.MenuItem.prototype.SELECTED_CHECKED_IMAGE_PATH = - "nt/ic/ut/bsc/menuchk8_hov_1.gif"; +_onTriggerClick: function(p_oEvent, p_oMenu) { -/** -* Constant representing the path to the image to be used for the disabled -* checked state. -* @final -* @type String -*/ -YAHOO.widget.MenuItem.prototype.DISABLED_CHECKED_IMAGE_PATH = - "nt/ic/ut/bsc/menuchk8_dim_1.gif"; + if(p_oEvent.ctrlKey) { -/** -* Constant representing the alt text for the image to be used for the -* checked image. -* @final -* @type String -*/ -YAHOO.widget.MenuItem.prototype.CHECKED_IMAGE_ALT_TEXT = "Checked."; + YAHOO.util.Event.stopEvent(p_oEvent); + } -/** -* Constant representing the alt text for the image to be used for the -* checked image when the item is disabled. -* @final -* @type String -*/ -YAHOO.widget.MenuItem.prototype.DISABLED_CHECKED_IMAGE_ALT_TEXT = - "Checked. (Item disabled.)"; +}, -// Private properties - /** -* Reference to the HTMLImageElement used to create the checked -* indicator for a MenuItem instance. +* @method _onTriggerContextMenu +* @description "contextmenu" event handler ("mousedown" for Opera) for the HTML +* element(s) that trigger the display of the context menu. * @private -* @type {HTMLImageElement} +* @param {Event} p_oEvent Object representing the DOM event object passed back +* by the event utility (YAHOO.util.Event). +* @param {YAHOO.widget.ContextMenu} p_oMenu Object representing the context +* menu that is handling the event. */ -YAHOO.widget.MenuItem.prototype._checkImage = null; +_onTriggerContextMenu: function(p_oEvent, p_oMenu) { + // Hide any other ContextMenu instances that might be visible -// Private event handlers + YAHOO.widget.MenuManager.hideVisible(); -/** -* "keydown" Custom Event handler for a MenuItem instance. -* @private -* @param {String} p_sType The name of the event that was fired. -* @param {Array} p_aArgs Collection of arguments sent when the event -* was fired. -* @param {YAHOO.widget.MenuItem} p_oMenuModule The MenuModule instance that -* fired the event. -*/ -YAHOO.widget.MenuItem.prototype._onKeyDown = - function(p_sType, p_aArgs, p_oMenuItem) { + var Event = YAHOO.util.Event, + oConfig = this.cfg; - var Event = YAHOO.util.Event; - var oDOMEvent = p_aArgs[0]; - var oParent = this.parent; - var oConfig = this.cfg; - var oMenuItem; + if(p_oEvent.type == "mousedown" && !p_oEvent.ctrlKey) { + return; - switch(oDOMEvent.keyCode) { + } - case 38: // Up arrow - case 40: // Down arrow + this.contextEventTarget = Event.getTarget(p_oEvent); - if( - this == oParent.activeItem && - !oConfig.getProperty("selected") - ) { - oConfig.setProperty("selected", true); + // Position and display the context menu - } - else { + var nX = Event.getPageX(p_oEvent), + nY = Event.getPageY(p_oEvent); - var oNextItem = (oDOMEvent.keyCode == 38) ? - this.getPreviousEnabledSibling() : - this.getNextEnabledSibling(); - if(oNextItem) { + oConfig.applyConfig( { xy:[nX, nY], visible:true } ); + oConfig.fireQueue(); - oParent.clearActiveItem(); - oNextItem.cfg.setProperty("selected", true); + /* + Prevent the browser's default context menu from appearing and + stop the propagation of the "contextmenu" event so that + other ContextMenu instances are not displayed. + */ - oNextItem.focus(); + Event.stopEvent(p_oEvent); - } +}, - } - Event.preventDefault(oDOMEvent); - break; +// Public methods - case 39: // Right arrow +/** +* @method toString +* @description Returns a string representing the context menu. +* @return {String} +*/ +toString: function() { - oParent.clearActiveItem(); + return ("ContextMenu " + this.id); - oConfig.setProperty("selected", true); +}, - this.focus(); +/** +* @method initDefaultConfig +* @description Initializes the class's configurable properties which can be +* changed using the context menu's Config object ("cfg"). +*/ +initDefaultConfig: function() { - var oSubmenu = oConfig.getProperty("submenu"); + YAHOO.widget.ContextMenu.superclass.initDefaultConfig.call(this); - if(oSubmenu) { + /** + * @config trigger + * @description The HTML element(s) whose "contextmenu" event ("mousedown" + * for Opera) trigger the display of the context menu. Can be a string + * representing the id attribute of the HTML element, an object reference + * for the HTML element, or an array of strings or HTML element references. + * @default null + * @type String|HTMLElement|Array + */ + this.cfg.addProperty("trigger", { handler: this.configTrigger }); - oSubmenu.show(); - oSubmenu.setInitialSelection(); +}, - } - else if( - YAHOO.widget.MenuBarItem && - oParent.parent && - oParent.parent instanceof YAHOO.widget.MenuBarItem - ) { - oParent.hide(); - - // Set focus to the parent MenuItem if one exists - - oMenuItem = oParent.parent; - - if(oMenuItem) { - - oMenuItem.focus(); - oMenuItem.cfg.setProperty("selected", true); - - } - - } - - Event.preventDefault(oDOMEvent); - - break; - - - case 37: // Left arrow - - // Only hide if this this is a MenuItem of a submenu - - if(oParent.parent) { - - oParent.hide(); - - // Set focus to the parent MenuItem if one exists - - oMenuItem = oParent.parent; - - if(oMenuItem) { - - oMenuItem.focus(); - oMenuItem.cfg.setProperty("selected", true); - - } - - } - - Event.preventDefault(oDOMEvent); - - break; - - } - - }; - - /** -* "mouseover" Custom Event handler for a MenuItem instance. -* @private -* @param {String} p_sType The name of the event that was fired. -* @param {Array} p_aArgs Collection of arguments sent when the event -* was fired. -* @param {YAHOO.widget.MenuItem} p_oMenuModule The MenuModule instance that -* fired the event. +* @method destroy +* @description Removes the context menu's <div> element +* (and accompanying child nodes) from the document. */ -YAHOO.widget.MenuItem.prototype._onMouseOver = +destroy: function() { - function(p_sType, p_aArgs, p_oMenuItem) { + // Remove the DOM event handlers from the current trigger(s) - var oParent = this.parent; - var oConfig = this.cfg; - var oActiveItem = oParent.activeItem; + this._removeEventHandlers(); - // Hide any other submenus that might be visible + // Continue with the superclass implementation of this method - if(oActiveItem && oActiveItem != this) { + YAHOO.widget.ContextMenu.superclass.destroy.call(this); - oParent.clearActiveItem(); +}, - } - // Select and focus the current MenuItem instance +// Public event handlers for configuration properties - oConfig.setProperty("selected", true); - this.focus(); - - // Show the submenu for this instance - - var oSubmenu = oConfig.getProperty("submenu"); - - if(oSubmenu) { - - oSubmenu.show(); - - } - - }; - - /** -* "mouseout" Custom Event handler for a MenuItem instance. -* @private -* @param {String} p_sType The name of the event that was fired. -* @param {Array} p_aArgs Collection of arguments sent when the event +* @method configTrigger +* @description Event handler for when the value of the "trigger" configuration +* property changes. +* @param {String} p_sType String representing the name of the event that * was fired. -* @param {YAHOO.widget.MenuItem} p_oMenuModule The MenuModule instance that -* fired the event. +* @param {Array} p_aArgs Array of arguments sent when the event was fired. +* @param {YAHOO.widget.ContextMenu} p_oMenu Object representing the context +* menu that fired the event. */ -YAHOO.widget.MenuItem.prototype._onMouseOut = +configTrigger: function(p_sType, p_aArgs, p_oMenu) { - function(p_sType, p_aArgs, p_oMenuItem) { + var Event = YAHOO.util.Event, + oTrigger = p_aArgs[0]; - var oConfig = this.cfg; - var oSubmenu = oConfig.getProperty("submenu"); + if(oTrigger) { - oConfig.setProperty("selected", false); + /* + If there is a current "trigger" - remove the event handlers + from that element(s) before assigning new ones + */ - if(oSubmenu) { + if(this._oTrigger) { - var oDOMEvent = p_aArgs[0]; - var oRelatedTarget = YAHOO.util.Event.getRelatedTarget(oDOMEvent); + this._removeEventHandlers(); - if( - !( - oRelatedTarget == oSubmenu.element || - YAHOO.util.Dom.isAncestor(oSubmenu.element, oRelatedTarget) - ) - ) { - - oSubmenu.hide(); - - } - } - }; + this._oTrigger = oTrigger; -/** -* "click" Custom Event handler for a MenuItem instance. -* @private -* @param {String} p_sType The name of the event that was fired. -* @param {Array} p_aArgs Collection of arguments sent when the event -* was fired. -* @param {YAHOO.widget.MenuItem} p_oMenuModule The MenuModule instance that -* fired the event. -*/ -YAHOO.widget.MenuItem.prototype._onClick = + /* + Listen for the "mousedown" event in Opera b/c it does not + support the "contextmenu" event + */ - function(p_sType, p_aArgs, p_oMenuItem) { + var bOpera = (this.browser == "opera"); - function findRoot(p_oMenu) { + Event.addListener( + oTrigger, + (bOpera ? "mousedown" : "contextmenu"), + this._onTriggerContextMenu, + this, + true + ); - var oItem = p_oMenu.parent; // The parent MenuItem instance - if(oItem) { + /* + Assign a "click" event handler to the trigger element(s) for + Opera to prevent default browser behaviors. + */ - var oParentMenu = oItem.parent; + if(bOpera) { - if( - oParentMenu && - (oParentMenu instanceof YAHOO.widget.Menu) && - oParentMenu.cfg.getProperty("position") == "dynamic" - ) { + Event.addListener( + oTrigger, + "click", + this._onTriggerClick, + this, + true + ); - return findRoot(oParentMenu); - - } - - } - - return p_oMenu; - } + } + else { - var oRoot = findRoot(this.parent); - var sURL = this.cfg.getProperty("url"); + this._removeEventHandlers(); - if( - (sURL.substr((sURL.length-1),1) == "#") && - oRoot && - oRoot.cfg.getProperty("position") == "dynamic" - ) { + } - oRoot.hide(); +} - } +}); // END YAHOO.extend - }; - -// Event handlers for configuration properties - /** -* Event handler for when the "checked" configuration property of -* a MenuItem instance changes. -* @param {String} p_sType The name of the event that was fired. -* @param {Array} p_aArgs Collection of arguments sent when the -* event was fired. -* @param {YAHOO.widget.MenuItem} p_oItem The MenuItem instance -* that fired the event. +* Creates an item for a context menu. +* +* @param {String} p_oObject String specifying the text of the context menu item. +* @param {HTMLLIElement} p_oObject Object specifying the +* <li> element of the context menu item. +* @param {HTMLOptGroupElement} p_oObject Object +* specifying the <optgroup> element of the context +* menu item. +* @param {HTMLOptionElement} p_oObject Object specifying +* the <option> element of the context menu item. +* @param {Object} p_oConfig Optional. Object literal specifying the +* configuration for the context menu item. See configuration class +* documentation for more details. +* @class ContextMenuItem +* @constructor +* @extends YAHOO.widget.MenuItem */ -YAHOO.widget.MenuItem.prototype.configChecked = +YAHOO.widget.ContextMenuItem = function(p_oObject, p_oConfig) { - function(p_sType, p_aArgs, p_oItem) { + YAHOO.widget.ContextMenuItem.superclass.constructor.call( + this, + p_oObject, + p_oConfig + ); - var Dom = YAHOO.util.Dom; - var bChecked = p_aArgs[0]; - var oEl = this.element; - var oConfig = this.cfg; - var oImg; +}; +YAHOO.extend(YAHOO.widget.ContextMenuItem, YAHOO.widget.MenuItem, { - if(bChecked) { - var me = this; - - function preloadImage(p_sPath) { - - var sPath = me.imageRoot + p_sPath; - - if(!document.images[sPath]) { - - var oImage = document.createElement("img"); - oImage.src = sPath; - oImage.name = sPath; - oImage.id = sPath; - oImage.style.display = "none"; - - document.body.appendChild(oImage); - - } - - } - - preloadImage(this.CHECKED_IMAGE_PATH); - preloadImage(this.SELECTED_CHECKED_IMAGE_PATH); - preloadImage(this.DISABLED_CHECKED_IMAGE_PATH); - - - oImg = document.createElement("img"); - oImg.src = (this.imageRoot + this.CHECKED_IMAGE_PATH); - oImg.alt = this.CHECKED_IMAGE_ALT_TEXT; - - var oSubmenu = this.cfg.getProperty("submenu"); - - if(oSubmenu) { - - oEl.insertBefore(oImg, oSubmenu.element); - - } - else { - - oEl.appendChild(oImg); - - } - - - Dom.addClass([oEl, oImg], "checked"); - - this._checkImage = oImg; - - if(oConfig.getProperty("disabled")) { - - oConfig.refireEvent("disabled"); - - } - - if(oConfig.getProperty("selected")) { - - oConfig.refireEvent("selected"); - - } - - } - else { - - oImg = this._checkImage; - - Dom.removeClass([oEl, oImg], "checked"); - - if(oImg) { - - oEl.removeChild(oImg); - - } - - this._checkImage = null; - - } - - }; - - /** -* Event handler for when the "selected" configuration property of -* a MenuItem instance changes. -* @param {String} p_sType The name of the event that was fired. -* @param {Array} p_aArgs Collection of arguments sent when the -* event was fired. -* @param {YAHOO.widget.MenuItem} p_oItem The MenuItem instance -* that fired the event. +* @method init +* @description The ContextMenuItem class's initialization method. This method +* is automatically called by the constructor, and sets up all DOM references +* for pre-existing markup, and creates required markup if it is not +* already present. +* @param {String} p_oObject String specifying the text of the context menu item. +* @param {HTMLLIElement} p_oObject Object specifying the +* <li> element of the context menu item. +* @param {HTMLOptGroupElement} p_oObject Object +* specifying the <optgroup> element of the context +* menu item. +* @param {HTMLOptionElement} p_oObject Object specifying +* the <option> element of the context menu item. +* @param {Object} p_oConfig Optional. Object literal specifying the +* configuration for the context menu item. See configuration class +* documentation for more details. */ -YAHOO.widget.MenuItem.prototype.configSelected = +init: function(p_oObject, p_oConfig) { - function(p_sType, p_aArgs, p_oItem) { + if(!this.SUBMENU_TYPE) { - YAHOO.widget.MenuItem.superclass.configSelected.call( - this, p_sType, p_aArgs, p_oItem - ); + this.SUBMENU_TYPE = YAHOO.widget.ContextMenu; - var oConfig = this.cfg; + } - if(!oConfig.getProperty("disabled") && oConfig.getProperty("checked")) { - var bSelected = p_aArgs[0]; + /* + Call the init of the superclass (YAHOO.widget.MenuItem) + Note: We don't pass the user config in here yet + because we only want it executed once, at the lowest + subclass level. + */ - var sSrc = this.imageRoot + (bSelected ? - this.SELECTED_CHECKED_IMAGE_PATH : this.CHECKED_IMAGE_PATH); + YAHOO.widget.ContextMenuItem.superclass.init.call(this, p_oObject); - this._checkImage.src = document.images[sSrc].src; + var oConfig = this.cfg; - } + if(p_oConfig) { - }; + oConfig.applyConfig(p_oConfig, true); + } -/** -* Event handler for when the "disabled" configuration property of -* a MenuItem instance changes. -* @param {String} p_sType The name of the event that was fired. -* @param {Array} p_aArgs Collection of arguments sent when the -* event was fired. -* @param {YAHOO.widget.MenuItem} p_oItem The MenuItem instance -* that fired the event. -*/ -YAHOO.widget.MenuItem.prototype.configDisabled = + oConfig.fireQueue(); - function(p_sType, p_aArgs, p_oItem) { +}, - YAHOO.widget.MenuItem.superclass.configDisabled.call( - this, p_sType, p_aArgs, p_oItem - ); - if(this.cfg.getProperty("checked")) { - var bDisabled = p_aArgs[0]; - var sAlt = this.CHECKED_IMAGE_ALT_TEXT; - var sSrc = this.CHECKED_IMAGE_PATH; - var oImg = this._checkImage; - - if(bDisabled) { - - sAlt = this.DISABLED_CHECKED_IMAGE_ALT_TEXT; - sSrc = this.DISABLED_CHECKED_IMAGE_PATH; - - } - - oImg.src = document.images[(this.imageRoot + sSrc)].src; - oImg.alt = sAlt; - - } - - }; - - // Public methods + /** -* Initializes the class's configurable properties which can be changed using -* the MenuModule's Config object (cfg). +* @method toString +* @description Returns a string representing the context menu item. +* @return {String} */ -YAHOO.widget.MenuItem.prototype.initDefaultConfig = function() { +toString: function() { - YAHOO.widget.MenuItem.superclass.initDefaultConfig.call(this); + return ("MenuBarItem: " + this.cfg.getProperty("text")); - // Add configuration properties +} - this.cfg.addProperty( - "checked", - { - value: false, - handler: this.configChecked, - validator: this.cfg.checkBoolean, - suppressEvent: true, - supercedes:["disabled"] - } - ); +}); // END YAHOO.extend -}; - /** -* @class Creates a list of options which vary depending on the context in -* which the menu is invoked. +* Horizontal collection of items, each of which can contain a submenu. +* +* @param {String} p_oElement String specifying the id attribute of the +* <div> element of the menu bar. +* @param {String} p_oElement String specifying the id attribute of the +* <select> element to be used as the data source for the +* menu bar. +* @param {HTMLDivElement} p_oElement Object specifying +* the <div> element of the menu bar. +* @param {HTMLSelectElement} p_oElement Object +* specifying the <select> element to be used as the data +* source for the menu bar. +* @param {Object} p_oConfig Optional. Object literal specifying the +* configuration for the menu bar. See configuration class documentation for +* more details. +* @class Menubar * @constructor * @extends YAHOO.widget.Menu -* @base YAHOO.widget.Menu -* @param {String or HTMLElement} p_oElement String id or HTMLElement -* (either HTMLSelectElement or HTMLDivElement) of the source HTMLElement node. -* @param {Object} p_oConfig Optional. The configuration object literal -* containing the configuration for a ContextMenu instance. See -* configuration class documentation for more details. +* @namespace YAHOO.widget */ -YAHOO.widget.ContextMenu = function(p_oElement, p_oConfig) { +YAHOO.widget.MenuBar = function(p_oElement, p_oConfig) { - YAHOO.widget.ContextMenu.superclass.constructor.call( + YAHOO.widget.MenuBar.superclass.constructor.call( this, p_oElement, p_oConfig ); }; -YAHOO.extend(YAHOO.widget.ContextMenu, YAHOO.widget.Menu); +YAHOO.extend(YAHOO.widget.MenuBar, YAHOO.widget.Menu, { - -// Private properties - - /** -* Array of ContextMenu instances -* @private -* @type {Array} +* @method init +* @description The MenuBar class's initialization method. This method is +* automatically called by the constructor, and sets up all DOM references for +* pre-existing markup, and creates required markup if it is not already present. +* @param {String} p_oElement String specifying the id attribute of the +* <div> element of the menu bar. +* @param {String} p_oElement String specifying the id attribute of the +* <select> element to be used as the data source for the +* menu bar. +* @param {HTMLDivElement} p_oElement Object specifying +* the <div> element of the menu bar. +* @param {HTMLSelectElement} p_oElement Object +* specifying the <select> element to be used as the data +* source for the menu bar. +* @param {Object} p_oConfig Optional. Object literal specifying the +* configuration for the menu bar. See configuration class documentation for +* more details. */ -YAHOO.widget.ContextMenu._aMenus = []; +init: function(p_oElement, p_oConfig) { - -/** -* The id(s) or element(s) that trigger the display of the ContextMenu instance -* @private -* @type {String/Array/HTMLElement} -*/ -YAHOO.widget.ContextMenu.prototype._oTrigger = null; - - -// Public properties - -/** -* Returns the HTMLElement node that was the target of the "contextmenu" -* DOM event. -* @type HTMLElement -*/ -YAHOO.widget.ContextMenu.prototype.contextEventTarget = null; - - -/** -* The ContextMenu class's initialization method. This method is automatically -* called by the constructor, and sets up all DOM references for pre-existing -* markup, and creates required markup if it is not already present. -* @param {String or HTMLElement} p_oElement String id or HTMLElement -* (either HTMLSelectElement or HTMLDivElement) of the source HTMLElement node. -* @param {Object} p_oConfig Optional. The configuration object literal -* containing the configuration for a ContextMenu instance. See -* configuration class documentation for more details. -*/ -YAHOO.widget.ContextMenu.prototype.init = function(p_oElement, p_oConfig) { - if(!this.ITEM_TYPE) { - this.ITEM_TYPE = YAHOO.widget.ContextMenuItem; + this.ITEM_TYPE = YAHOO.widget.MenuBarItem; } // Call the init of the superclass (YAHOO.widget.Menu) - YAHOO.widget.ContextMenu.superclass.init.call(this, p_oElement); + YAHOO.widget.MenuBar.superclass.init.call(this, p_oElement); - this.beforeInitEvent.fire(YAHOO.widget.ContextMenu); + this.beforeInitEvent.fire(YAHOO.widget.MenuBar); if(p_oConfig) { @@ -5008,407 +10332,351 @@ } + this.initEvent.fire(YAHOO.widget.MenuBar); - this.initEvent.fire(YAHOO.widget.ContextMenu); +}, - var aMenus = YAHOO.widget.ContextMenu._aMenus; - aMenus[aMenus.length] = this; +// Constants -}; - -// Private event handlers - /** -* "click" event handler for the document object. -* @private -* @param {Event} p_oEvent Event object passed back by the -* event utility (YAHOO.util.Event). -* @param {YAHOO.widget.ContextMenu} p_oMenu The ContextMenu instance -* handling the event. +* @property CSS_CLASS_NAME +* @description String representing the CSS class(es) to be applied to the menu +* bar's <div> element. +* @default "yuimenubar" +* @final +* @type String */ -YAHOO.widget.ContextMenu.prototype._onDocumentClick = +CSS_CLASS_NAME: "yuimenubar", - function(p_oEvent, p_oMenu) { - this.hide(); - }; +// Protected event handlers /** -* "click" event handler for the HTMLElement node that triggered the event. -* Used to cancel default behaviors in Opera. +* @method _onKeyDown +* @description "keydown" Custom Event handler for the menu bar. * @private -* @param {Event} p_oEvent Event object passed back by the -* event utility (YAHOO.util.Event). -* @param {YAHOO.widget.ContextMenu} p_oMenu The ContextMenu instance -* handling the event. +* @param {String} p_sType String representing the name of the event that +* was fired. +* @param {Array} p_aArgs Array of arguments sent when the event was fired. +* @param {YAHOO.widget.MenuBar} p_oMenuBar Object representing the menu bar +* that fired the event. */ -YAHOO.widget.ContextMenu.prototype._onTriggerClick = +_onKeyDown: function(p_sType, p_aArgs, p_oMenuBar) { - function(p_oEvent, p_oMenu) { + var Event = YAHOO.util.Event, + oEvent = p_aArgs[0], + oItem = p_aArgs[1], + oSubmenu; - if(p_oEvent.ctrlKey) { - YAHOO.util.Event.stopEvent(p_oEvent); + if(oItem && !oItem.cfg.getProperty("disabled")) { - } + var oItemCfg = oItem.cfg; - }; + switch(oEvent.keyCode) { + case 37: // Left arrow + case 39: // Right arrow -/** -* "contextmenu" event handler ("mousedown" for Opera) for the HTMLElement -* node that triggered the event. -* @private -* @param {Event} p_oEvent Event object passed back by the -* event utility (YAHOO.util.Event). -* @param {YAHOO.widget.ContextMenu} p_oMenu The ContextMenu instance -* handling the event. -*/ -YAHOO.widget.ContextMenu.prototype._onTriggerContextMenu = + if( + oItem == this.activeItem && + !oItemCfg.getProperty("selected") + ) { - function(p_oEvent, p_oMenu) { + oItemCfg.setProperty("selected", true); - var Event = YAHOO.util.Event; - var oConfig = this.cfg; + } + else { + var oNextItem = (oEvent.keyCode == 37) ? + oItem.getPreviousEnabledSibling() : + oItem.getNextEnabledSibling(); - // Hide any other ContextMenu instances that might be visible + if(oNextItem) { - var aMenus = YAHOO.widget.ContextMenu._aMenus; - var i = aMenus.length - 1; + this.clearActiveItem(); - do { + oNextItem.cfg.setProperty("selected", true); - aMenus[i].hide(); - } - while(i--); + if(this.cfg.getProperty("autosubmenudisplay")) { + oSubmenu = oNextItem.cfg.getProperty("submenu"); - if(p_oEvent.type == "mousedown" && !p_oEvent.ctrlKey) { + if(oSubmenu) { - return; + oSubmenu.show(); + oSubmenu.activeItem.blur(); + oSubmenu.activeItem = null; - } + } - this.contextEventTarget = Event.getTarget(p_oEvent); + } + oNextItem.focus(); - // Position and display the context menu + } - var nX = Event.getPageX(p_oEvent); - var nY = Event.getPageY(p_oEvent); + } + Event.preventDefault(oEvent); - oConfig.applyConfig( { xy:[nX, nY], visible:true } ); - oConfig.fireQueue(); + break; + case 40: // Down arrow - /* - Prevent the browser's default context menu from appearing and - stop the propagation of the "contextmenu" event so that - other ContextMenu instances are no displayed. - */ + if(this.activeItem != oItem) { - Event.stopEvent(p_oEvent); + this.clearActiveItem(); - }; + oItemCfg.setProperty("selected", true); + oItem.focus(); + } + oSubmenu = oItemCfg.getProperty("submenu"); -// Public methods + if(oSubmenu) { -/** -* Initializes the class's configurable properties which can be changed using -* a ContextMenu instance's Config object (cfg). -*/ -YAHOO.widget.ContextMenu.prototype.initDefaultConfig = function() { + if(oSubmenu.cfg.getProperty("visible")) { - YAHOO.widget.ContextMenu.superclass.initDefaultConfig.call(this); + oSubmenu.setInitialSelection(); + oSubmenu.setInitialFocus(); + } + else { - // Add a configuration property + oSubmenu.show(); - this.cfg.addProperty("trigger", { handler: this.configTrigger }); + } -}; + } + Event.preventDefault(oEvent); -// Event handlers for configuration properties + break; -/** -* Event handler for when the "trigger" configuration property of -* a MenuItem instance. -* @param {String} p_sType The name of the event that was fired. -* @param {Array} p_aArgs Collection of arguments sent when the -* event was fired. -* @param {YAHOO.widget.ContextMenu} p_oMenu The ContextMenu that instance fired -* the event. -*/ -YAHOO.widget.ContextMenu.prototype.configTrigger = + } - function(p_sType, p_aArgs, p_oMenu) { + } - var Event = YAHOO.util.Event; - var oTrigger = p_aArgs[0]; - if(oTrigger) { + if(oEvent.keyCode == 27 && this.activeItem) { // Esc key + oSubmenu = this.activeItem.cfg.getProperty("submenu"); - /* - If there is a current "trigger" - remove the event handlers - from that element(s) before assigning new ones - */ - if(this._oTrigger) { + if(oSubmenu && oSubmenu.cfg.getProperty("visible")) { - Event.purgeElement(this._oTrigger); + oSubmenu.hide(); + this.activeItem.focus(); - } + } + else { + this.activeItem.cfg.setProperty("selected", false); + this.activeItem.blur(); - this._oTrigger = oTrigger; + } + Event.preventDefault(oEvent); - /* - Listen for the "mousedown" event in Opera b/c it does not - support the "contextmenu" event - */ + } - var bOpera = (this.browser == "opera"); +}, - Event.addListener( - oTrigger, - (bOpera ? "mousedown" : "contextmenu"), - this._onTriggerContextMenu, - this, - true - ); +/** +* @method _onClick +* @description "click" event handler for the menu bar. +* @protected +* @param {String} p_sType String representing the name of the event that +* was fired. +* @param {Array} p_aArgs Array of arguments sent when the event was fired. +* @param {YAHOO.widget.MenuBar} p_oMenuBar Object representing the menu bar +* that fired the event. +*/ +_onClick: function(p_sType, p_aArgs, p_oMenuBar) { - /* - Assign a "click" event handler to the trigger element(s) for - Opera to prevent default browser behaviors. - */ + YAHOO.widget.MenuBar.superclass._onClick.call( + this, + p_sType, + p_aArgs, + p_oMenuBar + ); - if(bOpera) { - Event.addListener( - oTrigger, - "click", - this._onTriggerClick, - this, - true - ); + var oItem = p_aArgs[1]; - } + if(oItem && !oItem.cfg.getProperty("disabled")) { + var Event = YAHOO.util.Event, + Dom = YAHOO.util.Dom, - // Assign a "mousedown" event handler to the document + oEvent = p_aArgs[0], + oTarget = Event.getTarget(oEvent), - Event.addListener( - document, - "click", - this._onDocumentClick, - this, - true - ); + oActiveItem = this.activeItem, + oConfig = this.cfg; - } - }; + // Hide any other submenus that might be visible + if(oActiveItem && oActiveItem != oItem) { -/** -* @class Creates an item for a context menu instance. -* @constructor -* @extends YAHOO.widget.MenuItem -* @base YAHOO.widget.MenuItem -* @param {String or HTMLElement} p_oObject String or HTMLElement -* (either HTMLLIElement, HTMLOptGroupElement or HTMLOptionElement) of the -* source HTMLElement node. -* @param {Object} p_oConfig The configuration object literal containing -* the configuration for a ContextMenuItem instance. See the configuration -* class documentation for more details. -*/ -YAHOO.widget.ContextMenuItem = function(p_oObject, p_oConfig) { + this.clearActiveItem(); - YAHOO.widget.ContextMenuItem.superclass.constructor.call( - this, - p_oObject, - p_oConfig - ); + } -}; -YAHOO.extend(YAHOO.widget.ContextMenuItem, YAHOO.widget.MenuItem); + // Select and focus the current item + oItem.cfg.setProperty("selected", true); + oItem.focus(); -/** -* The ContextMenuItem class's initialization method. This method is -* automatically called by the constructor, and sets up all DOM references for -* pre-existing markup, and creates required markup if it is not -* already present. -* @param {String or HTMLElement} p_oObject String or HTMLElement -* (either HTMLLIElement, HTMLOptGroupElement or HTMLOptionElement) of the -* source HTMLElement node. -* @param {Object} p_oConfig The configuration object literal containing -* the configuration for a ContextMenuItem instance. See the configuration -* class documentation for more details. -*/ -YAHOO.widget.ContextMenuItem.prototype.init = - function(p_oObject, p_oConfig) { + // Show the submenu for the item - if(!this.SUBMENU_TYPE) { + var oSubmenu = oItem.cfg.getProperty("submenu"); - this.SUBMENU_TYPE = YAHOO.widget.ContextMenu; - } + if(oSubmenu && oTarget != oItem.submenuIndicator) { - if(!this.SUBMENU_ITEM_TYPE) { + if(oSubmenu.cfg.getProperty("visible")) { - this.SUBMENU_ITEM_TYPE = YAHOO.widget.ContextMenuItem; + oSubmenu.hide(); - } + } + else { + oSubmenu.show(); - /* - Call the init of the superclass (YAHOO.widget.MenuItem) - Note: We don't pass the user config in here yet - because we only want it executed once, at the lowest - subclass level. - */ + } - YAHOO.widget.ContextMenuItem.superclass.init.call(this, p_oObject); + } - var oConfig = this.cfg; + } - if(p_oConfig) { +}, - oConfig.applyConfig(p_oConfig, true); - } - oConfig.fireQueue(); +// Public methods - }; - /** -* @class Horizontal collection of items, each of which can contain a submenu. -* Extends YAHOO.widget.MenuModule to provide a set of default mouse and -* key event behaviors. -* @constructor -* @extends YAHOO.widget.MenuModule -* @base YAHOO.widget.MenuModule -* @param {String or HTMLElement} p_oElement String id or HTMLElement -* (either HTMLSelectElement or HTMLDivElement) of the source HTMLElement node. -* @param {Object} p_oConfig Optional. The configuration object literal -* containing the configuration for a MenuBar instance. See -* configuration class documentation for more details. +* @method toString +* @description Returns a string representing the menu bar. +* @return {String} */ -YAHOO.widget.MenuBar = function(p_oElement, p_oConfig) { +toString: function() { - YAHOO.widget.MenuBar.superclass.constructor.call( - this, - p_oElement, - p_oConfig - ); + return ("MenuBar " + this.id); -}; +}, -YAHOO.extend(YAHOO.widget.MenuBar, YAHOO.widget.MenuModule); - /** -* The MenuBar class's initialization method. This method is automatically -* called by the constructor, and sets up all DOM references for pre-existing -* markup, and creates required markup if it is not already present. -* @param {String or HTMLElement} p_oElement String id or HTMLElement -* (either HTMLSelectElement or HTMLDivElement) of the source HTMLElement node. -* @param {Object} p_oConfig Optional. The configuration object literal -* containing the configuration for a MenuBar instance. See -* configuration class documentation for more details. +* @description Initializes the class's configurable properties which can be +* changed using the menu bar's Config object ("cfg"). +* @method initDefaultConfig */ -YAHOO.widget.MenuBar.prototype.init = function(p_oElement, p_oConfig) { +initDefaultConfig: function() { - if(!this.ITEM_TYPE) { + YAHOO.widget.MenuBar.superclass.initDefaultConfig.call(this); - this.ITEM_TYPE = YAHOO.widget.MenuBarItem; + var oConfig = this.cfg; - } + // Add configuration properties - // Call the init of the superclass (YAHOO.widget.MenuModule) - - YAHOO.widget.MenuBar.superclass.init.call(this, p_oElement); - - - this.beforeInitEvent.fire(YAHOO.widget.MenuBar); - - var oConfig = this.cfg; - /* Set the default value for the "position" configuration property - to "static" + to "static" by re-adding the property. */ - if(!p_oConfig || (p_oConfig && !p_oConfig.position)) { - oConfig.queueProperty("position", "static"); + /** + * @config position + * @description String indicating how a menu bar should be positioned on the + * screen. Possible values are "static" and "dynamic." Static menu bars + * are visible by default and reside in the normal flow of the document + * (CSS position: static). Dynamic menu bars are hidden by default, reside + * out of the normal flow of the document (CSS position: absolute), and can + * overlay other elements on the screen. + * @default static + * @type String + */ + oConfig.addProperty( + "position", + { + value: "static", + handler: this.configPosition, + validator: this._checkPosition, + supercedes: ["visible"] + } + ); - } /* Set the default value for the "submenualignment" configuration property - to "tl" and "bl" + to ["tl","bl"] by re-adding the property. */ - if(!p_oConfig || (p_oConfig && !p_oConfig.submenualignment)) { - oConfig.queueProperty("submenualignment", ["tl","bl"]); + /** + * @config submenualignment + * @description Array defining how submenus should be aligned to their + * parent menu bar item. The format is: [itemCorner, submenuCorner]. + * @default ["tl","bl"] + * @type Array + */ + oConfig.addProperty("submenualignment", { value: ["tl","bl"] } ); - } + /* + Change the default value for the "autosubmenudisplay" configuration + property to "false" by re-adding the property. + */ - if(p_oConfig) { + /** + * @config autosubmenudisplay + * @description Boolean indicating if submenus are automatically made + * visible when the user mouses over the menu bar's items. + * @default false + * @type Boolean + */ + oConfig.addProperty( + "autosubmenudisplay", + { value: false, validator: oConfig.checkBoolean } + ); - oConfig.applyConfig(p_oConfig, true); +} - } +}); // END YAHOO.extend - this.initEvent.fire(YAHOO.widget.MenuBar); -}; - - -// Constants - /** -* Constant representing the CSS class(es) to be applied to the root -* HTMLDivElement of the MenuBar instance. -* @final -* @type String -*/ -YAHOO.widget.MenuBar.prototype.CSS_CLASS_NAME = "yuimenubar"; - - -/** -* @class The MenuBarItem class allows you to create and modify an item for a -* MenuBar instance. MenuBarItem extends YAHOO.widget.MenuModuleItem to provide -* a set of default mouse and key event behaviors. +* Creates an item for a menu bar. +* +* @param {String} p_oObject String specifying the text of the menu bar item. +* @param {HTMLLIElement} p_oObject Object specifying the +* <li> element of the menu bar item. +* @param {HTMLOptGroupElement} p_oObject Object +* specifying the <optgroup> element of the menu bar item. +* @param {HTMLOptionElement} p_oObject Object specifying +* the <option> element of the menu bar item. +* @param {Object} p_oConfig Optional. Object literal specifying the +* configuration for the menu bar item. See configuration class documentation +* for more details. +* @class MenuBarItem * @constructor -* @extends YAHOO.widget.MenuModuleItem -* @base YAHOO.widget.MenuModuleItem -* @param {String or HTMLElement} p_oObject String or HTMLElement -* (either HTMLLIElement, HTMLOptGroupElement or HTMLOptionElement) of the -* source HTMLElement node. -* @param {Object} p_oConfig The configuration object literal containing -* the configuration for a MenuBarItem instance. See the configuration -* class documentation for more details. +* @extends YAHOO.widget.MenuItem */ YAHOO.widget.MenuBarItem = function(p_oObject, p_oConfig) { @@ -5420,38 +10688,39 @@ }; -YAHOO.extend(YAHOO.widget.MenuBarItem, YAHOO.widget.MenuModuleItem); +YAHOO.extend(YAHOO.widget.MenuBarItem, YAHOO.widget.MenuItem, { /** -* The MenuBarItem class's initialization method. This method is automatically -* called by the constructor, and sets up all DOM references for -* pre-existing markup, and creates required markup if it is not -* already present. -* @param {String or HTMLElement} p_oObject String or HTMLElement -* (either HTMLLIElement, HTMLOptGroupElement or HTMLOptionElement) of the -* source HTMLElement node. -* @param {Object} p_oConfig The configuration object literal containing -* the configuration for a MenuBarItem instance. See the configuration -* class documentation for more details. +* @method init +* @description The MenuBarItem class's initialization method. This method is +* automatically called by the constructor, and sets up all DOM references for +* pre-existing markup, and creates required markup if it is not already present. +* @param {String} p_oObject String specifying the text of the menu bar item. +* @param {HTMLLIElement} p_oObject Object specifying the +* <li> element of the menu bar item. +* @param {HTMLOptGroupElement} p_oObject Object +* specifying the <optgroup> element of the menu bar item. +* @param {HTMLOptionElement} p_oObject Object specifying +* the <option> element of the menu bar item. +* @param {Object} p_oConfig Optional. Object literal specifying the +* configuration for the menu bar item. See configuration class documentation +* for more details. */ -YAHOO.widget.MenuBarItem.prototype.init = function(p_oObject, p_oConfig) { +init: function(p_oObject, p_oConfig) { if(!this.SUBMENU_TYPE) { this.SUBMENU_TYPE = YAHOO.widget.Menu; } - if(!this.SUBMENU_ITEM_TYPE) { - this.SUBMENU_ITEM_TYPE = YAHOO.widget.MenuItem; - - } - - /* - Call the init of the superclass (YAHOO.widget.MenuModuleItem) + Call the init of the superclass (YAHOO.widget.MenuItem) Note: We don't pass the user config in here yet because we only want it executed once, at the lowest subclass level. @@ -5460,10 +10729,6 @@ YAHOO.widget.MenuBarItem.superclass.init.call(this, p_oObject); - // Add event handlers to each "MenuBarItem" instance - - this.keyDownEvent.subscribe(this._onKeyDown, this, true); - var oConfig = this.cfg; if(p_oConfig) { @@ -5474,126 +10739,69 @@ oConfig.fireQueue(); -}; +}, + // Constants /** -* Constant representing the CSS class(es) to be applied to the root -* HTMLLIElement of the MenuBarItem. +* @property CSS_CLASS_NAME +* @description String representing the CSS class(es) to be applied to the +* <li> element of the menu bar item. +* @default "yuimenubaritem" * @final * @type String */ -YAHOO.widget.MenuBarItem.prototype.CSS_CLASS_NAME = "yuimenubaritem"; +CSS_CLASS_NAME: "yuimenubaritem", /** -* Constant representing the path to the image to be used for the submenu -* arrow indicator. +* @property SUBMENU_INDICATOR_IMAGE_PATH +* @description String representing the path to the image to be used for the +* menu bar item's submenu arrow indicator. +* @default "nt/ic/ut/alt1/menuarodwn8_nrm_1.gif" * @final * @type String */ -YAHOO.widget.MenuBarItem.prototype.SUBMENU_INDICATOR_IMAGE_PATH = - "nt/ic/ut/alt1/menuarodwn8_nrm_1.gif"; +SUBMENU_INDICATOR_IMAGE_PATH: "nt/ic/ut/alt1/menuarodwn8_nrm_1.gif", /** -* Constant representing the path to the image to be used for the submenu -* arrow indicator when a MenuBarItem instance is selected. +* @property SELECTED_SUBMENU_INDICATOR_IMAGE_PATH +* @description String representing the path to the image to be used for the +* submenu arrow indicator when the menu bar item is selected. +* @default "nt/ic/ut/alt1/menuarodwn8_hov_1.gif" * @final * @type String */ -YAHOO.widget.MenuBarItem.prototype.SELECTED_SUBMENU_INDICATOR_IMAGE_PATH = - "nt/ic/ut/alt1/menuarodwn8_hov_1.gif"; +SELECTED_SUBMENU_INDICATOR_IMAGE_PATH: "nt/ic/ut/alt1/menuarodwn8_hov_1.gif", /** -* Constant representing the path to the image to be used for the submenu -* arrow indicator when a MenuBarItem instance is disabled. +* @property DISABLED_SUBMENU_INDICATOR_IMAGE_PATH +* @description String representing the path to the image to be used for the +* submenu arrow indicator when the menu bar item is disabled. +* @default "nt/ic/ut/alt1/menuarodwn8_dim_1.gif" * @final * @type String */ -YAHOO.widget.MenuBarItem.prototype.DISABLED_SUBMENU_INDICATOR_IMAGE_PATH = - "nt/ic/ut/alt1/menuarodwn8_dim_1.gif"; +DISABLED_SUBMENU_INDICATOR_IMAGE_PATH: "nt/ic/ut/alt1/menuarodwn8_dim_1.gif", -// Private event handlers +// Public methods + + /** -* "keydown" Custom Event handler for a MenuBarItem instance. -* @private -* @param {String} p_sType The name of the event that was fired. -* @param {Array} p_aArgs Collection of arguments sent when the event -* was fired. -* @param {YAHOO.widget.MenuBarItem} p_oMenuModule The MenuModule instance that -* fired the event. +* @method toString +* @description Returns a string representing the menu bar item. +* @return {String} */ -YAHOO.widget.MenuBarItem.prototype._onKeyDown = +toString: function() { - function(p_sType, p_aArgs, p_oMenuItem) { + return ("MenuBarItem: " + this.cfg.getProperty("text")); - var Event = YAHOO.util.Event; - var oDOMEvent = p_aArgs[0]; - var oConfig = this.cfg; - var oParent = this.parent; +} - switch(oDOMEvent.keyCode) { - - case 37: // Left arrow - case 39: // Right arrow - - if( - this == oParent.activeItem && - !oConfig.getProperty("selected") - ) { - - oConfig.setProperty("selected", true); - - } - else { - - var oNextItem = (oDOMEvent.keyCode == 37) ? - this.getPreviousEnabledSibling() : - this.getNextEnabledSibling(); - - if(oNextItem) { - - oParent.clearActiveItem(); - - oNextItem.cfg.setProperty("selected", true); - - oNextItem.focus(); - - } - - } - - Event.preventDefault(oDOMEvent); - - break; - - case 40: // Down arrow - - oParent.clearActiveItem(); - - oConfig.setProperty("selected", true); - - this.focus(); - - var oSubmenu = oConfig.getProperty("submenu"); - - if(oSubmenu) { - - oSubmenu.show(); - oSubmenu.setInitialSelection(); - - } - - Event.preventDefault(oDOMEvent); - - break; - - } - - }; \ No newline at end of file +}); // END YAHOO.extend \ No newline at end of file