/hippo/src/main/webapp/yui/menu/menu.js
JavaScript | 2672 lines | 1057 code | 903 blank | 712 comment | 212 complexity | a7e26f3d475ea2390af24915b94adc59 MD5 | raw file
- /*
- Copyright (c) 2009, Yahoo! Inc. All rights reserved.
- Code licensed under the BSD License:
- http://developer.yahoo.net/yui/license.txt
- version: 2.7.0
- */
- /**
- * @module menu
- * @description <p>The Menu family of components features a collection of
- * controls that make it easy to add menus to your website or web application.
- * With the Menu Controls you can create website fly-out menus, customized
- * context menus, or application-style menu bars with just a small amount of
- * scripting.</p><p>The Menu family of controls features:</p>
- * <ul>
- * <li>Keyboard and mouse navigation.</li>
- * <li>A rich event model that provides access to all of a menu's
- * interesting moments.</li>
- * <li>Support for
- * <a href="http://en.wikipedia.org/wiki/Progressive_Enhancement">Progressive
- * Enhancement</a>; Menus can be created from simple,
- * semantic markup on the page or purely through JavaScript.</li>
- * </ul>
- * @title Menu
- * @namespace YAHOO.widget
- * @requires Event, Dom, Container
- */
- (function () {
- var _DIV = "DIV",
- _HD = "hd",
- _BD = "bd",
- _FT = "ft",
- _LI = "LI",
- _DISABLED = "disabled",
- _MOUSEOVER = "mouseover",
- _MOUSEOUT = "mouseout",
- _MOUSEDOWN = "mousedown",
- _MOUSEUP = "mouseup",
- _FOCUS = YAHOO.env.ua.ie ? "focusin" : "focus",
- _CLICK = "click",
- _KEYDOWN = "keydown",
- _KEYUP = "keyup",
- _KEYPRESS = "keypress",
- _CLICK_TO_HIDE = "clicktohide",
- _POSITION = "position",
- _DYNAMIC = "dynamic",
- _SHOW_DELAY = "showdelay",
- _SELECTED = "selected",
- _VISIBLE = "visible",
- _UL = "UL",
- _MENUMANAGER = "MenuManager",
-
-
- Dom = YAHOO.util.Dom,
- Event = YAHOO.util.Event,
- Lang = YAHOO.lang;
- /**
- * 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 () {
-
- // Private member variables
-
-
- // Flag indicating if the DOM event handlers have been attached
-
- var m_bInitializedEventHandlers = false,
-
-
- // Collection of menus
- m_oMenus = {},
- // Collection of visible menus
-
- m_oVisibleMenus = {},
-
-
- // Collection of menu items
- m_oItems = {},
- // Map of DOM event types to their equivalent CustomEvent types
-
- m_oEventTypes = {
- "click": "clickEvent",
- "mousedown": "mouseDownEvent",
- "mouseup": "mouseUpEvent",
- "mouseover": "mouseOverEvent",
- "mouseout": "mouseOutEvent",
- "keydown": "keyDownEvent",
- "keyup": "keyUpEvent",
- "keypress": "keyPressEvent",
- "focus": "focusEvent",
- "focusin": "focusEvent",
- "blur": "blurEvent",
- "focusout": "blurEvent"
- },
- // The element in the DOM that currently has focus
-
- m_oFocusedElement = null,
-
-
- m_oFocusedMenuItem = null;
-
-
-
- // Private methods
-
-
- /**
- * @method getMenuRootElement
- * @description Finds the root DIV node of a menu or the root LI node of
- * a menu item.
- * @private
- * @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/
- * level-one-html.html#ID-58190037">HTMLElement</a>} p_oElement Object
- * specifying an HTML element.
- */
- function getMenuRootElement(p_oElement) {
-
- var oParentNode,
- returnVal;
-
- if (p_oElement && p_oElement.tagName) {
-
- switch (p_oElement.tagName.toUpperCase()) {
-
- case _DIV:
-
- oParentNode = p_oElement.parentNode;
-
- // Check if the DIV is the inner "body" node of a menu
- if ((
- Dom.hasClass(p_oElement, _HD) ||
- Dom.hasClass(p_oElement, _BD) ||
- Dom.hasClass(p_oElement, _FT)
- ) &&
- oParentNode &&
- oParentNode.tagName &&
- oParentNode.tagName.toUpperCase() == _DIV) {
-
- returnVal = oParentNode;
-
- }
- else {
-
- returnVal = p_oElement;
-
- }
-
- break;
- case _LI:
-
- returnVal = p_oElement;
-
- break;
- default:
-
- oParentNode = p_oElement.parentNode;
-
- if (oParentNode) {
-
- returnVal = getMenuRootElement(oParentNode);
-
- }
-
- break;
-
- }
-
- }
-
- return returnVal;
-
- }
-
-
-
- // Private event handlers
-
-
- /**
- * @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) {
-
- // Get the target node of the DOM event
-
- var oTarget = Event.getTarget(p_oEvent),
-
- // See if the target of the event was a menu, or a menu item
-
- oElement = getMenuRootElement(oTarget),
- sCustomEventType,
- sTagName,
- sId,
- oMenuItem,
- oMenu;
-
-
- if (oElement) {
-
- sTagName = oElement.tagName.toUpperCase();
-
- if (sTagName == _LI) {
-
- sId = oElement.id;
-
- if (sId && m_oItems[sId]) {
-
- oMenuItem = m_oItems[sId];
- oMenu = oMenuItem.parent;
-
- }
-
- }
- else if (sTagName == _DIV) {
-
- if (oElement.id) {
-
- oMenu = m_oMenus[oElement.id];
-
- }
-
- }
-
- }
-
-
- if (oMenu) {
-
- sCustomEventType = m_oEventTypes[p_oEvent.type];
-
-
- // Fire the Custom Event that corresponds the current DOM event
-
- if (oMenuItem && !oMenuItem.cfg.getProperty(_DISABLED)) {
-
- oMenuItem[sCustomEventType].fire(p_oEvent);
-
- }
-
- 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
- */
-
- for (var i in m_oVisibleMenus) {
-
- if (Lang.hasOwnProperty(m_oVisibleMenus, i)) {
-
- oMenu = m_oVisibleMenus[i];
- if (oMenu.cfg.getProperty(_CLICK_TO_HIDE) &&
- !(oMenu instanceof YAHOO.widget.MenuBar) &&
- oMenu.cfg.getProperty(_POSITION) == _DYNAMIC) {
-
- oMenu.hide();
-
- }
- else {
-
- if (oMenu.cfg.getProperty(_SHOW_DELAY) > 0) {
-
- oMenu._cancelShowDelay();
-
- }
- if (oMenu.activeItem) {
-
- oMenu.activeItem.blur();
- oMenu.activeItem.cfg.setProperty(_SELECTED, false);
-
- oMenu.activeItem = null;
-
- }
-
- }
-
- }
-
- }
-
- }
- else if (p_oEvent.type == _FOCUS) {
-
- m_oFocusedElement = oTarget;
-
- }
-
- }
-
-
- /**
- * @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 The menu that fired the event.
- */
- function onMenuDestroy(p_sType, p_aArgs, p_oMenu) {
-
- if (m_oMenus[p_oMenu.id]) {
-
- this.removeMenu(p_oMenu);
-
- }
-
- }
-
-
- /**
- * @method onMenuFocus
- * @description "focus" 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.
- */
- function onMenuFocus(p_sType, p_aArgs) {
-
- var oItem = p_aArgs[1];
-
- if (oItem) {
-
- m_oFocusedMenuItem = oItem;
-
- }
-
- }
-
-
- /**
- * @method onMenuBlur
- * @description "blur" 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.
- */
- function onMenuBlur(p_sType, p_aArgs) {
-
- m_oFocusedMenuItem = null;
-
- }
-
- /**
- * @method onMenuHide
- * @description "hide" 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.
- * @param <a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/
- * level-one-html.html#ID-58190037">p_oFocusedElement</a> The HTML element that had focus
- * prior to the Menu being made visible
- */
- function onMenuHide(p_sType, p_aArgs, p_oFocusedElement) {
- /*
- Restore focus to the element in the DOM that had focus prior to the Menu
- being made visible
- */
- if (p_oFocusedElement && p_oFocusedElement.focus) {
-
- try {
- p_oFocusedElement.focus();
- }
- catch(ex) {
- }
-
- }
-
- this.hideEvent.unsubscribe(onMenuHide, p_oFocusedElement);
-
- }
-
- /**
- * @method onMenuShow
- * @description "show" 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.
- */
- function onMenuShow(p_sType, p_aArgs) {
- /*
- Dynamically positioned, root Menus focus themselves when visible, and will then,
- when hidden, restore focus to the UI control that had focus before the Menu was
- made visible
- */
- if (this === this.getRoot() && this.cfg.getProperty(_POSITION) === _DYNAMIC) {
-
- this.hideEvent.subscribe(onMenuHide, m_oFocusedElement);
- this.focus();
-
- }
-
- }
-
-
- /**
- * @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.
- */
- function onMenuVisibleConfigChange(p_sType, p_aArgs) {
-
- var bVisible = p_aArgs[0],
- sId = this.id;
-
- if (bVisible) {
-
- m_oVisibleMenus[sId] = this;
-
-
- }
- else if (m_oVisibleMenus[sId]) {
-
- delete m_oVisibleMenus[sId];
-
-
- }
-
- }
-
-
- /**
- * @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.
- */
- function onItemDestroy(p_sType, p_aArgs) {
-
- removeItem(this);
-
- }
- /**
- * @method removeItem
- * @description Removes a MenuItem instance from the MenuManager's collection of MenuItems.
- * @private
- * @param {MenuItem} p_oMenuItem The MenuItem instance to be removed.
- */
- function removeItem(p_oMenuItem) {
- var sId = p_oMenuItem.id;
-
- if (sId && m_oItems[sId]) {
-
- if (m_oFocusedMenuItem == p_oMenuItem) {
-
- m_oFocusedMenuItem = null;
-
- }
-
- delete m_oItems[sId];
-
- p_oMenuItem.destroyEvent.unsubscribe(onItemDestroy);
-
-
- }
- }
-
-
- /**
- * @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) {
-
- var oItem = p_aArgs[0],
- sId;
-
- if (oItem instanceof YAHOO.widget.MenuItem) {
-
- sId = oItem.id;
-
- if (!m_oItems[sId]) {
-
- m_oItems[sId] = oItem;
-
- oItem.destroyEvent.subscribe(onItemDestroy);
-
-
- }
-
- }
-
- }
-
-
- 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) {
-
- var oDoc;
-
- if (p_oMenu instanceof YAHOO.widget.Menu && p_oMenu.id &&
- !m_oMenus[p_oMenu.id]) {
-
- m_oMenus[p_oMenu.id] = p_oMenu;
-
-
- if (!m_bInitializedEventHandlers) {
-
- oDoc = document;
-
- Event.on(oDoc, _MOUSEOVER, onDOMEvent, this, true);
- Event.on(oDoc, _MOUSEOUT, onDOMEvent, this, true);
- Event.on(oDoc, _MOUSEDOWN, onDOMEvent, this, true);
- Event.on(oDoc, _MOUSEUP, onDOMEvent, this, true);
- Event.on(oDoc, _CLICK, onDOMEvent, this, true);
- Event.on(oDoc, _KEYDOWN, onDOMEvent, this, true);
- Event.on(oDoc, _KEYUP, onDOMEvent, this, true);
- Event.on(oDoc, _KEYPRESS, onDOMEvent, this, true);
-
- Event.onFocus(oDoc, onDOMEvent, this, true);
- Event.onBlur(oDoc, onDOMEvent, this, true);
-
- m_bInitializedEventHandlers = true;
-
-
- }
-
- p_oMenu.cfg.subscribeToConfigEvent(_VISIBLE, onMenuVisibleConfigChange);
- p_oMenu.destroyEvent.subscribe(onMenuDestroy, p_oMenu, this);
- p_oMenu.itemAddedEvent.subscribe(onItemAdded);
- p_oMenu.focusEvent.subscribe(onMenuFocus);
- p_oMenu.blurEvent.subscribe(onMenuBlur);
- p_oMenu.showEvent.subscribe(onMenuShow);
-
-
- }
-
- },
-
-
- /**
- * @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) {
-
- var sId,
- aItems,
- i;
-
- if (p_oMenu) {
-
- sId = p_oMenu.id;
-
- if ((sId in m_oMenus) && (m_oMenus[sId] == p_oMenu)) {
- // Unregister each menu item
- aItems = p_oMenu.getItems();
- if (aItems && aItems.length > 0) {
- i = aItems.length - 1;
- do {
- removeItem(aItems[i]);
- }
- while (i--);
- }
- // Unregister the menu
- delete m_oMenus[sId];
-
-
- /*
- Unregister the menu from the collection of
- visible menus
- */
- if ((sId in m_oVisibleMenus) && (m_oVisibleMenus[sId] == p_oMenu)) {
-
- delete m_oVisibleMenus[sId];
-
-
- }
- // Unsubscribe event listeners
- if (p_oMenu.cfg) {
- p_oMenu.cfg.unsubscribeFromConfigEvent(_VISIBLE,
- onMenuVisibleConfigChange);
-
- }
- p_oMenu.destroyEvent.unsubscribe(onMenuDestroy,
- p_oMenu);
-
- p_oMenu.itemAddedEvent.unsubscribe(onItemAdded);
- p_oMenu.focusEvent.unsubscribe(onMenuFocus);
- p_oMenu.blurEvent.unsubscribe(onMenuBlur);
- }
-
- }
-
- },
-
-
- /**
- * @method hideVisible
- * @description Hides all visible, dynamically positioned menus
- * (excluding instances of YAHOO.widget.MenuBar).
- */
- hideVisible: function () {
-
- var oMenu;
-
- for (var i in m_oVisibleMenus) {
-
- if (Lang.hasOwnProperty(m_oVisibleMenus, i)) {
-
- oMenu = m_oVisibleMenus[i];
-
- if (!(oMenu instanceof YAHOO.widget.MenuBar) &&
- oMenu.cfg.getProperty(_POSITION) == _DYNAMIC) {
-
- oMenu.hide();
-
- }
-
- }
-
- }
-
- },
- /**
- * @method getVisible
- * @description Returns a collection of all visible menus registered
- * with the menu manger.
- * @return {Object}
- */
- getVisible: function () {
-
- return m_oVisibleMenus;
-
- },
-
- /**
- * @method getMenus
- * @description Returns a collection of all menus registered with the
- * menu manger.
- * @return {Object}
- */
- 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
- * <code><div></code> element representing the menu to
- * be retrieved.
- * @return {YAHOO.widget.Menu}
- */
- getMenu: function (p_sId) {
-
- var returnVal;
-
- if (p_sId in m_oMenus) {
-
- returnVal = m_oMenus[p_sId];
-
- }
-
- return returnVal;
-
- },
-
-
- /**
- * @method getMenuItem
- * @description Returns a menu item with the specified id.
- * @param {String} p_sId String specifying the id of the
- * <code><li></code> element representing the menu item to
- * be retrieved.
- * @return {YAHOO.widget.MenuItem}
- */
- getMenuItem: function (p_sId) {
-
- var returnVal;
-
- if (p_sId in m_oItems) {
-
- returnVal = m_oItems[p_sId];
-
- }
-
- return returnVal;
-
- },
- /**
- * @method getMenuItemGroup
- * @description Returns an array of menu item instances whose
- * corresponding <code><li></code> elements are child
- * nodes of the <code><ul></code> element with the
- * specified id.
- * @param {String} p_sId String specifying the id of the
- * <code><ul></code> element representing the group of
- * menu items to be retrieved.
- * @return {Array}
- */
- getMenuItemGroup: function (p_sId) {
- var oUL = Dom.get(p_sId),
- aItems,
- oNode,
- oItem,
- sId,
- returnVal;
-
- if (oUL && oUL.tagName && oUL.tagName.toUpperCase() == _UL) {
- oNode = oUL.firstChild;
- if (oNode) {
- aItems = [];
-
- do {
- sId = oNode.id;
- if (sId) {
-
- oItem = this.getMenuItem(sId);
-
- if (oItem) {
-
- aItems[aItems.length] = oItem;
-
- }
-
- }
-
- }
- while ((oNode = oNode.nextSibling));
- if (aItems.length > 0) {
- returnVal = aItems;
-
- }
- }
-
- }
- return returnVal;
-
- },
-
- /**
- * @method getFocusedMenuItem
- * @description Returns a reference to the menu item that currently
- * has focus.
- * @return {YAHOO.widget.MenuItem}
- */
- getFocusedMenuItem: function () {
-
- return m_oFocusedMenuItem;
-
- },
-
-
- /**
- * @method getFocusedMenu
- * @description Returns a reference to the menu that currently
- * has focus.
- * @return {YAHOO.widget.Menu}
- */
- getFocusedMenu: function () {
- var returnVal;
-
- if (m_oFocusedMenuItem) {
-
- returnVal = m_oFocusedMenuItem.parent.getRoot();
-
- }
-
- return returnVal;
-
- },
-
-
- /**
- * @method toString
- * @description Returns a string representing the menu manager.
- * @return {String}
- */
- toString: function () {
-
- return _MENUMANAGER;
-
- }
-
- };
-
- }();
- })();
- (function () {
- var Lang = YAHOO.lang,
- // String constants
-
- _MENU = "Menu",
- _DIV_UPPERCASE = "DIV",
- _DIV_LOWERCASE = "div",
- _ID = "id",
- _SELECT = "SELECT",
- _XY = "xy",
- _Y = "y",
- _UL_UPPERCASE = "UL",
- _UL_LOWERCASE = "ul",
- _FIRST_OF_TYPE = "first-of-type",
- _LI = "LI",
- _OPTGROUP = "OPTGROUP",
- _OPTION = "OPTION",
- _DISABLED = "disabled",
- _NONE = "none",
- _SELECTED = "selected",
- _GROUP_INDEX = "groupindex",
- _INDEX = "index",
- _SUBMENU = "submenu",
- _VISIBLE = "visible",
- _HIDE_DELAY = "hidedelay",
- _POSITION = "position",
- _DYNAMIC = "dynamic",
- _STATIC = "static",
- _DYNAMIC_STATIC = _DYNAMIC + "," + _STATIC,
- _WINDOWS = "windows",
- _URL = "url",
- _HASH = "#",
- _TARGET = "target",
- _MAX_HEIGHT = "maxheight",
- _TOP_SCROLLBAR = "topscrollbar",
- _BOTTOM_SCROLLBAR = "bottomscrollbar",
- _UNDERSCORE = "_",
- _TOP_SCROLLBAR_DISABLED = _TOP_SCROLLBAR + _UNDERSCORE + _DISABLED,
- _BOTTOM_SCROLLBAR_DISABLED = _BOTTOM_SCROLLBAR + _UNDERSCORE + _DISABLED,
- _MOUSEMOVE = "mousemove",
- _SHOW_DELAY = "showdelay",
- _SUBMENU_HIDE_DELAY = "submenuhidedelay",
- _IFRAME = "iframe",
- _CONSTRAIN_TO_VIEWPORT = "constraintoviewport",
- _PREVENT_CONTEXT_OVERLAP = "preventcontextoverlap",
- _SUBMENU_ALIGNMENT = "submenualignment",
- _AUTO_SUBMENU_DISPLAY = "autosubmenudisplay",
- _CLICK_TO_HIDE = "clicktohide",
- _CONTAINER = "container",
- _SCROLL_INCREMENT = "scrollincrement",
- _MIN_SCROLL_HEIGHT = "minscrollheight",
- _CLASSNAME = "classname",
- _SHADOW = "shadow",
- _KEEP_OPEN = "keepopen",
- _HD = "hd",
- _HAS_TITLE = "hastitle",
- _CONTEXT = "context",
- _EMPTY_STRING = "",
- _MOUSEDOWN = "mousedown",
- _KEYDOWN = "keydown",
- _HEIGHT = "height",
- _WIDTH = "width",
- _PX = "px",
- _EFFECT = "effect",
- _MONITOR_RESIZE = "monitorresize",
- _DISPLAY = "display",
- _BLOCK = "block",
- _VISIBILITY = "visibility",
- _ABSOLUTE = "absolute",
- _ZINDEX = "zindex",
- _YUI_MENU_BODY_SCROLLED = "yui-menu-body-scrolled",
- _NON_BREAKING_SPACE = " ",
- _SPACE = " ",
- _MOUSEOVER = "mouseover",
- _MOUSEOUT = "mouseout",
- _ITEM_ADDED = "itemAdded",
- _ITEM_REMOVED = "itemRemoved",
- _HIDDEN = "hidden",
- _YUI_MENU_SHADOW = "yui-menu-shadow",
- _YUI_MENU_SHADOW_VISIBLE = _YUI_MENU_SHADOW + "-visible",
- _YUI_MENU_SHADOW_YUI_MENU_SHADOW_VISIBLE = _YUI_MENU_SHADOW + _SPACE + _YUI_MENU_SHADOW_VISIBLE;
- /**
- * The Menu class creates a container that holds a vertical list representing
- * a set of options or commands. Menu is the base class for all
- * menu containers.
- * @param {String} p_oElement String specifying the id attribute of the
- * <code><div></code> element of the menu.
- * @param {String} p_oElement String specifying the id attribute of the
- * <code><select></code> element to be used as the data source
- * for the menu.
- * @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/
- * level-one-html.html#ID-22445964">HTMLDivElement</a>} p_oElement Object
- * specifying the <code><div></code> element of the menu.
- * @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/
- * level-one-html.html#ID-94282980">HTMLSelectElement</a>} p_oElement
- * Object specifying the <code><select></code> 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
- * more details.
- * @namespace YAHOO.widget
- * @class Menu
- * @constructor
- * @extends YAHOO.widget.Overlay
- */
- YAHOO.widget.Menu = function (p_oElement, p_oConfig) {
- if (p_oConfig) {
- this.parent = p_oConfig.parent;
- this.lazyLoad = p_oConfig.lazyLoad || p_oConfig.lazyload;
- this.itemData = p_oConfig.itemData || p_oConfig.itemdata;
- }
- YAHOO.widget.Menu.superclass.constructor.call(this, p_oElement, p_oConfig);
- };
- /**
- * @method checkPosition
- * @description Checks to make sure that the value of the "position" property
- * is one of the supported strings. Returns true if the position is supported.
- * @private
- * @param {Object} p_sPosition String specifying the position of the menu.
- * @return {Boolean}
- */
- function checkPosition(p_sPosition) {
- var returnVal = false;
- if (Lang.isString(p_sPosition)) {
- returnVal = (_DYNAMIC_STATIC.indexOf((p_sPosition.toLowerCase())) != -1);
- }
- return returnVal;
- }
- var Dom = YAHOO.util.Dom,
- Event = YAHOO.util.Event,
- Module = YAHOO.widget.Module,
- Overlay = YAHOO.widget.Overlay,
- Menu = YAHOO.widget.Menu,
- MenuManager = YAHOO.widget.MenuManager,
- CustomEvent = YAHOO.util.CustomEvent,
- UA = YAHOO.env.ua,
-
- m_oShadowTemplate,
- EVENT_TYPES = [
-
- ["mouseOverEvent", _MOUSEOVER],
- ["mouseOutEvent", _MOUSEOUT],
- ["mouseDownEvent", _MOUSEDOWN],
- ["mouseUpEvent", "mouseup"],
- ["clickEvent", "click"],
- ["keyPressEvent", "keypress"],
- ["keyDownEvent", _KEYDOWN],
- ["keyUpEvent", "keyup"],
- ["focusEvent", "focus"],
- ["blurEvent", "blur"],
- ["itemAddedEvent", _ITEM_ADDED],
- ["itemRemovedEvent", _ITEM_REMOVED]
- ],
- VISIBLE_CONFIG = {
- key: _VISIBLE,
- value: false,
- validator: Lang.isBoolean
- },
- CONSTRAIN_TO_VIEWPORT_CONFIG = {
- key: _CONSTRAIN_TO_VIEWPORT,
- value: true,
- validator: Lang.isBoolean,
- supercedes: [_IFRAME,"x",_Y,_XY]
- },
- PREVENT_CONTEXT_OVERLAP_CONFIG = {
- key: _PREVENT_CONTEXT_OVERLAP,
- value: true,
- validator: Lang.isBoolean,
- supercedes: [_CONSTRAIN_TO_VIEWPORT]
- },
- POSITION_CONFIG = {
- key: _POSITION,
- value: _DYNAMIC,
- validator: checkPosition,
- supercedes: [_VISIBLE, _IFRAME]
- },
- SUBMENU_ALIGNMENT_CONFIG = {
- key: _SUBMENU_ALIGNMENT,
- value: ["tl","tr"]
- },
- AUTO_SUBMENU_DISPLAY_CONFIG = {
- key: _AUTO_SUBMENU_DISPLAY,
- value: true,
- validator: Lang.isBoolean,
- suppressEvent: true
- },
- SHOW_DELAY_CONFIG = {
- key: _SHOW_DELAY,
- value: 250,
- validator: Lang.isNumber,
- suppressEvent: true
- },
- HIDE_DELAY_CONFIG = {
- key: _HIDE_DELAY,
- value: 0,
- validator: Lang.isNumber,
- suppressEvent: true
- },
- SUBMENU_HIDE_DELAY_CONFIG = {
- key: _SUBMENU_HIDE_DELAY,
- value: 250,
- validator: Lang.isNumber,
- suppressEvent: true
- },
- CLICK_TO_HIDE_CONFIG = {
- key: _CLICK_TO_HIDE,
- value: true,
- validator: Lang.isBoolean,
- suppressEvent: true
- },
- CONTAINER_CONFIG = {
- key: _CONTAINER,
- suppressEvent: true
- },
- SCROLL_INCREMENT_CONFIG = {
- key: _SCROLL_INCREMENT,
- value: 1,
- validator: Lang.isNumber,
- supercedes: [_MAX_HEIGHT],
- suppressEvent: true
- },
- MIN_SCROLL_HEIGHT_CONFIG = {
- key: _MIN_SCROLL_HEIGHT,
- value: 90,
- validator: Lang.isNumber,
- supercedes: [_MAX_HEIGHT],
- suppressEvent: true
- },
- MAX_HEIGHT_CONFIG = {
- key: _MAX_HEIGHT,
- value: 0,
- validator: Lang.isNumber,
- supercedes: [_IFRAME],
- suppressEvent: true
- },
- CLASS_NAME_CONFIG = {
- key: _CLASSNAME,
- value: null,
- validator: Lang.isString,
- suppressEvent: true
- },
- DISABLED_CONFIG = {
- key: _DISABLED,
- value: false,
- validator: Lang.isBoolean,
- suppressEvent: true
- },
-
- SHADOW_CONFIG = {
- key: _SHADOW,
- value: true,
- validator: Lang.isBoolean,
- suppressEvent: true,
- supercedes: [_VISIBLE]
- },
-
- KEEP_OPEN_CONFIG = {
- key: _KEEP_OPEN,
- value: false,
- validator: Lang.isBoolean
- };
- YAHOO.lang.extend(Menu, Overlay, {
- // Constants
- /**
- * @property CSS_CLASS_NAME
- * @description String representing the CSS class(es) to be applied to the
- * menu's <code><div></code> element.
- * @default "yuimenu"
- * @final
- * @type String
- */
- CSS_CLASS_NAME: "yuimenu",
- /**
- * @property ITEM_TYPE
- * @description Object representing the type of menu item to instantiate and
- * add when parsing the child nodes (either <code><li></code> element,
- * <code><optgroup></code> element or <code><option></code>)
- * of the menu's source HTML element.
- * @default YAHOO.widget.MenuItem
- * @final
- * @type YAHOO.widget.MenuItem
- */
- ITEM_TYPE: null,
- /**
- * @property GROUP_TITLE_TAG_NAME
- * @description String representing the tagname of the HTML element used to
- * title the menu's item groups.
- * @default H6
- * @final
- * @type String
- */
- GROUP_TITLE_TAG_NAME: "h6",
- /**
- * @property OFF_SCREEN_POSITION
- * @description Array representing the default x and y position that a menu
- * should have when it is positioned outside the viewport by the
- * "poistionOffScreen" method.
- * @default "-999em"
- * @final
- * @type String
- */
- OFF_SCREEN_POSITION: "-999em",
- // Private properties
- /**
- * @property _useHideDelay
- * @description Boolean indicating if the "mouseover" and "mouseout" event
- * handlers used for hiding the menu via a call to "YAHOO.lang.later" have
- * already been assigned.
- * @default false
- * @private
- * @type Boolean
- */
- _useHideDelay: false,
- /**
- * @property _bHandledMouseOverEvent
- * @description Boolean indicating the current state of the menu's
- * "mouseover" event.
- * @default false
- * @private
- * @type Boolean
- */
- _bHandledMouseOverEvent: false,
- /**
- * @property _bHandledMouseOutEvent
- * @description Boolean indicating the current state of the menu's
- * "mouseout" event.
- * @default false
- * @private
- * @type Boolean
- */
- _bHandledMouseOutEvent: false,
- /**
- * @property _aGroupTitleElements
- * @description Array of HTML element used to title groups of menu items.
- * @default []
- * @private
- * @type Array
- */
- _aGroupTitleElements: null,
- /**
- * @property _aItemGroups
- * @description Multi-dimensional Array representing the menu items as they
- * are grouped in the menu.
- * @default []
- * @private
- * @type Array
- */
- _aItemGroups: null,
- /**
- * @property _aListElements
- * @description Array of <code><ul></code> elements, each of which is
- * the parent node for each item's <code><li></code> element.
- * @default []
- * @private
- * @type Array
- */
- _aListElements: null,
- /**
- * @property _nCurrentMouseX
- * @description The current x coordinate of the mouse inside the area of
- * the menu.
- * @default 0
- * @private
- * @type Number
- */
- _nCurrentMouseX: 0,
- /**
- * @property _bStopMouseEventHandlers
- * @description Stops "mouseover," "mouseout," and "mousemove" event handlers
- * from executing.
- * @default false
- * @private
- * @type Boolean
- */
- _bStopMouseEventHandlers: false,
- /**
- * @property _sClassName
- * @description The current value of the "classname" configuration attribute.
- * @default null
- * @private
- * @type String
- */
- _sClassName: null,
- // Public properties
- /**
- * @property lazyLoad
- * @description Boolean indicating if the menu's "lazy load" feature is
- * enabled. If set to "true," initialization and rendering of the menu's
- * items will be deferred until the first time it is made visible. This
- * property should be set via the constructor using the configuration
- * object literal.
- * @default false
- * @type Boolean
- */
- lazyLoad: false,
- /**
- * @property itemData
- * @description Array of items to be added to the menu. The array can contain
- * strings representing the text for each item to be created, object literals
- * representing the menu item configuration properties, or MenuItem instances.
- * This property should be set via the constructor using the configuration
- * object literal.
- * @default null
- * @type Array
- */
- itemData: null,
- /**
- * @property activeItem
- * @description Object reference to the item in the menu that has is selected.
- * @default null
- * @type YAHOO.widget.MenuItem
- */
- activeItem: null,
- /**
- * @property parent
- * @description Object reference to the menu's parent menu or menu item.
- * This property can be set via the constructor using the configuration
- * object literal.
- * @default null
- * @type YAHOO.widget.MenuItem
- */
- parent: null,
- /**
- * @property srcElement
- * @description Object reference to the HTML element (either
- * <code><select></code> or <code><div></code>) used to
- * create the menu.
- * @default null
- * @type <a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/
- * level-one-html.html#ID-94282980">HTMLSelectElement</a>|<a
- * href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-one-html.
- * html#ID-22445964">HTMLDivElement</a>
- */
- srcElement: null,
- // Events
- /**
- * @event mouseOverEvent
- * @description Fires when the mouse has entered the menu. Passes back
- * the DOM Event object as an argument.
- */
- /**
- * @event mouseOutEvent
- * @description Fires when the mouse has left the menu. Passes back the DOM
- * Event object as an argument.
- * @type YAHOO.util.CustomEvent
- */
- /**
- * @event mouseDownEvent
- * @description Fires when the user mouses down on the menu. Passes back the
- * DOM Event object as an argument.
- * @type YAHOO.util.CustomEvent
- */
- /**
- * @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
- */
- /**
- * @event clickEvent
- * @description Fires when the user clicks the on the menu. Passes back the
- * DOM Event object as an argument.
- * @type YAHOO.util.CustomEvent
- */
- /**
- * @event keyPressEvent
- * @description Fires when the user presses an alphanumeric key when one of the
- * menu's items has focus. Passes back the DOM Event object as an argument.
- * @type YAHOO.util.CustomEvent
- */
- /**
- * @event keyDownEvent
- * @description Fires when the user presses a key when one of the menu's items
- * has focus. Passes back the DOM Event object as an argument.
- * @type YAHOO.util.CustomEvent
- */
- /**
- * @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.
- * @type YAHOO.util.CustomEvent
- */
- /**
- * @event itemAddedEvent
- * @description Fires when an item is added to the menu.
- * @type YAHOO.util.CustomEvent
- */
- /**
- * @event itemRemovedEvent
- * @description Fires when an item is removed to the menu.
- * @type YAHOO.util.CustomEvent
- */
- /**
- * @method init
- * @description 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} p_oElement String specifying the id attribute of the
- * <code><div></code> element of the menu.
- * @param {String} p_oElement String specifying the id attribute of the
- * <code><select></code> element to be used as the data source
- * for the menu.
- * @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/
- * level-one-html.html#ID-22445964">HTMLDivElement</a>} p_oElement Object
- * specifying the <code><div></code> element of the menu.
- * @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/
- * level-one-html.html#ID-94282980">HTMLSelectElement</a>} p_oElement
- * Object specifying the <code><select></code> 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
- * more details.
- */
- init: function (p_oElement, p_oConfig) {
- this._aItemGroups = [];
- this._aListElements = [];
- this._aGroupTitleElements = [];
- if (!this.ITEM_TYPE) {
- this.ITEM_TYPE = YAHOO.widget.MenuItem;
- }
- var oElement;
- if (Lang.isString(p_oElement)) {
- oElement = Dom.get(p_oElement);
- }
- else if (p_oElement.tagName) {
- oElement = p_oElement;
- }
- if (oElement && oElement.tagName) {
- switch(oElement.tagName.toUpperCase()) {
-
- case _DIV_UPPERCASE:
- this.srcElement = oElement;
- if (!oElement.id) {
- oElement.setAttribute(_ID, Dom.generateId());
- }
- /*
- Note: we don't pass the user config in here yet
- because we only want it executed once, at the lowest
- subclass level.
- */
-
- Menu.superclass.init.call(this, oElement);
- this.beforeInitEvent.fire(Menu);
-
- break;
-
- case _SELECT:
-
- this.srcElement = oElement;
-
- /*
- The source element is not something that we can use
- outright, so we need to create a new Overlay
- Note: we don't pass the user config in here yet
- because we only want it executed once, at the lowest
- subclass level.
- */
- Menu.superclass.init.call(this, Dom.generateId());
- this.beforeInitEvent.fire(Menu);
- break;
- }
- }
- else {
- /*
- Note: we don't pass the user config in here yet
- because we only want it executed once, at the lowest
- subclass level.
- */
-
- Menu.superclass.init.call(this, p_oElement);
- this.beforeInitEvent.fire(Menu);
- }
- if (this.element) {
- Dom.addClass(this.element, this.CSS_CLASS_NAME);
- // Subscribe to Custom Events
- this.initEvent.subscribe(this._onInit);
- this.beforeRenderEvent.subscribe(this._onBeforeRender);
- this.renderEvent.subscribe(this._onRender);
- this.beforeShowEvent.subscribe(this._onBeforeShow);
- this.hideEvent.subscribe(this._onHide);
- this.showEvent.subscribe(this._onShow);
- this.beforeHideEvent.subscribe(this._onBeforeHide);
- this.mouseOverEvent.subscribe(this._onMouseOver);
- this.mouseOutEvent.subscribe(this._onMouseOut);
- this.clickEvent.subscribe(this._onClick);
- this.keyDownEvent.subscribe(this._onKeyDown);
- this.keyPressEvent.subscribe(this._onKeyPress);
- this.blurEvent.subscribe(this._onBlur);
- // Fixes an issue in Firefox 2 and Webkit where Dom's "getX" and "getY"
- // methods return values that don't take scrollTop into consideration
- if ((UA.gecko && UA.gecko < 1.9) || UA.webkit) {
- this.cfg.subscribeToConfigEvent(_Y, this._onYChange);
- }
- if (p_oConfig) {
-
- this.cfg.applyConfig(p_oConfig, true);
-
- }
- // Register the Menu instance with the MenuManager
- MenuManager.addMenu(this);
-
- this.initEvent.fire(Menu);
- }
- },
- // Private methods
- /**
- * @method _initSubTree
- * @description Iterates the childNodes of the source element to find nodes
- * used to instantiate menu and menu items.
- * @private
- */
- _initSubTree: function () {
- var oSrcElement = this.srcElement,
- sSrcElementTagName,
- nGroup,
- sGroupTitleTagName,
- oNode,
- aListElements,
- nListElements,
- i;
- if (oSrcElement) {
-
- sSrcElementTagName =
- (oSrcElement.tagName && oSrcElement.tagName.toUpperCase());
- if (sSrcElementTagName == _DIV_UPPERCASE) {
-
- // Populate the collection of item groups and item group titles
-
- oNode = this.body.firstChild;
-
- if (oNode) {
-
- nGroup = 0;
- sGroupTitleTagName = this.GROUP_TITLE_TAG_NAME.toUpperCase();
-
- do {
-
- if (oNode && oNode.tagName) {
-
- switch (oNode.tagName.toUpperCase()) {
-
- case sGroupTitleTagName:
-
- this._aGroupTitleElements[nGroup] = oNode;
-
- break;
-
- case _UL_UPPERCASE:
-
- this._aListElements[nGroup] = oNode;
- this._aItemGroups[nGroup] = [];
- nGroup++;
-
- break;
-
- }
-
- }
-
- }
- while ((oNode = oNode.nextSibling));
-
-
- /*
- Apply the "first-of-type" class to the first UL to mimic
- the ":first-of-type" CSS3 psuedo class.
- */
-
- if (this._aListElements[0]) {
-
- Dom.addClass(this._aListElements[0], _FIRST_OF_TYPE);
-
- }
-
- }
-
- }
-
-
- oNode = null;
-
-
- if (sSrcElementTagName) {
-
- switch (sSrcElementTagName) {
-
- case _DIV_UPPERCASE:
- aListElements = this._aListElements;
- nListElements = aListElements.length;
-
- if (nListElements > 0) {
-
-
- i = nListElements - 1;
-
- do {
-
- oNode = aListElements[i].firstChild;
-
- if (oNode) {
-
- do {
-
- if (oNode && oNode.tagName &&
- oNode.tagName.toUpperCase() == _LI) {
-
-
- this.addItem(new this.ITEM_TYPE(oNode,
- { parent: this }), i);
-
- }
-
- }
- while ((oNode = oNode.nextSibling));
-
- }
-
- }
- while (i--);
-
- }
-
- break;
-
- case _SELECT:
-
-
- oNode = oSrcElement.firstChild;
-
- do {
-
- if (oNode && oNode.tagName) {
-
- switch (oNode.tagName.toUpperCase()) {
-
- case _OPTGROUP:
- case _OPTION:
-
-
- this.addItem(
- new this.ITEM_TYPE(
- oNode,
- { parent: this }
- )
- );
-
- break;
-
- }
-
- }
-
- }
- while ((oNode = oNode.nextSibling));
-
- break;
-
- }
-
- }
-
- }
- },
- /**
- * @method _getFirstEnabledItem
- * @description Returns the first enabled item in the menu.
- * @return {YAHOO.widget.MenuItem}
- * @private
- */
- _getFirstEnabledItem: function () {
- var aItems = this.getItems(),
- nItems = aItems.length,
- oItem,
- returnVal;
-
- for(var i=0; i<nItems; i++) {
- oItem = aItems[i];
- if (oItem && !oItem.cfg.getProperty(_DISABLED) && oItem.element.style.display != _NONE) {
- returnVal = oItem;
- break;
- }
-
- }
-
- return returnVal;
-
- },
- /**
- * @method _addItemToGroup
- * @description Adds a menu item to a group.
- * @private
- * @param {Number} p_nGroupIndex Number indicating the group to which the
- * item belongs.
- * @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_nItemIndex Optional. Number indicating the index at
- * which the menu item should be added.
- * @return {YAHOO.widget.MenuItem}
- */
- _addItemToGroup: function (p_nGroupIndex, p_oItem, p_nItemIndex) {
- var oItem,
- nGroupIndex,
- aGroup,
- oGroupItem,
- bAppend,
- oNextItemSibling,
- nItemIndex,
- returnVal;
- function getNextItemSibling(p_aArray, p_nStartIndex) {
- return (p_aArray[p_nStartIndex] || getNextItemSibling(p_aArray, (p_nStartIndex+1)));
- }
- if (p_oItem instanceof this.ITEM_TYPE) {
- oItem = p_oItem;
- oItem.parent = this;
- }
- else if (Lang.isString(p_oItem)) {
- oItem = new this.ITEM_TYPE(p_oItem, { parent: this });
-
- }
- else if (Lang.isObject(p_oItem)) {
- p_oItem.parent = this;
- oItem = new this.ITEM_TYPE(p_oItem.text, p_oItem);
- }
- if (oItem) {
- if (oItem.cfg.getProperty(_SELECTED)) {
- this.activeItem = oItem;
-
- }
- nGroupIndex = Lang.isNumber(p_nGroupIndex) ? p_nGroupIndex : 0;
- aGroup = this._getItemGroup(nGroupIndex);
- if (!aGroup) {
- aGroup = this._createItemGroup(nGroupIndex);
- }
- if (Lang.isNumber(p_nItemIndex)) {
- bAppend = (p_nItemIndex >= 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 {
-
- 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.itemAddedEvent.fire(oGroupItem);
- this.changeContentEvent.fire();
- returnVal = oGroupItem;
-
- }
- }
- else {
-
- 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(_GROUP_INDEX, 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.itemAddedEvent.fire(oGroupItem);
- this.changeContentEvent.fire();
- returnVal = oGroupItem;
-
- }
-
- }
- }
-
- return returnVal;
-
- },
- /**
- * @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 = Lang.isNumber(p_nGroupIndex) ? p_nGroupIndex : 0,
- aGroup = this._getItemGroup(nGroupIndex),
- aArray,
- oItem,
- oUL;
- if (aGroup) {
- 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
-
- 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);
- this.changeContentEvent.fire();
-
- }
- }
- // 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),
- nItems,
- nItemIndex,
- returnVal,
- i;
- if (aGroup) {
- nItems = aGroup.length;
- nItemIndex = -1;
-
- if (nItems > 0) {
-
- i = nItems-1;
-
- do {
-
- if (aGroup[i] == p_oItem) {
-
- nItemIndex = i;
- break;
-
- }
-
- }
- while (i--);
-
- if (nItemIndex > -1) {
-
- returnVal = this._removeItemFromGroupByIndex(p_nGroupIndex, nItemIndex);
-
- }
-
- }
-
- }
-
- return returnVal;
- },
- /**
- * @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,
- oItem,
- oLI,
- i;
- if (nItems > 0) {
- i = nItems - 1;
- // 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(_GROUP_INDEX, 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
- * <code><ul></code> 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) {
- var oUL,
- returnVal;
- if (!this._aItemGroups[p_nIndex]) {
- this._aItemGroups[p_nIndex] = [];
- oUL = document.createElement(_UL_LOWERCASE);
- this._aListElements[p_nIndex] = oUL;
- returnVal = this._aItemGroups[p_nIndex];
- }
-
- return returnVal;
- },
- /**
- * @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 = Lang.isNumber(p_nIndex) ? p_nIndex : 0,
- aGroups = this._aItemGroups,
- returnVal;
- if (nIndex in aGroups) {
- returnVal = aGroups[nIndex];
- }
-
- return returnVal;
- },
- /**
- * @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);
- }
- },
- /**
- * @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.destroyEvent.subscribe(this._onMenuItemDestroy, p_oItem, this);
- p_oItem.cfg.configChangedEvent.subscribe(this._onMenuItemConfigChange, p_oItem, this);
- },
- /**
- * @method _onVisibleChange
- * @description Change event handler for the the menu's "visible" configuration
- * property.
- * @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.
- */
- _onVisibleChange: function (p_sType, p_aArgs) {
- var bVisible = p_aArgs[0];
-
- if (bVisible) {
- Dom.addClass(this.element, _VISIBLE);
- }
- else {
- Dom.removeClass(this.element, _VISIBLE);
- }
- },
- /**
- * @method _cancelHideDelay
- * @description Cancels the call to "hideMenu."
- * @private
- */
- _cancelHideDelay: function () {
- var oTimer = this.getRoot()._hideDelayTimer;
- if (oTimer) {
- oTimer.cancel();
- }
- },
- /**
- * @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();
-
- oRoot._hideDelayTimer = Lang.later(oRoot.cfg.getProperty(_HIDE_DELAY), this, function () {
-
- if (oRoot.activeItem) {
- if (oRoot.hasFocus()) {
- oRoot.activeItem.focus();
-
- }
-
- oRoot.clearActiveItem();
- }
- if (oRoot == this && !(this instanceof YAHOO.widget.MenuBar) &&
- this.cfg.getProperty(_POSITION) == _DYNAMIC) {
- this.hide();
-
- }
-
- });
- },
- /**
- * @method _cancelShowDelay
- * @description Cancels the call to the "showMenu."
- * @private
- */
- _cancelShowDelay: function () {
- var oTimer = this.getRoot()._showDelayTimer;
- if (oTimer) {
- oTimer.cancel();
- }
- },
- /**
- * @method _execSubmenuHideDelay
- * @description Hides a submenu after the number of milliseconds specified by
- * the "submenuhidedelay" configuration property have ellapsed.
- * @private
- * @param {YAHOO.widget.Menu} p_oSubmenu Object specifying the submenu that
- * should be hidden.
- * @param {Number} p_nMouseX The x coordinate of the mouse when it left
- * the specified submenu's parent menu item.
- * @param {Number} p_nHideDelay The number of milliseconds that should ellapse
- * before the submenu is hidden.
- */
- _execSubmenuHideDelay: function (p_oSubmenu, p_nMouseX, p_nHideDelay) {
- p_oSubmenu._submenuHideDelayTimer = Lang.later(50, this, function () {
- if (this._nCurrentMouseX > (p_nMouseX + 10)) {
- p_oSubmenu._submenuHideDelayTimer = Lang.later(p_nHideDelay, p_oSubmenu, function () {
-
- this.hide();
- });
- }
- else {
- p_oSubmenu.hide();
-
- }
-
- });
- },
- // Protected methods
- /**
- * @method _disableScrollHeader
- * @description Disables the header used for scrolling the body of the menu.
- * @protected
- */
- _disableScrollHeader: function () {
- if (!this._bHeaderDisabled) {
- Dom.addClass(this.header, _TOP_SCROLLBAR_DISABLED);
- this._bHeaderDisabled = true;
- }
- },
- /**
- * @method _disableScrollFooter
- * @description Disables the footer used for scrolling the body of the menu.
- * @protected
- */
- _disableScrollFooter: function () {
- if (!this._bFooterDisabled) {
- Dom.addClass(this.footer, _BOTTOM_SCROLLBAR_DISABLED);
- this._bFooterDisabled = true;
- }
- },
- /**
- * @method _enableScrollHeader
- * @description Enables the header used for scrolling the body of the menu.
- * @protected
- */
- _enableScrollHeader: function () {
- if (this._bHeaderDisabled) {
- Dom.removeClass(this.header, _TOP_SCROLLBAR_DISABLED);
- this._bHeaderDisabled = false;
- }
- },
- /**
- * @method _enableScrollFooter
- * @description Enables the footer used for scrolling the body of the menu.
- * @protected
- */
- _enableScrollFooter: function () {
- if (this._bFooterDisabled) {
- Dom.removeClass(this.footer, _BOTTOM_SCROLLBAR_DISABLED);
- this._bFooterDisabled = false;
- }
- },
- /**
- * @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.
- */
- _onMouseOver: function (p_sType, p_aArgs) {
- var oEvent = p_aArgs[0],
- oItem = p_aArgs[1],
- oTarget = Event.getTarget(oEvent),
- oRoot = this.getRoot(),
- oSubmenuHideDelayTimer = this._submenuHideDelayTimer,
- oParentMenu,
- nShowDelay,
- bShowDelay,
- oActiveItem,
- oItemCfg,
- oSubmenu;
- var showSubmenu = function () {
- if (this.parent.cfg.getProperty(_SELECTED)) {
- this.show();
- }
- };
- if (!this._bStopMouseEventHandlers) {
-
- if (!this._bHandledMouseOverEvent && (oTarget == this.element ||
- Dom.isAncestor(this.element, oTarget))) {
-
- // Menu mouseover logic
- if (this._useHideDelay) {
- this._cancelHideDelay();
- }
-
- this._nCurrentMouseX = 0;
-
- Event.on(this.element, _MOUSEMOVE, this._onMouseMove, this, true);
- /*
- If the mouse is moving from the submenu back to its corresponding menu item,
- don't hide the submenu or clear the active MenuItem.
- */
- if (!(oItem && Dom.isAncestor(oItem.element, Event.getRelatedTarget(oEvent)))) {
- this.clearActiveItem();
- }
-
- if (this.parent && oSubmenuHideDelayTimer) {
-
- oSubmenuHideDelayTimer.cancel();
-
- this.parent.cfg.setProperty(_SELECTED, true);
-
- oParentMenu = this.parent.parent;
-
- oParentMenu._bHandledMouseOutEvent = true;
- oParentMenu._bHandledMouseOverEvent = false;
-
- }
-
-
- this._bHandledMouseOverEvent = true;
- this._bHandledMouseOutEvent = false;
-
- }
-
-
- if (oItem && !oItem.handledMouseOverEvent && !oItem.cfg.getProperty(_DISABLED) &&
- (oTarget == oItem.element || Dom.isAncestor(oItem.element, oTarget))) {
-
- // Menu Item mouseover logic
-
- nShowDelay = this.cfg.getProperty(_SHOW_DELAY);
- bShowDelay = (nShowDelay > 0);
-
-
- if (bShowDelay) {
-
- this._cancelShowDelay();
-
- }
-
-
- oActiveItem = this.activeItem;
-
- if (oActiveItem) {
-
- oActiveItem.cfg.setProperty(_SELECTED, false);
-
-