mirror of
http://git.whoc.org.uk/git/password-manager.git
synced 2024-11-10 22:37:16 +01:00
6781 lines
177 KiB
JavaScript
6781 lines
177 KiB
JavaScript
/*
|
|
Copyright (c) 2006, Yahoo! Inc. All rights reserved.
|
|
Code licensed under the BSD License:
|
|
http://developer.yahoo.com/yui/license.txt
|
|
version: 0.12.0
|
|
*/
|
|
|
|
/**
|
|
* @module menu
|
|
* @description <p>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.</p>
|
|
* <ul>
|
|
* <li>Screen-reader accessibility.</li>
|
|
* <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 Library
|
|
* @namespace YAHOO.widget
|
|
* @requires Event, Dom, Container
|
|
*/
|
|
(function() {
|
|
|
|
var Dom = YAHOO.util.Dom;
|
|
var 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 = new function() {
|
|
|
|
// Private member variables
|
|
|
|
// Flag indicating if the DOM event handlers have been attached
|
|
|
|
var m_bInitializedEventHandlers = false;
|
|
|
|
// Collection of menus
|
|
|
|
var m_oMenus = {};
|
|
|
|
|
|
// Collection of menu items
|
|
|
|
var m_oItems = {};
|
|
|
|
// Collection of visible menus
|
|
|
|
var m_oVisibleMenus = {};
|
|
|
|
// Logger
|
|
|
|
|
|
// Private methods
|
|
|
|
/**
|
|
* Adds an item to the collection of known menu items.
|
|
* @private
|
|
* @param {YAHOO.widget.MenuItem} p_oItem Object specifying the MenuItem
|
|
* instance to be added.
|
|
*/
|
|
var addItem = function(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);
|
|
|
|
|
|
}
|
|
|
|
};
|
|
|
|
/**
|
|
* 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.
|
|
*/
|
|
var removeItem = function(p_oItem) {
|
|
|
|
var sYUIId = p_oItem.element.getAttribute("yuiid");
|
|
|
|
if(sYUIId && m_oItems[sYUIId]) {
|
|
|
|
delete m_oItems[sYUIId];
|
|
|
|
|
|
}
|
|
|
|
};
|
|
|
|
/**
|
|
* 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.
|
|
*/
|
|
var getMenuRootElement = function(p_oElement) {
|
|
|
|
var oParentNode;
|
|
|
|
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, "bd") &&
|
|
oParentNode &&
|
|
oParentNode.tagName &&
|
|
oParentNode.tagName.toUpperCase() == "DIV"
|
|
) {
|
|
|
|
return oParentNode;
|
|
|
|
}
|
|
else {
|
|
|
|
return p_oElement;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case "LI":
|
|
|
|
return p_oElement;
|
|
|
|
default:
|
|
|
|
oParentNode = p_oElement.parentNode;
|
|
|
|
if(oParentNode) {
|
|
|
|
return getMenuRootElement(oParentNode);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
// Private event handlers
|
|
|
|
/**
|
|
* 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).
|
|
*/
|
|
var onDOMEvent = function(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
|
|
|
|
var oElement = getMenuRootElement(oTarget);
|
|
|
|
var oMenuItem;
|
|
var 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) {
|
|
|
|
// Map of DOM event names to CustomEvent names
|
|
|
|
var oEventTypes = {
|
|
"click": "clickEvent",
|
|
"mousedown": "mouseDownEvent",
|
|
"mouseup": "mouseUpEvent",
|
|
"mouseover": "mouseOverEvent",
|
|
"mouseout": "mouseOutEvent",
|
|
"keydown": "keyDownEvent",
|
|
"keyup": "keyUpEvent",
|
|
"keypress": "keyPressEvent"
|
|
};
|
|
|
|
var sCustomEventType = oEventTypes[p_oEvent.type];
|
|
|
|
// Fire the Custom Even 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
|
|
*/
|
|
|
|
var oActiveItem;
|
|
|
|
for(var i in m_oMenus) {
|
|
|
|
if(m_oMenus.hasOwnProperty(i)) {
|
|
|
|
oMenu = m_oMenus[i];
|
|
|
|
if(
|
|
oMenu.cfg.getProperty("clicktohide") &&
|
|
oMenu.cfg.getProperty("position") == "dynamic"
|
|
) {
|
|
|
|
oMenu.hide();
|
|
|
|
}
|
|
else {
|
|
|
|
oMenu.clearActiveItem(true);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
/**
|
|
* "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.
|
|
*/
|
|
var onMenuDestroy = function(p_sType, p_aArgs, p_oMenu) {
|
|
|
|
this.removeMenu(p_oMenu);
|
|
|
|
};
|
|
|
|
/**
|
|
* "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.
|
|
*/
|
|
var onItemDestroy = function(p_sType, p_aArgs, p_oItem) {
|
|
|
|
var sYUIId = p_oItem.element.getAttribute("yuiid");
|
|
|
|
if(sYUIId) {
|
|
|
|
delete m_oItems[sYUIId];
|
|
|
|
}
|
|
|
|
};
|
|
|
|
/**
|
|
* 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.
|
|
*/
|
|
var onMenuVisibleConfigChange = function(p_sType, p_aArgs, p_oMenu) {
|
|
|
|
var bVisible = p_aArgs[0];
|
|
|
|
if(bVisible) {
|
|
|
|
m_oVisibleMenus[p_oMenu.id] = p_oMenu;
|
|
|
|
|
|
}
|
|
else if(m_oVisibleMenus[p_oMenu.id]) {
|
|
|
|
delete m_oVisibleMenus[p_oMenu.id];
|
|
|
|
|
|
}
|
|
|
|
};
|
|
|
|
/**
|
|
* "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.
|
|
*/
|
|
var onItemAdded = function(p_sType, p_aArgs) {
|
|
|
|
addItem(p_aArgs[0]);
|
|
|
|
};
|
|
|
|
|
|
/**
|
|
* "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.
|
|
*/
|
|
var onItemRemoved = function(p_sType, p_aArgs) {
|
|
|
|
removeItem(p_aArgs[0]);
|
|
|
|
};
|
|
|
|
// 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.
|
|
*/
|
|
this.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, this, true);
|
|
Event.addListener(oDoc, "mouseout", onDOMEvent, this, true);
|
|
Event.addListener(oDoc, "mousedown", onDOMEvent, this, true);
|
|
Event.addListener(oDoc, "mouseup", onDOMEvent, this, true);
|
|
Event.addListener(oDoc, "click", onDOMEvent, this, true);
|
|
Event.addListener(oDoc, "keydown", onDOMEvent, this, true);
|
|
Event.addListener(oDoc, "keyup", onDOMEvent, this, true);
|
|
Event.addListener(oDoc, "keypress", onDOMEvent, this, true);
|
|
|
|
m_bInitializedEventHandlers = true;
|
|
|
|
|
|
}
|
|
|
|
p_oMenu.destroyEvent.subscribe(onMenuDestroy, p_oMenu, this);
|
|
|
|
p_oMenu.cfg.subscribeToConfigEvent(
|
|
"visible",
|
|
onMenuVisibleConfigChange,
|
|
p_oMenu
|
|
);
|
|
|
|
p_oMenu.itemAddedEvent.subscribe(onItemAdded);
|
|
p_oMenu.itemRemovedEvent.subscribe(onItemRemoved);
|
|
|
|
|
|
}
|
|
|
|
};
|
|
|
|
/**
|
|
* @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.
|
|
*/
|
|
this.removeMenu = function(p_oMenu) {
|
|
|
|
if(p_oMenu && m_oMenus[p_oMenu.id]) {
|
|
|
|
delete m_oMenus[p_oMenu.id];
|
|
|
|
|
|
}
|
|
|
|
};
|
|
|
|
/**
|
|
* @method hideVisible
|
|
* @description Hides all visible, dynamically positioned menus.
|
|
*/
|
|
this.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();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
/**
|
|
* @method getMenus
|
|
* @description Returns an array of all menus registered with the
|
|
* menu manger.
|
|
* @return {Array}
|
|
*/
|
|
this.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}
|
|
*/
|
|
this.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}
|
|
*/
|
|
this.toString = function() {
|
|
|
|
return ("MenuManager");
|
|
|
|
};
|
|
|
|
};
|
|
|
|
})();
|
|
|
|
(function() {
|
|
|
|
var Dom = YAHOO.util.Dom;
|
|
var Event = YAHOO.util.Event;
|
|
|
|
/**
|
|
* 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
|
|
);
|
|
|
|
};
|
|
|
|
YAHOO.extend(YAHOO.widget.Menu, YAHOO.widget.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",
|
|
|
|
// Private properties
|
|
|
|
/**
|
|
* @property _nHideDelayId
|
|
* @description Number representing the time-out setting used to cancel the
|
|
* hiding of a menu.
|
|
* @default null
|
|
* @private
|
|
* @type Number
|
|
*/
|
|
_nHideDelayId: null,
|
|
|
|
/**
|
|
* @property _nShowDelayId
|
|
* @description Number representing the time-out setting used to cancel the
|
|
* showing of a menu.
|
|
* @default null
|
|
* @private
|
|
* @type Number
|
|
*/
|
|
_nShowDelayId: null,
|
|
|
|
/**
|
|
* @property _hideDelayEventHandlersAssigned
|
|
* @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.
|
|
* @default false
|
|
* @private
|
|
* @type Boolean
|
|
*/
|
|
_hideDelayEventHandlersAssigned: 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 Array of menu items.
|
|
* @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,
|
|
|
|
// 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 focus.
|
|
* @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.
|
|
*/
|
|
mouseOverEvent: null,
|
|
|
|
/**
|
|
* @event mouseOutEvent
|
|
* @description Fires when the mouse has left the menu. Passes back the DOM
|
|
* Event object as an argument.
|
|
* @type YAHOO.util.CustomEvent
|
|
*/
|
|
mouseOutEvent: null,
|
|
|
|
/**
|
|
* @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
|
|
*/
|
|
mouseDownEvent: null,
|
|
|
|
/**
|
|
* @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,
|
|
|
|
/**
|
|
* @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
|
|
*/
|
|
clickEvent: null,
|
|
|
|
/**
|
|
* @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
|
|
*/
|
|
keyPressEvent: null,
|
|
|
|
/**
|
|
* @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
|
|
*/
|
|
keyDownEvent: null,
|
|
|
|
/**
|
|
* @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
|
|
*/
|
|
keyUpEvent: null,
|
|
|
|
/**
|
|
* @event itemAddedEvent
|
|
* @description Fires when an item is added to the menu.
|
|
* @type YAHOO.util.CustomEvent
|
|
*/
|
|
itemAddedEvent: null,
|
|
|
|
/**
|
|
* @event itemRemovedEvent
|
|
* @description Fires when an item is removed to the menu.
|
|
* @type YAHOO.util.CustomEvent
|
|
*/
|
|
itemRemovedEvent: null,
|
|
|
|
/**
|
|
* @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(typeof p_oElement == "string") {
|
|
|
|
oElement = document.getElementById(p_oElement);
|
|
|
|
}
|
|
else if(p_oElement.tagName) {
|
|
|
|
oElement = p_oElement;
|
|
|
|
}
|
|
|
|
if(oElement && oElement.tagName) {
|
|
|
|
switch(oElement.tagName.toUpperCase()) {
|
|
|
|
case "DIV":
|
|
|
|
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.
|
|
*/
|
|
|
|
YAHOO.widget.Menu.superclass.init.call(this, oElement);
|
|
|
|
this.beforeInitEvent.fire(YAHOO.widget.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.
|
|
*/
|
|
|
|
YAHOO.widget.Menu.superclass.init.call(this, Dom.generateId());
|
|
|
|
this.beforeInitEvent.fire(YAHOO.widget.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.
|
|
*/
|
|
|
|
YAHOO.widget.Menu.superclass.init.call(this, p_oElement);
|
|
|
|
this.beforeInitEvent.fire(YAHOO.widget.Menu);
|
|
|
|
}
|
|
|
|
if(this.element) {
|
|
|
|
var oEl = this.element;
|
|
|
|
Dom.addClass(oEl, this.CSS_CLASS_NAME);
|
|
|
|
// 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.beforeShowEvent.subscribe(this._onBeforeShow, this, true);
|
|
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);
|
|
this.clickEvent.subscribe(this._onClick, this, true);
|
|
this.keyDownEvent.subscribe(this._onKeyDown, this, true);
|
|
|
|
if(p_oConfig) {
|
|
|
|
this.cfg.applyConfig(p_oConfig, true);
|
|
|
|
}
|
|
|
|
// Register the Menu instance with the MenuManager
|
|
|
|
YAHOO.widget.MenuManager.addMenu(this);
|
|
|
|
|
|
this.initEvent.fire(YAHOO.widget.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 oNode;
|
|
|
|
if(this.srcElement.tagName == "DIV") {
|
|
|
|
/*
|
|
Populate the collection of item groups and item
|
|
group titles
|
|
*/
|
|
|
|
oNode = this.body.firstChild;
|
|
|
|
var nGroup = 0;
|
|
var 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":
|
|
|
|
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(this.srcElement.tagName) {
|
|
|
|
switch(this.srcElement.tagName.toUpperCase()) {
|
|
|
|
case "DIV":
|
|
|
|
if(this._aListElements.length > 0) {
|
|
|
|
|
|
var i = this._aListElements.length - 1;
|
|
|
|
do {
|
|
|
|
oNode = this._aListElements[i].firstChild;
|
|
|
|
|
|
do {
|
|
|
|
if(oNode && oNode.tagName) {
|
|
|
|
switch(oNode.tagName.toUpperCase()) {
|
|
|
|
case "LI":
|
|
|
|
|
|
this.addItem(
|
|
new this.ITEM_TYPE(
|
|
oNode,
|
|
{ parent: this }
|
|
),
|
|
i
|
|
);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
while((oNode = oNode.nextSibling));
|
|
|
|
}
|
|
while(i--);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case "SELECT":
|
|
|
|
|
|
oNode = this.srcElement.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 nGroups = this._aItemGroups.length;
|
|
var oItem;
|
|
var aItemGroup;
|
|
|
|
for(var i=0; i<nGroups; i++) {
|
|
|
|
aItemGroup = this._aItemGroups[i];
|
|
|
|
if(aItemGroup) {
|
|
|
|
var nItems = aItemGroup.length;
|
|
|
|
for(var n=0; n<nItems; n++) {
|
|
|
|
oItem = aItemGroup[n];
|
|
|
|
if(
|
|
!oItem.cfg.getProperty("disabled") &&
|
|
oItem.element.style.display != "none"
|
|
) {
|
|
|
|
return oItem;
|
|
|
|
}
|
|
|
|
oItem = null;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
/**
|
|
* @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}
|
|
*/
|
|
_checkPosition: function(p_sPosition) {
|
|
|
|
if(typeof p_sPosition == "string") {
|
|
|
|
var sPosition = p_sPosition.toLowerCase();
|
|
|
|
return ("dynamic,static".indexOf(sPosition) != -1);
|
|
|
|
}
|
|
|
|
},
|
|
|
|
/**
|
|
* @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;
|
|
|
|
if(p_oItem instanceof this.ITEM_TYPE) {
|
|
|
|
oItem = p_oItem;
|
|
oItem.parent = this;
|
|
|
|
}
|
|
else if(typeof p_oItem == "string") {
|
|
|
|
oItem = new this.ITEM_TYPE(p_oItem, { parent: this });
|
|
|
|
}
|
|
else if(typeof p_oItem == "object" && p_oItem.text) {
|
|
|
|
var sText = p_oItem.text;
|
|
|
|
delete p_oItem["text"];
|
|
|
|
p_oItem.parent = this;
|
|
|
|
oItem = new this.ITEM_TYPE(sText, p_oItem);
|
|
|
|
}
|
|
|
|
if(oItem) {
|
|
|
|
var nGroupIndex = typeof p_nGroupIndex == "number" ? p_nGroupIndex : 0;
|
|
|
|
var aGroup = this._getItemGroup(nGroupIndex);
|
|
|
|
var oGroupItem;
|
|
|
|
if(!aGroup) {
|
|
|
|
aGroup = this._createItemGroup(nGroupIndex);
|
|
|
|
}
|
|
|
|
if(typeof p_nItemIndex == "number") {
|
|
|
|
var 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 {
|
|
|
|
|
|
/**
|
|
* 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}
|
|
*/
|
|
var getNextItemSibling =
|
|
|
|
function(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.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.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;
|
|
var aGroup = this._getItemGroup(nGroupIndex);
|
|
|
|
if(aGroup) {
|
|
|
|
var aArray = aGroup.splice(p_nItemIndex, 1);
|
|
var 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;
|
|
var 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);
|
|
var nItems = aGroup.length;
|
|
|
|
if(nItems > 0) {
|
|
|
|
var i = nItems - 1;
|
|
var oItem;
|
|
var 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
|
|
* <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) {
|
|
|
|
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
|
|
* <code><div></code> 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();
|
|
var me = this;
|
|
|
|
var hideMenu = function() {
|
|
|
|
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) {
|
|
|
|
this._cancelShowDelay();
|
|
|
|
var oRoot = this.getRoot();
|
|
|
|
var showMenu = function() {
|
|
|
|
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];
|
|
var oItem = p_aArgs[1];
|
|
var oTarget = Event.getTarget(oEvent);
|
|
|
|
if(
|
|
!this._bHandledMouseOverEvent &&
|
|
(oTarget == this.element || Dom.isAncestor(this.element, oTarget))
|
|
) {
|
|
|
|
// MENU MOUSEOVER LOGIC HERE
|
|
|
|
this.clearActiveItem();
|
|
|
|
this._bHandledMouseOverEvent = true;
|
|
this._bHandledMouseOutEvent = false;
|
|
|
|
}
|
|
|
|
if(
|
|
oItem && !oItem.handledMouseOverEvent &&
|
|
(oTarget == oItem.element || Dom.isAncestor(oItem.element, oTarget))
|
|
) {
|
|
|
|
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(this.cfg.getProperty("showdelay") > 0) {
|
|
|
|
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];
|
|
var oItem = p_aArgs[1];
|
|
var oRelatedTarget = Event.getRelatedTarget(oEvent);
|
|
var bMovingToSubmenu = false;
|
|
|
|
if(oItem) {
|
|
|
|
var oItemCfg = oItem.cfg;
|
|
var 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(this.cfg.getProperty("showdelay") > 0) {
|
|
|
|
this._cancelShowDelay();
|
|
|
|
}
|
|
|
|
if(!bMovingToSubmenu) {
|
|
|
|
oItemCfg.setProperty("selected", false);
|
|
|
|
}
|
|
|
|
if(this.cfg.getProperty("autosubmenudisplay")) {
|
|
|
|
if(oSubmenu) {
|
|
|
|
if(
|
|
!(
|
|
oRelatedTarget == oSubmenu.element ||
|
|
YAHOO.util.Dom.isAncestor(
|
|
oSubmenu.element,
|
|
oRelatedTarget
|
|
)
|
|
)
|
|
) {
|
|
|
|
oSubmenu.hide();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
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];
|
|
var oItem = p_aArgs[1];
|
|
var oTarget = Event.getTarget(oEvent);
|
|
|
|
if(oItem) {
|
|
|
|
var oItemCfg = oItem.cfg;
|
|
var 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");
|
|
var bCurrentPageURL = (sURL.substr((sURL.length-1),1) == "#");
|
|
var sTarget = oItemCfg.getProperty("target");
|
|
var 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];
|
|
var oItem = p_aArgs[1];
|
|
var oSubmenu;
|
|
|
|
if(oItem) {
|
|
|
|
var oItemCfg = oItem.cfg;
|
|
var oParentItem = this.parent;
|
|
var oRoot;
|
|
var 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);
|
|
|
|
}
|
|
|
|
},
|
|
|
|
// 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
|
|
* <code><ul></code>, <code><li></code> 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;
|
|
var oEl = this.element;
|
|
var nListElements = this._aListElements.length;
|
|
|
|
if(nListElements > 0) {
|
|
|
|
var i = 0;
|
|
var bFirstList = true;
|
|
var oUL;
|
|
var 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<nOptions; n++) {
|
|
|
|
if(this.itemData[n].tagName) {
|
|
|
|
this.addItem((new this.ITEM_TYPE(this.itemData[n])));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
else {
|
|
|
|
this.addItems(this.itemData);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if(this.srcElement) {
|
|
|
|
this.render();
|
|
|
|
}
|
|
else {
|
|
|
|
if(this.parent) {
|
|
|
|
this.render(this.parent.element);
|
|
|
|
}
|
|
else {
|
|
|
|
this.render(this.cfg.getProperty("container"));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
/**
|
|
* @method _onShow
|
|
* @description "show" 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.
|
|
*/
|
|
_onShow: function(p_sType, p_aArgs, p_oMenu) {
|
|
|
|
this.setInitialFocus();
|
|
|
|
var oParent = this.parent;
|
|
|
|
if(oParent) {
|
|
|
|
var oParentMenu = oParent.parent;
|
|
|
|
var aParentAlignment = oParentMenu.cfg.getProperty("submenualignment");
|
|
var aAlignment = this.cfg.getProperty("submenualignment");
|
|
|
|
if(
|
|
(aParentAlignment[0] != aAlignment[0]) &&
|
|
(aParentAlignment[1] != aAlignment[1])
|
|
) {
|
|
|
|
this.cfg.setProperty(
|
|
"submenualignment",
|
|
[ aParentAlignment[0], aParentAlignment[1] ]
|
|
);
|
|
|
|
}
|
|
|
|
if(
|
|
!oParentMenu.cfg.getProperty("autosubmenudisplay") &&
|
|
oParentMenu.cfg.getProperty("position") == "static"
|
|
) {
|
|
|
|
oParentMenu.cfg.setProperty("autosubmenudisplay", true);
|
|
|
|
/**
|
|
* "click" event handler for the document
|
|
* @private
|
|
* @param {Event} p_oEvent Object reference for the DOM event object
|
|
* passed back by the event utility (YAHOO.util.Event).
|
|
*/
|
|
var disableAutoSubmenuDisplay = function(p_oEvent) {
|
|
|
|
if(
|
|
p_oEvent.type == "mousedown" ||
|
|
(p_oEvent.type == "keydown" && p_oEvent.keyCode == 27)
|
|
) {
|
|
|
|
/*
|
|
Set the "autosubmenudisplay" to "false" if the user
|
|
clicks outside the menu bar.
|
|
*/
|
|
|
|
var oTarget = Event.getTarget(p_oEvent);
|
|
|
|
if(
|
|
oTarget != oParentMenu.element ||
|
|
!YAHOO.util.Dom.isAncestor(oParentMenu.element, oTarget)
|
|
) {
|
|
|
|
oParentMenu.cfg.setProperty(
|
|
"autosubmenudisplay",
|
|
false
|
|
);
|
|
|
|
Event.removeListener(
|
|
document,
|
|
"mousedown",
|
|
disableAutoSubmenuDisplay
|
|
);
|
|
|
|
Event.removeListener(
|
|
document,
|
|
"keydown",
|
|
disableAutoSubmenuDisplay
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
Event.addListener(document, "mousedown", disableAutoSubmenuDisplay);
|
|
Event.addListener(document, "keydown", disableAutoSubmenuDisplay);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
/**
|
|
* @method _onBeforeHide
|
|
* @description "beforehide" 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.
|
|
*/
|
|
_onBeforeHide: function(p_sType, p_aArgs, p_oMenu) {
|
|
|
|
this.clearActiveItem(true);
|
|
|
|
},
|
|
|
|
/**
|
|
* @method _onParentMenuConfigChange
|
|
* @description "configchange" event handler for a submenu.
|
|
* @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_oSubmenu Object representing the submenu that
|
|
* subscribed to the event.
|
|
*/
|
|
_onParentMenuConfigChange: function(p_sType, p_aArgs, p_oSubmenu) {
|
|
|
|
var sPropertyName = p_aArgs[0][0];
|
|
var oPropertyValue = p_aArgs[0][1];
|
|
|
|
switch(sPropertyName) {
|
|
|
|
case "iframe":
|
|
case "constraintoviewport":
|
|
case "hidedelay":
|
|
case "showdelay":
|
|
case "clicktohide":
|
|
case "effect":
|
|
|
|
p_oSubmenu.cfg.setProperty(sPropertyName, oPropertyValue);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
},
|
|
|
|
/**
|
|
* @method _onParentMenuRender
|
|
* @description "render" event handler for a submenu. Renders a
|
|
* submenu in response to the firing of its parent's "render" event.
|
|
* @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_oSubmenu Object representing the submenu that
|
|
* subscribed to the event.
|
|
*/
|
|
_onParentMenuRender: function(p_sType, p_aArgs, p_oSubmenu) {
|
|
|
|
/*
|
|
Set the "constraintoviewport" configuration
|
|
property to match the parent Menu
|
|
*/
|
|
|
|
var oParentMenu = p_oSubmenu.parent.parent;
|
|
|
|
var oConfig = {
|
|
|
|
constraintoviewport:
|
|
oParentMenu.cfg.getProperty("constraintoviewport"),
|
|
|
|
xy: [0,0],
|
|
|
|
clicktohide:
|
|
oParentMenu.cfg.getProperty("clicktohide"),
|
|
|
|
effect:
|
|
oParentMenu.cfg.getProperty("effect")
|
|
|
|
};
|
|
|
|
var nShowDelay = oParentMenu.cfg.getProperty("showdelay");
|
|
|
|
if(nShowDelay > 0) {
|
|
|
|
oConfig.showdelay = nShowDelay;
|
|
|
|
}
|
|
|
|
var nHideDelay = oParentMenu.cfg.getProperty("hidedelay");
|
|
|
|
if(nHideDelay > 0) {
|
|
|
|
oConfig.hidedelay = nHideDelay;
|
|
|
|
}
|
|
|
|
/*
|
|
Only sync the "iframe" configuration property if the parent
|
|
menu's "position" configuration is the same.
|
|
*/
|
|
|
|
if(
|
|
this.cfg.getProperty("position") ==
|
|
oParentMenu.cfg.getProperty("position")
|
|
) {
|
|
|
|
oConfig.iframe = oParentMenu.cfg.getProperty("iframe");
|
|
|
|
}
|
|
|
|
|
|
p_oSubmenu.cfg.applyConfig(oConfig);
|
|
|
|
if(!this.lazyLoad) {
|
|
|
|
if(Dom.inDocument(this.element)) {
|
|
|
|
this.render();
|
|
|
|
}
|
|
else {
|
|
|
|
this.render(this.parent.element);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
/**
|
|
* @method _onSubmenuBeforeShow
|
|
* @description "beforeshow" event handler for a submenu.
|
|
* @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_oSubmenu Object representing the submenu that
|
|
* subscribed to the event.
|
|
*/
|
|
_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;
|
|
|
|
},
|
|
|
|
/**
|
|
* @method _onSubmenuShow
|
|
* @description "show" event handler for a submenu.
|
|
* @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_oSubmenu Object representing the submenu that
|
|
* subscribed to the event.
|
|
*/
|
|
_onSubmenuShow: function(p_sType, p_aArgs, p_oSubmenu) {
|
|
|
|
var oParent = this.parent;
|
|
|
|
oParent.submenuIndicator.alt = oParent.EXPANDED_SUBMENU_INDICATOR_ALT_TEXT;
|
|
|
|
},
|
|
|
|
/**
|
|
* @method _onSubmenuHide
|
|
* @description "hide" Custom Event handler for a submenu.
|
|
* @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_oSubmenu Object representing the submenu that
|
|
* subscribed to the event.
|
|
*/
|
|
_onSubmenuHide: function(p_sType, p_aArgs, p_oSubmenu) {
|
|
|
|
var oParent = this.parent;
|
|
|
|
oParent.submenuIndicator.alt = oParent.COLLAPSED_SUBMENU_INDICATOR_ALT_TEXT;
|
|
|
|
},
|
|
|
|
/**
|
|
* @method _onMenuItemFocus
|
|
* @description "focus" event handler for the menu's items.
|
|
* @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.
|
|
*/
|
|
_onMenuItemFocus: function(p_sType, p_aArgs, p_oItem) {
|
|
|
|
this.activeItem = p_oItem;
|
|
|
|
},
|
|
|
|
/**
|
|
* @method _onMenuItemBlur
|
|
* @description "blur" event handler for the menu's items.
|
|
* @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.
|
|
*/
|
|
_onMenuItemBlur: function(p_sType, p_aArgs) {
|
|
|
|
this.activeItem = null;
|
|
|
|
},
|
|
|
|
/**
|
|
* @method _onMenuItemConfigChange
|
|
* @description "configchange" event handler for the menu's items.
|
|
* @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.
|
|
*/
|
|
_onMenuItemConfigChange: function(p_sType, p_aArgs, p_oItem) {
|
|
|
|
var sProperty = p_aArgs[0][0];
|
|
|
|
switch(sProperty) {
|
|
|
|
case "submenu":
|
|
|
|
var oSubmenu = p_aArgs[0][1];
|
|
|
|
if(oSubmenu) {
|
|
|
|
this._configureSubmenu(p_oItem);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case "text":
|
|
case "helptext":
|
|
|
|
/*
|
|
A change to an item's "text" or "helptext"
|
|
configuration properties requires the width of the parent
|
|
menu to be recalculated.
|
|
*/
|
|
|
|
if(this.element.style.width) {
|
|
|
|
var sWidth = this._getOffsetWidth() + "px";
|
|
|
|
Dom.setStyle(this.element, "width", sWidth);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
},
|
|
|
|
// Public event handlers for configuration properties
|
|
|
|
/**
|
|
* @method enforceConstraints
|
|
* @description The default event handler executed when the moveEvent is fired,
|
|
* if the "constraintoviewport" configuration property is set to true.
|
|
* @param {String} type The name of the event that was fired.
|
|
* @param {Array} args Collection of arguments sent when the
|
|
* event was fired.
|
|
* @param {Array} obj Array containing the current Menu instance
|
|
* and the item that fired the event.
|
|
*/
|
|
enforceConstraints: function(type, args, obj) {
|
|
|
|
var oConfig = this.cfg;
|
|
|
|
var pos = args[0];
|
|
|
|
var x = pos[0];
|
|
var y = pos[1];
|
|
|
|
var bod = document.getElementsByTagName('body')[0];
|
|
var htm = document.getElementsByTagName('html')[0];
|
|
|
|
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();
|
|
|
|
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;
|
|
|
|
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));
|
|
|
|
}
|
|
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);
|
|
|
|
},
|
|
|
|
/**
|
|
* @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];
|
|
var 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";
|
|
var 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];
|
|
var oMouseOutEvent = this.mouseOutEvent;
|
|
var oMouseOverEvent = this.mouseOverEvent;
|
|
var 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
|
|
|
|
/**
|
|
* Event handler called when the resize monitor element's "resize" evet is fired.
|
|
*/
|
|
onDomResize: function(e, obj) {
|
|
|
|
if(!this._handleResize) {
|
|
|
|
this._handleResize = true;
|
|
return;
|
|
|
|
}
|
|
|
|
var oConfig = this.cfg;
|
|
|
|
if(oConfig.getProperty("position") == "dynamic") {
|
|
|
|
oConfig.setProperty("width", (this._getOffsetWidth() + "px"));
|
|
|
|
}
|
|
|
|
YAHOO.widget.Menu.superclass.onDomResize.call(this, e, obj);
|
|
|
|
},
|
|
|
|
/**
|
|
* @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;
|
|
var 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;
|
|
var 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;
|
|
var aItems = [];
|
|
var oItem;
|
|
|
|
for(var i=0; i<nItems; i++) {
|
|
|
|
oItem = p_aItems[i];
|
|
|
|
if(isArray(oItem)) {
|
|
|
|
aItems[aItems.length] = this.addItems(oItem, i);
|
|
|
|
}
|
|
else {
|
|
|
|
aItems[aItems.length] =
|
|
this._addItemToGroup(p_nGroupIndex, oItem);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if(aItems.length) {
|
|
|
|
return aItems;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
/**
|
|
* @method insertItem
|
|
* @description Inserts an item into the menu at the specified index.
|
|
* @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 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 {YAHOO.widget.MenuItem}
|
|
*/
|
|
insertItem: function(p_oItem, p_nItemIndex, p_nGroupIndex) {
|
|
|
|
if(p_oItem) {
|
|
|
|
return this._addItemToGroup(p_nGroupIndex, p_oItem, p_nItemIndex);
|
|
|
|
}
|
|
|
|
},
|
|
|
|
/**
|
|
* @method removeItem
|
|
* @description Removes the specified item from the menu.
|
|
* @param {YAHOO.widget.MenuItem} p_oObject Object reference for the MenuItem
|
|
* instance to be removed from the menu.
|
|
* @param {Number} p_oObject Number specifying the index of the item
|
|
* to be removed.
|
|
* @param {Number} p_nGroupIndex Optional. Number specifying the group to
|
|
* which the item belongs.
|
|
* @return {YAHOO.widget.MenuItem}
|
|
*/
|
|
removeItem: function(p_oObject, p_nGroupIndex) {
|
|
|
|
if(typeof p_oObject != "undefined") {
|
|
|
|
var oItem;
|
|
|
|
if(p_oObject instanceof YAHOO.widget.MenuItem) {
|
|
|
|
oItem = this._removeItemFromGroupByValue(p_nGroupIndex, p_oObject);
|
|
|
|
}
|
|
else if(typeof p_oObject == "number") {
|
|
|
|
oItem = this._removeItemFromGroupByIndex(p_nGroupIndex, p_oObject);
|
|
|
|
}
|
|
|
|
if(oItem) {
|
|
|
|
oItem.destroy();
|
|
|
|
return oItem;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
/**
|
|
* @method getItemGroups
|
|
* @description Returns a multi-dimensional array of all of the items in the menu.
|
|
* @return {Array}
|
|
*/
|
|
getItemGroups: function() {
|
|
|
|
return this._aItemGroups;
|
|
|
|
},
|
|
|
|
/**
|
|
* @method getItem
|
|
* @description 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 {YAHOO.widget.MenuItem}
|
|
*/
|
|
getItem: function(p_nItemIndex, p_nGroupIndex) {
|
|
|
|
if(typeof p_nItemIndex == "number") {
|
|
|
|
var aGroup = this._getItemGroup(p_nGroupIndex);
|
|
|
|
if(aGroup) {
|
|
|
|
return aGroup[p_nItemIndex];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
/**
|
|
* @method destroy
|
|
* @description Removes the menu's <code><div></code> 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();
|
|
|
|
var nItemGroups = this._aItemGroups.length;
|
|
var nItems;
|
|
var oItemGroup;
|
|
var oItem;
|
|
var i;
|
|
var 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);
|
|
|
|
|
|
},
|
|
|
|
/**
|
|
* @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 <code><div></code>
|
|
* 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
|
|
* <code><div></code> 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 <a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/
|
|
* level-one-html.html#ID-58190037">HTMLElement</a>|String
|
|
* @default document.body
|
|
*/
|
|
this.cfg.addProperty(
|
|
"container",
|
|
{ value:document.body, handler:this.configContainer }
|
|
);
|
|
|
|
}
|
|
|
|
}); // END YAHOO.extend
|
|
|
|
})();
|
|
|
|
/**
|
|
* The base class for all menuing containers.
|
|
*
|
|
* @param {String} p_oElement String specifying the id attribute of the
|
|
* <code><div></code> element of the menu module.
|
|
* @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 module.
|
|
* @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 module.
|
|
* @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 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
|
|
* @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.MenuModule = YAHOO.widget.Menu;
|
|
|
|
(function() {
|
|
|
|
var Dom = YAHOO.util.Dom;
|
|
var Module = YAHOO.widget.Module;
|
|
var Menu = YAHOO.widget.Menu;
|
|
|
|
/**
|
|
* Creates an item for a menu.
|
|
*
|
|
* @param {String} p_oObject String specifying the text of the menu item.
|
|
* @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-
|
|
* one-html.html#ID-74680021">HTMLLIElement</a>} p_oObject Object specifying
|
|
* the <code><li></code> element of the menu item.
|
|
* @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-
|
|
* one-html.html#ID-38450247">HTMLOptGroupElement</a>} p_oObject Object
|
|
* specifying the <code><optgroup></code> element of the menu item.
|
|
* @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-
|
|
* one-html.html#ID-70901257">HTMLOptionElement</a>} p_oObject Object
|
|
* specifying the <code><option></code> 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.MenuItem.prototype = {
|
|
|
|
// Constants
|
|
|
|
/**
|
|
* @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",
|
|
|
|
/**
|
|
* @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
|
|
*/
|
|
SELECTED_SUBMENU_INDICATOR_IMAGE_PATH:
|
|
"nt/ic/ut/alt1/menuarorght8_hov_1.gif",
|
|
|
|
/**
|
|
* @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
|
|
*/
|
|
DISABLED_SUBMENU_INDICATOR_IMAGE_PATH:
|
|
"nt/ic/ut/alt1/menuarorght8_dim_1.gif",
|
|
|
|
/**
|
|
* @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.",
|
|
|
|
/**
|
|
* @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.",
|
|
|
|
/**
|
|
* @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.",
|
|
|
|
/**
|
|
* @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
|
|
*/
|
|
CHECKED_IMAGE_PATH: "nt/ic/ut/bsc/menuchk8_nrm_1.gif",
|
|
|
|
|
|
/**
|
|
* @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 String
|
|
*/
|
|
SELECTED_CHECKED_IMAGE_PATH: "nt/ic/ut/bsc/menuchk8_hov_1.gif",
|
|
|
|
|
|
/**
|
|
* @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 String
|
|
*/
|
|
DISABLED_CHECKED_IMAGE_PATH: "nt/ic/ut/bsc/menuchk8_dim_1.gif",
|
|
|
|
|
|
/**
|
|
* @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
|
|
*/
|
|
CHECKED_IMAGE_ALT_TEXT: "Checked.",
|
|
|
|
|
|
/**
|
|
* @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
|
|
*/
|
|
DISABLED_CHECKED_IMAGE_ALT_TEXT: "Checked. (Item disabled.)",
|
|
|
|
/**
|
|
* @property CSS_CLASS_NAME
|
|
* @description String representing the CSS class(es) to be applied to the
|
|
* <code><li></code> element of the menu item.
|
|
* @default "yuimenuitem"
|
|
* @final
|
|
* @type String
|
|
*/
|
|
CSS_CLASS_NAME: "yuimenuitem",
|
|
|
|
/**
|
|
* @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
|
|
*/
|
|
SUBMENU_TYPE: null,
|
|
|
|
/**
|
|
* @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
|
|
*/
|
|
IMG_ROOT: "http://us.i1.yimg.com/us.yimg.com/i/",
|
|
|
|
|
|
/**
|
|
* @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
|
|
* <code><a></code> element.
|
|
* @default null
|
|
* @private
|
|
* @type <a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-
|
|
* one-html.html#ID-48250443">HTMLAnchorElement</a>
|
|
*/
|
|
_oAnchor: null,
|
|
|
|
|
|
/**
|
|
* @property _oText
|
|
* @description Object reference to the menu item's text node.
|
|
* @default null
|
|
* @private
|
|
* @type TextNode
|
|
*/
|
|
_oText: null,
|
|
|
|
|
|
/**
|
|
* @property _oHelpTextEM
|
|
* @description Object reference to the menu item's help text
|
|
* <code><em></code> element.
|
|
* @default null
|
|
* @private
|
|
* @type <a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-
|
|
* one-html.html#ID-58190037">HTMLElement</a>
|
|
*/
|
|
_oHelpTextEM: null,
|
|
|
|
|
|
/**
|
|
* @property _oSubmenu
|
|
* @description Object reference to the menu item's submenu.
|
|
* @default null
|
|
* @private
|
|
* @type YAHOO.widget.Menu
|
|
*/
|
|
_oSubmenu: null,
|
|
|
|
/**
|
|
* @property _checkImage
|
|
* @description Object reference to the menu item's checkmark image.
|
|
* @default null
|
|
* @private
|
|
* @type <a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-
|
|
* one-html.html#ID-17701901">HTMLImageElement</a>
|
|
*/
|
|
_checkImage: null,
|
|
|
|
// Public properties
|
|
|
|
/**
|
|
* @property constructor
|
|
* @description Object reference to the menu item's constructor function.
|
|
* @default YAHOO.widget.MenuItem
|
|
* @type YAHOO.widget.MenuItem
|
|
*/
|
|
constructor: YAHOO.widget.MenuItem,
|
|
|
|
/**
|
|
* @property imageRoot
|
|
* @description String representing the root path for all of the menu
|
|
* item's images.
|
|
* @type String
|
|
*/
|
|
imageRoot: null,
|
|
|
|
/**
|
|
* @property isSecure
|
|
* @description Boolean representing whether or not the current browsing
|
|
* context is secure (HTTPS).
|
|
* @type Boolean
|
|
*/
|
|
isSecure: Module.prototype.isSecure,
|
|
|
|
/**
|
|
* @property index
|
|
* @description Number indicating the ordinal position of the menu item in
|
|
* its group.
|
|
* @default null
|
|
* @type Number
|
|
*/
|
|
index: null,
|
|
|
|
/**
|
|
* @property groupIndex
|
|
* @description Number indicating the index of the group to which the menu
|
|
* item belongs.
|
|
* @default null
|
|
* @type Number
|
|
*/
|
|
groupIndex: null,
|
|
|
|
/**
|
|
* @property parent
|
|
* @description Object reference to the menu item's parent menu.
|
|
* @default null
|
|
* @type YAHOO.widget.Menu
|
|
*/
|
|
parent: null,
|
|
|
|
/**
|
|
* @property element
|
|
* @description Object reference to the menu item's
|
|
* <code><li></code> element.
|
|
* @default <a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level
|
|
* -one-html.html#ID-74680021">HTMLLIElement</a>
|
|
* @type <a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-
|
|
* one-html.html#ID-74680021">HTMLLIElement</a>
|
|
*/
|
|
element: null,
|
|
|
|
/**
|
|
* @property srcElement
|
|
* @description Object reference to the HTML element (either
|
|
* <code><li></code>, <code><optgroup></code> or
|
|
* <code><option></code>) used create the menu item.
|
|
* @default <a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/
|
|
* level-one-html.html#ID-74680021">HTMLLIElement</a>|<a href="http://www.
|
|
* w3.org/TR/2000/WD-DOM-Level-1-20000929/level-one-html.html#ID-38450247"
|
|
* >HTMLOptGroupElement</a>|<a href="http://www.w3.org/TR/2000/WD-DOM-
|
|
* Level-1-20000929/level-one-html.html#ID-70901257">HTMLOptionElement</a>
|
|
* @type <a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-
|
|
* one-html.html#ID-74680021">HTMLLIElement</a>|<a href="http://www.w3.
|
|
* org/TR/2000/WD-DOM-Level-1-20000929/level-one-html.html#ID-38450247">
|
|
* HTMLOptGroupElement</a>|<a href="http://www.w3.org/TR/2000/WD-DOM-
|
|
* Level-1-20000929/level-one-html.html#ID-70901257">HTMLOptionElement</a>
|
|
*/
|
|
srcElement: null,
|
|
|
|
/**
|
|
* @property value
|
|
* @description Object reference to the menu item's value.
|
|
* @default null
|
|
* @type Object
|
|
*/
|
|
value: null,
|
|
|
|
/**
|
|
* @property submenuIndicator
|
|
* @description Object reference to the <code><img></code> element
|
|
* used to create the submenu indicator for the menu item.
|
|
* @default <a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/
|
|
* level-one-html.html#ID-17701901">HTMLImageElement</a>
|
|
* @type <a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/
|
|
* level-one-html.html#ID-17701901">HTMLImageElement</a>
|
|
*/
|
|
submenuIndicator: null,
|
|
|
|
/**
|
|
* @property browser
|
|
* @description String representing the browser.
|
|
* @type String
|
|
*/
|
|
browser: Module.prototype.browser,
|
|
|
|
// Events
|
|
|
|
/**
|
|
* @event destroyEvent
|
|
* @description Fires when the menu item's <code><li></code>
|
|
* element is removed from its parent <code><ul></code> element.
|
|
* @type YAHOO.util.CustomEvent
|
|
*/
|
|
destroyEvent: null,
|
|
|
|
/**
|
|
* @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
|
|
*/
|
|
mouseOverEvent: null,
|
|
|
|
/**
|
|
* @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
|
|
*/
|
|
mouseOutEvent: null,
|
|
|
|
/**
|
|
* @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
|
|
*/
|
|
mouseDownEvent: null,
|
|
|
|
/**
|
|
* @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,
|
|
|
|
/**
|
|
* @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
|
|
*/
|
|
clickEvent: null,
|
|
|
|
/**
|
|
* @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,
|
|
|
|
/**
|
|
* @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,
|
|
|
|
/**
|
|
* @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,
|
|
|
|
/**
|
|
* @event focusEvent
|
|
* @description Fires when the menu item receives focus.
|
|
* @type YAHOO.util.CustomEvent
|
|
*/
|
|
focusEvent: null,
|
|
|
|
/**
|
|
* @event blurEvent
|
|
* @description Fires when the menu item loses the input focus.
|
|
* @type YAHOO.util.CustomEvent
|
|
*/
|
|
blurEvent: null,
|
|
|
|
/**
|
|
* @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} p_oObject String specifying the text of the menu item.
|
|
* @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-
|
|
* one-html.html#ID-74680021">HTMLLIElement</a>} p_oObject Object specifying
|
|
* the <code><li></code> element of the menu item.
|
|
* @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-
|
|
* one-html.html#ID-38450247">HTMLOptGroupElement</a>} p_oObject Object
|
|
* specifying the <code><optgroup></code> element of the menu item.
|
|
* @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-
|
|
* one-html.html#ID-70901257">HTMLOptionElement</a>} p_oObject Object
|
|
* specifying the <code><option></code> 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) {
|
|
|
|
this.imageRoot = (this.isSecure) ? this.IMG_ROOT_SSL : this.IMG_ROOT;
|
|
|
|
if(!this.SUBMENU_TYPE) {
|
|
|
|
this.SUBMENU_TYPE = Menu;
|
|
|
|
}
|
|
|
|
// Create the config object
|
|
|
|
this.cfg = new YAHOO.util.Config(this);
|
|
|
|
this.initDefaultConfig();
|
|
|
|
var oConfig = this.cfg;
|
|
|
|
if(this._checkString(p_oObject)) {
|
|
|
|
this._createRootNodeStructure();
|
|
|
|
oConfig.setProperty("text", p_oObject);
|
|
|
|
}
|
|
else if(this._checkDOMNode(p_oObject)) {
|
|
|
|
switch(p_oObject.tagName.toUpperCase()) {
|
|
|
|
case "OPTION":
|
|
|
|
this._createRootNodeStructure();
|
|
|
|
oConfig.setProperty("text", p_oObject.text);
|
|
|
|
this.srcElement = p_oObject;
|
|
|
|
break;
|
|
|
|
case "OPTGROUP":
|
|
|
|
this._createRootNodeStructure();
|
|
|
|
oConfig.setProperty("text", p_oObject.label);
|
|
|
|
this.srcElement = p_oObject;
|
|
|
|
this._initSubTree();
|
|
|
|
break;
|
|
|
|
case "LI":
|
|
|
|
// Get the anchor node (if it exists)
|
|
|
|
var oAnchor = this._getFirstElement(p_oObject, "A");
|
|
var sURL = "#";
|
|
var sTarget = null;
|
|
var sText = null;
|
|
|
|
// Capture the "text" and/or the "URL"
|
|
|
|
if(oAnchor) {
|
|
|
|
sURL = oAnchor.getAttribute("href");
|
|
sTarget = oAnchor.getAttribute("target");
|
|
|
|
if(oAnchor.innerText) {
|
|
|
|
sText = oAnchor.innerText;
|
|
|
|
}
|
|
else {
|
|
|
|
var oRange = oAnchor.ownerDocument.createRange();
|
|
|
|
oRange.selectNodeContents(oAnchor);
|
|
|
|
sText = oRange.toString();
|
|
|
|
}
|
|
|
|
}
|
|
else {
|
|
|
|
var oText = p_oObject.firstChild;
|
|
|
|
sText = oText.nodeValue;
|
|
|
|
oAnchor = document.createElement("a");
|
|
|
|
oAnchor.setAttribute("href", sURL);
|
|
|
|
p_oObject.replaceChild(oAnchor, oText);
|
|
|
|
oAnchor.appendChild(oText);
|
|
|
|
}
|
|
|
|
this.srcElement = p_oObject;
|
|
this.element = p_oObject;
|
|
this._oAnchor = oAnchor;
|
|
|
|
|
|
// Check if emphasis has been applied to the MenuItem
|
|
|
|
var oEmphasisNode = this._getFirstElement(oAnchor);
|
|
var bEmphasis = false;
|
|
var bStrongEmphasis = false;
|
|
|
|
if(oEmphasisNode) {
|
|
|
|
// Set a reference to the text node
|
|
|
|
this._oText = oEmphasisNode.firstChild;
|
|
|
|
switch(oEmphasisNode.tagName.toUpperCase()) {
|
|
|
|
case "EM":
|
|
|
|
bEmphasis = true;
|
|
|
|
break;
|
|
|
|
case "STRONG":
|
|
|
|
bStrongEmphasis = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
else {
|
|
|
|
// Set a reference to the text node
|
|
|
|
this._oText = oAnchor.firstChild;
|
|
|
|
}
|
|
|
|
/*
|
|
Set these properties silently to sync up the
|
|
configuration object without making changes to the
|
|
element's DOM
|
|
*/
|
|
|
|
oConfig.setProperty("text", sText, true);
|
|
oConfig.setProperty("url", sURL, true);
|
|
oConfig.setProperty("target", sTarget, true);
|
|
oConfig.setProperty("emphasis", bEmphasis, true);
|
|
oConfig.setProperty(
|
|
"strongemphasis",
|
|
bStrongEmphasis,
|
|
true
|
|
);
|
|
|
|
this._initSubTree();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if(this.element) {
|
|
|
|
Dom.addClass(this.element, this.CSS_CLASS_NAME);
|
|
|
|
// Create custom events
|
|
|
|
var CustomEvent = YAHOO.util.CustomEvent;
|
|
|
|
this.destroyEvent = new CustomEvent("destroyEvent", this);
|
|
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.focusEvent = new CustomEvent("focusEvent", this);
|
|
this.blurEvent = new CustomEvent("blurEvent", this);
|
|
|
|
if(p_oConfig) {
|
|
|
|
oConfig.applyConfig(p_oConfig);
|
|
|
|
}
|
|
|
|
oConfig.fireQueue();
|
|
|
|
}
|
|
|
|
},
|
|
|
|
// Private methods
|
|
|
|
/**
|
|
* @method _getFirstElement
|
|
* @description Returns an HTML element's first HTML element node.
|
|
* @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
|
|
* reference specifying the element to be evaluated.
|
|
* @param {String} p_sTagName Optional. String specifying the tagname of
|
|
* the element to be retrieved.
|
|
* @return {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/
|
|
* level-one-html.html#ID-58190037">HTMLElement</a>}
|
|
*/
|
|
_getFirstElement: function(p_oElement, p_sTagName) {
|
|
|
|
var oElement;
|
|
|
|
if(p_oElement.firstChild && p_oElement.firstChild.nodeType == 1) {
|
|
|
|
oElement = p_oElement.firstChild;
|
|
|
|
}
|
|
else if(
|
|
p_oElement.firstChild &&
|
|
p_oElement.firstChild.nextSibling &&
|
|
p_oElement.firstChild.nextSibling.nodeType == 1
|
|
) {
|
|
|
|
oElement = p_oElement.firstChild.nextSibling;
|
|
|
|
}
|
|
|
|
if(p_sTagName) {
|
|
|
|
return (oElement && oElement.tagName.toUpperCase() == p_sTagName) ?
|
|
oElement : false;
|
|
|
|
}
|
|
|
|
return oElement;
|
|
|
|
},
|
|
|
|
/**
|
|
* @method _checkString
|
|
* @description Determines if an object is a string.
|
|
* @private
|
|
* @param {Object} p_oObject Object to be evaluated.
|
|
* @return {Boolean}
|
|
*/
|
|
_checkString: function(p_oObject) {
|
|
|
|
return (typeof p_oObject == "string");
|
|
|
|
},
|
|
|
|
/**
|
|
* @method _checkDOMNode
|
|
* @description Determines if an object is an HTML element.
|
|
* @private
|
|
* @param {Object} p_oObject Object to be evaluated.
|
|
* @return {Boolean}
|
|
*/
|
|
_checkDOMNode: function(p_oObject) {
|
|
|
|
return (p_oObject && p_oObject.tagName);
|
|
|
|
},
|
|
|
|
/**
|
|
* @method _createRootNodeStructure
|
|
* @description Creates the core DOM structure for the menu item.
|
|
* @private
|
|
*/
|
|
_createRootNodeStructure: function () {
|
|
|
|
this.element = document.createElement("li");
|
|
|
|
this._oText = document.createTextNode("");
|
|
|
|
this._oAnchor = document.createElement("a");
|
|
this._oAnchor.appendChild(this._oText);
|
|
|
|
this.cfg.refireEvent("url");
|
|
|
|
this.element.appendChild(this._oAnchor);
|
|
|
|
},
|
|
|
|
/**
|
|
* @method _initSubTree
|
|
* @description Iterates the source element's childNodes collection and uses
|
|
* the child nodes to instantiate other menus.
|
|
* @private
|
|
*/
|
|
_initSubTree: function() {
|
|
|
|
var oSrcEl = this.srcElement;
|
|
var oConfig = this.cfg;
|
|
|
|
if(oSrcEl.childNodes.length > 0) {
|
|
|
|
if(
|
|
this.parent.lazyLoad &&
|
|
this.parent.srcElement &&
|
|
this.parent.srcElement.tagName.toUpperCase() == "SELECT"
|
|
) {
|
|
|
|
oConfig.setProperty(
|
|
"submenu",
|
|
{ id: Dom.generateId(), itemdata: oSrcEl.childNodes }
|
|
);
|
|
|
|
}
|
|
else {
|
|
|
|
var oNode = oSrcEl.firstChild;
|
|
var aOptions = [];
|
|
|
|
do {
|
|
|
|
if(oNode && oNode.tagName) {
|
|
|
|
switch(oNode.tagName.toUpperCase()) {
|
|
|
|
case "DIV":
|
|
|
|
oConfig.setProperty("submenu", oNode);
|
|
|
|
break;
|
|
|
|
case "OPTION":
|
|
|
|
aOptions[aOptions.length] = oNode;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
while((oNode = oNode.nextSibling));
|
|
|
|
|
|
var nOptions = aOptions.length;
|
|
|
|
if(nOptions > 0) {
|
|
|
|
var oMenu = new this.SUBMENU_TYPE(Dom.generateId());
|
|
|
|
oConfig.setProperty("submenu", oMenu);
|
|
|
|
for(var n=0; n<nOptions; n++) {
|
|
|
|
oMenu.addItem((new oMenu.ITEM_TYPE(aOptions[n])));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
/**
|
|
* @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) {
|
|
|
|
var sPath = this.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);
|
|
|
|
}
|
|
|
|
},
|
|
|
|
// Event handlers for configuration properties
|
|
|
|
/**
|
|
* @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) {
|
|
|
|
var sText = p_aArgs[0];
|
|
|
|
if(this._oText) {
|
|
|
|
this._oText.nodeValue = sText;
|
|
|
|
}
|
|
|
|
},
|
|
|
|
/**
|
|
* @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 oHelpText = p_aArgs[0];
|
|
var oEl = this.element;
|
|
var oConfig = this.cfg;
|
|
var aNodes = [oEl, this._oAnchor];
|
|
var oImg = this.submenuIndicator;
|
|
|
|
/**
|
|
* Adds the "hashelptext" class to the necessary nodes and refires the
|
|
* "selected" and "disabled" configuration events.
|
|
* @private
|
|
*/
|
|
var initHelpText = function() {
|
|
|
|
Dom.addClass(aNodes, "hashelptext");
|
|
|
|
if(oConfig.getProperty("disabled")) {
|
|
|
|
oConfig.refireEvent("disabled");
|
|
|
|
}
|
|
|
|
if(oConfig.getProperty("selected")) {
|
|
|
|
oConfig.refireEvent("selected");
|
|
|
|
}
|
|
|
|
};
|
|
|
|
/**
|
|
* Removes the "hashelptext" class and corresponding DOM element (EM).
|
|
* @private
|
|
*/
|
|
var removeHelpText = function() {
|
|
|
|
Dom.removeClass(aNodes, "hashelptext");
|
|
|
|
oEl.removeChild(me._oHelpTextEM);
|
|
me._oHelpTextEM = null;
|
|
|
|
};
|
|
|
|
if(this._checkDOMNode(oHelpText)) {
|
|
|
|
if(this._oHelpTextEM) {
|
|
|
|
this._oHelpTextEM.parentNode.replaceChild(
|
|
oHelpText,
|
|
this._oHelpTextEM
|
|
);
|
|
|
|
}
|
|
else {
|
|
|
|
this._oHelpTextEM = oHelpText;
|
|
|
|
oEl.insertBefore(this._oHelpTextEM, oImg);
|
|
|
|
}
|
|
|
|
initHelpText();
|
|
|
|
}
|
|
else if(this._checkString(oHelpText)) {
|
|
|
|
if(oHelpText.length === 0) {
|
|
|
|
removeHelpText();
|
|
|
|
}
|
|
else {
|
|
|
|
if(!this._oHelpTextEM) {
|
|
|
|
this._oHelpTextEM = document.createElement("em");
|
|
|
|
oEl.insertBefore(this._oHelpTextEM, oImg);
|
|
|
|
}
|
|
|
|
this._oHelpTextEM.innerHTML = oHelpText;
|
|
|
|
initHelpText();
|
|
|
|
}
|
|
|
|
}
|
|
else if(!oHelpText && this._oHelpTextEM) {
|
|
|
|
removeHelpText();
|
|
|
|
}
|
|
|
|
},
|
|
|
|
/**
|
|
* @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) {
|
|
|
|
var sURL = p_aArgs[0];
|
|
|
|
if(!sURL) {
|
|
|
|
sURL = "#";
|
|
|
|
}
|
|
|
|
this._oAnchor.setAttribute("href", sURL);
|
|
|
|
},
|
|
|
|
/**
|
|
* @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;
|
|
|
|
if(sTarget && sTarget.length > 0) {
|
|
|
|
oAnchor.setAttribute("target", sTarget);
|
|
|
|
}
|
|
else {
|
|
|
|
oAnchor.removeAttribute("target");
|
|
|
|
}
|
|
|
|
},
|
|
|
|
/**
|
|
* @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;
|
|
|
|
if(bEmphasis && oConfig.getProperty("strongemphasis")) {
|
|
|
|
oConfig.setProperty("strongemphasis", false);
|
|
|
|
}
|
|
|
|
if(oAnchor) {
|
|
|
|
if(bEmphasis) {
|
|
|
|
oEM = document.createElement("em");
|
|
oEM.appendChild(oText);
|
|
|
|
oAnchor.appendChild(oEM);
|
|
|
|
}
|
|
else {
|
|
|
|
oEM = this._getFirstElement(oAnchor, "EM");
|
|
|
|
oAnchor.removeChild(oEM);
|
|
oAnchor.appendChild(oText);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
/**
|
|
* @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;
|
|
|
|
if(bStrongEmphasis && oConfig.getProperty("emphasis")) {
|
|
|
|
oConfig.setProperty("emphasis", false);
|
|
|
|
}
|
|
|
|
if(oAnchor) {
|
|
|
|
if(bStrongEmphasis) {
|
|
|
|
oStrong = document.createElement("strong");
|
|
oStrong.appendChild(oText);
|
|
|
|
oAnchor.appendChild(oStrong);
|
|
|
|
}
|
|
else {
|
|
|
|
oStrong = this._getFirstElement(oAnchor, "STRONG");
|
|
|
|
oAnchor.removeChild(oStrong);
|
|
oAnchor.appendChild(oText);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
/**
|
|
* @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];
|
|
var oEl = this.element;
|
|
var oConfig = this.cfg;
|
|
var 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 oAnchor = this._oAnchor;
|
|
var aNodes = [this.element, oAnchor];
|
|
var oEM = this._oHelpTextEM;
|
|
var oConfig = this.cfg;
|
|
var oImg;
|
|
var sImgSrc;
|
|
var sImgAlt;
|
|
|
|
if(oEM) {
|
|
|
|
aNodes[2] = oEM;
|
|
|
|
}
|
|
|
|
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")) {
|
|
|
|
oConfig.setProperty("selected", false);
|
|
|
|
}
|
|
|
|
oAnchor.removeAttribute("href");
|
|
|
|
Dom.addClass(aNodes, "disabled");
|
|
|
|
sImgSrc = this.DISABLED_SUBMENU_INDICATOR_IMAGE_PATH;
|
|
sImgAlt = this.DISABLED_SUBMENU_INDICATOR_ALT_TEXT;
|
|
|
|
}
|
|
else {
|
|
|
|
oAnchor.setAttribute("href", oConfig.getProperty("url"));
|
|
|
|
Dom.removeClass(aNodes, "disabled");
|
|
|
|
sImgSrc = this.SUBMENU_INDICATOR_IMAGE_PATH;
|
|
sImgAlt = this.COLLAPSED_SUBMENU_INDICATOR_ALT_TEXT;
|
|
|
|
}
|
|
|
|
if(oImg) {
|
|
|
|
oImg.src = this.imageRoot + sImgSrc;
|
|
oImg.alt = sImgAlt;
|
|
|
|
}
|
|
|
|
},
|
|
|
|
/**
|
|
* @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 bSelected = p_aArgs[0];
|
|
var oEM = this._oHelpTextEM;
|
|
var aNodes = [this.element, this._oAnchor];
|
|
var oImg = this.submenuIndicator;
|
|
var sImgSrc;
|
|
|
|
if(oEM) {
|
|
|
|
aNodes[aNodes.length] = oEM;
|
|
|
|
}
|
|
|
|
if(oImg) {
|
|
|
|
aNodes[aNodes.length] = oImg;
|
|
|
|
}
|
|
|
|
|
|
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");
|
|
sImgSrc = this.SELECTED_SUBMENU_INDICATOR_IMAGE_PATH;
|
|
|
|
}
|
|
else {
|
|
|
|
Dom.removeClass(aNodes, "selected");
|
|
sImgSrc = this.SUBMENU_INDICATOR_IMAGE_PATH;
|
|
|
|
}
|
|
|
|
if(oImg) {
|
|
|
|
oImg.src = document.images[(this.imageRoot + sImgSrc)].src;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
/**
|
|
* @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 oEl = this.element;
|
|
var oSubmenu = p_aArgs[0];
|
|
var oImg = this.submenuIndicator;
|
|
var oConfig = this.cfg;
|
|
var aNodes = [this.element, this._oAnchor];
|
|
var oMenu;
|
|
var bLazyLoad = this.parent && this.parent.lazyLoad;
|
|
|
|
if(oSubmenu) {
|
|
|
|
if(oSubmenu instanceof Menu) {
|
|
|
|
oMenu = oSubmenu;
|
|
oMenu.parent = this;
|
|
oMenu.lazyLoad = bLazyLoad;
|
|
|
|
}
|
|
else if(
|
|
typeof oSubmenu == "object" &&
|
|
oSubmenu.id &&
|
|
!oSubmenu.nodeType
|
|
) {
|
|
|
|
var sSubmenuId = oSubmenu.id;
|
|
var oSubmenuConfig = oSubmenu;
|
|
|
|
delete oSubmenu["id"];
|
|
|
|
oSubmenuConfig.lazyload = bLazyLoad;
|
|
oSubmenuConfig.parent = this;
|
|
|
|
oMenu = new this.SUBMENU_TYPE(sSubmenuId, oSubmenuConfig);
|
|
|
|
// Set the value of the property to the Menu instance
|
|
|
|
this.cfg.setProperty("submenu", oMenu, true);
|
|
|
|
}
|
|
else {
|
|
|
|
oMenu = new this.SUBMENU_TYPE(
|
|
oSubmenu,
|
|
{ lazyload: bLazyLoad, parent: this }
|
|
);
|
|
|
|
// Set the value of the property to the Menu instance
|
|
|
|
this.cfg.setProperty("submenu", oMenu, true);
|
|
|
|
}
|
|
|
|
if(oMenu) {
|
|
|
|
this._oSubmenu = oMenu;
|
|
|
|
if(!oImg) {
|
|
|
|
this._preloadImage(this.SUBMENU_INDICATOR_IMAGE_PATH);
|
|
this._preloadImage(
|
|
this.SELECTED_SUBMENU_INDICATOR_IMAGE_PATH
|
|
);
|
|
|
|
this._preloadImage(
|
|
this.DISABLED_SUBMENU_INDICATOR_IMAGE_PATH
|
|
);
|
|
|
|
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;
|
|
|
|
Dom.addClass(aNodes, "hassubmenu");
|
|
|
|
if(oConfig.getProperty("disabled")) {
|
|
|
|
oConfig.refireEvent("disabled");
|
|
|
|
}
|
|
|
|
if(oConfig.getProperty("selected")) {
|
|
|
|
oConfig.refireEvent("selected");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
else {
|
|
|
|
Dom.removeClass(aNodes, "hassubmenu");
|
|
|
|
if(oImg) {
|
|
|
|
oEl.removeChild(oImg);
|
|
|
|
}
|
|
|
|
if(this._oSubmenu) {
|
|
|
|
this._oSubmenu.destroy();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
// Public methods
|
|
|
|
/**
|
|
* @method initDefaultConfig
|
|
* @description Initializes an item's configurable properties.
|
|
*/
|
|
initDefaultConfig : function() {
|
|
|
|
var oConfig = this.cfg;
|
|
var 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",
|
|
{
|
|
value: "",
|
|
handler: this.configText,
|
|
validator: this._checkString,
|
|
suppressEvent: true
|
|
}
|
|
);
|
|
|
|
|
|
/**
|
|
* @config helptext
|
|
* @description String specifying additional instructional text to
|
|
* accompany the text for the nenu item.
|
|
* @default null
|
|
* @type String|<a href="http://www.w3.org/TR/
|
|
* 2000/WD-DOM-Level-1-20000929/level-one-html.html#ID-58190037">
|
|
* HTMLElement</a>
|
|
*/
|
|
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. <strong>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.</strong>
|
|
* 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",
|
|
{
|
|
value: false,
|
|
handler: this.configEmphasis,
|
|
validator: CheckBoolean,
|
|
suppressEvent: true
|
|
}
|
|
);
|
|
|
|
/**
|
|
* @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",
|
|
{
|
|
value: false,
|
|
handler: this.configStrongEmphasis,
|
|
validator: CheckBoolean,
|
|
suppressEvent: true
|
|
}
|
|
);
|
|
|
|
/**
|
|
* @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,
|
|
handler: this.configDisabled,
|
|
validator: CheckBoolean,
|
|
suppressEvent: true
|
|
}
|
|
);
|
|
|
|
/**
|
|
* @config selected
|
|
* @description Boolean indicating if the menu item should
|
|
* be highlighted.
|
|
* @default false
|
|
* @type Boolean
|
|
*/
|
|
oConfig.addProperty(
|
|
"selected",
|
|
{
|
|
value: false,
|
|
handler: this.configSelected,
|
|
validator: CheckBoolean,
|
|
suppressEvent: true
|
|
}
|
|
);
|
|
|
|
/**
|
|
* @config submenu
|
|
* @description Object specifying the submenu to be appended to the
|
|
* menu item. The value can be one of the following: <ul><li>Object
|
|
* specifying a Menu instance.</li><li>Object literal specifying the
|
|
* menu to be created. Format: <code>{ id: [menu id], itemdata:
|
|
* [<a href="YAHOO.widget.Menu.html#itemData">array of values for
|
|
* items</a>] }</code>.</li><li>String specifying the id attribute
|
|
* of the <code><div></code> element of the menu.</li><li>
|
|
* Object specifying the <code><div></code> element of the
|
|
* menu.</li></ul>
|
|
* @default null
|
|
* @type Menu|String|Object|<a href="http://www.w3.org/TR/2000/
|
|
* WD-DOM-Level-1-20000929/level-one-html.html#ID-58190037">
|
|
* HTMLElement</a>
|
|
*/
|
|
oConfig.addProperty("submenu", { handler: this.configSubmenu });
|
|
|
|
},
|
|
|
|
/**
|
|
* @method getNextEnabledSibling
|
|
* @description Finds the menu item's next enabled sibling.
|
|
* @return YAHOO.widget.MenuItem
|
|
*/
|
|
getNextEnabledSibling: function() {
|
|
|
|
if(this.parent instanceof Menu) {
|
|
|
|
var nGroupIndex = this.groupIndex;
|
|
|
|
/**
|
|
* 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}
|
|
*/
|
|
var getNextArrayItem = function(p_aArray, p_nStartIndex) {
|
|
|
|
return p_aArray[p_nStartIndex] ||
|
|
getNextArrayItem(p_aArray, (p_nStartIndex+1));
|
|
|
|
};
|
|
|
|
|
|
var aItemGroups = this.parent.getItemGroups();
|
|
var oNextItem;
|
|
|
|
|
|
if(this.index < (aItemGroups[nGroupIndex].length - 1)) {
|
|
|
|
oNextItem = getNextArrayItem(
|
|
aItemGroups[nGroupIndex],
|
|
(this.index+1)
|
|
);
|
|
|
|
}
|
|
else {
|
|
|
|
var nNextGroupIndex;
|
|
|
|
if(nGroupIndex < (aItemGroups.length - 1)) {
|
|
|
|
nNextGroupIndex = nGroupIndex + 1;
|
|
|
|
}
|
|
else {
|
|
|
|
nNextGroupIndex = 0;
|
|
|
|
}
|
|
|
|
var aNextGroup = getNextArrayItem(aItemGroups, nNextGroupIndex);
|
|
|
|
// Retrieve the first menu item in the next group
|
|
|
|
oNextItem = getNextArrayItem(aNextGroup, 0);
|
|
|
|
}
|
|
|
|
return (
|
|
oNextItem.cfg.getProperty("disabled") ||
|
|
oNextItem.element.style.display == "none"
|
|
) ?
|
|
oNextItem.getNextEnabledSibling() : oNextItem;
|
|
|
|
}
|
|
|
|
},
|
|
|
|
/**
|
|
* @method getPreviousEnabledSibling
|
|
* @description Finds the menu item's previous enabled sibling.
|
|
* @return {YAHOO.widget.MenuItem}
|
|
*/
|
|
getPreviousEnabledSibling: function() {
|
|
|
|
if(this.parent instanceof Menu) {
|
|
|
|
var nGroupIndex = this.groupIndex;
|
|
|
|
/**
|
|
* Returns the previous 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}
|
|
*/
|
|
var getPreviousArrayItem = function(p_aArray, p_nStartIndex) {
|
|
|
|
return p_aArray[p_nStartIndex] ||
|
|
getPreviousArrayItem(p_aArray, (p_nStartIndex-1));
|
|
|
|
};
|
|
|
|
/**
|
|
* Get the index of the first 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}
|
|
*/
|
|
var getFirstItemIndex = function(p_aArray, p_nStartIndex) {
|
|
|
|
return p_aArray[p_nStartIndex] ?
|
|
p_nStartIndex :
|
|
getFirstItemIndex(p_aArray, (p_nStartIndex+1));
|
|
|
|
};
|
|
|
|
var aItemGroups = this.parent.getItemGroups();
|
|
var oPreviousItem;
|
|
|
|
if(
|
|
this.index > getFirstItemIndex(aItemGroups[nGroupIndex], 0)
|
|
) {
|
|
|
|
oPreviousItem =
|
|
getPreviousArrayItem(
|
|
aItemGroups[nGroupIndex],
|
|
(this.index-1)
|
|
);
|
|
|
|
}
|
|
else {
|
|
|
|
var nPreviousGroupIndex;
|
|
|
|
if(nGroupIndex > getFirstItemIndex(aItemGroups, 0)) {
|
|
|
|
nPreviousGroupIndex = nGroupIndex - 1;
|
|
|
|
}
|
|
else {
|
|
|
|
nPreviousGroupIndex = aItemGroups.length - 1;
|
|
|
|
}
|
|
|
|
var aPreviousGroup =
|
|
getPreviousArrayItem(aItemGroups, nPreviousGroupIndex);
|
|
|
|
oPreviousItem =
|
|
getPreviousArrayItem(
|
|
aPreviousGroup,
|
|
(aPreviousGroup.length - 1)
|
|
);
|
|
|
|
}
|
|
|
|
return (
|
|
oPreviousItem.cfg.getProperty("disabled") ||
|
|
oPreviousItem.element.style.display == "none"
|
|
) ?
|
|
oPreviousItem.getPreviousEnabledSibling() : oPreviousItem;
|
|
|
|
}
|
|
|
|
},
|
|
|
|
/**
|
|
* @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;
|
|
|
|
if(
|
|
!this.cfg.getProperty("disabled") &&
|
|
oParent &&
|
|
oParent.cfg.getProperty("visible") &&
|
|
this.element.style.display != "none"
|
|
) {
|
|
|
|
if(oActiveItem) {
|
|
|
|
oActiveItem.blur();
|
|
|
|
}
|
|
|
|
try {
|
|
|
|
oAnchor.focus();
|
|
|
|
}
|
|
catch(e) {
|
|
|
|
}
|
|
|
|
this.focusEvent.fire();
|
|
|
|
}
|
|
|
|
},
|
|
|
|
/**
|
|
* @method blur
|
|
* @description Causes the menu item to lose focus and fires the
|
|
* onblur event.
|
|
*/
|
|
blur: function() {
|
|
|
|
var oParent = this.parent;
|
|
|
|
if(
|
|
!this.cfg.getProperty("disabled") &&
|
|
oParent &&
|
|
Dom.getStyle(oParent.element, "visibility") == "visible"
|
|
) {
|
|
|
|
this._oAnchor.blur();
|
|
|
|
this.blurEvent.fire();
|
|
|
|
}
|
|
|
|
},
|
|
|
|
/**
|
|
* @method destroy
|
|
* @description Removes the menu item's <code><li></code> element
|
|
* from its parent <code><ul></code> element.
|
|
*/
|
|
destroy: function() {
|
|
|
|
var oEl = this.element;
|
|
|
|
if(oEl) {
|
|
|
|
// Remove CustomEvent 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.focusEvent.unsubscribeAll();
|
|
this.blurEvent.unsubscribeAll();
|
|
this.cfg.configChangedEvent.unsubscribeAll();
|
|
|
|
// Remove the element from the parent node
|
|
|
|
var oParentNode = oEl.parentNode;
|
|
|
|
if(oParentNode) {
|
|
|
|
oParentNode.removeChild(oEl);
|
|
|
|
this.destroyEvent.fire();
|
|
|
|
}
|
|
|
|
this.destroyEvent.unsubscribeAll();
|
|
|
|
}
|
|
|
|
},
|
|
|
|
/**
|
|
* @method toString
|
|
* @description Returns a string representing the menu item.
|
|
* @return {String}
|
|
*/
|
|
toString: function() {
|
|
|
|
return ("MenuItem: " + this.cfg.getProperty("text"));
|
|
|
|
}
|
|
|
|
};
|
|
|
|
})();
|
|
|
|
/**
|
|
* Creates an item for a menu module.
|
|
*
|
|
* @param {String} p_oObject String specifying the text of the menu module item.
|
|
* @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-one-
|
|
* html.html#ID-74680021">HTMLLIElement</a>} p_oObject Object specifying the
|
|
* <code><li></code> element of the menu module item.
|
|
* @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-one-
|
|
* html.html#ID-38450247">HTMLOptGroupElement</a>} p_oObject Object specifying
|
|
* the <code><optgroup></code> element of the menu module item.
|
|
* @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-one-
|
|
* html.html#ID-70901257">HTMLOptionElement</a>} p_oObject Object specifying the
|
|
* <code><option></code> 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.MenuModuleItem = YAHOO.widget.MenuItem;
|
|
|
|
/**
|
|
* 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
|
|
* <code><div></code> element of the context 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
|
|
* context 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 context 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 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.ContextMenu = function(p_oElement, p_oConfig) {
|
|
|
|
YAHOO.widget.ContextMenu.superclass.constructor.call(
|
|
this,
|
|
p_oElement,
|
|
p_oConfig
|
|
);
|
|
|
|
};
|
|
|
|
YAHOO.extend(YAHOO.widget.ContextMenu, YAHOO.widget.Menu, {
|
|
|
|
// Private properties
|
|
|
|
/**
|
|
* @property _oTrigger
|
|
* @description Object reference to the current value of the "trigger"
|
|
* configuration property.
|
|
* @default null
|
|
* @private
|
|
* @type String|<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/leve
|
|
* l-one-html.html#ID-58190037">HTMLElement</a>|Array
|
|
*/
|
|
_oTrigger: null,
|
|
|
|
// Public properties
|
|
|
|
/**
|
|
* @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 <a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-one-
|
|
* html.html#ID-58190037">HTMLElement</a>
|
|
*/
|
|
contextEventTarget: null,
|
|
|
|
/**
|
|
* @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
|
|
* <code><div></code> element of the context 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 context 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 context 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 context menu.
|
|
* @param {Object} p_oConfig Optional. Object literal specifying the
|
|
* configuration for the context menu. See configuration class documentation
|
|
* for more details.
|
|
*/
|
|
init: function(p_oElement, p_oConfig) {
|
|
|
|
if(!this.ITEM_TYPE) {
|
|
|
|
this.ITEM_TYPE = YAHOO.widget.ContextMenuItem;
|
|
|
|
}
|
|
|
|
// Call the init of the superclass (YAHOO.widget.Menu)
|
|
|
|
YAHOO.widget.ContextMenu.superclass.init.call(this, p_oElement);
|
|
|
|
this.beforeInitEvent.fire(YAHOO.widget.ContextMenu);
|
|
|
|
if(p_oConfig) {
|
|
|
|
this.cfg.applyConfig(p_oConfig, true);
|
|
|
|
}
|
|
|
|
|
|
this.initEvent.fire(YAHOO.widget.ContextMenu);
|
|
|
|
},
|
|
|
|
// Private methods
|
|
|
|
/**
|
|
* @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
|
|
*/
|
|
_removeEventHandlers: function() {
|
|
|
|
var Event = YAHOO.util.Event;
|
|
var oTrigger = this._oTrigger;
|
|
var bOpera = (this.browser == "opera");
|
|
|
|
// Remove the event handlers from the trigger(s)
|
|
|
|
Event.removeListener(
|
|
oTrigger,
|
|
(bOpera ? "mousedown" : "contextmenu"),
|
|
this._onTriggerContextMenu
|
|
);
|
|
|
|
if(bOpera) {
|
|
|
|
Event.removeListener(oTrigger, "click", this._onTriggerClick);
|
|
|
|
}
|
|
|
|
},
|
|
|
|
// Private event handlers
|
|
|
|
/**
|
|
* @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.
|
|
*/
|
|
_onTriggerClick: function(p_oEvent, p_oMenu) {
|
|
|
|
if(p_oEvent.ctrlKey) {
|
|
|
|
YAHOO.util.Event.stopEvent(p_oEvent);
|
|
|
|
}
|
|
|
|
},
|
|
|
|
/**
|
|
* @method _onTriggerContextMenu
|
|
* @description "contextmenu" event handler ("mousedown" for Opera) for the HTML
|
|
* element(s) that trigger the display of the context menu.
|
|
* @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.
|
|
*/
|
|
_onTriggerContextMenu: function(p_oEvent, p_oMenu) {
|
|
|
|
// Hide any other ContextMenu instances that might be visible
|
|
|
|
YAHOO.widget.MenuManager.hideVisible();
|
|
|
|
var Event = YAHOO.util.Event;
|
|
var oConfig = this.cfg;
|
|
|
|
if(p_oEvent.type == "mousedown" && !p_oEvent.ctrlKey) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
this.contextEventTarget = Event.getTarget(p_oEvent);
|
|
|
|
// Position and display the context menu
|
|
|
|
var nX = Event.getPageX(p_oEvent);
|
|
var nY = Event.getPageY(p_oEvent);
|
|
|
|
oConfig.applyConfig( { xy:[nX, nY], visible:true } );
|
|
oConfig.fireQueue();
|
|
|
|
/*
|
|
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.
|
|
*/
|
|
|
|
Event.stopEvent(p_oEvent);
|
|
|
|
},
|
|
|
|
// Public methods
|
|
|
|
/**
|
|
* @method toString
|
|
* @description Returns a string representing the context menu.
|
|
* @return {String}
|
|
*/
|
|
toString: function() {
|
|
|
|
return ("ContextMenu " + this.id);
|
|
|
|
},
|
|
|
|
/**
|
|
* @method initDefaultConfig
|
|
* @description Initializes the class's configurable properties which can be
|
|
* changed using the context menu's Config object ("cfg").
|
|
*/
|
|
initDefaultConfig: function() {
|
|
|
|
YAHOO.widget.ContextMenu.superclass.initDefaultConfig.call(this);
|
|
|
|
/**
|
|
* @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|<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/
|
|
* level-one-html.html#ID-58190037">HTMLElement</a>|Array
|
|
*/
|
|
this.cfg.addProperty("trigger", { handler: this.configTrigger });
|
|
|
|
},
|
|
|
|
/**
|
|
* @method destroy
|
|
* @description Removes the context menu's <code><div></code> element
|
|
* (and accompanying child nodes) from the document.
|
|
*/
|
|
destroy: function() {
|
|
|
|
// Remove the DOM event handlers from the current trigger(s)
|
|
|
|
this._removeEventHandlers();
|
|
|
|
|
|
// Continue with the superclass implementation of this method
|
|
|
|
YAHOO.widget.ContextMenu.superclass.destroy.call(this);
|
|
|
|
},
|
|
|
|
// Public event handlers for configuration properties
|
|
|
|
/**
|
|
* @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 {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.
|
|
*/
|
|
configTrigger: function(p_sType, p_aArgs, p_oMenu) {
|
|
|
|
var Event = YAHOO.util.Event;
|
|
var oTrigger = p_aArgs[0];
|
|
|
|
if(oTrigger) {
|
|
|
|
/*
|
|
If there is a current "trigger" - remove the event handlers
|
|
from that element(s) before assigning new ones
|
|
*/
|
|
|
|
if(this._oTrigger) {
|
|
|
|
this._removeEventHandlers();
|
|
|
|
}
|
|
|
|
this._oTrigger = oTrigger;
|
|
|
|
/*
|
|
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
|
|
);
|
|
|
|
/*
|
|
Assign a "click" event handler to the trigger element(s) for
|
|
Opera to prevent default browser behaviors.
|
|
*/
|
|
|
|
if(bOpera) {
|
|
|
|
Event.addListener(
|
|
oTrigger,
|
|
"click",
|
|
this._onTriggerClick,
|
|
this,
|
|
true
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
else {
|
|
|
|
this._removeEventHandlers();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}); // END YAHOO.extend
|
|
|
|
/**
|
|
* Creates an item for a context menu.
|
|
*
|
|
* @param {String} p_oObject String specifying the text of the context menu item.
|
|
* @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-
|
|
* one-html.html#ID-74680021">HTMLLIElement</a>} p_oObject Object specifying the
|
|
* <code><li></code> element of the context menu item.
|
|
* @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-
|
|
* one-html.html#ID-38450247">HTMLOptGroupElement</a>} p_oObject Object
|
|
* specifying the <code><optgroup></code> element of the context
|
|
* menu item.
|
|
* @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-
|
|
* one-html.html#ID-70901257">HTMLOptionElement</a>} p_oObject Object specifying
|
|
* the <code><option></code> 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.ContextMenuItem = function(p_oObject, p_oConfig) {
|
|
|
|
YAHOO.widget.ContextMenuItem.superclass.constructor.call(
|
|
this,
|
|
p_oObject,
|
|
p_oConfig
|
|
);
|
|
|
|
};
|
|
|
|
YAHOO.extend(YAHOO.widget.ContextMenuItem, YAHOO.widget.MenuItem, {
|
|
|
|
/**
|
|
* @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 {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-
|
|
* one-html.html#ID-74680021">HTMLLIElement</a>} p_oObject Object specifying the
|
|
* <code><li></code> element of the context menu item.
|
|
* @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-
|
|
* one-html.html#ID-38450247">HTMLOptGroupElement</a>} p_oObject Object
|
|
* specifying the <code><optgroup></code> element of the context
|
|
* menu item.
|
|
* @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-
|
|
* one-html.html#ID-70901257">HTMLOptionElement</a>} p_oObject Object specifying
|
|
* the <code><option></code> 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.
|
|
*/
|
|
init: function(p_oObject, p_oConfig) {
|
|
|
|
if(!this.SUBMENU_TYPE) {
|
|
|
|
this.SUBMENU_TYPE = YAHOO.widget.ContextMenu;
|
|
|
|
}
|
|
|
|
/*
|
|
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
|
|
|
|
/**
|
|
* @method toString
|
|
* @description Returns a string representing the context menu item.
|
|
* @return {String}
|
|
*/
|
|
toString: function() {
|
|
|
|
return ("MenuBarItem: " + this.cfg.getProperty("text"));
|
|
|
|
}
|
|
|
|
}); // END YAHOO.extend
|
|
|
|
/**
|
|
* Horizontal collection of items, each of which can contain a submenu.
|
|
*
|
|
* @param {String} p_oElement String specifying the id attribute of the
|
|
* <code><div></code> element of the menu bar.
|
|
* @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 bar.
|
|
* @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 bar.
|
|
* @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 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
|
|
* @namespace YAHOO.widget
|
|
*/
|
|
YAHOO.widget.MenuBar = function(p_oElement, p_oConfig) {
|
|
|
|
YAHOO.widget.MenuBar.superclass.constructor.call(
|
|
this,
|
|
p_oElement,
|
|
p_oConfig
|
|
);
|
|
|
|
};
|
|
|
|
YAHOO.extend(YAHOO.widget.MenuBar, YAHOO.widget.Menu, {
|
|
|
|
/**
|
|
* @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
|
|
* <code><div></code> element of the menu bar.
|
|
* @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 bar.
|
|
* @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 bar.
|
|
* @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 bar.
|
|
* @param {Object} p_oConfig Optional. Object literal specifying the
|
|
* configuration for the menu bar. See configuration class documentation for
|
|
* more details.
|
|
*/
|
|
init: function(p_oElement, p_oConfig) {
|
|
|
|
if(!this.ITEM_TYPE) {
|
|
|
|
this.ITEM_TYPE = YAHOO.widget.MenuBarItem;
|
|
|
|
}
|
|
|
|
// Call the init of the superclass (YAHOO.widget.Menu)
|
|
|
|
YAHOO.widget.MenuBar.superclass.init.call(this, p_oElement);
|
|
|
|
this.beforeInitEvent.fire(YAHOO.widget.MenuBar);
|
|
|
|
if(p_oConfig) {
|
|
|
|
this.cfg.applyConfig(p_oConfig, true);
|
|
|
|
}
|
|
|
|
this.initEvent.fire(YAHOO.widget.MenuBar);
|
|
|
|
},
|
|
|
|
// Constants
|
|
|
|
/**
|
|
* @property CSS_CLASS_NAME
|
|
* @description String representing the CSS class(es) to be applied to the menu
|
|
* bar's <code><div></code> element.
|
|
* @default "yuimenubar"
|
|
* @final
|
|
* @type String
|
|
*/
|
|
CSS_CLASS_NAME: "yuimenubar",
|
|
|
|
// Protected event handlers
|
|
|
|
/**
|
|
* @method _onKeyDown
|
|
* @description "keydown" Custom Event handler for the menu bar.
|
|
* @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.MenuBar} p_oMenuBar Object representing the menu bar
|
|
* that fired the event.
|
|
*/
|
|
_onKeyDown: function(p_sType, p_aArgs, p_oMenuBar) {
|
|
|
|
var Event = YAHOO.util.Event;
|
|
var oEvent = p_aArgs[0];
|
|
var oItem = p_aArgs[1];
|
|
var oItemCfg = oItem.cfg;
|
|
var oSubmenu;
|
|
|
|
switch(oEvent.keyCode) {
|
|
|
|
case 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);
|
|
|
|
break;
|
|
|
|
case 37: // Left arrow
|
|
case 39: // Right arrow
|
|
|
|
if(
|
|
oItem == this.activeItem &&
|
|
!oItemCfg.getProperty("selected")
|
|
) {
|
|
|
|
oItemCfg.setProperty("selected", true);
|
|
|
|
}
|
|
else {
|
|
|
|
var oNextItem = (oEvent.keyCode == 37) ?
|
|
oItem.getPreviousEnabledSibling() :
|
|
oItem.getNextEnabledSibling();
|
|
|
|
if(oNextItem) {
|
|
|
|
this.clearActiveItem();
|
|
|
|
oNextItem.cfg.setProperty("selected", true);
|
|
|
|
if(this.cfg.getProperty("autosubmenudisplay")) {
|
|
|
|
oSubmenu = oNextItem.cfg.getProperty("submenu");
|
|
|
|
if(oSubmenu) {
|
|
|
|
oSubmenu.show();
|
|
oSubmenu.activeItem.blur();
|
|
oSubmenu.activeItem = null;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
oNextItem.focus();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Event.preventDefault(oEvent);
|
|
|
|
break;
|
|
|
|
case 40: // Down arrow
|
|
|
|
if(this.activeItem != oItem) {
|
|
|
|
this.clearActiveItem();
|
|
|
|
oItemCfg.setProperty("selected", true);
|
|
oItem.focus();
|
|
|
|
}
|
|
|
|
oSubmenu = oItemCfg.getProperty("submenu");
|
|
|
|
if(oSubmenu) {
|
|
|
|
if(oSubmenu.cfg.getProperty("visible")) {
|
|
|
|
oSubmenu.setInitialSelection();
|
|
oSubmenu.setInitialFocus();
|
|
|
|
}
|
|
else {
|
|
|
|
oSubmenu.show();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Event.preventDefault(oEvent);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
},
|
|
|
|
/**
|
|
* @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) {
|
|
|
|
YAHOO.widget.MenuBar.superclass._onClick.call(
|
|
this,
|
|
p_sType,
|
|
p_aArgs,
|
|
p_oMenuBar
|
|
);
|
|
|
|
var oItem = p_aArgs[1];
|
|
|
|
if(oItem) {
|
|
|
|
var Event = YAHOO.util.Event;
|
|
var Dom = YAHOO.util.Dom;
|
|
|
|
var oEvent = p_aArgs[0];
|
|
var oTarget = Event.getTarget(oEvent);
|
|
|
|
var oActiveItem = this.activeItem;
|
|
var oConfig = this.cfg;
|
|
|
|
// Hide any other submenus that might be visible
|
|
|
|
if(oActiveItem && oActiveItem != oItem) {
|
|
|
|
this.clearActiveItem();
|
|
|
|
}
|
|
|
|
|
|
// Select and focus the current item
|
|
|
|
oItem.cfg.setProperty("selected", true);
|
|
oItem.focus();
|
|
|
|
|
|
// Show the submenu for the item
|
|
|
|
var oSubmenu = oItem.cfg.getProperty("submenu");
|
|
|
|
if(oSubmenu && oTarget != oItem.submenuIndicator) {
|
|
|
|
if(oSubmenu.cfg.getProperty("visible")) {
|
|
|
|
oSubmenu.hide();
|
|
|
|
}
|
|
else {
|
|
|
|
oSubmenu.show();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
// Public methods
|
|
|
|
/**
|
|
* @method toString
|
|
* @description Returns a string representing the menu bar.
|
|
* @return {String}
|
|
*/
|
|
toString: function() {
|
|
|
|
return ("MenuBar " + this.id);
|
|
|
|
},
|
|
|
|
/**
|
|
* @description Initializes the class's configurable properties which can be
|
|
* changed using the menu bar's Config object ("cfg").
|
|
* @method initDefaultConfig
|
|
*/
|
|
initDefaultConfig: function() {
|
|
|
|
YAHOO.widget.MenuBar.superclass.initDefaultConfig.call(this);
|
|
|
|
var oConfig = this.cfg;
|
|
|
|
// Add configuration properties
|
|
|
|
/*
|
|
Set the default value for the "position" configuration property
|
|
to "static" by re-adding the property.
|
|
*/
|
|
|
|
/**
|
|
* @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","bl"] by re-adding the property.
|
|
*/
|
|
|
|
/**
|
|
* @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.
|
|
*/
|
|
|
|
/**
|
|
* @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 }
|
|
);
|
|
|
|
}
|
|
|
|
}); // END YAHOO.extend
|
|
|
|
/**
|
|
* Creates an item for a menu bar.
|
|
*
|
|
* @param {String} p_oObject String specifying the text of the menu bar item.
|
|
* @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-
|
|
* one-html.html#ID-74680021">HTMLLIElement</a>} p_oObject Object specifying the
|
|
* <code><li></code> element of the menu bar item.
|
|
* @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-
|
|
* one-html.html#ID-38450247">HTMLOptGroupElement</a>} p_oObject Object
|
|
* specifying the <code><optgroup></code> element of the menu bar item.
|
|
* @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-
|
|
* one-html.html#ID-70901257">HTMLOptionElement</a>} p_oObject Object specifying
|
|
* the <code><option></code> 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.MenuItem
|
|
*/
|
|
YAHOO.widget.MenuBarItem = function(p_oObject, p_oConfig) {
|
|
|
|
YAHOO.widget.MenuBarItem.superclass.constructor.call(
|
|
this,
|
|
p_oObject,
|
|
p_oConfig
|
|
);
|
|
|
|
};
|
|
|
|
YAHOO.extend(YAHOO.widget.MenuBarItem, YAHOO.widget.MenuItem, {
|
|
|
|
/**
|
|
* @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 {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-
|
|
* one-html.html#ID-74680021">HTMLLIElement</a>} p_oObject Object specifying the
|
|
* <code><li></code> element of the menu bar item.
|
|
* @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-
|
|
* one-html.html#ID-38450247">HTMLOptGroupElement</a>} p_oObject Object
|
|
* specifying the <code><optgroup></code> element of the menu bar item.
|
|
* @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-
|
|
* one-html.html#ID-70901257">HTMLOptionElement</a>} p_oObject Object specifying
|
|
* the <code><option></code> 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.
|
|
*/
|
|
init: function(p_oObject, p_oConfig) {
|
|
|
|
if(!this.SUBMENU_TYPE) {
|
|
|
|
this.SUBMENU_TYPE = YAHOO.widget.Menu;
|
|
|
|
}
|
|
|
|
/*
|
|
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.MenuBarItem.superclass.init.call(this, p_oObject);
|
|
|
|
var oConfig = this.cfg;
|
|
|
|
if(p_oConfig) {
|
|
|
|
oConfig.applyConfig(p_oConfig, true);
|
|
|
|
}
|
|
|
|
oConfig.fireQueue();
|
|
|
|
},
|
|
|
|
// Constants
|
|
|
|
/**
|
|
* @property CSS_CLASS_NAME
|
|
* @description String representing the CSS class(es) to be applied to the
|
|
* <code><li></code> element of the menu bar item.
|
|
* @default "yuimenubaritem"
|
|
* @final
|
|
* @type String
|
|
*/
|
|
CSS_CLASS_NAME: "yuimenubaritem",
|
|
|
|
/**
|
|
* @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
|
|
*/
|
|
SUBMENU_INDICATOR_IMAGE_PATH: "nt/ic/ut/alt1/menuarodwn8_nrm_1.gif",
|
|
|
|
/**
|
|
* @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
|
|
*/
|
|
SELECTED_SUBMENU_INDICATOR_IMAGE_PATH: "nt/ic/ut/alt1/menuarodwn8_hov_1.gif",
|
|
|
|
/**
|
|
* @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
|
|
*/
|
|
DISABLED_SUBMENU_INDICATOR_IMAGE_PATH: "nt/ic/ut/alt1/menuarodwn8_dim_1.gif",
|
|
|
|
// Public methods
|
|
|
|
/**
|
|
* @method toString
|
|
* @description Returns a string representing the menu bar item.
|
|
* @return {String}
|
|
*/
|
|
toString: function() {
|
|
|
|
return ("MenuBarItem: " + this.cfg.getProperty("text"));
|
|
|
|
}
|
|
|
|
}); // END YAHOO.extend
|
|
|