fixed the resizable text area with IE problem fixed the ad space with IE problem merged the 7.2.0 and 7.1.4 change logs
5313 lines
No EOL
136 KiB
JavaScript
5313 lines
No EOL
136 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.11.3
|
|
*/
|
|
|
|
|
|
|
|
/**
|
|
* @class The superclass of all menu containers.
|
|
* @constructor
|
|
* @extends YAHOO.widget.Overlay
|
|
* @base YAHOO.widget.Overlay
|
|
* @param {String or HTMLElement} p_oElement String id or HTMLElement
|
|
* (either HTMLSelectElement or HTMLDivElement) of the source HTMLElement node.
|
|
* @param {Object} p_oConfig Optional. The configuration object literal
|
|
* containing the configuration for a MenuModule instance. See
|
|
* configuration class documentation for more details.
|
|
*/
|
|
YAHOO.widget.MenuModule = function(p_oElement, p_oConfig) {
|
|
|
|
YAHOO.widget.MenuModule.superclass.constructor.call(
|
|
this,
|
|
p_oElement,
|
|
p_oConfig
|
|
);
|
|
|
|
};
|
|
|
|
YAHOO.extend(YAHOO.widget.MenuModule, YAHOO.widget.Overlay);
|
|
|
|
// Private globals
|
|
|
|
/**
|
|
* Private global flag indicating if the DOM event handlers have been attached
|
|
* @private
|
|
* @type {Boolean}
|
|
*/
|
|
YAHOO.widget.MenuModule._initEventHandlers = true;
|
|
|
|
/**
|
|
* Private global collection of menus
|
|
* @private
|
|
* @type {Object}
|
|
*/
|
|
YAHOO.widget.MenuModule._menus = {};
|
|
|
|
/**
|
|
* Private global collection of menu items
|
|
* @private
|
|
* @type {Object}
|
|
*/
|
|
YAHOO.widget.MenuModule._menuItems = {};
|
|
|
|
/**
|
|
* Generic, global event handler for all of a menu's DOM-based events. This
|
|
* listens for events against the document object. If the target of a given
|
|
* event is a member of a menu or menu item's DOM, the instance's corresponding
|
|
* Custom Event is fired.
|
|
* @private
|
|
* @param {Event} p_oEvent Event object passed back by the event
|
|
* utility (YAHOO.util.Event).
|
|
*/
|
|
YAHOO.widget.MenuModule._onDOMEvent = function(p_oEvent) {
|
|
|
|
// Create references to the DOM and Event utilities
|
|
|
|
var Dom = YAHOO.util.Dom;
|
|
var Event = YAHOO.util.Event;
|
|
|
|
// The target node of the DOM event
|
|
|
|
var oTarget = Event.getTarget(p_oEvent);
|
|
|
|
// A reference to the root LI node of a menu item
|
|
|
|
var oMenuItemRootElement;
|
|
|
|
/**
|
|
* Finds the root DIV node of a menu and the root LI node of a menu item
|
|
* @private
|
|
* @param {HTMLElement} p_oElement An HTML element
|
|
*/
|
|
function getMenuRootElement(p_oElement) {
|
|
|
|
var oParentNode;
|
|
|
|
switch(p_oElement.tagName) {
|
|
|
|
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 == "DIV"
|
|
) {
|
|
|
|
return oParentNode;
|
|
|
|
}
|
|
else {
|
|
|
|
return p_oElement;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case "LI":
|
|
|
|
/*
|
|
Capture the root LI node of the menu item and allow
|
|
fall through to keep climbing up to find the item's parent
|
|
root DIV
|
|
*/
|
|
|
|
oMenuItemRootElement = p_oElement;
|
|
|
|
default:
|
|
|
|
oParentNode = p_oElement.parentNode;
|
|
|
|
if(oParentNode) {
|
|
|
|
return getMenuRootElement(oParentNode);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// The root DIV node of a menu
|
|
|
|
var oMenuRootElement = getMenuRootElement(oTarget);
|
|
|
|
if(oMenuRootElement && oMenuRootElement.id) {
|
|
|
|
var oMenuItem;
|
|
var oMenu = YAHOO.widget.MenuModule._menus[oMenuRootElement.id];
|
|
|
|
if(oMenuItemRootElement) {
|
|
|
|
var sYUIId = oMenuItemRootElement.getAttribute("yuiid");
|
|
|
|
if(sYUIId) {
|
|
|
|
oMenuItem = YAHOO.widget.MenuModule._menuItems[sYUIId];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
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];
|
|
|
|
switch(p_oEvent.type) {
|
|
|
|
case "mouseover":
|
|
|
|
if(
|
|
!oMenu._bFiredMouseOverEvent &&
|
|
(
|
|
oTarget == oMenu.element ||
|
|
Dom.isAncestor(oMenu.element, oTarget)
|
|
)
|
|
) {
|
|
|
|
oMenu.mouseOverEvent.fire(p_oEvent);
|
|
|
|
oMenu._bFiredMouseOverEvent = true;
|
|
oMenu._bFiredMouseOutEvent = false;
|
|
|
|
}
|
|
|
|
if(
|
|
oMenuItem &&
|
|
!oMenuItem._bFiredMouseOverEvent &&
|
|
(
|
|
oTarget == oMenuItem.element ||
|
|
Dom.isAncestor(oMenuItem.element, oTarget)
|
|
) &&
|
|
!oMenuItem.cfg.getProperty("disabled")
|
|
) {
|
|
|
|
oMenuItem.mouseOverEvent.fire(p_oEvent);
|
|
|
|
oMenuItem._bFiredMouseOverEvent = true;
|
|
oMenuItem._bFiredMouseOutEvent = false;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case "mouseout":
|
|
|
|
var oRelatedTarget = Event.getRelatedTarget(p_oEvent);
|
|
var bMovingToSubmenu = false;
|
|
|
|
if(oMenuItem) {
|
|
|
|
var oSubmenu = oMenuItem.cfg.getProperty("submenu");
|
|
|
|
if(
|
|
oSubmenu &&
|
|
(
|
|
oRelatedTarget == oSubmenu.element ||
|
|
Dom.isAncestor(oSubmenu.element, oRelatedTarget)
|
|
)
|
|
) {
|
|
|
|
bMovingToSubmenu = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if(
|
|
oMenuItem &&
|
|
!oMenuItem._bFiredMouseOutEvent &&
|
|
(
|
|
(
|
|
oRelatedTarget != oMenuItem.element &&
|
|
!Dom.isAncestor(
|
|
oMenuItem.element,
|
|
oRelatedTarget
|
|
)
|
|
) || bMovingToSubmenu
|
|
) &&
|
|
!oMenuItem.cfg.getProperty("disabled")
|
|
) {
|
|
|
|
// Fire the "mouseout" Custom Event for the item
|
|
|
|
oMenuItem.mouseOutEvent.fire(p_oEvent);
|
|
|
|
oMenuItem._bFiredMouseOutEvent = true;
|
|
oMenuItem._bFiredMouseOverEvent = false;
|
|
|
|
}
|
|
|
|
if(
|
|
!oMenu._bFiredMouseOutEvent &&
|
|
(
|
|
(
|
|
oRelatedTarget != oMenu.element &&
|
|
!Dom.isAncestor(oMenu.element, oRelatedTarget)
|
|
)
|
|
|| bMovingToSubmenu
|
|
)
|
|
) {
|
|
|
|
oMenu.mouseOutEvent.fire(p_oEvent);
|
|
|
|
oMenu._bFiredMouseOutEvent = true;
|
|
oMenu._bFiredMouseOverEvent = false;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
if(oMenuItem && !oMenuItem.cfg.getProperty("disabled")) {
|
|
|
|
oMenuItem[sCustomEventType].fire(p_oEvent);
|
|
|
|
}
|
|
|
|
oMenu[sCustomEventType].fire(p_oEvent);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
// Constants
|
|
|
|
/**
|
|
* Constant representing the CSS class(es) to be applied to the root
|
|
* HTMLDivElement of the MenuModule instance.
|
|
* @final
|
|
* @type String
|
|
*/
|
|
YAHOO.widget.MenuModule.prototype.CSS_CLASS_NAME = "yuimenu";
|
|
|
|
/**
|
|
* Constant representing the type of item to instantiate and add when parsing
|
|
* the child nodes (either HTMLLIElement, HTMLOptGroupElement or
|
|
* HTMLOptionElement) of a menu's DOM. The default
|
|
* is YAHOO.widget.MenuModuleItem.
|
|
* @final
|
|
* @type YAHOO.widget.MenuModuleItem
|
|
*/
|
|
YAHOO.widget.MenuModule.prototype.ITEM_TYPE = null;
|
|
|
|
/**
|
|
* Constant representing the tagname of the HTMLElement used to title
|
|
* a group of items.
|
|
* @final
|
|
* @type String
|
|
*/
|
|
YAHOO.widget.MenuModule.prototype.GROUP_TITLE_TAG_NAME = "H6";
|
|
|
|
// Private properties
|
|
|
|
/**
|
|
* The current state of a MenuModule instance's "mouseover" event
|
|
* @private
|
|
* @type {Boolean}
|
|
*/
|
|
YAHOO.widget.MenuModule.prototype._bFiredMouseOverEvent = false;
|
|
|
|
/**
|
|
* The current state of a MenuModule instance's "mouseout" event
|
|
* @private
|
|
* @type {Boolean}
|
|
*/
|
|
YAHOO.widget.MenuModule.prototype._bFiredMouseOutEvent = false;
|
|
|
|
/**
|
|
* Array of HTMLElements used to title groups of items.
|
|
* @private
|
|
* @type {Array}
|
|
*/
|
|
YAHOO.widget.MenuModule.prototype._aGroupTitleElements = null;
|
|
|
|
/**
|
|
* Multi-dimensional array of items.
|
|
* @private
|
|
* @type {Array}
|
|
*/
|
|
YAHOO.widget.MenuModule.prototype._aItemGroups = null;
|
|
|
|
/**
|
|
* An array of HTMLUListElements, each of which is the parent node of each
|
|
* items's HTMLLIElement node.
|
|
* @private
|
|
* @type {Array}
|
|
*/
|
|
YAHOO.widget.MenuModule.prototype._aListElements = null;
|
|
|
|
/**
|
|
* Reference to the Event utility singleton.
|
|
* @private
|
|
* @type {YAHOO.util.Event}
|
|
*/
|
|
YAHOO.widget.MenuModule.prototype._oEventUtil = YAHOO.util.Event;
|
|
|
|
/**
|
|
* Reference to the Dom utility singleton.
|
|
* @private
|
|
* @type {YAHOO.util.Dom}
|
|
*/
|
|
YAHOO.widget.MenuModule.prototype._oDom = YAHOO.util.Dom;
|
|
|
|
// Public properties
|
|
|
|
/**
|
|
* Reference to the item that has focus.
|
|
* @private
|
|
* @type {YAHOO.widget.MenuModuleItem}
|
|
*/
|
|
YAHOO.widget.MenuModule.prototype.activeItem = null;
|
|
|
|
/**
|
|
* Returns a MenuModule instance's parent object.
|
|
* @type {YAHOO.widget.MenuModuleItem}
|
|
*/
|
|
YAHOO.widget.MenuModule.prototype.parent = null;
|
|
|
|
/**
|
|
* Returns the HTMLElement (either HTMLSelectElement or HTMLDivElement)
|
|
* used create the MenuModule instance.
|
|
* @type {HTMLSelectElement/HTMLDivElement}
|
|
*/
|
|
YAHOO.widget.MenuModule.prototype.srcElement = null;
|
|
|
|
// Events
|
|
|
|
/**
|
|
* Fires when the mouse has entered a MenuModule instance. Passes back the
|
|
* DOM Event object as an argument.
|
|
* @type {YAHOO.util.CustomEvent}
|
|
* @see YAHOO.util.CustomEvent
|
|
*/
|
|
YAHOO.widget.MenuModule.prototype.mouseOverEvent = null;
|
|
|
|
/**
|
|
* Fires when the mouse has left a MenuModule instance. Passes back the DOM
|
|
* Event object as an argument.
|
|
* @type {YAHOO.util.CustomEvent}
|
|
* @see YAHOO.util.CustomEvent
|
|
*/
|
|
YAHOO.widget.MenuModule.prototype.mouseOutEvent = null;
|
|
|
|
/**
|
|
* Fires when the user mouses down on a MenuModule instance. Passes back the
|
|
* DOM Event object as an argument.
|
|
* @type {YAHOO.util.CustomEvent}
|
|
* @see YAHOO.util.CustomEvent
|
|
*/
|
|
YAHOO.widget.MenuModule.prototype.mouseDownEvent = null;
|
|
|
|
/**
|
|
* Fires when the user releases a mouse button while the mouse is over
|
|
* a MenuModule instance. Passes back the DOM Event object as an argument.
|
|
* @type {YAHOO.util.CustomEvent}
|
|
* @see YAHOO.util.CustomEvent
|
|
*/
|
|
YAHOO.widget.MenuModule.prototype.mouseUpEvent = null;
|
|
|
|
/**
|
|
* Fires when the user clicks the on a MenuModule instance. Passes back the
|
|
* DOM Event object as an argument.
|
|
* @type {YAHOO.util.CustomEvent}
|
|
* @see YAHOO.util.CustomEvent
|
|
*/
|
|
YAHOO.widget.MenuModule.prototype.clickEvent = null;
|
|
|
|
/**
|
|
* Fires when the user presses an alphanumeric key. Passes back the
|
|
* DOM Event object as an argument.
|
|
* @type {YAHOO.util.CustomEvent}
|
|
* @see YAHOO.util.CustomEvent
|
|
*/
|
|
YAHOO.widget.MenuModule.prototype.keyPressEvent = null;
|
|
|
|
/**
|
|
* Fires when the user presses a key. Passes back the DOM Event
|
|
* object as an argument.
|
|
* @type {YAHOO.util.CustomEvent}
|
|
* @see YAHOO.util.CustomEvent
|
|
*/
|
|
YAHOO.widget.MenuModule.prototype.keyDownEvent = null;
|
|
|
|
/**
|
|
* Fires when the user releases a key. Passes back the DOM Event
|
|
* object as an argument.
|
|
* @type {YAHOO.util.CustomEvent}
|
|
* @see YAHOO.util.CustomEvent
|
|
*/
|
|
YAHOO.widget.MenuModule.prototype.keyUpEvent = null;
|
|
|
|
/**
|
|
* The MenuModule class's initialization method. This method is automatically
|
|
* called by the constructor, and sets up all DOM references for
|
|
* pre-existing markup, and creates required markup if it is not already present.
|
|
* @param {String or HTMLElement} p_oElement String id or HTMLElement
|
|
* (either HTMLSelectElement or HTMLDivElement) of the source HTMLElement node.
|
|
* @param {Object} p_oConfig Optional. The configuration object literal
|
|
* containing the configuration for a MenuModule instance. See
|
|
* configuration class documentation for more details.
|
|
*/
|
|
YAHOO.widget.MenuModule.prototype.init = function(p_oElement, p_oConfig) {
|
|
|
|
var Dom = this._oDom;
|
|
var Event = this._oEventUtil;
|
|
|
|
if(!this.ITEM_TYPE) {
|
|
|
|
this.ITEM_TYPE = YAHOO.widget.MenuModuleItem;
|
|
|
|
}
|
|
|
|
this._aItemGroups = [];
|
|
this._aListElements = [];
|
|
this._aGroupTitleElements = [];
|
|
|
|
var oElement;
|
|
|
|
if(typeof p_oElement == "string") {
|
|
|
|
oElement = document.getElementById(p_oElement);
|
|
|
|
}
|
|
else if(p_oElement.tagName) {
|
|
|
|
oElement = p_oElement;
|
|
|
|
}
|
|
|
|
if(oElement) {
|
|
|
|
switch(oElement.tagName) {
|
|
|
|
case "DIV":
|
|
|
|
this.srcElement = oElement;
|
|
|
|
/*
|
|
Note: we don't pass the user config in here yet
|
|
because we only want it executed once, at the lowest
|
|
subclass level.
|
|
*/
|
|
|
|
YAHOO.widget.MenuModule.superclass.init.call(this, oElement);
|
|
|
|
this.beforeInitEvent.fire(YAHOO.widget.MenuModule);
|
|
|
|
/*
|
|
Populate the collection of item groups and item
|
|
group titles
|
|
*/
|
|
|
|
var oNode = this.body.firstChild;
|
|
var i = 0;
|
|
|
|
do {
|
|
|
|
switch(oNode.tagName) {
|
|
|
|
case this.GROUP_TITLE_TAG_NAME:
|
|
|
|
this._aGroupTitleElements[i] = oNode;
|
|
|
|
break;
|
|
|
|
case "UL":
|
|
|
|
this._aListElements[i] = oNode;
|
|
this._aItemGroups[i] = [];
|
|
i++;
|
|
|
|
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");
|
|
|
|
}
|
|
|
|
|
|
|
|
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
|
|
*/
|
|
|
|
var sId = 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.MenuModule.superclass.init.call(this, sId);
|
|
|
|
this.beforeInitEvent.fire(YAHOO.widget.MenuModule);
|
|
|
|
|
|
|
|
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.MenuModule.superclass.init.call(this, p_oElement);
|
|
|
|
this.beforeInitEvent.fire(YAHOO.widget.MenuModule);
|
|
|
|
|
|
|
|
}
|
|
|
|
if(this.element) {
|
|
|
|
var oEl = this.element;
|
|
var CustomEvent = YAHOO.util.CustomEvent;
|
|
|
|
Dom.addClass(oEl, this.CSS_CLASS_NAME);
|
|
|
|
// Assign DOM event handlers
|
|
|
|
if(YAHOO.widget.MenuModule._initEventHandlers) {
|
|
|
|
var oDoc = document;
|
|
var onDOMEvent = YAHOO.widget.MenuModule._onDOMEvent;
|
|
|
|
Event.addListener(oDoc, "mouseover", onDOMEvent);
|
|
Event.addListener(oDoc, "mouseout", onDOMEvent);
|
|
Event.addListener(oDoc, "mousedown", onDOMEvent);
|
|
Event.addListener(oDoc, "mouseup", onDOMEvent);
|
|
Event.addListener(oDoc, "click", onDOMEvent);
|
|
Event.addListener(oDoc, "keydown", onDOMEvent);
|
|
Event.addListener(oDoc, "keyup", onDOMEvent);
|
|
Event.addListener(oDoc, "keypress", onDOMEvent);
|
|
|
|
YAHOO.widget.MenuModule._initEventHandlers = false;
|
|
|
|
}
|
|
|
|
// Create custom events
|
|
|
|
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);
|
|
|
|
// Subscribe to Custom Events
|
|
|
|
this.initEvent.subscribe(this._onInit, this, true);
|
|
this.beforeRenderEvent.subscribe(this._onBeforeRender, this, true);
|
|
this.renderEvent.subscribe(this._onRender, this, true);
|
|
this.showEvent.subscribe(this._onShow, this, true);
|
|
this.beforeHideEvent.subscribe(this._onBeforeHide, this, true);
|
|
|
|
if(p_oConfig) {
|
|
|
|
this.cfg.applyConfig(p_oConfig, true);
|
|
|
|
}
|
|
|
|
this.cfg.queueProperty("visible", false);
|
|
|
|
if(this.srcElement) {
|
|
|
|
this._initSubTree();
|
|
|
|
}
|
|
|
|
YAHOO.widget.MenuModule._menus[oEl.id] = this;
|
|
|
|
}
|
|
|
|
this.initEvent.fire(YAHOO.widget.MenuModule);
|
|
|
|
};
|
|
|
|
// Private methods
|
|
|
|
/**
|
|
* Iterates the source element's childNodes collection and uses the child
|
|
* nodes to instantiate MenuModule and MenuModuleItem instances.
|
|
* @private
|
|
*/
|
|
YAHOO.widget.MenuModule.prototype._initSubTree = function() {
|
|
|
|
var oNode;
|
|
|
|
|
|
switch(this.srcElement.tagName) {
|
|
|
|
case "DIV":
|
|
|
|
if(this._aListElements.length > 0) {
|
|
|
|
|
|
var i = this._aListElements.length - 1;
|
|
|
|
do {
|
|
|
|
oNode = this._aListElements[i].firstChild;
|
|
|
|
|
|
do {
|
|
|
|
switch(oNode.tagName) {
|
|
|
|
case "LI":
|
|
|
|
|
|
this.addItem(new this.ITEM_TYPE(oNode), i);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
while((oNode = oNode.nextSibling));
|
|
|
|
}
|
|
while(i--);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case "SELECT":
|
|
|
|
|
|
oNode = this.srcElement.firstChild;
|
|
|
|
do {
|
|
|
|
switch(oNode.tagName) {
|
|
|
|
case "OPTGROUP":
|
|
case "OPTION":
|
|
|
|
|
|
this.addItem(new this.ITEM_TYPE(oNode));
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
while((oNode = oNode.nextSibling));
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
/**
|
|
* Returns the first enabled item in a menu instance.
|
|
* @return Returns a MenuModuleItem instance.
|
|
* @type YAHOO.widget.MenuModuleItem
|
|
* @private
|
|
*/
|
|
YAHOO.widget.MenuModule.prototype._getFirstEnabledItem = function() {
|
|
|
|
var nGroups = this._aItemGroups.length;
|
|
var oItem;
|
|
var aItemGroup;
|
|
|
|
for(var i=0; i<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;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
/**
|
|
* Determines if the value is one of the supported positions.
|
|
* @private
|
|
* @param {Object} p_sPosition The object to be evaluated.
|
|
* @return Returns true if the position is supported.
|
|
* @type Boolean
|
|
*/
|
|
YAHOO.widget.MenuModule.prototype._checkPosition = function(p_sPosition) {
|
|
|
|
if(typeof p_sPosition == "string") {
|
|
|
|
var sPosition = p_sPosition.toLowerCase();
|
|
|
|
return ("dynamic,static".indexOf(sPosition) != -1);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
/**
|
|
* Adds an item to a group.
|
|
* @private
|
|
* @param {Number} p_nGroupIndex Number indicating the group to which
|
|
* the item belongs.
|
|
* @param {YAHOO.widget.MenuModuleItem} p_oItem The item to be added.
|
|
* @param {Number} p_nItemIndex Optional. Index at which the item
|
|
* should be added.
|
|
* @return The item that was added.
|
|
* @type YAHOO.widget.MenuModuleItem
|
|
*/
|
|
YAHOO.widget.MenuModule.prototype._addItemToGroup =
|
|
|
|
function(p_nGroupIndex, p_oItem, p_nItemIndex) {
|
|
|
|
var Dom = this._oDom;
|
|
var oItem;
|
|
|
|
if(p_oItem instanceof this.ITEM_TYPE) {
|
|
|
|
oItem = p_oItem;
|
|
|
|
}
|
|
else if(typeof p_oItem == "string") {
|
|
|
|
oItem = new this.ITEM_TYPE(p_oItem);
|
|
|
|
}
|
|
|
|
if(oItem) {
|
|
|
|
var sYUIId = Dom.generateId();
|
|
|
|
oItem.element.setAttribute("yuiid", sYUIId);
|
|
|
|
YAHOO.widget.MenuModule._menuItems[sYUIId] = 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
|
|
* @param {p_aArray} An array
|
|
* @param {p_nStartIndex} The index to start searching
|
|
* the array
|
|
* @ignore
|
|
* @return Returns an item in an array
|
|
* @type Object
|
|
*/
|
|
function getNextItemSibling(p_aArray, p_nStartIndex) {
|
|
|
|
return (
|
|
p_aArray[p_nStartIndex] ||
|
|
getNextItemSibling(
|
|
p_aArray,
|
|
(p_nStartIndex+1)
|
|
)
|
|
);
|
|
|
|
}
|
|
|
|
|
|
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._configureItemSubmenuModule(oGroupItem);
|
|
|
|
this._updateItemProperties(nGroupIndex);
|
|
|
|
|
|
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._configureItemSubmenuModule(oGroupItem);
|
|
|
|
if(nItemIndex === 0) {
|
|
|
|
Dom.addClass(oGroupItem.element, "first-of-type");
|
|
|
|
}
|
|
|
|
|
|
return oGroupItem;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
/**
|
|
* Removes an item from a group by index.
|
|
* @private
|
|
* @param {Number} p_nGroupIndex Number indicating the group to which
|
|
* the item belongs.
|
|
* @param {Number} p_nItemIndex Number indicating the index of the item to
|
|
* be removed.
|
|
* @return The item that was removed.
|
|
* @type YAHOO.widget.MenuModuleItem
|
|
*/
|
|
YAHOO.widget.MenuModule.prototype._removeItemFromGroupByIndex =
|
|
|
|
function(p_nGroupIndex, p_nItemIndex) {
|
|
|
|
var nGroupIndex = typeof p_nGroupIndex == "number" ? p_nGroupIndex : 0;
|
|
var aGroup = this._getItemGroup(nGroupIndex);
|
|
|
|
if(aGroup) {
|
|
|
|
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) {
|
|
|
|
this._oDom.addClass(oUL, "first-of-type");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
// Return a reference to the item that was removed
|
|
|
|
return oItem;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
/**
|
|
* Removes a item from a group by reference.
|
|
* @private
|
|
* @param {Number} p_nGroupIndex Number indicating the group to which
|
|
* the item belongs.
|
|
* @param {YAHOO.widget.MenuModuleItem} p_oItem The item to be removed.
|
|
* @return The item that was removed.
|
|
* @type YAHOO.widget.MenuModuleItem
|
|
*/
|
|
YAHOO.widget.MenuModule.prototype._removeItemFromGroupByValue =
|
|
|
|
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
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
/**
|
|
* Updates the index, groupindex, and className properties of the items
|
|
* in the specified group.
|
|
* @private
|
|
* @param {Number} p_nGroupIndex Number indicating the group of items to update.
|
|
*/
|
|
YAHOO.widget.MenuModule.prototype._updateItemProperties =
|
|
|
|
function(p_nGroupIndex) {
|
|
|
|
var aGroup = this._getItemGroup(p_nGroupIndex);
|
|
var nItems = aGroup.length;
|
|
|
|
if(nItems > 0) {
|
|
|
|
var Dom = this._oDom;
|
|
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");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
/**
|
|
* Creates a new item group (array) and it's associated HTMLUlElement node
|
|
* @private
|
|
* @param {Number} p_nIndex Number indicating the group to create.
|
|
* @return An item group.
|
|
* @type Array
|
|
*/
|
|
YAHOO.widget.MenuModule.prototype._createItemGroup = function(p_nIndex) {
|
|
|
|
if(!this._aItemGroups[p_nIndex]) {
|
|
|
|
this._aItemGroups[p_nIndex] = [];
|
|
|
|
var oUL = document.createElement("ul");
|
|
|
|
this._aListElements[p_nIndex] = oUL;
|
|
|
|
return this._aItemGroups[p_nIndex];
|
|
|
|
}
|
|
|
|
};
|
|
|
|
/**
|
|
* Returns the item group at the specified index.
|
|
* @private
|
|
* @param {Number} p_nIndex Number indicating the index of the item group to
|
|
* be retrieved.
|
|
* @return An array of items.
|
|
* @type Array
|
|
*/
|
|
YAHOO.widget.MenuModule.prototype._getItemGroup = function(p_nIndex) {
|
|
|
|
var nIndex = ((typeof p_nIndex == "number") ? p_nIndex : 0);
|
|
|
|
return this._aItemGroups[nIndex];
|
|
|
|
};
|
|
|
|
/**
|
|
* Subscribe's a MenuModule instance to it's parent MenuModule instance's events.
|
|
* @private
|
|
* @param {YAHOO.widget.MenuModuleItem} p_oItem The item to listen
|
|
* for events on.
|
|
*/
|
|
YAHOO.widget.MenuModule.prototype._configureItemSubmenuModule =
|
|
|
|
function(p_oItem) {
|
|
|
|
var oSubmenu = p_oItem.cfg.getProperty("submenu");
|
|
|
|
if(oSubmenu) {
|
|
|
|
/*
|
|
Listen for configuration changes to the parent MenuModule
|
|
instance so they they can be applied to the submenu.
|
|
*/
|
|
|
|
this.cfg.configChangedEvent.subscribe(
|
|
this._onParentMenuModuleConfigChange,
|
|
oSubmenu,
|
|
true
|
|
);
|
|
|
|
this.renderEvent.subscribe(
|
|
this._onParentMenuModuleRender,
|
|
oSubmenu,
|
|
true
|
|
);
|
|
|
|
oSubmenu.beforeShowEvent.subscribe(
|
|
this._onSubmenuBeforeShow,
|
|
oSubmenu,
|
|
true
|
|
);
|
|
|
|
oSubmenu.showEvent.subscribe(this._onSubmenuShow, oSubmenu, true);
|
|
|
|
oSubmenu.hideEvent.subscribe(this._onSubmenuHide, oSubmenu, true);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
/**
|
|
* Subscribes a MenuModule instance to the specified item's Custom Events.
|
|
* @private
|
|
* @param {YAHOO.widget.MenuModuleItem} p_oItem The item to listen for events on.
|
|
*/
|
|
YAHOO.widget.MenuModule.prototype._subscribeToItemEvents = function(p_oItem) {
|
|
|
|
var aArguments = [this, p_oItem];
|
|
|
|
p_oItem.focusEvent.subscribe(this._onItemFocus, aArguments);
|
|
|
|
p_oItem.blurEvent.subscribe(this._onItemBlur, aArguments);
|
|
|
|
p_oItem.cfg.configChangedEvent.subscribe(
|
|
this._onItemConfigChange,
|
|
aArguments
|
|
);
|
|
|
|
};
|
|
|
|
/**
|
|
* Returns the offset width of a MenuModule instance.
|
|
* @private
|
|
*/
|
|
YAHOO.widget.MenuModule.prototype._getOffsetWidth = function() {
|
|
|
|
var oClone = this.element.cloneNode(true);
|
|
|
|
this._oDom.setStyle(oClone, "width", "");
|
|
|
|
document.body.appendChild(oClone);
|
|
|
|
var sWidth = oClone.offsetWidth;
|
|
|
|
document.body.removeChild(oClone);
|
|
|
|
return sWidth;
|
|
|
|
};
|
|
|
|
// Private Custom Event handlers
|
|
|
|
/**
|
|
* "init" Custom Event handler for a MenuModule instance.
|
|
* @private
|
|
* @param {String} p_sType The name of the event that was fired.
|
|
* @param {Array} p_aArgs Collection of arguments sent when the event
|
|
* was fired.
|
|
* @param {YAHOO.widget.MenuModule} p_oMenuModule The MenuModule instance that
|
|
* fired the event.
|
|
*/
|
|
YAHOO.widget.MenuModule.prototype._onInit =
|
|
|
|
function(p_sType, p_aArgs, p_oMenuModule) {
|
|
|
|
var sCSSPosition = (this.cfg.getProperty("position") == "static") ?
|
|
"static" : "absolute";
|
|
|
|
this._oDom.setStyle(this.element, "position", sCSSPosition);
|
|
|
|
};
|
|
|
|
/**
|
|
* "beforerender" Custom Event handler for a MenuModule instance. Appends all
|
|
* of the HTMLUListElement (<UL<s) nodes (and their child
|
|
* HTMLLIElement (<LI<)) nodes and their accompanying title nodes to
|
|
* the body of the MenuModule instance.
|
|
* @private
|
|
* @param {String} p_sType The name of the event that was fired.
|
|
* @param {Array} p_aArgs Collection of arguments sent when the event
|
|
* was fired.
|
|
* @param {YAHOO.widget.MenuModule} p_oMenuModule The MenuModule instance that
|
|
* fired the event.
|
|
*/
|
|
YAHOO.widget.MenuModule.prototype._onBeforeRender =
|
|
|
|
function(p_sType, p_aArgs, p_oMenuModule) {
|
|
|
|
var Dom = this._oDom;
|
|
var oConfig = this.cfg;
|
|
var oEl = this.element;
|
|
var nListElements = this._aListElements.length;
|
|
|
|
|
|
if(oConfig.getProperty("position") == "static") {
|
|
|
|
oConfig.queueProperty("iframe", false);
|
|
oConfig.queueProperty("visible", true);
|
|
|
|
}
|
|
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
/**
|
|
* "render" Custom Event handler for a MenuModule instance.
|
|
* @private
|
|
* @param {String} p_sType The name of the event that was fired.
|
|
* @param {Array} p_aArgs Collection of arguments sent when the event
|
|
* was fired.
|
|
* @param {YAHOO.widget.MenuModule} p_oMenuModule The MenuModule instance that
|
|
* fired the event.
|
|
*/
|
|
YAHOO.widget.MenuModule.prototype._onRender =
|
|
|
|
function(p_sType, p_aArgs, p_oMenuModule) {
|
|
|
|
if(this.cfg.getProperty("position") == "dynamic") {
|
|
|
|
var sWidth = this.element.parentNode.tagName == "BODY" ?
|
|
this.element.offsetWidth : this._getOffsetWidth();
|
|
|
|
this.cfg.setProperty("width", (sWidth + "px"));
|
|
|
|
}
|
|
|
|
};
|
|
|
|
/**
|
|
* "show" Custom Event handler for a MenuModule instance.
|
|
* @private
|
|
* @param {String} p_sType The name of the event that was fired.
|
|
* @param {Array} p_aArgs Collection of arguments sent when the event
|
|
* was fired.
|
|
* @param {YAHOO.widget.MenuModule} p_oMenuModule The MenuModule instance that
|
|
* fired the event.
|
|
*/
|
|
YAHOO.widget.MenuModule.prototype._onShow =
|
|
|
|
function(p_sType, p_aArgs, p_oMenuModule) {
|
|
|
|
/*
|
|
Setting focus to an item in the newly visible submenu alerts the
|
|
contents of the submenu to the screen reader.
|
|
*/
|
|
|
|
this.setInitialFocus();
|
|
|
|
};
|
|
|
|
/**
|
|
* "hide" Custom Event handler for a MenuModule instance.
|
|
* @private
|
|
* @param {String} p_sType The name of the event that was fired.
|
|
* @param {Array} p_aArgs Collection of arguments sent when the event
|
|
* was fired.
|
|
* @param {YAHOO.widget.MenuModule} p_oMenuModule The MenuModule instance that
|
|
* fired the event.
|
|
*/
|
|
YAHOO.widget.MenuModule.prototype._onBeforeHide =
|
|
|
|
function(p_sType, p_aArgs, p_oMenuModule) {
|
|
|
|
var oActiveItem = this.activeItem;
|
|
|
|
if(oActiveItem) {
|
|
|
|
oActiveItem.blur();
|
|
|
|
if(oActiveItem.cfg.getProperty("selected")) {
|
|
|
|
oActiveItem.cfg.setProperty("selected", false);
|
|
|
|
}
|
|
|
|
var oSubmenu = oActiveItem.cfg.getProperty("submenu");
|
|
|
|
if(oSubmenu && oSubmenu.cfg.getProperty("visible")) {
|
|
|
|
oSubmenu.hide();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
/**
|
|
* "configchange" Custom Event handler for a submenu.
|
|
* @private
|
|
* @param {String} p_sType The name of the event that was fired.
|
|
* @param {Array} p_aArgs Collection of arguments sent when the event
|
|
* was fired.
|
|
* @param {YAHOO.widget.MenuModule} p_oSubmenu The submenu that subscribed
|
|
* to the event.
|
|
*/
|
|
YAHOO.widget.MenuModule.prototype._onParentMenuModuleConfigChange =
|
|
|
|
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":
|
|
|
|
p_oSubmenu.cfg.setProperty(sPropertyName, oPropertyValue);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
/**
|
|
* "render" Custom Event handler for a MenuModule instance. Renders a
|
|
* submenu in response to the firing of it's parent's "render" event.
|
|
* @private
|
|
* @param {String} p_sType The name of the event that was fired.
|
|
* @param {Array} p_aArgs Collection of arguments sent when the event
|
|
* was fired.
|
|
* @param {YAHOO.widget.MenuModule} p_oSubmenu The submenu that subscribed
|
|
* to the event.
|
|
*/
|
|
YAHOO.widget.MenuModule.prototype._onParentMenuModuleRender =
|
|
|
|
function(p_sType, p_aArgs, p_oSubmenu) {
|
|
|
|
/*
|
|
Set the "constraintoviewport" configuration
|
|
property to match the parent MenuModule
|
|
*/
|
|
|
|
var oParentMenu = p_oSubmenu.parent.parent;
|
|
|
|
var oConfig = {
|
|
|
|
constraintoviewport:
|
|
oParentMenu.cfg.getProperty("constraintoviewport"),
|
|
|
|
xy: [0,0]
|
|
|
|
};
|
|
|
|
/*
|
|
Only sync the "iframe" configuration property if the parent
|
|
MenuModule instance's position is of the same value
|
|
*/
|
|
|
|
if(
|
|
this.cfg.getProperty("position") ==
|
|
oParentMenu.cfg.getProperty("position")
|
|
) {
|
|
|
|
oConfig.iframe = oParentMenu.cfg.getProperty("iframe");
|
|
|
|
}
|
|
|
|
|
|
p_oSubmenu.cfg.applyConfig(oConfig);
|
|
|
|
|
|
if(this._oDom.inDocument(this.element)) {
|
|
|
|
this.render();
|
|
|
|
}
|
|
else {
|
|
|
|
this.render(this.parent.element);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
/**
|
|
* "beforeshow" Custom Event handler for a submenu.
|
|
* @private
|
|
* @param {String} p_sType The name of the event that was fired.
|
|
* @param {Array} p_aArgs Collection of arguments sent when the event
|
|
* was fired.
|
|
* @param {YAHOO.widget.MenuModule} p_oSubmenu The submenu that fired
|
|
* the event.
|
|
*/
|
|
YAHOO.widget.MenuModule.prototype._onSubmenuBeforeShow =
|
|
|
|
function(p_sType, p_aArgs, p_oSubmenu) {
|
|
|
|
var oParent = this.parent;
|
|
var aAlignment = oParent.parent.cfg.getProperty("submenualignment");
|
|
|
|
this.cfg.setProperty(
|
|
"context",
|
|
[
|
|
oParent.element,
|
|
aAlignment[0],
|
|
aAlignment[1]
|
|
]
|
|
);
|
|
|
|
oParent.submenuIndicator.alt =
|
|
oParent.EXPANDED_SUBMENU_INDICATOR_ALT_TEXT;
|
|
|
|
};
|
|
|
|
/**
|
|
* "show" Custom Event handler for a submenu.
|
|
* @private
|
|
* @param {String} p_sType The name of the event that was fired.
|
|
* @param {Array} p_aArgs Collection of arguments sent when the event
|
|
* was fired.
|
|
* @param {YAHOO.widget.MenuModule} p_oSubmenu The submenu that fired
|
|
* the event.
|
|
*/
|
|
YAHOO.widget.MenuModule.prototype._onSubmenuShow =
|
|
|
|
function(p_sType, p_aArgs, p_oSubmenu) {
|
|
|
|
var oParent = this.parent;
|
|
|
|
oParent.submenuIndicator.alt =
|
|
oParent.EXPANDED_SUBMENU_INDICATOR_ALT_TEXT;
|
|
|
|
};
|
|
|
|
/**
|
|
* "hide" Custom Event handler for a submenu.
|
|
* @private
|
|
* @param {String} p_sType The name of the event that was fired.
|
|
* @param {Array} p_aArgs Collection of arguments sent when the event
|
|
* was fired.
|
|
* @param {YAHOO.widget.MenuModule} p_oSubmenu The submenu that fired
|
|
* the event.
|
|
*/
|
|
YAHOO.widget.MenuModule.prototype._onSubmenuHide =
|
|
|
|
function(p_sType, p_aArgs, p_oSubmenu) {
|
|
|
|
var oParent = this.parent;
|
|
|
|
if(oParent.parent.cfg.getProperty("visible")) {
|
|
|
|
oParent.cfg.setProperty("selected", false);
|
|
|
|
oParent.focus();
|
|
|
|
}
|
|
|
|
oParent.submenuIndicator.alt =
|
|
oParent.COLLAPSED_SUBMENU_INDICATOR_ALT_TEXT;
|
|
|
|
};
|
|
|
|
/**
|
|
* "focus" YAHOO.util.CustomEvent handler for a MenuModule instance's items.
|
|
* @private
|
|
* @param {String} p_sType The name of the event that was fired.
|
|
* @param {Array} p_aArgs Collection of arguments sent when the event
|
|
* was fired.
|
|
* @param {Array} p_aObjects Array containing the current MenuModule instance
|
|
* and the item that fired the event.
|
|
*/
|
|
YAHOO.widget.MenuModule.prototype._onItemFocus =
|
|
|
|
function(p_sType, p_aArgs, p_aObjects) {
|
|
|
|
var me = p_aObjects[0];
|
|
var oItem = p_aObjects[1];
|
|
|
|
me.activeItem = oItem;
|
|
|
|
};
|
|
|
|
/**
|
|
* "blur" YAHOO.util.CustomEvent handler for a MenuModule instance's items.
|
|
* @private
|
|
* @param {String} p_sType The name of the event that was fired.
|
|
* @param {Array} p_aArgs Collection of arguments sent when the event
|
|
* was fired.
|
|
* @param {Array} p_aObjects Array containing the current MenuModule instance
|
|
* and the item that fired the event.
|
|
*/
|
|
YAHOO.widget.MenuModule.prototype._onItemBlur =
|
|
|
|
function(p_sType, p_aArgs, p_aObjects) {
|
|
|
|
var me = p_aObjects[0];
|
|
var oItem = p_aObjects[1];
|
|
var oSubmenu = oItem.cfg.getProperty("submenu");
|
|
|
|
if(!oSubmenu || (oSubmenu && !oSubmenu.cfg.getProperty("visible"))) {
|
|
|
|
me.activeItem = null;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
/**
|
|
* "configchange" YAHOO.util.CustomEvent handler for the MenuModule
|
|
* instance's items.
|
|
* @private
|
|
* @param {String} p_sType The name of the event that was fired.
|
|
* @param {Array} p_aArgs Collection of arguments sent when the
|
|
* event was fired.
|
|
* @param {Array} p_aObjects Array containing the current MenuModule instance
|
|
* and the item that fired the event.
|
|
*/
|
|
YAHOO.widget.MenuModule.prototype._onItemConfigChange =
|
|
|
|
function(p_sType, p_aArgs, p_aObjects) {
|
|
|
|
var me = p_aObjects[0];
|
|
var sProperty = p_aArgs[0][0];
|
|
var oItem = p_aObjects[1];
|
|
|
|
switch(sProperty) {
|
|
|
|
case "submenu":
|
|
|
|
var oSubmenu = p_aArgs[0][1];
|
|
|
|
if(oSubmenu) {
|
|
|
|
me._configureItemSubmenuModule(oItem);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case "text":
|
|
case "helptext":
|
|
|
|
/*
|
|
A change to an item's "text" or "helptext"
|
|
configuration properties requires the width of the parent
|
|
MenuModule instance to be recalculated.
|
|
*/
|
|
|
|
if(me.element.style.width) {
|
|
|
|
var sWidth = me._getOffsetWidth() + "px";
|
|
|
|
me._oDom.setStyle(me.element, "width", sWidth);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
/**
|
|
* The default event handler executed when the moveEvent is fired, if the
|
|
* "constraintoviewport" configuration property is set to true.
|
|
*/
|
|
YAHOO.widget.MenuModule.prototype.enforceConstraints =
|
|
|
|
function(type, args, obj) {
|
|
|
|
var Dom = this._oDom;
|
|
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);
|
|
|
|
};
|
|
|
|
// Event handlers for configuration properties
|
|
|
|
/**
|
|
* Event handler for when the "position" configuration property of a
|
|
* MenuModule changes.
|
|
* @param {String} p_sType The name of the event that was fired.
|
|
* @param {Array} p_aArgs Collection of arguments sent when the event
|
|
* was fired.
|
|
* @param {YAHOO.widget.MenuModule} p_oMenuModule The MenuModule instance fired
|
|
* the event.
|
|
*/
|
|
YAHOO.widget.MenuModule.prototype.configPosition =
|
|
|
|
function(p_sType, p_aArgs, p_oMenuModule) {
|
|
|
|
var sCSSPosition = p_aArgs[0] == "static" ? "static" : "absolute";
|
|
|
|
this._oDom.setStyle(this.element, "position", sCSSPosition);
|
|
|
|
};
|
|
|
|
/**
|
|
* Event handler for when the "iframe" configuration property of a
|
|
* MenuModule changes.
|
|
* @param {String} p_sType The name of the event that was fired.
|
|
* @param {Array} p_aArgs Collection of arguments sent when the event
|
|
* was fired.
|
|
* @param {YAHOO.widget.MenuModule} p_oMenuModule The MenuModule instance fired
|
|
* the event.
|
|
* @see YAHOO.widget.Overlay#configIframe
|
|
*/
|
|
YAHOO.widget.MenuModule.prototype.configIframe =
|
|
|
|
function(p_sType, p_aArgs, p_oMenuModule) {
|
|
|
|
if(this.cfg.getProperty("position") == "dynamic") {
|
|
|
|
YAHOO.widget.MenuModule.superclass.configIframe.call(
|
|
this,
|
|
p_sType,
|
|
p_aArgs,
|
|
p_oMenuModule
|
|
);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
// Public methods
|
|
|
|
YAHOO.widget.MenuModule.prototype.toString = function() {
|
|
|
|
return ("Menu " + this.id);
|
|
|
|
};
|
|
|
|
/**
|
|
* Sets the title of a group of items.
|
|
* @param {String} p_sGroupTitle The title of the group.
|
|
* @param {Number} p_nGroupIndex Optional. Number indicating the group to which
|
|
* the title belongs.
|
|
*/
|
|
YAHOO.widget.MenuModule.prototype.setItemGroupTitle =
|
|
|
|
function(p_sGroupTitle, p_nGroupIndex) {
|
|
|
|
if(typeof p_sGroupTitle == "string" && p_sGroupTitle.length > 0) {
|
|
|
|
var Dom = this._oDom;
|
|
|
|
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"
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
/**
|
|
* Appends the specified item to a MenuModule instance.
|
|
* @param {YAHOO.widget.MenuModuleItem} p_oItem The item to be added.
|
|
* @param {Number} p_nGroupIndex Optional. Number indicating the group to which
|
|
* the item belongs.
|
|
* @return The item that was added to the MenuModule.
|
|
* @type YAHOO.widget.MenuModuleItem
|
|
*/
|
|
YAHOO.widget.MenuModule.prototype.addItem = function(p_oItem, p_nGroupIndex) {
|
|
|
|
if(p_oItem) {
|
|
|
|
return this._addItemToGroup(p_nGroupIndex, p_oItem);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
/**
|
|
* Inserts an item into a MenuModule instance at the specified index.
|
|
* @param {YAHOO.widget.MenuModuleItem} p_oItem The item to be inserted.
|
|
* @param {Number} p_nItemIndex Number indicating the ordinal position
|
|
* at which the item should be added.
|
|
* @param {Number} p_nGroupIndex Optional. Number indicating the group to which
|
|
* the item belongs.
|
|
* @return The item that was inserted into the MenuModule.
|
|
* @type YAHOO.widget.MenuModuleItem
|
|
*/
|
|
YAHOO.widget.MenuModule.prototype.insertItem =
|
|
|
|
function(p_oItem, p_nItemIndex, p_nGroupIndex) {
|
|
|
|
if(p_oItem) {
|
|
|
|
return this._addItemToGroup(p_nGroupIndex, p_oItem, p_nItemIndex);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
/**
|
|
* Removes the specified item from a MenuModule instance.
|
|
* @param {YAHOO.widget.MenuModuleItem/Number} p_oObject The item or index of
|
|
* the item to be removed.
|
|
* @param {Number} p_nGroupIndex Optional. Number indicating the group to which
|
|
* the item belongs.
|
|
* @return The item that was removed from the MenuModule.
|
|
* @type YAHOO.widget.MenuModuleItem
|
|
*/
|
|
YAHOO.widget.MenuModule.prototype.removeItem =
|
|
|
|
function(p_oObject, p_nGroupIndex) {
|
|
|
|
if(typeof p_oObject != "undefined") {
|
|
|
|
var oItem;
|
|
|
|
if(p_oObject instanceof YAHOO.widget.MenuModuleItem) {
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
/**
|
|
* Returns a multi-dimensional array of all of a MenuModule's items.
|
|
* @return An array of items.
|
|
* @type Array
|
|
*/
|
|
YAHOO.widget.MenuModule.prototype.getItemGroups = function() {
|
|
|
|
return this._aItemGroups;
|
|
|
|
};
|
|
|
|
/**
|
|
* Returns the item at the specified index.
|
|
* @param {Number} p_nItemIndex Number indicating the ordinal position of the
|
|
* item to be retrieved.
|
|
* @param {Number} p_nGroupIndex Optional. Number indicating the group to which
|
|
* the item belongs.
|
|
* @return An item.
|
|
* @type YAHOO.widget.MenuModuleItem
|
|
*/
|
|
YAHOO.widget.MenuModule.prototype.getItem =
|
|
|
|
function(p_nItemIndex, p_nGroupIndex) {
|
|
|
|
if(typeof p_nItemIndex == "number") {
|
|
|
|
var aGroup = this._getItemGroup(p_nGroupIndex);
|
|
|
|
if(aGroup) {
|
|
|
|
return aGroup[p_nItemIndex];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
/**
|
|
* Removes the MenuModule instance's element from the DOM and sets all child
|
|
* elements to null.
|
|
*/
|
|
YAHOO.widget.MenuModule.prototype.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.MenuModule.superclass.destroy.call(this);
|
|
|
|
|
|
};
|
|
|
|
/**
|
|
* Sets focus to a MenuModule instance's first enabled item.
|
|
*/
|
|
YAHOO.widget.MenuModule.prototype.setInitialFocus = function() {
|
|
|
|
var oItem = this._getFirstEnabledItem();
|
|
|
|
if(oItem) {
|
|
|
|
oItem.focus();
|
|
}
|
|
|
|
};
|
|
|
|
/**
|
|
* Sets the "selected" configuration property of a MenuModule instance's first
|
|
* enabled item to "true."
|
|
*/
|
|
YAHOO.widget.MenuModule.prototype.setInitialSelection = function() {
|
|
|
|
var oItem = this._getFirstEnabledItem();
|
|
|
|
if(oItem) {
|
|
|
|
oItem.cfg.setProperty("selected", true);
|
|
}
|
|
|
|
};
|
|
|
|
/**
|
|
* Sets the "selected" configuration property of a MenuModule instance's active
|
|
* item to "false," blurs the item and hide's the item's submenu.
|
|
*/
|
|
YAHOO.widget.MenuModule.prototype.clearActiveItem = function () {
|
|
|
|
if(this.activeItem) {
|
|
|
|
var oConfig = this.activeItem.cfg;
|
|
|
|
oConfig.setProperty("selected", false);
|
|
|
|
var oSubmenu = oConfig.getProperty("submenu");
|
|
|
|
if(oSubmenu) {
|
|
|
|
oSubmenu.hide();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
/**
|
|
* Initializes the class's configurable properties which can be changed using
|
|
* the MenuModule's Config object (cfg).
|
|
*/
|
|
YAHOO.widget.MenuModule.prototype.initDefaultConfig = function() {
|
|
|
|
YAHOO.widget.MenuModule.superclass.initDefaultConfig.call(this);
|
|
|
|
var oConfig = this.cfg;
|
|
|
|
// Add configuration properties
|
|
|
|
oConfig.addProperty(
|
|
"position",
|
|
{
|
|
value: "dynamic",
|
|
handler: this.configPosition,
|
|
validator: this._checkPosition
|
|
}
|
|
);
|
|
|
|
// this.cfg.refireEvent("position");
|
|
|
|
oConfig.addProperty("submenualignment", { value: ["tl","tr"] } );
|
|
|
|
};
|
|
|
|
/**
|
|
* @class The MenuModuleItem class allows you to create and modify an item for a
|
|
* MenuModule instance.
|
|
* @constructor
|
|
* @param {String or HTMLElement} p_oObject String or HTMLElement
|
|
* (either HTMLLIElement, HTMLOptGroupElement or HTMLOptionElement) of the
|
|
* source HTMLElement node.
|
|
* @param {Object} p_oConfig The configuration object literal containing
|
|
* the configuration for a MenuModuleItem instance. See the configuration
|
|
* class documentation for more details.
|
|
*/
|
|
YAHOO.widget.MenuModuleItem = function(p_oObject, p_oConfig) {
|
|
|
|
if(p_oObject) {
|
|
|
|
this.init(p_oObject, p_oConfig);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
YAHOO.widget.MenuModuleItem.prototype = {
|
|
|
|
// Constants
|
|
|
|
/**
|
|
* Constant representing the path to the image to be used for the submenu
|
|
* arrow indicator.
|
|
* @final
|
|
* @type String
|
|
*/
|
|
SUBMENU_INDICATOR_IMAGE_PATH: "nt/ic/ut/alt1/menuarorght8_nrm_1.gif",
|
|
|
|
/**
|
|
* Constant representing the path to the image to be used for the submenu
|
|
* arrow indicator when a MenuModuleItem instance is selected.
|
|
* @final
|
|
* @type String
|
|
*/
|
|
SELECTED_SUBMENU_INDICATOR_IMAGE_PATH:
|
|
"nt/ic/ut/alt1/menuarorght8_hov_1.gif",
|
|
|
|
/**
|
|
* Constant representing the path to the image to be used for the submenu
|
|
* arrow indicator when a MenuModuleItem instance is disabled.
|
|
* @final
|
|
* @type String
|
|
*/
|
|
DISABLED_SUBMENU_INDICATOR_IMAGE_PATH:
|
|
"nt/ic/ut/alt1/menuarorght8_dim_1.gif",
|
|
|
|
/**
|
|
* Constant representing the alt text for the image to be used for the
|
|
* submenu arrow indicator.
|
|
* @final
|
|
* @type String
|
|
*/
|
|
COLLAPSED_SUBMENU_INDICATOR_ALT_TEXT: "Collapsed. Click to expand.",
|
|
|
|
/**
|
|
* Constant representing the alt text for the image to be used for the
|
|
* submenu arrow indicator when the submenu is visible.
|
|
* @final
|
|
* @type String
|
|
*/
|
|
EXPANDED_SUBMENU_INDICATOR_ALT_TEXT: "Expanded. Click to collapse.",
|
|
|
|
/**
|
|
* Constant representing the alt text for the image to be used for the
|
|
* submenu arrow indicator when a MenuModuleItem instance is disabled.
|
|
* @final
|
|
* @type String
|
|
*/
|
|
DISABLED_SUBMENU_INDICATOR_ALT_TEXT: "Disabled.",
|
|
|
|
/**
|
|
* Constant representing the CSS class(es) to be applied to the root
|
|
* HTMLLIElement of the MenuModuleItem.
|
|
* @final
|
|
* @type String
|
|
*/
|
|
CSS_CLASS_NAME: "yuimenuitem",
|
|
|
|
/**
|
|
* Constant representing the type of menu to instantiate when creating
|
|
* submenu instances from parsing the child nodes (either HTMLSelectElement
|
|
* or HTMLDivElement) of the item's DOM. The default
|
|
* is YAHOO.widget.MenuModule.
|
|
* @final
|
|
* @type YAHOO.widget.MenuModule
|
|
*/
|
|
SUBMENU_TYPE: null,
|
|
|
|
/**
|
|
* Constant representing the type of item to instantiate when
|
|
* creating item instances from parsing the child nodes (either
|
|
* HTMLLIElement, HTMLOptGroupElement or HTMLOptionElement) of the
|
|
* submenu's DOM.
|
|
* The default is YAHOO.widget.MenuModuleItem.
|
|
* @final
|
|
* @type YAHOO.widget.MenuModuleItem
|
|
*/
|
|
SUBMENU_ITEM_TYPE: null,
|
|
|
|
/**
|
|
* Constant representing the prefix path to use for non-secure images
|
|
* @type string
|
|
*/
|
|
IMG_ROOT: "http://us.i1.yimg.com/us.yimg.com/i/",
|
|
|
|
|
|
/**
|
|
* Constant representing the prefix path to use for securely served images
|
|
* @type string
|
|
*/
|
|
IMG_ROOT_SSL: "https://a248.e.akamai.net/sec.yimg.com/i/",
|
|
|
|
// Private member variables
|
|
|
|
/**
|
|
* Reference to the HTMLAnchorElement of the MenuModuleItem's core internal
|
|
* DOM structure.
|
|
* @private
|
|
* @type {HTMLAnchorElement}
|
|
*/
|
|
_oAnchor: null,
|
|
|
|
|
|
/**
|
|
* Reference to the text node of the MenuModuleItem's core internal
|
|
* DOM structure.
|
|
* @private
|
|
* @type {Text}
|
|
*/
|
|
_oText: null,
|
|
|
|
|
|
/**
|
|
* Reference to the HTMLElement (<EM<) used to create the optional
|
|
* help text for a MenuModuleItem instance.
|
|
* @private
|
|
* @type {HTMLElement}
|
|
*/
|
|
_oHelpTextEM: null,
|
|
|
|
|
|
/**
|
|
* Reference to the submenu for a MenuModuleItem instance.
|
|
* @private
|
|
* @type {YAHOO.widget.MenuModule}
|
|
*/
|
|
_oSubmenu: null,
|
|
|
|
|
|
/**
|
|
* Reference to the Dom utility singleton.
|
|
* @private
|
|
* @type {YAHOO.util.Dom}
|
|
*/
|
|
_oDom: YAHOO.util.Dom,
|
|
|
|
/**
|
|
* The current state of a MenuModuleItem instance's "mouseover" event
|
|
* @private
|
|
* @type {Boolean}
|
|
*/
|
|
_bFiredMouseOverEvent: false,
|
|
|
|
|
|
/**
|
|
* The current state of a MenuModuleItem instance's "mouseout" event
|
|
* @private
|
|
* @type {Boolean}
|
|
*/
|
|
_bFiredMouseOutEvent: false,
|
|
|
|
// Public properties
|
|
|
|
/**
|
|
* The class's constructor function
|
|
* @type YAHOO.widget.MenuModuleItem
|
|
*/
|
|
constructor: YAHOO.widget.MenuModuleItem,
|
|
|
|
/**
|
|
* The string representing the image root
|
|
* @type string
|
|
*/
|
|
imageRoot: null,
|
|
|
|
/**
|
|
* Boolean representing whether or not the current browsing context
|
|
* is secure (https)
|
|
* @type boolean
|
|
*/
|
|
isSecure: YAHOO.widget.Module.prototype.isSecure,
|
|
|
|
/**
|
|
* Returns the ordinal position of a MenuModuleItem instance in a group.
|
|
* @type Number
|
|
*/
|
|
index: null,
|
|
|
|
/**
|
|
* Returns the index of the group to which a MenuModuleItem instance belongs.
|
|
* @type Number
|
|
*/
|
|
groupIndex: null,
|
|
|
|
/**
|
|
* Returns the parent object for a MenuModuleItem instance.
|
|
* @type {YAHOO.widget.MenuModule}
|
|
*/
|
|
parent: null,
|
|
|
|
/**
|
|
* Returns the HTMLLIElement for a MenuModuleItem instance.
|
|
* @type {HTMLLIElement}
|
|
*/
|
|
element: null,
|
|
|
|
/**
|
|
* Returns the HTMLElement (either HTMLLIElement, HTMLOptGroupElement or
|
|
* HTMLOptionElement) used create the MenuModuleItem instance.
|
|
* @type {HTMLLIElement/HTMLOptGroupElement/HTMLOptionElement}
|
|
*/
|
|
srcElement: null,
|
|
|
|
/**
|
|
* Specifies an arbitrary value for a MenuModuleItem instance.
|
|
* @type {Object}
|
|
*/
|
|
value: null,
|
|
|
|
/**
|
|
* Reference to the HTMLImageElement used to create the submenu
|
|
* indicator for a MenuModuleItem instance.
|
|
* @type {HTMLImageElement}
|
|
*/
|
|
submenuIndicator: null,
|
|
|
|
/**
|
|
* String representing the browser
|
|
* @type string
|
|
*/
|
|
browser: YAHOO.widget.Module.prototype.browser,
|
|
|
|
// Events
|
|
|
|
/**
|
|
* Fires when a MenuModuleItem instances's HTMLLIElement is removed from
|
|
* it's parent HTMLUListElement node.
|
|
* @type {YAHOO.util.CustomEvent}
|
|
* @see YAHOO.util.CustomEvent
|
|
*/
|
|
destroyEvent: null,
|
|
|
|
/**
|
|
* Fires when the mouse has entered a MenuModuleItem instance. Passes
|
|
* back the DOM Event object as an argument.
|
|
* @type {YAHOO.util.CustomEvent}
|
|
* @see YAHOO.util.CustomEvent
|
|
*/
|
|
mouseOverEvent: null,
|
|
|
|
/**
|
|
* Fires when the mouse has left a MenuModuleItem instance. Passes back
|
|
* the DOM Event object as an argument.
|
|
* @type {YAHOO.util.CustomEvent}
|
|
* @see YAHOO.util.CustomEvent
|
|
*/
|
|
mouseOutEvent: null,
|
|
|
|
/**
|
|
* Fires when the user mouses down on a MenuModuleItem instance. Passes
|
|
* back the DOM Event object as an argument.
|
|
* @type {YAHOO.util.CustomEvent}
|
|
* @see YAHOO.util.CustomEvent
|
|
*/
|
|
mouseDownEvent: null,
|
|
|
|
/**
|
|
* Fires when the user releases a mouse button while the mouse is
|
|
* over a MenuModuleItem instance. Passes back the DOM Event object as
|
|
* an argument.
|
|
* @type {YAHOO.util.CustomEvent}
|
|
* @see YAHOO.util.CustomEvent
|
|
*/
|
|
mouseUpEvent: null,
|
|
|
|
/**
|
|
* Fires when the user clicks the on a MenuModuleItem instance. Passes
|
|
* back the DOM Event object as an argument.
|
|
* @type {YAHOO.util.CustomEvent}
|
|
* @see YAHOO.util.CustomEvent
|
|
*/
|
|
clickEvent: null,
|
|
|
|
/**
|
|
* Fires when the user presses an alphanumeric key. Passes back the
|
|
* DOM Event object as an argument.
|
|
* @type {YAHOO.util.CustomEvent}
|
|
* @see YAHOO.util.CustomEvent
|
|
*/
|
|
keyPressEvent: null,
|
|
|
|
/**
|
|
* Fires when the user presses a key. Passes back the DOM Event
|
|
* object as an argument.
|
|
* @type {YAHOO.util.CustomEvent}
|
|
* @see YAHOO.util.CustomEvent
|
|
*/
|
|
keyDownEvent: null,
|
|
|
|
/**
|
|
* Fires when the user releases a key. Passes back the DOM Event
|
|
* object as an argument.
|
|
* @type {YAHOO.util.CustomEvent}
|
|
* @see YAHOO.util.CustomEvent
|
|
*/
|
|
keyUpEvent: null,
|
|
|
|
/**
|
|
* Fires when a MenuModuleItem instance receives focus.
|
|
* @type {YAHOO.util.CustomEvent}
|
|
* @see YAHOO.util.CustomEvent
|
|
*/
|
|
focusEvent: null,
|
|
|
|
/**
|
|
* Fires when a MenuModuleItem instance loses the input focus.
|
|
* @type {YAHOO.util.CustomEvent}
|
|
* @see YAHOO.util.CustomEvent
|
|
*/
|
|
blurEvent: null,
|
|
|
|
/**
|
|
* The MenuModuleItem class's initialization method. This method is
|
|
* automatically called by the constructor, and sets up all DOM references
|
|
* for pre-existing markup, and creates required markup if it is not
|
|
* already present.
|
|
* @param {String or HTMLElement} p_oObject String or HTMLElement
|
|
* (either HTMLLIElement, HTMLOptGroupElement or HTMLOptionElement) of the
|
|
* source HTMLElement node.
|
|
* @param {Object} p_oConfig The configuration object literal containing
|
|
* the configuration for a MenuModuleItem instance. See the configuration
|
|
* class documentation for more details.
|
|
*/
|
|
init: function(p_oObject, p_oConfig) {
|
|
|
|
this.imageRoot = (this.isSecure) ? this.IMG_ROOT_SSL : this.IMG_ROOT;
|
|
|
|
if(!this.SUBMENU_TYPE) {
|
|
|
|
this.SUBMENU_TYPE = YAHOO.widget.MenuModule;
|
|
|
|
}
|
|
|
|
if(!this.SUBMENU_ITEM_TYPE) {
|
|
|
|
this.SUBMENU_ITEM_TYPE = YAHOO.widget.MenuModuleItem;
|
|
|
|
}
|
|
|
|
// 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) {
|
|
|
|
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 MenuModuleItem
|
|
|
|
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) {
|
|
|
|
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) {
|
|
|
|
this._oDom.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);
|
|
|
|
// Subscribe to custom event
|
|
|
|
this.clickEvent.subscribe(this._onMenuModuleItemClick, this, true);
|
|
|
|
if(p_oConfig) {
|
|
|
|
oConfig.applyConfig(p_oConfig);
|
|
|
|
}
|
|
|
|
oConfig.fireQueue();
|
|
|
|
}
|
|
|
|
},
|
|
|
|
// Private methods
|
|
|
|
/**
|
|
* Returns an HTMLElement's first HTMLElement node
|
|
* @private
|
|
* @param {HTMLElement} p_oElement The element to be evaluated.
|
|
* @param {String} p_sTagName Optional. The tagname of the element.
|
|
* @return Returns an HTMLElement node.
|
|
* @type Boolean
|
|
*/
|
|
_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 == p_sTagName) ?
|
|
oElement : false;
|
|
|
|
}
|
|
|
|
return oElement;
|
|
|
|
},
|
|
|
|
/**
|
|
* Determines if an object is a string
|
|
* @private
|
|
* @param {Object} p_oObject The object to be evaluated.
|
|
* @return Returns true if the object is a string.
|
|
* @type Boolean
|
|
*/
|
|
_checkString: function(p_oObject) {
|
|
|
|
return (typeof p_oObject == "string");
|
|
|
|
},
|
|
|
|
/**
|
|
* Determines if an object is an HTMLElement.
|
|
* @private
|
|
* @param {Object} p_oObject The object to be evaluated.
|
|
* @return Returns true if the object is an HTMLElement.
|
|
* @type Boolean
|
|
*/
|
|
_checkDOMNode: function(p_oObject) {
|
|
|
|
return (p_oObject && p_oObject.tagName);
|
|
|
|
},
|
|
|
|
/**
|
|
* Creates the core DOM structure for a MenuModuleItem instance.
|
|
* @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);
|
|
|
|
},
|
|
|
|
/**
|
|
* Iterates the source element's childNodes collection and uses the
|
|
* child nodes to instantiate other menus.
|
|
* @private
|
|
*/
|
|
_initSubTree: function() {
|
|
|
|
var Menu = this.SUBMENU_TYPE;
|
|
var MenuModuleItem = this.SUBMENU_ITEM_TYPE;
|
|
var oSrcEl = this.srcElement;
|
|
var oConfig = this.cfg;
|
|
|
|
if(oSrcEl.childNodes.length > 0) {
|
|
|
|
var oNode = oSrcEl.firstChild;
|
|
var aOptions = [];
|
|
|
|
do {
|
|
|
|
switch(oNode.tagName) {
|
|
|
|
case "DIV":
|
|
|
|
oConfig.setProperty("submenu", (new Menu(oNode)));
|
|
|
|
break;
|
|
|
|
case "OPTION":
|
|
|
|
aOptions[aOptions.length] = oNode;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
while((oNode = oNode.nextSibling));
|
|
|
|
var nOptions = aOptions.length;
|
|
|
|
if(nOptions > 0) {
|
|
|
|
oConfig.setProperty(
|
|
"submenu",
|
|
(new Menu(this._oDom.generateId()))
|
|
);
|
|
|
|
for(var n=0; n<nOptions; n++) {
|
|
|
|
this._oSubmenu.addItem((new MenuModuleItem(aOptions[n])));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
/**
|
|
* "click" event handler for a MenuModuleItem
|
|
* @private
|
|
* @param {String} p_sType The name of the event that was fired.
|
|
* @param {Array} p_aArgs Collection of arguments sent when the event
|
|
* was fired.
|
|
* @param {YAHOO.widget.MenuItem} p_oMenuModuleItem The MenuModule instance
|
|
* that fired the event.
|
|
*/
|
|
_onMenuModuleItemClick: function(p_sType, p_aArgs, p_oMenuModuleItem) {
|
|
|
|
var Event = YAHOO.util.Event;
|
|
var oEvent = p_aArgs[0];
|
|
var oTarget = Event.getTarget(oEvent);
|
|
var oSubmenu = this.cfg.getProperty("submenu");
|
|
|
|
/*
|
|
ACCESSIBILITY FEATURE FOR SCREEN READERS: Expand/collapse the
|
|
submenu when the user clicks on the submenu indicator image.
|
|
*/
|
|
|
|
if(oTarget == this.submenuIndicator && oSubmenu) {
|
|
|
|
if(oSubmenu.cfg.getProperty("visible")) {
|
|
|
|
oSubmenu.hide();
|
|
|
|
}
|
|
else {
|
|
|
|
var oActiveItem = this.parent.activeItem;
|
|
|
|
|
|
// Hide any other submenus that might be visible
|
|
|
|
if(oActiveItem && oActiveItem != this) {
|
|
|
|
this.parent.clearActiveItem();
|
|
|
|
}
|
|
|
|
this.parent.activeItem = this;
|
|
|
|
this.cfg.setProperty("selected", true);
|
|
|
|
oSubmenu.show();
|
|
|
|
}
|
|
|
|
}
|
|
else {
|
|
|
|
var sURL = this.cfg.getProperty("url");
|
|
var bCurrentPageURL = (sURL.substr((sURL.length-1),1) == "#");
|
|
|
|
var sTarget = this.cfg.getProperty("target");
|
|
var bHasTarget = (sTarget && sTarget.length > 0);
|
|
|
|
// Prevent the browser from following links equal to "#"
|
|
|
|
if(oTarget.tagName == "A" && bCurrentPageURL && !bHasTarget) {
|
|
|
|
Event.preventDefault(oEvent);
|
|
|
|
}
|
|
|
|
if(oTarget.tagName != "A" && !bCurrentPageURL && !bHasTarget) {
|
|
|
|
/*
|
|
Follow the URL of the item regardless of whether or
|
|
not the user clicked specifically on the
|
|
HTMLAnchorElement (<A<) node.
|
|
*/
|
|
|
|
document.location = sURL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
// Event handlers for configuration properties
|
|
|
|
/**
|
|
* Event handler for when the "text" configuration property of
|
|
* a MenuModuleItem instance changes.
|
|
* @param {String} p_sType The name of the event that was fired.
|
|
* @param {Array} p_aArgs Collection of arguments sent when the
|
|
* event was fired.
|
|
* @param {YAHOO.widget.MenuModuleItem} p_oItem The MenuModuleItem instance
|
|
* that fired the event.
|
|
*/
|
|
configText: function(p_sType, p_aArgs, p_oItem) {
|
|
|
|
var sText = p_aArgs[0];
|
|
|
|
if(this._oText) {
|
|
|
|
this._oText.nodeValue = sText;
|
|
|
|
}
|
|
|
|
},
|
|
|
|
/**
|
|
* Event handler for when the "helptext" configuration property of
|
|
* a MenuModuleItem instance changes.
|
|
* @param {String} p_sType The name of the event that was fired.
|
|
* @param {Array} p_aArgs Collection of arguments sent when the
|
|
* event was fired.
|
|
* @param {YAHOO.widget.MenuModuleItem} p_oItem The MenuModuleItem instance
|
|
* that fired the event.
|
|
*/
|
|
configHelpText: function(p_sType, p_aArgs, p_oItem) {
|
|
|
|
var me = this;
|
|
var Dom = this._oDom;
|
|
var oHelpText = p_aArgs[0];
|
|
var oEl = this.element;
|
|
var oConfig = this.cfg;
|
|
var aNodes = [oEl, this._oAnchor];
|
|
var oImg = this.submenuIndicator;
|
|
|
|
/**
|
|
* Adds the "hashelptext" class to the necessary nodes and refires the
|
|
* "selected" and "disabled" configuration events
|
|
* @ignore
|
|
*/
|
|
function initHelpText() {
|
|
|
|
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)
|
|
* @ignore
|
|
*/
|
|
function removeHelpText() {
|
|
|
|
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();
|
|
|
|
}
|
|
|
|
},
|
|
|
|
/**
|
|
* Event handler for when the "url" configuration property of
|
|
* a MenuModuleItem instance changes.
|
|
* @param {String} p_sType The name of the event that was fired.
|
|
* @param {Array} p_aArgs Collection of arguments sent when the
|
|
* event was fired.
|
|
* @param {YAHOO.widget.MenuModuleItem} p_oItem The MenuModuleItem instance
|
|
* 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);
|
|
|
|
},
|
|
|
|
/**
|
|
* Event handler for when the "target" configuration property of
|
|
* a MenuModuleItem instance changes.
|
|
* @param {String} p_sType The name of the event that was fired.
|
|
* @param {Array} p_aArgs Collection of arguments sent when the
|
|
* event was fired.
|
|
* @param {YAHOO.widget.MenuModuleItem} p_oItem The MenuModuleItem instance
|
|
* 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");
|
|
|
|
}
|
|
|
|
},
|
|
|
|
/**
|
|
* Event handler for when the "emphasis" configuration property of
|
|
* a MenuModuleItem instance changes.
|
|
* @param {String} p_sType The name of the event that was fired.
|
|
* @param {Array} p_aArgs Collection of arguments sent when the
|
|
* event was fired.
|
|
* @param {YAHOO.widget.MenuModuleItem} p_oItem The MenuModuleItem instance
|
|
* 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);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
/**
|
|
* Event handler for when the "strongemphasis" configuration property of
|
|
* a MenuModuleItem instance changes.
|
|
* @param {String} p_sType The name of the event that was fired.
|
|
* @param {Array} p_aArgs Collection of arguments sent when the
|
|
* event was fired.
|
|
* @param {YAHOO.widget.MenuModuleItem} p_oItem The MenuModuleItem instance
|
|
* 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);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
/**
|
|
* Event handler for when the "disabled" configuration property of
|
|
* a MenuModuleItem instance changes.
|
|
* @param {String} p_sType The name of the event that was fired.
|
|
* @param {Array} p_aArgs Collection of arguments sent when the
|
|
* event was fired.
|
|
* @param {YAHOO.widget.MenuModuleItem} p_oItem The MenuModuleItem instance
|
|
* that fired the event.
|
|
*/
|
|
configDisabled: function(p_sType, p_aArgs, p_oItem) {
|
|
|
|
var bDisabled = p_aArgs[0];
|
|
var Dom = this._oDom;
|
|
var oAnchor = this._oAnchor;
|
|
var aNodes = [this.element, oAnchor];
|
|
var oEM = this._oHelpTextEM;
|
|
var oConfig = this.cfg;
|
|
var oImg = this.submenuIndicator;
|
|
var sImageSrc;
|
|
var sImageAlt;
|
|
|
|
if(oEM) {
|
|
|
|
aNodes[2] = oEM;
|
|
|
|
}
|
|
|
|
if(bDisabled) {
|
|
|
|
if(oConfig.getProperty("selected")) {
|
|
|
|
oConfig.setProperty("selected", false);
|
|
|
|
}
|
|
|
|
oAnchor.removeAttribute("href");
|
|
|
|
Dom.addClass(aNodes, "disabled");
|
|
|
|
sImageSrc = this.DISABLED_SUBMENU_INDICATOR_IMAGE_PATH;
|
|
sImageAlt = this.DISABLED_SUBMENU_INDICATOR_ALT_TEXT;
|
|
|
|
}
|
|
else {
|
|
|
|
oAnchor.setAttribute("href", oConfig.getProperty("url"));
|
|
|
|
Dom.removeClass(aNodes, "disabled");
|
|
|
|
sImageSrc = this.SUBMENU_INDICATOR_IMAGE_PATH;
|
|
sImageAlt = this.COLLAPSED_SUBMENU_INDICATOR_ALT_TEXT;
|
|
|
|
}
|
|
|
|
if(oImg) {
|
|
|
|
oImg.src = this.imageRoot + sImageSrc;
|
|
oImg.alt = sImageAlt;
|
|
|
|
}
|
|
|
|
},
|
|
|
|
/**
|
|
* Event handler for when the "selected" configuration property of
|
|
* a MenuModuleItem instance changes.
|
|
* @param {String} p_sType The name of the event that was fired.
|
|
* @param {Array} p_aArgs Collection of arguments sent when the
|
|
* event was fired.
|
|
* @param {YAHOO.widget.MenuModuleItem} p_oItem The MenuModuleItem instance
|
|
* that fired the event.
|
|
*/
|
|
configSelected: function(p_sType, p_aArgs, p_oItem) {
|
|
|
|
if(!this.cfg.getProperty("disabled")) {
|
|
|
|
var Dom = this._oDom;
|
|
var bSelected = p_aArgs[0];
|
|
var oEM = this._oHelpTextEM;
|
|
var aNodes = [this.element, this._oAnchor];
|
|
var oImg = this.submenuIndicator;
|
|
var sImageSrc;
|
|
|
|
if(oEM) {
|
|
|
|
aNodes[aNodes.length] = oEM;
|
|
|
|
}
|
|
|
|
if(oImg) {
|
|
|
|
aNodes[aNodes.length] = oImg;
|
|
|
|
}
|
|
|
|
if(bSelected) {
|
|
|
|
Dom.addClass(aNodes, "selected");
|
|
sImageSrc = this.SELECTED_SUBMENU_INDICATOR_IMAGE_PATH;
|
|
|
|
}
|
|
else {
|
|
|
|
Dom.removeClass(aNodes, "selected");
|
|
sImageSrc = this.SUBMENU_INDICATOR_IMAGE_PATH;
|
|
|
|
}
|
|
|
|
if(oImg) {
|
|
|
|
oImg.src = document.images[(this.imageRoot + sImageSrc)].src;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
/**
|
|
* Event handler for when the "submenu" configuration property of
|
|
* a MenuModuleItem instance changes.
|
|
* @param {String} p_sType The name of the event that was fired.
|
|
* @param {Array} p_aArgs Collection of arguments sent when the
|
|
* event was fired.
|
|
* @param {YAHOO.widget.MenuModuleItem} p_oItem The MenuModuleItem instance
|
|
* that fired the event.
|
|
*/
|
|
configSubmenu: function(p_sType, p_aArgs, p_oItem) {
|
|
|
|
var Dom = this._oDom;
|
|
var oEl = this.element;
|
|
var oSubmenu = p_aArgs[0];
|
|
var oImg = this.submenuIndicator;
|
|
var oConfig = this.cfg;
|
|
var aNodes = [this.element, this._oAnchor];
|
|
|
|
if(oSubmenu) {
|
|
|
|
// Set the submenu's parent to this MenuModuleItem instance
|
|
|
|
oSubmenu.parent = this;
|
|
|
|
this._oSubmenu = oSubmenu;
|
|
|
|
if(!oImg) {
|
|
|
|
var me = this;
|
|
|
|
function preloadImage(p_sPath) {
|
|
|
|
var sPath = me.imageRoot + p_sPath;
|
|
|
|
if(!document.images[sPath]) {
|
|
|
|
var oImage = document.createElement("img");
|
|
oImage.src = sPath;
|
|
oImage.name = sPath;
|
|
oImage.id = sPath;
|
|
oImage.style.display = "none";
|
|
|
|
document.body.appendChild(oImage);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
preloadImage(this.SUBMENU_INDICATOR_IMAGE_PATH);
|
|
preloadImage(this.SELECTED_SUBMENU_INDICATOR_IMAGE_PATH);
|
|
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
|
|
|
|
/**
|
|
* Initializes an item's configurable properties.
|
|
*/
|
|
initDefaultConfig : function() {
|
|
|
|
var oConfig = this.cfg;
|
|
var CheckBoolean = oConfig.checkBoolean;
|
|
|
|
// Define the config properties
|
|
|
|
oConfig.addProperty(
|
|
"text",
|
|
{
|
|
value: "",
|
|
handler: this.configText,
|
|
validator: this._checkString,
|
|
suppressEvent: true
|
|
}
|
|
);
|
|
|
|
oConfig.addProperty("helptext", { handler: this.configHelpText });
|
|
|
|
oConfig.addProperty(
|
|
"url",
|
|
{ value: "#", handler: this.configURL, suppressEvent: true }
|
|
);
|
|
|
|
oConfig.addProperty(
|
|
"target",
|
|
{ handler: this.configTarget, suppressEvent: true }
|
|
);
|
|
|
|
oConfig.addProperty(
|
|
"emphasis",
|
|
{
|
|
value: false,
|
|
handler: this.configEmphasis,
|
|
validator: CheckBoolean,
|
|
suppressEvent: true
|
|
}
|
|
);
|
|
|
|
oConfig.addProperty(
|
|
"strongemphasis",
|
|
{
|
|
value: false,
|
|
handler: this.configStrongEmphasis,
|
|
validator: CheckBoolean,
|
|
suppressEvent: true
|
|
}
|
|
);
|
|
|
|
oConfig.addProperty(
|
|
"disabled",
|
|
{
|
|
value: false,
|
|
handler: this.configDisabled,
|
|
validator: CheckBoolean,
|
|
suppressEvent: true
|
|
}
|
|
);
|
|
|
|
oConfig.addProperty(
|
|
"selected",
|
|
{
|
|
value: false,
|
|
handler: this.configSelected,
|
|
validator: CheckBoolean,
|
|
suppressEvent: true
|
|
}
|
|
);
|
|
|
|
oConfig.addProperty("submenu", { handler: this.configSubmenu });
|
|
|
|
},
|
|
|
|
/**
|
|
* Finds the next enabled MenuModuleItem instance in a MenuModule instance
|
|
* @return Returns a MenuModuleItem instance.
|
|
* @type YAHOO.widget.MenuModuleItem
|
|
*/
|
|
getNextEnabledSibling: function() {
|
|
|
|
if(this.parent instanceof YAHOO.widget.MenuModule) {
|
|
|
|
var nGroupIndex = this.groupIndex;
|
|
|
|
/**
|
|
* Returns the next item in an array
|
|
* @param {p_aArray} An array
|
|
* @param {p_nStartIndex} The index to start searching the array
|
|
* @ignore
|
|
* @return Returns an item in an array
|
|
* @type Object
|
|
*/
|
|
function getNextArrayItem(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 MenuModuleItem instance in the next group
|
|
|
|
oNextItem = getNextArrayItem(aNextGroup, 0);
|
|
|
|
}
|
|
|
|
return (
|
|
oNextItem.cfg.getProperty("disabled") ||
|
|
oNextItem.element.style.display == "none"
|
|
) ?
|
|
oNextItem.getNextEnabledSibling() : oNextItem;
|
|
|
|
}
|
|
|
|
},
|
|
|
|
/**
|
|
* Finds the previous enabled MenuModuleItem instance in a
|
|
* MenuModule instance
|
|
* @return Returns a MenuModuleItem instance.
|
|
* @type YAHOO.widget.MenuModuleItem
|
|
*/
|
|
getPreviousEnabledSibling: function() {
|
|
|
|
if(this.parent instanceof YAHOO.widget.MenuModule) {
|
|
|
|
var nGroupIndex = this.groupIndex;
|
|
|
|
/**
|
|
* Returns the previous item in an array
|
|
* @param {p_aArray} An array
|
|
* @param {p_nStartIndex} The index to start searching the array
|
|
* @ignore
|
|
* @return Returns an item in an array
|
|
* @type Object
|
|
*/
|
|
function getPreviousArrayItem(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
|
|
* @param {p_aArray} An array
|
|
* @param {p_nStartIndex} The index to start searching the array
|
|
* @ignore
|
|
* @return Returns an item in an array
|
|
* @type Object
|
|
*/
|
|
function getFirstItemIndex(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;
|
|
|
|
}
|
|
|
|
},
|
|
|
|
/**
|
|
* Causes a MenuModuleItem instance 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();
|
|
|
|
}
|
|
|
|
oAnchor.focus();
|
|
|
|
this.focusEvent.fire();
|
|
|
|
}
|
|
|
|
},
|
|
|
|
/**
|
|
* Causes a MenuModuleItem instance to lose focus and fires the onblur event.
|
|
*/
|
|
blur: function() {
|
|
|
|
var oParent = this.parent;
|
|
|
|
if(
|
|
!this.cfg.getProperty("disabled") &&
|
|
oParent &&
|
|
this._oDom.getStyle(oParent.element, "visibility") == "visible"
|
|
) {
|
|
|
|
this._oAnchor.blur();
|
|
|
|
this.blurEvent.fire();
|
|
|
|
}
|
|
|
|
},
|
|
|
|
/**
|
|
* Removes a MenuModuleItem instance's HTMLLIElement from it's parent
|
|
* HTMLUListElement node.
|
|
*/
|
|
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();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
/**
|
|
* @class Extends YAHOO.widget.MenuModule to provide a set of default mouse and
|
|
* key event behaviors.
|
|
* @constructor
|
|
* @extends YAHOO.widget.MenuModule
|
|
* @base YAHOO.widget.MenuModule
|
|
* @param {String or HTMLElement} p_oElement String id or HTMLElement
|
|
* (either HTMLSelectElement or HTMLDivElement) of the source HTMLElement node.
|
|
* @param {Object} p_oConfig Optional. The configuration object literal
|
|
* containing the configuration for a Menu instance. See
|
|
* configuration class documentation for more details.
|
|
*/
|
|
YAHOO.widget.Menu = function(p_oElement, p_oConfig) {
|
|
|
|
YAHOO.widget.Menu.superclass.constructor.call(
|
|
this,
|
|
p_oElement,
|
|
p_oConfig
|
|
);
|
|
|
|
};
|
|
|
|
YAHOO.extend(YAHOO.widget.Menu, YAHOO.widget.MenuModule);
|
|
|
|
/**
|
|
* The Menu class's initialization method. This method is automatically
|
|
* called by the constructor, and sets up all DOM references for pre-existing
|
|
* markup, and creates required markup if it is not already present.
|
|
* @param {String or HTMLElement} p_oElement String id or HTMLElement
|
|
* (either HTMLSelectElement or HTMLDivElement) of the source HTMLElement node.
|
|
* @param {Object} p_oConfig Optional. The configuration object literal
|
|
* containing the configuration for a Menu instance. See
|
|
* configuration class documentation for more details.
|
|
*/
|
|
YAHOO.widget.Menu.prototype.init = function(p_oElement, p_oConfig) {
|
|
|
|
if(!this.ITEM_TYPE) {
|
|
|
|
this.ITEM_TYPE = YAHOO.widget.MenuItem;
|
|
|
|
}
|
|
|
|
// Call the init of the superclass (YAHOO.widget.Menu)
|
|
|
|
YAHOO.widget.Menu.superclass.init.call(this, p_oElement);
|
|
|
|
this.beforeInitEvent.fire(YAHOO.widget.Menu);
|
|
|
|
// Add event handlers
|
|
|
|
this.showEvent.subscribe(this._onMenuShow, this, true);
|
|
this.mouseOverEvent.subscribe(this._onMenuMouseOver, this, true);
|
|
this.keyDownEvent.subscribe(this._onMenuKeyDown, this, true);
|
|
|
|
if(p_oConfig) {
|
|
|
|
this.cfg.applyConfig(p_oConfig, true);
|
|
|
|
}
|
|
|
|
this.initEvent.fire(YAHOO.widget.Menu);
|
|
|
|
};
|
|
|
|
// Private event handlers
|
|
|
|
/**
|
|
* "show" Custom Event handler for a menu.
|
|
* @private
|
|
* @param {String} p_sType The name of the event that was fired.
|
|
* @param {Array} p_aArgs Collection of arguments sent when the event
|
|
* was fired.
|
|
* @param {YAHOO.widget.Menu} p_oMenu The menu that fired the event.
|
|
*/
|
|
YAHOO.widget.Menu.prototype._onMenuShow =
|
|
|
|
function(p_sType, p_aArgs, p_oMenu) {
|
|
|
|
var oParent = this.parent;
|
|
|
|
if(oParent && oParent.parent instanceof YAHOO.widget.Menu) {
|
|
|
|
var aAlignment = oParent.parent.cfg.getProperty("submenualignment");
|
|
|
|
this.cfg.setProperty(
|
|
"submenualignment",
|
|
[ aAlignment[0], aAlignment[1] ]
|
|
);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
/**
|
|
* "mouseover" Custom Event handler for a Menu instance.
|
|
* @private
|
|
* @param {String} p_sType The name of the event that was fired.
|
|
* @param {Array} p_aArgs Collection of arguments sent when the event
|
|
* was fired.
|
|
* @param {YAHOO.widget.Menu} p_oMenu The Menu instance that fired the event.
|
|
*/
|
|
YAHOO.widget.Menu.prototype._onMenuMouseOver =
|
|
|
|
function(p_sType, p_aArgs, p_oMenu) {
|
|
|
|
/*
|
|
If the menu is a submenu, then select the menu's parent
|
|
MenuItem instance
|
|
*/
|
|
|
|
if(this.parent) {
|
|
|
|
this.parent.cfg.setProperty("selected", true);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
/**
|
|
* "mouseover" Custom Event handler for a Menu instance.
|
|
* @private
|
|
* @param {String} p_sType The name of the event that was fired.
|
|
* @param {Array} p_aArgs Collection of arguments sent when the event
|
|
* was fired.
|
|
* @param {YAHOO.widget.Menu} p_oMenu The Menu instance that fired the event.
|
|
*/
|
|
YAHOO.widget.Menu.prototype._onMenuKeyDown =
|
|
|
|
function(p_sType, p_aArgs, p_oMenu) {
|
|
|
|
if(this.cfg.getProperty("position") == "dynamic") {
|
|
|
|
var oDOMEvent = p_aArgs[0];
|
|
var oParent = this.parent;
|
|
|
|
if(oDOMEvent.keyCode == 27) { // Esc key
|
|
|
|
this.hide();
|
|
|
|
// Set focus to the parent MenuItem if one exists
|
|
|
|
if(oParent) {
|
|
|
|
oParent.focus();
|
|
|
|
if(oParent.parent instanceof YAHOO.widget.Menu) {
|
|
|
|
oParent.cfg.setProperty("selected", true);
|
|
|
|
}
|
|
|
|
YAHOO.util.Event.preventDefault(oDOMEvent);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
// Public event handlers
|
|
|
|
/**
|
|
* Event handler fired when the resize monitor element is resized.
|
|
*/
|
|
YAHOO.widget.Menu.prototype.onDomResize = function(e, obj) {
|
|
|
|
if(!this._handleResize) {
|
|
|
|
this._handleResize = true;
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
var me = this;
|
|
var oConfig = this.cfg;
|
|
|
|
if(oConfig.getProperty("position") == "dynamic") {
|
|
|
|
oConfig.setProperty("width", (this._getOffsetWidth() + "px"));
|
|
|
|
if(this.parent && oConfig.getProperty("visible")) {
|
|
|
|
function align() {
|
|
|
|
me.align();
|
|
|
|
}
|
|
|
|
window.setTimeout(align, 0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
YAHOO.widget.Menu.superclass.onDomResize.call(this, e, obj);
|
|
|
|
};
|
|
|
|
/**
|
|
* @class The MenuItem class allows you to create and modify an item for a
|
|
* Menu instance. MenuItem extends YAHOO.widget.MenuModuleItem to provide a
|
|
* set of default mouse and key event behaviors.
|
|
* @constructor
|
|
* @extends YAHOO.widget.MenuModuleItem
|
|
* @base YAHOO.widget.MenuModuleItem
|
|
* @param {String or HTMLElement} p_oObject String or HTMLElement
|
|
* (either HTMLLIElement, HTMLOptGroupElement or HTMLOptionElement) of the
|
|
* source HTMLElement node.
|
|
* @param {Object} p_oConfig The configuration object literal containing
|
|
* the configuration for a MenuItem instance. See the configuration
|
|
* class documentation for more details.
|
|
*/
|
|
YAHOO.widget.MenuItem = function(p_oObject, p_oConfig) {
|
|
|
|
YAHOO.widget.MenuItem.superclass.constructor.call(
|
|
this,
|
|
p_oObject,
|
|
p_oConfig
|
|
);
|
|
|
|
};
|
|
|
|
YAHOO.extend(YAHOO.widget.MenuItem, YAHOO.widget.MenuModuleItem);
|
|
|
|
/**
|
|
* The MenuItem class's initialization method. This method is automatically
|
|
* called by the constructor, and sets up all DOM references for
|
|
* pre-existing markup, and creates required markup if it is not
|
|
* already present.
|
|
* @param {String or HTMLElement} p_oObject String or HTMLElement
|
|
* (either HTMLLIElement, HTMLOptGroupElement or HTMLOptionElement) of the
|
|
* source HTMLElement node.
|
|
* @param {Object} p_oConfig The configuration object literal containing
|
|
* the configuration for a MenuItem instance. See the configuration
|
|
* class documentation for more details.
|
|
*/
|
|
YAHOO.widget.MenuItem.prototype.init = function(p_oObject, p_oConfig) {
|
|
|
|
if(!this.SUBMENU_TYPE) {
|
|
|
|
this.SUBMENU_TYPE = YAHOO.widget.Menu;
|
|
|
|
}
|
|
|
|
if(!this.SUBMENU_ITEM_TYPE) {
|
|
|
|
this.SUBMENU_ITEM_TYPE = YAHOO.widget.MenuItem;
|
|
|
|
}
|
|
|
|
/*
|
|
Call the init of the superclass (YAHOO.widget.MenuModuleItem)
|
|
Note: We don't pass the user config in here yet
|
|
because we only want it executed once, at the lowest
|
|
subclass level.
|
|
*/
|
|
|
|
YAHOO.widget.MenuItem.superclass.init.call(this, p_oObject);
|
|
|
|
// Add event handlers to each "MenuItem" instance
|
|
|
|
this.keyDownEvent.subscribe(this._onKeyDown, this, true);
|
|
this.mouseOverEvent.subscribe(this._onMouseOver, this, true);
|
|
this.mouseOutEvent.subscribe(this._onMouseOut, this, true);
|
|
this.clickEvent.subscribe(this._onClick, this, true);
|
|
|
|
var oConfig = this.cfg;
|
|
|
|
if(p_oConfig) {
|
|
|
|
oConfig.applyConfig(p_oConfig, true);
|
|
|
|
}
|
|
|
|
oConfig.fireQueue();
|
|
|
|
};
|
|
|
|
// Constants
|
|
|
|
/**
|
|
* Constant representing the path to the image to be used for the checked state.
|
|
* @final
|
|
* @type String
|
|
*/
|
|
YAHOO.widget.MenuItem.prototype.CHECKED_IMAGE_PATH =
|
|
"nt/ic/ut/bsc/menuchk8_nrm_1.gif";
|
|
|
|
/**
|
|
* Constant representing the path to the image to be used for the selected
|
|
* checked state.
|
|
* @final
|
|
* @type String
|
|
*/
|
|
YAHOO.widget.MenuItem.prototype.SELECTED_CHECKED_IMAGE_PATH =
|
|
"nt/ic/ut/bsc/menuchk8_hov_1.gif";
|
|
|
|
/**
|
|
* Constant representing the path to the image to be used for the disabled
|
|
* checked state.
|
|
* @final
|
|
* @type String
|
|
*/
|
|
YAHOO.widget.MenuItem.prototype.DISABLED_CHECKED_IMAGE_PATH =
|
|
"nt/ic/ut/bsc/menuchk8_dim_1.gif";
|
|
|
|
/**
|
|
* Constant representing the alt text for the image to be used for the
|
|
* checked image.
|
|
* @final
|
|
* @type String
|
|
*/
|
|
YAHOO.widget.MenuItem.prototype.CHECKED_IMAGE_ALT_TEXT = "Checked.";
|
|
|
|
/**
|
|
* Constant representing the alt text for the image to be used for the
|
|
* checked image when the item is disabled.
|
|
* @final
|
|
* @type String
|
|
*/
|
|
YAHOO.widget.MenuItem.prototype.DISABLED_CHECKED_IMAGE_ALT_TEXT =
|
|
"Checked. (Item disabled.)";
|
|
|
|
// Private properties
|
|
|
|
/**
|
|
* Reference to the HTMLImageElement used to create the checked
|
|
* indicator for a MenuItem instance.
|
|
* @private
|
|
* @type {HTMLImageElement}
|
|
*/
|
|
YAHOO.widget.MenuItem.prototype._checkImage = null;
|
|
|
|
// Private event handlers
|
|
|
|
/**
|
|
* "keydown" Custom Event handler for a MenuItem instance.
|
|
* @private
|
|
* @param {String} p_sType The name of the event that was fired.
|
|
* @param {Array} p_aArgs Collection of arguments sent when the event
|
|
* was fired.
|
|
* @param {YAHOO.widget.MenuItem} p_oMenuModule The MenuModule instance that
|
|
* fired the event.
|
|
*/
|
|
YAHOO.widget.MenuItem.prototype._onKeyDown =
|
|
|
|
function(p_sType, p_aArgs, p_oMenuItem) {
|
|
|
|
var Event = YAHOO.util.Event;
|
|
var oDOMEvent = p_aArgs[0];
|
|
var oParent = this.parent;
|
|
var oConfig = this.cfg;
|
|
var oMenuItem;
|
|
|
|
|
|
switch(oDOMEvent.keyCode) {
|
|
|
|
case 38: // Up arrow
|
|
case 40: // Down arrow
|
|
|
|
if(
|
|
this == oParent.activeItem &&
|
|
!oConfig.getProperty("selected")
|
|
) {
|
|
|
|
oConfig.setProperty("selected", true);
|
|
|
|
}
|
|
else {
|
|
|
|
var oNextItem = (oDOMEvent.keyCode == 38) ?
|
|
this.getPreviousEnabledSibling() :
|
|
this.getNextEnabledSibling();
|
|
|
|
if(oNextItem) {
|
|
|
|
oParent.clearActiveItem();
|
|
|
|
oNextItem.cfg.setProperty("selected", true);
|
|
|
|
oNextItem.focus();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Event.preventDefault(oDOMEvent);
|
|
|
|
break;
|
|
|
|
|
|
case 39: // Right arrow
|
|
|
|
oParent.clearActiveItem();
|
|
|
|
oConfig.setProperty("selected", true);
|
|
|
|
this.focus();
|
|
|
|
var oSubmenu = oConfig.getProperty("submenu");
|
|
|
|
if(oSubmenu) {
|
|
|
|
oSubmenu.show();
|
|
oSubmenu.setInitialSelection();
|
|
|
|
}
|
|
else if(
|
|
YAHOO.widget.MenuBarItem &&
|
|
oParent.parent &&
|
|
oParent.parent instanceof YAHOO.widget.MenuBarItem
|
|
) {
|
|
|
|
oParent.hide();
|
|
|
|
// Set focus to the parent MenuItem if one exists
|
|
|
|
oMenuItem = oParent.parent;
|
|
|
|
if(oMenuItem) {
|
|
|
|
oMenuItem.focus();
|
|
oMenuItem.cfg.setProperty("selected", true);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Event.preventDefault(oDOMEvent);
|
|
|
|
break;
|
|
|
|
|
|
case 37: // Left arrow
|
|
|
|
// Only hide if this this is a MenuItem of a submenu
|
|
|
|
if(oParent.parent) {
|
|
|
|
oParent.hide();
|
|
|
|
// Set focus to the parent MenuItem if one exists
|
|
|
|
oMenuItem = oParent.parent;
|
|
|
|
if(oMenuItem) {
|
|
|
|
oMenuItem.focus();
|
|
oMenuItem.cfg.setProperty("selected", true);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Event.preventDefault(oDOMEvent);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
/**
|
|
* "mouseover" Custom Event handler for a MenuItem instance.
|
|
* @private
|
|
* @param {String} p_sType The name of the event that was fired.
|
|
* @param {Array} p_aArgs Collection of arguments sent when the event
|
|
* was fired.
|
|
* @param {YAHOO.widget.MenuItem} p_oMenuModule The MenuModule instance that
|
|
* fired the event.
|
|
*/
|
|
YAHOO.widget.MenuItem.prototype._onMouseOver =
|
|
|
|
function(p_sType, p_aArgs, p_oMenuItem) {
|
|
|
|
var oParent = this.parent;
|
|
var oConfig = this.cfg;
|
|
var oActiveItem = oParent.activeItem;
|
|
|
|
|
|
// Hide any other submenus that might be visible
|
|
|
|
if(oActiveItem && oActiveItem != this) {
|
|
|
|
oParent.clearActiveItem();
|
|
|
|
}
|
|
|
|
|
|
// Select and focus the current MenuItem instance
|
|
|
|
oConfig.setProperty("selected", true);
|
|
this.focus();
|
|
|
|
|
|
// Show the submenu for this instance
|
|
|
|
var oSubmenu = oConfig.getProperty("submenu");
|
|
|
|
if(oSubmenu) {
|
|
|
|
oSubmenu.show();
|
|
|
|
}
|
|
|
|
};
|
|
|
|
/**
|
|
* "mouseout" Custom Event handler for a MenuItem instance.
|
|
* @private
|
|
* @param {String} p_sType The name of the event that was fired.
|
|
* @param {Array} p_aArgs Collection of arguments sent when the event
|
|
* was fired.
|
|
* @param {YAHOO.widget.MenuItem} p_oMenuModule The MenuModule instance that
|
|
* fired the event.
|
|
*/
|
|
YAHOO.widget.MenuItem.prototype._onMouseOut =
|
|
|
|
function(p_sType, p_aArgs, p_oMenuItem) {
|
|
|
|
var oConfig = this.cfg;
|
|
var oSubmenu = oConfig.getProperty("submenu");
|
|
|
|
oConfig.setProperty("selected", false);
|
|
|
|
if(oSubmenu) {
|
|
|
|
var oDOMEvent = p_aArgs[0];
|
|
var oRelatedTarget = YAHOO.util.Event.getRelatedTarget(oDOMEvent);
|
|
|
|
if(
|
|
!(
|
|
oRelatedTarget == oSubmenu.element ||
|
|
YAHOO.util.Dom.isAncestor(oSubmenu.element, oRelatedTarget)
|
|
)
|
|
) {
|
|
|
|
oSubmenu.hide();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
/**
|
|
* "click" Custom Event handler for a MenuItem instance.
|
|
* @private
|
|
* @param {String} p_sType The name of the event that was fired.
|
|
* @param {Array} p_aArgs Collection of arguments sent when the event
|
|
* was fired.
|
|
* @param {YAHOO.widget.MenuItem} p_oMenuModule The MenuModule instance that
|
|
* fired the event.
|
|
*/
|
|
YAHOO.widget.MenuItem.prototype._onClick =
|
|
|
|
function(p_sType, p_aArgs, p_oMenuItem) {
|
|
|
|
function findRoot(p_oMenu) {
|
|
|
|
var oItem = p_oMenu.parent; // The parent MenuItem instance
|
|
|
|
if(oItem) {
|
|
|
|
var oParentMenu = oItem.parent;
|
|
|
|
if(
|
|
oParentMenu &&
|
|
(oParentMenu instanceof YAHOO.widget.Menu) &&
|
|
oParentMenu.cfg.getProperty("position") == "dynamic"
|
|
) {
|
|
|
|
return findRoot(oParentMenu);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return p_oMenu;
|
|
|
|
}
|
|
|
|
|
|
var oRoot = findRoot(this.parent);
|
|
var sURL = this.cfg.getProperty("url");
|
|
|
|
if(
|
|
(sURL.substr((sURL.length-1),1) == "#") &&
|
|
oRoot &&
|
|
oRoot.cfg.getProperty("position") == "dynamic"
|
|
) {
|
|
|
|
oRoot.hide();
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
// Event handlers for configuration properties
|
|
|
|
/**
|
|
* Event handler for when the "checked" configuration property of
|
|
* a MenuItem instance changes.
|
|
* @param {String} p_sType The name of the event that was fired.
|
|
* @param {Array} p_aArgs Collection of arguments sent when the
|
|
* event was fired.
|
|
* @param {YAHOO.widget.MenuItem} p_oItem The MenuItem instance
|
|
* that fired the event.
|
|
*/
|
|
YAHOO.widget.MenuItem.prototype.configChecked =
|
|
|
|
function(p_sType, p_aArgs, p_oItem) {
|
|
|
|
var Dom = YAHOO.util.Dom;
|
|
var bChecked = p_aArgs[0];
|
|
var oEl = this.element;
|
|
var oConfig = this.cfg;
|
|
var oImg;
|
|
|
|
|
|
if(bChecked) {
|
|
|
|
var me = this;
|
|
|
|
function preloadImage(p_sPath) {
|
|
|
|
var sPath = me.imageRoot + p_sPath;
|
|
|
|
if(!document.images[sPath]) {
|
|
|
|
var oImage = document.createElement("img");
|
|
oImage.src = sPath;
|
|
oImage.name = sPath;
|
|
oImage.id = sPath;
|
|
oImage.style.display = "none";
|
|
|
|
document.body.appendChild(oImage);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
preloadImage(this.CHECKED_IMAGE_PATH);
|
|
preloadImage(this.SELECTED_CHECKED_IMAGE_PATH);
|
|
preloadImage(this.DISABLED_CHECKED_IMAGE_PATH);
|
|
|
|
oImg = document.createElement("img");
|
|
oImg.src = (this.imageRoot + this.CHECKED_IMAGE_PATH);
|
|
oImg.alt = this.CHECKED_IMAGE_ALT_TEXT;
|
|
|
|
var oSubmenu = this.cfg.getProperty("submenu");
|
|
|
|
if(oSubmenu) {
|
|
|
|
oEl.insertBefore(oImg, oSubmenu.element);
|
|
|
|
}
|
|
else {
|
|
|
|
oEl.appendChild(oImg);
|
|
|
|
}
|
|
|
|
Dom.addClass([oEl, oImg], "checked");
|
|
|
|
this._checkImage = oImg;
|
|
|
|
if(oConfig.getProperty("disabled")) {
|
|
|
|
oConfig.refireEvent("disabled");
|
|
|
|
}
|
|
|
|
if(oConfig.getProperty("selected")) {
|
|
|
|
oConfig.refireEvent("selected");
|
|
|
|
}
|
|
|
|
}
|
|
else {
|
|
|
|
oImg = this._checkImage;
|
|
|
|
Dom.removeClass([oEl, oImg], "checked");
|
|
|
|
if(oImg) {
|
|
|
|
oEl.removeChild(oImg);
|
|
|
|
}
|
|
|
|
this._checkImage = null;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
/**
|
|
* Event handler for when the "selected" configuration property of
|
|
* a MenuItem instance changes.
|
|
* @param {String} p_sType The name of the event that was fired.
|
|
* @param {Array} p_aArgs Collection of arguments sent when the
|
|
* event was fired.
|
|
* @param {YAHOO.widget.MenuItem} p_oItem The MenuItem instance
|
|
* that fired the event.
|
|
*/
|
|
YAHOO.widget.MenuItem.prototype.configSelected =
|
|
|
|
function(p_sType, p_aArgs, p_oItem) {
|
|
|
|
YAHOO.widget.MenuItem.superclass.configSelected.call(
|
|
this, p_sType, p_aArgs, p_oItem
|
|
);
|
|
|
|
var oConfig = this.cfg;
|
|
|
|
if(!oConfig.getProperty("disabled") && oConfig.getProperty("checked")) {
|
|
|
|
var bSelected = p_aArgs[0];
|
|
|
|
var sSrc = this.imageRoot + (bSelected ?
|
|
this.SELECTED_CHECKED_IMAGE_PATH : this.CHECKED_IMAGE_PATH);
|
|
|
|
this._checkImage.src = document.images[sSrc].src;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
/**
|
|
* Event handler for when the "disabled" configuration property of
|
|
* a MenuItem instance changes.
|
|
* @param {String} p_sType The name of the event that was fired.
|
|
* @param {Array} p_aArgs Collection of arguments sent when the
|
|
* event was fired.
|
|
* @param {YAHOO.widget.MenuItem} p_oItem The MenuItem instance
|
|
* that fired the event.
|
|
*/
|
|
YAHOO.widget.MenuItem.prototype.configDisabled =
|
|
|
|
function(p_sType, p_aArgs, p_oItem) {
|
|
|
|
YAHOO.widget.MenuItem.superclass.configDisabled.call(
|
|
this, p_sType, p_aArgs, p_oItem
|
|
);
|
|
|
|
if(this.cfg.getProperty("checked")) {
|
|
|
|
var bDisabled = p_aArgs[0];
|
|
var sAlt = this.CHECKED_IMAGE_ALT_TEXT;
|
|
var sSrc = this.CHECKED_IMAGE_PATH;
|
|
var oImg = this._checkImage;
|
|
|
|
if(bDisabled) {
|
|
|
|
sAlt = this.DISABLED_CHECKED_IMAGE_ALT_TEXT;
|
|
sSrc = this.DISABLED_CHECKED_IMAGE_PATH;
|
|
|
|
}
|
|
|
|
oImg.src = document.images[(this.imageRoot + sSrc)].src;
|
|
oImg.alt = sAlt;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
// Public methods
|
|
|
|
/**
|
|
* Initializes the class's configurable properties which can be changed using
|
|
* the MenuModule's Config object (cfg).
|
|
*/
|
|
YAHOO.widget.MenuItem.prototype.initDefaultConfig = function() {
|
|
|
|
YAHOO.widget.MenuItem.superclass.initDefaultConfig.call(this);
|
|
|
|
// Add configuration properties
|
|
|
|
this.cfg.addProperty(
|
|
"checked",
|
|
{
|
|
value: false,
|
|
handler: this.configChecked,
|
|
validator: this.cfg.checkBoolean,
|
|
suppressEvent: true,
|
|
supercedes:["disabled"]
|
|
}
|
|
);
|
|
|
|
};
|
|
|
|
/**
|
|
* @class Creates a list of options which vary depending on the context in
|
|
* which the menu is invoked.
|
|
* @constructor
|
|
* @extends YAHOO.widget.Menu
|
|
* @base YAHOO.widget.Menu
|
|
* @param {String or HTMLElement} p_oElement String id or HTMLElement
|
|
* (either HTMLSelectElement or HTMLDivElement) of the source HTMLElement node.
|
|
* @param {Object} p_oConfig Optional. The configuration object literal
|
|
* containing the configuration for a ContextMenu instance. See
|
|
* configuration class documentation for more details.
|
|
*/
|
|
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
|
|
|
|
/**
|
|
* Array of ContextMenu instances
|
|
* @private
|
|
* @type {Array}
|
|
*/
|
|
YAHOO.widget.ContextMenu._aMenus = [];
|
|
|
|
/**
|
|
* The id(s) or element(s) that trigger the display of the ContextMenu instance
|
|
* @private
|
|
* @type {String/Array/HTMLElement}
|
|
*/
|
|
YAHOO.widget.ContextMenu.prototype._oTrigger = null;
|
|
|
|
// Public properties
|
|
|
|
/**
|
|
* Returns the HTMLElement node that was the target of the "contextmenu"
|
|
* DOM event.
|
|
* @type HTMLElement
|
|
*/
|
|
YAHOO.widget.ContextMenu.prototype.contextEventTarget = null;
|
|
|
|
/**
|
|
* The ContextMenu class's initialization method. This method is automatically
|
|
* called by the constructor, and sets up all DOM references for pre-existing
|
|
* markup, and creates required markup if it is not already present.
|
|
* @param {String or HTMLElement} p_oElement String id or HTMLElement
|
|
* (either HTMLSelectElement or HTMLDivElement) of the source HTMLElement node.
|
|
* @param {Object} p_oConfig Optional. The configuration object literal
|
|
* containing the configuration for a ContextMenu instance. See
|
|
* configuration class documentation for more details.
|
|
*/
|
|
YAHOO.widget.ContextMenu.prototype.init = function(p_oElement, p_oConfig) {
|
|
|
|
if(!this.ITEM_TYPE) {
|
|
|
|
this.ITEM_TYPE = YAHOO.widget.ContextMenuItem;
|
|
|
|
}
|
|
|
|
// 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);
|
|
|
|
var aMenus = YAHOO.widget.ContextMenu._aMenus;
|
|
|
|
aMenus[aMenus.length] = this;
|
|
|
|
};
|
|
|
|
// Private event handlers
|
|
|
|
/**
|
|
* "click" event handler for the document object.
|
|
* @private
|
|
* @param {Event} p_oEvent Event object passed back by the
|
|
* event utility (YAHOO.util.Event).
|
|
* @param {YAHOO.widget.ContextMenu} p_oMenu The ContextMenu instance
|
|
* handling the event.
|
|
*/
|
|
YAHOO.widget.ContextMenu.prototype._onDocumentClick =
|
|
|
|
function(p_oEvent, p_oMenu) {
|
|
|
|
this.hide();
|
|
|
|
};
|
|
|
|
/**
|
|
* "click" event handler for the HTMLElement node that triggered the event.
|
|
* Used to cancel default behaviors in Opera.
|
|
* @private
|
|
* @param {Event} p_oEvent Event object passed back by the
|
|
* event utility (YAHOO.util.Event).
|
|
* @param {YAHOO.widget.ContextMenu} p_oMenu The ContextMenu instance
|
|
* handling the event.
|
|
*/
|
|
YAHOO.widget.ContextMenu.prototype._onTriggerClick =
|
|
|
|
function(p_oEvent, p_oMenu) {
|
|
|
|
if(p_oEvent.ctrlKey) {
|
|
|
|
YAHOO.util.Event.stopEvent(p_oEvent);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
/**
|
|
* "contextmenu" event handler ("mousedown" for Opera) for the HTMLElement
|
|
* node that triggered the event.
|
|
* @private
|
|
* @param {Event} p_oEvent Event object passed back by the
|
|
* event utility (YAHOO.util.Event).
|
|
* @param {YAHOO.widget.ContextMenu} p_oMenu The ContextMenu instance
|
|
* handling the event.
|
|
*/
|
|
YAHOO.widget.ContextMenu.prototype._onTriggerContextMenu =
|
|
|
|
function(p_oEvent, p_oMenu) {
|
|
|
|
var Event = YAHOO.util.Event;
|
|
var oConfig = this.cfg;
|
|
|
|
// Hide any other ContextMenu instances that might be visible
|
|
|
|
var aMenus = YAHOO.widget.ContextMenu._aMenus;
|
|
var i = aMenus.length - 1;
|
|
|
|
do {
|
|
|
|
aMenus[i].hide();
|
|
|
|
}
|
|
while(i--);
|
|
|
|
|
|
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 no displayed.
|
|
*/
|
|
|
|
Event.stopEvent(p_oEvent);
|
|
|
|
};
|
|
|
|
// Public methods
|
|
|
|
/**
|
|
* Initializes the class's configurable properties which can be changed using
|
|
* a ContextMenu instance's Config object (cfg).
|
|
*/
|
|
YAHOO.widget.ContextMenu.prototype.initDefaultConfig = function() {
|
|
|
|
YAHOO.widget.ContextMenu.superclass.initDefaultConfig.call(this);
|
|
|
|
// Add a configuration property
|
|
|
|
this.cfg.addProperty("trigger", { handler: this.configTrigger });
|
|
|
|
};
|
|
|
|
// Event handlers for configuration properties
|
|
|
|
/**
|
|
* Event handler for when the "trigger" configuration property of
|
|
* a MenuItem instance.
|
|
* @param {String} p_sType The name of the event that was fired.
|
|
* @param {Array} p_aArgs Collection of arguments sent when the
|
|
* event was fired.
|
|
* @param {YAHOO.widget.ContextMenu} p_oMenu The ContextMenu that instance fired
|
|
* the event.
|
|
*/
|
|
YAHOO.widget.ContextMenu.prototype.configTrigger =
|
|
|
|
function(p_sType, p_aArgs, p_oMenu) {
|
|
|
|
var Event = YAHOO.util.Event;
|
|
var oTrigger = p_aArgs[0];
|
|
|
|
if(oTrigger) {
|
|
|
|
|
|
/*
|
|
If there is a current "trigger" - remove the event handlers
|
|
from that element(s) before assigning new ones
|
|
*/
|
|
if(this._oTrigger) {
|
|
|
|
Event.purgeElement(this._oTrigger);
|
|
|
|
}
|
|
|
|
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
|
|
);
|
|
|
|
}
|
|
|
|
|
|
// Assign a "mousedown" event handler to the document
|
|
|
|
Event.addListener(
|
|
document,
|
|
"click",
|
|
this._onDocumentClick,
|
|
this,
|
|
true
|
|
);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
/**
|
|
* @class Creates an item for a context menu instance.
|
|
* @constructor
|
|
* @extends YAHOO.widget.MenuItem
|
|
* @base YAHOO.widget.MenuItem
|
|
* @param {String or HTMLElement} p_oObject String or HTMLElement
|
|
* (either HTMLLIElement, HTMLOptGroupElement or HTMLOptionElement) of the
|
|
* source HTMLElement node.
|
|
* @param {Object} p_oConfig The configuration object literal containing
|
|
* the configuration for a ContextMenuItem instance. See the configuration
|
|
* class documentation for more details.
|
|
*/
|
|
YAHOO.widget.ContextMenuItem = function(p_oObject, p_oConfig) {
|
|
|
|
YAHOO.widget.ContextMenuItem.superclass.constructor.call(
|
|
this,
|
|
p_oObject,
|
|
p_oConfig
|
|
);
|
|
|
|
};
|
|
|
|
YAHOO.extend(YAHOO.widget.ContextMenuItem, YAHOO.widget.MenuItem);
|
|
|
|
/**
|
|
* The ContextMenuItem class's initialization method. This method is
|
|
* automatically called by the constructor, and sets up all DOM references for
|
|
* pre-existing markup, and creates required markup if it is not
|
|
* already present.
|
|
* @param {String or HTMLElement} p_oObject String or HTMLElement
|
|
* (either HTMLLIElement, HTMLOptGroupElement or HTMLOptionElement) of the
|
|
* source HTMLElement node.
|
|
* @param {Object} p_oConfig The configuration object literal containing
|
|
* the configuration for a ContextMenuItem instance. See the configuration
|
|
* class documentation for more details.
|
|
*/
|
|
YAHOO.widget.ContextMenuItem.prototype.init =
|
|
|
|
function(p_oObject, p_oConfig) {
|
|
|
|
if(!this.SUBMENU_TYPE) {
|
|
|
|
this.SUBMENU_TYPE = YAHOO.widget.ContextMenu;
|
|
|
|
}
|
|
|
|
if(!this.SUBMENU_ITEM_TYPE) {
|
|
|
|
this.SUBMENU_ITEM_TYPE = YAHOO.widget.ContextMenuItem;
|
|
|
|
}
|
|
|
|
|
|
/*
|
|
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();
|
|
|
|
};
|
|
|
|
/**
|
|
* @class Horizontal collection of items, each of which can contain a submenu.
|
|
* Extends YAHOO.widget.MenuModule to provide a set of default mouse and
|
|
* key event behaviors.
|
|
* @constructor
|
|
* @extends YAHOO.widget.MenuModule
|
|
* @base YAHOO.widget.MenuModule
|
|
* @param {String or HTMLElement} p_oElement String id or HTMLElement
|
|
* (either HTMLSelectElement or HTMLDivElement) of the source HTMLElement node.
|
|
* @param {Object} p_oConfig Optional. The configuration object literal
|
|
* containing the configuration for a MenuBar instance. See
|
|
* configuration class documentation for more details.
|
|
*/
|
|
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.MenuModule);
|
|
|
|
/**
|
|
* The MenuBar class's initialization method. This method is automatically
|
|
* called by the constructor, and sets up all DOM references for pre-existing
|
|
* markup, and creates required markup if it is not already present.
|
|
* @param {String or HTMLElement} p_oElement String id or HTMLElement
|
|
* (either HTMLSelectElement or HTMLDivElement) of the source HTMLElement node.
|
|
* @param {Object} p_oConfig Optional. The configuration object literal
|
|
* containing the configuration for a MenuBar instance. See
|
|
* configuration class documentation for more details.
|
|
*/
|
|
YAHOO.widget.MenuBar.prototype.init = function(p_oElement, p_oConfig) {
|
|
|
|
if(!this.ITEM_TYPE) {
|
|
|
|
this.ITEM_TYPE = YAHOO.widget.MenuBarItem;
|
|
|
|
}
|
|
|
|
// Call the init of the superclass (YAHOO.widget.MenuModule)
|
|
|
|
YAHOO.widget.MenuBar.superclass.init.call(this, p_oElement);
|
|
|
|
this.beforeInitEvent.fire(YAHOO.widget.MenuBar);
|
|
|
|
var oConfig = this.cfg;
|
|
|
|
/*
|
|
Set the default value for the "position" configuration property
|
|
to "static"
|
|
*/
|
|
if(!p_oConfig || (p_oConfig && !p_oConfig.position)) {
|
|
|
|
oConfig.queueProperty("position", "static");
|
|
|
|
}
|
|
|
|
/*
|
|
Set the default value for the "submenualignment" configuration property
|
|
to "tl" and "bl"
|
|
*/
|
|
if(!p_oConfig || (p_oConfig && !p_oConfig.submenualignment)) {
|
|
|
|
oConfig.queueProperty("submenualignment", ["tl","bl"]);
|
|
|
|
}
|
|
|
|
if(p_oConfig) {
|
|
|
|
oConfig.applyConfig(p_oConfig, true);
|
|
|
|
}
|
|
|
|
this.initEvent.fire(YAHOO.widget.MenuBar);
|
|
|
|
};
|
|
|
|
// Constants
|
|
|
|
/**
|
|
* Constant representing the CSS class(es) to be applied to the root
|
|
* HTMLDivElement of the MenuBar instance.
|
|
* @final
|
|
* @type String
|
|
*/
|
|
YAHOO.widget.MenuBar.prototype.CSS_CLASS_NAME = "yuimenubar";
|
|
|
|
/**
|
|
* @class The MenuBarItem class allows you to create and modify an item for a
|
|
* MenuBar instance. MenuBarItem extends YAHOO.widget.MenuModuleItem to provide
|
|
* a set of default mouse and key event behaviors.
|
|
* @constructor
|
|
* @extends YAHOO.widget.MenuModuleItem
|
|
* @base YAHOO.widget.MenuModuleItem
|
|
* @param {String or HTMLElement} p_oObject String or HTMLElement
|
|
* (either HTMLLIElement, HTMLOptGroupElement or HTMLOptionElement) of the
|
|
* source HTMLElement node.
|
|
* @param {Object} p_oConfig The configuration object literal containing
|
|
* the configuration for a MenuBarItem instance. See the configuration
|
|
* class documentation for more details.
|
|
*/
|
|
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.MenuModuleItem);
|
|
|
|
/**
|
|
* The MenuBarItem class's initialization method. This method is automatically
|
|
* called by the constructor, and sets up all DOM references for
|
|
* pre-existing markup, and creates required markup if it is not
|
|
* already present.
|
|
* @param {String or HTMLElement} p_oObject String or HTMLElement
|
|
* (either HTMLLIElement, HTMLOptGroupElement or HTMLOptionElement) of the
|
|
* source HTMLElement node.
|
|
* @param {Object} p_oConfig The configuration object literal containing
|
|
* the configuration for a MenuBarItem instance. See the configuration
|
|
* class documentation for more details.
|
|
*/
|
|
YAHOO.widget.MenuBarItem.prototype.init = function(p_oObject, p_oConfig) {
|
|
|
|
if(!this.SUBMENU_TYPE) {
|
|
|
|
this.SUBMENU_TYPE = YAHOO.widget.Menu;
|
|
|
|
}
|
|
|
|
if(!this.SUBMENU_ITEM_TYPE) {
|
|
|
|
this.SUBMENU_ITEM_TYPE = YAHOO.widget.MenuItem;
|
|
|
|
}
|
|
|
|
/*
|
|
Call the init of the superclass (YAHOO.widget.MenuModuleItem)
|
|
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);
|
|
|
|
// Add event handlers to each "MenuBarItem" instance
|
|
|
|
this.keyDownEvent.subscribe(this._onKeyDown, this, true);
|
|
|
|
var oConfig = this.cfg;
|
|
|
|
if(p_oConfig) {
|
|
|
|
oConfig.applyConfig(p_oConfig, true);
|
|
|
|
}
|
|
|
|
oConfig.fireQueue();
|
|
|
|
};
|
|
|
|
// Constants
|
|
|
|
/**
|
|
* Constant representing the CSS class(es) to be applied to the root
|
|
* HTMLLIElement of the MenuBarItem.
|
|
* @final
|
|
* @type String
|
|
*/
|
|
YAHOO.widget.MenuBarItem.prototype.CSS_CLASS_NAME = "yuimenubaritem";
|
|
|
|
/**
|
|
* Constant representing the path to the image to be used for the submenu
|
|
* arrow indicator.
|
|
* @final
|
|
* @type String
|
|
*/
|
|
YAHOO.widget.MenuBarItem.prototype.SUBMENU_INDICATOR_IMAGE_PATH =
|
|
"nt/ic/ut/alt1/menuarodwn8_nrm_1.gif";
|
|
|
|
/**
|
|
* Constant representing the path to the image to be used for the submenu
|
|
* arrow indicator when a MenuBarItem instance is selected.
|
|
* @final
|
|
* @type String
|
|
*/
|
|
YAHOO.widget.MenuBarItem.prototype.SELECTED_SUBMENU_INDICATOR_IMAGE_PATH =
|
|
"nt/ic/ut/alt1/menuarodwn8_hov_1.gif";
|
|
|
|
/**
|
|
* Constant representing the path to the image to be used for the submenu
|
|
* arrow indicator when a MenuBarItem instance is disabled.
|
|
* @final
|
|
* @type String
|
|
*/
|
|
YAHOO.widget.MenuBarItem.prototype.DISABLED_SUBMENU_INDICATOR_IMAGE_PATH =
|
|
"nt/ic/ut/alt1/menuarodwn8_dim_1.gif";
|
|
|
|
// Private event handlers
|
|
|
|
/**
|
|
* "keydown" Custom Event handler for a MenuBarItem instance.
|
|
* @private
|
|
* @param {String} p_sType The name of the event that was fired.
|
|
* @param {Array} p_aArgs Collection of arguments sent when the event
|
|
* was fired.
|
|
* @param {YAHOO.widget.MenuBarItem} p_oMenuModule The MenuModule instance that
|
|
* fired the event.
|
|
*/
|
|
YAHOO.widget.MenuBarItem.prototype._onKeyDown =
|
|
|
|
function(p_sType, p_aArgs, p_oMenuItem) {
|
|
|
|
var Event = YAHOO.util.Event;
|
|
var oDOMEvent = p_aArgs[0];
|
|
var oConfig = this.cfg;
|
|
var oParent = this.parent;
|
|
|
|
switch(oDOMEvent.keyCode) {
|
|
|
|
case 37: // Left arrow
|
|
case 39: // Right arrow
|
|
|
|
if(
|
|
this == oParent.activeItem &&
|
|
!oConfig.getProperty("selected")
|
|
) {
|
|
|
|
oConfig.setProperty("selected", true);
|
|
|
|
}
|
|
else {
|
|
|
|
var oNextItem = (oDOMEvent.keyCode == 37) ?
|
|
this.getPreviousEnabledSibling() :
|
|
this.getNextEnabledSibling();
|
|
|
|
if(oNextItem) {
|
|
|
|
oParent.clearActiveItem();
|
|
|
|
oNextItem.cfg.setProperty("selected", true);
|
|
|
|
oNextItem.focus();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Event.preventDefault(oDOMEvent);
|
|
|
|
break;
|
|
|
|
case 40: // Down arrow
|
|
|
|
oParent.clearActiveItem();
|
|
|
|
oConfig.setProperty("selected", true);
|
|
|
|
this.focus();
|
|
|
|
var oSubmenu = oConfig.getProperty("submenu");
|
|
|
|
if(oSubmenu) {
|
|
|
|
oSubmenu.show();
|
|
oSubmenu.setInitialSelection();
|
|
|
|
}
|
|
|
|
Event.preventDefault(oDOMEvent);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}; |