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;
87 var m_oLogger
= new YAHOO
.widget
.LogWriter("MenuManager");
95 * @method getMenuRootElement
96 * @description Finds the root DIV node of a menu or the root LI node of
99 * @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/
100 * level-one-html.html#ID-58190037">HTMLElement</a>} p_oElement Object
101 * specifying an HTML element.
103 function getMenuRootElement(p_oElement
) {
107 if (p_oElement
&& p_oElement
.tagName
) {
109 switch (p_oElement
.tagName
.toUpperCase()) {
113 oParentNode
= p_oElement
.parentNode
;
115 // Check if the DIV is the inner "body" node of a menu
119 Dom
.hasClass(p_oElement
, "hd") ||
120 Dom
.hasClass(p_oElement
, "bd") ||
121 Dom
.hasClass(p_oElement
, "ft")
124 oParentNode
.tagName
&&
125 oParentNode
.tagName
.toUpperCase() == "DIV")
145 oParentNode
= p_oElement
.parentNode
;
149 return getMenuRootElement(oParentNode
);
163 // Private event handlers
168 * @description Generic, global event handler for all of a menu's
169 * DOM-based events. This listens for events against the document
170 * object. If the target of a given event is a member of a menu or
171 * menu item's DOM, the instance's corresponding Custom Event is fired.
173 * @param {Event} p_oEvent Object representing the DOM event object
174 * passed back by the event utility (YAHOO.util.Event).
176 function onDOMEvent(p_oEvent
) {
178 // Get the target node of the DOM event
180 var oTarget
= Event
.getTarget(p_oEvent
),
182 // See if the target of the event was a menu, or a menu item
184 oElement
= getMenuRootElement(oTarget
),
194 sTagName
= oElement
.tagName
.toUpperCase();
196 if (sTagName
== "LI") {
200 if (sId
&& m_oItems
[sId
]) {
202 oMenuItem
= m_oItems
[sId
];
203 oMenu
= oMenuItem
.parent
;
208 else if (sTagName
== "DIV") {
212 oMenu
= m_oMenus
[oElement
.id
];
223 sCustomEventType
= m_oEventTypes
[p_oEvent
.type
];
226 // Fire the Custom Event that corresponds the current DOM event
228 if (oMenuItem
&& !oMenuItem
.cfg
.getProperty("disabled")) {
230 oMenuItem
[sCustomEventType
].fire(p_oEvent
);
234 p_oEvent
.type
== "keyup" ||
235 p_oEvent
.type
== "mousedown")
238 if (m_oFocusedMenuItem
!= oMenuItem
) {
240 if (m_oFocusedMenuItem
) {
242 m_oFocusedMenuItem
.blurEvent
.fire();
246 oMenuItem
.focusEvent
.fire();
254 oMenu
[sCustomEventType
].fire(p_oEvent
, oMenuItem
);
257 else if (p_oEvent
.type
== "mousedown") {
259 if (m_oFocusedMenuItem
) {
261 m_oFocusedMenuItem
.blurEvent
.fire();
263 m_oFocusedMenuItem
= null;
269 If the target of the event wasn't a menu, hide all
270 dynamically positioned menus
273 for (var i
in m_oMenus
) {
275 if (YAHOO
.lang
.hasOwnProperty(m_oMenus
,i
)) {
279 if (oMenu
.cfg
.getProperty("clicktohide") &&
280 !(oMenu
instanceof YAHOO
.widget
.MenuBar
) &&
281 oMenu
.cfg
.getProperty("position") == "dynamic") {
288 oMenu
.clearActiveItem(true);
297 else if (p_oEvent
.type
== "keyup") {
299 if (m_oFocusedMenuItem
) {
301 m_oFocusedMenuItem
.blurEvent
.fire();
303 m_oFocusedMenuItem
= null;
313 * @method onMenuDestroy
314 * @description "destroy" event handler for a menu.
316 * @param {String} p_sType String representing the name of the event
318 * @param {Array} p_aArgs Array of arguments sent when the event
320 * @param {YAHOO.widget.Menu} p_oMenu The menu that fired the event.
322 function onMenuDestroy(p_sType
, p_aArgs
, p_oMenu
) {
324 if (m_oMenus
[p_oMenu
.id
]) {
326 this.removeMenu(p_oMenu
);
334 * @method onMenuFocus
335 * @description "focus" event handler for a MenuItem instance.
337 * @param {String} p_sType String representing the name of the event
339 * @param {Array} p_aArgs Array of arguments sent when the event
342 function onMenuFocus(p_sType
, p_aArgs
) {
344 var oItem
= p_aArgs
[0];
348 m_oFocusedMenuItem
= oItem
;
357 * @description "blur" event handler for a MenuItem instance.
359 * @param {String} p_sType String representing the name of the event
361 * @param {Array} p_aArgs Array of arguments sent when the event
364 function onMenuBlur(p_sType
, p_aArgs
) {
366 m_oFocusedMenuItem
= null;
373 * @method onMenuVisibleConfigChange
374 * @description Event handler for when the "visible" configuration
375 * property of a Menu instance changes.
377 * @param {String} p_sType String representing the name of the event
379 * @param {Array} p_aArgs Array of arguments sent when the event
382 function onMenuVisibleConfigChange(p_sType
, p_aArgs
) {
384 var bVisible
= p_aArgs
[0],
389 m_oVisibleMenus
[sId
] = this;
393 " added to the collection of visible menus.");
396 else if (m_oVisibleMenus
[sId
]) {
398 delete m_oVisibleMenus
[sId
];
402 " removed from the collection of visible menus.");
410 * @method onItemDestroy
411 * @description "destroy" event handler for a MenuItem instance.
413 * @param {String} p_sType String representing the name of the event
415 * @param {Array} p_aArgs Array of arguments sent when the event
418 function onItemDestroy(p_sType
, p_aArgs
) {
422 if (sId
&& m_oItems
[sId
]) {
424 if (m_oFocusedMenuItem
== this) {
426 m_oFocusedMenuItem
= null;
430 delete m_oItems
[sId
];
432 m_oLogger
.log(this + " successfully unregistered.");
440 * @method onItemAdded
441 * @description "itemadded" event handler for a Menu instance.
443 * @param {String} p_sType String representing the name of the event
445 * @param {Array} p_aArgs Array of arguments sent when the event
448 function onItemAdded(p_sType
, p_aArgs
) {
450 var oItem
= p_aArgs
[0],
453 if (oItem
instanceof YAHOO
.widget
.MenuItem
) {
457 if (!m_oItems
[sId
]) {
459 m_oItems
[sId
] = oItem
;
461 oItem
.destroyEvent
.subscribe(onItemDestroy
);
463 m_oLogger
.log(oItem
+ " successfully registered.");
474 // Privileged methods
479 * @description Adds a menu to the collection of known menus.
480 * @param {YAHOO.widget.Menu} p_oMenu Object specifying the Menu
481 * instance to be added.
483 addMenu: function (p_oMenu
) {
488 p_oMenu
instanceof YAHOO
.widget
.Menu
&&
490 !m_oMenus
[p_oMenu
.id
]
493 m_oMenus
[p_oMenu
.id
] = p_oMenu
;
496 if (!m_bInitializedEventHandlers
) {
500 Event
.on(oDoc
, "mouseover", onDOMEvent
, this, true);
501 Event
.on(oDoc
, "mouseout", onDOMEvent
, this, true);
502 Event
.on(oDoc
, "mousedown", onDOMEvent
, this, true);
503 Event
.on(oDoc
, "mouseup", onDOMEvent
, this, true);
504 Event
.on(oDoc
, "click", onDOMEvent
, this, true);
505 Event
.on(oDoc
, "keydown", onDOMEvent
, this, true);
506 Event
.on(oDoc
, "keyup", onDOMEvent
, this, true);
507 Event
.on(oDoc
, "keypress", onDOMEvent
, this, true);
510 m_bInitializedEventHandlers
= true;
512 m_oLogger
.log("DOM event handlers initialized.");
516 p_oMenu
.destroyEvent
.subscribe(
521 p_oMenu
.cfg
.subscribeToConfigEvent(
523 onMenuVisibleConfigChange
);
525 p_oMenu
.itemAddedEvent
.subscribe(onItemAdded
);
526 p_oMenu
.focusEvent
.subscribe(onMenuFocus
);
527 p_oMenu
.blurEvent
.subscribe(onMenuBlur
);
529 m_oLogger
.log(p_oMenu
+ " successfully registered.");
538 * @description Removes a menu from the collection of known menus.
539 * @param {YAHOO.widget.Menu} p_oMenu Object specifying the Menu
540 * instance to be removed.
542 removeMenu: function (p_oMenu
) {
550 if (m_oMenus
[sId
] == p_oMenu
) {
552 delete m_oMenus
[sId
];
554 m_oLogger
.log(p_oMenu
+ " successfully unregistered.");
557 if (m_oVisibleMenus
[sId
] == p_oMenu
) {
559 delete m_oVisibleMenus
[sId
];
563 " unregistered from the" +
564 " collection of visible menus.");
576 * @method hideVisible
577 * @description Hides all visible, dynamically positioned menus
578 * (excluding instances of YAHOO.widget.MenuBar).
580 hideVisible: function () {
584 for (var i
in m_oVisibleMenus
) {
586 if (YAHOO
.lang
.hasOwnProperty(m_oVisibleMenus
,i
)) {
588 oMenu
= m_oVisibleMenus
[i
];
590 if (!(oMenu
instanceof YAHOO
.widget
.MenuBar
) &&
591 oMenu
.cfg
.getProperty("position") == "dynamic") {
606 * @description Returns an array of all menus registered with the
610 getMenus: function () {
619 * @description Returns a menu with the specified id.
620 * @param {String} p_sId String specifying the id of the
621 * <code><div></code> element representing the menu to
623 * @return {YAHOO.widget.Menu}
625 getMenu: function (p_sId
) {
627 var oMenu
= m_oMenus
[p_sId
];
639 * @method getMenuItem
640 * @description Returns a menu item with the specified id.
641 * @param {String} p_sId String specifying the id of the
642 * <code><li></code> element representing the menu item to
644 * @return {YAHOO.widget.MenuItem}
646 getMenuItem: function (p_sId
) {
648 var oItem
= m_oItems
[p_sId
];
660 * @method getMenuItemGroup
661 * @description Returns an array of menu item instances whose
662 * corresponding <code><li></code> elements are child
663 * nodes of the <code><ul></code> element with the
665 * @param {String} p_sId String specifying the id of the
666 * <code><ul></code> element representing the group of
667 * menu items to be retrieved.
670 getMenuItemGroup: function (p_sId
) {
672 var oUL
= Dom
.get(p_sId
),
679 if (oUL
&& oUL
.tagName
&&
680 oUL
.tagName
.toUpperCase() == "UL") {
682 oNode
= oUL
.firstChild
;
694 oItem
= this.getMenuItem(sId
);
698 aItems
[aItems
.length
] = oItem
;
705 while ((oNode
= oNode
.nextSibling
));
708 if (aItems
.length
> 0) {
722 * @method getFocusedMenuItem
723 * @description Returns a reference to the menu item that currently
725 * @return {YAHOO.widget.MenuItem}
727 getFocusedMenuItem: function () {
729 return m_oFocusedMenuItem
;
735 * @method getFocusedMenu
736 * @description Returns a reference to the menu that currently
738 * @return {YAHOO.widget.Menu}
740 getFocusedMenu: function () {
742 if (m_oFocusedMenuItem
) {
744 return (m_oFocusedMenuItem
.parent
.getRoot());
753 * @description Returns a string representing the menu manager.
756 toString: function () {
758 return "MenuManager";
774 * The Menu class creates a container that holds a vertical list representing
775 * a set of options or commands. Menu is the base class for all
777 * @param {String} p_oElement String specifying the id attribute of the
778 * <code><div></code> element of the menu.
779 * @param {String} p_oElement String specifying the id attribute of the
780 * <code><select></code> element to be used as the data source
782 * @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/
783 * level-one-html.html#ID-22445964">HTMLDivElement</a>} p_oElement Object
784 * specifying the <code><div></code> element of the menu.
785 * @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/
786 * level-one-html.html#ID-94282980">HTMLSelectElement</a>} p_oElement
787 * Object specifying the <code><select></code> element to be used as
788 * the data source for the menu.
789 * @param {Object} p_oConfig Optional. Object literal specifying the
790 * configuration for the menu. See configuration class documentation for
792 * @namespace YAHOO.widget
795 * @extends YAHOO.widget.Overlay
797 YAHOO
.widget
.Menu = function (p_oElement
, p_oConfig
) {
801 this.parent
= p_oConfig
.parent
;
802 this.lazyLoad
= p_oConfig
.lazyLoad
|| p_oConfig
.lazyload
;
803 this.itemData
= p_oConfig
.itemData
|| p_oConfig
.itemdata
;
808 YAHOO
.widget
.Menu
.superclass
.constructor.call(this, p_oElement
, p_oConfig
);
815 * @method checkPosition
816 * @description Checks to make sure that the value of the "position" property
817 * is one of the supported strings. Returns true if the position is supported.
819 * @param {Object} p_sPosition String specifying the position of the menu.
822 function checkPosition(p_sPosition
) {
824 if (typeof p_sPosition
== "string") {
826 return ("dynamic,static".indexOf((p_sPosition
.toLowerCase())) != -1);
833 var Dom
= YAHOO
.util
.Dom
,
834 Event
= YAHOO
.util
.Event
,
835 Module
= YAHOO
.widget
.Module
,
836 Overlay
= YAHOO
.widget
.Overlay
,
837 Menu
= YAHOO
.widget
.Menu
,
838 MenuManager
= YAHOO
.widget
.MenuManager
,
839 CustomEvent
= YAHOO
.util
.CustomEvent
,
845 * Constant representing the name of the Menu's events
846 * @property EVENT_TYPES
853 "MOUSE_OVER": "mouseover",
854 "MOUSE_OUT": "mouseout",
855 "MOUSE_DOWN": "mousedown",
856 "MOUSE_UP": "mouseup",
858 "KEY_PRESS": "keypress",
859 "KEY_DOWN": "keydown",
863 "ITEM_ADDED": "itemAdded",
864 "ITEM_REMOVED": "itemRemoved"
870 * Constant representing the Menu's configuration properties
871 * @property DEFAULT_CONFIG
881 validator
: Lang
.isBoolean
884 "CONSTRAIN_TO_VIEWPORT": {
885 key
: "constraintoviewport",
887 validator
: Lang
.isBoolean
,
888 supercedes
: ["iframe","x","y","xy"]
894 validator
: checkPosition
,
895 supercedes
: ["visible", "iframe"]
898 "SUBMENU_ALIGNMENT": {
899 key
: "submenualignment",
903 "AUTO_SUBMENU_DISPLAY": {
904 key
: "autosubmenudisplay",
906 validator
: Lang
.isBoolean
912 validator
: Lang
.isNumber
918 validator
: Lang
.isNumber
,
922 "SUBMENU_HIDE_DELAY": {
923 key
: "submenuhidedelay",
925 validator
: Lang
.isNumber
931 validator
: Lang
.isBoolean
941 validator
: Lang
.isNumber
,
942 supercedes
: ["iframe"]
948 validator
: Lang
.isString
954 validator
: Lang
.isBoolean
961 YAHOO
.lang
.extend(Menu
, Overlay
, {
968 * @property CSS_CLASS_NAME
969 * @description String representing the CSS class(es) to be applied to the
970 * menu's <code><div></code> element.
975 CSS_CLASS_NAME
: "yuimenu",
979 * @property ITEM_TYPE
980 * @description Object representing the type of menu item to instantiate and
981 * add when parsing the child nodes (either <code><li></code> element,
982 * <code><optgroup></code> element or <code><option></code>)
983 * of the menu's source HTML element.
984 * @default YAHOO.widget.MenuItem
986 * @type YAHOO.widget.MenuItem
992 * @property GROUP_TITLE_TAG_NAME
993 * @description String representing the tagname of the HTML element used to
994 * title the menu's item groups.
999 GROUP_TITLE_TAG_NAME
: "h6",
1003 // Private properties
1007 * @property _nHideDelayId
1008 * @description Number representing the time-out setting used to cancel the
1014 _nHideDelayId
: null,
1018 * @property _nShowDelayId
1019 * @description Number representing the time-out setting used to cancel the
1020 * showing of a menu.
1025 _nShowDelayId
: null,
1029 * @property _nSubmenuHideDelayId
1030 * @description Number representing the time-out setting used to cancel the
1031 * hiding of a submenu.
1036 _nSubmenuHideDelayId
: null,
1040 * @property _nBodyScrollId
1041 * @description Number representing the time-out setting used to cancel the
1042 * scrolling of the menu's body element.
1047 _nBodyScrollId
: null,
1051 * @property _bHideDelayEventHandlersAssigned
1052 * @description Boolean indicating if the "mouseover" and "mouseout" event
1053 * handlers used for hiding the menu via a call to "window.setTimeout" have
1054 * already been assigned.
1059 _bHideDelayEventHandlersAssigned
: false,
1063 * @property _bHandledMouseOverEvent
1064 * @description Boolean indicating the current state of the menu's
1065 * "mouseover" event.
1070 _bHandledMouseOverEvent
: false,
1074 * @property _bHandledMouseOutEvent
1075 * @description Boolean indicating the current state of the menu's
1081 _bHandledMouseOutEvent
: false,
1085 * @property _aGroupTitleElements
1086 * @description Array of HTML element used to title groups of menu items.
1091 _aGroupTitleElements
: null,
1095 * @property _aItemGroups
1096 * @description Multi-dimensional Array representing the menu items as they
1097 * are grouped in the menu.
1106 * @property _aListElements
1107 * @description Array of <code><ul></code> elements, each of which is
1108 * the parent node for each item's <code><li></code> element.
1113 _aListElements
: null,
1117 * @property _nCurrentMouseX
1118 * @description The current x coordinate of the mouse inside the area of
1128 * @property _nMaxHeight
1129 * @description The original value of the "maxheight" configuration property
1130 * as set by the user.
1139 * @property _bStopMouseEventHandlers
1140 * @description Stops "mouseover," "mouseout," and "mousemove" event handlers
1146 _bStopMouseEventHandlers
: false,
1150 * @property _sClassName
1151 * @description The current value of the "classname" configuration attribute.
1160 * @property _bDisabled
1161 * @description The current value of the "disabled" configuration attribute.
1169 // Public properties
1173 * @property lazyLoad
1174 * @description Boolean indicating if the menu's "lazy load" feature is
1175 * enabled. If set to "true," initialization and rendering of the menu's
1176 * items will be deferred until the first time it is made visible. This
1177 * property should be set via the constructor using the configuration
1186 * @property itemData
1187 * @description Array of items to be added to the menu. The array can contain
1188 * strings representing the text for each item to be created, object literals
1189 * representing the menu item configuration properties, or MenuItem instances.
1190 * This property should be set via the constructor using the configuration
1199 * @property activeItem
1200 * @description Object reference to the item in the menu that has is selected.
1202 * @type YAHOO.widget.MenuItem
1209 * @description Object reference to the menu's parent menu or menu item.
1210 * This property can be set via the constructor using the configuration
1213 * @type YAHOO.widget.MenuItem
1219 * @property srcElement
1220 * @description Object reference to the HTML element (either
1221 * <code><select></code> or <code><div></code>) used to
1224 * @type <a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/
1225 * level-one-html.html#ID-94282980">HTMLSelectElement</a>|<a
1226 * href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-one-html.
1227 * html#ID-22445964">HTMLDivElement</a>
1237 * @event mouseOverEvent
1238 * @description Fires when the mouse has entered the menu. Passes back
1239 * the DOM Event object as an argument.
1241 mouseOverEvent
: null,
1245 * @event mouseOutEvent
1246 * @description Fires when the mouse has left the menu. Passes back the DOM
1247 * Event object as an argument.
1248 * @type YAHOO.util.CustomEvent
1250 mouseOutEvent
: null,
1254 * @event mouseDownEvent
1255 * @description Fires when the user mouses down on the menu. Passes back the
1256 * DOM Event object as an argument.
1257 * @type YAHOO.util.CustomEvent
1259 mouseDownEvent
: null,
1263 * @event mouseUpEvent
1264 * @description Fires when the user releases a mouse button while the mouse is
1265 * over the menu. Passes back the DOM Event object as an argument.
1266 * @type YAHOO.util.CustomEvent
1273 * @description Fires when the user clicks the on the menu. Passes back the
1274 * DOM Event object as an argument.
1275 * @type YAHOO.util.CustomEvent
1281 * @event keyPressEvent
1282 * @description Fires when the user presses an alphanumeric key when one of the
1283 * menu's items has focus. Passes back the DOM Event object as an argument.
1284 * @type YAHOO.util.CustomEvent
1286 keyPressEvent
: null,
1290 * @event keyDownEvent
1291 * @description Fires when the user presses a key when one of the menu's items
1292 * has focus. Passes back the DOM Event object as an argument.
1293 * @type YAHOO.util.CustomEvent
1300 * @description Fires when the user releases a key when one of the menu's items
1301 * has focus. Passes back the DOM Event object as an argument.
1302 * @type YAHOO.util.CustomEvent
1308 * @event itemAddedEvent
1309 * @description Fires when an item is added to the menu.
1310 * @type YAHOO.util.CustomEvent
1312 itemAddedEvent
: null,
1316 * @event itemRemovedEvent
1317 * @description Fires when an item is removed to the menu.
1318 * @type YAHOO.util.CustomEvent
1320 itemRemovedEvent
: null,
1325 * @description The Menu class's initialization method. This method is
1326 * automatically called by the constructor, and sets up all DOM references
1327 * for pre-existing markup, and creates required markup if it is not
1329 * @param {String} p_oElement String specifying the id attribute of the
1330 * <code><div></code> element of the menu.
1331 * @param {String} p_oElement String specifying the id attribute of the
1332 * <code><select></code> element to be used as the data source
1334 * @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/
1335 * level-one-html.html#ID-22445964">HTMLDivElement</a>} p_oElement Object
1336 * specifying the <code><div></code> element of the menu.
1337 * @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/
1338 * level-one-html.html#ID-94282980">HTMLSelectElement</a>} p_oElement
1339 * Object specifying the <code><select></code> element to be used as
1340 * the data source for the menu.
1341 * @param {Object} p_oConfig Optional. Object literal specifying the
1342 * configuration for the menu. See configuration class documentation for
1345 init: function (p_oElement
, p_oConfig
) {
1347 this._aItemGroups
= [];
1348 this._aListElements
= [];
1349 this._aGroupTitleElements
= [];
1351 if (!this.ITEM_TYPE
) {
1353 this.ITEM_TYPE
= YAHOO
.widget
.MenuItem
;
1360 if (typeof p_oElement
== "string") {
1362 oElement
= document
.getElementById(p_oElement
);
1365 else if (p_oElement
.tagName
) {
1367 oElement
= p_oElement
;
1372 if (oElement
&& oElement
.tagName
) {
1374 switch(oElement
.tagName
.toUpperCase()) {
1378 this.srcElement
= oElement
;
1382 oElement
.setAttribute("id", Dom
.generateId());
1388 Note: we don't pass the user config in here yet
1389 because we only want it executed once, at the lowest
1393 Menu
.superclass
.init
.call(this, oElement
);
1395 this.beforeInitEvent
.fire(Menu
);
1397 this.logger
= new YAHOO
.widget
.LogWriter(this.toString());
1399 this.logger
.log("Source element: " + this.srcElement
.tagName
);
1405 this.srcElement
= oElement
;
1409 The source element is not something that we can use
1410 outright, so we need to create a new Overlay
1412 Note: we don't pass the user config in here yet
1413 because we only want it executed once, at the lowest
1417 Menu
.superclass
.init
.call(this, Dom
.generateId());
1419 this.beforeInitEvent
.fire(Menu
);
1421 this.logger
= new YAHOO
.widget
.LogWriter(this.toString());
1423 this.logger
.log("Source element: " + this.srcElement
.tagName
);
1433 Note: we don't pass the user config in here yet
1434 because we only want it executed once, at the lowest
1438 Menu
.superclass
.init
.call(this, p_oElement
);
1440 this.beforeInitEvent
.fire(Menu
);
1442 this.logger
= new YAHOO
.widget
.LogWriter(this.toString());
1444 this.logger
.log("No source element found. " +
1445 "Created element with id: " + this.id
);
1452 Dom
.addClass(this.element
, this.CSS_CLASS_NAME
);
1455 // Subscribe to Custom Events
1457 this.initEvent
.subscribe(this._onInit
);
1458 this.beforeRenderEvent
.subscribe(this._onBeforeRender
);
1459 this.renderEvent
.subscribe(this._onRender
);
1460 this.renderEvent
.subscribe(this.onRender
);
1461 this.beforeShowEvent
.subscribe(this._onBeforeShow
);
1462 this.showEvent
.subscribe(this._onShow
);
1463 this.beforeHideEvent
.subscribe(this._onBeforeHide
);
1464 this.hideEvent
.subscribe(this._onHide
);
1465 this.mouseOverEvent
.subscribe(this._onMouseOver
);
1466 this.mouseOutEvent
.subscribe(this._onMouseOut
);
1467 this.clickEvent
.subscribe(this._onClick
);
1468 this.keyDownEvent
.subscribe(this._onKeyDown
);
1469 this.keyPressEvent
.subscribe(this._onKeyPress
);
1471 Module
.textResizeEvent
.subscribe(this._onTextResize
, this, true);
1476 this.cfg
.applyConfig(p_oConfig
, true);
1481 // Register the Menu instance with the MenuManager
1483 MenuManager
.addMenu(this);
1486 this.initEvent
.fire(Menu
);
1498 * @method _initSubTree
1499 * @description Iterates the childNodes of the source element to find nodes
1500 * used to instantiate menu and menu items.
1503 _initSubTree: function () {
1505 var oSrcElement
= this.srcElement
,
1517 sSrcElementTagName
=
1518 (oSrcElement
.tagName
&& oSrcElement
.tagName
.toUpperCase());
1521 if (sSrcElementTagName
== "DIV") {
1523 // Populate the collection of item groups and item group titles
1525 oNode
= this.body
.firstChild
;
1531 sGroupTitleTagName
= this.GROUP_TITLE_TAG_NAME
.toUpperCase();
1536 if (oNode
&& oNode
.tagName
) {
1538 switch (oNode
.tagName
.toUpperCase()) {
1540 case sGroupTitleTagName
:
1542 this._aGroupTitleElements
[nGroup
] = oNode
;
1548 this._aListElements
[nGroup
] = oNode
;
1549 this._aItemGroups
[nGroup
] = [];
1559 while ((oNode
= oNode
.nextSibling
));
1563 Apply the "first-of-type" class to the first UL to mimic
1564 the "first-of-type" CSS3 psuedo class.
1567 if (this._aListElements
[0]) {
1569 Dom
.addClass(this._aListElements
[0], "first-of-type");
1580 this.logger
.log("Searching DOM for items to initialize.");
1583 if (sSrcElementTagName
) {
1585 switch (sSrcElementTagName
) {
1589 aListElements
= this._aListElements
;
1590 nListElements
= aListElements
.length
;
1592 if (nListElements
> 0) {
1594 this.logger
.log("Found " + nListElements
+
1595 " item groups to initialize.");
1597 i
= nListElements
- 1;
1601 oNode
= aListElements
[i
].firstChild
;
1605 this.logger
.log("Scanning " +
1606 aListElements
[i
].childNodes
.length
+
1607 " child nodes for items to initialize.");
1611 if (oNode
&& oNode
.tagName
&&
1612 oNode
.tagName
.toUpperCase() == "LI") {
1614 this.logger
.log("Initializing " +
1615 oNode
.tagName
+ " node.");
1617 this.addItem(new this.ITEM_TYPE(oNode
,
1618 { parent
: this }), i
);
1623 while ((oNode
= oNode
.nextSibling
));
1636 this.logger
.log("Scanning " +
1637 oSrcElement
.childNodes
.length
+
1638 " child nodes for items to initialize.");
1640 oNode
= oSrcElement
.firstChild
;
1644 if (oNode
&& oNode
.tagName
) {
1646 switch (oNode
.tagName
.toUpperCase()) {
1651 this.logger
.log("Initializing " +
1652 oNode
.tagName
+ " node.");
1668 while ((oNode
= oNode
.nextSibling
));
1682 * @method _getFirstEnabledItem
1683 * @description Returns the first enabled item in the menu.
1684 * @return {YAHOO.widget.MenuItem}
1687 _getFirstEnabledItem: function () {
1689 var aItems
= this.getItems(),
1690 nItems
= aItems
.length
,
1693 for(var i
=0; i
<nItems
; i
++) {
1697 if (oItem
&& !oItem
.cfg
.getProperty("disabled") &&
1698 oItem
.element
.style
.display
!= "none") {
1710 * @method _addItemToGroup
1711 * @description Adds a menu item to a group.
1713 * @param {Number} p_nGroupIndex Number indicating the group to which the
1715 * @param {YAHOO.widget.MenuItem} p_oItem Object reference for the MenuItem
1716 * instance to be added to the menu.
1717 * @param {String} p_oItem String specifying the text of the item to be added
1719 * @param {Object} p_oItem Object literal containing a set of menu item
1720 * configuration properties.
1721 * @param {Number} p_nItemIndex Optional. Number indicating the index at
1722 * which the menu item should be added.
1723 * @return {YAHOO.widget.MenuItem}
1725 _addItemToGroup: function (p_nGroupIndex
, p_oItem
, p_nItemIndex
) {
1728 bDisabled
= this.cfg
.getProperty("disabled"),
1736 function getNextItemSibling(p_aArray
, p_nStartIndex
) {
1738 return (p_aArray
[p_nStartIndex
] || getNextItemSibling(p_aArray
,
1739 (p_nStartIndex
+1)));
1743 if (p_oItem
instanceof this.ITEM_TYPE
) {
1746 oItem
.parent
= this;
1749 else if (typeof p_oItem
== "string") {
1751 oItem
= new this.ITEM_TYPE(p_oItem
, { parent
: this });
1754 else if (typeof p_oItem
== "object") {
1756 p_oItem
.parent
= this;
1758 oItem
= new this.ITEM_TYPE(p_oItem
.text
, p_oItem
);
1765 if (oItem
.cfg
.getProperty("selected")) {
1767 this.activeItem
= oItem
;
1772 nGroupIndex
= typeof p_nGroupIndex
== "number" ? p_nGroupIndex
: 0;
1773 aGroup
= this._getItemGroup(nGroupIndex
);
1779 aGroup
= this._createItemGroup(nGroupIndex
);
1784 if (typeof p_nItemIndex
== "number") {
1786 bAppend
= (p_nItemIndex
>= aGroup
.length
);
1789 if (aGroup
[p_nItemIndex
]) {
1791 aGroup
.splice(p_nItemIndex
, 0, oItem
);
1796 aGroup
[p_nItemIndex
] = oItem
;
1801 oGroupItem
= aGroup
[p_nItemIndex
];
1805 if (bAppend
&& (!oGroupItem
.element
.parentNode
||
1806 oGroupItem
.element
.parentNode
.nodeType
== 11)) {
1808 this._aListElements
[nGroupIndex
].appendChild(
1809 oGroupItem
.element
);
1814 oNextItemSibling
= getNextItemSibling(aGroup
,
1817 if (oNextItemSibling
&& (!oGroupItem
.element
.parentNode
||
1818 oGroupItem
.element
.parentNode
.nodeType
== 11)) {
1820 this._aListElements
[nGroupIndex
].insertBefore(
1822 oNextItemSibling
.element
);
1829 oGroupItem
.parent
= this;
1831 this._subscribeToItemEvents(oGroupItem
);
1833 this._configureSubmenu(oGroupItem
);
1835 this._updateItemProperties(nGroupIndex
);
1837 this.logger
.log("Item inserted." +
1838 " Text: " + oGroupItem
.cfg
.getProperty("text") + ", " +
1839 " Index: " + oGroupItem
.index
+ ", " +
1840 " Group Index: " + oGroupItem
.groupIndex
);
1842 this.itemAddedEvent
.fire(oGroupItem
);
1843 this.changeContentEvent
.fire();
1852 nItemIndex
= aGroup
.length
;
1854 aGroup
[nItemIndex
] = oItem
;
1856 oGroupItem
= aGroup
[nItemIndex
];
1861 if (!Dom
.isAncestor(this._aListElements
[nGroupIndex
],
1862 oGroupItem
.element
)) {
1864 this._aListElements
[nGroupIndex
].appendChild(
1865 oGroupItem
.element
);
1869 oGroupItem
.element
.setAttribute("groupindex", nGroupIndex
);
1870 oGroupItem
.element
.setAttribute("index", nItemIndex
);
1872 oGroupItem
.parent
= this;
1874 oGroupItem
.index
= nItemIndex
;
1875 oGroupItem
.groupIndex
= nGroupIndex
;
1877 this._subscribeToItemEvents(oGroupItem
);
1879 this._configureSubmenu(oGroupItem
);
1881 if (nItemIndex
=== 0) {
1883 Dom
.addClass(oGroupItem
.element
, "first-of-type");
1887 this.logger
.log("Item added." +
1888 " Text: " + oGroupItem
.cfg
.getProperty("text") + ", " +
1889 " Index: " + oGroupItem
.index
+ ", " +
1890 " Group Index: " + oGroupItem
.groupIndex
);
1893 this.itemAddedEvent
.fire(oGroupItem
);
1894 this.changeContentEvent
.fire();
1908 * @method _removeItemFromGroupByIndex
1909 * @description Removes a menu item from a group by index. Returns the menu
1910 * item that was removed.
1912 * @param {Number} p_nGroupIndex Number indicating the group to which the menu
1914 * @param {Number} p_nItemIndex Number indicating the index of the menu item
1916 * @return {YAHOO.widget.MenuItem}
1918 _removeItemFromGroupByIndex: function (p_nGroupIndex
, p_nItemIndex
) {
1920 var nGroupIndex
= typeof p_nGroupIndex
== "number" ? p_nGroupIndex
: 0,
1921 aGroup
= this._getItemGroup(nGroupIndex
),
1928 aArray
= aGroup
.splice(p_nItemIndex
, 1);
1933 // Update the index and className properties of each member
1935 this._updateItemProperties(nGroupIndex
);
1937 if (aGroup
.length
=== 0) {
1941 oUL
= this._aListElements
[nGroupIndex
];
1943 if (this.body
&& oUL
) {
1945 this.body
.removeChild(oUL
);
1949 // Remove the group from the array of items
1951 this._aItemGroups
.splice(nGroupIndex
, 1);
1954 // Remove the UL from the array of ULs
1956 this._aListElements
.splice(nGroupIndex
, 1);
1960 Assign the "first-of-type" class to the new first UL
1964 oUL
= this._aListElements
[0];
1968 Dom
.addClass(oUL
, "first-of-type");
1975 this.itemRemovedEvent
.fire(oItem
);
1976 this.changeContentEvent
.fire();
1979 // Return a reference to the item that was removed
1991 * @method _removeItemFromGroupByValue
1992 * @description Removes a menu item from a group by reference. Returns the
1993 * menu item that was removed.
1995 * @param {Number} p_nGroupIndex Number indicating the group to which the
1996 * menu item belongs.
1997 * @param {YAHOO.widget.MenuItem} p_oItem Object reference for the MenuItem
1998 * instance to be removed.
1999 * @return {YAHOO.widget.MenuItem}
2001 _removeItemFromGroupByValue: function (p_nGroupIndex
, p_oItem
) {
2003 var aGroup
= this._getItemGroup(p_nGroupIndex
),
2010 nItems
= aGroup
.length
;
2019 if (aGroup
[i
] == p_oItem
) {
2029 if (nItemIndex
> -1) {
2031 return (this._removeItemFromGroupByIndex(p_nGroupIndex
,
2044 * @method _updateItemProperties
2045 * @description Updates the "index," "groupindex," and "className" properties
2046 * of the menu items in the specified group.
2048 * @param {Number} p_nGroupIndex Number indicating the group of items to update.
2050 _updateItemProperties: function (p_nGroupIndex
) {
2052 var aGroup
= this._getItemGroup(p_nGroupIndex
),
2053 nItems
= aGroup
.length
,
2063 // Update the index and className properties of each member
2071 oLI
= oItem
.element
;
2074 oItem
.groupIndex
= p_nGroupIndex
;
2076 oLI
.setAttribute("groupindex", p_nGroupIndex
);
2077 oLI
.setAttribute("index", i
);
2079 Dom
.removeClass(oLI
, "first-of-type");
2089 Dom
.addClass(oLI
, "first-of-type");
2099 * @method _createItemGroup
2100 * @description Creates a new menu item group (array) and its associated
2101 * <code><ul></code> element. Returns an aray of menu item groups.
2103 * @param {Number} p_nIndex Number indicating the group to create.
2106 _createItemGroup: function (p_nIndex
) {
2110 if (!this._aItemGroups
[p_nIndex
]) {
2112 this._aItemGroups
[p_nIndex
] = [];
2114 oUL
= document
.createElement("ul");
2116 this._aListElements
[p_nIndex
] = oUL
;
2118 return this._aItemGroups
[p_nIndex
];
2126 * @method _getItemGroup
2127 * @description Returns the menu item group at the specified index.
2129 * @param {Number} p_nIndex Number indicating the index of the menu item group
2133 _getItemGroup: function (p_nIndex
) {
2135 var nIndex
= ((typeof p_nIndex
== "number") ? p_nIndex
: 0);
2137 return this._aItemGroups
[nIndex
];
2143 * @method _configureSubmenu
2144 * @description Subscribes the menu item's submenu to its parent menu's events.
2146 * @param {YAHOO.widget.MenuItem} p_oItem Object reference for the MenuItem
2147 * instance with the submenu to be configured.
2149 _configureSubmenu: function (p_oItem
) {
2151 var oSubmenu
= p_oItem
.cfg
.getProperty("submenu");
2156 Listen for configuration changes to the parent menu
2157 so they they can be applied to the submenu.
2160 this.cfg
.configChangedEvent
.subscribe(this._onParentMenuConfigChange
,
2163 this.renderEvent
.subscribe(this._onParentMenuRender
, oSubmenu
, true);
2165 oSubmenu
.beforeShowEvent
.subscribe(this._onSubmenuBeforeShow
, null,
2168 oSubmenu
.showEvent
.subscribe(this._onSubmenuShow
, null, p_oItem
);
2169 oSubmenu
.hideEvent
.subscribe(this._onSubmenuHide
, null, p_oItem
);
2177 * @method _subscribeToItemEvents
2178 * @description Subscribes a menu to a menu item's event.
2180 * @param {YAHOO.widget.MenuItem} p_oItem Object reference for the MenuItem
2181 * instance whose events should be subscribed to.
2183 _subscribeToItemEvents: function (p_oItem
) {
2185 p_oItem
.focusEvent
.subscribe(this._onMenuItemFocus
);
2187 p_oItem
.blurEvent
.subscribe(this._onMenuItemBlur
);
2189 p_oItem
.cfg
.configChangedEvent
.subscribe(this._onMenuItemConfigChange
,
2196 * @method _getOffsetWidth
2197 * @description Returns the offset width of the menu's
2198 * <code><div></code> element.
2201 _getOffsetWidth: function () {
2203 var oClone
= this.element
.cloneNode(true);
2205 Dom
.removeClass(oClone
, "visible");
2207 Dom
.setStyle(oClone
, "width", "");
2209 document
.body
.appendChild(oClone
);
2211 var sWidth
= oClone
.offsetWidth
;
2213 document
.body
.removeChild(oClone
);
2222 * @description Sets the width of the menu's root <code><div></code>
2223 * element to its offsetWidth.
2226 _setWidth: function () {
2228 var oElement
= this.element
,
2232 if (oElement
.parentNode
.tagName
.toUpperCase() == "BODY") {
2234 if (YAHOO
.env
.ua
.opera
) {
2236 sWidth
= this._getOffsetWidth();
2241 if (Dom
.hasClass(oElement
, "visible")) {
2245 Dom
.removeClass(oElement
, "visible");
2249 Dom
.setStyle(oElement
, "width", "auto");
2251 sWidth
= oElement
.offsetWidth
;
2258 sWidth
= this._getOffsetWidth();
2262 this.cfg
.setProperty("width", (sWidth
+ "px"));
2267 Dom
.addClass(oElement
, "visible");
2275 * @method _onWidthChange
2276 * @description Change event handler for the the menu's "width" configuration
2279 * @param {String} p_sType String representing the name of the event that
2281 * @param {Array} p_aArgs Array of arguments sent when the event was fired.
2283 _onWidthChange: function (p_sType
, p_aArgs
) {
2285 var sWidth
= p_aArgs
[0];
2287 if (sWidth
&& !this._hasSetWidthHandlers
) {
2289 this.itemAddedEvent
.subscribe(this._setWidth
);
2290 this.itemRemovedEvent
.subscribe(this._setWidth
);
2292 this._hasSetWidthHandlers
= true;
2295 else if (this._hasSetWidthHandlers
) {
2297 this.itemAddedEvent
.unsubscribe(this._setWidth
);
2298 this.itemRemovedEvent
.unsubscribe(this._setWidth
);
2300 this._hasSetWidthHandlers
= false;
2308 * @method _onVisibleChange
2309 * @description Change event handler for the the menu's "visible" configuration
2312 * @param {String} p_sType String representing the name of the event that
2314 * @param {Array} p_aArgs Array of arguments sent when the event was fired.
2316 _onVisibleChange: function (p_sType
, p_aArgs
) {
2318 var bVisible
= p_aArgs
[0];
2322 Dom
.addClass(this.element
, "visible");
2327 Dom
.removeClass(this.element
, "visible");
2335 * @method _cancelHideDelay
2336 * @description Cancels the call to "hideMenu."
2339 _cancelHideDelay: function () {
2341 var oRoot
= this.getRoot();
2343 if (oRoot
._nHideDelayId
) {
2345 window
.clearTimeout(oRoot
._nHideDelayId
);
2353 * @method _execHideDelay
2354 * @description Hides the menu after the number of milliseconds specified by
2355 * the "hidedelay" configuration property.
2358 _execHideDelay: function () {
2360 this._cancelHideDelay();
2362 var oRoot
= this.getRoot(),
2365 function hideMenu() {
2367 if (oRoot
.activeItem
) {
2369 oRoot
.clearActiveItem();
2373 if (oRoot
== me
&& !(me
instanceof YAHOO
.widget
.MenuBar
) &&
2374 me
.cfg
.getProperty("position") == "dynamic") {
2383 oRoot
._nHideDelayId
=
2384 window
.setTimeout(hideMenu
, oRoot
.cfg
.getProperty("hidedelay"));
2390 * @method _cancelShowDelay
2391 * @description Cancels the call to the "showMenu."
2394 _cancelShowDelay: function () {
2396 var oRoot
= this.getRoot();
2398 if (oRoot
._nShowDelayId
) {
2400 window
.clearTimeout(oRoot
._nShowDelayId
);
2408 * @method _execShowDelay
2409 * @description Shows the menu after the number of milliseconds specified by
2410 * the "showdelay" configuration property have ellapsed.
2412 * @param {YAHOO.widget.Menu} p_oMenu Object specifying the menu that should
2415 _execShowDelay: function (p_oMenu
) {
2417 var oRoot
= this.getRoot();
2419 function showMenu() {
2421 if (p_oMenu
.parent
.cfg
.getProperty("selected")) {
2430 oRoot
._nShowDelayId
=
2431 window
.setTimeout(showMenu
, oRoot
.cfg
.getProperty("showdelay"));
2437 * @method _execSubmenuHideDelay
2438 * @description Hides a submenu after the number of milliseconds specified by
2439 * the "submenuhidedelay" configuration property have ellapsed.
2441 * @param {YAHOO.widget.Menu} p_oSubmenu Object specifying the submenu that
2443 * @param {Number} p_nMouseX The x coordinate of the mouse when it left
2444 * the specified submenu's parent menu item.
2445 * @param {Number} p_nHideDelay The number of milliseconds that should ellapse
2446 * before the submenu is hidden.
2448 _execSubmenuHideDelay: function (p_oSubmenu
, p_nMouseX
, p_nHideDelay
) {
2452 p_oSubmenu
._nSubmenuHideDelayId
= window
.setTimeout(function () {
2454 if (me
._nCurrentMouseX
> (p_nMouseX
+ 10)) {
2456 p_oSubmenu
._nSubmenuHideDelayId
= window
.setTimeout(function () {
2475 // Protected methods
2479 * @method _disableScrollHeader
2480 * @description Disables the header used for scrolling the body of the menu.
2483 _disableScrollHeader: function () {
2485 if (!this._bHeaderDisabled
) {
2487 Dom
.addClass(this.header
, "topscrollbar_disabled");
2488 this._bHeaderDisabled
= true;
2496 * @method _disableScrollFooter
2497 * @description Disables the footer used for scrolling the body of the menu.
2500 _disableScrollFooter: function () {
2502 if (!this._bFooterDisabled
) {
2504 Dom
.addClass(this.footer
, "bottomscrollbar_disabled");
2505 this._bFooterDisabled
= true;
2513 * @method _enableScrollHeader
2514 * @description Enables the header used for scrolling the body of the menu.
2517 _enableScrollHeader: function () {
2519 if (this._bHeaderDisabled
) {
2521 Dom
.removeClass(this.header
, "topscrollbar_disabled");
2522 this._bHeaderDisabled
= false;
2530 * @method _enableScrollFooter
2531 * @description Enables the footer used for scrolling the body of the menu.
2534 _enableScrollFooter: function () {
2536 if (this._bFooterDisabled
) {
2538 Dom
.removeClass(this.footer
, "bottomscrollbar_disabled");
2539 this._bFooterDisabled
= false;
2547 * @method _onMouseOver
2548 * @description "mouseover" event handler for the menu.
2550 * @param {String} p_sType String representing the name of the event that
2552 * @param {Array} p_aArgs Array of arguments sent when the event was fired.
2554 _onMouseOver: function (p_sType
, p_aArgs
) {
2556 if (this._bStopMouseEventHandlers
) {
2563 var oEvent
= p_aArgs
[0],
2565 oTarget
= Event
.getTarget(oEvent
),
2574 if (!this._bHandledMouseOverEvent
&& (oTarget
== this.element
||
2575 Dom
.isAncestor(this.element
, oTarget
))) {
2577 // Menu mouseover logic
2579 this._nCurrentMouseX
= 0;
2581 Event
.on(this.element
, "mousemove", this._onMouseMove
, this, true);
2584 this.clearActiveItem();
2587 if (this.parent
&& this._nSubmenuHideDelayId
) {
2589 window
.clearTimeout(this._nSubmenuHideDelayId
);
2591 this.parent
.cfg
.setProperty("selected", true);
2593 oParentMenu
= this.parent
.parent
;
2595 oParentMenu
._bHandledMouseOutEvent
= true;
2596 oParentMenu
._bHandledMouseOverEvent
= false;
2601 this._bHandledMouseOverEvent
= true;
2602 this._bHandledMouseOutEvent
= false;
2607 if (oItem
&& !oItem
.handledMouseOverEvent
&&
2608 !oItem
.cfg
.getProperty("disabled") &&
2609 (oTarget
== oItem
.element
|| Dom
.isAncestor(oItem
.element
, oTarget
))) {
2611 // Menu Item mouseover logic
2613 nShowDelay
= this.cfg
.getProperty("showdelay");
2614 bShowDelay
= (nShowDelay
> 0);
2619 this._cancelShowDelay();
2624 oActiveItem
= this.activeItem
;
2628 oActiveItem
.cfg
.setProperty("selected", false);
2633 oItemCfg
= oItem
.cfg
;
2635 // Select and focus the current menu item
2637 oItemCfg
.setProperty("selected", true);
2640 if (this.hasFocus()) {
2647 if (this.cfg
.getProperty("autosubmenudisplay")) {
2649 // Show the submenu this menu item
2651 oSubmenu
= oItemCfg
.getProperty("submenu");
2657 this._execShowDelay(oSubmenu
);
2670 oItem
.handledMouseOverEvent
= true;
2671 oItem
.handledMouseOutEvent
= false;
2679 * @method _onMouseOut
2680 * @description "mouseout" event handler for the menu.
2682 * @param {String} p_sType String representing the name of the event that
2684 * @param {Array} p_aArgs Array of arguments sent when the event was fired.
2686 _onMouseOut: function (p_sType
, p_aArgs
) {
2688 if (this._bStopMouseEventHandlers
) {
2695 var oEvent
= p_aArgs
[0],
2697 oRelatedTarget
= Event
.getRelatedTarget(oEvent
),
2698 bMovingToSubmenu
= false,
2705 if (oItem
&& !oItem
.cfg
.getProperty("disabled")) {
2707 oItemCfg
= oItem
.cfg
;
2708 oSubmenu
= oItemCfg
.getProperty("submenu");
2711 if (oSubmenu
&& (oRelatedTarget
== oSubmenu
.element
||
2712 Dom
.isAncestor(oSubmenu
.element
, oRelatedTarget
))) {
2714 bMovingToSubmenu
= true;
2719 if (!oItem
.handledMouseOutEvent
&& ((oRelatedTarget
!= oItem
.element
&&
2720 !Dom
.isAncestor(oItem
.element
, oRelatedTarget
)) ||
2721 bMovingToSubmenu
)) {
2723 // Menu Item mouseout logic
2725 if (!bMovingToSubmenu
) {
2727 oItem
.cfg
.setProperty("selected", false);
2733 this.cfg
.getProperty("submenuhidedelay");
2735 nShowDelay
= this.cfg
.getProperty("showdelay");
2737 if (!(this instanceof YAHOO
.widget
.MenuBar
) &&
2738 nSubmenuHideDelay
> 0 &&
2739 nShowDelay
>= nSubmenuHideDelay
) {
2741 this._execSubmenuHideDelay(oSubmenu
,
2742 Event
.getPageX(oEvent
),
2757 oItem
.handledMouseOutEvent
= true;
2758 oItem
.handledMouseOverEvent
= false;
2765 if (!this._bHandledMouseOutEvent
&& ((oRelatedTarget
!= this.element
&&
2766 !Dom
.isAncestor(this.element
, oRelatedTarget
)) || bMovingToSubmenu
)) {
2768 // Menu mouseout logic
2770 Event
.removeListener(this.element
, "mousemove", this._onMouseMove
);
2772 this._nCurrentMouseX
= Event
.getPageX(oEvent
);
2774 this._bHandledMouseOutEvent
= true;
2775 this._bHandledMouseOverEvent
= false;
2783 * @method _onMouseMove
2784 * @description "click" event handler for the menu.
2786 * @param {Event} p_oEvent Object representing the DOM event object passed
2787 * back by the event utility (YAHOO.util.Event).
2788 * @param {YAHOO.widget.Menu} p_oMenu Object representing the menu that
2791 _onMouseMove: function (p_oEvent
, p_oMenu
) {
2793 if (this._bStopMouseEventHandlers
) {
2799 this._nCurrentMouseX
= Event
.getPageX(p_oEvent
);
2806 * @description "click" event handler for the menu.
2808 * @param {String} p_sType String representing the name of the event that
2810 * @param {Array} p_aArgs Array of arguments sent when the event was fired.
2812 _onClick: function (p_sType
, p_aArgs
) {
2814 var oEvent
= p_aArgs
[0],
2823 if (oItem
&& !oItem
.cfg
.getProperty("disabled")) {
2825 oTarget
= Event
.getTarget(oEvent
);
2826 oItemCfg
= oItem
.cfg
;
2827 oSubmenu
= oItemCfg
.getProperty("submenu");
2831 ACCESSIBILITY FEATURE FOR SCREEN READERS:
2832 Expand/collapse the submenu when the user clicks
2833 on the submenu indicator image.
2836 if (oTarget
== oItem
.submenuIndicator
&& oSubmenu
) {
2838 if (oSubmenu
.cfg
.getProperty("visible")) {
2842 oSubmenu
.parent
.focus();
2847 this.clearActiveItem();
2849 oItemCfg
.setProperty("selected", true);
2853 oSubmenu
.setInitialFocus();
2857 Event
.preventDefault(oEvent
);
2862 sURL
= oItemCfg
.getProperty("url");
2864 // Prevent the browser from following links equal to "#"
2866 if ((sURL
.substr((sURL
.length
-1),1) == "#")) {
2868 Event
.preventDefault(oEvent
);
2877 oRoot
= this.getRoot();
2879 if (oRoot
instanceof YAHOO
.widget
.MenuBar
||
2880 oRoot
.cfg
.getProperty("position") == "static") {
2882 oRoot
.clearActiveItem();
2885 else if (oRoot
.cfg
.getProperty("clicktohide")) {
2901 * @method _onKeyDown
2902 * @description "keydown" event handler for the menu.
2904 * @param {String} p_sType String representing the name of the event that
2906 * @param {Array} p_aArgs Array of arguments sent when the event was fired.
2908 _onKeyDown: function (p_sType
, p_aArgs
) {
2910 var oEvent
= p_aArgs
[0],
2929 This function is called to prevent a bug in Firefox. In Firefox,
2930 moving a DOM element into a stationary mouse pointer will cause the
2931 browser to fire mouse events. This can result in the menu mouse
2932 event handlers being called uncessarily, especially when menus are
2933 moved into a stationary mouse pointer as a result of a
2936 function stopMouseEventHandlers() {
2938 me
._bStopMouseEventHandlers
= true;
2940 window
.setTimeout(function () {
2942 me
._bStopMouseEventHandlers
= false;
2949 if (oItem
&& !oItem
.cfg
.getProperty("disabled")) {
2951 oItemCfg
= oItem
.cfg
;
2952 oParentItem
= this.parent
;
2954 switch(oEvent
.keyCode
) {
2956 case 38: // Up arrow
2957 case 40: // Down arrow
2959 oNextItem
= (oEvent
.keyCode
== 38) ?
2960 oItem
.getPreviousEnabledSibling() :
2961 oItem
.getNextEnabledSibling();
2965 this.clearActiveItem();
2967 oNextItem
.cfg
.setProperty("selected", true);
2971 if (this.cfg
.getProperty("maxheight") > 0) {
2974 nBodyScrollTop
= oBody
.scrollTop
;
2975 nBodyOffsetHeight
= oBody
.offsetHeight
;
2976 aItems
= this.getItems();
2977 nItems
= aItems
.length
- 1;
2978 nNextItemOffsetTop
= oNextItem
.element
.offsetTop
;
2981 if (oEvent
.keyCode
== 40 ) { // Down
2983 if (nNextItemOffsetTop
>= (nBodyOffsetHeight
+ nBodyScrollTop
)) {
2985 oBody
.scrollTop
= nNextItemOffsetTop
- nBodyOffsetHeight
;
2988 else if (nNextItemOffsetTop
<= nBodyScrollTop
) {
2990 oBody
.scrollTop
= 0;
2995 if (oNextItem
== aItems
[nItems
]) {
2997 oBody
.scrollTop
= oNextItem
.element
.offsetTop
;
3004 if (nNextItemOffsetTop
<= nBodyScrollTop
) {
3006 oBody
.scrollTop
= nNextItemOffsetTop
- oNextItem
.element
.offsetHeight
;
3009 else if (nNextItemOffsetTop
>= (nBodyScrollTop
+ nBodyOffsetHeight
)) {
3011 oBody
.scrollTop
= nNextItemOffsetTop
;
3016 if (oNextItem
== aItems
[0]) {
3018 oBody
.scrollTop
= 0;
3025 nBodyScrollTop
= oBody
.scrollTop
;
3026 nScrollTarget
= oBody
.scrollHeight
- oBody
.offsetHeight
;
3028 if (nBodyScrollTop
=== 0) {
3030 this._disableScrollHeader();
3031 this._enableScrollFooter();
3034 else if (nBodyScrollTop
== nScrollTarget
) {
3036 this._enableScrollHeader();
3037 this._disableScrollFooter();
3042 this._enableScrollHeader();
3043 this._enableScrollFooter();
3052 Event
.preventDefault(oEvent
);
3054 stopMouseEventHandlers();
3059 case 39: // Right arrow
3061 oSubmenu
= oItemCfg
.getProperty("submenu");
3065 if (!oItemCfg
.getProperty("selected")) {
3067 oItemCfg
.setProperty("selected", true);
3072 oSubmenu
.setInitialFocus();
3073 oSubmenu
.setInitialSelection();
3078 oRoot
= this.getRoot();
3080 if (oRoot
instanceof YAHOO
.widget
.MenuBar
) {
3082 oNextItem
= oRoot
.activeItem
.getNextEnabledSibling();
3086 oRoot
.clearActiveItem();
3088 oNextItem
.cfg
.setProperty("selected", true);
3090 oSubmenu
= oNextItem
.cfg
.getProperty("submenu");
3107 Event
.preventDefault(oEvent
);
3109 stopMouseEventHandlers();
3114 case 37: // Left arrow
3118 oParentMenu
= oParentItem
.parent
;
3120 if (oParentMenu
instanceof YAHOO
.widget
.MenuBar
) {
3123 oParentMenu
.activeItem
.getPreviousEnabledSibling();
3127 oParentMenu
.clearActiveItem();
3129 oNextItem
.cfg
.setProperty("selected", true);
3131 oSubmenu
= oNextItem
.cfg
.getProperty("submenu");
3148 oParentItem
.focus();
3154 Event
.preventDefault(oEvent
);
3156 stopMouseEventHandlers();
3166 if (oEvent
.keyCode
== 27) { // Esc key
3168 if (this.cfg
.getProperty("position") == "dynamic") {
3174 this.parent
.focus();
3179 else if (this.activeItem
) {
3181 oSubmenu
= this.activeItem
.cfg
.getProperty("submenu");
3183 if (oSubmenu
&& oSubmenu
.cfg
.getProperty("visible")) {
3186 this.activeItem
.focus();
3191 this.activeItem
.blur();
3192 this.activeItem
.cfg
.setProperty("selected", false);
3199 Event
.preventDefault(oEvent
);
3207 * @method _onKeyPress
3208 * @description "keypress" event handler for a Menu instance.
3210 * @param {String} p_sType The name of the event that was fired.
3211 * @param {Array} p_aArgs Collection of arguments sent when the event
3214 _onKeyPress: function (p_sType
, p_aArgs
) {
3216 var oEvent
= p_aArgs
[0];
3219 if (oEvent
.keyCode
== 40 || oEvent
.keyCode
== 38) {
3221 Event
.preventDefault(oEvent
);
3229 * @method _onTextResize
3230 * @description "textresize" event handler for the menu.
3232 * @param {String} p_sType String representing the name of the event that
3234 * @param {Array} p_aArgs Array of arguments sent when the event was fired.
3235 * @param {YAHOO.widget.Menu} p_oMenu Object representing the menu that
3238 _onTextResize: function (p_sType
, p_aArgs
, p_oMenu
) {
3240 if (YAHOO
.env
.ua
.gecko
&& !this._handleResize
) {
3242 this._handleResize
= true;
3248 var oConfig
= this.cfg
;
3250 if (oConfig
.getProperty("position") == "dynamic") {
3252 oConfig
.setProperty("width", (this._getOffsetWidth() + "px"));
3260 * @method _onScrollTargetMouseOver
3261 * @description "mouseover" event handler for the menu's "header" and "footer"
3262 * elements. Used to scroll the body of the menu up and down when the
3263 * menu's "maxheight" configuration property is set to a value greater than 0.
3265 * @param {Event} p_oEvent Object representing the DOM event object passed
3266 * back by the event utility (YAHOO.util.Event).
3267 * @param {YAHOO.widget.Menu} p_oMenu Object representing the menu that
3270 _onScrollTargetMouseOver: function (p_oEvent
, p_oMenu
) {
3272 this._cancelHideDelay();
3274 var oTarget
= Event
.getTarget(p_oEvent
),
3281 function scrollBodyDown() {
3283 var nScrollTop
= oBody
.scrollTop
;
3286 if (nScrollTop
< nScrollTarget
) {
3288 oBody
.scrollTop
= (nScrollTop
+ 1);
3290 me
._enableScrollHeader();
3295 oBody
.scrollTop
= nScrollTarget
;
3297 window
.clearInterval(me
._nBodyScrollId
);
3299 me
._disableScrollFooter();
3306 function scrollBodyUp() {
3308 var nScrollTop
= oBody
.scrollTop
;
3311 if (nScrollTop
> 0) {
3313 oBody
.scrollTop
= (nScrollTop
- 1);
3315 me
._enableScrollFooter();
3320 oBody
.scrollTop
= 0;
3322 window
.clearInterval(me
._nBodyScrollId
);
3324 me
._disableScrollHeader();
3331 if (Dom
.hasClass(oTarget
, "hd")) {
3333 fnScrollFunction
= scrollBodyUp
;
3338 nScrollTarget
= oBody
.scrollHeight
- oBody
.offsetHeight
;
3340 fnScrollFunction
= scrollBodyDown
;
3345 this._nBodyScrollId
= window
.setInterval(fnScrollFunction
, 10);
3351 * @method _onScrollTargetMouseOut
3352 * @description "mouseout" event handler for the menu's "header" and "footer"
3353 * elements. Used to stop scrolling the body of the menu up and down when the
3354 * menu's "maxheight" configuration property is set to a value greater than 0.
3356 * @param {Event} p_oEvent Object representing the DOM event object passed
3357 * back by the event utility (YAHOO.util.Event).
3358 * @param {YAHOO.widget.Menu} p_oMenu Object representing the menu that
3361 _onScrollTargetMouseOut: function (p_oEvent
, p_oMenu
) {
3363 window
.clearInterval(this._nBodyScrollId
);
3365 this._cancelHideDelay();
3376 * @description "init" event handler for the menu.
3378 * @param {String} p_sType String representing the name of the event that
3380 * @param {Array} p_aArgs Array of arguments sent when the event was fired.
3382 _onInit: function (p_sType
, p_aArgs
) {
3384 this.cfg
.subscribeToConfigEvent("width", this._onWidthChange
);
3385 this.cfg
.subscribeToConfigEvent("visible", this._onVisibleChange
);
3387 var bRootMenu
= !this.parent
,
3388 bLazyLoad
= this.lazyLoad
;
3392 Automatically initialize a menu's subtree if:
3394 1) This is the root menu and lazyload is off
3396 2) This is the root menu, lazyload is on, but the menu is
3399 3) This menu is a submenu and lazyload is off
3404 if (((bRootMenu
&& !bLazyLoad
) ||
3405 (bRootMenu
&& (this.cfg
.getProperty("visible") ||
3406 this.cfg
.getProperty("position") == "static")) ||
3407 (!bRootMenu
&& !bLazyLoad
)) && this.getItemGroups().length
=== 0) {
3409 if (this.srcElement
) {
3411 this._initSubTree();
3416 if (this.itemData
) {
3418 this.addItems(this.itemData
);
3423 else if (bLazyLoad
) {
3425 this.cfg
.fireQueue();
3433 * @method _onBeforeRender
3434 * @description "beforerender" event handler for the menu. Appends all of the
3435 * <code><ul></code>, <code><li></code> and their accompanying
3436 * title elements to the body element of the menu.
3438 * @param {String} p_sType String representing the name of the event that
3440 * @param {Array} p_aArgs Array of arguments sent when the event was fired.
3442 _onBeforeRender: function (p_sType
, p_aArgs
) {
3444 var oConfig
= this.cfg
,
3446 nListElements
= this._aListElements
.length
,
3452 if (nListElements
> 0) {
3456 oUL
= this._aListElements
[i
];
3462 Dom
.addClass(oUL
, "first-of-type");
3468 if (!Dom
.isAncestor(oEl
, oUL
)) {
3470 this.appendToBody(oUL
);
3475 oGroupTitle
= this._aGroupTitleElements
[i
];
3479 if (!Dom
.isAncestor(oEl
, oGroupTitle
)) {
3481 oUL
.parentNode
.insertBefore(oGroupTitle
, oUL
);
3486 Dom
.addClass(oUL
, "hastitle");
3495 while(i
< nListElements
);
3504 * @description "render" event handler for the menu.
3506 * @param {String} p_sType String representing the name of the event that
3508 * @param {Array} p_aArgs Array of arguments sent when the event was fired.
3510 _onRender: function (p_sType
, p_aArgs
) {
3512 if (this.cfg
.getProperty("position") == "dynamic" &&
3513 !this.cfg
.getProperty("width")) {
3523 * @method _onBeforeShow
3524 * @description "beforeshow" event handler for the menu.
3526 * @param {String} p_sType String representing the name of the event that
3528 * @param {Array} p_aArgs Array of arguments sent when the event was fired.
3530 _onBeforeShow: function (p_sType
, p_aArgs
) {
3541 if (this.lazyLoad
&& this.getItemGroups().length
=== 0) {
3543 if (this.srcElement
) {
3545 this._initSubTree();
3550 if (this.itemData
) {
3552 if (this.parent
&& this.parent
.parent
&&
3553 this.parent
.parent
.srcElement
&&
3554 this.parent
.parent
.srcElement
.tagName
.toUpperCase() ==
3557 nOptions
= this.itemData
.length
;
3559 for(n
=0; n
<nOptions
; n
++) {
3561 if (this.itemData
[n
].tagName
) {
3563 this.addItem((new this.ITEM_TYPE(this.itemData
[n
])));
3572 this.addItems(this.itemData
);
3579 oSrcElement
= this.srcElement
;
3583 if (oSrcElement
.tagName
.toUpperCase() == "SELECT") {
3585 if (Dom
.inDocument(oSrcElement
)) {
3587 this.render(oSrcElement
.parentNode
);
3592 this.render(this.cfg
.getProperty("container"));
3608 this.render(this.parent
.element
);
3613 this.render(this.cfg
.getProperty("container"));
3614 this.cfg
.refireEvent("xy");
3623 if (!(this instanceof YAHOO
.widget
.MenuBar
) &&
3624 this.cfg
.getProperty("position") == "dynamic") {
3626 nViewportHeight
= Dom
.getViewportHeight();
3629 if (this.parent
&& this.parent
.parent
instanceof YAHOO
.widget
.MenuBar
) {
3631 oRegion
= YAHOO
.util
.Region
.getRegion(this.parent
.element
);
3633 nViewportHeight
= (nViewportHeight
- oRegion
.bottom
);
3638 if (this.element
.offsetHeight
>= nViewportHeight
) {
3640 nMaxHeight
= this.cfg
.getProperty("maxheight");
3643 Cache the original value for the "maxheight" configuration
3644 property so that we can set it back when the menu is hidden.
3647 this._nMaxHeight
= nMaxHeight
;
3649 this.cfg
.setProperty("maxheight", (nViewportHeight
- 20));
3654 if (this.cfg
.getProperty("maxheight") > 0) {
3658 if (oBody
.scrollTop
> 0) {
3660 oBody
.scrollTop
= 0;
3664 this._disableScrollHeader();
3665 this._enableScrollFooter();
3677 * @description "show" event handler for the menu.
3679 * @param {String} p_sType String representing the name of the event that
3681 * @param {Array} p_aArgs Array of arguments sent when the event was fired.
3683 _onShow: function (p_sType
, p_aArgs
) {
3685 var oParent
= this.parent
,
3691 function disableAutoSubmenuDisplay(p_oEvent
) {
3695 if (p_oEvent
.type
== "mousedown" || (p_oEvent
.type
== "keydown" &&
3696 p_oEvent
.keyCode
== 27)) {
3699 Set the "autosubmenudisplay" to "false" if the user
3700 clicks outside the menu bar.
3703 oTarget
= Event
.getTarget(p_oEvent
);
3705 if (oTarget
!= oParentMenu
.element
||
3706 !Dom
.isAncestor(oParentMenu
.element
, oTarget
)) {
3708 oParentMenu
.cfg
.setProperty("autosubmenudisplay", false);
3710 Event
.removeListener(document
, "mousedown",
3711 disableAutoSubmenuDisplay
);
3713 Event
.removeListener(document
, "keydown",
3714 disableAutoSubmenuDisplay
);
3725 oParentMenu
= oParent
.parent
;
3726 aParentAlignment
= oParentMenu
.cfg
.getProperty("submenualignment");
3727 aAlignment
= this.cfg
.getProperty("submenualignment");
3730 if ((aParentAlignment
[0] != aAlignment
[0]) &&
3731 (aParentAlignment
[1] != aAlignment
[1])) {
3733 this.cfg
.setProperty("submenualignment",
3734 [aParentAlignment
[0], aParentAlignment
[1]]);
3739 if (!oParentMenu
.cfg
.getProperty("autosubmenudisplay") &&
3740 (oParentMenu
instanceof YAHOO
.widget
.MenuBar
||
3741 oParentMenu
.cfg
.getProperty("position") == "static")) {
3743 oParentMenu
.cfg
.setProperty("autosubmenudisplay", true);
3745 Event
.on(document
, "mousedown", disableAutoSubmenuDisplay
);
3746 Event
.on(document
, "keydown", disableAutoSubmenuDisplay
);
3756 * @method _onBeforeHide
3757 * @description "beforehide" event handler for the menu.
3759 * @param {String} p_sType String representing the name of the event that
3761 * @param {Array} p_aArgs Array of arguments sent when the event was fired.
3763 _onBeforeHide: function (p_sType
, p_aArgs
) {
3765 var oActiveItem
= this.activeItem
,
3771 oConfig
= oActiveItem
.cfg
;
3773 oConfig
.setProperty("selected", false);
3775 oSubmenu
= oConfig
.getProperty("submenu");
3785 if (this.getRoot() == this) {
3796 * @description "hide" event handler for the menu.
3798 * @param {String} p_sType String representing the name of the event that
3800 * @param {Array} p_aArgs Array of arguments sent when the event was fired.
3802 _onHide: function (p_sType
, p_aArgs
) {
3804 if (this._nMaxHeight
!= -1) {
3806 this.cfg
.setProperty("maxheight", this._nMaxHeight
);
3808 this._nMaxHeight
= -1;
3816 * @method _onParentMenuConfigChange
3817 * @description "configchange" event handler for a submenu.
3819 * @param {String} p_sType String representing the name of the event that
3821 * @param {Array} p_aArgs Array of arguments sent when the event was fired.
3822 * @param {YAHOO.widget.Menu} p_oSubmenu Object representing the submenu that
3823 * subscribed to the event.
3825 _onParentMenuConfigChange: function (p_sType
, p_aArgs
, p_oSubmenu
) {
3827 var sPropertyName
= p_aArgs
[0][0],
3828 oPropertyValue
= p_aArgs
[0][1];
3830 switch(sPropertyName
) {
3833 case "constraintoviewport":
3836 case "submenuhidedelay":
3841 p_oSubmenu
.cfg
.setProperty(sPropertyName
, oPropertyValue
);
3851 * @method _onParentMenuRender
3852 * @description "render" event handler for a submenu. Renders a
3853 * submenu in response to the firing of its parent's "render" event.
3855 * @param {String} p_sType String representing the name of the event that
3857 * @param {Array} p_aArgs Array of arguments sent when the event was fired.
3858 * @param {YAHOO.widget.Menu} p_oSubmenu Object representing the submenu that
3859 * subscribed to the event.
3861 _onParentMenuRender: function (p_sType
, p_aArgs
, p_oSubmenu
) {
3863 var oParentMenu
= p_oSubmenu
.parent
.parent
,
3867 constraintoviewport
:
3868 oParentMenu
.cfg
.getProperty("constraintoviewport"),
3872 clicktohide
: oParentMenu
.cfg
.getProperty("clicktohide"),
3874 effect
: oParentMenu
.cfg
.getProperty("effect"),
3876 showdelay
: oParentMenu
.cfg
.getProperty("showdelay"),
3878 hidedelay
: oParentMenu
.cfg
.getProperty("hidedelay"),
3880 submenuhidedelay
: oParentMenu
.cfg
.getProperty("submenuhidedelay"),
3882 classname
: oParentMenu
.cfg
.getProperty("classname")
3890 Only sync the "iframe" configuration property if the parent
3891 menu's "position" configuration is the same.
3894 if (this.cfg
.getProperty("position") ==
3895 oParentMenu
.cfg
.getProperty("position")) {
3897 oConfig
.iframe
= oParentMenu
.cfg
.getProperty("iframe");
3902 p_oSubmenu
.cfg
.applyConfig(oConfig
);
3905 if (!this.lazyLoad
) {
3907 oLI
= this.parent
.element
;
3909 if (this.element
.parentNode
== oLI
) {
3926 * @method _onSubmenuBeforeShow
3927 * @description "beforeshow" event handler for a submenu.
3929 * @param {String} p_sType String representing the name of the event that
3931 * @param {Array} p_aArgs Array of arguments sent when the event was fired.
3933 _onSubmenuBeforeShow: function (p_sType
, p_aArgs
) {
3935 var oParent
= this.parent
,
3936 aAlignment
= oParent
.parent
.cfg
.getProperty("submenualignment");
3938 this.cfg
.setProperty("context",
3939 [oParent
.element
, aAlignment
[0], aAlignment
[1]]);
3942 var nScrollTop
= oParent
.parent
.body
.scrollTop
;
3944 if ((YAHOO
.env
.ua
.gecko
|| YAHOO
.env
.ua
.webkit
) && nScrollTop
> 0) {
3946 this.cfg
.setProperty("y", (this.cfg
.getProperty("y") - nScrollTop
));
3954 * @method _onSubmenuShow
3955 * @description "show" event handler for a submenu.
3957 * @param {String} p_sType String representing the name of the event that
3959 * @param {Array} p_aArgs Array of arguments sent when the event was fired.
3961 _onSubmenuShow: function (p_sType
, p_aArgs
) {
3963 this.submenuIndicator
.innerHTML
= this.EXPANDED_SUBMENU_INDICATOR_TEXT
;
3969 * @method _onSubmenuHide
3970 * @description "hide" Custom Event handler for a submenu.
3972 * @param {String} p_sType String representing the name of the event that
3974 * @param {Array} p_aArgs Array of arguments sent when the event was fired.
3976 _onSubmenuHide: function (p_sType
, p_aArgs
) {
3978 this.submenuIndicator
.innerHTML
= this.COLLAPSED_SUBMENU_INDICATOR_TEXT
;
3984 * @method _onMenuItemFocus
3985 * @description "focus" event handler for the menu's items.
3987 * @param {String} p_sType String representing the name of the event that
3989 * @param {Array} p_aArgs Array of arguments sent when the event was fired.
3991 _onMenuItemFocus: function (p_sType
, p_aArgs
) {
3993 this.parent
.focusEvent
.fire(this);
3999 * @method _onMenuItemBlur
4000 * @description "blur" event handler for the menu's items.
4002 * @param {String} p_sType String representing the name of the event
4004 * @param {Array} p_aArgs Array of arguments sent when the event was fired.
4006 _onMenuItemBlur: function (p_sType
, p_aArgs
) {
4008 this.parent
.blurEvent
.fire(this);
4014 * @method _onMenuItemConfigChange
4015 * @description "configchange" event handler for the menu's items.
4017 * @param {String} p_sType String representing the name of the event that
4019 * @param {Array} p_aArgs Array of arguments sent when the event was fired.
4020 * @param {YAHOO.widget.MenuItem} p_oItem Object representing the menu item
4021 * that fired the event.
4023 _onMenuItemConfigChange: function (p_sType
, p_aArgs
, p_oItem
) {
4025 var sPropertyName
= p_aArgs
[0][0],
4026 oPropertyValue
= p_aArgs
[0][1],
4030 switch(sPropertyName
) {
4034 if (oPropertyValue
=== true) {
4036 this.activeItem
= p_oItem
;
4044 oSubmenu
= p_aArgs
[0][1];
4048 this._configureSubmenu(p_oItem
);
4058 A change to an item's "text" or "helptext"
4059 configuration properties requires the width of the parent
4060 menu to be recalculated.
4063 if (this.element
.style
.width
) {
4065 sWidth
= this._getOffsetWidth() + "px";
4067 Dom
.setStyle(this.element
, "width", sWidth
);
4079 // Public event handlers for configuration properties
4083 * @method enforceConstraints
4084 * @description The default event handler executed when the moveEvent is fired,
4085 * if the "constraintoviewport" configuration property is set to true.
4086 * @param {String} type The name of the event that was fired.
4087 * @param {Array} args Collection of arguments sent when the
4089 * @param {Array} obj Array containing the current Menu instance
4090 * and the item that fired the event.
4092 enforceConstraints: function (type
, args
, obj
) {
4094 var oParentMenuItem
= this.parent
,
4115 if (oParentMenuItem
&&
4116 !(oParentMenuItem
.parent
instanceof YAHOO
.widget
.MenuBar
)) {
4118 oElement
= this.element
;
4126 offsetHeight
= oElement
.offsetHeight
;
4127 offsetWidth
= oElement
.offsetWidth
;
4129 viewPortWidth
= Dom
.getViewportWidth();
4130 viewPortHeight
= Dom
.getViewportHeight();
4132 scrollX
= Dom
.getDocumentScrollLeft();
4133 scrollY
= Dom
.getDocumentScrollTop();
4136 (oParentMenuItem
.parent
instanceof YAHOO
.widget
.MenuBar
) ? 0 : 10;
4138 topConstraint
= scrollY
+ nPadding
;
4139 leftConstraint
= scrollX
+ nPadding
;
4141 bottomConstraint
= scrollY
+ viewPortHeight
- offsetHeight
- nPadding
;
4142 rightConstraint
= scrollX
+ viewPortWidth
- offsetWidth
- nPadding
;
4144 aContext
= oConfig
.getProperty("context");
4145 oContextElement
= aContext
? aContext
[0] : null;
4152 } else if ((x
+ offsetWidth
) > viewPortWidth
) {
4154 if (oContextElement
&&
4155 ((x
- oContextElement
.offsetWidth
) > offsetWidth
)) {
4157 x
= (x
- (oContextElement
.offsetWidth
+ offsetWidth
));
4162 x
= rightConstraint
;
4172 } else if (y
> bottomConstraint
) {
4174 if (oContextElement
&& (y
> offsetHeight
)) {
4176 y
= ((y
+ oContextElement
.offsetHeight
) - offsetHeight
);
4181 y
= bottomConstraint
;
4187 oConfig
.setProperty("x", x
, true);
4188 oConfig
.setProperty("y", y
, true);
4189 oConfig
.setProperty("xy", [x
,y
], true);
4192 else if (this == this.getRoot() &&
4193 this.cfg
.getProperty("position") == "dynamic") {
4195 Menu
.superclass
.enforceConstraints
.call(this, type
, args
, obj
);
4203 * @method configVisible
4204 * @description Event handler for when the "visible" configuration property
4206 * @param {String} p_sType String representing the name of the event that
4208 * @param {Array} p_aArgs Array of arguments sent when the event was fired.
4209 * @param {YAHOO.widget.Menu} p_oMenu Object representing the menu that
4212 configVisible: function (p_sType
, p_aArgs
, p_oMenu
) {
4217 if (this.cfg
.getProperty("position") == "dynamic") {
4219 Menu
.superclass
.configVisible
.call(this, p_sType
, p_aArgs
, p_oMenu
);
4224 bVisible
= p_aArgs
[0];
4225 sDisplay
= Dom
.getStyle(this.element
, "display");
4229 if (sDisplay
!= "block") {
4230 this.beforeShowEvent
.fire();
4231 Dom
.setStyle(this.element
, "display", "block");
4232 this.showEvent
.fire();
4238 if (sDisplay
== "block") {
4239 this.beforeHideEvent
.fire();
4240 Dom
.setStyle(this.element
, "display", "none");
4241 this.hideEvent
.fire();
4252 * @method configPosition
4253 * @description Event handler for when the "position" configuration property
4254 * of the menu changes.
4255 * @param {String} p_sType String representing the name of the event that
4257 * @param {Array} p_aArgs Array of arguments sent when the event was fired.
4258 * @param {YAHOO.widget.Menu} p_oMenu Object representing the menu that
4261 configPosition: function (p_sType
, p_aArgs
, p_oMenu
) {
4263 var oElement
= this.element
,
4264 sCSSPosition
= p_aArgs
[0] == "static" ? "static" : "absolute",
4265 sCurrentPosition
= Dom
.getStyle(oElement
, "position"),
4270 Dom
.setStyle(this.element
, "position", sCSSPosition
);
4273 if (sCSSPosition
== "static") {
4276 Remove the iframe for statically positioned menus since it will
4277 intercept mouse events.
4280 oCfg
.setProperty("iframe", false);
4283 // Statically positioned menus are visible by default
4285 Dom
.setStyle(this.element
, "display", "block");
4287 oCfg
.setProperty("visible", true);
4292 if (sCurrentPosition
!= "absolute") {
4294 oCfg
.setProperty("iframe", (YAHOO
.env
.ua
.ie
== 6 ? true : false));
4299 Even though the "visible" property is queued to
4300 "false" by default, we need to set the "visibility" property to
4301 "hidden" since Overlay's "configVisible" implementation checks the
4302 element's "visibility" style property before deciding whether
4303 or not to show an Overlay instance.
4306 Dom
.setStyle(this.element
, "visibility", "hidden");
4311 if (sCSSPosition
== "absolute") {
4313 nZIndex
= oCfg
.getProperty("zindex");
4315 if (!nZIndex
|| nZIndex
=== 0) {
4317 nZIndex
= this.parent
?
4318 (this.parent
.parent
.cfg
.getProperty("zindex") + 1) : 1;
4320 oCfg
.setProperty("zindex", nZIndex
);
4330 * @method configIframe
4331 * @description Event handler for when the "iframe" configuration property of
4333 * @param {String} p_sType String representing the name of the event that
4335 * @param {Array} p_aArgs Array of arguments sent when the event was fired.
4336 * @param {YAHOO.widget.Menu} p_oMenu Object representing the menu that
4339 configIframe: function (p_sType
, p_aArgs
, p_oMenu
) {
4341 if (this.cfg
.getProperty("position") == "dynamic") {
4343 Menu
.superclass
.configIframe
.call(this, p_sType
, p_aArgs
, p_oMenu
);
4351 * @method configHideDelay
4352 * @description Event handler for when the "hidedelay" configuration property
4353 * of the menu changes.
4354 * @param {String} p_sType String representing the name of the event that
4356 * @param {Array} p_aArgs Array of arguments sent when the event was fired.
4357 * @param {YAHOO.widget.Menu} p_oMenu Object representing the menu that
4360 configHideDelay: function (p_sType
, p_aArgs
, p_oMenu
) {
4362 var nHideDelay
= p_aArgs
[0],
4363 oMouseOutEvent
= this.mouseOutEvent
,
4364 oMouseOverEvent
= this.mouseOverEvent
,
4365 oKeyDownEvent
= this.keyDownEvent
;
4367 if (nHideDelay
> 0) {
4370 Only assign event handlers once. This way the user change
4371 the value for the hidedelay as many times as they want.
4374 if (!this._bHideDelayEventHandlersAssigned
) {
4376 oMouseOutEvent
.subscribe(this._execHideDelay
);
4377 oMouseOverEvent
.subscribe(this._cancelHideDelay
);
4378 oKeyDownEvent
.subscribe(this._cancelHideDelay
);
4380 this._bHideDelayEventHandlersAssigned
= true;
4387 oMouseOutEvent
.unsubscribe(this._execHideDelay
);
4388 oMouseOverEvent
.unsubscribe(this._cancelHideDelay
);
4389 oKeyDownEvent
.unsubscribe(this._cancelHideDelay
);
4391 this._bHideDelayEventHandlersAssigned
= false;
4399 * @method configContainer
4400 * @description Event handler for when the "container" configuration property
4401 of the menu changes.
4402 * @param {String} p_sType String representing the name of the event that
4404 * @param {Array} p_aArgs Array of arguments sent when the event was fired.
4405 * @param {YAHOO.widget.Menu} p_oMenu Object representing the menu that
4408 configContainer: function (p_sType
, p_aArgs
, p_oMenu
) {
4410 var oElement
= p_aArgs
[0];
4412 if (typeof oElement
== 'string') {
4414 this.cfg
.setProperty("container", document
.getElementById(oElement
),
4423 * @method _setMaxHeight
4424 * @description "renderEvent" handler used to defer the setting of the
4425 * "maxheight" configuration property until the menu is rendered in lazy
4427 * @param {String} p_sType The name of the event that was fired.
4428 * @param {Array} p_aArgs Collection of arguments sent when the event
4430 * @param {Number} p_nMaxHeight Number representing the value to set for the
4431 * "maxheight" configuration property.
4434 _setMaxHeight: function (p_sType
, p_aArgs
, p_nMaxHeight
) {
4436 this.cfg
.setProperty("maxheight", p_nMaxHeight
);
4437 this.renderEvent
.unsubscribe(this._setMaxHeight
);
4443 * @method configMaxHeight
4444 * @description Event handler for when the "maxheight" configuration property of
4446 * @param {String} p_sType The name of the event that was fired.
4447 * @param {Array} p_aArgs Collection of arguments sent when the event
4449 * @param {YAHOO.widget.Menu} p_oMenu The Menu instance fired
4452 configMaxHeight: function (p_sType
, p_aArgs
, p_oMenu
) {
4454 var nMaxHeight
= p_aArgs
[0],
4456 oHeader
= this.header
,
4457 oFooter
= this.footer
,
4458 fnMouseOver
= this._onScrollTargetMouseOver
,
4459 fnMouseOut
= this._onScrollTargetMouseOut
,
4463 if (this.lazyLoad
&& !oBody
) {
4465 this.renderEvent
.unsubscribe(this._setMaxHeight
);
4467 if (nMaxHeight
> 0) {
4469 this.renderEvent
.subscribe(this._setMaxHeight
, nMaxHeight
, this);
4477 Dom
.setStyle(oBody
, "height", "auto");
4478 Dom
.setStyle(oBody
, "overflow", "visible");
4481 if ((nMaxHeight
> 0) && (oBody
.offsetHeight
> nMaxHeight
)) {
4483 if (!this.cfg
.getProperty("width")) {
4489 if (!oHeader
&& !oFooter
) {
4491 this.setHeader(" ");
4492 this.setFooter(" ");
4494 oHeader
= this.header
;
4495 oFooter
= this.footer
;
4497 Dom
.addClass(oHeader
, "topscrollbar");
4498 Dom
.addClass(oFooter
, "bottomscrollbar");
4500 this.element
.insertBefore(oHeader
, oBody
);
4501 this.element
.appendChild(oFooter
);
4503 Event
.on(oHeader
, "mouseover", fnMouseOver
, this, true);
4504 Event
.on(oHeader
, "mouseout", fnMouseOut
, this, true);
4505 Event
.on(oFooter
, "mouseover", fnMouseOver
, this, true);
4506 Event
.on(oFooter
, "mouseout", fnMouseOut
, this, true);
4510 nHeight
= (nMaxHeight
- (this.footer
.offsetHeight
+
4511 this.header
.offsetHeight
));
4513 Dom
.setStyle(oBody
, "height", (nHeight
+ "px"));
4514 Dom
.setStyle(oBody
, "overflow", "hidden");
4517 else if (oHeader
&& oFooter
) {
4519 Dom
.setStyle(oBody
, "height", "auto");
4520 Dom
.setStyle(oBody
, "overflow", "visible");
4522 Event
.removeListener(oHeader
, "mouseover", fnMouseOver
);
4523 Event
.removeListener(oHeader
, "mouseout", fnMouseOut
);
4524 Event
.removeListener(oFooter
, "mouseover", fnMouseOver
);
4525 Event
.removeListener(oFooter
, "mouseout", fnMouseOut
);
4527 this.element
.removeChild(oHeader
);
4528 this.element
.removeChild(oFooter
);
4535 this.cfg
.refireEvent("iframe");
4541 * @method configClassName
4542 * @description Event handler for when the "classname" configuration property of
4544 * @param {String} p_sType The name of the event that was fired.
4545 * @param {Array} p_aArgs Collection of arguments sent when the event was fired.
4546 * @param {YAHOO.widget.Menu} p_oMenu The Menu instance fired the event.
4548 configClassName: function (p_sType
, p_aArgs
, p_oMenu
) {
4550 var sClassName
= p_aArgs
[0];
4552 if (this._sClassName
) {
4554 Dom
.removeClass(this.element
, this._sClassName
);
4558 Dom
.addClass(this.element
, sClassName
);
4559 this._sClassName
= sClassName
;
4565 * @method _onItemAdded
4566 * @description "itemadded" event handler for a Menu instance.
4568 * @param {String} p_sType The name of the event that was fired.
4569 * @param {Array} p_aArgs Collection of arguments sent when the event
4572 _onItemAdded: function (p_sType
, p_aArgs
) {
4574 var oItem
= p_aArgs
[0];
4578 oItem
.cfg
.setProperty("disabled", true);
4586 * @method configDisabled
4587 * @description Event handler for when the "disabled" configuration property of
4589 * @param {String} p_sType The name of the event that was fired.
4590 * @param {Array} p_aArgs Collection of arguments sent when the event was fired.
4591 * @param {YAHOO.widget.Menu} p_oMenu The Menu instance fired the event.
4593 configDisabled: function (p_sType
, p_aArgs
, p_oMenu
) {
4595 var bDisabled
= p_aArgs
[0],
4600 if (this._bDisabled
!= bDisabled
) {
4602 aItems
= this.getItems();
4603 nItems
= aItems
.length
;
4611 aItems
[i
].cfg
.setProperty("disabled", bDisabled
);
4618 Dom
[(bDisabled
? "addClass" : "removeClass")](this.element
, "disabled");
4620 this.itemAddedEvent
[(bDisabled
? "subscribe" : "unsubscribe")](
4623 this._bDisabled
= bDisabled
;
4632 * @description "render" event handler for the menu.
4633 * @param {String} p_sType String representing the name of the event that
4635 * @param {Array} p_aArgs Array of arguments sent when the event was fired.
4637 onRender: function (p_sType
, p_aArgs
) {
4639 function sizeShadow() {
4641 var oElement
= this.element
,
4642 oShadow
= this._shadow
;
4646 oShadow
.style
.width
= (oElement
.offsetWidth
+ 6) + "px";
4647 oShadow
.style
.height
= (oElement
.offsetHeight
+ 1) + "px";
4654 function addShadowVisibleClass() {
4656 Dom
.addClass(this._shadow
, "yui-menu-shadow-visible");
4661 function removeShadowVisibleClass() {
4663 Dom
.removeClass(this._shadow
, "yui-menu-shadow-visible");
4668 function createShadow() {
4670 var oShadow
= this._shadow
,
4676 oElement
= this.element
;
4679 if (!m_oShadowTemplate
) {
4681 m_oShadowTemplate
= document
.createElement("div");
4682 m_oShadowTemplate
.className
= "yui-menu-shadow";
4686 oShadow
= m_oShadowTemplate
.cloneNode(false);
4688 oElement
.appendChild(oShadow
);
4690 this._shadow
= oShadow
;
4692 addShadowVisibleClass
.call(this);
4694 this.beforeShowEvent
.subscribe(addShadowVisibleClass
);
4695 this.beforeHideEvent
.subscribe(removeShadowVisibleClass
);
4697 if (YAHOO
.env
.ua
.ie
) {
4700 Need to call sizeShadow & syncIframe via setTimeout for
4701 IE 7 Quirks Mode and IE 6 Standards Mode and Quirks Mode
4702 or the shadow and iframe shim will not be sized and
4703 positioned properly.
4706 window
.setTimeout(function () {
4708 sizeShadow
.call(me
);
4713 this.cfg
.subscribeToConfigEvent("width", sizeShadow
);
4714 this.cfg
.subscribeToConfigEvent("height", sizeShadow
);
4715 this.changeContentEvent
.subscribe(sizeShadow
);
4717 Module
.textResizeEvent
.subscribe(sizeShadow
, me
, true);
4719 this.destroyEvent
.subscribe(function () {
4721 Module
.textResizeEvent
.unsubscribe(sizeShadow
, me
);
4732 function onBeforeShow() {
4734 createShadow
.call(this);
4736 this.beforeShowEvent
.unsubscribe(onBeforeShow
);
4741 if (this.cfg
.getProperty("position") == "dynamic") {
4743 if (this.cfg
.getProperty("visible")) {
4745 createShadow
.call(this);
4750 this.beforeShowEvent
.subscribe(onBeforeShow
);
4763 * @method initEvents
4764 * @description Initializes the custom events for the menu.
4766 initEvents: function () {
4768 Menu
.superclass
.initEvents
.call(this);
4770 // Create custom events
4772 var SIGNATURE
= CustomEvent
.LIST
;
4774 this.mouseOverEvent
= this.createEvent(EVENT_TYPES
.MOUSE_OVER
);
4775 this.mouseOverEvent
.signature
= SIGNATURE
;
4777 this.mouseOutEvent
= this.createEvent(EVENT_TYPES
.MOUSE_OUT
);
4778 this.mouseOutEvent
.signature
= SIGNATURE
;
4780 this.mouseDownEvent
= this.createEvent(EVENT_TYPES
.MOUSE_DOWN
);
4781 this.mouseDownEvent
.signature
= SIGNATURE
;
4783 this.mouseUpEvent
= this.createEvent(EVENT_TYPES
.MOUSE_UP
);
4784 this.mouseUpEvent
.signature
= SIGNATURE
;
4786 this.clickEvent
= this.createEvent(EVENT_TYPES
.CLICK
);
4787 this.clickEvent
.signature
= SIGNATURE
;
4789 this.keyPressEvent
= this.createEvent(EVENT_TYPES
.KEY_PRESS
);
4790 this.keyPressEvent
.signature
= SIGNATURE
;
4792 this.keyDownEvent
= this.createEvent(EVENT_TYPES
.KEY_DOWN
);
4793 this.keyDownEvent
.signature
= SIGNATURE
;
4795 this.keyUpEvent
= this.createEvent(EVENT_TYPES
.KEY_UP
);
4796 this.keyUpEvent
.signature
= SIGNATURE
;
4798 this.focusEvent
= this.createEvent(EVENT_TYPES
.FOCUS
);
4799 this.focusEvent
.signature
= SIGNATURE
;
4801 this.blurEvent
= this.createEvent(EVENT_TYPES
.BLUR
);
4802 this.blurEvent
.signature
= SIGNATURE
;
4804 this.itemAddedEvent
= this.createEvent(EVENT_TYPES
.ITEM_ADDED
);
4805 this.itemAddedEvent
.signature
= SIGNATURE
;
4807 this.itemRemovedEvent
= this.createEvent(EVENT_TYPES
.ITEM_REMOVED
);
4808 this.itemRemovedEvent
.signature
= SIGNATURE
;
4815 * @description Finds the menu's root menu.
4817 getRoot: function () {
4819 var oItem
= this.parent
,
4824 oParentMenu
= oItem
.parent
;
4826 return oParentMenu
? oParentMenu
.getRoot() : this;
4840 * @description Returns a string representing the menu.
4843 toString: function () {
4845 var sReturnVal
= "Menu",
4850 sReturnVal
+= (" " + sId
);
4860 * @method setItemGroupTitle
4861 * @description Sets the title of a group of menu items.
4862 * @param {String} p_sGroupTitle String specifying the title of the group.
4863 * @param {Number} p_nGroupIndex Optional. Number specifying the group to which
4864 * the title belongs.
4866 setItemGroupTitle: function (p_sGroupTitle
, p_nGroupIndex
) {
4873 if (typeof p_sGroupTitle
== "string" && p_sGroupTitle
.length
> 0) {
4875 nGroupIndex
= typeof p_nGroupIndex
== "number" ? p_nGroupIndex
: 0;
4876 oTitle
= this._aGroupTitleElements
[nGroupIndex
];
4881 oTitle
.innerHTML
= p_sGroupTitle
;
4886 oTitle
= document
.createElement(this.GROUP_TITLE_TAG_NAME
);
4888 oTitle
.innerHTML
= p_sGroupTitle
;
4890 this._aGroupTitleElements
[nGroupIndex
] = oTitle
;
4895 i
= this._aGroupTitleElements
.length
- 1;
4899 if (this._aGroupTitleElements
[i
]) {
4901 Dom
.removeClass(this._aGroupTitleElements
[i
], "first-of-type");
4911 if (nFirstIndex
!== null) {
4913 Dom
.addClass(this._aGroupTitleElements
[nFirstIndex
],
4918 this.changeContentEvent
.fire();
4928 * @description Appends an item to the menu.
4929 * @param {YAHOO.widget.MenuItem} p_oItem Object reference for the MenuItem
4930 * instance to be added to the menu.
4931 * @param {String} p_oItem String specifying the text of the item to be added
4933 * @param {Object} p_oItem Object literal containing a set of menu item
4934 * configuration properties.
4935 * @param {Number} p_nGroupIndex Optional. Number indicating the group to
4936 * which the item belongs.
4937 * @return {YAHOO.widget.MenuItem}
4939 addItem: function (p_oItem
, p_nGroupIndex
) {
4943 return this._addItemToGroup(p_nGroupIndex
, p_oItem
);
4952 * @description Adds an array of items to the menu.
4953 * @param {Array} p_aItems Array of items to be added to the menu. The array
4954 * can contain strings specifying the text for each item to be created, object
4955 * literals specifying each of the menu item configuration properties,
4956 * or MenuItem instances.
4957 * @param {Number} p_nGroupIndex Optional. Number specifying the group to
4958 * which the items belongs.
4961 addItems: function (p_aItems
, p_nGroupIndex
) {
4968 if (Lang
.isArray(p_aItems
)) {
4970 nItems
= p_aItems
.length
;
4973 for(i
=0; i
<nItems
; i
++) {
4975 oItem
= p_aItems
[i
];
4979 if (Lang
.isArray(oItem
)) {
4981 aItems
[aItems
.length
] = this.addItems(oItem
, i
);
4986 aItems
[aItems
.length
] =
4987 this._addItemToGroup(p_nGroupIndex
, oItem
);
4996 if (aItems
.length
) {
5008 * @method insertItem
5009 * @description Inserts an item into the menu at the specified index.
5010 * @param {YAHOO.widget.MenuItem} p_oItem Object reference for the MenuItem
5011 * instance to be added to the menu.
5012 * @param {String} p_oItem String specifying the text of the item to be added
5014 * @param {Object} p_oItem Object literal containing a set of menu item
5015 * configuration properties.
5016 * @param {Number} p_nItemIndex Number indicating the ordinal position at which
5017 * the item should be added.
5018 * @param {Number} p_nGroupIndex Optional. Number indicating the group to which
5020 * @return {YAHOO.widget.MenuItem}
5022 insertItem: function (p_oItem
, p_nItemIndex
, p_nGroupIndex
) {
5026 return this._addItemToGroup(p_nGroupIndex
, p_oItem
, p_nItemIndex
);
5034 * @method removeItem
5035 * @description Removes the specified item from the menu.
5036 * @param {YAHOO.widget.MenuItem} p_oObject Object reference for the MenuItem
5037 * instance to be removed from the menu.
5038 * @param {Number} p_oObject Number specifying the index of the item
5040 * @param {Number} p_nGroupIndex Optional. Number specifying the group to
5041 * which the item belongs.
5042 * @return {YAHOO.widget.MenuItem}
5044 removeItem: function (p_oObject
, p_nGroupIndex
) {
5048 if (typeof p_oObject
!= "undefined") {
5050 if (p_oObject
instanceof YAHOO
.widget
.MenuItem
) {
5052 oItem
= this._removeItemFromGroupByValue(p_nGroupIndex
, p_oObject
);
5055 else if (typeof p_oObject
== "number") {
5057 oItem
= this._removeItemFromGroupByIndex(p_nGroupIndex
, p_oObject
);
5065 this.logger
.log("Item removed." +
5066 " Text: " + oItem
.cfg
.getProperty("text") + ", " +
5067 " Index: " + oItem
.index
+ ", " +
5068 " Group Index: " + oItem
.groupIndex
);
5081 * @description Returns an array of all of the items in the menu.
5084 getItems: function () {
5086 var aGroups
= this._aItemGroups
,
5087 nGroups
= aGroups
.length
;
5089 return ((nGroups
== 1) ? aGroups
[0] :
5090 (Array
.prototype.concat
.apply([], aGroups
)));
5096 * @method getItemGroups
5097 * @description Multi-dimensional Array representing the menu items as they
5098 * are grouped in the menu.
5101 getItemGroups: function () {
5103 return this._aItemGroups
;
5110 * @description Returns the item at the specified index.
5111 * @param {Number} p_nItemIndex Number indicating the ordinal position of the
5112 * item to be retrieved.
5113 * @param {Number} p_nGroupIndex Optional. Number indicating the group to which
5115 * @return {YAHOO.widget.MenuItem}
5117 getItem: function (p_nItemIndex
, p_nGroupIndex
) {
5121 if (typeof p_nItemIndex
== "number") {
5123 aGroup
= this._getItemGroup(p_nGroupIndex
);
5127 return aGroup
[p_nItemIndex
];
5137 * @method getSubmenus
5138 * @description Returns an array of all of the submenus that are immediate
5139 * children of the menu.
5142 getSubmenus: function () {
5144 var aItems
= this.getItems(),
5145 nItems
= aItems
.length
,
5156 for(i
=0; i
<nItems
; i
++) {
5162 oSubmenu
= oItem
.cfg
.getProperty("submenu");
5166 aSubmenus
[aSubmenus
.length
] = oSubmenu
;
5181 * @method clearContent
5182 * @description Removes all of the content from the menu, including the menu
5183 * items, group titles, header and footer.
5185 clearContent: function () {
5187 var aItems
= this.getItems(),
5188 nItems
= aItems
.length
,
5189 oElement
= this.element
,
5191 oHeader
= this.header
,
5192 oFooter
= this.footer
,
5208 oSubmenu
= oItem
.cfg
.getProperty("submenu");
5212 this.cfg
.configChangedEvent
.unsubscribe(
5213 this._onParentMenuConfigChange
, oSubmenu
);
5215 this.renderEvent
.unsubscribe(this._onParentMenuRender
,
5220 this.removeItem(oItem
);
5232 Event
.purgeElement(oHeader
);
5233 oElement
.removeChild(oHeader
);
5240 Event
.purgeElement(oFooter
);
5241 oElement
.removeChild(oFooter
);
5247 Event
.purgeElement(oBody
);
5249 oBody
.innerHTML
= "";
5254 this._aItemGroups
= [];
5255 this._aListElements
= [];
5256 this._aGroupTitleElements
= [];
5258 this.cfg
.setProperty("width", null);
5265 * @description Removes the menu's <code><div></code> element
5266 * (and accompanying child nodes) from the document.
5268 destroy: function () {
5270 Module
.textResizeEvent
.unsubscribe(this._onTextResize
, this);
5275 this.clearContent();
5277 this._aItemGroups
= null;
5278 this._aListElements
= null;
5279 this._aGroupTitleElements
= null;
5282 // Continue with the superclass implementation of this method
5284 Menu
.superclass
.destroy
.call(this);
5286 this.logger
.log("Destroyed.");
5292 * @method setInitialFocus
5293 * @description Sets focus to the menu's first enabled item.
5295 setInitialFocus: function () {
5297 var oItem
= this._getFirstEnabledItem();
5309 * @method setInitialSelection
5310 * @description Sets the "selected" configuration property of the menu's first
5311 * enabled item to "true."
5313 setInitialSelection: function () {
5315 var oItem
= this._getFirstEnabledItem();
5319 oItem
.cfg
.setProperty("selected", true);
5326 * @method clearActiveItem
5327 * @description Sets the "selected" configuration property of the menu's active
5328 * item to "false" and hides the item's submenu.
5329 * @param {Boolean} p_bBlur Boolean indicating if the menu's active item
5330 * should be blurred.
5332 clearActiveItem: function (p_bBlur
) {
5334 if (this.cfg
.getProperty("showdelay") > 0) {
5336 this._cancelShowDelay();
5341 var oActiveItem
= this.activeItem
,
5347 oConfig
= oActiveItem
.cfg
;
5355 oConfig
.setProperty("selected", false);
5357 oSubmenu
= oConfig
.getProperty("submenu");
5365 this.activeItem
= null;
5374 * @description Causes the menu to receive focus and fires the "focus" event.
5376 focus: function () {
5378 if (!this.hasFocus()) {
5380 this.setInitialFocus();
5389 * @description Causes the menu to lose focus and fires the "blur" event.
5395 if (this.hasFocus()) {
5397 oItem
= MenuManager
.getFocusedMenuItem();
5412 * @description Returns a boolean indicating whether or not the menu has focus.
5415 hasFocus: function () {
5417 return (MenuManager
.getFocusedMenu() == this.getRoot());
5423 * Adds the specified CustomEvent subscriber to the menu and each of
5426 * @param p_type {string} the type, or name of the event
5427 * @param p_fn {function} the function to exectute when the event fires
5428 * @param p_obj {Object} An object to be passed along when the event
5430 * @param p_override {boolean} If true, the obj passed in becomes the
5431 * execution scope of the listener
5433 subscribe: function () {
5435 function onItemAdded(p_sType
, p_aArgs
, p_oObject
) {
5437 var oItem
= p_aArgs
[0],
5438 oSubmenu
= oItem
.cfg
.getProperty("submenu");
5442 oSubmenu
.subscribe
.apply(oSubmenu
, p_oObject
);
5449 Menu
.superclass
.subscribe
.apply(this, arguments
);
5450 Menu
.superclass
.subscribe
.call(this, "itemAdded", onItemAdded
, arguments
);
5453 var aSubmenus
= this.getSubmenus(),
5460 nSubmenus
= aSubmenus
.length
;
5462 if (nSubmenus
> 0) {
5468 oSubmenu
= aSubmenus
[i
];
5470 oSubmenu
.subscribe
.apply(oSubmenu
, arguments
);
5483 * @description Initializes the class's configurable properties which can be
5484 * changed using the menu's Config object ("cfg").
5485 * @method initDefaultConfig
5487 initDefaultConfig: function () {
5489 Menu
.superclass
.initDefaultConfig
.call(this);
5491 var oConfig
= this.cfg
;
5493 // Add configuration attributes
5496 Change the default value for the "visible" configuration
5497 property to "false" by re-adding the property.
5502 * @description Boolean indicating whether or not the menu is visible. If
5503 * the menu's "position" configuration property is set to "dynamic" (the
5504 * default), this property toggles the menu's <code><div></code>
5505 * element's "visibility" style property between "visible" (true) or
5506 * "hidden" (false). If the menu's "position" configuration property is
5507 * set to "static" this property toggles the menu's
5508 * <code><div></code> element's "display" style property
5509 * between "block" (true) or "none" (false).
5513 oConfig
.addProperty(
5514 DEFAULT_CONFIG
.VISIBLE
.key
,
5516 handler
: this.configVisible
,
5517 value
: DEFAULT_CONFIG
.VISIBLE
.value
,
5518 validator
: DEFAULT_CONFIG
.VISIBLE
.validator
5524 Change the default value for the "constraintoviewport" configuration
5525 property to "true" by re-adding the property.
5529 * @config constraintoviewport
5530 * @description Boolean indicating if the menu will try to remain inside
5531 * the boundaries of the size of viewport.
5535 oConfig
.addProperty(
5536 DEFAULT_CONFIG
.CONSTRAIN_TO_VIEWPORT
.key
,
5538 handler
: this.configConstrainToViewport
,
5539 value
: DEFAULT_CONFIG
.CONSTRAIN_TO_VIEWPORT
.value
,
5540 validator
: DEFAULT_CONFIG
.CONSTRAIN_TO_VIEWPORT
.validator
,
5541 supercedes
: DEFAULT_CONFIG
.CONSTRAIN_TO_VIEWPORT
.supercedes
5548 * @description String indicating how a menu should be positioned on the
5549 * screen. Possible values are "static" and "dynamic." Static menus are
5550 * visible by default and reside in the normal flow of the document
5551 * (CSS position: static). Dynamic menus are hidden by default, reside
5552 * out of the normal flow of the document (CSS position: absolute), and
5553 * can overlay other elements on the screen.
5557 oConfig
.addProperty(
5558 DEFAULT_CONFIG
.POSITION
.key
,
5560 handler
: this.configPosition
,
5561 value
: DEFAULT_CONFIG
.POSITION
.value
,
5562 validator
: DEFAULT_CONFIG
.POSITION
.validator
,
5563 supercedes
: DEFAULT_CONFIG
.POSITION
.supercedes
5569 * @config submenualignment
5570 * @description Array defining how submenus should be aligned to their
5571 * parent menu item. The format is: [itemCorner, submenuCorner]. By default
5572 * a submenu's top left corner is aligned to its parent menu item's top
5574 * @default ["tl","tr"]
5577 oConfig
.addProperty(
5578 DEFAULT_CONFIG
.SUBMENU_ALIGNMENT
.key
,
5580 value
: DEFAULT_CONFIG
.SUBMENU_ALIGNMENT
.value
5586 * @config autosubmenudisplay
5587 * @description Boolean indicating if submenus are automatically made
5588 * visible when the user mouses over the menu's items.
5592 oConfig
.addProperty(
5593 DEFAULT_CONFIG
.AUTO_SUBMENU_DISPLAY
.key
,
5595 value
: DEFAULT_CONFIG
.AUTO_SUBMENU_DISPLAY
.value
,
5596 validator
: DEFAULT_CONFIG
.AUTO_SUBMENU_DISPLAY
.validator
5603 * @description Number indicating the time (in milliseconds) that should
5604 * expire before a submenu is made visible when the user mouses over
5609 oConfig
.addProperty(
5610 DEFAULT_CONFIG
.SHOW_DELAY
.key
,
5612 value
: DEFAULT_CONFIG
.SHOW_DELAY
.value
,
5613 validator
: DEFAULT_CONFIG
.SHOW_DELAY
.validator
5620 * @description Number indicating the time (in milliseconds) that should
5621 * expire before the menu is hidden.
5625 oConfig
.addProperty(
5626 DEFAULT_CONFIG
.HIDE_DELAY
.key
,
5628 handler
: this.configHideDelay
,
5629 value
: DEFAULT_CONFIG
.HIDE_DELAY
.value
,
5630 validator
: DEFAULT_CONFIG
.HIDE_DELAY
.validator
,
5631 suppressEvent
: DEFAULT_CONFIG
.HIDE_DELAY
.suppressEvent
5637 * @config submenuhidedelay
5638 * @description Number indicating the time (in milliseconds) that should
5639 * expire before a submenu is hidden when the user mouses out of a menu item
5640 * heading in the direction of a submenu. The value must be greater than or
5641 * equal to the value specified for the "showdelay" configuration property.
5645 oConfig
.addProperty(
5646 DEFAULT_CONFIG
.SUBMENU_HIDE_DELAY
.key
,
5648 value
: DEFAULT_CONFIG
.SUBMENU_HIDE_DELAY
.value
,
5649 validator
: DEFAULT_CONFIG
.SUBMENU_HIDE_DELAY
.validator
5655 * @config clicktohide
5656 * @description Boolean indicating if the menu will automatically be
5657 * hidden if the user clicks outside of it.
5661 oConfig
.addProperty(
5662 DEFAULT_CONFIG
.CLICK_TO_HIDE
.key
,
5664 value
: DEFAULT_CONFIG
.CLICK_TO_HIDE
.value
,
5665 validator
: DEFAULT_CONFIG
.CLICK_TO_HIDE
.validator
5672 * @description HTML element reference or string specifying the id
5673 * attribute of the HTML element that the menu's markup should be
5675 * @type <a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/
5676 * level-one-html.html#ID-58190037">HTMLElement</a>|String
5677 * @default document.body
5679 oConfig
.addProperty(
5680 DEFAULT_CONFIG
.CONTAINER
.key
,
5682 handler
: this.configContainer
,
5683 value
: document
.body
5690 * @description Defines the maximum height (in pixels) for a menu before the
5691 * contents of the body are scrolled.
5695 oConfig
.addProperty(
5696 DEFAULT_CONFIG
.MAX_HEIGHT
.key
,
5698 handler
: this.configMaxHeight
,
5699 value
: DEFAULT_CONFIG
.MAX_HEIGHT
.value
,
5700 validator
: DEFAULT_CONFIG
.MAX_HEIGHT
.validator
5707 * @description CSS class to be applied to the menu's root
5708 * <code><div></code> element. The specified class(es) are
5709 * appended in addition to the default class as specified by the menu's
5710 * CSS_CLASS_NAME constant.
5714 oConfig
.addProperty(
5715 DEFAULT_CONFIG
.CLASS_NAME
.key
,
5717 handler
: this.configClassName
,
5718 value
: DEFAULT_CONFIG
.CLASS_NAME
.value
,
5719 validator
: DEFAULT_CONFIG
.CLASS_NAME
.validator
5726 * @description Boolean indicating if the menu should be disabled.
5727 * Disabling a menu disables each of its items. (Disabled menu items are
5728 * dimmed and will not respond to user input or fire events.) Disabled
5729 * menus have a corresponding "disabled" CSS class applied to their root
5730 * <code><div></code> element.
5734 oConfig
.addProperty(
5735 DEFAULT_CONFIG
.DISABLED
.key
,
5737 handler
: this.configDisabled
,
5738 value
: DEFAULT_CONFIG
.DISABLED
.value
,
5739 validator
: DEFAULT_CONFIG
.DISABLED
.validator
5745 }); // END YAHOO.lang.extend
5755 * Creates an item for a menu.
5757 * @param {String} p_oObject String specifying the text of the menu item.
5758 * @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-
5759 * one-html.html#ID-74680021">HTMLLIElement</a>} p_oObject Object specifying
5760 * the <code><li></code> element of the menu item.
5761 * @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-
5762 * one-html.html#ID-38450247">HTMLOptGroupElement</a>} p_oObject Object
5763 * specifying the <code><optgroup></code> element of the menu item.
5764 * @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-
5765 * one-html.html#ID-70901257">HTMLOptionElement</a>} p_oObject Object
5766 * specifying the <code><option></code> element of the menu item.
5767 * @param {Object} p_oConfig Optional. Object literal specifying the
5768 * configuration for the menu item. See configuration class documentation
5773 YAHOO
.widget
.MenuItem = function(p_oObject
, p_oConfig
) {
5779 this.parent
= p_oConfig
.parent
;
5780 this.value
= p_oConfig
.value
;
5781 this.id
= p_oConfig
.id
;
5785 this.init(p_oObject
, p_oConfig
);
5791 var Dom
= YAHOO
.util
.Dom
,
5792 Module
= YAHOO
.widget
.Module
,
5793 Menu
= YAHOO
.widget
.Menu
,
5794 MenuItem
= YAHOO
.widget
.MenuItem
,
5795 CustomEvent
= YAHOO
.util
.CustomEvent
,
5798 m_oMenuItemTemplate
,
5801 * Constant representing the name of the MenuItem's events
5802 * @property EVENT_TYPES
5809 "MOUSE_OVER": "mouseover",
5810 "MOUSE_OUT": "mouseout",
5811 "MOUSE_DOWN": "mousedown",
5812 "MOUSE_UP": "mouseup",
5814 "KEY_PRESS": "keypress",
5815 "KEY_DOWN": "keydown",
5817 "ITEM_ADDED": "itemAdded",
5818 "ITEM_REMOVED": "itemRemoved",
5821 "DESTROY": "destroy"
5826 * Constant representing the MenuItem's configuration properties
5827 * @property DEFAULT_CONFIG
5837 validator
: Lang
.isString
,
5843 supercedes
: ["text"]
5860 validator
: Lang
.isBoolean
,
5861 suppressEvent
: true,
5862 supercedes
: ["text"]
5865 "STRONG_EMPHASIS": {
5866 key
: "strongemphasis",
5868 validator
: Lang
.isBoolean
,
5869 suppressEvent
: true,
5870 supercedes
: ["text"]
5876 validator
: Lang
.isBoolean
,
5877 suppressEvent
: true,
5878 supercedes
: ["text"]
5884 validator
: Lang
.isBoolean
,
5885 suppressEvent
: true,
5886 supercedes
: ["text"]
5892 validator
: Lang
.isBoolean
,
5898 supercedes
: ["text"]
5908 validator
: Lang
.isString
5914 MenuItem
.prototype = {
5919 * @property COLLAPSED_SUBMENU_INDICATOR_TEXT
5920 * @description String representing the text for the <code><em></code>
5921 * element used for the submenu arrow indicator.
5922 * @default "Submenu collapsed. Click to expand submenu."
5926 COLLAPSED_SUBMENU_INDICATOR_TEXT
:
5927 "Submenu collapsed. Click to expand submenu.",
5931 * @property EXPANDED_SUBMENU_INDICATOR_TEXT
5932 * @description String representing the text for the submenu arrow indicator
5933 * element (<code><em></code>) when the submenu is visible.
5934 * @default "Submenu expanded. Click to collapse submenu."
5938 EXPANDED_SUBMENU_INDICATOR_TEXT
:
5939 "Submenu expanded. Click to collapse submenu.",
5943 * @property DISABLED_SUBMENU_INDICATOR_TEXT
5944 * @description String representing the text for the submenu arrow indicator
5945 * element (<code><em></code>) when the menu item is disabled.
5946 * @default "Submenu collapsed. (Item disabled.)."
5950 DISABLED_SUBMENU_INDICATOR_TEXT
: "Submenu collapsed. (Item disabled.)",
5954 * @property CHECKED_TEXT
5955 * @description String representing the text to be used for the checked
5956 * indicator element (<code><em></code>).
5957 * @default "Checked."
5961 CHECKED_TEXT
: "Menu item checked.",
5965 * @property DISABLED_CHECKED_TEXT
5966 * @description String representing the text to be used for the checked
5967 * indicator element (<code><em></code>) when the menu item
5969 * @default "Checked. (Item disabled.)"
5973 DISABLED_CHECKED_TEXT
: "Checked. (Item disabled.)",
5977 * @property CSS_CLASS_NAME
5978 * @description String representing the CSS class(es) to be applied to the
5979 * <code><li></code> element of the menu item.
5980 * @default "yuimenuitem"
5984 CSS_CLASS_NAME
: "yuimenuitem",
5988 * @property CSS_LABEL_CLASS_NAME
5989 * @description String representing the CSS class(es) to be applied to the
5990 * menu item's <code><a></code> element.
5991 * @default "yuimenuitemlabel"
5995 CSS_LABEL_CLASS_NAME
: "yuimenuitemlabel",
5999 * @property SUBMENU_TYPE
6000 * @description Object representing the type of menu to instantiate and
6001 * add when parsing the child nodes of the menu item's source HTML element.
6003 * @type YAHOO.widget.Menu
6009 // Private member variables
6013 * @property _oAnchor
6014 * @description Object reference to the menu item's
6015 * <code><a></code> element.
6018 * @type <a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-
6019 * one-html.html#ID-48250443">HTMLAnchorElement</a>
6025 * @property _oHelpTextEM
6026 * @description Object reference to the menu item's help text
6027 * <code><em></code> element.
6030 * @type <a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-
6031 * one-html.html#ID-58190037">HTMLElement</a>
6037 * @property _oSubmenu
6038 * @description Object reference to the menu item's submenu.
6041 * @type YAHOO.widget.Menu
6047 * @property _oCheckedIndicator
6048 * @description Object reference to the menu item's checkmark image.
6049 * @default <a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/
6050 * level-one-html.html#ID-58190037">HTMLElement</a>
6052 * @type <a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/
6053 * level-one-html.html#ID-58190037">HTMLElement</a>
6055 _oCheckedIndicator
: null,
6059 * @property _oOnclickAttributeValue
6060 * @description Object reference to the menu item's current value for the
6061 * "onclick" configuration attribute.
6066 _oOnclickAttributeValue
: null,
6070 * @property _sClassName
6071 * @description The current value of the "classname" configuration attribute.
6080 // Public properties
6084 * @property constructor
6085 * @description Object reference to the menu item's constructor function.
6086 * @default YAHOO.widget.MenuItem
6087 * @type YAHOO.widget.MenuItem
6089 constructor: MenuItem
,
6094 * @description Number indicating the ordinal position of the menu item in
6103 * @property groupIndex
6104 * @description Number indicating the index of the group to which the menu
6114 * @description Object reference to the menu item's parent menu.
6116 * @type YAHOO.widget.Menu
6123 * @description Object reference to the menu item's
6124 * <code><li></code> element.
6125 * @default <a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level
6126 * -one-html.html#ID-74680021">HTMLLIElement</a>
6127 * @type <a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-
6128 * one-html.html#ID-74680021">HTMLLIElement</a>
6134 * @property srcElement
6135 * @description Object reference to the HTML element (either
6136 * <code><li></code>, <code><optgroup></code> or
6137 * <code><option></code>) used create the menu item.
6138 * @default <a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/
6139 * level-one-html.html#ID-74680021">HTMLLIElement</a>|<a href="http://www.
6140 * w3.org/TR/2000/WD-DOM-Level-1-20000929/level-one-html.html#ID-38450247"
6141 * >HTMLOptGroupElement</a>|<a href="http://www.w3.org/TR/2000/WD-DOM-
6142 * Level-1-20000929/level-one-html.html#ID-70901257">HTMLOptionElement</a>
6143 * @type <a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-
6144 * one-html.html#ID-74680021">HTMLLIElement</a>|<a href="http://www.w3.
6145 * org/TR/2000/WD-DOM-Level-1-20000929/level-one-html.html#ID-38450247">
6146 * HTMLOptGroupElement</a>|<a href="http://www.w3.org/TR/2000/WD-DOM-
6147 * Level-1-20000929/level-one-html.html#ID-70901257">HTMLOptionElement</a>
6154 * @description Object reference to the menu item's value.
6162 * @property submenuIndicator
6163 * @description Object reference to the <code><em></code> element
6164 * used to create the submenu indicator for the menu item.
6165 * @default <a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/
6166 * level-one-html.html#ID-58190037">HTMLElement</a>
6167 * @type <a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/
6168 * level-one-html.html#ID-58190037">HTMLElement</a>
6170 submenuIndicator
: null,
6175 * @deprecated Use YAHOO.env.ua
6176 * @description String representing the browser.
6179 browser
: Module
.prototype.browser
,
6184 * @description Id of the menu item's root <code><li></code>
6185 * element. This property should be set via the constructor using the
6186 * configuration object literal. If an id is not specified, then one will
6187 * be created using the "generateId" method of the Dom utility.
6199 * @event destroyEvent
6200 * @description Fires when the menu item's <code><li></code>
6201 * element is removed from its parent <code><ul></code> element.
6202 * @type YAHOO.util.CustomEvent
6208 * @event mouseOverEvent
6209 * @description Fires when the mouse has entered the menu item. Passes
6210 * back the DOM Event object as an argument.
6211 * @type YAHOO.util.CustomEvent
6213 mouseOverEvent
: null,
6217 * @event mouseOutEvent
6218 * @description Fires when the mouse has left the menu item. Passes back
6219 * the DOM Event object as an argument.
6220 * @type YAHOO.util.CustomEvent
6222 mouseOutEvent
: null,
6226 * @event mouseDownEvent
6227 * @description Fires when the user mouses down on the menu item. Passes
6228 * back the DOM Event object as an argument.
6229 * @type YAHOO.util.CustomEvent
6231 mouseDownEvent
: null,
6235 * @event mouseUpEvent
6236 * @description Fires when the user releases a mouse button while the mouse
6237 * is over the menu item. Passes back the DOM Event object as an argument.
6238 * @type YAHOO.util.CustomEvent
6245 * @description Fires when the user clicks the on the menu item. Passes
6246 * back the DOM Event object as an argument.
6247 * @type YAHOO.util.CustomEvent
6253 * @event keyPressEvent
6254 * @description Fires when the user presses an alphanumeric key when the
6255 * menu item has focus. Passes back the DOM Event object as an argument.
6256 * @type YAHOO.util.CustomEvent
6258 keyPressEvent
: null,
6262 * @event keyDownEvent
6263 * @description Fires when the user presses a key when the menu item has
6264 * focus. Passes back the DOM Event object as an argument.
6265 * @type YAHOO.util.CustomEvent
6272 * @description Fires when the user releases a key when the menu item has
6273 * focus. Passes back the DOM Event object as an argument.
6274 * @type YAHOO.util.CustomEvent
6281 * @description Fires when the menu item receives focus.
6282 * @type YAHOO.util.CustomEvent
6289 * @description Fires when the menu item loses the input focus.
6290 * @type YAHOO.util.CustomEvent
6297 * @description The MenuItem class's initialization method. This method is
6298 * automatically called by the constructor, and sets up all DOM references
6299 * for pre-existing markup, and creates required markup if it is not
6301 * @param {String} p_oObject String specifying the text of the menu item.
6302 * @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-
6303 * one-html.html#ID-74680021">HTMLLIElement</a>} p_oObject Object specifying
6304 * the <code><li></code> element of the menu item.
6305 * @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-
6306 * one-html.html#ID-38450247">HTMLOptGroupElement</a>} p_oObject Object
6307 * specifying the <code><optgroup></code> element of the menu item.
6308 * @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-
6309 * one-html.html#ID-70901257">HTMLOptionElement</a>} p_oObject Object
6310 * specifying the <code><option></code> element of the menu item.
6311 * @param {Object} p_oConfig Optional. Object literal specifying the
6312 * configuration for the menu item. See configuration class documentation
6315 init: function(p_oObject
, p_oConfig
) {
6318 if(!this.SUBMENU_TYPE
) {
6320 this.SUBMENU_TYPE
= Menu
;
6325 // Create the config object
6327 this.cfg
= new YAHOO
.util
.Config(this);
6329 this.initDefaultConfig();
6331 var SIGNATURE
= CustomEvent
.LIST
,
6340 if(Lang
.isString(p_oObject
)) {
6342 this._createRootNodeStructure();
6344 oConfig
.queueProperty("text", p_oObject
);
6347 else if(p_oObject
&& p_oObject
.tagName
) {
6349 switch(p_oObject
.tagName
.toUpperCase()) {
6353 this._createRootNodeStructure();
6355 oConfig
.queueProperty("text", p_oObject
.text
);
6357 this.srcElement
= p_oObject
;
6363 this._createRootNodeStructure();
6365 oConfig
.queueProperty("text", p_oObject
.label
);
6367 this.srcElement
= p_oObject
;
6369 this._initSubTree();
6375 // Get the anchor node (if it exists)
6377 oAnchor
= Dom
.getFirstChild(p_oObject
);
6380 // Capture the "text" and/or the "URL"
6384 sURL
= oAnchor
.getAttribute("href");
6385 sTarget
= oAnchor
.getAttribute("target");
6386 sText
= oAnchor
.innerHTML
;
6390 this.srcElement
= p_oObject
;
6391 this.element
= p_oObject
;
6392 this._oAnchor
= oAnchor
;
6395 Set these properties silently to sync up the
6396 configuration object without making changes to the
6400 oConfig
.setProperty("text", sText
, true);
6401 oConfig
.setProperty("url", sURL
, true);
6402 oConfig
.setProperty("target", sTarget
, true);
6404 this._initSubTree();
6415 sId
= this.element
.id
;
6419 sId
= this.id
|| Dom
.generateId();
6421 this.element
.id
= sId
;
6428 Dom
.addClass(this.element
, this.CSS_CLASS_NAME
);
6429 Dom
.addClass(this._oAnchor
, this.CSS_LABEL_CLASS_NAME
);
6432 // Create custom events
6434 this.mouseOverEvent
= this.createEvent(EVENT_TYPES
.MOUSE_OVER
);
6435 this.mouseOverEvent
.signature
= SIGNATURE
;
6437 this.mouseOutEvent
= this.createEvent(EVENT_TYPES
.MOUSE_OUT
);
6438 this.mouseOutEvent
.signature
= SIGNATURE
;
6440 this.mouseDownEvent
= this.createEvent(EVENT_TYPES
.MOUSE_DOWN
);
6441 this.mouseDownEvent
.signature
= SIGNATURE
;
6443 this.mouseUpEvent
= this.createEvent(EVENT_TYPES
.MOUSE_UP
);
6444 this.mouseUpEvent
.signature
= SIGNATURE
;
6446 this.clickEvent
= this.createEvent(EVENT_TYPES
.CLICK
);
6447 this.clickEvent
.signature
= SIGNATURE
;
6449 this.keyPressEvent
= this.createEvent(EVENT_TYPES
.KEY_PRESS
);
6450 this.keyPressEvent
.signature
= SIGNATURE
;
6452 this.keyDownEvent
= this.createEvent(EVENT_TYPES
.KEY_DOWN
);
6453 this.keyDownEvent
.signature
= SIGNATURE
;
6455 this.keyUpEvent
= this.createEvent(EVENT_TYPES
.KEY_UP
);
6456 this.keyUpEvent
.signature
= SIGNATURE
;
6458 this.focusEvent
= this.createEvent(EVENT_TYPES
.FOCUS
);
6459 this.focusEvent
.signature
= SIGNATURE
;
6461 this.blurEvent
= this.createEvent(EVENT_TYPES
.BLUR
);
6462 this.blurEvent
.signature
= SIGNATURE
;
6464 this.destroyEvent
= this.createEvent(EVENT_TYPES
.DESTROY
);
6465 this.destroyEvent
.signature
= SIGNATURE
;
6469 oConfig
.applyConfig(p_oConfig
);
6473 oConfig
.fireQueue();
6485 * @method _createRootNodeStructure
6486 * @description Creates the core DOM structure for the menu item.
6489 _createRootNodeStructure: function () {
6494 if(!m_oMenuItemTemplate
) {
6496 m_oMenuItemTemplate
= document
.createElement("li");
6497 m_oMenuItemTemplate
.innerHTML
= "<a href=\"#\"></a>";
6501 oElement
= m_oMenuItemTemplate
.cloneNode(true);
6502 oElement
.className
= this.CSS_CLASS_NAME
;
6504 oAnchor
= oElement
.firstChild
;
6505 oAnchor
.className
= this.CSS_LABEL_CLASS_NAME
;
6507 this.element
= oElement
;
6508 this._oAnchor
= oAnchor
;
6514 * @method _initSubTree
6515 * @description Iterates the source element's childNodes collection and uses
6516 * the child nodes to instantiate other menus.
6519 _initSubTree: function() {
6521 var oSrcEl
= this.srcElement
,
6530 if(oSrcEl
.childNodes
.length
> 0) {
6532 if(this.parent
.lazyLoad
&& this.parent
.srcElement
&&
6533 this.parent
.srcElement
.tagName
.toUpperCase() == "SELECT") {
6535 oConfig
.setProperty(
6537 { id
: Dom
.generateId(), itemdata
: oSrcEl
.childNodes
}
6543 oNode
= oSrcEl
.firstChild
;
6548 if(oNode
&& oNode
.tagName
) {
6550 switch(oNode
.tagName
.toUpperCase()) {
6554 oConfig
.setProperty("submenu", oNode
);
6560 aOptions
[aOptions
.length
] = oNode
;
6569 while((oNode
= oNode
.nextSibling
));
6572 nOptions
= aOptions
.length
;
6576 oMenu
= new this.SUBMENU_TYPE(Dom
.generateId());
6578 oConfig
.setProperty("submenu", oMenu
);
6580 for(n
=0; n
<nOptions
; n
++) {
6582 oMenu
.addItem((new oMenu
.ITEM_TYPE(aOptions
[n
])));
6596 // Event handlers for configuration properties
6600 * @method configText
6601 * @description Event handler for when the "text" configuration property of
6602 * the menu item changes.
6603 * @param {String} p_sType String representing the name of the event that
6605 * @param {Array} p_aArgs Array of arguments sent when the event was fired.
6606 * @param {YAHOO.widget.MenuItem} p_oItem Object representing the menu item
6607 * that fired the event.
6609 configText: function(p_sType
, p_aArgs
, p_oItem
) {
6611 var sText
= p_aArgs
[0],
6613 oAnchor
= this._oAnchor
,
6614 sHelpText
= oConfig
.getProperty("helptext"),
6617 oSubmenu
= oConfig
.getProperty("submenu"),
6618 sSubmenuIndicatorHTML
= "",
6619 sEmphasisStartTag
= "",
6620 sEmphasisEndTag
= "";
6628 sHelpTextHTML
= "<em class=\"helptext\">" + sHelpText
+ "</em>";
6633 if (oConfig
.getProperty("checked")) {
6635 sCheckHTML
= "<em class=\"checkedindicator\">" +
6636 this.CHECKED_TEXT
+ "</em>";
6643 sSubmenuIndicatorHTML
= "<em class=\"submenuindicator\">" +
6644 ((oSubmenu
instanceof Menu
&&
6645 oSubmenu
.cfg
.getProperty("visible")) ?
6646 this.EXPANDED_SUBMENU_INDICATOR_TEXT
:
6647 this.COLLAPSED_SUBMENU_INDICATOR_TEXT
) + "</em>";
6652 if (oConfig
.getProperty("emphasis")) {
6654 sEmphasisStartTag
= "<em>";
6655 sEmphasisEndTag
= "</em>";
6660 if (oConfig
.getProperty("strongemphasis")) {
6662 sEmphasisStartTag
= "<strong>";
6663 sEmphasisEndTag
= "</strong>";
6668 oAnchor
.innerHTML
= (sEmphasisStartTag
+ sText
+
6669 sEmphasisEndTag
+ sHelpTextHTML
+
6670 sCheckHTML
+ sSubmenuIndicatorHTML
);
6675 this.submenuIndicator
= oAnchor
.lastChild
;
6685 * @method configHelpText
6686 * @description Event handler for when the "helptext" configuration property
6687 * of the menu item changes.
6688 * @param {String} p_sType String representing the name of the event that
6690 * @param {Array} p_aArgs Array of arguments sent when the event was fired.
6691 * @param {YAHOO.widget.MenuItem} p_oItem Object representing the menu item
6692 * that fired the event.
6694 configHelpText: function(p_sType
, p_aArgs
, p_oItem
) {
6696 var sHelpText
= p_aArgs
[0],
6697 oAnchor
= this._oAnchor
;
6701 Dom
.addClass(oAnchor
, "hashelptext");
6706 Dom
.removeClass(oAnchor
, "hashelptext");
6710 this.cfg
.refireEvent("text");
6717 * @description Event handler for when the "url" configuration property of
6718 * the menu item changes.
6719 * @param {String} p_sType String representing the name of the event that
6721 * @param {Array} p_aArgs Array of arguments sent when the event was fired.
6722 * @param {YAHOO.widget.MenuItem} p_oItem Object representing the menu item
6723 * that fired the event.
6725 configURL: function(p_sType
, p_aArgs
, p_oItem
) {
6727 var sURL
= p_aArgs
[0];
6735 this._oAnchor
.setAttribute("href", sURL
);
6741 * @method configTarget
6742 * @description Event handler for when the "target" configuration property
6743 * of the menu item changes.
6744 * @param {String} p_sType String representing the name of the event that
6746 * @param {Array} p_aArgs Array of arguments sent when the event was fired.
6747 * @param {YAHOO.widget.MenuItem} p_oItem Object representing the menu item
6748 * that fired the event.
6750 configTarget: function(p_sType
, p_aArgs
, p_oItem
) {
6752 var sTarget
= p_aArgs
[0],
6753 oAnchor
= this._oAnchor
;
6755 if(sTarget
&& sTarget
.length
> 0) {
6757 oAnchor
.setAttribute("target", sTarget
);
6762 oAnchor
.removeAttribute("target");
6770 * @method configEmphasis
6771 * @description Event handler for when the "emphasis" configuration property
6772 * of the menu item changes.
6773 * @param {String} p_sType String representing the name of the event that
6775 * @param {Array} p_aArgs Array of arguments sent when the event was fired.
6776 * @param {YAHOO.widget.MenuItem} p_oItem Object representing the menu item
6777 * that fired the event.
6779 configEmphasis: function(p_sType
, p_aArgs
, p_oItem
) {
6781 var bEmphasis
= p_aArgs
[0],
6785 if(bEmphasis
&& oConfig
.getProperty("strongemphasis")) {
6787 oConfig
.setProperty("strongemphasis", false);
6792 oConfig
.refireEvent("text");
6798 * @method configStrongEmphasis
6799 * @description Event handler for when the "strongemphasis" configuration
6800 * property of the menu item changes.
6801 * @param {String} p_sType String representing the name of the event that
6803 * @param {Array} p_aArgs Array of arguments sent when the event was fired.
6804 * @param {YAHOO.widget.MenuItem} p_oItem Object representing the menu item
6805 * that fired the event.
6807 configStrongEmphasis: function(p_sType
, p_aArgs
, p_oItem
) {
6809 var bStrongEmphasis
= p_aArgs
[0],
6813 if(bStrongEmphasis
&& oConfig
.getProperty("emphasis")) {
6815 oConfig
.setProperty("emphasis", false);
6819 oConfig
.refireEvent("text");
6825 * @method configChecked
6826 * @description Event handler for when the "checked" configuration property
6827 * of the menu item changes.
6828 * @param {String} p_sType String representing the name of the event that
6830 * @param {Array} p_aArgs Array of arguments sent when the event was fired.
6831 * @param {YAHOO.widget.MenuItem} p_oItem Object representing the menu item
6832 * that fired the event.
6834 configChecked: function(p_sType
, p_aArgs
, p_oItem
) {
6836 var bChecked
= p_aArgs
[0],
6837 oAnchor
= this._oAnchor
;
6841 Dom
.addClass(oAnchor
, "checked");
6846 Dom
.removeClass(oAnchor
, "checked");
6850 this.cfg
.refireEvent("text");
6857 * @method configDisabled
6858 * @description Event handler for when the "disabled" configuration property
6859 * of the menu item changes.
6860 * @param {String} p_sType String representing the name of the event that
6862 * @param {Array} p_aArgs Array of arguments sent when the event was fired.
6863 * @param {YAHOO.widget.MenuItem} p_oItem Object representing the menu item
6864 * that fired the event.
6866 configDisabled: function(p_sType
, p_aArgs
, p_oItem
) {
6868 var bDisabled
= p_aArgs
[0],
6870 oAnchor
= this._oAnchor
;
6875 if(oConfig
.getProperty("selected")) {
6877 oConfig
.setProperty("selected", false);
6881 oAnchor
.removeAttribute("href");
6883 Dom
.addClass(oAnchor
, "disabled");
6888 oAnchor
.setAttribute("href", oConfig
.getProperty("url"));
6890 Dom
.removeClass(oAnchor
, "disabled");
6898 * @method configSelected
6899 * @description Event handler for when the "selected" configuration property
6900 * of the menu item changes.
6901 * @param {String} p_sType String representing the name of the event that
6903 * @param {Array} p_aArgs Array of arguments sent when the event was fired.
6904 * @param {YAHOO.widget.MenuItem} p_oItem Object representing the menu item
6905 * that fired the event.
6907 configSelected: function(p_sType
, p_aArgs
, p_oItem
) {
6912 if(!this.cfg
.getProperty("disabled")) {
6914 bSelected
= p_aArgs
[0];
6915 oAnchor
= this._oAnchor
;
6920 Dom
.addClass(oAnchor
, "selected");
6925 Dom
.removeClass(oAnchor
, "selected");
6935 * @method configSubmenu
6936 * @description Event handler for when the "submenu" configuration property
6937 * of the menu item changes.
6938 * @param {String} p_sType String representing the name of the event that
6940 * @param {Array} p_aArgs Array of arguments sent when the event was fired.
6941 * @param {YAHOO.widget.MenuItem} p_oItem Object representing the menu item
6942 * that fired the event.
6944 configSubmenu: function(p_sType
, p_aArgs
, p_oItem
) {
6946 var oAnchor
= this._oAnchor
,
6947 oSubmenu
= p_aArgs
[0],
6948 oSubmenuIndicator
= this.submenuIndicator
,
6950 bLazyLoad
= this.parent
&& this.parent
.lazyLoad
,
6958 if(oSubmenu
instanceof Menu
) {
6961 oMenu
.parent
= this;
6962 oMenu
.lazyLoad
= bLazyLoad
;
6965 else if(typeof oSubmenu
== "object" && oSubmenu
.id
&&
6966 !oSubmenu
.nodeType
) {
6968 sSubmenuId
= oSubmenu
.id
;
6969 oSubmenuConfig
= oSubmenu
;
6971 oSubmenuConfig
.lazyload
= bLazyLoad
;
6972 oSubmenuConfig
.parent
= this;
6974 oMenu
= new this.SUBMENU_TYPE(sSubmenuId
, oSubmenuConfig
);
6977 // Set the value of the property to the Menu instance
6979 this.cfg
.setProperty("submenu", oMenu
, true);
6984 oMenu
= new this.SUBMENU_TYPE(oSubmenu
,
6985 { lazyload
: bLazyLoad
, parent
: this });
6988 // Set the value of the property to the Menu instance
6990 this.cfg
.setProperty("submenu", oMenu
, true);
6997 Dom
.addClass(oAnchor
, "hassubmenu");
6999 this._oSubmenu
= oMenu
;
7006 Dom
.removeClass(oAnchor
, "hassubmenu");
7008 if(oSubmenuIndicator
) {
7010 oAnchor
.removeChild(oSubmenuIndicator
);
7014 if(this._oSubmenu
) {
7016 this._oSubmenu
.destroy();
7022 oConfig
.refireEvent("text");
7028 * @method configOnClick
7029 * @description Event handler for when the "onclick" configuration property
7030 * of the menu item changes.
7031 * @param {String} p_sType String representing the name of the event that
7033 * @param {Array} p_aArgs Array of arguments sent when the event was fired.
7034 * @param {YAHOO.widget.MenuItem} p_oItem Object representing the menu item
7035 * that fired the event.
7037 configOnClick: function(p_sType
, p_aArgs
, p_oItem
) {
7039 var oObject
= p_aArgs
[0];
7042 Remove any existing listeners if a "click" event handler has
7043 already been specified.
7046 if(this._oOnclickAttributeValue
&&
7047 (this._oOnclickAttributeValue
!= oObject
)) {
7049 this.clickEvent
.unsubscribe(this._oOnclickAttributeValue
.fn
,
7050 this._oOnclickAttributeValue
.obj
);
7052 this._oOnclickAttributeValue
= null;
7057 if(!this._oOnclickAttributeValue
&& typeof oObject
== "object" &&
7058 typeof oObject
.fn
== "function") {
7060 this.clickEvent
.subscribe(oObject
.fn
,
7061 ((!YAHOO
.lang
.isUndefined(oObject
.obj
)) ? oObject
.obj
: this),
7064 this._oOnclickAttributeValue
= oObject
;
7072 * @method configClassName
7073 * @description Event handler for when the "classname" configuration
7074 * property of a menu item changes.
7075 * @param {String} p_sType String representing the name of the event that
7077 * @param {Array} p_aArgs Array of arguments sent when the event was fired.
7078 * @param {YAHOO.widget.MenuItem} p_oItem Object representing the menu item
7079 * that fired the event.
7081 configClassName: function(p_sType
, p_aArgs
, p_oItem
) {
7083 var sClassName
= p_aArgs
[0];
7085 if(this._sClassName
) {
7087 Dom
.removeClass(this.element
, this._sClassName
);
7091 Dom
.addClass(this.element
, sClassName
);
7092 this._sClassName
= sClassName
;
7102 * @method initDefaultConfig
7103 * @description Initializes an item's configurable properties.
7105 initDefaultConfig : function() {
7107 var oConfig
= this.cfg
;
7110 // Define the configuration attributes
7114 * @description String specifying the text label for the menu item.
7115 * When building a menu from existing HTML the value of this property
7116 * will be interpreted from the menu's markup.
7120 oConfig
.addProperty(
7121 DEFAULT_CONFIG
.TEXT
.key
,
7123 handler
: this.configText
,
7124 value
: DEFAULT_CONFIG
.TEXT
.value
,
7125 validator
: DEFAULT_CONFIG
.TEXT
.validator
,
7126 suppressEvent
: DEFAULT_CONFIG
.TEXT
.suppressEvent
7133 * @description String specifying additional instructional text to
7134 * accompany the text for the menu item.
7135 * @deprecated Use "text" configuration property to add help text markup.
7136 * For example: <code>oMenuItem.cfg.setProperty("text", "Copy <em
7137 * class=\"helptext\">Ctrl + C</em<");</code>
7139 * @type String|<a href="http://www.w3.org/TR/
7140 * 2000/WD-DOM-Level-1-20000929/level-one-html.html#ID-58190037">
7143 oConfig
.addProperty(
7144 DEFAULT_CONFIG
.HELP_TEXT
.key
,
7145 { handler
: this.configHelpText
}
7151 * @description String specifying the URL for the menu item's anchor's
7152 * "href" attribute. When building a menu from existing HTML the value
7153 * of this property will be interpreted from the menu's markup.
7157 oConfig
.addProperty(
7158 DEFAULT_CONFIG
.URL
.key
,
7160 handler
: this.configURL
,
7161 value
: DEFAULT_CONFIG
.URL
.value
,
7162 suppressEvent
: DEFAULT_CONFIG
.URL
.suppressEvent
7169 * @description String specifying the value for the "target" attribute
7170 * of the menu item's anchor element. <strong>Specifying a target will
7171 * require the user to click directly on the menu item's anchor node in
7172 * order to cause the browser to navigate to the specified URL.</strong>
7173 * When building a menu from existing HTML the value of this property
7174 * will be interpreted from the menu's markup.
7178 oConfig
.addProperty(
7179 DEFAULT_CONFIG
.TARGET
.key
,
7181 handler
: this.configTarget
,
7182 suppressEvent
: DEFAULT_CONFIG
.TARGET
.suppressEvent
7189 * @description Boolean indicating if the text of the menu item will be
7190 * rendered with emphasis.
7191 * @deprecated Use "text" configuration property to add emphasis.
7192 * For example: <code>oMenuItem.cfg.setProperty("text", "<em>Some
7193 * Text</em<");</code>
7197 oConfig
.addProperty(
7198 DEFAULT_CONFIG
.EMPHASIS
.key
,
7200 handler
: this.configEmphasis
,
7201 value
: DEFAULT_CONFIG
.EMPHASIS
.value
,
7202 validator
: DEFAULT_CONFIG
.EMPHASIS
.validator
,
7203 suppressEvent
: DEFAULT_CONFIG
.EMPHASIS
.suppressEvent
7209 * @config strongemphasis
7210 * @description Boolean indicating if the text of the menu item will be
7211 * rendered with strong emphasis.
7212 * @deprecated Use "text" configuration property to add strong emphasis.
7213 * For example: <code>oMenuItem.cfg.setProperty("text", "<strong>
7214 * Some Text</strong<");</code>
7218 oConfig
.addProperty(
7219 DEFAULT_CONFIG
.STRONG_EMPHASIS
.key
,
7221 handler
: this.configStrongEmphasis
,
7222 value
: DEFAULT_CONFIG
.STRONG_EMPHASIS
.value
,
7223 validator
: DEFAULT_CONFIG
.STRONG_EMPHASIS
.validator
,
7224 suppressEvent
: DEFAULT_CONFIG
.STRONG_EMPHASIS
.suppressEvent
7231 * @description Boolean indicating if the menu item should be rendered
7236 oConfig
.addProperty(
7237 DEFAULT_CONFIG
.CHECKED
.key
,
7239 handler
: this.configChecked
,
7240 value
: DEFAULT_CONFIG
.CHECKED
.value
,
7241 validator
: DEFAULT_CONFIG
.CHECKED
.validator
,
7242 suppressEvent
: DEFAULT_CONFIG
.CHECKED
.suppressEvent
,
7243 supercedes
: DEFAULT_CONFIG
.CHECKED
.supercedes
7250 * @description Boolean indicating if the menu item should be disabled.
7251 * (Disabled menu items are dimmed and will not respond to user input
7256 oConfig
.addProperty(
7257 DEFAULT_CONFIG
.DISABLED
.key
,
7259 handler
: this.configDisabled
,
7260 value
: DEFAULT_CONFIG
.DISABLED
.value
,
7261 validator
: DEFAULT_CONFIG
.DISABLED
.validator
,
7262 suppressEvent
: DEFAULT_CONFIG
.DISABLED
.suppressEvent
7269 * @description Boolean indicating if the menu item should
7274 oConfig
.addProperty(
7275 DEFAULT_CONFIG
.SELECTED
.key
,
7277 handler
: this.configSelected
,
7278 value
: DEFAULT_CONFIG
.SELECTED
.value
,
7279 validator
: DEFAULT_CONFIG
.SELECTED
.validator
,
7280 suppressEvent
: DEFAULT_CONFIG
.SELECTED
.suppressEvent
7287 * @description Object specifying the submenu to be appended to the
7288 * menu item. The value can be one of the following: <ul><li>Object
7289 * specifying a Menu instance.</li><li>Object literal specifying the
7290 * menu to be created. Format: <code>{ id: [menu id], itemdata:
7291 * [<a href="YAHOO.widget.Menu.html#itemData">array of values for
7292 * items</a>] }</code>.</li><li>String specifying the id attribute
7293 * of the <code><div></code> element of the menu.</li><li>
7294 * Object specifying the <code><div></code> element of the
7297 * @type Menu|String|Object|<a href="http://www.w3.org/TR/2000/
7298 * WD-DOM-Level-1-20000929/level-one-html.html#ID-58190037">
7301 oConfig
.addProperty(
7302 DEFAULT_CONFIG
.SUBMENU
.key
,
7303 { handler
: this.configSubmenu
}
7309 * @description Object literal representing the code to be executed when
7310 * the item is clicked. Format:<br> <code> {<br>
7311 * <strong>fn:</strong> Function, // The handler to call when
7312 * the event fires.<br> <strong>obj:</strong> Object, // An
7313 * object to pass back to the handler.<br> <strong>scope:</strong>
7314 * Object // The object to use for the scope of the handler.
7319 oConfig
.addProperty(
7320 DEFAULT_CONFIG
.ONCLICK
.key
,
7321 { handler
: this.configOnClick
}
7327 * @description CSS class to be applied to the menu item's root
7328 * <code><li></code> element. The specified class(es) are
7329 * appended in addition to the default class as specified by the menu
7330 * item's CSS_CLASS_NAME constant.
7334 oConfig
.addProperty(
7335 DEFAULT_CONFIG
.CLASS_NAME
.key
,
7337 handler
: this.configClassName
,
7338 value
: DEFAULT_CONFIG
.CLASS_NAME
.value
,
7339 validator
: DEFAULT_CONFIG
.CLASS_NAME
.validator
7347 * @method getNextEnabledSibling
7348 * @description Finds the menu item's next enabled sibling.
7349 * @return YAHOO.widget.MenuItem
7351 getNextEnabledSibling: function() {
7359 function getNextArrayItem(p_aArray
, p_nStartIndex
) {
7361 return p_aArray
[p_nStartIndex
] ||
7362 getNextArrayItem(p_aArray
, (p_nStartIndex
+1));
7366 if(this.parent
instanceof Menu
) {
7368 nGroupIndex
= this.groupIndex
;
7370 aItemGroups
= this.parent
.getItemGroups();
7372 if(this.index
< (aItemGroups
[nGroupIndex
].length
- 1)) {
7374 oNextItem
= getNextArrayItem(aItemGroups
[nGroupIndex
],
7380 if(nGroupIndex
< (aItemGroups
.length
- 1)) {
7382 nNextGroupIndex
= nGroupIndex
+ 1;
7387 nNextGroupIndex
= 0;
7391 aNextGroup
= getNextArrayItem(aItemGroups
, nNextGroupIndex
);
7393 // Retrieve the first menu item in the next group
7395 oNextItem
= getNextArrayItem(aNextGroup
, 0);
7399 return (oNextItem
.cfg
.getProperty("disabled") ||
7400 oNextItem
.element
.style
.display
== "none") ?
7401 oNextItem
.getNextEnabledSibling() : oNextItem
;
7409 * @method getPreviousEnabledSibling
7410 * @description Finds the menu item's previous enabled sibling.
7411 * @return {YAHOO.widget.MenuItem}
7413 getPreviousEnabledSibling: function() {
7418 nPreviousGroupIndex
,
7421 function getPreviousArrayItem(p_aArray
, p_nStartIndex
) {
7423 return p_aArray
[p_nStartIndex
] ||
7424 getPreviousArrayItem(p_aArray
, (p_nStartIndex
-1));
7428 function getFirstItemIndex(p_aArray
, p_nStartIndex
) {
7430 return p_aArray
[p_nStartIndex
] ? p_nStartIndex
:
7431 getFirstItemIndex(p_aArray
, (p_nStartIndex
+1));
7435 if(this.parent
instanceof Menu
) {
7437 nGroupIndex
= this.groupIndex
;
7438 aItemGroups
= this.parent
.getItemGroups();
7441 if(this.index
> getFirstItemIndex(aItemGroups
[nGroupIndex
], 0)) {
7443 oPreviousItem
= getPreviousArrayItem(aItemGroups
[nGroupIndex
],
7449 if(nGroupIndex
> getFirstItemIndex(aItemGroups
, 0)) {
7451 nPreviousGroupIndex
= nGroupIndex
- 1;
7456 nPreviousGroupIndex
= aItemGroups
.length
- 1;
7460 aPreviousGroup
= getPreviousArrayItem(aItemGroups
,
7461 nPreviousGroupIndex
);
7463 oPreviousItem
= getPreviousArrayItem(aPreviousGroup
,
7464 (aPreviousGroup
.length
- 1));
7468 return (oPreviousItem
.cfg
.getProperty("disabled") ||
7469 oPreviousItem
.element
.style
.display
== "none") ?
7470 oPreviousItem
.getPreviousEnabledSibling() : oPreviousItem
;
7479 * @description Causes the menu item to receive the focus and fires the
7484 var oParent
= this.parent
,
7485 oAnchor
= this._oAnchor
,
7486 oActiveItem
= oParent
.activeItem
,
7490 function setFocus() {
7494 if (YAHOO
.env
.ua
.ie
&& !document
.hasFocus()) {
7510 if(!this.cfg
.getProperty("disabled") && oParent
&&
7511 oParent
.cfg
.getProperty("visible") &&
7512 this.element
.style
.display
!= "none") {
7522 Setting focus via a timer fixes a race condition in Firefox, IE
7523 and Opera where the browser viewport jumps as it trys to
7524 position and focus the menu.
7527 window
.setTimeout(setFocus
, 0);
7529 this.focusEvent
.fire();
7538 * @description Causes the menu item to lose focus and fires the
7543 var oParent
= this.parent
;
7545 if(!this.cfg
.getProperty("disabled") && oParent
&&
7546 oParent
.cfg
.getProperty("visible")) {
7548 this._oAnchor
.blur();
7550 this.blurEvent
.fire();
7559 * @description Returns a boolean indicating whether or not the menu item
7563 hasFocus: function() {
7565 return (YAHOO
.widget
.MenuManager
.getFocusedMenuItem() == this);
7572 * @description Removes the menu item's <code><li></code> element
7573 * from its parent <code><ul></code> element.
7575 destroy: function() {
7577 var oEl
= this.element
,
7584 // If the item has a submenu, destroy it first
7586 oSubmenu
= this.cfg
.getProperty("submenu");
7595 // Remove CustomEvent listeners
7597 this.mouseOverEvent
.unsubscribeAll();
7598 this.mouseOutEvent
.unsubscribeAll();
7599 this.mouseDownEvent
.unsubscribeAll();
7600 this.mouseUpEvent
.unsubscribeAll();
7601 this.clickEvent
.unsubscribeAll();
7602 this.keyPressEvent
.unsubscribeAll();
7603 this.keyDownEvent
.unsubscribeAll();
7604 this.keyUpEvent
.unsubscribeAll();
7605 this.focusEvent
.unsubscribeAll();
7606 this.blurEvent
.unsubscribeAll();
7607 this.cfg
.configChangedEvent
.unsubscribeAll();
7610 // Remove the element from the parent node
7612 oParentNode
= oEl
.parentNode
;
7616 oParentNode
.removeChild(oEl
);
7618 this.destroyEvent
.fire();
7622 this.destroyEvent
.unsubscribeAll();
7631 * @description Returns a string representing the menu item.
7634 toString: function() {
7636 var sReturnVal
= "MenuItem",
7641 sReturnVal
+= (" " + sId
);
7651 Lang
.augmentProto(MenuItem
, YAHOO
.util
.EventProvider
);
7658 * Creates a list of options or commands which are made visible in response to
7659 * an HTML element's "contextmenu" event ("mousedown" for Opera).
7661 * @param {String} p_oElement String specifying the id attribute of the
7662 * <code><div></code> element of the context menu.
7663 * @param {String} p_oElement String specifying the id attribute of the
7664 * <code><select></code> element to be used as the data source for the
7666 * @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-one-
7667 * html.html#ID-22445964">HTMLDivElement</a>} p_oElement Object specifying the
7668 * <code><div></code> element of the context menu.
7669 * @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-one-
7670 * html.html#ID-94282980">HTMLSelectElement</a>} p_oElement Object specifying
7671 * the <code><select></code> element to be used as the data source for
7673 * @param {Object} p_oConfig Optional. Object literal specifying the
7674 * configuration for the context menu. See configuration class documentation
7676 * @class ContextMenu
7678 * @extends YAHOO.widget.Menu
7679 * @namespace YAHOO.widget
7681 YAHOO
.widget
.ContextMenu = function(p_oElement
, p_oConfig
) {
7683 YAHOO
.widget
.ContextMenu
.superclass
.constructor.call(this,
7684 p_oElement
, p_oConfig
);
7688 var Event
= YAHOO
.util
.Event
,
7689 ContextMenu
= YAHOO
.widget
.ContextMenu
,
7692 * Constant representing the name of the ContextMenu's events
7693 * @property EVENT_TYPES
7700 "TRIGGER_CONTEXT_MENU": "triggerContextMenu",
7701 "CONTEXT_MENU": (YAHOO
.env
.ua
.opera
? "mousedown" : "contextmenu"),
7708 * Constant representing the ContextMenu's configuration properties
7709 * @property DEFAULT_CONFIG
7723 YAHOO
.lang
.extend(ContextMenu
, YAHOO
.widget
.Menu
, {
7727 // Private properties
7731 * @property _oTrigger
7732 * @description Object reference to the current value of the "trigger"
7733 * configuration property.
7736 * @type String|<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/leve
7737 * l-one-html.html#ID-58190037">HTMLElement</a>|Array
7743 * @property _bCancelled
7744 * @description Boolean indicating if the display of the context menu should
7754 // Public properties
7758 * @property contextEventTarget
7759 * @description Object reference for the HTML element that was the target of the
7760 * "contextmenu" DOM event ("mousedown" for Opera) that triggered the display of
7763 * @type <a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-one-
7764 * html.html#ID-58190037">HTMLElement</a>
7766 contextEventTarget
: null,
7774 * @event triggerContextMenuEvent
7775 * @description Custom Event wrapper for the "contextmenu" DOM event
7776 * ("mousedown" for Opera) fired by the element(s) that trigger the display of
7779 triggerContextMenuEvent
: null,
7785 * @description The ContextMenu class's initialization method. This method is
7786 * automatically called by the constructor, and sets up all DOM references for
7787 * pre-existing markup, and creates required markup if it is not already present.
7788 * @param {String} p_oElement String specifying the id attribute of the
7789 * <code><div></code> element of the context menu.
7790 * @param {String} p_oElement String specifying the id attribute of the
7791 * <code><select></code> element to be used as the data source for
7793 * @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-one-
7794 * html.html#ID-22445964">HTMLDivElement</a>} p_oElement Object specifying the
7795 * <code><div></code> element of the context menu.
7796 * @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-one-
7797 * html.html#ID-94282980">HTMLSelectElement</a>} p_oElement Object specifying
7798 * the <code><select></code> element to be used as the data source for
7800 * @param {Object} p_oConfig Optional. Object literal specifying the
7801 * configuration for the context menu. See configuration class documentation
7804 init: function(p_oElement
, p_oConfig
) {
7806 if(!this.ITEM_TYPE
) {
7808 this.ITEM_TYPE
= YAHOO
.widget
.ContextMenuItem
;
7813 // Call the init of the superclass (YAHOO.widget.Menu)
7815 ContextMenu
.superclass
.init
.call(this, p_oElement
);
7818 this.beforeInitEvent
.fire(ContextMenu
);
7823 this.cfg
.applyConfig(p_oConfig
, true);
7828 this.initEvent
.fire(ContextMenu
);
7834 * @method initEvents
7835 * @description Initializes the custom events for the context menu.
7837 initEvents: function() {
7839 ContextMenu
.superclass
.initEvents
.call(this);
7841 // Create custom events
7843 this.triggerContextMenuEvent
=
7844 this.createEvent(EVENT_TYPES
.TRIGGER_CONTEXT_MENU
);
7846 this.triggerContextMenuEvent
.signature
= YAHOO
.util
.CustomEvent
.LIST
;
7853 * @description Cancels the display of the context menu.
7855 cancel: function() {
7857 this._bCancelled
= true;
7867 * @method _removeEventHandlers
7868 * @description Removes all of the DOM event handlers from the HTML element(s)
7869 * whose "context menu" event ("click" for Opera) trigger the display of
7873 _removeEventHandlers: function() {
7875 var oTrigger
= this._oTrigger
;
7878 // Remove the event handlers from the trigger(s)
7882 Event
.removeListener(oTrigger
, EVENT_TYPES
.CONTEXT_MENU
,
7883 this._onTriggerContextMenu
);
7885 if(YAHOO
.env
.ua
.opera
) {
7887 Event
.removeListener(oTrigger
, EVENT_TYPES
.CLICK
,
7888 this._onTriggerClick
);
7898 // Private event handlers
7902 * @method _onTriggerClick
7903 * @description "click" event handler for the HTML element(s) identified as the
7904 * "trigger" for the context menu. Used to cancel default behaviors in Opera.
7906 * @param {Event} p_oEvent Object representing the DOM event object passed back
7907 * by the event utility (YAHOO.util.Event).
7908 * @param {YAHOO.widget.ContextMenu} p_oMenu Object representing the context
7909 * menu that is handling the event.
7911 _onTriggerClick: function(p_oEvent
, p_oMenu
) {
7913 if(p_oEvent
.ctrlKey
) {
7915 Event
.stopEvent(p_oEvent
);
7923 * @method _onTriggerContextMenu
7924 * @description "contextmenu" event handler ("mousedown" for Opera) for the HTML
7925 * element(s) that trigger the display of the context menu.
7927 * @param {Event} p_oEvent Object representing the DOM event object passed back
7928 * by the event utility (YAHOO.util.Event).
7929 * @param {YAHOO.widget.ContextMenu} p_oMenu Object representing the context
7930 * menu that is handling the event.
7932 _onTriggerContextMenu: function(p_oEvent
, p_oMenu
) {
7934 if(p_oEvent
.type
== "mousedown" && !p_oEvent
.ctrlKey
) {
7942 Prevent the browser's default context menu from appearing and
7943 stop the propagation of the "contextmenu" event so that
7944 other ContextMenu instances are not displayed.
7947 Event
.stopEvent(p_oEvent
);
7950 // Hide any other ContextMenu instances that might be visible
7952 YAHOO
.widget
.MenuManager
.hideVisible();
7955 this.contextEventTarget
= Event
.getTarget(p_oEvent
);
7957 this.triggerContextMenuEvent
.fire(p_oEvent
);
7960 if(!this._bCancelled
) {
7962 // Position and display the context menu
7964 this.cfg
.setProperty("xy", Event
.getXY(p_oEvent
));
7970 this._bCancelled
= false;
7981 * @description Returns a string representing the context menu.
7984 toString: function() {
7986 var sReturnVal
= "ContextMenu",
7991 sReturnVal
+= (" " + sId
);
8001 * @method initDefaultConfig
8002 * @description Initializes the class's configurable properties which can be
8003 * changed using the context menu's Config object ("cfg").
8005 initDefaultConfig: function() {
8007 ContextMenu
.superclass
.initDefaultConfig
.call(this);
8011 * @description The HTML element(s) whose "contextmenu" event ("mousedown"
8012 * for Opera) trigger the display of the context menu. Can be a string
8013 * representing the id attribute of the HTML element, an object reference
8014 * for the HTML element, or an array of strings or HTML element references.
8016 * @type String|<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/
8017 * level-one-html.html#ID-58190037">HTMLElement</a>|Array
8019 this.cfg
.addProperty(DEFAULT_CONFIG
.TRIGGER
.key
,
8020 { handler
: this.configTrigger
});
8027 * @description Removes the context menu's <code><div></code> element
8028 * (and accompanying child nodes) from the document.
8030 destroy: function() {
8032 // Remove the DOM event handlers from the current trigger(s)
8034 this._removeEventHandlers();
8037 // Continue with the superclass implementation of this method
8039 ContextMenu
.superclass
.destroy
.call(this);
8045 // Public event handlers for configuration properties
8049 * @method configTrigger
8050 * @description Event handler for when the value of the "trigger" configuration
8052 * @param {String} p_sType String representing the name of the event that
8054 * @param {Array} p_aArgs Array of arguments sent when the event was fired.
8055 * @param {YAHOO.widget.ContextMenu} p_oMenu Object representing the context
8056 * menu that fired the event.
8058 configTrigger: function(p_sType
, p_aArgs
, p_oMenu
) {
8060 var oTrigger
= p_aArgs
[0];
8065 If there is a current "trigger" - remove the event handlers
8066 from that element(s) before assigning new ones
8069 if(this._oTrigger
) {
8071 this._removeEventHandlers();
8075 this._oTrigger
= oTrigger
;
8079 Listen for the "mousedown" event in Opera b/c it does not
8080 support the "contextmenu" event
8083 Event
.on(oTrigger
, EVENT_TYPES
.CONTEXT_MENU
,
8084 this._onTriggerContextMenu
, this, true);
8088 Assign a "click" event handler to the trigger element(s) for
8089 Opera to prevent default browser behaviors.
8092 if(YAHOO
.env
.ua
.opera
) {
8094 Event
.on(oTrigger
, EVENT_TYPES
.CLICK
, this._onTriggerClick
,
8102 this._removeEventHandlers();
8108 }); // END YAHOO.lang.extend
8115 * Creates an item for a context menu.
8117 * @param {String} p_oObject String specifying the text of the context menu item.
8118 * @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-
8119 * one-html.html#ID-74680021">HTMLLIElement</a>} p_oObject Object specifying the
8120 * <code><li></code> element of the context menu item.
8121 * @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-
8122 * one-html.html#ID-38450247">HTMLOptGroupElement</a>} p_oObject Object
8123 * specifying the <code><optgroup></code> element of the context
8125 * @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-
8126 * one-html.html#ID-70901257">HTMLOptionElement</a>} p_oObject Object specifying
8127 * the <code><option></code> element of the context menu item.
8128 * @param {Object} p_oConfig Optional. Object literal specifying the
8129 * configuration for the context menu item. See configuration class
8130 * documentation for more details.
8131 * @class ContextMenuItem
8133 * @extends YAHOO.widget.MenuItem
8135 YAHOO
.widget
.ContextMenuItem = function(p_oObject
, p_oConfig
) {
8137 YAHOO
.widget
.ContextMenuItem
.superclass
.constructor.call(this,
8138 p_oObject
, p_oConfig
);
8142 YAHOO
.lang
.extend(YAHOO
.widget
.ContextMenuItem
, YAHOO
.widget
.MenuItem
, {
8147 * @description The ContextMenuItem class's initialization method. This method
8148 * is automatically called by the constructor, and sets up all DOM references
8149 * for pre-existing markup, and creates required markup if it is not
8151 * @param {String} p_oObject String specifying the text of the context menu item.
8152 * @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-
8153 * one-html.html#ID-74680021">HTMLLIElement</a>} p_oObject Object specifying the
8154 * <code><li></code> element of the context menu item.
8155 * @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-
8156 * one-html.html#ID-38450247">HTMLOptGroupElement</a>} p_oObject Object
8157 * specifying the <code><optgroup></code> element of the context
8159 * @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-
8160 * one-html.html#ID-70901257">HTMLOptionElement</a>} p_oObject Object specifying
8161 * the <code><option></code> element of the context menu item.
8162 * @param {Object} p_oConfig Optional. Object literal specifying the
8163 * configuration for the context menu item. See configuration class
8164 * documentation for more details.
8166 init: function(p_oObject
, p_oConfig
) {
8168 if(!this.SUBMENU_TYPE
) {
8170 this.SUBMENU_TYPE
= YAHOO
.widget
.ContextMenu
;
8176 Call the init of the superclass (YAHOO.widget.MenuItem)
8177 Note: We don't pass the user config in here yet
8178 because we only want it executed once, at the lowest
8182 YAHOO
.widget
.ContextMenuItem
.superclass
.init
.call(this, p_oObject
);
8184 var oConfig
= this.cfg
;
8188 oConfig
.applyConfig(p_oConfig
, true);
8192 oConfig
.fireQueue();
8203 * @description Returns a string representing the context menu item.
8206 toString: function() {
8208 var sReturnVal
= "ContextMenuItem";
8210 if(this.cfg
&& this.cfg
.getProperty("text")) {
8212 sReturnVal
+= (": " + this.cfg
.getProperty("text"));
8220 }); // END YAHOO.lang.extend
8225 * Horizontal collection of items, each of which can contain a submenu.
8227 * @param {String} p_oElement String specifying the id attribute of the
8228 * <code><div></code> element of the menu bar.
8229 * @param {String} p_oElement String specifying the id attribute of the
8230 * <code><select></code> element to be used as the data source for the
8232 * @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-
8233 * one-html.html#ID-22445964">HTMLDivElement</a>} p_oElement Object specifying
8234 * the <code><div></code> element of the menu bar.
8235 * @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-
8236 * one-html.html#ID-94282980">HTMLSelectElement</a>} p_oElement Object
8237 * specifying the <code><select></code> element to be used as the data
8238 * source for the menu bar.
8239 * @param {Object} p_oConfig Optional. Object literal specifying the
8240 * configuration for the menu bar. See configuration class documentation for
8244 * @extends YAHOO.widget.Menu
8245 * @namespace YAHOO.widget
8247 YAHOO
.widget
.MenuBar = function(p_oElement
, p_oConfig
) {
8249 YAHOO
.widget
.MenuBar
.superclass
.constructor.call(this,
8250 p_oElement
, p_oConfig
);
8256 * @method checkPosition
8257 * @description Checks to make sure that the value of the "position" property
8258 * is one of the supported strings. Returns true if the position is supported.
8260 * @param {Object} p_sPosition String specifying the position of the menu.
8263 function checkPosition(p_sPosition
) {
8265 if (typeof p_sPosition
== "string") {
8267 return ("dynamic,static".indexOf((p_sPosition
.toLowerCase())) != -1);
8274 var Event
= YAHOO
.util
.Event
,
8275 Dom
= YAHOO
.util
.Dom
,
8276 MenuBar
= YAHOO
.widget
.MenuBar
,
8279 * Constant representing the MenuBar's configuration properties
8280 * @property DEFAULT_CONFIG
8290 validator
: checkPosition
,
8291 supercedes
: ["visible"]
8294 "SUBMENU_ALIGNMENT": {
8295 key
: "submenualignment",
8299 "AUTO_SUBMENU_DISPLAY": {
8300 key
: "autosubmenudisplay",
8302 validator
: YAHOO
.lang
.isBoolean
8309 YAHOO
.lang
.extend(MenuBar
, YAHOO
.widget
.Menu
, {
8313 * @description The MenuBar class's initialization method. This method is
8314 * automatically called by the constructor, and sets up all DOM references for
8315 * pre-existing markup, and creates required markup if it is not already present.
8316 * @param {String} p_oElement String specifying the id attribute of the
8317 * <code><div></code> element of the menu bar.
8318 * @param {String} p_oElement String specifying the id attribute of the
8319 * <code><select></code> element to be used as the data source for the
8321 * @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-
8322 * one-html.html#ID-22445964">HTMLDivElement</a>} p_oElement Object specifying
8323 * the <code><div></code> element of the menu bar.
8324 * @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-
8325 * one-html.html#ID-94282980">HTMLSelectElement</a>} p_oElement Object
8326 * specifying the <code><select></code> element to be used as the data
8327 * source for the menu bar.
8328 * @param {Object} p_oConfig Optional. Object literal specifying the
8329 * configuration for the menu bar. See configuration class documentation for
8332 init: function(p_oElement
, p_oConfig
) {
8334 if(!this.ITEM_TYPE
) {
8336 this.ITEM_TYPE
= YAHOO
.widget
.MenuBarItem
;
8341 // Call the init of the superclass (YAHOO.widget.Menu)
8343 MenuBar
.superclass
.init
.call(this, p_oElement
);
8346 this.beforeInitEvent
.fire(MenuBar
);
8351 this.cfg
.applyConfig(p_oConfig
, true);
8355 this.initEvent
.fire(MenuBar
);
8365 * @property CSS_CLASS_NAME
8366 * @description String representing the CSS class(es) to be applied to the menu
8367 * bar's <code><div></code> element.
8368 * @default "yuimenubar"
8372 CSS_CLASS_NAME
: "yuimenubar",
8376 // Protected event handlers
8380 * @method _onKeyDown
8381 * @description "keydown" Custom Event handler for the menu bar.
8383 * @param {String} p_sType String representing the name of the event that
8385 * @param {Array} p_aArgs Array of arguments sent when the event was fired.
8386 * @param {YAHOO.widget.MenuBar} p_oMenuBar Object representing the menu bar
8387 * that fired the event.
8389 _onKeyDown: function(p_sType
, p_aArgs
, p_oMenuBar
) {
8391 var oEvent
= p_aArgs
[0],
8398 if(oItem
&& !oItem
.cfg
.getProperty("disabled")) {
8400 oItemCfg
= oItem
.cfg
;
8402 switch(oEvent
.keyCode
) {
8404 case 37: // Left arrow
8405 case 39: // Right arrow
8407 if(oItem
== this.activeItem
&&
8408 !oItemCfg
.getProperty("selected")) {
8410 oItemCfg
.setProperty("selected", true);
8415 oNextItem
= (oEvent
.keyCode
== 37) ?
8416 oItem
.getPreviousEnabledSibling() :
8417 oItem
.getNextEnabledSibling();
8421 this.clearActiveItem();
8423 oNextItem
.cfg
.setProperty("selected", true);
8426 if(this.cfg
.getProperty("autosubmenudisplay")) {
8428 oSubmenu
= oNextItem
.cfg
.getProperty("submenu");
8444 Event
.preventDefault(oEvent
);
8448 case 40: // Down arrow
8450 if(this.activeItem
!= oItem
) {
8452 this.clearActiveItem();
8454 oItemCfg
.setProperty("selected", true);
8459 oSubmenu
= oItemCfg
.getProperty("submenu");
8463 if(oSubmenu
.cfg
.getProperty("visible")) {
8465 oSubmenu
.setInitialSelection();
8466 oSubmenu
.setInitialFocus();
8477 Event
.preventDefault(oEvent
);
8486 if(oEvent
.keyCode
== 27 && this.activeItem
) { // Esc key
8488 oSubmenu
= this.activeItem
.cfg
.getProperty("submenu");
8490 if(oSubmenu
&& oSubmenu
.cfg
.getProperty("visible")) {
8493 this.activeItem
.focus();
8498 this.activeItem
.cfg
.setProperty("selected", false);
8499 this.activeItem
.blur();
8503 Event
.preventDefault(oEvent
);
8512 * @description "click" event handler for the menu bar.
8514 * @param {String} p_sType String representing the name of the event that
8516 * @param {Array} p_aArgs Array of arguments sent when the event was fired.
8517 * @param {YAHOO.widget.MenuBar} p_oMenuBar Object representing the menu bar
8518 * that fired the event.
8520 _onClick: function(p_sType
, p_aArgs
, p_oMenuBar
) {
8522 MenuBar
.superclass
._onClick
.call(this, p_sType
, p_aArgs
, p_oMenuBar
);
8524 var oItem
= p_aArgs
[1],
8532 if(oItem
&& !oItem
.cfg
.getProperty("disabled")) {
8534 oEvent
= p_aArgs
[0];
8535 oTarget
= Event
.getTarget(oEvent
);
8536 oActiveItem
= this.activeItem
;
8540 // Hide any other submenus that might be visible
8542 if(oActiveItem
&& oActiveItem
!= oItem
) {
8544 this.clearActiveItem();
8549 oItem
.cfg
.setProperty("selected", true);
8552 // Show the submenu for the item
8554 oSubmenu
= oItem
.cfg
.getProperty("submenu");
8557 if(oSubmenu
&& oTarget
!= oItem
.submenuIndicator
) {
8559 if(oSubmenu
.cfg
.getProperty("visible")) {
8583 * @description Returns a string representing the menu bar.
8586 toString: function() {
8588 var sReturnVal
= "MenuBar",
8593 sReturnVal
+= (" " + sId
);
8603 * @description Initializes the class's configurable properties which can be
8604 * changed using the menu bar's Config object ("cfg").
8605 * @method initDefaultConfig
8607 initDefaultConfig: function() {
8609 MenuBar
.superclass
.initDefaultConfig
.call(this);
8611 var oConfig
= this.cfg
;
8613 // Add configuration properties
8617 Set the default value for the "position" configuration property
8618 to "static" by re-adding the property.
8624 * @description String indicating how a menu bar should be positioned on the
8625 * screen. Possible values are "static" and "dynamic." Static menu bars
8626 * are visible by default and reside in the normal flow of the document
8627 * (CSS position: static). Dynamic menu bars are hidden by default, reside
8628 * out of the normal flow of the document (CSS position: absolute), and can
8629 * overlay other elements on the screen.
8633 oConfig
.addProperty(
8634 DEFAULT_CONFIG
.POSITION
.key
,
8636 handler
: this.configPosition
,
8637 value
: DEFAULT_CONFIG
.POSITION
.value
,
8638 validator
: DEFAULT_CONFIG
.POSITION
.validator
,
8639 supercedes
: DEFAULT_CONFIG
.POSITION
.supercedes
8645 Set the default value for the "submenualignment" configuration property
8646 to ["tl","bl"] by re-adding the property.
8650 * @config submenualignment
8651 * @description Array defining how submenus should be aligned to their
8652 * parent menu bar item. The format is: [itemCorner, submenuCorner].
8653 * @default ["tl","bl"]
8656 oConfig
.addProperty(
8657 DEFAULT_CONFIG
.SUBMENU_ALIGNMENT
.key
,
8659 value
: DEFAULT_CONFIG
.SUBMENU_ALIGNMENT
.value
8665 Change the default value for the "autosubmenudisplay" configuration
8666 property to "false" by re-adding the property.
8670 * @config autosubmenudisplay
8671 * @description Boolean indicating if submenus are automatically made
8672 * visible when the user mouses over the menu bar's items.
8676 oConfig
.addProperty(
8677 DEFAULT_CONFIG
.AUTO_SUBMENU_DISPLAY
.key
,
8679 value
: DEFAULT_CONFIG
.AUTO_SUBMENU_DISPLAY
.value
,
8680 validator
: DEFAULT_CONFIG
.AUTO_SUBMENU_DISPLAY
.validator
8686 }); // END YAHOO.lang.extend
8693 * Creates an item for a menu bar.
8695 * @param {String} p_oObject String specifying the text of the menu bar item.
8696 * @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-
8697 * one-html.html#ID-74680021">HTMLLIElement</a>} p_oObject Object specifying the
8698 * <code><li></code> element of the menu bar item.
8699 * @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-
8700 * one-html.html#ID-38450247">HTMLOptGroupElement</a>} p_oObject Object
8701 * specifying the <code><optgroup></code> element of the menu bar item.
8702 * @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-
8703 * one-html.html#ID-70901257">HTMLOptionElement</a>} p_oObject Object specifying
8704 * the <code><option></code> element of the menu bar item.
8705 * @param {Object} p_oConfig Optional. Object literal specifying the
8706 * configuration for the menu bar item. See configuration class documentation
8708 * @class MenuBarItem
8710 * @extends YAHOO.widget.MenuItem
8712 YAHOO
.widget
.MenuBarItem = function(p_oObject
, p_oConfig
) {
8714 YAHOO
.widget
.MenuBarItem
.superclass
.constructor.call(this,
8715 p_oObject
, p_oConfig
);
8719 YAHOO
.lang
.extend(YAHOO
.widget
.MenuBarItem
, YAHOO
.widget
.MenuItem
, {
8725 * @description The MenuBarItem class's initialization method. This method is
8726 * automatically called by the constructor, and sets up all DOM references for
8727 * pre-existing markup, and creates required markup if it is not already present.
8728 * @param {String} p_oObject String specifying the text of the menu bar item.
8729 * @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-
8730 * one-html.html#ID-74680021">HTMLLIElement</a>} p_oObject Object specifying the
8731 * <code><li></code> element of the menu bar item.
8732 * @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-
8733 * one-html.html#ID-38450247">HTMLOptGroupElement</a>} p_oObject Object
8734 * specifying the <code><optgroup></code> element of the menu bar item.
8735 * @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-
8736 * one-html.html#ID-70901257">HTMLOptionElement</a>} p_oObject Object specifying
8737 * the <code><option></code> element of the menu bar item.
8738 * @param {Object} p_oConfig Optional. Object literal specifying the
8739 * configuration for the menu bar item. See configuration class documentation
8742 init: function(p_oObject
, p_oConfig
) {
8744 if(!this.SUBMENU_TYPE
) {
8746 this.SUBMENU_TYPE
= YAHOO
.widget
.Menu
;
8752 Call the init of the superclass (YAHOO.widget.MenuItem)
8753 Note: We don't pass the user config in here yet
8754 because we only want it executed once, at the lowest
8758 YAHOO
.widget
.MenuBarItem
.superclass
.init
.call(this, p_oObject
);
8761 var oConfig
= this.cfg
;
8765 oConfig
.applyConfig(p_oConfig
, true);
8769 oConfig
.fireQueue();
8779 * @property CSS_CLASS_NAME
8780 * @description String representing the CSS class(es) to be applied to the
8781 * <code><li></code> element of the menu bar item.
8782 * @default "yuimenubaritem"
8786 CSS_CLASS_NAME
: "yuimenubaritem",
8790 * @property CSS_LABEL_CLASS_NAME
8791 * @description String representing the CSS class(es) to be applied to the
8792 * menu bar item's <code><a></code> element.
8793 * @default "yuimenubaritemlabel"
8797 CSS_LABEL_CLASS_NAME
: "yuimenubaritemlabel",
8806 * @description Returns a string representing the menu bar item.
8809 toString: function() {
8811 var sReturnVal
= "MenuBarItem";
8813 if(this.cfg
&& this.cfg
.getProperty("text")) {
8815 sReturnVal
+= (": " + this.cfg
.getProperty("text"));
8823 }); // END YAHOO.lang.extend
8824 YAHOO
.register("menu", YAHOO
.widget
.Menu
, {version
: "2.3.0", build
: "442"});