2 Copyright (c) 2007, Yahoo! Inc. All rights reserved.
3 Code licensed under the BSD License:
4 http://developer.yahoo.net/yui/license.txt
11 * @description <p>The Menu family of components features a collection of
12 * controls that make it easy to add menus to your website or web application.
13 * With the Menu Controls you can create website fly-out menus, customized
14 * context menus, or application-style menu bars with just a small amount of
15 * scripting.</p><p>The Menu family of controls features:</p>
17 * <li>Screen-reader accessibility.</li>
18 * <li>Keyboard and mouse navigation.</li>
19 * <li>A rich event model that provides access to all of a menu's
20 * interesting moments.</li>
22 * <a href="http://en.wikipedia.org/wiki/Progressive_Enhancement">Progressive
23 * Enhancement</a>; Menus can be created from simple,
24 * semantic markup on the page or purely through JavaScript.</li>
27 * @namespace YAHOO.widget
28 * @requires Event, Dom, Container
32 var Dom
= YAHOO
.util
.Dom
,
33 Event
= YAHOO
.util
.Event
;
37 * Singleton that manages a collection of all menus and menu items. Listens
38 * for DOM events at the document level and dispatches the events to the
39 * corresponding menu or menu item.
41 * @namespace YAHOO.widget
45 YAHOO
.widget
.MenuManager = function () {
47 // Private member variables
50 // Flag indicating if the DOM event handlers have been attached
52 var m_bInitializedEventHandlers
= false,
55 // Collection of menus
60 // Collection of visible menus
65 // Collection of menu items
70 // Map of DOM event types to their equivalent CustomEvent types
73 "click": "clickEvent",
74 "mousedown": "mouseDownEvent",
75 "mouseup": "mouseUpEvent",
76 "mouseover": "mouseOverEvent",
77 "mouseout": "mouseOutEvent",
78 "keydown": "keyDownEvent",
79 "keyup": "keyUpEvent",
80 "keypress": "keyPressEvent"
84 m_oFocusedMenuItem
= null;
94 * @method getMenuRootElement
95 * @description Finds the root DIV node of a menu or the root LI node of
98 * @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/
99 * level-one-html.html#ID-58190037">HTMLElement</a>} p_oElement Object
100 * specifying an HTML element.
102 function getMenuRootElement(p_oElement
) {
106 if (p_oElement
&& p_oElement
.tagName
) {
108 switch (p_oElement
.tagName
.toUpperCase()) {
112 oParentNode
= p_oElement
.parentNode
;
114 // Check if the DIV is the inner "body" node of a menu
118 Dom
.hasClass(p_oElement
, "hd") ||
119 Dom
.hasClass(p_oElement
, "bd") ||
120 Dom
.hasClass(p_oElement
, "ft")
123 oParentNode
.tagName
&&
124 oParentNode
.tagName
.toUpperCase() == "DIV")
144 oParentNode
= p_oElement
.parentNode
;
148 return getMenuRootElement(oParentNode
);
162 // Private event handlers
167 * @description Generic, global event handler for all of a menu's
168 * DOM-based events. This listens for events against the document
169 * object. If the target of a given event is a member of a menu or
170 * menu item's DOM, the instance's corresponding Custom Event is fired.
172 * @param {Event} p_oEvent Object representing the DOM event object
173 * passed back by the event utility (YAHOO.util.Event).
175 function onDOMEvent(p_oEvent
) {
177 // Get the target node of the DOM event
179 var oTarget
= Event
.getTarget(p_oEvent
),
181 // See if the target of the event was a menu, or a menu item
183 oElement
= getMenuRootElement(oTarget
),
193 sTagName
= oElement
.tagName
.toUpperCase();
195 if (sTagName
== "LI") {
199 if (sId
&& m_oItems
[sId
]) {
201 oMenuItem
= m_oItems
[sId
];
202 oMenu
= oMenuItem
.parent
;
207 else if (sTagName
== "DIV") {
211 oMenu
= m_oMenus
[oElement
.id
];
222 sCustomEventType
= m_oEventTypes
[p_oEvent
.type
];
225 // Fire the Custom Event that corresponds the current DOM event
227 if (oMenuItem
&& !oMenuItem
.cfg
.getProperty("disabled")) {
229 oMenuItem
[sCustomEventType
].fire(p_oEvent
);
233 p_oEvent
.type
== "keyup" ||
234 p_oEvent
.type
== "mousedown")
237 if (m_oFocusedMenuItem
!= oMenuItem
) {
239 if (m_oFocusedMenuItem
) {
241 m_oFocusedMenuItem
.blurEvent
.fire();
245 oMenuItem
.focusEvent
.fire();
253 oMenu
[sCustomEventType
].fire(p_oEvent
, oMenuItem
);
256 else if (p_oEvent
.type
== "mousedown") {
258 if (m_oFocusedMenuItem
) {
260 m_oFocusedMenuItem
.blurEvent
.fire();
262 m_oFocusedMenuItem
= null;
268 If the target of the event wasn't a menu, hide all
269 dynamically positioned menus
272 for (var i
in m_oMenus
) {
274 if (YAHOO
.lang
.hasOwnProperty(m_oMenus
,i
)) {
278 if (oMenu
.cfg
.getProperty("clicktohide") &&
279 !(oMenu
instanceof YAHOO
.widget
.MenuBar
) &&
280 oMenu
.cfg
.getProperty("position") == "dynamic") {
287 oMenu
.clearActiveItem(true);
296 else if (p_oEvent
.type
== "keyup") {
298 if (m_oFocusedMenuItem
) {
300 m_oFocusedMenuItem
.blurEvent
.fire();
302 m_oFocusedMenuItem
= null;
312 * @method onMenuDestroy
313 * @description "destroy" event handler for a menu.
315 * @param {String} p_sType String representing the name of the event
317 * @param {Array} p_aArgs Array of arguments sent when the event
319 * @param {YAHOO.widget.Menu} p_oMenu The menu that fired the event.
321 function onMenuDestroy(p_sType
, p_aArgs
, p_oMenu
) {
323 if (m_oMenus
[p_oMenu
.id
]) {
325 this.removeMenu(p_oMenu
);
333 * @method onMenuFocus
334 * @description "focus" event handler for a MenuItem instance.
336 * @param {String} p_sType String representing the name of the event
338 * @param {Array} p_aArgs Array of arguments sent when the event
341 function onMenuFocus(p_sType
, p_aArgs
) {
343 var oItem
= p_aArgs
[0];
347 m_oFocusedMenuItem
= oItem
;
356 * @description "blur" event handler for a MenuItem instance.
358 * @param {String} p_sType String representing the name of the event
360 * @param {Array} p_aArgs Array of arguments sent when the event
363 function onMenuBlur(p_sType
, p_aArgs
) {
365 m_oFocusedMenuItem
= null;
372 * @method onMenuVisibleConfigChange
373 * @description Event handler for when the "visible" configuration
374 * property of a Menu instance changes.
376 * @param {String} p_sType String representing the name of the event
378 * @param {Array} p_aArgs Array of arguments sent when the event
381 function onMenuVisibleConfigChange(p_sType
, p_aArgs
) {
383 var bVisible
= p_aArgs
[0],
388 m_oVisibleMenus
[sId
] = this;
392 else if (m_oVisibleMenus
[sId
]) {
394 delete m_oVisibleMenus
[sId
];
403 * @method onItemDestroy
404 * @description "destroy" event handler for a MenuItem instance.
406 * @param {String} p_sType String representing the name of the event
408 * @param {Array} p_aArgs Array of arguments sent when the event
411 function onItemDestroy(p_sType
, p_aArgs
) {
415 if (sId
&& m_oItems
[sId
]) {
417 if (m_oFocusedMenuItem
== this) {
419 m_oFocusedMenuItem
= null;
423 delete m_oItems
[sId
];
432 * @method onItemAdded
433 * @description "itemadded" event handler for a Menu instance.
435 * @param {String} p_sType String representing the name of the event
437 * @param {Array} p_aArgs Array of arguments sent when the event
440 function onItemAdded(p_sType
, p_aArgs
) {
442 var oItem
= p_aArgs
[0],
445 if (oItem
instanceof YAHOO
.widget
.MenuItem
) {
449 if (!m_oItems
[sId
]) {
451 m_oItems
[sId
] = oItem
;
453 oItem
.destroyEvent
.subscribe(onItemDestroy
);
465 // Privileged methods
470 * @description Adds a menu to the collection of known menus.
471 * @param {YAHOO.widget.Menu} p_oMenu Object specifying the Menu
472 * instance to be added.
474 addMenu: function (p_oMenu
) {
479 p_oMenu
instanceof YAHOO
.widget
.Menu
&&
481 !m_oMenus
[p_oMenu
.id
]
484 m_oMenus
[p_oMenu
.id
] = p_oMenu
;
487 if (!m_bInitializedEventHandlers
) {
491 Event
.on(oDoc
, "mouseover", onDOMEvent
, this, true);
492 Event
.on(oDoc
, "mouseout", onDOMEvent
, this, true);
493 Event
.on(oDoc
, "mousedown", onDOMEvent
, this, true);
494 Event
.on(oDoc
, "mouseup", onDOMEvent
, this, true);
495 Event
.on(oDoc
, "click", onDOMEvent
, this, true);
496 Event
.on(oDoc
, "keydown", onDOMEvent
, this, true);
497 Event
.on(oDoc
, "keyup", onDOMEvent
, this, true);
498 Event
.on(oDoc
, "keypress", onDOMEvent
, this, true);
501 m_bInitializedEventHandlers
= true;
506 p_oMenu
.destroyEvent
.subscribe(
511 p_oMenu
.cfg
.subscribeToConfigEvent(
513 onMenuVisibleConfigChange
);
515 p_oMenu
.itemAddedEvent
.subscribe(onItemAdded
);
516 p_oMenu
.focusEvent
.subscribe(onMenuFocus
);
517 p_oMenu
.blurEvent
.subscribe(onMenuBlur
);
527 * @description Removes a menu from the collection of known menus.
528 * @param {YAHOO.widget.Menu} p_oMenu Object specifying the Menu
529 * instance to be removed.
531 removeMenu: function (p_oMenu
) {
539 if (m_oMenus
[sId
] == p_oMenu
) {
541 delete m_oMenus
[sId
];
545 if (m_oVisibleMenus
[sId
] == p_oMenu
) {
547 delete m_oVisibleMenus
[sId
];
560 * @method hideVisible
561 * @description Hides all visible, dynamically positioned menus
562 * (excluding instances of YAHOO.widget.MenuBar).
564 hideVisible: function () {
568 for (var i
in m_oVisibleMenus
) {
570 if (YAHOO
.lang
.hasOwnProperty(m_oVisibleMenus
,i
)) {
572 oMenu
= m_oVisibleMenus
[i
];
574 if (!(oMenu
instanceof YAHOO
.widget
.MenuBar
) &&
575 oMenu
.cfg
.getProperty("position") == "dynamic") {
590 * @description Returns an array of all menus registered with the
594 getMenus: function () {
603 * @description Returns a menu with the specified id.
604 * @param {String} p_sId String specifying the id of the
605 * <code><div></code> element representing the menu to
607 * @return {YAHOO.widget.Menu}
609 getMenu: function (p_sId
) {
611 var oMenu
= m_oMenus
[p_sId
];
623 * @method getMenuItem
624 * @description Returns a menu item with the specified id.
625 * @param {String} p_sId String specifying the id of the
626 * <code><li></code> element representing the menu item to
628 * @return {YAHOO.widget.MenuItem}
630 getMenuItem: function (p_sId
) {
632 var oItem
= m_oItems
[p_sId
];
644 * @method getMenuItemGroup
645 * @description Returns an array of menu item instances whose
646 * corresponding <code><li></code> elements are child
647 * nodes of the <code><ul></code> element with the
649 * @param {String} p_sId String specifying the id of the
650 * <code><ul></code> element representing the group of
651 * menu items to be retrieved.
654 getMenuItemGroup: function (p_sId
) {
656 var oUL
= Dom
.get(p_sId
),
663 if (oUL
&& oUL
.tagName
&&
664 oUL
.tagName
.toUpperCase() == "UL") {
666 oNode
= oUL
.firstChild
;
678 oItem
= this.getMenuItem(sId
);
682 aItems
[aItems
.length
] = oItem
;
689 while ((oNode
= oNode
.nextSibling
));
692 if (aItems
.length
> 0) {
706 * @method getFocusedMenuItem
707 * @description Returns a reference to the menu item that currently
709 * @return {YAHOO.widget.MenuItem}
711 getFocusedMenuItem: function () {
713 return m_oFocusedMenuItem
;
719 * @method getFocusedMenu
720 * @description Returns a reference to the menu that currently
722 * @return {YAHOO.widget.Menu}
724 getFocusedMenu: function () {
726 if (m_oFocusedMenuItem
) {
728 return (m_oFocusedMenuItem
.parent
.getRoot());
737 * @description Returns a string representing the menu manager.
740 toString: function () {
742 return "MenuManager";
758 * The Menu class creates a container that holds a vertical list representing
759 * a set of options or commands. Menu is the base class for all
761 * @param {String} p_oElement String specifying the id attribute of the
762 * <code><div></code> element of the menu.
763 * @param {String} p_oElement String specifying the id attribute of the
764 * <code><select></code> element to be used as the data source
766 * @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/
767 * level-one-html.html#ID-22445964">HTMLDivElement</a>} p_oElement Object
768 * specifying the <code><div></code> element of the menu.
769 * @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/
770 * level-one-html.html#ID-94282980">HTMLSelectElement</a>} p_oElement
771 * Object specifying the <code><select></code> element to be used as
772 * the data source for the menu.
773 * @param {Object} p_oConfig Optional. Object literal specifying the
774 * configuration for the menu. See configuration class documentation for
776 * @namespace YAHOO.widget
779 * @extends YAHOO.widget.Overlay
781 YAHOO
.widget
.Menu = function (p_oElement
, p_oConfig
) {
785 this.parent
= p_oConfig
.parent
;
786 this.lazyLoad
= p_oConfig
.lazyLoad
|| p_oConfig
.lazyload
;
787 this.itemData
= p_oConfig
.itemData
|| p_oConfig
.itemdata
;
792 YAHOO
.widget
.Menu
.superclass
.constructor.call(this, p_oElement
, p_oConfig
);
799 * @method checkPosition
800 * @description Checks to make sure that the value of the "position" property
801 * is one of the supported strings. Returns true if the position is supported.
803 * @param {Object} p_sPosition String specifying the position of the menu.
806 function checkPosition(p_sPosition
) {
808 if (typeof p_sPosition
== "string") {
810 return ("dynamic,static".indexOf((p_sPosition
.toLowerCase())) != -1);
817 var Dom
= YAHOO
.util
.Dom
,
818 Event
= YAHOO
.util
.Event
,
819 Module
= YAHOO
.widget
.Module
,
820 Overlay
= YAHOO
.widget
.Overlay
,
821 Menu
= YAHOO
.widget
.Menu
,
822 MenuManager
= YAHOO
.widget
.MenuManager
,
823 CustomEvent
= YAHOO
.util
.CustomEvent
,
829 * Constant representing the name of the Menu's events
830 * @property EVENT_TYPES
837 "MOUSE_OVER": "mouseover",
838 "MOUSE_OUT": "mouseout",
839 "MOUSE_DOWN": "mousedown",
840 "MOUSE_UP": "mouseup",
842 "KEY_PRESS": "keypress",
843 "KEY_DOWN": "keydown",
847 "ITEM_ADDED": "itemAdded",
848 "ITEM_REMOVED": "itemRemoved"
854 * Constant representing the Menu's configuration properties
855 * @property DEFAULT_CONFIG
865 validator
: Lang
.isBoolean
868 "CONSTRAIN_TO_VIEWPORT": {
869 key
: "constraintoviewport",
871 validator
: Lang
.isBoolean
,
872 supercedes
: ["iframe","x","y","xy"]
878 validator
: checkPosition
,
879 supercedes
: ["visible", "iframe"]
882 "SUBMENU_ALIGNMENT": {
883 key
: "submenualignment",
887 "AUTO_SUBMENU_DISPLAY": {
888 key
: "autosubmenudisplay",
890 validator
: Lang
.isBoolean
896 validator
: Lang
.isNumber
902 validator
: Lang
.isNumber
,
906 "SUBMENU_HIDE_DELAY": {
907 key
: "submenuhidedelay",
909 validator
: Lang
.isNumber
915 validator
: Lang
.isBoolean
925 validator
: Lang
.isNumber
,
926 supercedes
: ["iframe"]
932 validator
: Lang
.isString
938 validator
: Lang
.isBoolean
945 YAHOO
.lang
.extend(Menu
, Overlay
, {
952 * @property CSS_CLASS_NAME
953 * @description String representing the CSS class(es) to be applied to the
954 * menu's <code><div></code> element.
959 CSS_CLASS_NAME
: "yuimenu",
963 * @property ITEM_TYPE
964 * @description Object representing the type of menu item to instantiate and
965 * add when parsing the child nodes (either <code><li></code> element,
966 * <code><optgroup></code> element or <code><option></code>)
967 * of the menu's source HTML element.
968 * @default YAHOO.widget.MenuItem
970 * @type YAHOO.widget.MenuItem
976 * @property GROUP_TITLE_TAG_NAME
977 * @description String representing the tagname of the HTML element used to
978 * title the menu's item groups.
983 GROUP_TITLE_TAG_NAME
: "h6",
987 // Private properties
991 * @property _nHideDelayId
992 * @description Number representing the time-out setting used to cancel the
1002 * @property _nShowDelayId
1003 * @description Number representing the time-out setting used to cancel the
1004 * showing of a menu.
1009 _nShowDelayId
: null,
1013 * @property _nSubmenuHideDelayId
1014 * @description Number representing the time-out setting used to cancel the
1015 * hiding of a submenu.
1020 _nSubmenuHideDelayId
: null,
1024 * @property _nBodyScrollId
1025 * @description Number representing the time-out setting used to cancel the
1026 * scrolling of the menu's body element.
1031 _nBodyScrollId
: null,
1035 * @property _bHideDelayEventHandlersAssigned
1036 * @description Boolean indicating if the "mouseover" and "mouseout" event
1037 * handlers used for hiding the menu via a call to "window.setTimeout" have
1038 * already been assigned.
1043 _bHideDelayEventHandlersAssigned
: false,
1047 * @property _bHandledMouseOverEvent
1048 * @description Boolean indicating the current state of the menu's
1049 * "mouseover" event.
1054 _bHandledMouseOverEvent
: false,
1058 * @property _bHandledMouseOutEvent
1059 * @description Boolean indicating the current state of the menu's
1065 _bHandledMouseOutEvent
: false,
1069 * @property _aGroupTitleElements
1070 * @description Array of HTML element used to title groups of menu items.
1075 _aGroupTitleElements
: null,
1079 * @property _aItemGroups
1080 * @description Multi-dimensional Array representing the menu items as they
1081 * are grouped in the menu.
1090 * @property _aListElements
1091 * @description Array of <code><ul></code> elements, each of which is
1092 * the parent node for each item's <code><li></code> element.
1097 _aListElements
: null,
1101 * @property _nCurrentMouseX
1102 * @description The current x coordinate of the mouse inside the area of
1112 * @property _nMaxHeight
1113 * @description The original value of the "maxheight" configuration property
1114 * as set by the user.
1123 * @property _bStopMouseEventHandlers
1124 * @description Stops "mouseover," "mouseout," and "mousemove" event handlers
1130 _bStopMouseEventHandlers
: false,
1134 * @property _sClassName
1135 * @description The current value of the "classname" configuration attribute.
1144 * @property _bDisabled
1145 * @description The current value of the "disabled" configuration attribute.
1153 // Public properties
1157 * @property lazyLoad
1158 * @description Boolean indicating if the menu's "lazy load" feature is
1159 * enabled. If set to "true," initialization and rendering of the menu's
1160 * items will be deferred until the first time it is made visible. This
1161 * property should be set via the constructor using the configuration
1170 * @property itemData
1171 * @description Array of items to be added to the menu. The array can contain
1172 * strings representing the text for each item to be created, object literals
1173 * representing the menu item configuration properties, or MenuItem instances.
1174 * This property should be set via the constructor using the configuration
1183 * @property activeItem
1184 * @description Object reference to the item in the menu that has is selected.
1186 * @type YAHOO.widget.MenuItem
1193 * @description Object reference to the menu's parent menu or menu item.
1194 * This property can be set via the constructor using the configuration
1197 * @type YAHOO.widget.MenuItem
1203 * @property srcElement
1204 * @description Object reference to the HTML element (either
1205 * <code><select></code> or <code><div></code>) used to
1208 * @type <a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/
1209 * level-one-html.html#ID-94282980">HTMLSelectElement</a>|<a
1210 * href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-one-html.
1211 * html#ID-22445964">HTMLDivElement</a>
1221 * @event mouseOverEvent
1222 * @description Fires when the mouse has entered the menu. Passes back
1223 * the DOM Event object as an argument.
1225 mouseOverEvent
: null,
1229 * @event mouseOutEvent
1230 * @description Fires when the mouse has left the menu. Passes back the DOM
1231 * Event object as an argument.
1232 * @type YAHOO.util.CustomEvent
1234 mouseOutEvent
: null,
1238 * @event mouseDownEvent
1239 * @description Fires when the user mouses down on the menu. Passes back the
1240 * DOM Event object as an argument.
1241 * @type YAHOO.util.CustomEvent
1243 mouseDownEvent
: null,
1247 * @event mouseUpEvent
1248 * @description Fires when the user releases a mouse button while the mouse is
1249 * over the menu. Passes back the DOM Event object as an argument.
1250 * @type YAHOO.util.CustomEvent
1257 * @description Fires when the user clicks the on the menu. Passes back the
1258 * DOM Event object as an argument.
1259 * @type YAHOO.util.CustomEvent
1265 * @event keyPressEvent
1266 * @description Fires when the user presses an alphanumeric key when one of the
1267 * menu's items has focus. Passes back the DOM Event object as an argument.
1268 * @type YAHOO.util.CustomEvent
1270 keyPressEvent
: null,
1274 * @event keyDownEvent
1275 * @description Fires when the user presses a key when one of the menu's items
1276 * has focus. Passes back the DOM Event object as an argument.
1277 * @type YAHOO.util.CustomEvent
1284 * @description Fires when the user releases a key when one of the menu's items
1285 * has focus. Passes back the DOM Event object as an argument.
1286 * @type YAHOO.util.CustomEvent
1292 * @event itemAddedEvent
1293 * @description Fires when an item is added to the menu.
1294 * @type YAHOO.util.CustomEvent
1296 itemAddedEvent
: null,
1300 * @event itemRemovedEvent
1301 * @description Fires when an item is removed to the menu.
1302 * @type YAHOO.util.CustomEvent
1304 itemRemovedEvent
: null,
1309 * @description The Menu class's initialization method. This method is
1310 * automatically called by the constructor, and sets up all DOM references
1311 * for pre-existing markup, and creates required markup if it is not
1313 * @param {String} p_oElement String specifying the id attribute of the
1314 * <code><div></code> element of the menu.
1315 * @param {String} p_oElement String specifying the id attribute of the
1316 * <code><select></code> element to be used as the data source
1318 * @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/
1319 * level-one-html.html#ID-22445964">HTMLDivElement</a>} p_oElement Object
1320 * specifying the <code><div></code> element of the menu.
1321 * @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/
1322 * level-one-html.html#ID-94282980">HTMLSelectElement</a>} p_oElement
1323 * Object specifying the <code><select></code> element to be used as
1324 * the data source for the menu.
1325 * @param {Object} p_oConfig Optional. Object literal specifying the
1326 * configuration for the menu. See configuration class documentation for
1329 init: function (p_oElement
, p_oConfig
) {
1331 this._aItemGroups
= [];
1332 this._aListElements
= [];
1333 this._aGroupTitleElements
= [];
1335 if (!this.ITEM_TYPE
) {
1337 this.ITEM_TYPE
= YAHOO
.widget
.MenuItem
;
1344 if (typeof p_oElement
== "string") {
1346 oElement
= document
.getElementById(p_oElement
);
1349 else if (p_oElement
.tagName
) {
1351 oElement
= p_oElement
;
1356 if (oElement
&& oElement
.tagName
) {
1358 switch(oElement
.tagName
.toUpperCase()) {
1362 this.srcElement
= oElement
;
1366 oElement
.setAttribute("id", Dom
.generateId());
1372 Note: we don't pass the user config in here yet
1373 because we only want it executed once, at the lowest
1377 Menu
.superclass
.init
.call(this, oElement
);
1379 this.beforeInitEvent
.fire(Menu
);
1387 this.srcElement
= oElement
;
1391 The source element is not something that we can use
1392 outright, so we need to create a new Overlay
1394 Note: we don't pass the user config in here yet
1395 because we only want it executed once, at the lowest
1399 Menu
.superclass
.init
.call(this, Dom
.generateId());
1401 this.beforeInitEvent
.fire(Menu
);
1413 Note: we don't pass the user config in here yet
1414 because we only want it executed once, at the lowest
1418 Menu
.superclass
.init
.call(this, p_oElement
);
1420 this.beforeInitEvent
.fire(Menu
);
1429 Dom
.addClass(this.element
, this.CSS_CLASS_NAME
);
1432 // Subscribe to Custom Events
1434 this.initEvent
.subscribe(this._onInit
);
1435 this.beforeRenderEvent
.subscribe(this._onBeforeRender
);
1436 this.renderEvent
.subscribe(this._onRender
);
1437 this.renderEvent
.subscribe(this.onRender
);
1438 this.beforeShowEvent
.subscribe(this._onBeforeShow
);
1439 this.showEvent
.subscribe(this._onShow
);
1440 this.beforeHideEvent
.subscribe(this._onBeforeHide
);
1441 this.hideEvent
.subscribe(this._onHide
);
1442 this.mouseOverEvent
.subscribe(this._onMouseOver
);
1443 this.mouseOutEvent
.subscribe(this._onMouseOut
);
1444 this.clickEvent
.subscribe(this._onClick
);
1445 this.keyDownEvent
.subscribe(this._onKeyDown
);
1446 this.keyPressEvent
.subscribe(this._onKeyPress
);
1448 Module
.textResizeEvent
.subscribe(this._onTextResize
, this, true);
1453 this.cfg
.applyConfig(p_oConfig
, true);
1458 // Register the Menu instance with the MenuManager
1460 MenuManager
.addMenu(this);
1463 this.initEvent
.fire(Menu
);
1475 * @method _initSubTree
1476 * @description Iterates the childNodes of the source element to find nodes
1477 * used to instantiate menu and menu items.
1480 _initSubTree: function () {
1482 var oSrcElement
= this.srcElement
,
1494 sSrcElementTagName
=
1495 (oSrcElement
.tagName
&& oSrcElement
.tagName
.toUpperCase());
1498 if (sSrcElementTagName
== "DIV") {
1500 // Populate the collection of item groups and item group titles
1502 oNode
= this.body
.firstChild
;
1508 sGroupTitleTagName
= this.GROUP_TITLE_TAG_NAME
.toUpperCase();
1513 if (oNode
&& oNode
.tagName
) {
1515 switch (oNode
.tagName
.toUpperCase()) {
1517 case sGroupTitleTagName
:
1519 this._aGroupTitleElements
[nGroup
] = oNode
;
1525 this._aListElements
[nGroup
] = oNode
;
1526 this._aItemGroups
[nGroup
] = [];
1536 while ((oNode
= oNode
.nextSibling
));
1540 Apply the "first-of-type" class to the first UL to mimic
1541 the "first-of-type" CSS3 psuedo class.
1544 if (this._aListElements
[0]) {
1546 Dom
.addClass(this._aListElements
[0], "first-of-type");
1559 if (sSrcElementTagName
) {
1561 switch (sSrcElementTagName
) {
1565 aListElements
= this._aListElements
;
1566 nListElements
= aListElements
.length
;
1568 if (nListElements
> 0) {
1571 i
= nListElements
- 1;
1575 oNode
= aListElements
[i
].firstChild
;
1582 if (oNode
&& oNode
.tagName
&&
1583 oNode
.tagName
.toUpperCase() == "LI") {
1586 this.addItem(new this.ITEM_TYPE(oNode
,
1587 { parent
: this }), i
);
1592 while ((oNode
= oNode
.nextSibling
));
1606 oNode
= oSrcElement
.firstChild
;
1610 if (oNode
&& oNode
.tagName
) {
1612 switch (oNode
.tagName
.toUpperCase()) {
1632 while ((oNode
= oNode
.nextSibling
));
1646 * @method _getFirstEnabledItem
1647 * @description Returns the first enabled item in the menu.
1648 * @return {YAHOO.widget.MenuItem}
1651 _getFirstEnabledItem: function () {
1653 var aItems
= this.getItems(),
1654 nItems
= aItems
.length
,
1657 for(var i
=0; i
<nItems
; i
++) {
1661 if (oItem
&& !oItem
.cfg
.getProperty("disabled") &&
1662 oItem
.element
.style
.display
!= "none") {
1674 * @method _addItemToGroup
1675 * @description Adds a menu item to a group.
1677 * @param {Number} p_nGroupIndex Number indicating the group to which the
1679 * @param {YAHOO.widget.MenuItem} p_oItem Object reference for the MenuItem
1680 * instance to be added to the menu.
1681 * @param {String} p_oItem String specifying the text of the item to be added
1683 * @param {Object} p_oItem Object literal containing a set of menu item
1684 * configuration properties.
1685 * @param {Number} p_nItemIndex Optional. Number indicating the index at
1686 * which the menu item should be added.
1687 * @return {YAHOO.widget.MenuItem}
1689 _addItemToGroup: function (p_nGroupIndex
, p_oItem
, p_nItemIndex
) {
1692 bDisabled
= this.cfg
.getProperty("disabled"),
1700 function getNextItemSibling(p_aArray
, p_nStartIndex
) {
1702 return (p_aArray
[p_nStartIndex
] || getNextItemSibling(p_aArray
,
1703 (p_nStartIndex
+1)));
1707 if (p_oItem
instanceof this.ITEM_TYPE
) {
1710 oItem
.parent
= this;
1713 else if (typeof p_oItem
== "string") {
1715 oItem
= new this.ITEM_TYPE(p_oItem
, { parent
: this });
1718 else if (typeof p_oItem
== "object") {
1720 p_oItem
.parent
= this;
1722 oItem
= new this.ITEM_TYPE(p_oItem
.text
, p_oItem
);
1729 if (oItem
.cfg
.getProperty("selected")) {
1731 this.activeItem
= oItem
;
1736 nGroupIndex
= typeof p_nGroupIndex
== "number" ? p_nGroupIndex
: 0;
1737 aGroup
= this._getItemGroup(nGroupIndex
);
1743 aGroup
= this._createItemGroup(nGroupIndex
);
1748 if (typeof p_nItemIndex
== "number") {
1750 bAppend
= (p_nItemIndex
>= aGroup
.length
);
1753 if (aGroup
[p_nItemIndex
]) {
1755 aGroup
.splice(p_nItemIndex
, 0, oItem
);
1760 aGroup
[p_nItemIndex
] = oItem
;
1765 oGroupItem
= aGroup
[p_nItemIndex
];
1769 if (bAppend
&& (!oGroupItem
.element
.parentNode
||
1770 oGroupItem
.element
.parentNode
.nodeType
== 11)) {
1772 this._aListElements
[nGroupIndex
].appendChild(
1773 oGroupItem
.element
);
1778 oNextItemSibling
= getNextItemSibling(aGroup
,
1781 if (oNextItemSibling
&& (!oGroupItem
.element
.parentNode
||
1782 oGroupItem
.element
.parentNode
.nodeType
== 11)) {
1784 this._aListElements
[nGroupIndex
].insertBefore(
1786 oNextItemSibling
.element
);
1793 oGroupItem
.parent
= this;
1795 this._subscribeToItemEvents(oGroupItem
);
1797 this._configureSubmenu(oGroupItem
);
1799 this._updateItemProperties(nGroupIndex
);
1802 this.itemAddedEvent
.fire(oGroupItem
);
1803 this.changeContentEvent
.fire();
1812 nItemIndex
= aGroup
.length
;
1814 aGroup
[nItemIndex
] = oItem
;
1816 oGroupItem
= aGroup
[nItemIndex
];
1821 if (!Dom
.isAncestor(this._aListElements
[nGroupIndex
],
1822 oGroupItem
.element
)) {
1824 this._aListElements
[nGroupIndex
].appendChild(
1825 oGroupItem
.element
);
1829 oGroupItem
.element
.setAttribute("groupindex", nGroupIndex
);
1830 oGroupItem
.element
.setAttribute("index", nItemIndex
);
1832 oGroupItem
.parent
= this;
1834 oGroupItem
.index
= nItemIndex
;
1835 oGroupItem
.groupIndex
= nGroupIndex
;
1837 this._subscribeToItemEvents(oGroupItem
);
1839 this._configureSubmenu(oGroupItem
);
1841 if (nItemIndex
=== 0) {
1843 Dom
.addClass(oGroupItem
.element
, "first-of-type");
1849 this.itemAddedEvent
.fire(oGroupItem
);
1850 this.changeContentEvent
.fire();
1864 * @method _removeItemFromGroupByIndex
1865 * @description Removes a menu item from a group by index. Returns the menu
1866 * item that was removed.
1868 * @param {Number} p_nGroupIndex Number indicating the group to which the menu
1870 * @param {Number} p_nItemIndex Number indicating the index of the menu item
1872 * @return {YAHOO.widget.MenuItem}
1874 _removeItemFromGroupByIndex: function (p_nGroupIndex
, p_nItemIndex
) {
1876 var nGroupIndex
= typeof p_nGroupIndex
== "number" ? p_nGroupIndex
: 0,
1877 aGroup
= this._getItemGroup(nGroupIndex
),
1884 aArray
= aGroup
.splice(p_nItemIndex
, 1);
1889 // Update the index and className properties of each member
1891 this._updateItemProperties(nGroupIndex
);
1893 if (aGroup
.length
=== 0) {
1897 oUL
= this._aListElements
[nGroupIndex
];
1899 if (this.body
&& oUL
) {
1901 this.body
.removeChild(oUL
);
1905 // Remove the group from the array of items
1907 this._aItemGroups
.splice(nGroupIndex
, 1);
1910 // Remove the UL from the array of ULs
1912 this._aListElements
.splice(nGroupIndex
, 1);
1916 Assign the "first-of-type" class to the new first UL
1920 oUL
= this._aListElements
[0];
1924 Dom
.addClass(oUL
, "first-of-type");
1931 this.itemRemovedEvent
.fire(oItem
);
1932 this.changeContentEvent
.fire();
1935 // Return a reference to the item that was removed
1947 * @method _removeItemFromGroupByValue
1948 * @description Removes a menu item from a group by reference. Returns the
1949 * menu item that was removed.
1951 * @param {Number} p_nGroupIndex Number indicating the group to which the
1952 * menu item belongs.
1953 * @param {YAHOO.widget.MenuItem} p_oItem Object reference for the MenuItem
1954 * instance to be removed.
1955 * @return {YAHOO.widget.MenuItem}
1957 _removeItemFromGroupByValue: function (p_nGroupIndex
, p_oItem
) {
1959 var aGroup
= this._getItemGroup(p_nGroupIndex
),
1966 nItems
= aGroup
.length
;
1975 if (aGroup
[i
] == p_oItem
) {
1985 if (nItemIndex
> -1) {
1987 return (this._removeItemFromGroupByIndex(p_nGroupIndex
,
2000 * @method _updateItemProperties
2001 * @description Updates the "index," "groupindex," and "className" properties
2002 * of the menu items in the specified group.
2004 * @param {Number} p_nGroupIndex Number indicating the group of items to update.
2006 _updateItemProperties: function (p_nGroupIndex
) {
2008 var aGroup
= this._getItemGroup(p_nGroupIndex
),
2009 nItems
= aGroup
.length
,
2019 // Update the index and className properties of each member
2027 oLI
= oItem
.element
;
2030 oItem
.groupIndex
= p_nGroupIndex
;
2032 oLI
.setAttribute("groupindex", p_nGroupIndex
);
2033 oLI
.setAttribute("index", i
);
2035 Dom
.removeClass(oLI
, "first-of-type");
2045 Dom
.addClass(oLI
, "first-of-type");
2055 * @method _createItemGroup
2056 * @description Creates a new menu item group (array) and its associated
2057 * <code><ul></code> element. Returns an aray of menu item groups.
2059 * @param {Number} p_nIndex Number indicating the group to create.
2062 _createItemGroup: function (p_nIndex
) {
2066 if (!this._aItemGroups
[p_nIndex
]) {
2068 this._aItemGroups
[p_nIndex
] = [];
2070 oUL
= document
.createElement("ul");
2072 this._aListElements
[p_nIndex
] = oUL
;
2074 return this._aItemGroups
[p_nIndex
];
2082 * @method _getItemGroup
2083 * @description Returns the menu item group at the specified index.
2085 * @param {Number} p_nIndex Number indicating the index of the menu item group
2089 _getItemGroup: function (p_nIndex
) {
2091 var nIndex
= ((typeof p_nIndex
== "number") ? p_nIndex
: 0);
2093 return this._aItemGroups
[nIndex
];
2099 * @method _configureSubmenu
2100 * @description Subscribes the menu item's submenu to its parent menu's events.
2102 * @param {YAHOO.widget.MenuItem} p_oItem Object reference for the MenuItem
2103 * instance with the submenu to be configured.
2105 _configureSubmenu: function (p_oItem
) {
2107 var oSubmenu
= p_oItem
.cfg
.getProperty("submenu");
2112 Listen for configuration changes to the parent menu
2113 so they they can be applied to the submenu.
2116 this.cfg
.configChangedEvent
.subscribe(this._onParentMenuConfigChange
,
2119 this.renderEvent
.subscribe(this._onParentMenuRender
, oSubmenu
, true);
2121 oSubmenu
.beforeShowEvent
.subscribe(this._onSubmenuBeforeShow
, null,
2124 oSubmenu
.showEvent
.subscribe(this._onSubmenuShow
, null, p_oItem
);
2125 oSubmenu
.hideEvent
.subscribe(this._onSubmenuHide
, null, p_oItem
);
2133 * @method _subscribeToItemEvents
2134 * @description Subscribes a menu to a menu item's event.
2136 * @param {YAHOO.widget.MenuItem} p_oItem Object reference for the MenuItem
2137 * instance whose events should be subscribed to.
2139 _subscribeToItemEvents: function (p_oItem
) {
2141 p_oItem
.focusEvent
.subscribe(this._onMenuItemFocus
);
2143 p_oItem
.blurEvent
.subscribe(this._onMenuItemBlur
);
2145 p_oItem
.cfg
.configChangedEvent
.subscribe(this._onMenuItemConfigChange
,
2152 * @method _getOffsetWidth
2153 * @description Returns the offset width of the menu's
2154 * <code><div></code> element.
2157 _getOffsetWidth: function () {
2159 var oClone
= this.element
.cloneNode(true);
2161 Dom
.removeClass(oClone
, "visible");
2163 Dom
.setStyle(oClone
, "width", "");
2165 document
.body
.appendChild(oClone
);
2167 var sWidth
= oClone
.offsetWidth
;
2169 document
.body
.removeChild(oClone
);
2178 * @description Sets the width of the menu's root <code><div></code>
2179 * element to its offsetWidth.
2182 _setWidth: function () {
2184 var oElement
= this.element
,
2188 if (oElement
.parentNode
.tagName
.toUpperCase() == "BODY") {
2190 if (YAHOO
.env
.ua
.opera
) {
2192 sWidth
= this._getOffsetWidth();
2197 if (Dom
.hasClass(oElement
, "visible")) {
2201 Dom
.removeClass(oElement
, "visible");
2205 Dom
.setStyle(oElement
, "width", "auto");
2207 sWidth
= oElement
.offsetWidth
;
2214 sWidth
= this._getOffsetWidth();
2218 this.cfg
.setProperty("width", (sWidth
+ "px"));
2223 Dom
.addClass(oElement
, "visible");
2231 * @method _onWidthChange
2232 * @description Change event handler for the the menu's "width" configuration
2235 * @param {String} p_sType String representing the name of the event that
2237 * @param {Array} p_aArgs Array of arguments sent when the event was fired.
2239 _onWidthChange: function (p_sType
, p_aArgs
) {
2241 var sWidth
= p_aArgs
[0];
2243 if (sWidth
&& !this._hasSetWidthHandlers
) {
2245 this.itemAddedEvent
.subscribe(this._setWidth
);
2246 this.itemRemovedEvent
.subscribe(this._setWidth
);
2248 this._hasSetWidthHandlers
= true;
2251 else if (this._hasSetWidthHandlers
) {
2253 this.itemAddedEvent
.unsubscribe(this._setWidth
);
2254 this.itemRemovedEvent
.unsubscribe(this._setWidth
);
2256 this._hasSetWidthHandlers
= false;
2264 * @method _onVisibleChange
2265 * @description Change event handler for the the menu's "visible" configuration
2268 * @param {String} p_sType String representing the name of the event that
2270 * @param {Array} p_aArgs Array of arguments sent when the event was fired.
2272 _onVisibleChange: function (p_sType
, p_aArgs
) {
2274 var bVisible
= p_aArgs
[0];
2278 Dom
.addClass(this.element
, "visible");
2283 Dom
.removeClass(this.element
, "visible");
2291 * @method _cancelHideDelay
2292 * @description Cancels the call to "hideMenu."
2295 _cancelHideDelay: function () {
2297 var oRoot
= this.getRoot();
2299 if (oRoot
._nHideDelayId
) {
2301 window
.clearTimeout(oRoot
._nHideDelayId
);
2309 * @method _execHideDelay
2310 * @description Hides the menu after the number of milliseconds specified by
2311 * the "hidedelay" configuration property.
2314 _execHideDelay: function () {
2316 this._cancelHideDelay();
2318 var oRoot
= this.getRoot(),
2321 function hideMenu() {
2323 if (oRoot
.activeItem
) {
2325 oRoot
.clearActiveItem();
2329 if (oRoot
== me
&& !(me
instanceof YAHOO
.widget
.MenuBar
) &&
2330 me
.cfg
.getProperty("position") == "dynamic") {
2339 oRoot
._nHideDelayId
=
2340 window
.setTimeout(hideMenu
, oRoot
.cfg
.getProperty("hidedelay"));
2346 * @method _cancelShowDelay
2347 * @description Cancels the call to the "showMenu."
2350 _cancelShowDelay: function () {
2352 var oRoot
= this.getRoot();
2354 if (oRoot
._nShowDelayId
) {
2356 window
.clearTimeout(oRoot
._nShowDelayId
);
2364 * @method _execShowDelay
2365 * @description Shows the menu after the number of milliseconds specified by
2366 * the "showdelay" configuration property have ellapsed.
2368 * @param {YAHOO.widget.Menu} p_oMenu Object specifying the menu that should
2371 _execShowDelay: function (p_oMenu
) {
2373 var oRoot
= this.getRoot();
2375 function showMenu() {
2377 if (p_oMenu
.parent
.cfg
.getProperty("selected")) {
2386 oRoot
._nShowDelayId
=
2387 window
.setTimeout(showMenu
, oRoot
.cfg
.getProperty("showdelay"));
2393 * @method _execSubmenuHideDelay
2394 * @description Hides a submenu after the number of milliseconds specified by
2395 * the "submenuhidedelay" configuration property have ellapsed.
2397 * @param {YAHOO.widget.Menu} p_oSubmenu Object specifying the submenu that
2399 * @param {Number} p_nMouseX The x coordinate of the mouse when it left
2400 * the specified submenu's parent menu item.
2401 * @param {Number} p_nHideDelay The number of milliseconds that should ellapse
2402 * before the submenu is hidden.
2404 _execSubmenuHideDelay: function (p_oSubmenu
, p_nMouseX
, p_nHideDelay
) {
2408 p_oSubmenu
._nSubmenuHideDelayId
= window
.setTimeout(function () {
2410 if (me
._nCurrentMouseX
> (p_nMouseX
+ 10)) {
2412 p_oSubmenu
._nSubmenuHideDelayId
= window
.setTimeout(function () {
2431 // Protected methods
2435 * @method _disableScrollHeader
2436 * @description Disables the header used for scrolling the body of the menu.
2439 _disableScrollHeader: function () {
2441 if (!this._bHeaderDisabled
) {
2443 Dom
.addClass(this.header
, "topscrollbar_disabled");
2444 this._bHeaderDisabled
= true;
2452 * @method _disableScrollFooter
2453 * @description Disables the footer used for scrolling the body of the menu.
2456 _disableScrollFooter: function () {
2458 if (!this._bFooterDisabled
) {
2460 Dom
.addClass(this.footer
, "bottomscrollbar_disabled");
2461 this._bFooterDisabled
= true;
2469 * @method _enableScrollHeader
2470 * @description Enables the header used for scrolling the body of the menu.
2473 _enableScrollHeader: function () {
2475 if (this._bHeaderDisabled
) {
2477 Dom
.removeClass(this.header
, "topscrollbar_disabled");
2478 this._bHeaderDisabled
= false;
2486 * @method _enableScrollFooter
2487 * @description Enables the footer used for scrolling the body of the menu.
2490 _enableScrollFooter: function () {
2492 if (this._bFooterDisabled
) {
2494 Dom
.removeClass(this.footer
, "bottomscrollbar_disabled");
2495 this._bFooterDisabled
= false;
2503 * @method _onMouseOver
2504 * @description "mouseover" event handler for the menu.
2506 * @param {String} p_sType String representing the name of the event that
2508 * @param {Array} p_aArgs Array of arguments sent when the event was fired.
2510 _onMouseOver: function (p_sType
, p_aArgs
) {
2512 if (this._bStopMouseEventHandlers
) {
2519 var oEvent
= p_aArgs
[0],
2521 oTarget
= Event
.getTarget(oEvent
),
2530 if (!this._bHandledMouseOverEvent
&& (oTarget
== this.element
||
2531 Dom
.isAncestor(this.element
, oTarget
))) {
2533 // Menu mouseover logic
2535 this._nCurrentMouseX
= 0;
2537 Event
.on(this.element
, "mousemove", this._onMouseMove
, this, true);
2540 this.clearActiveItem();
2543 if (this.parent
&& this._nSubmenuHideDelayId
) {
2545 window
.clearTimeout(this._nSubmenuHideDelayId
);
2547 this.parent
.cfg
.setProperty("selected", true);
2549 oParentMenu
= this.parent
.parent
;
2551 oParentMenu
._bHandledMouseOutEvent
= true;
2552 oParentMenu
._bHandledMouseOverEvent
= false;
2557 this._bHandledMouseOverEvent
= true;
2558 this._bHandledMouseOutEvent
= false;
2563 if (oItem
&& !oItem
.handledMouseOverEvent
&&
2564 !oItem
.cfg
.getProperty("disabled") &&
2565 (oTarget
== oItem
.element
|| Dom
.isAncestor(oItem
.element
, oTarget
))) {
2567 // Menu Item mouseover logic
2569 nShowDelay
= this.cfg
.getProperty("showdelay");
2570 bShowDelay
= (nShowDelay
> 0);
2575 this._cancelShowDelay();
2580 oActiveItem
= this.activeItem
;
2584 oActiveItem
.cfg
.setProperty("selected", false);
2589 oItemCfg
= oItem
.cfg
;
2591 // Select and focus the current menu item
2593 oItemCfg
.setProperty("selected", true);
2596 if (this.hasFocus()) {
2603 if (this.cfg
.getProperty("autosubmenudisplay")) {
2605 // Show the submenu this menu item
2607 oSubmenu
= oItemCfg
.getProperty("submenu");
2613 this._execShowDelay(oSubmenu
);
2626 oItem
.handledMouseOverEvent
= true;
2627 oItem
.handledMouseOutEvent
= false;
2635 * @method _onMouseOut
2636 * @description "mouseout" event handler for the menu.
2638 * @param {String} p_sType String representing the name of the event that
2640 * @param {Array} p_aArgs Array of arguments sent when the event was fired.
2642 _onMouseOut: function (p_sType
, p_aArgs
) {
2644 if (this._bStopMouseEventHandlers
) {
2651 var oEvent
= p_aArgs
[0],
2653 oRelatedTarget
= Event
.getRelatedTarget(oEvent
),
2654 bMovingToSubmenu
= false,
2661 if (oItem
&& !oItem
.cfg
.getProperty("disabled")) {
2663 oItemCfg
= oItem
.cfg
;
2664 oSubmenu
= oItemCfg
.getProperty("submenu");
2667 if (oSubmenu
&& (oRelatedTarget
== oSubmenu
.element
||
2668 Dom
.isAncestor(oSubmenu
.element
, oRelatedTarget
))) {
2670 bMovingToSubmenu
= true;
2675 if (!oItem
.handledMouseOutEvent
&& ((oRelatedTarget
!= oItem
.element
&&
2676 !Dom
.isAncestor(oItem
.element
, oRelatedTarget
)) ||
2677 bMovingToSubmenu
)) {
2679 // Menu Item mouseout logic
2681 if (!bMovingToSubmenu
) {
2683 oItem
.cfg
.setProperty("selected", false);
2689 this.cfg
.getProperty("submenuhidedelay");
2691 nShowDelay
= this.cfg
.getProperty("showdelay");
2693 if (!(this instanceof YAHOO
.widget
.MenuBar
) &&
2694 nSubmenuHideDelay
> 0 &&
2695 nShowDelay
>= nSubmenuHideDelay
) {
2697 this._execSubmenuHideDelay(oSubmenu
,
2698 Event
.getPageX(oEvent
),
2713 oItem
.handledMouseOutEvent
= true;
2714 oItem
.handledMouseOverEvent
= false;
2721 if (!this._bHandledMouseOutEvent
&& ((oRelatedTarget
!= this.element
&&
2722 !Dom
.isAncestor(this.element
, oRelatedTarget
)) || bMovingToSubmenu
)) {
2724 // Menu mouseout logic
2726 Event
.removeListener(this.element
, "mousemove", this._onMouseMove
);
2728 this._nCurrentMouseX
= Event
.getPageX(oEvent
);
2730 this._bHandledMouseOutEvent
= true;
2731 this._bHandledMouseOverEvent
= false;
2739 * @method _onMouseMove
2740 * @description "click" event handler for the menu.
2742 * @param {Event} p_oEvent Object representing the DOM event object passed
2743 * back by the event utility (YAHOO.util.Event).
2744 * @param {YAHOO.widget.Menu} p_oMenu Object representing the menu that
2747 _onMouseMove: function (p_oEvent
, p_oMenu
) {
2749 if (this._bStopMouseEventHandlers
) {
2755 this._nCurrentMouseX
= Event
.getPageX(p_oEvent
);
2762 * @description "click" event handler for the menu.
2764 * @param {String} p_sType String representing the name of the event that
2766 * @param {Array} p_aArgs Array of arguments sent when the event was fired.
2768 _onClick: function (p_sType
, p_aArgs
) {
2770 var oEvent
= p_aArgs
[0],
2779 if (oItem
&& !oItem
.cfg
.getProperty("disabled")) {
2781 oTarget
= Event
.getTarget(oEvent
);
2782 oItemCfg
= oItem
.cfg
;
2783 oSubmenu
= oItemCfg
.getProperty("submenu");
2787 ACCESSIBILITY FEATURE FOR SCREEN READERS:
2788 Expand/collapse the submenu when the user clicks
2789 on the submenu indicator image.
2792 if (oTarget
== oItem
.submenuIndicator
&& oSubmenu
) {
2794 if (oSubmenu
.cfg
.getProperty("visible")) {
2798 oSubmenu
.parent
.focus();
2803 this.clearActiveItem();
2805 oItemCfg
.setProperty("selected", true);
2809 oSubmenu
.setInitialFocus();
2813 Event
.preventDefault(oEvent
);
2818 sURL
= oItemCfg
.getProperty("url");
2820 // Prevent the browser from following links equal to "#"
2822 if ((sURL
.substr((sURL
.length
-1),1) == "#")) {
2824 Event
.preventDefault(oEvent
);
2833 oRoot
= this.getRoot();
2835 if (oRoot
instanceof YAHOO
.widget
.MenuBar
||
2836 oRoot
.cfg
.getProperty("position") == "static") {
2838 oRoot
.clearActiveItem();
2841 else if (oRoot
.cfg
.getProperty("clicktohide")) {
2857 * @method _onKeyDown
2858 * @description "keydown" event handler for the menu.
2860 * @param {String} p_sType String representing the name of the event that
2862 * @param {Array} p_aArgs Array of arguments sent when the event was fired.
2864 _onKeyDown: function (p_sType
, p_aArgs
) {
2866 var oEvent
= p_aArgs
[0],
2885 This function is called to prevent a bug in Firefox. In Firefox,
2886 moving a DOM element into a stationary mouse pointer will cause the
2887 browser to fire mouse events. This can result in the menu mouse
2888 event handlers being called uncessarily, especially when menus are
2889 moved into a stationary mouse pointer as a result of a
2892 function stopMouseEventHandlers() {
2894 me
._bStopMouseEventHandlers
= true;
2896 window
.setTimeout(function () {
2898 me
._bStopMouseEventHandlers
= false;
2905 if (oItem
&& !oItem
.cfg
.getProperty("disabled")) {
2907 oItemCfg
= oItem
.cfg
;
2908 oParentItem
= this.parent
;
2910 switch(oEvent
.keyCode
) {
2912 case 38: // Up arrow
2913 case 40: // Down arrow
2915 oNextItem
= (oEvent
.keyCode
== 38) ?
2916 oItem
.getPreviousEnabledSibling() :
2917 oItem
.getNextEnabledSibling();
2921 this.clearActiveItem();
2923 oNextItem
.cfg
.setProperty("selected", true);
2927 if (this.cfg
.getProperty("maxheight") > 0) {
2930 nBodyScrollTop
= oBody
.scrollTop
;
2931 nBodyOffsetHeight
= oBody
.offsetHeight
;
2932 aItems
= this.getItems();
2933 nItems
= aItems
.length
- 1;
2934 nNextItemOffsetTop
= oNextItem
.element
.offsetTop
;
2937 if (oEvent
.keyCode
== 40 ) { // Down
2939 if (nNextItemOffsetTop
>= (nBodyOffsetHeight
+ nBodyScrollTop
)) {
2941 oBody
.scrollTop
= nNextItemOffsetTop
- nBodyOffsetHeight
;
2944 else if (nNextItemOffsetTop
<= nBodyScrollTop
) {
2946 oBody
.scrollTop
= 0;
2951 if (oNextItem
== aItems
[nItems
]) {
2953 oBody
.scrollTop
= oNextItem
.element
.offsetTop
;
2960 if (nNextItemOffsetTop
<= nBodyScrollTop
) {
2962 oBody
.scrollTop
= nNextItemOffsetTop
- oNextItem
.element
.offsetHeight
;
2965 else if (nNextItemOffsetTop
>= (nBodyScrollTop
+ nBodyOffsetHeight
)) {
2967 oBody
.scrollTop
= nNextItemOffsetTop
;
2972 if (oNextItem
== aItems
[0]) {
2974 oBody
.scrollTop
= 0;
2981 nBodyScrollTop
= oBody
.scrollTop
;
2982 nScrollTarget
= oBody
.scrollHeight
- oBody
.offsetHeight
;
2984 if (nBodyScrollTop
=== 0) {
2986 this._disableScrollHeader();
2987 this._enableScrollFooter();
2990 else if (nBodyScrollTop
== nScrollTarget
) {
2992 this._enableScrollHeader();
2993 this._disableScrollFooter();
2998 this._enableScrollHeader();
2999 this._enableScrollFooter();
3008 Event
.preventDefault(oEvent
);
3010 stopMouseEventHandlers();
3015 case 39: // Right arrow
3017 oSubmenu
= oItemCfg
.getProperty("submenu");
3021 if (!oItemCfg
.getProperty("selected")) {
3023 oItemCfg
.setProperty("selected", true);
3028 oSubmenu
.setInitialFocus();
3029 oSubmenu
.setInitialSelection();
3034 oRoot
= this.getRoot();
3036 if (oRoot
instanceof YAHOO
.widget
.MenuBar
) {
3038 oNextItem
= oRoot
.activeItem
.getNextEnabledSibling();
3042 oRoot
.clearActiveItem();
3044 oNextItem
.cfg
.setProperty("selected", true);
3046 oSubmenu
= oNextItem
.cfg
.getProperty("submenu");
3063 Event
.preventDefault(oEvent
);
3065 stopMouseEventHandlers();
3070 case 37: // Left arrow
3074 oParentMenu
= oParentItem
.parent
;
3076 if (oParentMenu
instanceof YAHOO
.widget
.MenuBar
) {
3079 oParentMenu
.activeItem
.getPreviousEnabledSibling();
3083 oParentMenu
.clearActiveItem();
3085 oNextItem
.cfg
.setProperty("selected", true);
3087 oSubmenu
= oNextItem
.cfg
.getProperty("submenu");
3104 oParentItem
.focus();
3110 Event
.preventDefault(oEvent
);
3112 stopMouseEventHandlers();
3122 if (oEvent
.keyCode
== 27) { // Esc key
3124 if (this.cfg
.getProperty("position") == "dynamic") {
3130 this.parent
.focus();
3135 else if (this.activeItem
) {
3137 oSubmenu
= this.activeItem
.cfg
.getProperty("submenu");
3139 if (oSubmenu
&& oSubmenu
.cfg
.getProperty("visible")) {
3142 this.activeItem
.focus();
3147 this.activeItem
.blur();
3148 this.activeItem
.cfg
.setProperty("selected", false);
3155 Event
.preventDefault(oEvent
);
3163 * @method _onKeyPress
3164 * @description "keypress" event handler for a Menu instance.
3166 * @param {String} p_sType The name of the event that was fired.
3167 * @param {Array} p_aArgs Collection of arguments sent when the event
3170 _onKeyPress: function (p_sType
, p_aArgs
) {
3172 var oEvent
= p_aArgs
[0];
3175 if (oEvent
.keyCode
== 40 || oEvent
.keyCode
== 38) {
3177 Event
.preventDefault(oEvent
);
3185 * @method _onTextResize
3186 * @description "textresize" event handler for the menu.
3188 * @param {String} p_sType String representing the name of the event that
3190 * @param {Array} p_aArgs Array of arguments sent when the event was fired.
3191 * @param {YAHOO.widget.Menu} p_oMenu Object representing the menu that
3194 _onTextResize: function (p_sType
, p_aArgs
, p_oMenu
) {
3196 if (YAHOO
.env
.ua
.gecko
&& !this._handleResize
) {
3198 this._handleResize
= true;
3204 var oConfig
= this.cfg
;
3206 if (oConfig
.getProperty("position") == "dynamic") {
3208 oConfig
.setProperty("width", (this._getOffsetWidth() + "px"));
3216 * @method _onScrollTargetMouseOver
3217 * @description "mouseover" event handler for the menu's "header" and "footer"
3218 * elements. Used to scroll the body of the menu up and down when the
3219 * menu's "maxheight" configuration property is set to a value greater than 0.
3221 * @param {Event} p_oEvent Object representing the DOM event object passed
3222 * back by the event utility (YAHOO.util.Event).
3223 * @param {YAHOO.widget.Menu} p_oMenu Object representing the menu that
3226 _onScrollTargetMouseOver: function (p_oEvent
, p_oMenu
) {
3228 this._cancelHideDelay();
3230 var oTarget
= Event
.getTarget(p_oEvent
),
3237 function scrollBodyDown() {
3239 var nScrollTop
= oBody
.scrollTop
;
3242 if (nScrollTop
< nScrollTarget
) {
3244 oBody
.scrollTop
= (nScrollTop
+ 1);
3246 me
._enableScrollHeader();
3251 oBody
.scrollTop
= nScrollTarget
;
3253 window
.clearInterval(me
._nBodyScrollId
);
3255 me
._disableScrollFooter();
3262 function scrollBodyUp() {
3264 var nScrollTop
= oBody
.scrollTop
;
3267 if (nScrollTop
> 0) {
3269 oBody
.scrollTop
= (nScrollTop
- 1);
3271 me
._enableScrollFooter();
3276 oBody
.scrollTop
= 0;
3278 window
.clearInterval(me
._nBodyScrollId
);
3280 me
._disableScrollHeader();
3287 if (Dom
.hasClass(oTarget
, "hd")) {
3289 fnScrollFunction
= scrollBodyUp
;
3294 nScrollTarget
= oBody
.scrollHeight
- oBody
.offsetHeight
;
3296 fnScrollFunction
= scrollBodyDown
;
3301 this._nBodyScrollId
= window
.setInterval(fnScrollFunction
, 10);
3307 * @method _onScrollTargetMouseOut
3308 * @description "mouseout" event handler for the menu's "header" and "footer"
3309 * elements. Used to stop scrolling the body of the menu up and down when the
3310 * menu's "maxheight" configuration property is set to a value greater than 0.
3312 * @param {Event} p_oEvent Object representing the DOM event object passed
3313 * back by the event utility (YAHOO.util.Event).
3314 * @param {YAHOO.widget.Menu} p_oMenu Object representing the menu that
3317 _onScrollTargetMouseOut: function (p_oEvent
, p_oMenu
) {
3319 window
.clearInterval(this._nBodyScrollId
);
3321 this._cancelHideDelay();
3332 * @description "init" event handler for the menu.
3334 * @param {String} p_sType String representing the name of the event that
3336 * @param {Array} p_aArgs Array of arguments sent when the event was fired.
3338 _onInit: function (p_sType
, p_aArgs
) {
3340 this.cfg
.subscribeToConfigEvent("width", this._onWidthChange
);
3341 this.cfg
.subscribeToConfigEvent("visible", this._onVisibleChange
);
3343 var bRootMenu
= !this.parent
,
3344 bLazyLoad
= this.lazyLoad
;
3348 Automatically initialize a menu's subtree if:
3350 1) This is the root menu and lazyload is off
3352 2) This is the root menu, lazyload is on, but the menu is
3355 3) This menu is a submenu and lazyload is off
3360 if (((bRootMenu
&& !bLazyLoad
) ||
3361 (bRootMenu
&& (this.cfg
.getProperty("visible") ||
3362 this.cfg
.getProperty("position") == "static")) ||
3363 (!bRootMenu
&& !bLazyLoad
)) && this.getItemGroups().length
=== 0) {
3365 if (this.srcElement
) {
3367 this._initSubTree();
3372 if (this.itemData
) {
3374 this.addItems(this.itemData
);
3379 else if (bLazyLoad
) {
3381 this.cfg
.fireQueue();
3389 * @method _onBeforeRender
3390 * @description "beforerender" event handler for the menu. Appends all of the
3391 * <code><ul></code>, <code><li></code> and their accompanying
3392 * title elements to the body element of the menu.
3394 * @param {String} p_sType String representing the name of the event that
3396 * @param {Array} p_aArgs Array of arguments sent when the event was fired.
3398 _onBeforeRender: function (p_sType
, p_aArgs
) {
3400 var oConfig
= this.cfg
,
3402 nListElements
= this._aListElements
.length
,
3408 if (nListElements
> 0) {
3412 oUL
= this._aListElements
[i
];
3418 Dom
.addClass(oUL
, "first-of-type");
3424 if (!Dom
.isAncestor(oEl
, oUL
)) {
3426 this.appendToBody(oUL
);
3431 oGroupTitle
= this._aGroupTitleElements
[i
];
3435 if (!Dom
.isAncestor(oEl
, oGroupTitle
)) {
3437 oUL
.parentNode
.insertBefore(oGroupTitle
, oUL
);
3442 Dom
.addClass(oUL
, "hastitle");
3451 while(i
< nListElements
);
3460 * @description "render" event handler for the menu.
3462 * @param {String} p_sType String representing the name of the event that
3464 * @param {Array} p_aArgs Array of arguments sent when the event was fired.
3466 _onRender: function (p_sType
, p_aArgs
) {
3468 if (this.cfg
.getProperty("position") == "dynamic" &&
3469 !this.cfg
.getProperty("width")) {
3479 * @method _onBeforeShow
3480 * @description "beforeshow" event handler for the menu.
3482 * @param {String} p_sType String representing the name of the event that
3484 * @param {Array} p_aArgs Array of arguments sent when the event was fired.
3486 _onBeforeShow: function (p_sType
, p_aArgs
) {
3497 if (this.lazyLoad
&& this.getItemGroups().length
=== 0) {
3499 if (this.srcElement
) {
3501 this._initSubTree();
3506 if (this.itemData
) {
3508 if (this.parent
&& this.parent
.parent
&&
3509 this.parent
.parent
.srcElement
&&
3510 this.parent
.parent
.srcElement
.tagName
.toUpperCase() ==
3513 nOptions
= this.itemData
.length
;
3515 for(n
=0; n
<nOptions
; n
++) {
3517 if (this.itemData
[n
].tagName
) {
3519 this.addItem((new this.ITEM_TYPE(this.itemData
[n
])));
3528 this.addItems(this.itemData
);
3535 oSrcElement
= this.srcElement
;
3539 if (oSrcElement
.tagName
.toUpperCase() == "SELECT") {
3541 if (Dom
.inDocument(oSrcElement
)) {
3543 this.render(oSrcElement
.parentNode
);
3548 this.render(this.cfg
.getProperty("container"));
3564 this.render(this.parent
.element
);
3569 this.render(this.cfg
.getProperty("container"));
3570 this.cfg
.refireEvent("xy");
3579 if (!(this instanceof YAHOO
.widget
.MenuBar
) &&
3580 this.cfg
.getProperty("position") == "dynamic") {
3582 nViewportHeight
= Dom
.getViewportHeight();
3585 if (this.parent
&& this.parent
.parent
instanceof YAHOO
.widget
.MenuBar
) {
3587 oRegion
= YAHOO
.util
.Region
.getRegion(this.parent
.element
);
3589 nViewportHeight
= (nViewportHeight
- oRegion
.bottom
);
3594 if (this.element
.offsetHeight
>= nViewportHeight
) {
3596 nMaxHeight
= this.cfg
.getProperty("maxheight");
3599 Cache the original value for the "maxheight" configuration
3600 property so that we can set it back when the menu is hidden.
3603 this._nMaxHeight
= nMaxHeight
;
3605 this.cfg
.setProperty("maxheight", (nViewportHeight
- 20));
3610 if (this.cfg
.getProperty("maxheight") > 0) {
3614 if (oBody
.scrollTop
> 0) {
3616 oBody
.scrollTop
= 0;
3620 this._disableScrollHeader();
3621 this._enableScrollFooter();
3633 * @description "show" event handler for the menu.
3635 * @param {String} p_sType String representing the name of the event that
3637 * @param {Array} p_aArgs Array of arguments sent when the event was fired.
3639 _onShow: function (p_sType
, p_aArgs
) {
3641 var oParent
= this.parent
,
3647 function disableAutoSubmenuDisplay(p_oEvent
) {
3651 if (p_oEvent
.type
== "mousedown" || (p_oEvent
.type
== "keydown" &&
3652 p_oEvent
.keyCode
== 27)) {
3655 Set the "autosubmenudisplay" to "false" if the user
3656 clicks outside the menu bar.
3659 oTarget
= Event
.getTarget(p_oEvent
);
3661 if (oTarget
!= oParentMenu
.element
||
3662 !Dom
.isAncestor(oParentMenu
.element
, oTarget
)) {
3664 oParentMenu
.cfg
.setProperty("autosubmenudisplay", false);
3666 Event
.removeListener(document
, "mousedown",
3667 disableAutoSubmenuDisplay
);
3669 Event
.removeListener(document
, "keydown",
3670 disableAutoSubmenuDisplay
);
3681 oParentMenu
= oParent
.parent
;
3682 aParentAlignment
= oParentMenu
.cfg
.getProperty("submenualignment");
3683 aAlignment
= this.cfg
.getProperty("submenualignment");
3686 if ((aParentAlignment
[0] != aAlignment
[0]) &&
3687 (aParentAlignment
[1] != aAlignment
[1])) {
3689 this.cfg
.setProperty("submenualignment",
3690 [aParentAlignment
[0], aParentAlignment
[1]]);
3695 if (!oParentMenu
.cfg
.getProperty("autosubmenudisplay") &&
3696 (oParentMenu
instanceof YAHOO
.widget
.MenuBar
||
3697 oParentMenu
.cfg
.getProperty("position") == "static")) {
3699 oParentMenu
.cfg
.setProperty("autosubmenudisplay", true);
3701 Event
.on(document
, "mousedown", disableAutoSubmenuDisplay
);
3702 Event
.on(document
, "keydown", disableAutoSubmenuDisplay
);
3712 * @method _onBeforeHide
3713 * @description "beforehide" event handler for the menu.
3715 * @param {String} p_sType String representing the name of the event that
3717 * @param {Array} p_aArgs Array of arguments sent when the event was fired.
3719 _onBeforeHide: function (p_sType
, p_aArgs
) {
3721 var oActiveItem
= this.activeItem
,
3727 oConfig
= oActiveItem
.cfg
;
3729 oConfig
.setProperty("selected", false);
3731 oSubmenu
= oConfig
.getProperty("submenu");
3741 if (this.getRoot() == this) {
3752 * @description "hide" event handler for the menu.
3754 * @param {String} p_sType String representing the name of the event that
3756 * @param {Array} p_aArgs Array of arguments sent when the event was fired.
3758 _onHide: function (p_sType
, p_aArgs
) {
3760 if (this._nMaxHeight
!= -1) {
3762 this.cfg
.setProperty("maxheight", this._nMaxHeight
);
3764 this._nMaxHeight
= -1;
3772 * @method _onParentMenuConfigChange
3773 * @description "configchange" event handler for a submenu.
3775 * @param {String} p_sType String representing the name of the event that
3777 * @param {Array} p_aArgs Array of arguments sent when the event was fired.
3778 * @param {YAHOO.widget.Menu} p_oSubmenu Object representing the submenu that
3779 * subscribed to the event.
3781 _onParentMenuConfigChange: function (p_sType
, p_aArgs
, p_oSubmenu
) {
3783 var sPropertyName
= p_aArgs
[0][0],
3784 oPropertyValue
= p_aArgs
[0][1];
3786 switch(sPropertyName
) {
3789 case "constraintoviewport":
3792 case "submenuhidedelay":
3797 p_oSubmenu
.cfg
.setProperty(sPropertyName
, oPropertyValue
);
3807 * @method _onParentMenuRender
3808 * @description "render" event handler for a submenu. Renders a
3809 * submenu in response to the firing of its parent's "render" event.
3811 * @param {String} p_sType String representing the name of the event that
3813 * @param {Array} p_aArgs Array of arguments sent when the event was fired.
3814 * @param {YAHOO.widget.Menu} p_oSubmenu Object representing the submenu that
3815 * subscribed to the event.
3817 _onParentMenuRender: function (p_sType
, p_aArgs
, p_oSubmenu
) {
3819 var oParentMenu
= p_oSubmenu
.parent
.parent
,
3823 constraintoviewport
:
3824 oParentMenu
.cfg
.getProperty("constraintoviewport"),
3828 clicktohide
: oParentMenu
.cfg
.getProperty("clicktohide"),
3830 effect
: oParentMenu
.cfg
.getProperty("effect"),
3832 showdelay
: oParentMenu
.cfg
.getProperty("showdelay"),
3834 hidedelay
: oParentMenu
.cfg
.getProperty("hidedelay"),
3836 submenuhidedelay
: oParentMenu
.cfg
.getProperty("submenuhidedelay"),
3838 classname
: oParentMenu
.cfg
.getProperty("classname")
3846 Only sync the "iframe" configuration property if the parent
3847 menu's "position" configuration is the same.
3850 if (this.cfg
.getProperty("position") ==
3851 oParentMenu
.cfg
.getProperty("position")) {
3853 oConfig
.iframe
= oParentMenu
.cfg
.getProperty("iframe");
3858 p_oSubmenu
.cfg
.applyConfig(oConfig
);
3861 if (!this.lazyLoad
) {
3863 oLI
= this.parent
.element
;
3865 if (this.element
.parentNode
== oLI
) {
3882 * @method _onSubmenuBeforeShow
3883 * @description "beforeshow" event handler for a submenu.
3885 * @param {String} p_sType String representing the name of the event that
3887 * @param {Array} p_aArgs Array of arguments sent when the event was fired.
3889 _onSubmenuBeforeShow: function (p_sType
, p_aArgs
) {
3891 var oParent
= this.parent
,
3892 aAlignment
= oParent
.parent
.cfg
.getProperty("submenualignment");
3894 this.cfg
.setProperty("context",
3895 [oParent
.element
, aAlignment
[0], aAlignment
[1]]);
3898 var nScrollTop
= oParent
.parent
.body
.scrollTop
;
3900 if ((YAHOO
.env
.ua
.gecko
|| YAHOO
.env
.ua
.webkit
) && nScrollTop
> 0) {
3902 this.cfg
.setProperty("y", (this.cfg
.getProperty("y") - nScrollTop
));
3910 * @method _onSubmenuShow
3911 * @description "show" event handler for a submenu.
3913 * @param {String} p_sType String representing the name of the event that
3915 * @param {Array} p_aArgs Array of arguments sent when the event was fired.
3917 _onSubmenuShow: function (p_sType
, p_aArgs
) {
3919 this.submenuIndicator
.innerHTML
= this.EXPANDED_SUBMENU_INDICATOR_TEXT
;
3925 * @method _onSubmenuHide
3926 * @description "hide" Custom Event handler for a submenu.
3928 * @param {String} p_sType String representing the name of the event that
3930 * @param {Array} p_aArgs Array of arguments sent when the event was fired.
3932 _onSubmenuHide: function (p_sType
, p_aArgs
) {
3934 this.submenuIndicator
.innerHTML
= this.COLLAPSED_SUBMENU_INDICATOR_TEXT
;
3940 * @method _onMenuItemFocus
3941 * @description "focus" event handler for the menu's items.
3943 * @param {String} p_sType String representing the name of the event that
3945 * @param {Array} p_aArgs Array of arguments sent when the event was fired.
3947 _onMenuItemFocus: function (p_sType
, p_aArgs
) {
3949 this.parent
.focusEvent
.fire(this);
3955 * @method _onMenuItemBlur
3956 * @description "blur" event handler for the menu's items.
3958 * @param {String} p_sType String representing the name of the event
3960 * @param {Array} p_aArgs Array of arguments sent when the event was fired.
3962 _onMenuItemBlur: function (p_sType
, p_aArgs
) {
3964 this.parent
.blurEvent
.fire(this);
3970 * @method _onMenuItemConfigChange
3971 * @description "configchange" event handler for the menu's items.
3973 * @param {String} p_sType String representing the name of the event that
3975 * @param {Array} p_aArgs Array of arguments sent when the event was fired.
3976 * @param {YAHOO.widget.MenuItem} p_oItem Object representing the menu item
3977 * that fired the event.
3979 _onMenuItemConfigChange: function (p_sType
, p_aArgs
, p_oItem
) {
3981 var sPropertyName
= p_aArgs
[0][0],
3982 oPropertyValue
= p_aArgs
[0][1],
3986 switch(sPropertyName
) {
3990 if (oPropertyValue
=== true) {
3992 this.activeItem
= p_oItem
;
4000 oSubmenu
= p_aArgs
[0][1];
4004 this._configureSubmenu(p_oItem
);
4014 A change to an item's "text" or "helptext"
4015 configuration properties requires the width of the parent
4016 menu to be recalculated.
4019 if (this.element
.style
.width
) {
4021 sWidth
= this._getOffsetWidth() + "px";
4023 Dom
.setStyle(this.element
, "width", sWidth
);
4035 // Public event handlers for configuration properties
4039 * @method enforceConstraints
4040 * @description The default event handler executed when the moveEvent is fired,
4041 * if the "constraintoviewport" configuration property is set to true.
4042 * @param {String} type The name of the event that was fired.
4043 * @param {Array} args Collection of arguments sent when the
4045 * @param {Array} obj Array containing the current Menu instance
4046 * and the item that fired the event.
4048 enforceConstraints: function (type
, args
, obj
) {
4050 var oParentMenuItem
= this.parent
,
4071 if (oParentMenuItem
&&
4072 !(oParentMenuItem
.parent
instanceof YAHOO
.widget
.MenuBar
)) {
4074 oElement
= this.element
;
4082 offsetHeight
= oElement
.offsetHeight
;
4083 offsetWidth
= oElement
.offsetWidth
;
4085 viewPortWidth
= Dom
.getViewportWidth();
4086 viewPortHeight
= Dom
.getViewportHeight();
4088 scrollX
= Dom
.getDocumentScrollLeft();
4089 scrollY
= Dom
.getDocumentScrollTop();
4092 (oParentMenuItem
.parent
instanceof YAHOO
.widget
.MenuBar
) ? 0 : 10;
4094 topConstraint
= scrollY
+ nPadding
;
4095 leftConstraint
= scrollX
+ nPadding
;
4097 bottomConstraint
= scrollY
+ viewPortHeight
- offsetHeight
- nPadding
;
4098 rightConstraint
= scrollX
+ viewPortWidth
- offsetWidth
- nPadding
;
4100 aContext
= oConfig
.getProperty("context");
4101 oContextElement
= aContext
? aContext
[0] : null;
4108 } else if ((x
+ offsetWidth
) > viewPortWidth
) {
4110 if (oContextElement
&&
4111 ((x
- oContextElement
.offsetWidth
) > offsetWidth
)) {
4113 x
= (x
- (oContextElement
.offsetWidth
+ offsetWidth
));
4118 x
= rightConstraint
;
4128 } else if (y
> bottomConstraint
) {
4130 if (oContextElement
&& (y
> offsetHeight
)) {
4132 y
= ((y
+ oContextElement
.offsetHeight
) - offsetHeight
);
4137 y
= bottomConstraint
;
4143 oConfig
.setProperty("x", x
, true);
4144 oConfig
.setProperty("y", y
, true);
4145 oConfig
.setProperty("xy", [x
,y
], true);
4148 else if (this == this.getRoot() &&
4149 this.cfg
.getProperty("position") == "dynamic") {
4151 Menu
.superclass
.enforceConstraints
.call(this, type
, args
, obj
);
4159 * @method configVisible
4160 * @description Event handler for when the "visible" configuration property
4162 * @param {String} p_sType String representing the name of the event that
4164 * @param {Array} p_aArgs Array of arguments sent when the event was fired.
4165 * @param {YAHOO.widget.Menu} p_oMenu Object representing the menu that
4168 configVisible: function (p_sType
, p_aArgs
, p_oMenu
) {
4173 if (this.cfg
.getProperty("position") == "dynamic") {
4175 Menu
.superclass
.configVisible
.call(this, p_sType
, p_aArgs
, p_oMenu
);
4180 bVisible
= p_aArgs
[0];
4181 sDisplay
= Dom
.getStyle(this.element
, "display");
4185 if (sDisplay
!= "block") {
4186 this.beforeShowEvent
.fire();
4187 Dom
.setStyle(this.element
, "display", "block");
4188 this.showEvent
.fire();
4194 if (sDisplay
== "block") {
4195 this.beforeHideEvent
.fire();
4196 Dom
.setStyle(this.element
, "display", "none");
4197 this.hideEvent
.fire();
4208 * @method configPosition
4209 * @description Event handler for when the "position" configuration property
4210 * of the menu changes.
4211 * @param {String} p_sType String representing the name of the event that
4213 * @param {Array} p_aArgs Array of arguments sent when the event was fired.
4214 * @param {YAHOO.widget.Menu} p_oMenu Object representing the menu that
4217 configPosition: function (p_sType
, p_aArgs
, p_oMenu
) {
4219 var oElement
= this.element
,
4220 sCSSPosition
= p_aArgs
[0] == "static" ? "static" : "absolute",
4221 sCurrentPosition
= Dom
.getStyle(oElement
, "position"),
4226 Dom
.setStyle(this.element
, "position", sCSSPosition
);
4229 if (sCSSPosition
== "static") {
4232 Remove the iframe for statically positioned menus since it will
4233 intercept mouse events.
4236 oCfg
.setProperty("iframe", false);
4239 // Statically positioned menus are visible by default
4241 Dom
.setStyle(this.element
, "display", "block");
4243 oCfg
.setProperty("visible", true);
4248 if (sCurrentPosition
!= "absolute") {
4250 oCfg
.setProperty("iframe", (YAHOO
.env
.ua
.ie
== 6 ? true : false));
4255 Even though the "visible" property is queued to
4256 "false" by default, we need to set the "visibility" property to
4257 "hidden" since Overlay's "configVisible" implementation checks the
4258 element's "visibility" style property before deciding whether
4259 or not to show an Overlay instance.
4262 Dom
.setStyle(this.element
, "visibility", "hidden");
4267 if (sCSSPosition
== "absolute") {
4269 nZIndex
= oCfg
.getProperty("zindex");
4271 if (!nZIndex
|| nZIndex
=== 0) {
4273 nZIndex
= this.parent
?
4274 (this.parent
.parent
.cfg
.getProperty("zindex") + 1) : 1;
4276 oCfg
.setProperty("zindex", nZIndex
);
4286 * @method configIframe
4287 * @description Event handler for when the "iframe" configuration property of
4289 * @param {String} p_sType String representing the name of the event that
4291 * @param {Array} p_aArgs Array of arguments sent when the event was fired.
4292 * @param {YAHOO.widget.Menu} p_oMenu Object representing the menu that
4295 configIframe: function (p_sType
, p_aArgs
, p_oMenu
) {
4297 if (this.cfg
.getProperty("position") == "dynamic") {
4299 Menu
.superclass
.configIframe
.call(this, p_sType
, p_aArgs
, p_oMenu
);
4307 * @method configHideDelay
4308 * @description Event handler for when the "hidedelay" configuration property
4309 * of the menu changes.
4310 * @param {String} p_sType String representing the name of the event that
4312 * @param {Array} p_aArgs Array of arguments sent when the event was fired.
4313 * @param {YAHOO.widget.Menu} p_oMenu Object representing the menu that
4316 configHideDelay: function (p_sType
, p_aArgs
, p_oMenu
) {
4318 var nHideDelay
= p_aArgs
[0],
4319 oMouseOutEvent
= this.mouseOutEvent
,
4320 oMouseOverEvent
= this.mouseOverEvent
,
4321 oKeyDownEvent
= this.keyDownEvent
;
4323 if (nHideDelay
> 0) {
4326 Only assign event handlers once. This way the user change
4327 the value for the hidedelay as many times as they want.
4330 if (!this._bHideDelayEventHandlersAssigned
) {
4332 oMouseOutEvent
.subscribe(this._execHideDelay
);
4333 oMouseOverEvent
.subscribe(this._cancelHideDelay
);
4334 oKeyDownEvent
.subscribe(this._cancelHideDelay
);
4336 this._bHideDelayEventHandlersAssigned
= true;
4343 oMouseOutEvent
.unsubscribe(this._execHideDelay
);
4344 oMouseOverEvent
.unsubscribe(this._cancelHideDelay
);
4345 oKeyDownEvent
.unsubscribe(this._cancelHideDelay
);
4347 this._bHideDelayEventHandlersAssigned
= false;
4355 * @method configContainer
4356 * @description Event handler for when the "container" configuration property
4357 of the menu changes.
4358 * @param {String} p_sType String representing the name of the event that
4360 * @param {Array} p_aArgs Array of arguments sent when the event was fired.
4361 * @param {YAHOO.widget.Menu} p_oMenu Object representing the menu that
4364 configContainer: function (p_sType
, p_aArgs
, p_oMenu
) {
4366 var oElement
= p_aArgs
[0];
4368 if (typeof oElement
== 'string') {
4370 this.cfg
.setProperty("container", document
.getElementById(oElement
),
4379 * @method _setMaxHeight
4380 * @description "renderEvent" handler used to defer the setting of the
4381 * "maxheight" configuration property until the menu is rendered in lazy
4383 * @param {String} p_sType The name of the event that was fired.
4384 * @param {Array} p_aArgs Collection of arguments sent when the event
4386 * @param {Number} p_nMaxHeight Number representing the value to set for the
4387 * "maxheight" configuration property.
4390 _setMaxHeight: function (p_sType
, p_aArgs
, p_nMaxHeight
) {
4392 this.cfg
.setProperty("maxheight", p_nMaxHeight
);
4393 this.renderEvent
.unsubscribe(this._setMaxHeight
);
4399 * @method configMaxHeight
4400 * @description Event handler for when the "maxheight" configuration property of
4402 * @param {String} p_sType The name of the event that was fired.
4403 * @param {Array} p_aArgs Collection of arguments sent when the event
4405 * @param {YAHOO.widget.Menu} p_oMenu The Menu instance fired
4408 configMaxHeight: function (p_sType
, p_aArgs
, p_oMenu
) {
4410 var nMaxHeight
= p_aArgs
[0],
4412 oHeader
= this.header
,
4413 oFooter
= this.footer
,
4414 fnMouseOver
= this._onScrollTargetMouseOver
,
4415 fnMouseOut
= this._onScrollTargetMouseOut
,
4419 if (this.lazyLoad
&& !oBody
) {
4421 this.renderEvent
.unsubscribe(this._setMaxHeight
);
4423 if (nMaxHeight
> 0) {
4425 this.renderEvent
.subscribe(this._setMaxHeight
, nMaxHeight
, this);
4433 Dom
.setStyle(oBody
, "height", "auto");
4434 Dom
.setStyle(oBody
, "overflow", "visible");
4437 if ((nMaxHeight
> 0) && (oBody
.offsetHeight
> nMaxHeight
)) {
4439 if (!this.cfg
.getProperty("width")) {
4445 if (!oHeader
&& !oFooter
) {
4447 this.setHeader(" ");
4448 this.setFooter(" ");
4450 oHeader
= this.header
;
4451 oFooter
= this.footer
;
4453 Dom
.addClass(oHeader
, "topscrollbar");
4454 Dom
.addClass(oFooter
, "bottomscrollbar");
4456 this.element
.insertBefore(oHeader
, oBody
);
4457 this.element
.appendChild(oFooter
);
4459 Event
.on(oHeader
, "mouseover", fnMouseOver
, this, true);
4460 Event
.on(oHeader
, "mouseout", fnMouseOut
, this, true);
4461 Event
.on(oFooter
, "mouseover", fnMouseOver
, this, true);
4462 Event
.on(oFooter
, "mouseout", fnMouseOut
, this, true);
4466 nHeight
= (nMaxHeight
- (this.footer
.offsetHeight
+
4467 this.header
.offsetHeight
));
4469 Dom
.setStyle(oBody
, "height", (nHeight
+ "px"));
4470 Dom
.setStyle(oBody
, "overflow", "hidden");
4473 else if (oHeader
&& oFooter
) {
4475 Dom
.setStyle(oBody
, "height", "auto");
4476 Dom
.setStyle(oBody
, "overflow", "visible");
4478 Event
.removeListener(oHeader
, "mouseover", fnMouseOver
);
4479 Event
.removeListener(oHeader
, "mouseout", fnMouseOut
);
4480 Event
.removeListener(oFooter
, "mouseover", fnMouseOver
);
4481 Event
.removeListener(oFooter
, "mouseout", fnMouseOut
);
4483 this.element
.removeChild(oHeader
);
4484 this.element
.removeChild(oFooter
);
4491 this.cfg
.refireEvent("iframe");
4497 * @method configClassName
4498 * @description Event handler for when the "classname" configuration property of
4500 * @param {String} p_sType The name of the event that was fired.
4501 * @param {Array} p_aArgs Collection of arguments sent when the event was fired.
4502 * @param {YAHOO.widget.Menu} p_oMenu The Menu instance fired the event.
4504 configClassName: function (p_sType
, p_aArgs
, p_oMenu
) {
4506 var sClassName
= p_aArgs
[0];
4508 if (this._sClassName
) {
4510 Dom
.removeClass(this.element
, this._sClassName
);
4514 Dom
.addClass(this.element
, sClassName
);
4515 this._sClassName
= sClassName
;
4521 * @method _onItemAdded
4522 * @description "itemadded" event handler for a Menu instance.
4524 * @param {String} p_sType The name of the event that was fired.
4525 * @param {Array} p_aArgs Collection of arguments sent when the event
4528 _onItemAdded: function (p_sType
, p_aArgs
) {
4530 var oItem
= p_aArgs
[0];
4534 oItem
.cfg
.setProperty("disabled", true);
4542 * @method configDisabled
4543 * @description Event handler for when the "disabled" configuration property of
4545 * @param {String} p_sType The name of the event that was fired.
4546 * @param {Array} p_aArgs Collection of arguments sent when the event was fired.
4547 * @param {YAHOO.widget.Menu} p_oMenu The Menu instance fired the event.
4549 configDisabled: function (p_sType
, p_aArgs
, p_oMenu
) {
4551 var bDisabled
= p_aArgs
[0],
4556 if (this._bDisabled
!= bDisabled
) {
4558 aItems
= this.getItems();
4559 nItems
= aItems
.length
;
4567 aItems
[i
].cfg
.setProperty("disabled", bDisabled
);
4574 Dom
[(bDisabled
? "addClass" : "removeClass")](this.element
, "disabled");
4576 this.itemAddedEvent
[(bDisabled
? "subscribe" : "unsubscribe")](
4579 this._bDisabled
= bDisabled
;
4588 * @description "render" event handler for the menu.
4589 * @param {String} p_sType String representing the name of the event that
4591 * @param {Array} p_aArgs Array of arguments sent when the event was fired.
4593 onRender: function (p_sType
, p_aArgs
) {
4595 function sizeShadow() {
4597 var oElement
= this.element
,
4598 oShadow
= this._shadow
;
4602 oShadow
.style
.width
= (oElement
.offsetWidth
+ 6) + "px";
4603 oShadow
.style
.height
= (oElement
.offsetHeight
+ 1) + "px";
4610 function addShadowVisibleClass() {
4612 Dom
.addClass(this._shadow
, "yui-menu-shadow-visible");
4617 function removeShadowVisibleClass() {
4619 Dom
.removeClass(this._shadow
, "yui-menu-shadow-visible");
4624 function createShadow() {
4626 var oShadow
= this._shadow
,
4632 oElement
= this.element
;
4635 if (!m_oShadowTemplate
) {
4637 m_oShadowTemplate
= document
.createElement("div");
4638 m_oShadowTemplate
.className
= "yui-menu-shadow";
4642 oShadow
= m_oShadowTemplate
.cloneNode(false);
4644 oElement
.appendChild(oShadow
);
4646 this._shadow
= oShadow
;
4648 addShadowVisibleClass
.call(this);
4650 this.beforeShowEvent
.subscribe(addShadowVisibleClass
);
4651 this.beforeHideEvent
.subscribe(removeShadowVisibleClass
);
4653 if (YAHOO
.env
.ua
.ie
) {
4656 Need to call sizeShadow & syncIframe via setTimeout for
4657 IE 7 Quirks Mode and IE 6 Standards Mode and Quirks Mode
4658 or the shadow and iframe shim will not be sized and
4659 positioned properly.
4662 window
.setTimeout(function () {
4664 sizeShadow
.call(me
);
4669 this.cfg
.subscribeToConfigEvent("width", sizeShadow
);
4670 this.cfg
.subscribeToConfigEvent("height", sizeShadow
);
4671 this.changeContentEvent
.subscribe(sizeShadow
);
4673 Module
.textResizeEvent
.subscribe(sizeShadow
, me
, true);
4675 this.destroyEvent
.subscribe(function () {
4677 Module
.textResizeEvent
.unsubscribe(sizeShadow
, me
);
4688 function onBeforeShow() {
4690 createShadow
.call(this);
4692 this.beforeShowEvent
.unsubscribe(onBeforeShow
);
4697 if (this.cfg
.getProperty("position") == "dynamic") {
4699 if (this.cfg
.getProperty("visible")) {
4701 createShadow
.call(this);
4706 this.beforeShowEvent
.subscribe(onBeforeShow
);
4719 * @method initEvents
4720 * @description Initializes the custom events for the menu.
4722 initEvents: function () {
4724 Menu
.superclass
.initEvents
.call(this);
4726 // Create custom events
4728 var SIGNATURE
= CustomEvent
.LIST
;
4730 this.mouseOverEvent
= this.createEvent(EVENT_TYPES
.MOUSE_OVER
);
4731 this.mouseOverEvent
.signature
= SIGNATURE
;
4733 this.mouseOutEvent
= this.createEvent(EVENT_TYPES
.MOUSE_OUT
);
4734 this.mouseOutEvent
.signature
= SIGNATURE
;
4736 this.mouseDownEvent
= this.createEvent(EVENT_TYPES
.MOUSE_DOWN
);
4737 this.mouseDownEvent
.signature
= SIGNATURE
;
4739 this.mouseUpEvent
= this.createEvent(EVENT_TYPES
.MOUSE_UP
);
4740 this.mouseUpEvent
.signature
= SIGNATURE
;
4742 this.clickEvent
= this.createEvent(EVENT_TYPES
.CLICK
);
4743 this.clickEvent
.signature
= SIGNATURE
;
4745 this.keyPressEvent
= this.createEvent(EVENT_TYPES
.KEY_PRESS
);
4746 this.keyPressEvent
.signature
= SIGNATURE
;
4748 this.keyDownEvent
= this.createEvent(EVENT_TYPES
.KEY_DOWN
);
4749 this.keyDownEvent
.signature
= SIGNATURE
;
4751 this.keyUpEvent
= this.createEvent(EVENT_TYPES
.KEY_UP
);
4752 this.keyUpEvent
.signature
= SIGNATURE
;
4754 this.focusEvent
= this.createEvent(EVENT_TYPES
.FOCUS
);
4755 this.focusEvent
.signature
= SIGNATURE
;
4757 this.blurEvent
= this.createEvent(EVENT_TYPES
.BLUR
);
4758 this.blurEvent
.signature
= SIGNATURE
;
4760 this.itemAddedEvent
= this.createEvent(EVENT_TYPES
.ITEM_ADDED
);
4761 this.itemAddedEvent
.signature
= SIGNATURE
;
4763 this.itemRemovedEvent
= this.createEvent(EVENT_TYPES
.ITEM_REMOVED
);
4764 this.itemRemovedEvent
.signature
= SIGNATURE
;
4771 * @description Finds the menu's root menu.
4773 getRoot: function () {
4775 var oItem
= this.parent
,
4780 oParentMenu
= oItem
.parent
;
4782 return oParentMenu
? oParentMenu
.getRoot() : this;
4796 * @description Returns a string representing the menu.
4799 toString: function () {
4801 var sReturnVal
= "Menu",
4806 sReturnVal
+= (" " + sId
);
4816 * @method setItemGroupTitle
4817 * @description Sets the title of a group of menu items.
4818 * @param {String} p_sGroupTitle String specifying the title of the group.
4819 * @param {Number} p_nGroupIndex Optional. Number specifying the group to which
4820 * the title belongs.
4822 setItemGroupTitle: function (p_sGroupTitle
, p_nGroupIndex
) {
4829 if (typeof p_sGroupTitle
== "string" && p_sGroupTitle
.length
> 0) {
4831 nGroupIndex
= typeof p_nGroupIndex
== "number" ? p_nGroupIndex
: 0;
4832 oTitle
= this._aGroupTitleElements
[nGroupIndex
];
4837 oTitle
.innerHTML
= p_sGroupTitle
;
4842 oTitle
= document
.createElement(this.GROUP_TITLE_TAG_NAME
);
4844 oTitle
.innerHTML
= p_sGroupTitle
;
4846 this._aGroupTitleElements
[nGroupIndex
] = oTitle
;
4851 i
= this._aGroupTitleElements
.length
- 1;
4855 if (this._aGroupTitleElements
[i
]) {
4857 Dom
.removeClass(this._aGroupTitleElements
[i
], "first-of-type");
4867 if (nFirstIndex
!== null) {
4869 Dom
.addClass(this._aGroupTitleElements
[nFirstIndex
],
4874 this.changeContentEvent
.fire();
4884 * @description Appends an item to the menu.
4885 * @param {YAHOO.widget.MenuItem} p_oItem Object reference for the MenuItem
4886 * instance to be added to the menu.
4887 * @param {String} p_oItem String specifying the text of the item to be added
4889 * @param {Object} p_oItem Object literal containing a set of menu item
4890 * configuration properties.
4891 * @param {Number} p_nGroupIndex Optional. Number indicating the group to
4892 * which the item belongs.
4893 * @return {YAHOO.widget.MenuItem}
4895 addItem: function (p_oItem
, p_nGroupIndex
) {
4899 return this._addItemToGroup(p_nGroupIndex
, p_oItem
);
4908 * @description Adds an array of items to the menu.
4909 * @param {Array} p_aItems Array of items to be added to the menu. The array
4910 * can contain strings specifying the text for each item to be created, object
4911 * literals specifying each of the menu item configuration properties,
4912 * or MenuItem instances.
4913 * @param {Number} p_nGroupIndex Optional. Number specifying the group to
4914 * which the items belongs.
4917 addItems: function (p_aItems
, p_nGroupIndex
) {
4924 if (Lang
.isArray(p_aItems
)) {
4926 nItems
= p_aItems
.length
;
4929 for(i
=0; i
<nItems
; i
++) {
4931 oItem
= p_aItems
[i
];
4935 if (Lang
.isArray(oItem
)) {
4937 aItems
[aItems
.length
] = this.addItems(oItem
, i
);
4942 aItems
[aItems
.length
] =
4943 this._addItemToGroup(p_nGroupIndex
, oItem
);
4952 if (aItems
.length
) {
4964 * @method insertItem
4965 * @description Inserts an item into the menu at the specified index.
4966 * @param {YAHOO.widget.MenuItem} p_oItem Object reference for the MenuItem
4967 * instance to be added to the menu.
4968 * @param {String} p_oItem String specifying the text of the item to be added
4970 * @param {Object} p_oItem Object literal containing a set of menu item
4971 * configuration properties.
4972 * @param {Number} p_nItemIndex Number indicating the ordinal position at which
4973 * the item should be added.
4974 * @param {Number} p_nGroupIndex Optional. Number indicating the group to which
4976 * @return {YAHOO.widget.MenuItem}
4978 insertItem: function (p_oItem
, p_nItemIndex
, p_nGroupIndex
) {
4982 return this._addItemToGroup(p_nGroupIndex
, p_oItem
, p_nItemIndex
);
4990 * @method removeItem
4991 * @description Removes the specified item from the menu.
4992 * @param {YAHOO.widget.MenuItem} p_oObject Object reference for the MenuItem
4993 * instance to be removed from the menu.
4994 * @param {Number} p_oObject Number specifying the index of the item
4996 * @param {Number} p_nGroupIndex Optional. Number specifying the group to
4997 * which the item belongs.
4998 * @return {YAHOO.widget.MenuItem}
5000 removeItem: function (p_oObject
, p_nGroupIndex
) {
5004 if (typeof p_oObject
!= "undefined") {
5006 if (p_oObject
instanceof YAHOO
.widget
.MenuItem
) {
5008 oItem
= this._removeItemFromGroupByValue(p_nGroupIndex
, p_oObject
);
5011 else if (typeof p_oObject
== "number") {
5013 oItem
= this._removeItemFromGroupByIndex(p_nGroupIndex
, p_oObject
);
5033 * @description Returns an array of all of the items in the menu.
5036 getItems: function () {
5038 var aGroups
= this._aItemGroups
,
5039 nGroups
= aGroups
.length
;
5041 return ((nGroups
== 1) ? aGroups
[0] :
5042 (Array
.prototype.concat
.apply([], aGroups
)));
5048 * @method getItemGroups
5049 * @description Multi-dimensional Array representing the menu items as they
5050 * are grouped in the menu.
5053 getItemGroups: function () {
5055 return this._aItemGroups
;
5062 * @description Returns the item at the specified index.
5063 * @param {Number} p_nItemIndex Number indicating the ordinal position of the
5064 * item to be retrieved.
5065 * @param {Number} p_nGroupIndex Optional. Number indicating the group to which
5067 * @return {YAHOO.widget.MenuItem}
5069 getItem: function (p_nItemIndex
, p_nGroupIndex
) {
5073 if (typeof p_nItemIndex
== "number") {
5075 aGroup
= this._getItemGroup(p_nGroupIndex
);
5079 return aGroup
[p_nItemIndex
];
5089 * @method getSubmenus
5090 * @description Returns an array of all of the submenus that are immediate
5091 * children of the menu.
5094 getSubmenus: function () {
5096 var aItems
= this.getItems(),
5097 nItems
= aItems
.length
,
5108 for(i
=0; i
<nItems
; i
++) {
5114 oSubmenu
= oItem
.cfg
.getProperty("submenu");
5118 aSubmenus
[aSubmenus
.length
] = oSubmenu
;
5133 * @method clearContent
5134 * @description Removes all of the content from the menu, including the menu
5135 * items, group titles, header and footer.
5137 clearContent: function () {
5139 var aItems
= this.getItems(),
5140 nItems
= aItems
.length
,
5141 oElement
= this.element
,
5143 oHeader
= this.header
,
5144 oFooter
= this.footer
,
5160 oSubmenu
= oItem
.cfg
.getProperty("submenu");
5164 this.cfg
.configChangedEvent
.unsubscribe(
5165 this._onParentMenuConfigChange
, oSubmenu
);
5167 this.renderEvent
.unsubscribe(this._onParentMenuRender
,
5172 this.removeItem(oItem
);
5184 Event
.purgeElement(oHeader
);
5185 oElement
.removeChild(oHeader
);
5192 Event
.purgeElement(oFooter
);
5193 oElement
.removeChild(oFooter
);
5199 Event
.purgeElement(oBody
);
5201 oBody
.innerHTML
= "";
5206 this._aItemGroups
= [];
5207 this._aListElements
= [];
5208 this._aGroupTitleElements
= [];
5210 this.cfg
.setProperty("width", null);
5217 * @description Removes the menu's <code><div></code> element
5218 * (and accompanying child nodes) from the document.
5220 destroy: function () {
5222 Module
.textResizeEvent
.unsubscribe(this._onTextResize
, this);
5227 this.clearContent();
5229 this._aItemGroups
= null;
5230 this._aListElements
= null;
5231 this._aGroupTitleElements
= null;
5234 // Continue with the superclass implementation of this method
5236 Menu
.superclass
.destroy
.call(this);
5243 * @method setInitialFocus
5244 * @description Sets focus to the menu's first enabled item.
5246 setInitialFocus: function () {
5248 var oItem
= this._getFirstEnabledItem();
5260 * @method setInitialSelection
5261 * @description Sets the "selected" configuration property of the menu's first
5262 * enabled item to "true."
5264 setInitialSelection: function () {
5266 var oItem
= this._getFirstEnabledItem();
5270 oItem
.cfg
.setProperty("selected", true);
5277 * @method clearActiveItem
5278 * @description Sets the "selected" configuration property of the menu's active
5279 * item to "false" and hides the item's submenu.
5280 * @param {Boolean} p_bBlur Boolean indicating if the menu's active item
5281 * should be blurred.
5283 clearActiveItem: function (p_bBlur
) {
5285 if (this.cfg
.getProperty("showdelay") > 0) {
5287 this._cancelShowDelay();
5292 var oActiveItem
= this.activeItem
,
5298 oConfig
= oActiveItem
.cfg
;
5306 oConfig
.setProperty("selected", false);
5308 oSubmenu
= oConfig
.getProperty("submenu");
5316 this.activeItem
= null;
5325 * @description Causes the menu to receive focus and fires the "focus" event.
5327 focus: function () {
5329 if (!this.hasFocus()) {
5331 this.setInitialFocus();
5340 * @description Causes the menu to lose focus and fires the "blur" event.
5346 if (this.hasFocus()) {
5348 oItem
= MenuManager
.getFocusedMenuItem();
5363 * @description Returns a boolean indicating whether or not the menu has focus.
5366 hasFocus: function () {
5368 return (MenuManager
.getFocusedMenu() == this.getRoot());
5374 * Adds the specified CustomEvent subscriber to the menu and each of
5377 * @param p_type {string} the type, or name of the event
5378 * @param p_fn {function} the function to exectute when the event fires
5379 * @param p_obj {Object} An object to be passed along when the event
5381 * @param p_override {boolean} If true, the obj passed in becomes the
5382 * execution scope of the listener
5384 subscribe: function () {
5386 function onItemAdded(p_sType
, p_aArgs
, p_oObject
) {
5388 var oItem
= p_aArgs
[0],
5389 oSubmenu
= oItem
.cfg
.getProperty("submenu");
5393 oSubmenu
.subscribe
.apply(oSubmenu
, p_oObject
);
5400 Menu
.superclass
.subscribe
.apply(this, arguments
);
5401 Menu
.superclass
.subscribe
.call(this, "itemAdded", onItemAdded
, arguments
);
5404 var aSubmenus
= this.getSubmenus(),
5411 nSubmenus
= aSubmenus
.length
;
5413 if (nSubmenus
> 0) {
5419 oSubmenu
= aSubmenus
[i
];
5421 oSubmenu
.subscribe
.apply(oSubmenu
, arguments
);
5434 * @description Initializes the class's configurable properties which can be
5435 * changed using the menu's Config object ("cfg").
5436 * @method initDefaultConfig
5438 initDefaultConfig: function () {
5440 Menu
.superclass
.initDefaultConfig
.call(this);
5442 var oConfig
= this.cfg
;
5444 // Add configuration attributes
5447 Change the default value for the "visible" configuration
5448 property to "false" by re-adding the property.
5453 * @description Boolean indicating whether or not the menu is visible. If
5454 * the menu's "position" configuration property is set to "dynamic" (the
5455 * default), this property toggles the menu's <code><div></code>
5456 * element's "visibility" style property between "visible" (true) or
5457 * "hidden" (false). If the menu's "position" configuration property is
5458 * set to "static" this property toggles the menu's
5459 * <code><div></code> element's "display" style property
5460 * between "block" (true) or "none" (false).
5464 oConfig
.addProperty(
5465 DEFAULT_CONFIG
.VISIBLE
.key
,
5467 handler
: this.configVisible
,
5468 value
: DEFAULT_CONFIG
.VISIBLE
.value
,
5469 validator
: DEFAULT_CONFIG
.VISIBLE
.validator
5475 Change the default value for the "constraintoviewport" configuration
5476 property to "true" by re-adding the property.
5480 * @config constraintoviewport
5481 * @description Boolean indicating if the menu will try to remain inside
5482 * the boundaries of the size of viewport.
5486 oConfig
.addProperty(
5487 DEFAULT_CONFIG
.CONSTRAIN_TO_VIEWPORT
.key
,
5489 handler
: this.configConstrainToViewport
,
5490 value
: DEFAULT_CONFIG
.CONSTRAIN_TO_VIEWPORT
.value
,
5491 validator
: DEFAULT_CONFIG
.CONSTRAIN_TO_VIEWPORT
.validator
,
5492 supercedes
: DEFAULT_CONFIG
.CONSTRAIN_TO_VIEWPORT
.supercedes
5499 * @description String indicating how a menu should be positioned on the
5500 * screen. Possible values are "static" and "dynamic." Static menus are
5501 * visible by default and reside in the normal flow of the document
5502 * (CSS position: static). Dynamic menus are hidden by default, reside
5503 * out of the normal flow of the document (CSS position: absolute), and
5504 * can overlay other elements on the screen.
5508 oConfig
.addProperty(
5509 DEFAULT_CONFIG
.POSITION
.key
,
5511 handler
: this.configPosition
,
5512 value
: DEFAULT_CONFIG
.POSITION
.value
,
5513 validator
: DEFAULT_CONFIG
.POSITION
.validator
,
5514 supercedes
: DEFAULT_CONFIG
.POSITION
.supercedes
5520 * @config submenualignment
5521 * @description Array defining how submenus should be aligned to their
5522 * parent menu item. The format is: [itemCorner, submenuCorner]. By default
5523 * a submenu's top left corner is aligned to its parent menu item's top
5525 * @default ["tl","tr"]
5528 oConfig
.addProperty(
5529 DEFAULT_CONFIG
.SUBMENU_ALIGNMENT
.key
,
5531 value
: DEFAULT_CONFIG
.SUBMENU_ALIGNMENT
.value
5537 * @config autosubmenudisplay
5538 * @description Boolean indicating if submenus are automatically made
5539 * visible when the user mouses over the menu's items.
5543 oConfig
.addProperty(
5544 DEFAULT_CONFIG
.AUTO_SUBMENU_DISPLAY
.key
,
5546 value
: DEFAULT_CONFIG
.AUTO_SUBMENU_DISPLAY
.value
,
5547 validator
: DEFAULT_CONFIG
.AUTO_SUBMENU_DISPLAY
.validator
5554 * @description Number indicating the time (in milliseconds) that should
5555 * expire before a submenu is made visible when the user mouses over
5560 oConfig
.addProperty(
5561 DEFAULT_CONFIG
.SHOW_DELAY
.key
,
5563 value
: DEFAULT_CONFIG
.SHOW_DELAY
.value
,
5564 validator
: DEFAULT_CONFIG
.SHOW_DELAY
.validator
5571 * @description Number indicating the time (in milliseconds) that should
5572 * expire before the menu is hidden.
5576 oConfig
.addProperty(
5577 DEFAULT_CONFIG
.HIDE_DELAY
.key
,
5579 handler
: this.configHideDelay
,
5580 value
: DEFAULT_CONFIG
.HIDE_DELAY
.value
,
5581 validator
: DEFAULT_CONFIG
.HIDE_DELAY
.validator
,
5582 suppressEvent
: DEFAULT_CONFIG
.HIDE_DELAY
.suppressEvent
5588 * @config submenuhidedelay
5589 * @description Number indicating the time (in milliseconds) that should
5590 * expire before a submenu is hidden when the user mouses out of a menu item
5591 * heading in the direction of a submenu. The value must be greater than or
5592 * equal to the value specified for the "showdelay" configuration property.
5596 oConfig
.addProperty(
5597 DEFAULT_CONFIG
.SUBMENU_HIDE_DELAY
.key
,
5599 value
: DEFAULT_CONFIG
.SUBMENU_HIDE_DELAY
.value
,
5600 validator
: DEFAULT_CONFIG
.SUBMENU_HIDE_DELAY
.validator
5606 * @config clicktohide
5607 * @description Boolean indicating if the menu will automatically be
5608 * hidden if the user clicks outside of it.
5612 oConfig
.addProperty(
5613 DEFAULT_CONFIG
.CLICK_TO_HIDE
.key
,
5615 value
: DEFAULT_CONFIG
.CLICK_TO_HIDE
.value
,
5616 validator
: DEFAULT_CONFIG
.CLICK_TO_HIDE
.validator
5623 * @description HTML element reference or string specifying the id
5624 * attribute of the HTML element that the menu's markup should be
5626 * @type <a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/
5627 * level-one-html.html#ID-58190037">HTMLElement</a>|String
5628 * @default document.body
5630 oConfig
.addProperty(
5631 DEFAULT_CONFIG
.CONTAINER
.key
,
5633 handler
: this.configContainer
,
5634 value
: document
.body
5641 * @description Defines the maximum height (in pixels) for a menu before the
5642 * contents of the body are scrolled.
5646 oConfig
.addProperty(
5647 DEFAULT_CONFIG
.MAX_HEIGHT
.key
,
5649 handler
: this.configMaxHeight
,
5650 value
: DEFAULT_CONFIG
.MAX_HEIGHT
.value
,
5651 validator
: DEFAULT_CONFIG
.MAX_HEIGHT
.validator
5658 * @description CSS class to be applied to the menu's root
5659 * <code><div></code> element. The specified class(es) are
5660 * appended in addition to the default class as specified by the menu's
5661 * CSS_CLASS_NAME constant.
5665 oConfig
.addProperty(
5666 DEFAULT_CONFIG
.CLASS_NAME
.key
,
5668 handler
: this.configClassName
,
5669 value
: DEFAULT_CONFIG
.CLASS_NAME
.value
,
5670 validator
: DEFAULT_CONFIG
.CLASS_NAME
.validator
5677 * @description Boolean indicating if the menu should be disabled.
5678 * Disabling a menu disables each of its items. (Disabled menu items are
5679 * dimmed and will not respond to user input or fire events.) Disabled
5680 * menus have a corresponding "disabled" CSS class applied to their root
5681 * <code><div></code> element.
5685 oConfig
.addProperty(
5686 DEFAULT_CONFIG
.DISABLED
.key
,
5688 handler
: this.configDisabled
,
5689 value
: DEFAULT_CONFIG
.DISABLED
.value
,
5690 validator
: DEFAULT_CONFIG
.DISABLED
.validator
5696 }); // END YAHOO.lang.extend
5706 * Creates an item for a menu.
5708 * @param {String} p_oObject String specifying the text of the menu item.
5709 * @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-
5710 * one-html.html#ID-74680021">HTMLLIElement</a>} p_oObject Object specifying
5711 * the <code><li></code> element of the menu item.
5712 * @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-
5713 * one-html.html#ID-38450247">HTMLOptGroupElement</a>} p_oObject Object
5714 * specifying the <code><optgroup></code> element of the menu item.
5715 * @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-
5716 * one-html.html#ID-70901257">HTMLOptionElement</a>} p_oObject Object
5717 * specifying the <code><option></code> element of the menu item.
5718 * @param {Object} p_oConfig Optional. Object literal specifying the
5719 * configuration for the menu item. See configuration class documentation
5724 YAHOO
.widget
.MenuItem = function(p_oObject
, p_oConfig
) {
5730 this.parent
= p_oConfig
.parent
;
5731 this.value
= p_oConfig
.value
;
5732 this.id
= p_oConfig
.id
;
5736 this.init(p_oObject
, p_oConfig
);
5742 var Dom
= YAHOO
.util
.Dom
,
5743 Module
= YAHOO
.widget
.Module
,
5744 Menu
= YAHOO
.widget
.Menu
,
5745 MenuItem
= YAHOO
.widget
.MenuItem
,
5746 CustomEvent
= YAHOO
.util
.CustomEvent
,
5749 m_oMenuItemTemplate
,
5752 * Constant representing the name of the MenuItem's events
5753 * @property EVENT_TYPES
5760 "MOUSE_OVER": "mouseover",
5761 "MOUSE_OUT": "mouseout",
5762 "MOUSE_DOWN": "mousedown",
5763 "MOUSE_UP": "mouseup",
5765 "KEY_PRESS": "keypress",
5766 "KEY_DOWN": "keydown",
5768 "ITEM_ADDED": "itemAdded",
5769 "ITEM_REMOVED": "itemRemoved",
5772 "DESTROY": "destroy"
5777 * Constant representing the MenuItem's configuration properties
5778 * @property DEFAULT_CONFIG
5788 validator
: Lang
.isString
,
5794 supercedes
: ["text"]
5811 validator
: Lang
.isBoolean
,
5812 suppressEvent
: true,
5813 supercedes
: ["text"]
5816 "STRONG_EMPHASIS": {
5817 key
: "strongemphasis",
5819 validator
: Lang
.isBoolean
,
5820 suppressEvent
: true,
5821 supercedes
: ["text"]
5827 validator
: Lang
.isBoolean
,
5828 suppressEvent
: true,
5829 supercedes
: ["text"]
5835 validator
: Lang
.isBoolean
,
5836 suppressEvent
: true,
5837 supercedes
: ["text"]
5843 validator
: Lang
.isBoolean
,
5849 supercedes
: ["text"]
5859 validator
: Lang
.isString
5865 MenuItem
.prototype = {
5870 * @property COLLAPSED_SUBMENU_INDICATOR_TEXT
5871 * @description String representing the text for the <code><em></code>
5872 * element used for the submenu arrow indicator.
5873 * @default "Submenu collapsed. Click to expand submenu."
5877 COLLAPSED_SUBMENU_INDICATOR_TEXT
:
5878 "Submenu collapsed. Click to expand submenu.",
5882 * @property EXPANDED_SUBMENU_INDICATOR_TEXT
5883 * @description String representing the text for the submenu arrow indicator
5884 * element (<code><em></code>) when the submenu is visible.
5885 * @default "Submenu expanded. Click to collapse submenu."
5889 EXPANDED_SUBMENU_INDICATOR_TEXT
:
5890 "Submenu expanded. Click to collapse submenu.",
5894 * @property DISABLED_SUBMENU_INDICATOR_TEXT
5895 * @description String representing the text for the submenu arrow indicator
5896 * element (<code><em></code>) when the menu item is disabled.
5897 * @default "Submenu collapsed. (Item disabled.)."
5901 DISABLED_SUBMENU_INDICATOR_TEXT
: "Submenu collapsed. (Item disabled.)",
5905 * @property CHECKED_TEXT
5906 * @description String representing the text to be used for the checked
5907 * indicator element (<code><em></code>).
5908 * @default "Checked."
5912 CHECKED_TEXT
: "Menu item checked.",
5916 * @property DISABLED_CHECKED_TEXT
5917 * @description String representing the text to be used for the checked
5918 * indicator element (<code><em></code>) when the menu item
5920 * @default "Checked. (Item disabled.)"
5924 DISABLED_CHECKED_TEXT
: "Checked. (Item disabled.)",
5928 * @property CSS_CLASS_NAME
5929 * @description String representing the CSS class(es) to be applied to the
5930 * <code><li></code> element of the menu item.
5931 * @default "yuimenuitem"
5935 CSS_CLASS_NAME
: "yuimenuitem",
5939 * @property CSS_LABEL_CLASS_NAME
5940 * @description String representing the CSS class(es) to be applied to the
5941 * menu item's <code><a></code> element.
5942 * @default "yuimenuitemlabel"
5946 CSS_LABEL_CLASS_NAME
: "yuimenuitemlabel",
5950 * @property SUBMENU_TYPE
5951 * @description Object representing the type of menu to instantiate and
5952 * add when parsing the child nodes of the menu item's source HTML element.
5954 * @type YAHOO.widget.Menu
5960 // Private member variables
5964 * @property _oAnchor
5965 * @description Object reference to the menu item's
5966 * <code><a></code> element.
5969 * @type <a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-
5970 * one-html.html#ID-48250443">HTMLAnchorElement</a>
5976 * @property _oHelpTextEM
5977 * @description Object reference to the menu item's help text
5978 * <code><em></code> element.
5981 * @type <a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-
5982 * one-html.html#ID-58190037">HTMLElement</a>
5988 * @property _oSubmenu
5989 * @description Object reference to the menu item's submenu.
5992 * @type YAHOO.widget.Menu
5998 * @property _oCheckedIndicator
5999 * @description Object reference to the menu item's checkmark image.
6000 * @default <a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/
6001 * level-one-html.html#ID-58190037">HTMLElement</a>
6003 * @type <a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/
6004 * level-one-html.html#ID-58190037">HTMLElement</a>
6006 _oCheckedIndicator
: null,
6010 * @property _oOnclickAttributeValue
6011 * @description Object reference to the menu item's current value for the
6012 * "onclick" configuration attribute.
6017 _oOnclickAttributeValue
: null,
6021 * @property _sClassName
6022 * @description The current value of the "classname" configuration attribute.
6031 // Public properties
6035 * @property constructor
6036 * @description Object reference to the menu item's constructor function.
6037 * @default YAHOO.widget.MenuItem
6038 * @type YAHOO.widget.MenuItem
6040 constructor: MenuItem
,
6045 * @description Number indicating the ordinal position of the menu item in
6054 * @property groupIndex
6055 * @description Number indicating the index of the group to which the menu
6065 * @description Object reference to the menu item's parent menu.
6067 * @type YAHOO.widget.Menu
6074 * @description Object reference to the menu item's
6075 * <code><li></code> element.
6076 * @default <a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level
6077 * -one-html.html#ID-74680021">HTMLLIElement</a>
6078 * @type <a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-
6079 * one-html.html#ID-74680021">HTMLLIElement</a>
6085 * @property srcElement
6086 * @description Object reference to the HTML element (either
6087 * <code><li></code>, <code><optgroup></code> or
6088 * <code><option></code>) used create the menu item.
6089 * @default <a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/
6090 * level-one-html.html#ID-74680021">HTMLLIElement</a>|<a href="http://www.
6091 * w3.org/TR/2000/WD-DOM-Level-1-20000929/level-one-html.html#ID-38450247"
6092 * >HTMLOptGroupElement</a>|<a href="http://www.w3.org/TR/2000/WD-DOM-
6093 * Level-1-20000929/level-one-html.html#ID-70901257">HTMLOptionElement</a>
6094 * @type <a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-
6095 * one-html.html#ID-74680021">HTMLLIElement</a>|<a href="http://www.w3.
6096 * org/TR/2000/WD-DOM-Level-1-20000929/level-one-html.html#ID-38450247">
6097 * HTMLOptGroupElement</a>|<a href="http://www.w3.org/TR/2000/WD-DOM-
6098 * Level-1-20000929/level-one-html.html#ID-70901257">HTMLOptionElement</a>
6105 * @description Object reference to the menu item's value.
6113 * @property submenuIndicator
6114 * @description Object reference to the <code><em></code> element
6115 * used to create the submenu indicator for the menu item.
6116 * @default <a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/
6117 * level-one-html.html#ID-58190037">HTMLElement</a>
6118 * @type <a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/
6119 * level-one-html.html#ID-58190037">HTMLElement</a>
6121 submenuIndicator
: null,
6126 * @deprecated Use YAHOO.env.ua
6127 * @description String representing the browser.
6130 browser
: Module
.prototype.browser
,
6135 * @description Id of the menu item's root <code><li></code>
6136 * element. This property should be set via the constructor using the
6137 * configuration object literal. If an id is not specified, then one will
6138 * be created using the "generateId" method of the Dom utility.
6150 * @event destroyEvent
6151 * @description Fires when the menu item's <code><li></code>
6152 * element is removed from its parent <code><ul></code> element.
6153 * @type YAHOO.util.CustomEvent
6159 * @event mouseOverEvent
6160 * @description Fires when the mouse has entered the menu item. Passes
6161 * back the DOM Event object as an argument.
6162 * @type YAHOO.util.CustomEvent
6164 mouseOverEvent
: null,
6168 * @event mouseOutEvent
6169 * @description Fires when the mouse has left the menu item. Passes back
6170 * the DOM Event object as an argument.
6171 * @type YAHOO.util.CustomEvent
6173 mouseOutEvent
: null,
6177 * @event mouseDownEvent
6178 * @description Fires when the user mouses down on the menu item. Passes
6179 * back the DOM Event object as an argument.
6180 * @type YAHOO.util.CustomEvent
6182 mouseDownEvent
: null,
6186 * @event mouseUpEvent
6187 * @description Fires when the user releases a mouse button while the mouse
6188 * is over the menu item. Passes back the DOM Event object as an argument.
6189 * @type YAHOO.util.CustomEvent
6196 * @description Fires when the user clicks the on the menu item. Passes
6197 * back the DOM Event object as an argument.
6198 * @type YAHOO.util.CustomEvent
6204 * @event keyPressEvent
6205 * @description Fires when the user presses an alphanumeric key when the
6206 * menu item has focus. Passes back the DOM Event object as an argument.
6207 * @type YAHOO.util.CustomEvent
6209 keyPressEvent
: null,
6213 * @event keyDownEvent
6214 * @description Fires when the user presses a key when the menu item has
6215 * focus. Passes back the DOM Event object as an argument.
6216 * @type YAHOO.util.CustomEvent
6223 * @description Fires when the user releases a key when the menu item has
6224 * focus. Passes back the DOM Event object as an argument.
6225 * @type YAHOO.util.CustomEvent
6232 * @description Fires when the menu item receives focus.
6233 * @type YAHOO.util.CustomEvent
6240 * @description Fires when the menu item loses the input focus.
6241 * @type YAHOO.util.CustomEvent
6248 * @description The MenuItem class's initialization method. This method is
6249 * automatically called by the constructor, and sets up all DOM references
6250 * for pre-existing markup, and creates required markup if it is not
6252 * @param {String} p_oObject String specifying the text of the menu item.
6253 * @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-
6254 * one-html.html#ID-74680021">HTMLLIElement</a>} p_oObject Object specifying
6255 * the <code><li></code> element of the menu item.
6256 * @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-
6257 * one-html.html#ID-38450247">HTMLOptGroupElement</a>} p_oObject Object
6258 * specifying the <code><optgroup></code> element of the menu item.
6259 * @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-
6260 * one-html.html#ID-70901257">HTMLOptionElement</a>} p_oObject Object
6261 * specifying the <code><option></code> element of the menu item.
6262 * @param {Object} p_oConfig Optional. Object literal specifying the
6263 * configuration for the menu item. See configuration class documentation
6266 init: function(p_oObject
, p_oConfig
) {
6269 if(!this.SUBMENU_TYPE
) {
6271 this.SUBMENU_TYPE
= Menu
;
6276 // Create the config object
6278 this.cfg
= new YAHOO
.util
.Config(this);
6280 this.initDefaultConfig();
6282 var SIGNATURE
= CustomEvent
.LIST
,
6291 if(Lang
.isString(p_oObject
)) {
6293 this._createRootNodeStructure();
6295 oConfig
.queueProperty("text", p_oObject
);
6298 else if(p_oObject
&& p_oObject
.tagName
) {
6300 switch(p_oObject
.tagName
.toUpperCase()) {
6304 this._createRootNodeStructure();
6306 oConfig
.queueProperty("text", p_oObject
.text
);
6308 this.srcElement
= p_oObject
;
6314 this._createRootNodeStructure();
6316 oConfig
.queueProperty("text", p_oObject
.label
);
6318 this.srcElement
= p_oObject
;
6320 this._initSubTree();
6326 // Get the anchor node (if it exists)
6328 oAnchor
= Dom
.getFirstChild(p_oObject
);
6331 // Capture the "text" and/or the "URL"
6335 sURL
= oAnchor
.getAttribute("href");
6336 sTarget
= oAnchor
.getAttribute("target");
6337 sText
= oAnchor
.innerHTML
;
6341 this.srcElement
= p_oObject
;
6342 this.element
= p_oObject
;
6343 this._oAnchor
= oAnchor
;
6346 Set these properties silently to sync up the
6347 configuration object without making changes to the
6351 oConfig
.setProperty("text", sText
, true);
6352 oConfig
.setProperty("url", sURL
, true);
6353 oConfig
.setProperty("target", sTarget
, true);
6355 this._initSubTree();
6366 sId
= this.element
.id
;
6370 sId
= this.id
|| Dom
.generateId();
6372 this.element
.id
= sId
;
6379 Dom
.addClass(this.element
, this.CSS_CLASS_NAME
);
6380 Dom
.addClass(this._oAnchor
, this.CSS_LABEL_CLASS_NAME
);
6383 // Create custom events
6385 this.mouseOverEvent
= this.createEvent(EVENT_TYPES
.MOUSE_OVER
);
6386 this.mouseOverEvent
.signature
= SIGNATURE
;
6388 this.mouseOutEvent
= this.createEvent(EVENT_TYPES
.MOUSE_OUT
);
6389 this.mouseOutEvent
.signature
= SIGNATURE
;
6391 this.mouseDownEvent
= this.createEvent(EVENT_TYPES
.MOUSE_DOWN
);
6392 this.mouseDownEvent
.signature
= SIGNATURE
;
6394 this.mouseUpEvent
= this.createEvent(EVENT_TYPES
.MOUSE_UP
);
6395 this.mouseUpEvent
.signature
= SIGNATURE
;
6397 this.clickEvent
= this.createEvent(EVENT_TYPES
.CLICK
);
6398 this.clickEvent
.signature
= SIGNATURE
;
6400 this.keyPressEvent
= this.createEvent(EVENT_TYPES
.KEY_PRESS
);
6401 this.keyPressEvent
.signature
= SIGNATURE
;
6403 this.keyDownEvent
= this.createEvent(EVENT_TYPES
.KEY_DOWN
);
6404 this.keyDownEvent
.signature
= SIGNATURE
;
6406 this.keyUpEvent
= this.createEvent(EVENT_TYPES
.KEY_UP
);
6407 this.keyUpEvent
.signature
= SIGNATURE
;
6409 this.focusEvent
= this.createEvent(EVENT_TYPES
.FOCUS
);
6410 this.focusEvent
.signature
= SIGNATURE
;
6412 this.blurEvent
= this.createEvent(EVENT_TYPES
.BLUR
);
6413 this.blurEvent
.signature
= SIGNATURE
;
6415 this.destroyEvent
= this.createEvent(EVENT_TYPES
.DESTROY
);
6416 this.destroyEvent
.signature
= SIGNATURE
;
6420 oConfig
.applyConfig(p_oConfig
);
6424 oConfig
.fireQueue();
6436 * @method _createRootNodeStructure
6437 * @description Creates the core DOM structure for the menu item.
6440 _createRootNodeStructure: function () {
6445 if(!m_oMenuItemTemplate
) {
6447 m_oMenuItemTemplate
= document
.createElement("li");
6448 m_oMenuItemTemplate
.innerHTML
= "<a href=\"#\"></a>";
6452 oElement
= m_oMenuItemTemplate
.cloneNode(true);
6453 oElement
.className
= this.CSS_CLASS_NAME
;
6455 oAnchor
= oElement
.firstChild
;
6456 oAnchor
.className
= this.CSS_LABEL_CLASS_NAME
;
6458 this.element
= oElement
;
6459 this._oAnchor
= oAnchor
;
6465 * @method _initSubTree
6466 * @description Iterates the source element's childNodes collection and uses
6467 * the child nodes to instantiate other menus.
6470 _initSubTree: function() {
6472 var oSrcEl
= this.srcElement
,
6481 if(oSrcEl
.childNodes
.length
> 0) {
6483 if(this.parent
.lazyLoad
&& this.parent
.srcElement
&&
6484 this.parent
.srcElement
.tagName
.toUpperCase() == "SELECT") {
6486 oConfig
.setProperty(
6488 { id
: Dom
.generateId(), itemdata
: oSrcEl
.childNodes
}
6494 oNode
= oSrcEl
.firstChild
;
6499 if(oNode
&& oNode
.tagName
) {
6501 switch(oNode
.tagName
.toUpperCase()) {
6505 oConfig
.setProperty("submenu", oNode
);
6511 aOptions
[aOptions
.length
] = oNode
;
6520 while((oNode
= oNode
.nextSibling
));
6523 nOptions
= aOptions
.length
;
6527 oMenu
= new this.SUBMENU_TYPE(Dom
.generateId());
6529 oConfig
.setProperty("submenu", oMenu
);
6531 for(n
=0; n
<nOptions
; n
++) {
6533 oMenu
.addItem((new oMenu
.ITEM_TYPE(aOptions
[n
])));
6547 // Event handlers for configuration properties
6551 * @method configText
6552 * @description Event handler for when the "text" configuration property of
6553 * the menu item changes.
6554 * @param {String} p_sType String representing the name of the event that
6556 * @param {Array} p_aArgs Array of arguments sent when the event was fired.
6557 * @param {YAHOO.widget.MenuItem} p_oItem Object representing the menu item
6558 * that fired the event.
6560 configText: function(p_sType
, p_aArgs
, p_oItem
) {
6562 var sText
= p_aArgs
[0],
6564 oAnchor
= this._oAnchor
,
6565 sHelpText
= oConfig
.getProperty("helptext"),
6568 oSubmenu
= oConfig
.getProperty("submenu"),
6569 sSubmenuIndicatorHTML
= "",
6570 sEmphasisStartTag
= "",
6571 sEmphasisEndTag
= "";
6579 sHelpTextHTML
= "<em class=\"helptext\">" + sHelpText
+ "</em>";
6584 if (oConfig
.getProperty("checked")) {
6586 sCheckHTML
= "<em class=\"checkedindicator\">" +
6587 this.CHECKED_TEXT
+ "</em>";
6594 sSubmenuIndicatorHTML
= "<em class=\"submenuindicator\">" +
6595 ((oSubmenu
instanceof Menu
&&
6596 oSubmenu
.cfg
.getProperty("visible")) ?
6597 this.EXPANDED_SUBMENU_INDICATOR_TEXT
:
6598 this.COLLAPSED_SUBMENU_INDICATOR_TEXT
) + "</em>";
6603 if (oConfig
.getProperty("emphasis")) {
6605 sEmphasisStartTag
= "<em>";
6606 sEmphasisEndTag
= "</em>";
6611 if (oConfig
.getProperty("strongemphasis")) {
6613 sEmphasisStartTag
= "<strong>";
6614 sEmphasisEndTag
= "</strong>";
6619 oAnchor
.innerHTML
= (sEmphasisStartTag
+ sText
+
6620 sEmphasisEndTag
+ sHelpTextHTML
+
6621 sCheckHTML
+ sSubmenuIndicatorHTML
);
6626 this.submenuIndicator
= oAnchor
.lastChild
;
6636 * @method configHelpText
6637 * @description Event handler for when the "helptext" configuration property
6638 * of the menu item changes.
6639 * @param {String} p_sType String representing the name of the event that
6641 * @param {Array} p_aArgs Array of arguments sent when the event was fired.
6642 * @param {YAHOO.widget.MenuItem} p_oItem Object representing the menu item
6643 * that fired the event.
6645 configHelpText: function(p_sType
, p_aArgs
, p_oItem
) {
6647 var sHelpText
= p_aArgs
[0],
6648 oAnchor
= this._oAnchor
;
6652 Dom
.addClass(oAnchor
, "hashelptext");
6657 Dom
.removeClass(oAnchor
, "hashelptext");
6661 this.cfg
.refireEvent("text");
6668 * @description Event handler for when the "url" configuration property of
6669 * the menu item changes.
6670 * @param {String} p_sType String representing the name of the event that
6672 * @param {Array} p_aArgs Array of arguments sent when the event was fired.
6673 * @param {YAHOO.widget.MenuItem} p_oItem Object representing the menu item
6674 * that fired the event.
6676 configURL: function(p_sType
, p_aArgs
, p_oItem
) {
6678 var sURL
= p_aArgs
[0];
6686 this._oAnchor
.setAttribute("href", sURL
);
6692 * @method configTarget
6693 * @description Event handler for when the "target" configuration property
6694 * of the menu item changes.
6695 * @param {String} p_sType String representing the name of the event that
6697 * @param {Array} p_aArgs Array of arguments sent when the event was fired.
6698 * @param {YAHOO.widget.MenuItem} p_oItem Object representing the menu item
6699 * that fired the event.
6701 configTarget: function(p_sType
, p_aArgs
, p_oItem
) {
6703 var sTarget
= p_aArgs
[0],
6704 oAnchor
= this._oAnchor
;
6706 if(sTarget
&& sTarget
.length
> 0) {
6708 oAnchor
.setAttribute("target", sTarget
);
6713 oAnchor
.removeAttribute("target");
6721 * @method configEmphasis
6722 * @description Event handler for when the "emphasis" configuration property
6723 * of the menu item changes.
6724 * @param {String} p_sType String representing the name of the event that
6726 * @param {Array} p_aArgs Array of arguments sent when the event was fired.
6727 * @param {YAHOO.widget.MenuItem} p_oItem Object representing the menu item
6728 * that fired the event.
6730 configEmphasis: function(p_sType
, p_aArgs
, p_oItem
) {
6732 var bEmphasis
= p_aArgs
[0],
6736 if(bEmphasis
&& oConfig
.getProperty("strongemphasis")) {
6738 oConfig
.setProperty("strongemphasis", false);
6743 oConfig
.refireEvent("text");
6749 * @method configStrongEmphasis
6750 * @description Event handler for when the "strongemphasis" configuration
6751 * property of the menu item changes.
6752 * @param {String} p_sType String representing the name of the event that
6754 * @param {Array} p_aArgs Array of arguments sent when the event was fired.
6755 * @param {YAHOO.widget.MenuItem} p_oItem Object representing the menu item
6756 * that fired the event.
6758 configStrongEmphasis: function(p_sType
, p_aArgs
, p_oItem
) {
6760 var bStrongEmphasis
= p_aArgs
[0],
6764 if(bStrongEmphasis
&& oConfig
.getProperty("emphasis")) {
6766 oConfig
.setProperty("emphasis", false);
6770 oConfig
.refireEvent("text");
6776 * @method configChecked
6777 * @description Event handler for when the "checked" configuration property
6778 * of the menu item changes.
6779 * @param {String} p_sType String representing the name of the event that
6781 * @param {Array} p_aArgs Array of arguments sent when the event was fired.
6782 * @param {YAHOO.widget.MenuItem} p_oItem Object representing the menu item
6783 * that fired the event.
6785 configChecked: function(p_sType
, p_aArgs
, p_oItem
) {
6787 var bChecked
= p_aArgs
[0],
6788 oAnchor
= this._oAnchor
;
6792 Dom
.addClass(oAnchor
, "checked");
6797 Dom
.removeClass(oAnchor
, "checked");
6801 this.cfg
.refireEvent("text");
6808 * @method configDisabled
6809 * @description Event handler for when the "disabled" configuration property
6810 * of the menu item changes.
6811 * @param {String} p_sType String representing the name of the event that
6813 * @param {Array} p_aArgs Array of arguments sent when the event was fired.
6814 * @param {YAHOO.widget.MenuItem} p_oItem Object representing the menu item
6815 * that fired the event.
6817 configDisabled: function(p_sType
, p_aArgs
, p_oItem
) {
6819 var bDisabled
= p_aArgs
[0],
6821 oAnchor
= this._oAnchor
;
6826 if(oConfig
.getProperty("selected")) {
6828 oConfig
.setProperty("selected", false);
6832 oAnchor
.removeAttribute("href");
6834 Dom
.addClass(oAnchor
, "disabled");
6839 oAnchor
.setAttribute("href", oConfig
.getProperty("url"));
6841 Dom
.removeClass(oAnchor
, "disabled");
6849 * @method configSelected
6850 * @description Event handler for when the "selected" configuration property
6851 * of the menu item changes.
6852 * @param {String} p_sType String representing the name of the event that
6854 * @param {Array} p_aArgs Array of arguments sent when the event was fired.
6855 * @param {YAHOO.widget.MenuItem} p_oItem Object representing the menu item
6856 * that fired the event.
6858 configSelected: function(p_sType
, p_aArgs
, p_oItem
) {
6863 if(!this.cfg
.getProperty("disabled")) {
6865 bSelected
= p_aArgs
[0];
6866 oAnchor
= this._oAnchor
;
6871 Dom
.addClass(oAnchor
, "selected");
6876 Dom
.removeClass(oAnchor
, "selected");
6886 * @method configSubmenu
6887 * @description Event handler for when the "submenu" configuration property
6888 * of the menu item changes.
6889 * @param {String} p_sType String representing the name of the event that
6891 * @param {Array} p_aArgs Array of arguments sent when the event was fired.
6892 * @param {YAHOO.widget.MenuItem} p_oItem Object representing the menu item
6893 * that fired the event.
6895 configSubmenu: function(p_sType
, p_aArgs
, p_oItem
) {
6897 var oAnchor
= this._oAnchor
,
6898 oSubmenu
= p_aArgs
[0],
6899 oSubmenuIndicator
= this.submenuIndicator
,
6901 bLazyLoad
= this.parent
&& this.parent
.lazyLoad
,
6909 if(oSubmenu
instanceof Menu
) {
6912 oMenu
.parent
= this;
6913 oMenu
.lazyLoad
= bLazyLoad
;
6916 else if(typeof oSubmenu
== "object" && oSubmenu
.id
&&
6917 !oSubmenu
.nodeType
) {
6919 sSubmenuId
= oSubmenu
.id
;
6920 oSubmenuConfig
= oSubmenu
;
6922 oSubmenuConfig
.lazyload
= bLazyLoad
;
6923 oSubmenuConfig
.parent
= this;
6925 oMenu
= new this.SUBMENU_TYPE(sSubmenuId
, oSubmenuConfig
);
6928 // Set the value of the property to the Menu instance
6930 this.cfg
.setProperty("submenu", oMenu
, true);
6935 oMenu
= new this.SUBMENU_TYPE(oSubmenu
,
6936 { lazyload
: bLazyLoad
, parent
: this });
6939 // Set the value of the property to the Menu instance
6941 this.cfg
.setProperty("submenu", oMenu
, true);
6948 Dom
.addClass(oAnchor
, "hassubmenu");
6950 this._oSubmenu
= oMenu
;
6957 Dom
.removeClass(oAnchor
, "hassubmenu");
6959 if(oSubmenuIndicator
) {
6961 oAnchor
.removeChild(oSubmenuIndicator
);
6965 if(this._oSubmenu
) {
6967 this._oSubmenu
.destroy();
6973 oConfig
.refireEvent("text");
6979 * @method configOnClick
6980 * @description Event handler for when the "onclick" configuration property
6981 * of the menu item changes.
6982 * @param {String} p_sType String representing the name of the event that
6984 * @param {Array} p_aArgs Array of arguments sent when the event was fired.
6985 * @param {YAHOO.widget.MenuItem} p_oItem Object representing the menu item
6986 * that fired the event.
6988 configOnClick: function(p_sType
, p_aArgs
, p_oItem
) {
6990 var oObject
= p_aArgs
[0];
6993 Remove any existing listeners if a "click" event handler has
6994 already been specified.
6997 if(this._oOnclickAttributeValue
&&
6998 (this._oOnclickAttributeValue
!= oObject
)) {
7000 this.clickEvent
.unsubscribe(this._oOnclickAttributeValue
.fn
,
7001 this._oOnclickAttributeValue
.obj
);
7003 this._oOnclickAttributeValue
= null;
7008 if(!this._oOnclickAttributeValue
&& typeof oObject
== "object" &&
7009 typeof oObject
.fn
== "function") {
7011 this.clickEvent
.subscribe(oObject
.fn
,
7012 ((!YAHOO
.lang
.isUndefined(oObject
.obj
)) ? oObject
.obj
: this),
7015 this._oOnclickAttributeValue
= oObject
;
7023 * @method configClassName
7024 * @description Event handler for when the "classname" configuration
7025 * property of a menu item changes.
7026 * @param {String} p_sType String representing the name of the event that
7028 * @param {Array} p_aArgs Array of arguments sent when the event was fired.
7029 * @param {YAHOO.widget.MenuItem} p_oItem Object representing the menu item
7030 * that fired the event.
7032 configClassName: function(p_sType
, p_aArgs
, p_oItem
) {
7034 var sClassName
= p_aArgs
[0];
7036 if(this._sClassName
) {
7038 Dom
.removeClass(this.element
, this._sClassName
);
7042 Dom
.addClass(this.element
, sClassName
);
7043 this._sClassName
= sClassName
;
7053 * @method initDefaultConfig
7054 * @description Initializes an item's configurable properties.
7056 initDefaultConfig : function() {
7058 var oConfig
= this.cfg
;
7061 // Define the configuration attributes
7065 * @description String specifying the text label for the menu item.
7066 * When building a menu from existing HTML the value of this property
7067 * will be interpreted from the menu's markup.
7071 oConfig
.addProperty(
7072 DEFAULT_CONFIG
.TEXT
.key
,
7074 handler
: this.configText
,
7075 value
: DEFAULT_CONFIG
.TEXT
.value
,
7076 validator
: DEFAULT_CONFIG
.TEXT
.validator
,
7077 suppressEvent
: DEFAULT_CONFIG
.TEXT
.suppressEvent
7084 * @description String specifying additional instructional text to
7085 * accompany the text for the menu item.
7086 * @deprecated Use "text" configuration property to add help text markup.
7087 * For example: <code>oMenuItem.cfg.setProperty("text", "Copy <em
7088 * class=\"helptext\">Ctrl + C</em<");</code>
7090 * @type String|<a href="http://www.w3.org/TR/
7091 * 2000/WD-DOM-Level-1-20000929/level-one-html.html#ID-58190037">
7094 oConfig
.addProperty(
7095 DEFAULT_CONFIG
.HELP_TEXT
.key
,
7096 { handler
: this.configHelpText
}
7102 * @description String specifying the URL for the menu item's anchor's
7103 * "href" attribute. When building a menu from existing HTML the value
7104 * of this property will be interpreted from the menu's markup.
7108 oConfig
.addProperty(
7109 DEFAULT_CONFIG
.URL
.key
,
7111 handler
: this.configURL
,
7112 value
: DEFAULT_CONFIG
.URL
.value
,
7113 suppressEvent
: DEFAULT_CONFIG
.URL
.suppressEvent
7120 * @description String specifying the value for the "target" attribute
7121 * of the menu item's anchor element. <strong>Specifying a target will
7122 * require the user to click directly on the menu item's anchor node in
7123 * order to cause the browser to navigate to the specified URL.</strong>
7124 * When building a menu from existing HTML the value of this property
7125 * will be interpreted from the menu's markup.
7129 oConfig
.addProperty(
7130 DEFAULT_CONFIG
.TARGET
.key
,
7132 handler
: this.configTarget
,
7133 suppressEvent
: DEFAULT_CONFIG
.TARGET
.suppressEvent
7140 * @description Boolean indicating if the text of the menu item will be
7141 * rendered with emphasis.
7142 * @deprecated Use "text" configuration property to add emphasis.
7143 * For example: <code>oMenuItem.cfg.setProperty("text", "<em>Some
7144 * Text</em<");</code>
7148 oConfig
.addProperty(
7149 DEFAULT_CONFIG
.EMPHASIS
.key
,
7151 handler
: this.configEmphasis
,
7152 value
: DEFAULT_CONFIG
.EMPHASIS
.value
,
7153 validator
: DEFAULT_CONFIG
.EMPHASIS
.validator
,
7154 suppressEvent
: DEFAULT_CONFIG
.EMPHASIS
.suppressEvent
7160 * @config strongemphasis
7161 * @description Boolean indicating if the text of the menu item will be
7162 * rendered with strong emphasis.
7163 * @deprecated Use "text" configuration property to add strong emphasis.
7164 * For example: <code>oMenuItem.cfg.setProperty("text", "<strong>
7165 * Some Text</strong<");</code>
7169 oConfig
.addProperty(
7170 DEFAULT_CONFIG
.STRONG_EMPHASIS
.key
,
7172 handler
: this.configStrongEmphasis
,
7173 value
: DEFAULT_CONFIG
.STRONG_EMPHASIS
.value
,
7174 validator
: DEFAULT_CONFIG
.STRONG_EMPHASIS
.validator
,
7175 suppressEvent
: DEFAULT_CONFIG
.STRONG_EMPHASIS
.suppressEvent
7182 * @description Boolean indicating if the menu item should be rendered
7187 oConfig
.addProperty(
7188 DEFAULT_CONFIG
.CHECKED
.key
,
7190 handler
: this.configChecked
,
7191 value
: DEFAULT_CONFIG
.CHECKED
.value
,
7192 validator
: DEFAULT_CONFIG
.CHECKED
.validator
,
7193 suppressEvent
: DEFAULT_CONFIG
.CHECKED
.suppressEvent
,
7194 supercedes
: DEFAULT_CONFIG
.CHECKED
.supercedes
7201 * @description Boolean indicating if the menu item should be disabled.
7202 * (Disabled menu items are dimmed and will not respond to user input
7207 oConfig
.addProperty(
7208 DEFAULT_CONFIG
.DISABLED
.key
,
7210 handler
: this.configDisabled
,
7211 value
: DEFAULT_CONFIG
.DISABLED
.value
,
7212 validator
: DEFAULT_CONFIG
.DISABLED
.validator
,
7213 suppressEvent
: DEFAULT_CONFIG
.DISABLED
.suppressEvent
7220 * @description Boolean indicating if the menu item should
7225 oConfig
.addProperty(
7226 DEFAULT_CONFIG
.SELECTED
.key
,
7228 handler
: this.configSelected
,
7229 value
: DEFAULT_CONFIG
.SELECTED
.value
,
7230 validator
: DEFAULT_CONFIG
.SELECTED
.validator
,
7231 suppressEvent
: DEFAULT_CONFIG
.SELECTED
.suppressEvent
7238 * @description Object specifying the submenu to be appended to the
7239 * menu item. The value can be one of the following: <ul><li>Object
7240 * specifying a Menu instance.</li><li>Object literal specifying the
7241 * menu to be created. Format: <code>{ id: [menu id], itemdata:
7242 * [<a href="YAHOO.widget.Menu.html#itemData">array of values for
7243 * items</a>] }</code>.</li><li>String specifying the id attribute
7244 * of the <code><div></code> element of the menu.</li><li>
7245 * Object specifying the <code><div></code> element of the
7248 * @type Menu|String|Object|<a href="http://www.w3.org/TR/2000/
7249 * WD-DOM-Level-1-20000929/level-one-html.html#ID-58190037">
7252 oConfig
.addProperty(
7253 DEFAULT_CONFIG
.SUBMENU
.key
,
7254 { handler
: this.configSubmenu
}
7260 * @description Object literal representing the code to be executed when
7261 * the item is clicked. Format:<br> <code> {<br>
7262 * <strong>fn:</strong> Function, // The handler to call when
7263 * the event fires.<br> <strong>obj:</strong> Object, // An
7264 * object to pass back to the handler.<br> <strong>scope:</strong>
7265 * Object // The object to use for the scope of the handler.
7270 oConfig
.addProperty(
7271 DEFAULT_CONFIG
.ONCLICK
.key
,
7272 { handler
: this.configOnClick
}
7278 * @description CSS class to be applied to the menu item's root
7279 * <code><li></code> element. The specified class(es) are
7280 * appended in addition to the default class as specified by the menu
7281 * item's CSS_CLASS_NAME constant.
7285 oConfig
.addProperty(
7286 DEFAULT_CONFIG
.CLASS_NAME
.key
,
7288 handler
: this.configClassName
,
7289 value
: DEFAULT_CONFIG
.CLASS_NAME
.value
,
7290 validator
: DEFAULT_CONFIG
.CLASS_NAME
.validator
7298 * @method getNextEnabledSibling
7299 * @description Finds the menu item's next enabled sibling.
7300 * @return YAHOO.widget.MenuItem
7302 getNextEnabledSibling: function() {
7310 function getNextArrayItem(p_aArray
, p_nStartIndex
) {
7312 return p_aArray
[p_nStartIndex
] ||
7313 getNextArrayItem(p_aArray
, (p_nStartIndex
+1));
7317 if(this.parent
instanceof Menu
) {
7319 nGroupIndex
= this.groupIndex
;
7321 aItemGroups
= this.parent
.getItemGroups();
7323 if(this.index
< (aItemGroups
[nGroupIndex
].length
- 1)) {
7325 oNextItem
= getNextArrayItem(aItemGroups
[nGroupIndex
],
7331 if(nGroupIndex
< (aItemGroups
.length
- 1)) {
7333 nNextGroupIndex
= nGroupIndex
+ 1;
7338 nNextGroupIndex
= 0;
7342 aNextGroup
= getNextArrayItem(aItemGroups
, nNextGroupIndex
);
7344 // Retrieve the first menu item in the next group
7346 oNextItem
= getNextArrayItem(aNextGroup
, 0);
7350 return (oNextItem
.cfg
.getProperty("disabled") ||
7351 oNextItem
.element
.style
.display
== "none") ?
7352 oNextItem
.getNextEnabledSibling() : oNextItem
;
7360 * @method getPreviousEnabledSibling
7361 * @description Finds the menu item's previous enabled sibling.
7362 * @return {YAHOO.widget.MenuItem}
7364 getPreviousEnabledSibling: function() {
7369 nPreviousGroupIndex
,
7372 function getPreviousArrayItem(p_aArray
, p_nStartIndex
) {
7374 return p_aArray
[p_nStartIndex
] ||
7375 getPreviousArrayItem(p_aArray
, (p_nStartIndex
-1));
7379 function getFirstItemIndex(p_aArray
, p_nStartIndex
) {
7381 return p_aArray
[p_nStartIndex
] ? p_nStartIndex
:
7382 getFirstItemIndex(p_aArray
, (p_nStartIndex
+1));
7386 if(this.parent
instanceof Menu
) {
7388 nGroupIndex
= this.groupIndex
;
7389 aItemGroups
= this.parent
.getItemGroups();
7392 if(this.index
> getFirstItemIndex(aItemGroups
[nGroupIndex
], 0)) {
7394 oPreviousItem
= getPreviousArrayItem(aItemGroups
[nGroupIndex
],
7400 if(nGroupIndex
> getFirstItemIndex(aItemGroups
, 0)) {
7402 nPreviousGroupIndex
= nGroupIndex
- 1;
7407 nPreviousGroupIndex
= aItemGroups
.length
- 1;
7411 aPreviousGroup
= getPreviousArrayItem(aItemGroups
,
7412 nPreviousGroupIndex
);
7414 oPreviousItem
= getPreviousArrayItem(aPreviousGroup
,
7415 (aPreviousGroup
.length
- 1));
7419 return (oPreviousItem
.cfg
.getProperty("disabled") ||
7420 oPreviousItem
.element
.style
.display
== "none") ?
7421 oPreviousItem
.getPreviousEnabledSibling() : oPreviousItem
;
7430 * @description Causes the menu item to receive the focus and fires the
7435 var oParent
= this.parent
,
7436 oAnchor
= this._oAnchor
,
7437 oActiveItem
= oParent
.activeItem
,
7441 function setFocus() {
7445 if (YAHOO
.env
.ua
.ie
&& !document
.hasFocus()) {
7461 if(!this.cfg
.getProperty("disabled") && oParent
&&
7462 oParent
.cfg
.getProperty("visible") &&
7463 this.element
.style
.display
!= "none") {
7473 Setting focus via a timer fixes a race condition in Firefox, IE
7474 and Opera where the browser viewport jumps as it trys to
7475 position and focus the menu.
7478 window
.setTimeout(setFocus
, 0);
7480 this.focusEvent
.fire();
7489 * @description Causes the menu item to lose focus and fires the
7494 var oParent
= this.parent
;
7496 if(!this.cfg
.getProperty("disabled") && oParent
&&
7497 oParent
.cfg
.getProperty("visible")) {
7499 this._oAnchor
.blur();
7501 this.blurEvent
.fire();
7510 * @description Returns a boolean indicating whether or not the menu item
7514 hasFocus: function() {
7516 return (YAHOO
.widget
.MenuManager
.getFocusedMenuItem() == this);
7523 * @description Removes the menu item's <code><li></code> element
7524 * from its parent <code><ul></code> element.
7526 destroy: function() {
7528 var oEl
= this.element
,
7535 // If the item has a submenu, destroy it first
7537 oSubmenu
= this.cfg
.getProperty("submenu");
7546 // Remove CustomEvent listeners
7548 this.mouseOverEvent
.unsubscribeAll();
7549 this.mouseOutEvent
.unsubscribeAll();
7550 this.mouseDownEvent
.unsubscribeAll();
7551 this.mouseUpEvent
.unsubscribeAll();
7552 this.clickEvent
.unsubscribeAll();
7553 this.keyPressEvent
.unsubscribeAll();
7554 this.keyDownEvent
.unsubscribeAll();
7555 this.keyUpEvent
.unsubscribeAll();
7556 this.focusEvent
.unsubscribeAll();
7557 this.blurEvent
.unsubscribeAll();
7558 this.cfg
.configChangedEvent
.unsubscribeAll();
7561 // Remove the element from the parent node
7563 oParentNode
= oEl
.parentNode
;
7567 oParentNode
.removeChild(oEl
);
7569 this.destroyEvent
.fire();
7573 this.destroyEvent
.unsubscribeAll();
7582 * @description Returns a string representing the menu item.
7585 toString: function() {
7587 var sReturnVal
= "MenuItem",
7592 sReturnVal
+= (" " + sId
);
7602 Lang
.augmentProto(MenuItem
, YAHOO
.util
.EventProvider
);
7609 * Creates a list of options or commands which are made visible in response to
7610 * an HTML element's "contextmenu" event ("mousedown" for Opera).
7612 * @param {String} p_oElement String specifying the id attribute of the
7613 * <code><div></code> element of the context menu.
7614 * @param {String} p_oElement String specifying the id attribute of the
7615 * <code><select></code> element to be used as the data source for the
7617 * @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-one-
7618 * html.html#ID-22445964">HTMLDivElement</a>} p_oElement Object specifying the
7619 * <code><div></code> element of the context menu.
7620 * @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-one-
7621 * html.html#ID-94282980">HTMLSelectElement</a>} p_oElement Object specifying
7622 * the <code><select></code> element to be used as the data source for
7624 * @param {Object} p_oConfig Optional. Object literal specifying the
7625 * configuration for the context menu. See configuration class documentation
7627 * @class ContextMenu
7629 * @extends YAHOO.widget.Menu
7630 * @namespace YAHOO.widget
7632 YAHOO
.widget
.ContextMenu = function(p_oElement
, p_oConfig
) {
7634 YAHOO
.widget
.ContextMenu
.superclass
.constructor.call(this,
7635 p_oElement
, p_oConfig
);
7639 var Event
= YAHOO
.util
.Event
,
7640 ContextMenu
= YAHOO
.widget
.ContextMenu
,
7643 * Constant representing the name of the ContextMenu's events
7644 * @property EVENT_TYPES
7651 "TRIGGER_CONTEXT_MENU": "triggerContextMenu",
7652 "CONTEXT_MENU": (YAHOO
.env
.ua
.opera
? "mousedown" : "contextmenu"),
7659 * Constant representing the ContextMenu's configuration properties
7660 * @property DEFAULT_CONFIG
7674 YAHOO
.lang
.extend(ContextMenu
, YAHOO
.widget
.Menu
, {
7678 // Private properties
7682 * @property _oTrigger
7683 * @description Object reference to the current value of the "trigger"
7684 * configuration property.
7687 * @type String|<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/leve
7688 * l-one-html.html#ID-58190037">HTMLElement</a>|Array
7694 * @property _bCancelled
7695 * @description Boolean indicating if the display of the context menu should
7705 // Public properties
7709 * @property contextEventTarget
7710 * @description Object reference for the HTML element that was the target of the
7711 * "contextmenu" DOM event ("mousedown" for Opera) that triggered the display of
7714 * @type <a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-one-
7715 * html.html#ID-58190037">HTMLElement</a>
7717 contextEventTarget
: null,
7725 * @event triggerContextMenuEvent
7726 * @description Custom Event wrapper for the "contextmenu" DOM event
7727 * ("mousedown" for Opera) fired by the element(s) that trigger the display of
7730 triggerContextMenuEvent
: null,
7736 * @description The ContextMenu class's initialization method. This method is
7737 * automatically called by the constructor, and sets up all DOM references for
7738 * pre-existing markup, and creates required markup if it is not already present.
7739 * @param {String} p_oElement String specifying the id attribute of the
7740 * <code><div></code> element of the context menu.
7741 * @param {String} p_oElement String specifying the id attribute of the
7742 * <code><select></code> element to be used as the data source for
7744 * @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-one-
7745 * html.html#ID-22445964">HTMLDivElement</a>} p_oElement Object specifying the
7746 * <code><div></code> element of the context menu.
7747 * @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-one-
7748 * html.html#ID-94282980">HTMLSelectElement</a>} p_oElement Object specifying
7749 * the <code><select></code> element to be used as the data source for
7751 * @param {Object} p_oConfig Optional. Object literal specifying the
7752 * configuration for the context menu. See configuration class documentation
7755 init: function(p_oElement
, p_oConfig
) {
7757 if(!this.ITEM_TYPE
) {
7759 this.ITEM_TYPE
= YAHOO
.widget
.ContextMenuItem
;
7764 // Call the init of the superclass (YAHOO.widget.Menu)
7766 ContextMenu
.superclass
.init
.call(this, p_oElement
);
7769 this.beforeInitEvent
.fire(ContextMenu
);
7774 this.cfg
.applyConfig(p_oConfig
, true);
7779 this.initEvent
.fire(ContextMenu
);
7785 * @method initEvents
7786 * @description Initializes the custom events for the context menu.
7788 initEvents: function() {
7790 ContextMenu
.superclass
.initEvents
.call(this);
7792 // Create custom events
7794 this.triggerContextMenuEvent
=
7795 this.createEvent(EVENT_TYPES
.TRIGGER_CONTEXT_MENU
);
7797 this.triggerContextMenuEvent
.signature
= YAHOO
.util
.CustomEvent
.LIST
;
7804 * @description Cancels the display of the context menu.
7806 cancel: function() {
7808 this._bCancelled
= true;
7818 * @method _removeEventHandlers
7819 * @description Removes all of the DOM event handlers from the HTML element(s)
7820 * whose "context menu" event ("click" for Opera) trigger the display of
7824 _removeEventHandlers: function() {
7826 var oTrigger
= this._oTrigger
;
7829 // Remove the event handlers from the trigger(s)
7833 Event
.removeListener(oTrigger
, EVENT_TYPES
.CONTEXT_MENU
,
7834 this._onTriggerContextMenu
);
7836 if(YAHOO
.env
.ua
.opera
) {
7838 Event
.removeListener(oTrigger
, EVENT_TYPES
.CLICK
,
7839 this._onTriggerClick
);
7849 // Private event handlers
7853 * @method _onTriggerClick
7854 * @description "click" event handler for the HTML element(s) identified as the
7855 * "trigger" for the context menu. Used to cancel default behaviors in Opera.
7857 * @param {Event} p_oEvent Object representing the DOM event object passed back
7858 * by the event utility (YAHOO.util.Event).
7859 * @param {YAHOO.widget.ContextMenu} p_oMenu Object representing the context
7860 * menu that is handling the event.
7862 _onTriggerClick: function(p_oEvent
, p_oMenu
) {
7864 if(p_oEvent
.ctrlKey
) {
7866 Event
.stopEvent(p_oEvent
);
7874 * @method _onTriggerContextMenu
7875 * @description "contextmenu" event handler ("mousedown" for Opera) for the HTML
7876 * element(s) that trigger the display of the context menu.
7878 * @param {Event} p_oEvent Object representing the DOM event object passed back
7879 * by the event utility (YAHOO.util.Event).
7880 * @param {YAHOO.widget.ContextMenu} p_oMenu Object representing the context
7881 * menu that is handling the event.
7883 _onTriggerContextMenu: function(p_oEvent
, p_oMenu
) {
7885 if(p_oEvent
.type
== "mousedown" && !p_oEvent
.ctrlKey
) {
7893 Prevent the browser's default context menu from appearing and
7894 stop the propagation of the "contextmenu" event so that
7895 other ContextMenu instances are not displayed.
7898 Event
.stopEvent(p_oEvent
);
7901 // Hide any other ContextMenu instances that might be visible
7903 YAHOO
.widget
.MenuManager
.hideVisible();
7906 this.contextEventTarget
= Event
.getTarget(p_oEvent
);
7908 this.triggerContextMenuEvent
.fire(p_oEvent
);
7911 if(!this._bCancelled
) {
7913 // Position and display the context menu
7915 this.cfg
.setProperty("xy", Event
.getXY(p_oEvent
));
7921 this._bCancelled
= false;
7932 * @description Returns a string representing the context menu.
7935 toString: function() {
7937 var sReturnVal
= "ContextMenu",
7942 sReturnVal
+= (" " + sId
);
7952 * @method initDefaultConfig
7953 * @description Initializes the class's configurable properties which can be
7954 * changed using the context menu's Config object ("cfg").
7956 initDefaultConfig: function() {
7958 ContextMenu
.superclass
.initDefaultConfig
.call(this);
7962 * @description The HTML element(s) whose "contextmenu" event ("mousedown"
7963 * for Opera) trigger the display of the context menu. Can be a string
7964 * representing the id attribute of the HTML element, an object reference
7965 * for the HTML element, or an array of strings or HTML element references.
7967 * @type String|<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/
7968 * level-one-html.html#ID-58190037">HTMLElement</a>|Array
7970 this.cfg
.addProperty(DEFAULT_CONFIG
.TRIGGER
.key
,
7971 { handler
: this.configTrigger
});
7978 * @description Removes the context menu's <code><div></code> element
7979 * (and accompanying child nodes) from the document.
7981 destroy: function() {
7983 // Remove the DOM event handlers from the current trigger(s)
7985 this._removeEventHandlers();
7988 // Continue with the superclass implementation of this method
7990 ContextMenu
.superclass
.destroy
.call(this);
7996 // Public event handlers for configuration properties
8000 * @method configTrigger
8001 * @description Event handler for when the value of the "trigger" configuration
8003 * @param {String} p_sType String representing the name of the event that
8005 * @param {Array} p_aArgs Array of arguments sent when the event was fired.
8006 * @param {YAHOO.widget.ContextMenu} p_oMenu Object representing the context
8007 * menu that fired the event.
8009 configTrigger: function(p_sType
, p_aArgs
, p_oMenu
) {
8011 var oTrigger
= p_aArgs
[0];
8016 If there is a current "trigger" - remove the event handlers
8017 from that element(s) before assigning new ones
8020 if(this._oTrigger
) {
8022 this._removeEventHandlers();
8026 this._oTrigger
= oTrigger
;
8030 Listen for the "mousedown" event in Opera b/c it does not
8031 support the "contextmenu" event
8034 Event
.on(oTrigger
, EVENT_TYPES
.CONTEXT_MENU
,
8035 this._onTriggerContextMenu
, this, true);
8039 Assign a "click" event handler to the trigger element(s) for
8040 Opera to prevent default browser behaviors.
8043 if(YAHOO
.env
.ua
.opera
) {
8045 Event
.on(oTrigger
, EVENT_TYPES
.CLICK
, this._onTriggerClick
,
8053 this._removeEventHandlers();
8059 }); // END YAHOO.lang.extend
8066 * Creates an item for a context menu.
8068 * @param {String} p_oObject String specifying the text of the context menu item.
8069 * @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-
8070 * one-html.html#ID-74680021">HTMLLIElement</a>} p_oObject Object specifying the
8071 * <code><li></code> element of the context menu item.
8072 * @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-
8073 * one-html.html#ID-38450247">HTMLOptGroupElement</a>} p_oObject Object
8074 * specifying the <code><optgroup></code> element of the context
8076 * @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-
8077 * one-html.html#ID-70901257">HTMLOptionElement</a>} p_oObject Object specifying
8078 * the <code><option></code> element of the context menu item.
8079 * @param {Object} p_oConfig Optional. Object literal specifying the
8080 * configuration for the context menu item. See configuration class
8081 * documentation for more details.
8082 * @class ContextMenuItem
8084 * @extends YAHOO.widget.MenuItem
8086 YAHOO
.widget
.ContextMenuItem = function(p_oObject
, p_oConfig
) {
8088 YAHOO
.widget
.ContextMenuItem
.superclass
.constructor.call(this,
8089 p_oObject
, p_oConfig
);
8093 YAHOO
.lang
.extend(YAHOO
.widget
.ContextMenuItem
, YAHOO
.widget
.MenuItem
, {
8098 * @description The ContextMenuItem class's initialization method. This method
8099 * is automatically called by the constructor, and sets up all DOM references
8100 * for pre-existing markup, and creates required markup if it is not
8102 * @param {String} p_oObject String specifying the text of the context menu item.
8103 * @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-
8104 * one-html.html#ID-74680021">HTMLLIElement</a>} p_oObject Object specifying the
8105 * <code><li></code> element of the context menu item.
8106 * @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-
8107 * one-html.html#ID-38450247">HTMLOptGroupElement</a>} p_oObject Object
8108 * specifying the <code><optgroup></code> element of the context
8110 * @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-
8111 * one-html.html#ID-70901257">HTMLOptionElement</a>} p_oObject Object specifying
8112 * the <code><option></code> element of the context menu item.
8113 * @param {Object} p_oConfig Optional. Object literal specifying the
8114 * configuration for the context menu item. See configuration class
8115 * documentation for more details.
8117 init: function(p_oObject
, p_oConfig
) {
8119 if(!this.SUBMENU_TYPE
) {
8121 this.SUBMENU_TYPE
= YAHOO
.widget
.ContextMenu
;
8127 Call the init of the superclass (YAHOO.widget.MenuItem)
8128 Note: We don't pass the user config in here yet
8129 because we only want it executed once, at the lowest
8133 YAHOO
.widget
.ContextMenuItem
.superclass
.init
.call(this, p_oObject
);
8135 var oConfig
= this.cfg
;
8139 oConfig
.applyConfig(p_oConfig
, true);
8143 oConfig
.fireQueue();
8154 * @description Returns a string representing the context menu item.
8157 toString: function() {
8159 var sReturnVal
= "ContextMenuItem";
8161 if(this.cfg
&& this.cfg
.getProperty("text")) {
8163 sReturnVal
+= (": " + this.cfg
.getProperty("text"));
8171 }); // END YAHOO.lang.extend
8176 * Horizontal collection of items, each of which can contain a submenu.
8178 * @param {String} p_oElement String specifying the id attribute of the
8179 * <code><div></code> element of the menu bar.
8180 * @param {String} p_oElement String specifying the id attribute of the
8181 * <code><select></code> element to be used as the data source for the
8183 * @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-
8184 * one-html.html#ID-22445964">HTMLDivElement</a>} p_oElement Object specifying
8185 * the <code><div></code> element of the menu bar.
8186 * @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-
8187 * one-html.html#ID-94282980">HTMLSelectElement</a>} p_oElement Object
8188 * specifying the <code><select></code> element to be used as the data
8189 * source for the menu bar.
8190 * @param {Object} p_oConfig Optional. Object literal specifying the
8191 * configuration for the menu bar. See configuration class documentation for
8195 * @extends YAHOO.widget.Menu
8196 * @namespace YAHOO.widget
8198 YAHOO
.widget
.MenuBar = function(p_oElement
, p_oConfig
) {
8200 YAHOO
.widget
.MenuBar
.superclass
.constructor.call(this,
8201 p_oElement
, p_oConfig
);
8207 * @method checkPosition
8208 * @description Checks to make sure that the value of the "position" property
8209 * is one of the supported strings. Returns true if the position is supported.
8211 * @param {Object} p_sPosition String specifying the position of the menu.
8214 function checkPosition(p_sPosition
) {
8216 if (typeof p_sPosition
== "string") {
8218 return ("dynamic,static".indexOf((p_sPosition
.toLowerCase())) != -1);
8225 var Event
= YAHOO
.util
.Event
,
8226 Dom
= YAHOO
.util
.Dom
,
8227 MenuBar
= YAHOO
.widget
.MenuBar
,
8230 * Constant representing the MenuBar's configuration properties
8231 * @property DEFAULT_CONFIG
8241 validator
: checkPosition
,
8242 supercedes
: ["visible"]
8245 "SUBMENU_ALIGNMENT": {
8246 key
: "submenualignment",
8250 "AUTO_SUBMENU_DISPLAY": {
8251 key
: "autosubmenudisplay",
8253 validator
: YAHOO
.lang
.isBoolean
8260 YAHOO
.lang
.extend(MenuBar
, YAHOO
.widget
.Menu
, {
8264 * @description The MenuBar class's initialization method. This method is
8265 * automatically called by the constructor, and sets up all DOM references for
8266 * pre-existing markup, and creates required markup if it is not already present.
8267 * @param {String} p_oElement String specifying the id attribute of the
8268 * <code><div></code> element of the menu bar.
8269 * @param {String} p_oElement String specifying the id attribute of the
8270 * <code><select></code> element to be used as the data source for the
8272 * @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-
8273 * one-html.html#ID-22445964">HTMLDivElement</a>} p_oElement Object specifying
8274 * the <code><div></code> element of the menu bar.
8275 * @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-
8276 * one-html.html#ID-94282980">HTMLSelectElement</a>} p_oElement Object
8277 * specifying the <code><select></code> element to be used as the data
8278 * source for the menu bar.
8279 * @param {Object} p_oConfig Optional. Object literal specifying the
8280 * configuration for the menu bar. See configuration class documentation for
8283 init: function(p_oElement
, p_oConfig
) {
8285 if(!this.ITEM_TYPE
) {
8287 this.ITEM_TYPE
= YAHOO
.widget
.MenuBarItem
;
8292 // Call the init of the superclass (YAHOO.widget.Menu)
8294 MenuBar
.superclass
.init
.call(this, p_oElement
);
8297 this.beforeInitEvent
.fire(MenuBar
);
8302 this.cfg
.applyConfig(p_oConfig
, true);
8306 this.initEvent
.fire(MenuBar
);
8316 * @property CSS_CLASS_NAME
8317 * @description String representing the CSS class(es) to be applied to the menu
8318 * bar's <code><div></code> element.
8319 * @default "yuimenubar"
8323 CSS_CLASS_NAME
: "yuimenubar",
8327 // Protected event handlers
8331 * @method _onKeyDown
8332 * @description "keydown" Custom Event handler for the menu bar.
8334 * @param {String} p_sType String representing the name of the event that
8336 * @param {Array} p_aArgs Array of arguments sent when the event was fired.
8337 * @param {YAHOO.widget.MenuBar} p_oMenuBar Object representing the menu bar
8338 * that fired the event.
8340 _onKeyDown: function(p_sType
, p_aArgs
, p_oMenuBar
) {
8342 var oEvent
= p_aArgs
[0],
8349 if(oItem
&& !oItem
.cfg
.getProperty("disabled")) {
8351 oItemCfg
= oItem
.cfg
;
8353 switch(oEvent
.keyCode
) {
8355 case 37: // Left arrow
8356 case 39: // Right arrow
8358 if(oItem
== this.activeItem
&&
8359 !oItemCfg
.getProperty("selected")) {
8361 oItemCfg
.setProperty("selected", true);
8366 oNextItem
= (oEvent
.keyCode
== 37) ?
8367 oItem
.getPreviousEnabledSibling() :
8368 oItem
.getNextEnabledSibling();
8372 this.clearActiveItem();
8374 oNextItem
.cfg
.setProperty("selected", true);
8377 if(this.cfg
.getProperty("autosubmenudisplay")) {
8379 oSubmenu
= oNextItem
.cfg
.getProperty("submenu");
8395 Event
.preventDefault(oEvent
);
8399 case 40: // Down arrow
8401 if(this.activeItem
!= oItem
) {
8403 this.clearActiveItem();
8405 oItemCfg
.setProperty("selected", true);
8410 oSubmenu
= oItemCfg
.getProperty("submenu");
8414 if(oSubmenu
.cfg
.getProperty("visible")) {
8416 oSubmenu
.setInitialSelection();
8417 oSubmenu
.setInitialFocus();
8428 Event
.preventDefault(oEvent
);
8437 if(oEvent
.keyCode
== 27 && this.activeItem
) { // Esc key
8439 oSubmenu
= this.activeItem
.cfg
.getProperty("submenu");
8441 if(oSubmenu
&& oSubmenu
.cfg
.getProperty("visible")) {
8444 this.activeItem
.focus();
8449 this.activeItem
.cfg
.setProperty("selected", false);
8450 this.activeItem
.blur();
8454 Event
.preventDefault(oEvent
);
8463 * @description "click" event handler for the menu bar.
8465 * @param {String} p_sType String representing the name of the event that
8467 * @param {Array} p_aArgs Array of arguments sent when the event was fired.
8468 * @param {YAHOO.widget.MenuBar} p_oMenuBar Object representing the menu bar
8469 * that fired the event.
8471 _onClick: function(p_sType
, p_aArgs
, p_oMenuBar
) {
8473 MenuBar
.superclass
._onClick
.call(this, p_sType
, p_aArgs
, p_oMenuBar
);
8475 var oItem
= p_aArgs
[1],
8483 if(oItem
&& !oItem
.cfg
.getProperty("disabled")) {
8485 oEvent
= p_aArgs
[0];
8486 oTarget
= Event
.getTarget(oEvent
);
8487 oActiveItem
= this.activeItem
;
8491 // Hide any other submenus that might be visible
8493 if(oActiveItem
&& oActiveItem
!= oItem
) {
8495 this.clearActiveItem();
8500 oItem
.cfg
.setProperty("selected", true);
8503 // Show the submenu for the item
8505 oSubmenu
= oItem
.cfg
.getProperty("submenu");
8508 if(oSubmenu
&& oTarget
!= oItem
.submenuIndicator
) {
8510 if(oSubmenu
.cfg
.getProperty("visible")) {
8534 * @description Returns a string representing the menu bar.
8537 toString: function() {
8539 var sReturnVal
= "MenuBar",
8544 sReturnVal
+= (" " + sId
);
8554 * @description Initializes the class's configurable properties which can be
8555 * changed using the menu bar's Config object ("cfg").
8556 * @method initDefaultConfig
8558 initDefaultConfig: function() {
8560 MenuBar
.superclass
.initDefaultConfig
.call(this);
8562 var oConfig
= this.cfg
;
8564 // Add configuration properties
8568 Set the default value for the "position" configuration property
8569 to "static" by re-adding the property.
8575 * @description String indicating how a menu bar should be positioned on the
8576 * screen. Possible values are "static" and "dynamic." Static menu bars
8577 * are visible by default and reside in the normal flow of the document
8578 * (CSS position: static). Dynamic menu bars are hidden by default, reside
8579 * out of the normal flow of the document (CSS position: absolute), and can
8580 * overlay other elements on the screen.
8584 oConfig
.addProperty(
8585 DEFAULT_CONFIG
.POSITION
.key
,
8587 handler
: this.configPosition
,
8588 value
: DEFAULT_CONFIG
.POSITION
.value
,
8589 validator
: DEFAULT_CONFIG
.POSITION
.validator
,
8590 supercedes
: DEFAULT_CONFIG
.POSITION
.supercedes
8596 Set the default value for the "submenualignment" configuration property
8597 to ["tl","bl"] by re-adding the property.
8601 * @config submenualignment
8602 * @description Array defining how submenus should be aligned to their
8603 * parent menu bar item. The format is: [itemCorner, submenuCorner].
8604 * @default ["tl","bl"]
8607 oConfig
.addProperty(
8608 DEFAULT_CONFIG
.SUBMENU_ALIGNMENT
.key
,
8610 value
: DEFAULT_CONFIG
.SUBMENU_ALIGNMENT
.value
8616 Change the default value for the "autosubmenudisplay" configuration
8617 property to "false" by re-adding the property.
8621 * @config autosubmenudisplay
8622 * @description Boolean indicating if submenus are automatically made
8623 * visible when the user mouses over the menu bar's items.
8627 oConfig
.addProperty(
8628 DEFAULT_CONFIG
.AUTO_SUBMENU_DISPLAY
.key
,
8630 value
: DEFAULT_CONFIG
.AUTO_SUBMENU_DISPLAY
.value
,
8631 validator
: DEFAULT_CONFIG
.AUTO_SUBMENU_DISPLAY
.validator
8637 }); // END YAHOO.lang.extend
8644 * Creates an item for a menu bar.
8646 * @param {String} p_oObject String specifying the text of the menu bar item.
8647 * @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-
8648 * one-html.html#ID-74680021">HTMLLIElement</a>} p_oObject Object specifying the
8649 * <code><li></code> element of the menu bar item.
8650 * @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-
8651 * one-html.html#ID-38450247">HTMLOptGroupElement</a>} p_oObject Object
8652 * specifying the <code><optgroup></code> element of the menu bar item.
8653 * @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-
8654 * one-html.html#ID-70901257">HTMLOptionElement</a>} p_oObject Object specifying
8655 * the <code><option></code> element of the menu bar item.
8656 * @param {Object} p_oConfig Optional. Object literal specifying the
8657 * configuration for the menu bar item. See configuration class documentation
8659 * @class MenuBarItem
8661 * @extends YAHOO.widget.MenuItem
8663 YAHOO
.widget
.MenuBarItem = function(p_oObject
, p_oConfig
) {
8665 YAHOO
.widget
.MenuBarItem
.superclass
.constructor.call(this,
8666 p_oObject
, p_oConfig
);
8670 YAHOO
.lang
.extend(YAHOO
.widget
.MenuBarItem
, YAHOO
.widget
.MenuItem
, {
8676 * @description The MenuBarItem class's initialization method. This method is
8677 * automatically called by the constructor, and sets up all DOM references for
8678 * pre-existing markup, and creates required markup if it is not already present.
8679 * @param {String} p_oObject String specifying the text of the menu bar item.
8680 * @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-
8681 * one-html.html#ID-74680021">HTMLLIElement</a>} p_oObject Object specifying the
8682 * <code><li></code> element of the menu bar item.
8683 * @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-
8684 * one-html.html#ID-38450247">HTMLOptGroupElement</a>} p_oObject Object
8685 * specifying the <code><optgroup></code> element of the menu bar item.
8686 * @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-
8687 * one-html.html#ID-70901257">HTMLOptionElement</a>} p_oObject Object specifying
8688 * the <code><option></code> element of the menu bar item.
8689 * @param {Object} p_oConfig Optional. Object literal specifying the
8690 * configuration for the menu bar item. See configuration class documentation
8693 init: function(p_oObject
, p_oConfig
) {
8695 if(!this.SUBMENU_TYPE
) {
8697 this.SUBMENU_TYPE
= YAHOO
.widget
.Menu
;
8703 Call the init of the superclass (YAHOO.widget.MenuItem)
8704 Note: We don't pass the user config in here yet
8705 because we only want it executed once, at the lowest
8709 YAHOO
.widget
.MenuBarItem
.superclass
.init
.call(this, p_oObject
);
8712 var oConfig
= this.cfg
;
8716 oConfig
.applyConfig(p_oConfig
, true);
8720 oConfig
.fireQueue();
8730 * @property CSS_CLASS_NAME
8731 * @description String representing the CSS class(es) to be applied to the
8732 * <code><li></code> element of the menu bar item.
8733 * @default "yuimenubaritem"
8737 CSS_CLASS_NAME
: "yuimenubaritem",
8741 * @property CSS_LABEL_CLASS_NAME
8742 * @description String representing the CSS class(es) to be applied to the
8743 * menu bar item's <code><a></code> element.
8744 * @default "yuimenubaritemlabel"
8748 CSS_LABEL_CLASS_NAME
: "yuimenubaritemlabel",
8757 * @description Returns a string representing the menu bar item.
8760 toString: function() {
8762 var sReturnVal
= "MenuBarItem";
8764 if(this.cfg
&& this.cfg
.getProperty("text")) {
8766 sReturnVal
+= (": " + this.cfg
.getProperty("text"));
8774 }); // END YAHOO.lang.extend
8775 YAHOO
.register("menu", YAHOO
.widget
.Menu
, {version
: "2.3.0", build
: "442"});