mirror of
https://github.com/moodle/moodle.git
synced 2025-08-04 00:16:46 +02:00
5414 lines
No EOL
139 KiB
JavaScript
Executable file
5414 lines
No EOL
139 KiB
JavaScript
Executable file
/*
|
|
Copyright (c) 2006, Yahoo! Inc. All rights reserved.
|
|
Code licensed under the BSD License:
|
|
http://developer.yahoo.net/yui/license.txt
|
|
Version 0.11.0
|
|
*/
|
|
|
|
|
|
/**
|
|
* @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);
|
|
|
|
|
|
// 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
|
|
|
|
/**
|
|
* 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;
|
|
|
|
|
|
/**
|
|
* Reference to the item the mouse is currently over.
|
|
* @private
|
|
* @type {YAHOO.widget.MenuModuleItem}
|
|
*/
|
|
YAHOO.widget.MenuModule.prototype._oCurrentItem = null;
|
|
|
|
|
|
/**
|
|
* 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;
|
|
|
|
|
|
// 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");
|
|
|
|
}
|
|
|
|
this.logger = new YAHOO.widget.LogWriter(this.toString());
|
|
|
|
this.logger.log("Source element: " + this.srcElement.tagName);
|
|
|
|
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);
|
|
|
|
this.logger = new YAHOO.widget.LogWriter(this.toString());
|
|
|
|
this.logger.log("Source element: " + this.srcElement.tagName);
|
|
|
|
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);
|
|
|
|
this.logger = new YAHOO.widget.LogWriter(this.toString());
|
|
|
|
this.logger.log("No source element found. " +
|
|
"Created element with id: " + this.id);
|
|
|
|
}
|
|
|
|
|
|
if(this.element) {
|
|
|
|
var oEl = this.element;
|
|
var CustomEvent = YAHOO.util.CustomEvent;
|
|
|
|
Dom.addClass(oEl, this.CSS_CLASS_NAME);
|
|
|
|
// Assign DOM event handlers
|
|
|
|
Event.addListener(
|
|
oEl,
|
|
"mouseover",
|
|
this._onElementMouseOver,
|
|
this,
|
|
true
|
|
);
|
|
|
|
Event.addListener(oEl, "mouseout", this._onElementMouseOut, this, true);
|
|
Event.addListener(oEl, "mousedown", this._onDOMEvent, this, true);
|
|
Event.addListener(oEl, "mouseup", this._onDOMEvent, this, true);
|
|
Event.addListener(oEl, "click", this._onElementClick, this, true);
|
|
Event.addListener(oEl, "keydown", this._onDOMEvent, this, true);
|
|
Event.addListener(oEl, "keyup", this._onDOMEvent, this, true);
|
|
Event.addListener(oEl, "keypress", this._onDOMEvent, this, true);
|
|
|
|
|
|
// 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.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();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
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;
|
|
|
|
this.logger.log("Searching DOM for items to initialize.");
|
|
|
|
switch(this.srcElement.tagName) {
|
|
|
|
case "DIV":
|
|
|
|
if(this._aListElements.length > 0) {
|
|
|
|
this.logger.log("Found " +
|
|
this._aListElements.length + " item groups to initialize.");
|
|
|
|
var i = this._aListElements.length - 1;
|
|
|
|
do {
|
|
|
|
oNode = this._aListElements[i].firstChild;
|
|
|
|
this.logger.log("Scanning " +
|
|
this._aListElements[i].childNodes.length +
|
|
" child nodes for items to initialize.");
|
|
|
|
do {
|
|
|
|
switch(oNode.tagName) {
|
|
|
|
case "LI":
|
|
|
|
this.logger.log("Initializing " +
|
|
oNode.tagName + " node.");
|
|
|
|
this.addItem(new this.ITEM_TYPE(oNode), i);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
while((oNode = oNode.nextSibling));
|
|
|
|
}
|
|
while(i--);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case "SELECT":
|
|
|
|
this.logger.log("Scanning " + this.srcElement.childNodes.length +
|
|
" child nodes for items to initialize.");
|
|
|
|
oNode = this.srcElement.firstChild;
|
|
|
|
do {
|
|
|
|
switch(oNode.tagName) {
|
|
|
|
case "OPTGROUP":
|
|
case "OPTION":
|
|
|
|
this.logger.log("Initializing " +
|
|
oNode.tagName + " node.");
|
|
|
|
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")) {
|
|
|
|
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 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) {
|
|
|
|
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) {
|
|
|
|
this._aListElements[nGroupIndex].insertBefore(
|
|
oGroupItem.element,
|
|
oNextItemSibling.element
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
oGroupItem.parent = this;
|
|
|
|
this._subscribeToItemEvents(oGroupItem);
|
|
|
|
this._configureItemSubmenuModule(oGroupItem);
|
|
|
|
this._updateItemProperties(nGroupIndex);
|
|
|
|
this.logger.log("Item inserted." +
|
|
" Text: " + oGroupItem.cfg.getProperty("text") + ", " +
|
|
" Index: " + oGroupItem.index + ", " +
|
|
" Group Index: " + oGroupItem.groupIndex);
|
|
|
|
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");
|
|
|
|
}
|
|
|
|
this.logger.log("Item added." +
|
|
" Text: " + oGroupItem.cfg.getProperty("text") + ", " +
|
|
" Index: " + oGroupItem.index + ", " +
|
|
" Group Index: " + oGroupItem.groupIndex);
|
|
|
|
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;
|
|
|
|
};
|
|
|
|
|
|
/**
|
|
* Determines if a DOM event was fired on an item and (if so) fires the item's
|
|
* associated Custom Event
|
|
* @private
|
|
* @param {HTMLElement} p_oElement The original target of the event.
|
|
* @param {String} p_sEventType The type/name of the Custom Event to fire.
|
|
* @param {Event} p_oDOMEvent The DOM event to pass back when firing the
|
|
* Custom Event.
|
|
* @return An item.
|
|
* @type YAHOO.widget.MenuModuleItem
|
|
*/
|
|
YAHOO.widget.MenuModule.prototype._fireItemEvent =
|
|
|
|
function(p_oElement, p_sEventType, p_oDOMEvent) {
|
|
|
|
var me = this;
|
|
|
|
/**
|
|
* Returns the specified element's parent HTMLLIElement (<LI<)
|
|
* @param {p_oElement} An HTMLElement node
|
|
* @ignore
|
|
* @return Returns an HTMLElement node
|
|
* @type HTMLElement
|
|
*/
|
|
function getItemElement(p_oElement) {
|
|
|
|
if(p_oElement == me.element) {
|
|
|
|
return;
|
|
|
|
}
|
|
else if(p_oElement.tagName == "LI") {
|
|
|
|
return p_oElement;
|
|
|
|
}
|
|
else if(p_oElement.parentNode) {
|
|
|
|
return getItemElement(p_oElement.parentNode);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
var oElement = getItemElement(p_oElement);
|
|
|
|
if(oElement) {
|
|
|
|
/*
|
|
Retrieve the item that corresponds to the
|
|
HTMLLIElement (<LI<) and fire the Custom Event
|
|
*/
|
|
|
|
var nGroupIndex = parseInt(oElement.getAttribute("groupindex"), 10);
|
|
var nIndex = parseInt(oElement.getAttribute("index"), 10);
|
|
var oItem = this._aItemGroups[nGroupIndex][nIndex];
|
|
|
|
if(!oItem.cfg.getProperty("disabled")) {
|
|
|
|
oItem[p_sEventType].fire(p_oDOMEvent);
|
|
|
|
return oItem;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
// Private DOM event handlers
|
|
|
|
/**
|
|
* Generic event handler for the MenuModule's root HTMLDivElement node. Used
|
|
* to handle "mousedown," "mouseup," "keydown," "keyup," and "keypress" events.
|
|
* @private
|
|
* @param {Event} p_oEvent Event object passed back by the event
|
|
* utility (YAHOO.util.Event).
|
|
* @param {YAHOO.widget.MenuModule} p_oMenuModule The MenuModule instance
|
|
* corresponding to the HTMLDivElement that fired the event.
|
|
*/
|
|
YAHOO.widget.MenuModule.prototype._onDOMEvent =
|
|
|
|
function(p_oEvent, p_oMenuModule) {
|
|
|
|
var Event = this._oEventUtil;
|
|
|
|
// Map of DOM event types to Custom Event types
|
|
|
|
var oEventTypes = {
|
|
"mousedown": "mouseDownEvent",
|
|
"mouseup": "mouseUpEvent",
|
|
"keydown": "keyDownEvent",
|
|
"keyup": "keyUpEvent",
|
|
"keypress": "keyPressEvent"
|
|
};
|
|
|
|
var sCustomEventType = oEventTypes[p_oEvent.type];
|
|
|
|
var oTarget = Event.getTarget(p_oEvent);
|
|
|
|
/*
|
|
Check if the target was an element that is a part of a
|
|
an item and (if so), fire the associated custom event.
|
|
*/
|
|
|
|
this._fireItemEvent(oTarget, sCustomEventType, p_oEvent);
|
|
|
|
|
|
// Fire the associated custom event for the MenuModule
|
|
|
|
this[sCustomEventType].fire(p_oEvent);
|
|
|
|
|
|
/*
|
|
Stop the propagation of the event at each MenuModule instance
|
|
since menus can be embedded in eachother.
|
|
*/
|
|
|
|
Event.stopPropagation(p_oEvent);
|
|
|
|
};
|
|
|
|
|
|
/**
|
|
* "mouseover" event handler for the MenuModule's root HTMLDivElement node.
|
|
* @private
|
|
* @param {Event} p_oEvent Event object passed back by the event
|
|
* utility (YAHOO.util.Event).
|
|
* @param {YAHOO.widget.MenuModule} p_oMenuModule The MenuModule instance
|
|
* corresponding to the HTMLDivElement that fired the event.
|
|
*/
|
|
YAHOO.widget.MenuModule.prototype._onElementMouseOver =
|
|
|
|
function(p_oEvent, p_oMenuModule) {
|
|
|
|
var Event = this._oEventUtil;
|
|
var oTarget = Event.getTarget(p_oEvent);
|
|
|
|
if(
|
|
(
|
|
oTarget == this.element ||
|
|
this._oDom.isAncestor(this.element, oTarget)
|
|
) &&
|
|
!this._bFiredMouseOverEvent
|
|
) {
|
|
|
|
// Fire the "mouseover" Custom Event for the MenuModule instance
|
|
|
|
this.mouseOverEvent.fire(p_oEvent);
|
|
|
|
this._bFiredMouseOverEvent = true;
|
|
this._bFiredMouseOutEvent = false;
|
|
|
|
}
|
|
|
|
|
|
/*
|
|
Check if the target was an element that is a part of an item
|
|
and (if so), fire the "mouseover" Custom Event.
|
|
*/
|
|
|
|
if(!this._oCurrentItem) {
|
|
|
|
this._oCurrentItem =
|
|
this._fireItemEvent(oTarget, "mouseOverEvent", p_oEvent);
|
|
|
|
}
|
|
|
|
|
|
/*
|
|
Stop the propagation of the event at each MenuModule instance
|
|
since menus can be embedded in eachother.
|
|
*/
|
|
|
|
Event.stopPropagation(p_oEvent);
|
|
|
|
};
|
|
|
|
|
|
/**
|
|
* "mouseout" event handler for the MenuModule's root HTMLDivElement node.
|
|
* @private
|
|
* @param {Event} p_oEvent Event object passed back by the event
|
|
* utility (YAHOO.util.Event).
|
|
* @param {YAHOO.widget.MenuModule} p_oMenuModule The MenuModule instance
|
|
* corresponding to the HTMLDivElement that fired the event.
|
|
*/
|
|
YAHOO.widget.MenuModule.prototype._onElementMouseOut =
|
|
|
|
function(p_oEvent, p_oMenuModule) {
|
|
|
|
var Dom = this._oDom;
|
|
var Event = this._oEventUtil;
|
|
var oRelatedTarget = Event.getRelatedTarget(p_oEvent);
|
|
var bLIMouseOut = true;
|
|
var bMovingToSubmenu = false;
|
|
|
|
|
|
// Determine where the mouse is going
|
|
|
|
if(this._oCurrentItem && oRelatedTarget) {
|
|
|
|
if(
|
|
oRelatedTarget == this._oCurrentItem.element ||
|
|
Dom.isAncestor(this._oCurrentItem.element, oRelatedTarget)
|
|
) {
|
|
|
|
bLIMouseOut = false;
|
|
|
|
}
|
|
|
|
|
|
var oSubmenu = this._oCurrentItem.cfg.getProperty("submenu");
|
|
|
|
if(
|
|
oSubmenu &&
|
|
(
|
|
oRelatedTarget == oSubmenu.element ||
|
|
Dom.isAncestor(oSubmenu.element, oRelatedTarget)
|
|
)
|
|
) {
|
|
|
|
bMovingToSubmenu = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
if(this._oCurrentItem && (bLIMouseOut || bMovingToSubmenu)) {
|
|
|
|
// Fire the "mouseout" Custom Event for the item
|
|
|
|
this._oCurrentItem.mouseOutEvent.fire(p_oEvent);
|
|
|
|
this._oCurrentItem = null;
|
|
|
|
}
|
|
|
|
|
|
if(
|
|
!this._bFiredMouseOutEvent &&
|
|
(
|
|
!Dom.isAncestor(this.element, oRelatedTarget) ||
|
|
bMovingToSubmenu
|
|
)
|
|
) {
|
|
|
|
// Fire the "mouseout" Custom Event for the MenuModule instance
|
|
|
|
this.mouseOutEvent.fire(p_oEvent);
|
|
|
|
this._bFiredMouseOutEvent = true;
|
|
this._bFiredMouseOverEvent = false;
|
|
|
|
}
|
|
|
|
|
|
/*
|
|
Stop the propagation of the event at each MenuModule instance
|
|
since menus can be embedded in eachother.
|
|
*/
|
|
|
|
Event.stopPropagation(p_oEvent);
|
|
|
|
};
|
|
|
|
|
|
/**
|
|
* "click" event handler for the MenuModule's root HTMLDivElement node.
|
|
* @private
|
|
* @param {Event} p_oEvent Event object passed back by the
|
|
* event utility (YAHOO.util.Event).
|
|
* @param {YAHOO.widget.MenuModule} p_oMenuModule The MenuModule instance
|
|
* corresponding to the HTMLDivElement that fired the event.
|
|
*/
|
|
YAHOO.widget.MenuModule.prototype._onElementClick =
|
|
|
|
function(p_oEvent, p_oMenuModule) {
|
|
|
|
var Event = this._oEventUtil;
|
|
|
|
var oTarget = Event.getTarget(p_oEvent);
|
|
|
|
/*
|
|
Check if the target was a DOM element that is a part of an
|
|
item and (if so), fire the associated "click"
|
|
Custom Event.
|
|
*/
|
|
|
|
var oItem = this._fireItemEvent(oTarget, "clickEvent", p_oEvent);
|
|
|
|
var bCurrentPageURL; // Indicates if the URL points to the current page
|
|
|
|
|
|
if(oItem) {
|
|
|
|
var sURL = oItem.cfg.getProperty("url");
|
|
var oSubmenu = oItem.cfg.getProperty("submenu");
|
|
|
|
bCurrentPageURL = (sURL.substr((sURL.length-1),1) == "#");
|
|
|
|
/*
|
|
ACCESSIBILITY FEATURE FOR SCREEN READERS: Expand/collapse the
|
|
submenu when the user clicks on the submenu indicator image.
|
|
*/
|
|
|
|
if(oTarget == oItem.submenuIndicator && oSubmenu) {
|
|
|
|
if(oSubmenu.cfg.getProperty("visible")) {
|
|
|
|
oSubmenu.hide();
|
|
|
|
}
|
|
else {
|
|
|
|
var oActiveItem = this.activeItem;
|
|
|
|
|
|
// Hide any other submenus that might be visible
|
|
|
|
if(oActiveItem && oActiveItem != this) {
|
|
|
|
this.clearActiveItem();
|
|
|
|
}
|
|
|
|
this.activeItem = oItem;
|
|
|
|
oItem.cfg.setProperty("selected", true);
|
|
|
|
oSubmenu.show();
|
|
|
|
}
|
|
|
|
}
|
|
else if(oTarget.tagName != "A" && !bCurrentPageURL) {
|
|
|
|
/*
|
|
Follow the URL of the item regardless of whether or
|
|
not the user clicked specifically on the
|
|
HTMLAnchorElement (<A<) node.
|
|
*/
|
|
|
|
document.location = sURL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
switch(oTarget.tagName) {
|
|
|
|
case "A":
|
|
|
|
if(bCurrentPageURL) {
|
|
|
|
// Don't follow URLs that are equal to "#"
|
|
|
|
Event.preventDefault(p_oEvent);
|
|
|
|
}
|
|
else {
|
|
|
|
/*
|
|
Break if the anchor's URL is something other than "#"
|
|
to prevent the call to "stopPropagation" from be
|
|
executed. This is required for Safari to be able to
|
|
follow the URL.
|
|
*/
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
default:
|
|
|
|
/*
|
|
Stop the propagation of the event at each MenuModule
|
|
instance since Menus can be embedded in eachother.
|
|
*/
|
|
|
|
Event.stopPropagation(p_oEvent);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
// Fire the associated "click" Custom Event for the MenuModule instance
|
|
|
|
this.clickEvent.fire(p_oEvent);
|
|
|
|
};
|
|
|
|
|
|
// Private Custom Event handlers
|
|
|
|
|
|
/**
|
|
* "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 "iframe" and "constraintoviewport" configuration
|
|
properties to match the parent MenuModule
|
|
*/
|
|
|
|
var oParentMenu = p_oSubmenu.parent.parent;
|
|
|
|
p_oSubmenu.cfg.applyConfig(
|
|
|
|
{
|
|
constraintoviewport:
|
|
oParentMenu.cfg.getProperty("constraintoviewport"),
|
|
|
|
xy: [0,0],
|
|
|
|
iframe: oParentMenu.cfg.getProperty("iframe")
|
|
|
|
}
|
|
|
|
);
|
|
|
|
|
|
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.
|
|
* @see YAHOO.widget.Overlay#configIframe
|
|
*/
|
|
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);
|
|
|
|
};
|
|
|
|
|
|
// 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();
|
|
|
|
this.logger.log("Item removed." +
|
|
" Text: " + oItem.cfg.getProperty("text") + ", " +
|
|
" Index: " + oItem.index + ", " +
|
|
" Group Index: " + oItem.groupIndex);
|
|
|
|
return oItem;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
/**
|
|
* Returns a multi-dimensional array of all of a MenuModule's items.
|
|
* @return An array of items.
|
|
* @type Array
|
|
*/
|
|
YAHOO.widget.MenuModule.prototype.getItemGroups = function() {
|
|
|
|
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 DOM event handlers
|
|
|
|
this._oEventUtil.purgeElement(this.element);
|
|
|
|
|
|
// Remove Custom Event listeners
|
|
|
|
this.mouseOverEvent.unsubscribeAll();
|
|
this.mouseOutEvent.unsubscribeAll();
|
|
this.mouseDownEvent.unsubscribeAll();
|
|
this.mouseUpEvent.unsubscribeAll();
|
|
this.clickEvent.unsubscribeAll();
|
|
this.keyPressEvent.unsubscribeAll();
|
|
this.keyDownEvent.unsubscribeAll();
|
|
this.keyUpEvent.unsubscribeAll();
|
|
this.beforeMoveEvent.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);
|
|
|
|
this.logger.log("Destroyed.");
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/**
|
|
* 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
|
|
}
|
|
);
|
|
|
|
oConfig.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,
|
|
|
|
|
|
// 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 sText = null;
|
|
|
|
|
|
// Capture the "text" and/or the "URL"
|
|
|
|
if(oAnchor) {
|
|
|
|
sURL = oAnchor.getAttribute("href");
|
|
|
|
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("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);
|
|
|
|
|
|
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])));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
// 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 "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[2] = oEM;
|
|
|
|
}
|
|
|
|
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 oImg = document.createElement("img");
|
|
oImg.src = sPath;
|
|
oImg.name = sPath;
|
|
oImg.id = sPath;
|
|
oImg.style.display = "none";
|
|
|
|
document.body.appendChild(oImg);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
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(
|
|
"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.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.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")
|
|
) {
|
|
|
|
if(oActiveItem) {
|
|
|
|
oActiveItem.blur();
|
|
|
|
}
|
|
|
|
oAnchor.focus();
|
|
|
|
/*
|
|
Opera 8.5 doesn't always focus the anchor if a MenuModuleItem
|
|
instance has a submenu, this is fixed by calling "focus"
|
|
twice.
|
|
*/
|
|
if(oParent && this.browser == "opera" && this._oSubmenu) {
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
this.logger.log("Browser font sized changed.");
|
|
|
|
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);
|
|
|
|
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.MenuModule} 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.MenuModule} 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.MenuModule} 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();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
// 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 oImg = document.createElement("img");
|
|
oImg.src = sPath;
|
|
oImg.name = sPath;
|
|
oImg.id = sPath;
|
|
oImg.style.display = "none";
|
|
|
|
document.body.appendChild(oImg);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
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
|
|
}
|
|
);
|
|
|
|
};
|
|
|
|
|
|
/**
|
|
* @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);
|
|
|
|
|
|
YAHOO.widget.ContextMenu.prototype._oTrigger = 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);
|
|
|
|
|
|
};
|
|
|
|
|
|
// Private event handlers
|
|
|
|
/**
|
|
* "mousedown" 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._onDocumentMouseDown =
|
|
|
|
function(p_oEvent, p_oMenu) {
|
|
|
|
var oTarget = YAHOO.util.Event.getTarget(p_oEvent);
|
|
var oTargetEl = this._oTargetElement;
|
|
|
|
if(
|
|
oTarget != oTargetEl ||
|
|
!YAHOO.util.Dom.isAncestor(oTargetEl, oTarget)
|
|
) {
|
|
|
|
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;
|
|
|
|
if(p_oEvent.type == "mousedown") {
|
|
|
|
if(!p_oEvent.ctrlKey) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
Event.stopEvent(p_oEvent);
|
|
|
|
}
|
|
|
|
|
|
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( { x:nX, y:nY, visible:true } );
|
|
oConfig.fireQueue();
|
|
|
|
|
|
// Prevent the browser's default context menu from appearing
|
|
|
|
Event.preventDefault(p_oEvent);
|
|
|
|
};
|
|
|
|
|
|
// Public properties
|
|
|
|
/**
|
|
* Returns the HTMLElement node that was the target of the "contextmenu"
|
|
* DOM event.
|
|
* @type HTMLElement
|
|
*/
|
|
YAHOO.widget.ContextMenu.prototype.contextEventTarget = null;
|
|
|
|
|
|
// 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,
|
|
"mousedown",
|
|
this._onDocumentMouseDown,
|
|
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.MenuModule} 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;
|
|
|
|
}
|
|
|
|
}; |