summaryrefslogtreecommitdiff
path: root/frontend/beta/js/YUI/menu.js
Unidiff
Diffstat (limited to 'frontend/beta/js/YUI/menu.js') (more/less context) (ignore whitespace changes)
-rw-r--r--frontend/beta/js/YUI/menu.js6780
1 files changed, 6780 insertions, 0 deletions
diff --git a/frontend/beta/js/YUI/menu.js b/frontend/beta/js/YUI/menu.js
new file mode 100644
index 0000000..50eb0cf
--- a/dev/null
+++ b/frontend/beta/js/YUI/menu.js
@@ -0,0 +1,6780 @@
1/*
2Copyright (c) 2006, Yahoo! Inc. All rights reserved.
3Code licensed under the BSD License:
4http://developer.yahoo.com/yui/license.txt
5version: 0.12.0
6*/
7
8/**
9* @module menu
10* @description <p>The Menu Library features a collection of widgets that make
11* it easy to add menus to your website or web application. With the Menu
12* Library you can create website fly-out menus, customized context menus, or
13* application-style menu bars with just a small amount of scripting.</p>
14* <ul>
15* <li>Screen-reader accessibility.</li>
16* <li>Keyboard and mouse navigation.</li>
17* <li>A rich event model that provides access to all of a menu's
18* interesting moments.</li>
19* <li>Support for
20* <a href="http://en.wikipedia.org/wiki/Progressive_Enhancement">Progressive
21* Enhancement</a>; Menus can be created from simple,
22* semantic markup on the page or purely through JavaScript.</li>
23* </ul>
24* @title Menu Library
25* @namespace YAHOO.widget
26* @requires Event, Dom, Container
27*/
28(function() {
29
30var Dom = YAHOO.util.Dom;
31var Event = YAHOO.util.Event;
32
33/**
34* Singleton that manages a collection of all menus and menu items. Listens for
35* DOM events at the document level and dispatches the events to the
36* corresponding menu or menu item.
37*
38* @namespace YAHOO.widget
39* @class MenuManager
40* @static
41*/
42YAHOO.widget.MenuManager = new function() {
43
44 // Private member variables
45
46 // Flag indicating if the DOM event handlers have been attached
47
48 var m_bInitializedEventHandlers = false;
49
50 // Collection of menus
51
52 var m_oMenus = {};
53
54
55 // Collection of menu items
56
57 var m_oItems = {};
58
59 // Collection of visible menus
60
61 var m_oVisibleMenus = {};
62
63 // Logger
64
65
66 // Private methods
67
68 /**
69 * Adds an item to the collection of known menu items.
70 * @private
71 * @param {YAHOO.widget.MenuItem} p_oItem Object specifying the MenuItem
72 * instance to be added.
73 */
74 var addItem = function(p_oItem) {
75
76 var sYUIId = Dom.generateId();
77
78 if(p_oItem && m_oItems[sYUIId] != p_oItem) {
79
80 p_oItem.element.setAttribute("yuiid", sYUIId);
81
82 m_oItems[sYUIId] = p_oItem;
83
84 p_oItem.destroyEvent.subscribe(onItemDestroy, p_oItem);
85
86
87 }
88
89 };
90
91 /**
92 * Removes an item from the collection of known menu items.
93 * @private
94 * @param {YAHOO.widget.MenuItem} p_oItem Object specifying the MenuItem
95 * instance to be removed.
96 */
97 var removeItem = function(p_oItem) {
98
99 var sYUIId = p_oItem.element.getAttribute("yuiid");
100
101 if(sYUIId && m_oItems[sYUIId]) {
102
103 delete m_oItems[sYUIId];
104
105
106 }
107
108 };
109
110 /**
111 * Finds the root DIV node of a menu or the root LI node of a menu item.
112 * @private
113 * @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-
114 * one-html.html#ID-58190037">HTMLElement</a>} p_oElement Object specifying
115 * an HTML element.
116 */
117 var getMenuRootElement = function(p_oElement) {
118
119 var oParentNode;
120
121 if(p_oElement && p_oElement.tagName) {
122
123 switch(p_oElement.tagName.toUpperCase()) {
124
125 case "DIV":
126
127 oParentNode = p_oElement.parentNode;
128
129 // Check if the DIV is the inner "body" node of a menu
130
131 if(
132 Dom.hasClass(p_oElement, "bd") &&
133 oParentNode &&
134 oParentNode.tagName &&
135 oParentNode.tagName.toUpperCase() == "DIV"
136 ) {
137
138 return oParentNode;
139
140 }
141 else {
142
143 return p_oElement;
144
145 }
146
147 break;
148
149 case "LI":
150
151 return p_oElement;
152
153 default:
154
155 oParentNode = p_oElement.parentNode;
156
157 if(oParentNode) {
158
159 return getMenuRootElement(oParentNode);
160
161 }
162
163 break;
164
165 }
166
167 }
168
169 };
170
171 // Private event handlers
172
173 /**
174 * Generic, global event handler for all of a menu's DOM-based
175 * events. This listens for events against the document object. If the
176 * target of a given event is a member of a menu or menu item's DOM, the
177 * instance's corresponding Custom Event is fired.
178 * @private
179 * @param {Event} p_oEvent Object representing the DOM event object passed
180 * back by the event utility (YAHOO.util.Event).
181 */
182 var onDOMEvent = function(p_oEvent) {
183
184 // Get the target node of the DOM event
185
186 var oTarget = Event.getTarget(p_oEvent);
187
188 // See if the target of the event was a menu, or a menu item
189
190 var oElement = getMenuRootElement(oTarget);
191
192 var oMenuItem;
193 var oMenu;
194
195 if(oElement) {
196
197 var sTagName = oElement.tagName.toUpperCase();
198
199 if(sTagName == "LI") {
200
201 var sYUIId = oElement.getAttribute("yuiid");
202
203 if(sYUIId) {
204
205 oMenuItem = m_oItems[sYUIId];
206 oMenu = oMenuItem.parent;
207
208 }
209
210 }
211 else if(sTagName == "DIV") {
212
213 if(oElement.id) {
214
215 oMenu = m_oMenus[oElement.id];
216
217 }
218
219 }
220
221 }
222
223 if(oMenu) {
224
225 // Map of DOM event names to CustomEvent names
226
227 var oEventTypes = {
228 "click": "clickEvent",
229 "mousedown": "mouseDownEvent",
230 "mouseup": "mouseUpEvent",
231 "mouseover": "mouseOverEvent",
232 "mouseout": "mouseOutEvent",
233 "keydown": "keyDownEvent",
234 "keyup": "keyUpEvent",
235 "keypress": "keyPressEvent"
236 };
237
238 var sCustomEventType = oEventTypes[p_oEvent.type];
239
240 // Fire the Custom Even that corresponds the current DOM event
241
242 if(oMenuItem && !oMenuItem.cfg.getProperty("disabled")) {
243
244 oMenuItem[sCustomEventType].fire(p_oEvent);
245
246 }
247
248 oMenu[sCustomEventType].fire(p_oEvent, oMenuItem);
249
250 }
251 else if(p_oEvent.type == "mousedown") {
252
253 /*
254 If the target of the event wasn't a menu, hide all
255 dynamically positioned menus
256 */
257
258 var oActiveItem;
259
260 for(var i in m_oMenus) {
261
262 if(m_oMenus.hasOwnProperty(i)) {
263
264 oMenu = m_oMenus[i];
265
266 if(
267 oMenu.cfg.getProperty("clicktohide") &&
268 oMenu.cfg.getProperty("position") == "dynamic"
269 ) {
270
271 oMenu.hide();
272
273 }
274 else {
275
276 oMenu.clearActiveItem(true);
277
278 }
279
280 }
281
282 }
283
284 }
285
286 };
287
288 /**
289 * "destroy" event handler for a menu.
290 * @private
291 * @param {String} p_sType String representing the name of the event that
292 * was fired.
293 * @param {Array} p_aArgs Array of arguments sent when the event was fired.
294 * @param {YAHOO.widget.Menu} p_oMenu Object representing the menu that
295 * fired the event.
296 */
297 var onMenuDestroy = function(p_sType, p_aArgs, p_oMenu) {
298
299 this.removeMenu(p_oMenu);
300
301 };
302
303 /**
304 * "destroy" event handler for a MenuItem instance.
305 * @private
306 * @param {String} p_sType String representing the name of the event that
307 * was fired.
308 * @param {Array} p_aArgs Array of arguments sent when the event was fired.
309 * @param {YAHOO.widget.MenuItem} p_oItem Object representing the menu item
310 * that fired the event.
311 */
312 var onItemDestroy = function(p_sType, p_aArgs, p_oItem) {
313
314 var sYUIId = p_oItem.element.getAttribute("yuiid");
315
316 if(sYUIId) {
317
318 delete m_oItems[sYUIId];
319
320 }
321
322 };
323
324 /**
325 * Event handler for when the "visible" configuration property
326 * of a Menu instance changes.
327 * @private
328 * @param {String} p_sType String representing the name of the event that
329 * was fired.
330 * @param {Array} p_aArgs Array of arguments sent when the event was fired.
331 * @param {YAHOO.widget.Menu} p_oMenu Object representing the menu that
332 * fired the event.
333 */
334 var onMenuVisibleConfigChange = function(p_sType, p_aArgs, p_oMenu) {
335
336 var bVisible = p_aArgs[0];
337
338 if(bVisible) {
339
340 m_oVisibleMenus[p_oMenu.id] = p_oMenu;
341
342
343 }
344 else if(m_oVisibleMenus[p_oMenu.id]) {
345
346 delete m_oVisibleMenus[p_oMenu.id];
347
348
349 }
350
351 };
352
353 /**
354 * "itemadded" event handler for a Menu instance.
355 * @private
356 * @param {String} p_sType String representing the name of the event that
357 * was fired.
358 * @param {Array} p_aArgs Array of arguments sent when the event was fired.
359 */
360 var onItemAdded = function(p_sType, p_aArgs) {
361
362 addItem(p_aArgs[0]);
363
364 };
365
366
367 /**
368 * "itemremoved" event handler for a Menu instance.
369 * @private
370 * @param {String} p_sType String representing the name of the event that
371 * was fired.
372 * @param {Array} p_aArgs Array of arguments sent when the event was fired.
373 */
374 var onItemRemoved = function(p_sType, p_aArgs) {
375
376 removeItem(p_aArgs[0]);
377
378 };
379
380 // Privileged methods
381
382 /**
383 * @method addMenu
384 * @description Adds a menu to the collection of known menus.
385 * @param {YAHOO.widget.Menu} p_oMenu Object specifying the Menu instance
386 * to be added.
387 */
388 this.addMenu = function(p_oMenu) {
389
390 if(p_oMenu && p_oMenu.id && !m_oMenus[p_oMenu.id]) {
391
392 m_oMenus[p_oMenu.id] = p_oMenu;
393
394
395 if(!m_bInitializedEventHandlers) {
396
397 var oDoc = document;
398
399 Event.addListener(oDoc, "mouseover", onDOMEvent, this, true);
400 Event.addListener(oDoc, "mouseout", onDOMEvent, this, true);
401 Event.addListener(oDoc, "mousedown", onDOMEvent, this, true);
402 Event.addListener(oDoc, "mouseup", onDOMEvent, this, true);
403 Event.addListener(oDoc, "click", onDOMEvent, this, true);
404 Event.addListener(oDoc, "keydown", onDOMEvent, this, true);
405 Event.addListener(oDoc, "keyup", onDOMEvent, this, true);
406 Event.addListener(oDoc, "keypress", onDOMEvent, this, true);
407
408 m_bInitializedEventHandlers = true;
409
410
411 }
412
413 p_oMenu.destroyEvent.subscribe(onMenuDestroy, p_oMenu, this);
414
415 p_oMenu.cfg.subscribeToConfigEvent(
416 "visible",
417 onMenuVisibleConfigChange,
418 p_oMenu
419 );
420
421 p_oMenu.itemAddedEvent.subscribe(onItemAdded);
422 p_oMenu.itemRemovedEvent.subscribe(onItemRemoved);
423
424
425 }
426
427 };
428
429 /**
430 * @method removeMenu
431 * @description Removes a menu from the collection of known menus.
432 * @param {YAHOO.widget.Menu} p_oMenu Object specifying the Menu instance
433 * to be removed.
434 */
435 this.removeMenu = function(p_oMenu) {
436
437 if(p_oMenu && m_oMenus[p_oMenu.id]) {
438
439 delete m_oMenus[p_oMenu.id];
440
441
442 }
443
444 };
445
446 /**
447 * @method hideVisible
448 * @description Hides all visible, dynamically positioned menus.
449 */
450 this.hideVisible = function() {
451
452 var oMenu;
453
454 for(var i in m_oVisibleMenus) {
455
456 if(m_oVisibleMenus.hasOwnProperty(i)) {
457
458 oMenu = m_oVisibleMenus[i];
459
460 if(oMenu.cfg.getProperty("position") == "dynamic") {
461
462 oMenu.hide();
463
464 }
465
466 }
467
468 }
469
470 };
471
472 /**
473 * @method getMenus
474 * @description Returns an array of all menus registered with the
475 * menu manger.
476 * @return {Array}
477 */
478 this.getMenus = function() {
479
480 return m_oMenus;
481
482 };
483
484 /**
485 * @method getMenu
486 * @description Returns a menu with the specified id.
487 * @param {String} p_sId String specifying the id of the menu to
488 * be retrieved.
489 * @return {YAHOO.widget.Menu}
490 */
491 this.getMenu = function(p_sId) {
492
493 if(m_oMenus[p_sId]) {
494
495 return m_oMenus[p_sId];
496
497 }
498
499 };
500
501
502 /**
503 * @method toString
504 * @description Returns a string representing the menu manager.
505 * @return {String}
506 */
507 this.toString = function() {
508
509 return ("MenuManager");
510
511 };
512
513};
514
515})();
516
517(function() {
518
519var Dom = YAHOO.util.Dom;
520var Event = YAHOO.util.Event;
521
522/**
523* The Menu class creates a container that holds a vertical list representing
524* a set of options or commands. Menu is the base class for all
525* menu containers.
526* @param {String} p_oElement String specifying the id attribute of the
527* <code>&#60;div&#62;</code> element of the menu.
528* @param {String} p_oElement String specifying the id attribute of the
529* <code>&#60;select&#62;</code> element to be used as the data source
530* for the menu.
531* @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/
532* level-one-html.html#ID-22445964">HTMLDivElement</a>} p_oElement Object
533* specifying the <code>&#60;div&#62;</code> element of the menu.
534* @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/
535* level-one-html.html#ID-94282980">HTMLSelectElement</a>} p_oElement
536* Object specifying the <code>&#60;select&#62;</code> element to be used as
537* the data source for the menu.
538* @param {Object} p_oConfig Optional. Object literal specifying the
539* configuration for the menu. See configuration class documentation for
540* more details.
541* @namespace YAHOO.widget
542* @class Menu
543* @constructor
544* @extends YAHOO.widget.Overlay
545*/
546YAHOO.widget.Menu = function(p_oElement, p_oConfig) {
547
548 if(p_oConfig) {
549
550 this.parent = p_oConfig.parent;
551
552 this.lazyLoad = p_oConfig.lazyLoad || p_oConfig.lazyload;
553
554 this.itemData = p_oConfig.itemData || p_oConfig.itemdata;
555
556 }
557
558 YAHOO.widget.Menu.superclass.constructor.call(
559 this,
560 p_oElement,
561 p_oConfig
562 );
563
564};
565
566YAHOO.extend(YAHOO.widget.Menu, YAHOO.widget.Overlay, {
567
568// Constants
569
570/**
571* @property CSS_CLASS_NAME
572* @description String representing the CSS class(es) to be applied to the
573* menu's <code>&#60;div&#62;</code> element.
574* @default "yuimenu"
575* @final
576* @type String
577*/
578CSS_CLASS_NAME: "yuimenu",
579
580/**
581* @property ITEM_TYPE
582* @description Object representing the type of menu item to instantiate and
583* add when parsing the child nodes (either <code>&#60;li&#62;</code> element,
584* <code>&#60;optgroup&#62;</code> element or <code>&#60;option&#62;</code>)
585* of the menu's source HTML element.
586* @default YAHOO.widget.MenuItem
587* @final
588* @type YAHOO.widget.MenuItem
589*/
590ITEM_TYPE: null,
591
592/**
593* @property GROUP_TITLE_TAG_NAME
594* @description String representing the tagname of the HTML element used to
595* title the menu's item groups.
596* @default H6
597* @final
598* @type String
599*/
600GROUP_TITLE_TAG_NAME: "h6",
601
602// Private properties
603
604/**
605* @property _nHideDelayId
606* @description Number representing the time-out setting used to cancel the
607* hiding of a menu.
608* @default null
609* @private
610* @type Number
611*/
612_nHideDelayId: null,
613
614/**
615* @property _nShowDelayId
616* @description Number representing the time-out setting used to cancel the
617* showing of a menu.
618* @default null
619* @private
620* @type Number
621*/
622_nShowDelayId: null,
623
624/**
625* @property _hideDelayEventHandlersAssigned
626* @description Boolean indicating if the "mouseover" and "mouseout" event
627* handlers used for hiding the menu via a call to "window.setTimeout" have
628* already been assigned.
629* @default false
630* @private
631* @type Boolean
632*/
633_hideDelayEventHandlersAssigned: false,
634
635/**
636* @property _bHandledMouseOverEvent
637* @description Boolean indicating the current state of the menu's
638* "mouseover" event.
639* @default false
640* @private
641* @type Boolean
642*/
643_bHandledMouseOverEvent: false,
644
645/**
646* @property _bHandledMouseOutEvent
647* @description Boolean indicating the current state of the menu's
648* "mouseout" event.
649* @default false
650* @private
651* @type Boolean
652*/
653_bHandledMouseOutEvent: false,
654
655/**
656* @property _aGroupTitleElements
657* @description Array of HTML element used to title groups of menu items.
658* @default []
659* @private
660* @type Array
661*/
662_aGroupTitleElements: null,
663
664/**
665* @property _aItemGroups
666* @description Array of menu items.
667* @default []
668* @private
669* @type Array
670*/
671_aItemGroups: null,
672
673/**
674* @property _aListElements
675* @description Array of <code>&#60;ul&#62;</code> elements, each of which is
676* the parent node for each item's <code>&#60;li&#62;</code> element.
677* @default []
678* @private
679* @type Array
680*/
681_aListElements: null,
682
683// Public properties
684
685/**
686* @property lazyLoad
687* @description Boolean indicating if the menu's "lazy load" feature is
688* enabled. If set to "true," initialization and rendering of the menu's
689* items will be deferred until the first time it is made visible. This
690* property should be set via the constructor using the configuration
691* object literal.
692* @default false
693* @type Boolean
694*/
695lazyLoad: false,
696
697/**
698* @property itemData
699* @description Array of items to be added to the menu. The array can contain
700* strings representing the text for each item to be created, object literals
701* representing the menu item configuration properties, or MenuItem instances.
702* This property should be set via the constructor using the configuration
703* object literal.
704* @default null
705* @type Array
706*/
707itemData: null,
708
709/**
710* @property activeItem
711* @description Object reference to the item in the menu that has focus.
712* @default null
713* @type YAHOO.widget.MenuItem
714*/
715activeItem: null,
716
717/**
718* @property parent
719* @description Object reference to the menu's parent menu or menu item.
720* This property can be set via the constructor using the configuration
721* object literal.
722* @default null
723* @type YAHOO.widget.MenuItem
724*/
725parent: null,
726
727/**
728* @property srcElement
729* @description Object reference to the HTML element (either
730* <code>&#60;select&#62;</code> or <code>&#60;div&#62;</code>) used to
731* create the menu.
732* @default null
733* @type <a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/
734* level-one-html.html#ID-94282980">HTMLSelectElement</a>|<a
735* href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-one-html.
736* html#ID-22445964">HTMLDivElement</a>
737*/
738srcElement: null,
739
740// Events
741
742/**
743* @event mouseOverEvent
744* @description Fires when the mouse has entered the menu. Passes back
745* the DOM Event object as an argument.
746*/
747mouseOverEvent: null,
748
749/**
750* @event mouseOutEvent
751* @description Fires when the mouse has left the menu. Passes back the DOM
752* Event object as an argument.
753* @type YAHOO.util.CustomEvent
754*/
755mouseOutEvent: null,
756
757/**
758* @event mouseDownEvent
759* @description Fires when the user mouses down on the menu. Passes back the
760* DOM Event object as an argument.
761* @type YAHOO.util.CustomEvent
762*/
763mouseDownEvent: null,
764
765/**
766* @event mouseUpEvent
767* @description Fires when the user releases a mouse button while the mouse is
768* over the menu. Passes back the DOM Event object as an argument.
769* @type YAHOO.util.CustomEvent
770*/
771mouseUpEvent: null,
772
773/**
774* @event clickEvent
775* @description Fires when the user clicks the on the menu. Passes back the
776* DOM Event object as an argument.
777* @type YAHOO.util.CustomEvent
778*/
779clickEvent: null,
780
781/**
782* @event keyPressEvent
783* @description Fires when the user presses an alphanumeric key when one of the
784* menu's items has focus. Passes back the DOM Event object as an argument.
785* @type YAHOO.util.CustomEvent
786*/
787keyPressEvent: null,
788
789/**
790* @event keyDownEvent
791* @description Fires when the user presses a key when one of the menu's items
792* has focus. Passes back the DOM Event object as an argument.
793* @type YAHOO.util.CustomEvent
794*/
795keyDownEvent: null,
796
797/**
798* @event keyUpEvent
799* @description Fires when the user releases a key when one of the menu's items
800* has focus. Passes back the DOM Event object as an argument.
801* @type YAHOO.util.CustomEvent
802*/
803keyUpEvent: null,
804
805/**
806* @event itemAddedEvent
807* @description Fires when an item is added to the menu.
808* @type YAHOO.util.CustomEvent
809*/
810itemAddedEvent: null,
811
812/**
813* @event itemRemovedEvent
814* @description Fires when an item is removed to the menu.
815* @type YAHOO.util.CustomEvent
816*/
817itemRemovedEvent: null,
818
819/**
820* @method init
821* @description The Menu class's initialization method. This method is
822* automatically called by the constructor, and sets up all DOM references
823* for pre-existing markup, and creates required markup if it is not
824* already present.
825* @param {String} p_oElement String specifying the id attribute of the
826* <code>&#60;div&#62;</code> element of the menu.
827* @param {String} p_oElement String specifying the id attribute of the
828* <code>&#60;select&#62;</code> element to be used as the data source
829* for the menu.
830* @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/
831* level-one-html.html#ID-22445964">HTMLDivElement</a>} p_oElement Object
832* specifying the <code>&#60;div&#62;</code> element of the menu.
833* @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/
834* level-one-html.html#ID-94282980">HTMLSelectElement</a>} p_oElement
835* Object specifying the <code>&#60;select&#62;</code> element to be used as
836* the data source for the menu.
837* @param {Object} p_oConfig Optional. Object literal specifying the
838* configuration for the menu. See configuration class documentation for
839* more details.
840*/
841init: function(p_oElement, p_oConfig) {
842
843 this._aItemGroups = [];
844 this._aListElements = [];
845 this._aGroupTitleElements = [];
846
847 if(!this.ITEM_TYPE) {
848
849 this.ITEM_TYPE = YAHOO.widget.MenuItem;
850
851 }
852
853 var oElement;
854
855 if(typeof p_oElement == "string") {
856
857 oElement = document.getElementById(p_oElement);
858
859 }
860 else if(p_oElement.tagName) {
861
862 oElement = p_oElement;
863
864 }
865
866 if(oElement && oElement.tagName) {
867
868 switch(oElement.tagName.toUpperCase()) {
869
870 case "DIV":
871
872 this.srcElement = oElement;
873
874 if(!oElement.id) {
875
876 oElement.setAttribute("id", Dom.generateId());
877
878 }
879
880 /*
881 Note: we don't pass the user config in here yet
882 because we only want it executed once, at the lowest
883 subclass level.
884 */
885
886 YAHOO.widget.Menu.superclass.init.call(this, oElement);
887
888 this.beforeInitEvent.fire(YAHOO.widget.Menu);
889
890
891 break;
892
893 case "SELECT":
894
895 this.srcElement = oElement;
896
897
898 /*
899 The source element is not something that we can use
900 outright, so we need to create a new Overlay
901
902 Note: we don't pass the user config in here yet
903 because we only want it executed once, at the lowest
904 subclass level.
905 */
906
907 YAHOO.widget.Menu.superclass.init.call(this, Dom.generateId());
908
909 this.beforeInitEvent.fire(YAHOO.widget.Menu);
910
911 break;
912
913 }
914
915 }
916 else {
917
918 /*
919 Note: we don't pass the user config in here yet
920 because we only want it executed once, at the lowest
921 subclass level.
922 */
923
924 YAHOO.widget.Menu.superclass.init.call(this, p_oElement);
925
926 this.beforeInitEvent.fire(YAHOO.widget.Menu);
927
928 }
929
930 if(this.element) {
931
932 var oEl = this.element;
933
934 Dom.addClass(oEl, this.CSS_CLASS_NAME);
935
936 // Subscribe to Custom Events
937
938 this.initEvent.subscribe(this._onInit, this, true);
939 this.beforeRenderEvent.subscribe(this._onBeforeRender, this, true);
940 this.renderEvent.subscribe(this._onRender, this, true);
941 this.beforeShowEvent.subscribe(this._onBeforeShow, this, true);
942 this.showEvent.subscribe(this._onShow, this, true);
943 this.beforeHideEvent.subscribe(this._onBeforeHide, this, true);
944 this.mouseOverEvent.subscribe(this._onMouseOver, this, true);
945 this.mouseOutEvent.subscribe(this._onMouseOut, this, true);
946 this.clickEvent.subscribe(this._onClick, this, true);
947 this.keyDownEvent.subscribe(this._onKeyDown, this, true);
948
949 if(p_oConfig) {
950
951 this.cfg.applyConfig(p_oConfig, true);
952
953 }
954
955 // Register the Menu instance with the MenuManager
956
957 YAHOO.widget.MenuManager.addMenu(this);
958
959
960 this.initEvent.fire(YAHOO.widget.Menu);
961
962 }
963
964},
965
966// Private methods
967
968/**
969* @method _initSubTree
970* @description Iterates the childNodes of the source element to find nodes
971* used to instantiate menu and menu items.
972* @private
973*/
974_initSubTree: function() {
975
976 var oNode;
977
978 if(this.srcElement.tagName == "DIV") {
979
980 /*
981 Populate the collection of item groups and item
982 group titles
983 */
984
985 oNode = this.body.firstChild;
986
987 var nGroup = 0;
988 var sGroupTitleTagName = this.GROUP_TITLE_TAG_NAME.toUpperCase();
989
990 do {
991
992 if(oNode && oNode.tagName) {
993
994 switch(oNode.tagName.toUpperCase()) {
995
996 case sGroupTitleTagName:
997
998 this._aGroupTitleElements[nGroup] = oNode;
999
1000 break;
1001
1002 case "UL":
1003
1004 this._aListElements[nGroup] = oNode;
1005 this._aItemGroups[nGroup] = [];
1006 nGroup++;
1007
1008 break;
1009
1010 }
1011
1012 }
1013
1014 }
1015 while((oNode = oNode.nextSibling));
1016
1017 /*
1018 Apply the "first-of-type" class to the first UL to mimic
1019 the "first-of-type" CSS3 psuedo class.
1020 */
1021
1022 if(this._aListElements[0]) {
1023
1024 Dom.addClass(this._aListElements[0], "first-of-type");
1025
1026 }
1027
1028 }
1029
1030 oNode = null;
1031
1032 if(this.srcElement.tagName) {
1033
1034 switch(this.srcElement.tagName.toUpperCase()) {
1035
1036 case "DIV":
1037
1038 if(this._aListElements.length > 0) {
1039
1040
1041 var i = this._aListElements.length - 1;
1042
1043 do {
1044
1045 oNode = this._aListElements[i].firstChild;
1046
1047
1048 do {
1049
1050 if(oNode && oNode.tagName) {
1051
1052 switch(oNode.tagName.toUpperCase()) {
1053
1054 case "LI":
1055
1056
1057 this.addItem(
1058 new this.ITEM_TYPE(
1059 oNode,
1060 { parent: this }
1061 ),
1062 i
1063 );
1064
1065 break;
1066
1067 }
1068
1069 }
1070
1071 }
1072 while((oNode = oNode.nextSibling));
1073
1074 }
1075 while(i--);
1076
1077 }
1078
1079 break;
1080
1081 case "SELECT":
1082
1083
1084 oNode = this.srcElement.firstChild;
1085
1086 do {
1087
1088 if(oNode && oNode.tagName) {
1089
1090 switch(oNode.tagName.toUpperCase()) {
1091
1092 case "OPTGROUP":
1093 case "OPTION":
1094
1095
1096 this.addItem(
1097 new this.ITEM_TYPE(
1098 oNode,
1099 { parent: this }
1100 )
1101 );
1102
1103 break;
1104
1105 }
1106
1107 }
1108
1109 }
1110 while((oNode = oNode.nextSibling));
1111
1112 break;
1113
1114 }
1115
1116 }
1117
1118},
1119
1120/**
1121* @method _getFirstEnabledItem
1122* @description Returns the first enabled item in the menu.
1123* @return {YAHOO.widget.MenuItem}
1124* @private
1125*/
1126_getFirstEnabledItem: function() {
1127
1128 var nGroups = this._aItemGroups.length;
1129 var oItem;
1130 var aItemGroup;
1131
1132 for(var i=0; i<nGroups; i++) {
1133
1134 aItemGroup = this._aItemGroups[i];
1135
1136 if(aItemGroup) {
1137
1138 var nItems = aItemGroup.length;
1139
1140 for(var n=0; n<nItems; n++) {
1141
1142 oItem = aItemGroup[n];
1143
1144 if(
1145 !oItem.cfg.getProperty("disabled") &&
1146 oItem.element.style.display != "none"
1147 ) {
1148
1149 return oItem;
1150
1151 }
1152
1153 oItem = null;
1154
1155 }
1156
1157 }
1158
1159 }
1160
1161},
1162
1163/**
1164* @method _checkPosition
1165* @description Checks to make sure that the value of the "position" property
1166* is one of the supported strings. Returns true if the position is supported.
1167* @private
1168* @param {Object} p_sPosition String specifying the position of the menu.
1169* @return {Boolean}
1170*/
1171_checkPosition: function(p_sPosition) {
1172
1173 if(typeof p_sPosition == "string") {
1174
1175 var sPosition = p_sPosition.toLowerCase();
1176
1177 return ("dynamic,static".indexOf(sPosition) != -1);
1178
1179 }
1180
1181},
1182
1183/**
1184* @method _addItemToGroup
1185* @description Adds a menu item to a group.
1186* @private
1187* @param {Number} p_nGroupIndex Number indicating the group to which the
1188* item belongs.
1189* @param {YAHOO.widget.MenuItem} p_oItem Object reference for the MenuItem
1190* instance to be added to the menu.
1191* @param {String} p_oItem String specifying the text of the item to be added
1192* to the menu.
1193* @param {Object} p_oItem Object literal containing a set of menu item
1194* configuration properties.
1195* @param {Number} p_nItemIndex Optional. Number indicating the index at
1196* which the menu item should be added.
1197* @return {YAHOO.widget.MenuItem}
1198*/
1199_addItemToGroup: function(p_nGroupIndex, p_oItem, p_nItemIndex) {
1200
1201 var oItem;
1202
1203 if(p_oItem instanceof this.ITEM_TYPE) {
1204
1205 oItem = p_oItem;
1206 oItem.parent = this;
1207
1208 }
1209 else if(typeof p_oItem == "string") {
1210
1211 oItem = new this.ITEM_TYPE(p_oItem, { parent: this });
1212
1213 }
1214 else if(typeof p_oItem == "object" && p_oItem.text) {
1215
1216 var sText = p_oItem.text;
1217
1218 delete p_oItem["text"];
1219
1220 p_oItem.parent = this;
1221
1222 oItem = new this.ITEM_TYPE(sText, p_oItem);
1223
1224 }
1225
1226 if(oItem) {
1227
1228 var nGroupIndex = typeof p_nGroupIndex == "number" ? p_nGroupIndex : 0;
1229
1230 var aGroup = this._getItemGroup(nGroupIndex);
1231
1232 var oGroupItem;
1233
1234 if(!aGroup) {
1235
1236 aGroup = this._createItemGroup(nGroupIndex);
1237
1238 }
1239
1240 if(typeof p_nItemIndex == "number") {
1241
1242 var bAppend = (p_nItemIndex >= aGroup.length);
1243
1244 if(aGroup[p_nItemIndex]) {
1245
1246 aGroup.splice(p_nItemIndex, 0, oItem);
1247
1248 }
1249 else {
1250
1251 aGroup[p_nItemIndex] = oItem;
1252
1253 }
1254
1255 oGroupItem = aGroup[p_nItemIndex];
1256
1257 if(oGroupItem) {
1258
1259 if(
1260 bAppend &&
1261 (
1262 !oGroupItem.element.parentNode ||
1263 oGroupItem.element.parentNode.nodeType == 11
1264 )
1265 ) {
1266
1267 this._aListElements[nGroupIndex].appendChild(
1268 oGroupItem.element
1269 );
1270
1271 }
1272 else {
1273
1274
1275 /**
1276 * Returns the next sibling of an item in an array.
1277 * @private
1278 * @param {p_aArray} Array to search.
1279 * @param {p_nStartIndex} Number indicating the index to
1280 * start searching the array.
1281 * @return {Object}
1282 */
1283 var getNextItemSibling =
1284
1285 function(p_aArray, p_nStartIndex) {
1286
1287 return (
1288 p_aArray[p_nStartIndex] ||
1289 getNextItemSibling(
1290 p_aArray,
1291 (p_nStartIndex+1)
1292 )
1293 );
1294
1295 };
1296
1297
1298 var oNextItemSibling =
1299 getNextItemSibling(aGroup, (p_nItemIndex+1));
1300
1301 if(
1302 oNextItemSibling &&
1303 (
1304 !oGroupItem.element.parentNode ||
1305 oGroupItem.element.parentNode.nodeType == 11
1306 )
1307 ) {
1308
1309 this._aListElements[nGroupIndex].insertBefore(
1310 oGroupItem.element,
1311 oNextItemSibling.element
1312 );
1313
1314 }
1315
1316 }
1317
1318
1319 oGroupItem.parent = this;
1320
1321 this._subscribeToItemEvents(oGroupItem);
1322
1323 this._configureSubmenu(oGroupItem);
1324
1325 this._updateItemProperties(nGroupIndex);
1326
1327
1328 this.itemAddedEvent.fire(oGroupItem);
1329
1330 return oGroupItem;
1331
1332 }
1333
1334 }
1335 else {
1336
1337 var nItemIndex = aGroup.length;
1338
1339 aGroup[nItemIndex] = oItem;
1340
1341 oGroupItem = aGroup[nItemIndex];
1342
1343
1344 if(oGroupItem) {
1345
1346 if(
1347 !Dom.isAncestor(
1348 this._aListElements[nGroupIndex],
1349 oGroupItem.element
1350 )
1351 ) {
1352
1353 this._aListElements[nGroupIndex].appendChild(
1354 oGroupItem.element
1355 );
1356
1357 }
1358
1359 oGroupItem.element.setAttribute("groupindex", nGroupIndex);
1360 oGroupItem.element.setAttribute("index", nItemIndex);
1361
1362 oGroupItem.parent = this;
1363
1364 oGroupItem.index = nItemIndex;
1365 oGroupItem.groupIndex = nGroupIndex;
1366
1367 this._subscribeToItemEvents(oGroupItem);
1368
1369 this._configureSubmenu(oGroupItem);
1370
1371 if(nItemIndex === 0) {
1372
1373 Dom.addClass(oGroupItem.element, "first-of-type");
1374
1375 }
1376
1377
1378
1379 this.itemAddedEvent.fire(oGroupItem);
1380
1381 return oGroupItem;
1382
1383 }
1384
1385 }
1386
1387 }
1388
1389},
1390
1391/**
1392* @method _removeItemFromGroupByIndex
1393* @description Removes a menu item from a group by index. Returns the menu
1394* item that was removed.
1395* @private
1396* @param {Number} p_nGroupIndex Number indicating the group to which the menu
1397* item belongs.
1398* @param {Number} p_nItemIndex Number indicating the index of the menu item
1399* to be removed.
1400* @return {YAHOO.widget.MenuItem}
1401*/
1402_removeItemFromGroupByIndex: function(p_nGroupIndex, p_nItemIndex) {
1403
1404 var nGroupIndex = typeof p_nGroupIndex == "number" ? p_nGroupIndex : 0;
1405 var aGroup = this._getItemGroup(nGroupIndex);
1406
1407 if(aGroup) {
1408
1409 var aArray = aGroup.splice(p_nItemIndex, 1);
1410 var oItem = aArray[0];
1411
1412 if(oItem) {
1413
1414 // Update the index and className properties of each member
1415
1416 this._updateItemProperties(nGroupIndex);
1417
1418 if(aGroup.length === 0) {
1419
1420 // Remove the UL
1421
1422 var oUL = this._aListElements[nGroupIndex];
1423
1424 if(this.body && oUL) {
1425
1426 this.body.removeChild(oUL);
1427
1428 }
1429
1430 // Remove the group from the array of items
1431
1432 this._aItemGroups.splice(nGroupIndex, 1);
1433
1434
1435 // Remove the UL from the array of ULs
1436
1437 this._aListElements.splice(nGroupIndex, 1);
1438
1439
1440 /*
1441 Assign the "first-of-type" class to the new first UL
1442 in the collection
1443 */
1444
1445 oUL = this._aListElements[0];
1446
1447 if(oUL) {
1448
1449 Dom.addClass(oUL, "first-of-type");
1450
1451 }
1452
1453 }
1454
1455
1456 this.itemRemovedEvent.fire(oItem);
1457
1458 // Return a reference to the item that was removed
1459
1460 return oItem;
1461
1462 }
1463
1464 }
1465
1466},
1467
1468/**
1469* @method _removeItemFromGroupByValue
1470* @description Removes a menu item from a group by reference. Returns the
1471* menu item that was removed.
1472* @private
1473* @param {Number} p_nGroupIndex Number indicating the group to which the
1474* menu item belongs.
1475* @param {YAHOO.widget.MenuItem} p_oItem Object reference for the MenuItem
1476* instance to be removed.
1477* @return {YAHOO.widget.MenuItem}
1478*/
1479_removeItemFromGroupByValue: function(p_nGroupIndex, p_oItem) {
1480
1481 var aGroup = this._getItemGroup(p_nGroupIndex);
1482
1483 if(aGroup) {
1484
1485 var nItems = aGroup.length;
1486 var nItemIndex = -1;
1487
1488 if(nItems > 0) {
1489
1490 var i = nItems-1;
1491
1492 do {
1493
1494 if(aGroup[i] == p_oItem) {
1495
1496 nItemIndex = i;
1497 break;
1498
1499 }
1500
1501 }
1502 while(i--);
1503
1504 if(nItemIndex > -1) {
1505
1506 return this._removeItemFromGroupByIndex(
1507 p_nGroupIndex,
1508 nItemIndex
1509 );
1510
1511 }
1512
1513 }
1514
1515 }
1516
1517},
1518
1519/**
1520* @method _updateItemProperties
1521* @description Updates the "index," "groupindex," and "className" properties
1522* of the menu items in the specified group.
1523* @private
1524* @param {Number} p_nGroupIndex Number indicating the group of items to update.
1525*/
1526_updateItemProperties: function(p_nGroupIndex) {
1527
1528 var aGroup = this._getItemGroup(p_nGroupIndex);
1529 var nItems = aGroup.length;
1530
1531 if(nItems > 0) {
1532
1533 var i = nItems - 1;
1534 var oItem;
1535 var oLI;
1536
1537 // Update the index and className properties of each member
1538
1539 do {
1540
1541 oItem = aGroup[i];
1542
1543 if(oItem) {
1544
1545 oLI = oItem.element;
1546
1547 oItem.index = i;
1548 oItem.groupIndex = p_nGroupIndex;
1549
1550 oLI.setAttribute("groupindex", p_nGroupIndex);
1551 oLI.setAttribute("index", i);
1552
1553 Dom.removeClass(oLI, "first-of-type");
1554
1555 }
1556
1557 }
1558 while(i--);
1559
1560 if(oLI) {
1561
1562 Dom.addClass(oLI, "first-of-type");
1563
1564 }
1565
1566 }
1567
1568},
1569
1570/**
1571* @method _createItemGroup
1572* @description Creates a new menu item group (array) and its associated
1573* <code>&#60;ul&#62;</code> element. Returns an aray of menu item groups.
1574* @private
1575* @param {Number} p_nIndex Number indicating the group to create.
1576* @return {Array}
1577*/
1578_createItemGroup: function(p_nIndex) {
1579
1580 if(!this._aItemGroups[p_nIndex]) {
1581
1582 this._aItemGroups[p_nIndex] = [];
1583
1584 var oUL = document.createElement("ul");
1585
1586 this._aListElements[p_nIndex] = oUL;
1587
1588 return this._aItemGroups[p_nIndex];
1589
1590 }
1591
1592},
1593
1594/**
1595* @method _getItemGroup
1596* @description Returns the menu item group at the specified index.
1597* @private
1598* @param {Number} p_nIndex Number indicating the index of the menu item group
1599* to be retrieved.
1600* @return {Array}
1601*/
1602_getItemGroup: function(p_nIndex) {
1603
1604 var nIndex = ((typeof p_nIndex == "number") ? p_nIndex : 0);
1605
1606 return this._aItemGroups[nIndex];
1607
1608},
1609
1610/**
1611* @method _configureSubmenu
1612* @description Subscribes the menu item's submenu to its parent menu's events.
1613* @private
1614* @param {YAHOO.widget.MenuItem} p_oItem Object reference for the MenuItem
1615* instance with the submenu to be configured.
1616*/
1617_configureSubmenu: function(p_oItem) {
1618
1619 var oSubmenu = p_oItem.cfg.getProperty("submenu");
1620
1621 if(oSubmenu) {
1622
1623 /*
1624 Listen for configuration changes to the parent menu
1625 so they they can be applied to the submenu.
1626 */
1627
1628 this.cfg.configChangedEvent.subscribe(
1629 this._onParentMenuConfigChange,
1630 oSubmenu,
1631 true
1632 );
1633
1634 this.renderEvent.subscribe(
1635 this._onParentMenuRender,
1636 oSubmenu,
1637 true
1638 );
1639
1640 oSubmenu.beforeShowEvent.subscribe(
1641 this._onSubmenuBeforeShow,
1642 oSubmenu,
1643 true
1644 );
1645
1646 oSubmenu.showEvent.subscribe(
1647 this._onSubmenuShow,
1648 oSubmenu,
1649 true
1650 );
1651
1652 oSubmenu.hideEvent.subscribe(
1653 this._onSubmenuHide,
1654 oSubmenu,
1655 true
1656 );
1657
1658 }
1659
1660},
1661
1662/**
1663* @method _subscribeToItemEvents
1664* @description Subscribes a menu to a menu item's event.
1665* @private
1666* @param {YAHOO.widget.MenuItem} p_oItem Object reference for the MenuItem
1667* instance whose events should be subscribed to.
1668*/
1669_subscribeToItemEvents: function(p_oItem) {
1670
1671 p_oItem.focusEvent.subscribe(this._onMenuItemFocus, p_oItem, this);
1672
1673 p_oItem.blurEvent.subscribe(this._onMenuItemBlur, this, true);
1674
1675 p_oItem.cfg.configChangedEvent.subscribe(
1676 this._onMenuItemConfigChange,
1677 p_oItem,
1678 this
1679 );
1680
1681},
1682
1683/**
1684* @method _getOffsetWidth
1685* @description Returns the offset width of the menu's
1686* <code>&#60;div&#62;</code> element.
1687* @private
1688*/
1689_getOffsetWidth: function() {
1690
1691 var oClone = this.element.cloneNode(true);
1692
1693 Dom.setStyle(oClone, "width", "");
1694
1695 document.body.appendChild(oClone);
1696
1697 var sWidth = oClone.offsetWidth;
1698
1699 document.body.removeChild(oClone);
1700
1701 return sWidth;
1702
1703},
1704
1705/**
1706* @method _cancelHideDelay
1707* @description Cancels the call to "hideMenu."
1708* @private
1709*/
1710_cancelHideDelay: function() {
1711
1712 var oRoot = this.getRoot();
1713
1714 if(oRoot._nHideDelayId) {
1715
1716 window.clearTimeout(oRoot._nHideDelayId);
1717
1718 }
1719
1720},
1721
1722/**
1723* @method _execHideDelay
1724* @description Hides the menu after the number of milliseconds specified by
1725* the "hidedelay" configuration property.
1726* @private
1727*/
1728_execHideDelay: function() {
1729
1730 this._cancelHideDelay();
1731
1732 var oRoot = this.getRoot();
1733 var me = this;
1734
1735 var hideMenu = function() {
1736
1737 if(oRoot.activeItem) {
1738
1739 oRoot.clearActiveItem();
1740
1741 }
1742
1743 if(oRoot == me && me.cfg.getProperty("position") == "dynamic") {
1744
1745 me.hide();
1746
1747 }
1748
1749 };
1750
1751 oRoot._nHideDelayId =
1752 window.setTimeout(hideMenu, oRoot.cfg.getProperty("hidedelay"));
1753
1754},
1755
1756/**
1757* @method _cancelShowDelay
1758* @description Cancels the call to the "showMenu."
1759* @private
1760*/
1761_cancelShowDelay: function() {
1762
1763 var oRoot = this.getRoot();
1764
1765 if(oRoot._nShowDelayId) {
1766
1767 window.clearTimeout(oRoot._nShowDelayId);
1768
1769 }
1770
1771},
1772
1773/**
1774* @method _execShowDelay
1775* @description Shows the menu after the number of milliseconds specified by
1776* the "showdelay" configuration property have ellapsed.
1777* @private
1778* @param {YAHOO.widget.Menu} p_oMenu Object specifying the menu that should
1779* be made visible.
1780*/
1781_execShowDelay: function(p_oMenu) {
1782
1783 this._cancelShowDelay();
1784
1785 var oRoot = this.getRoot();
1786
1787 var showMenu = function() {
1788
1789 p_oMenu.show();
1790
1791 };
1792
1793 oRoot._nShowDelayId =
1794 window.setTimeout(showMenu, oRoot.cfg.getProperty("showdelay"));
1795
1796},
1797
1798// Protected methods
1799
1800/**
1801* @method _onMouseOver
1802* @description "mouseover" event handler for the menu.
1803* @protected
1804* @param {String} p_sType String representing the name of the event that
1805* was fired.
1806* @param {Array} p_aArgs Array of arguments sent when the event was fired.
1807* @param {YAHOO.widget.Menu} p_oMenu Object representing the menu that
1808* fired the event.
1809*/
1810_onMouseOver: function(p_sType, p_aArgs, p_oMenu) {
1811
1812 var oEvent = p_aArgs[0];
1813 var oItem = p_aArgs[1];
1814 var oTarget = Event.getTarget(oEvent);
1815
1816 if(
1817 !this._bHandledMouseOverEvent &&
1818 (oTarget == this.element || Dom.isAncestor(this.element, oTarget))
1819 ) {
1820
1821 // MENU MOUSEOVER LOGIC HERE
1822
1823 this.clearActiveItem();
1824
1825 this._bHandledMouseOverEvent = true;
1826 this._bHandledMouseOutEvent = false;
1827
1828 }
1829
1830 if(
1831 oItem && !oItem.handledMouseOverEvent &&
1832 (oTarget == oItem.element || Dom.isAncestor(oItem.element, oTarget))
1833 ) {
1834
1835 var oItemCfg = oItem.cfg;
1836
1837 // Select and focus the current menu item
1838
1839 oItemCfg.setProperty("selected", true);
1840 oItem.focus();
1841
1842 if(this.cfg.getProperty("autosubmenudisplay")) {
1843
1844 // Show the submenu this menu item
1845
1846 var oSubmenu = oItemCfg.getProperty("submenu");
1847
1848 if(oSubmenu) {
1849
1850 if(this.cfg.getProperty("showdelay") > 0) {
1851
1852 this._execShowDelay(oSubmenu);
1853
1854 }
1855 else {
1856
1857 oSubmenu.show();
1858
1859 }
1860
1861 }
1862
1863 }
1864
1865 oItem.handledMouseOverEvent = true;
1866 oItem.handledMouseOutEvent = false;
1867
1868 }
1869
1870},
1871
1872/**
1873* @method _onMouseOut
1874* @description "mouseout" event handler for the menu.
1875* @protected
1876* @param {String} p_sType String representing the name of the event that
1877* was fired.
1878* @param {Array} p_aArgs Array of arguments sent when the event was fired.
1879* @param {YAHOO.widget.Menu} p_oMenu Object representing the menu that
1880* fired the event.
1881*/
1882_onMouseOut: function(p_sType, p_aArgs, p_oMenu) {
1883
1884 var oEvent = p_aArgs[0];
1885 var oItem = p_aArgs[1];
1886 var oRelatedTarget = Event.getRelatedTarget(oEvent);
1887 var bMovingToSubmenu = false;
1888
1889 if(oItem) {
1890
1891 var oItemCfg = oItem.cfg;
1892 var oSubmenu = oItemCfg.getProperty("submenu");
1893
1894 if(
1895 oSubmenu &&
1896 (
1897 oRelatedTarget == oSubmenu.element ||
1898 Dom.isAncestor(oSubmenu.element, oRelatedTarget)
1899 )
1900 ) {
1901
1902 bMovingToSubmenu = true;
1903
1904 }
1905
1906 if(
1907 !oItem.handledMouseOutEvent &&
1908 (
1909 (
1910 oRelatedTarget != oItem.element &&
1911 !Dom.isAncestor(oItem.element, oRelatedTarget)
1912 ) || bMovingToSubmenu
1913 )
1914 ) {
1915
1916 if(this.cfg.getProperty("showdelay") > 0) {
1917
1918 this._cancelShowDelay();
1919
1920 }
1921
1922 if(!bMovingToSubmenu) {
1923
1924 oItemCfg.setProperty("selected", false);
1925
1926 }
1927
1928 if(this.cfg.getProperty("autosubmenudisplay")) {
1929
1930 if(oSubmenu) {
1931
1932 if(
1933 !(
1934 oRelatedTarget == oSubmenu.element ||
1935 YAHOO.util.Dom.isAncestor(
1936 oSubmenu.element,
1937 oRelatedTarget
1938 )
1939 )
1940 ) {
1941
1942 oSubmenu.hide();
1943
1944 }
1945
1946 }
1947
1948 }
1949
1950 oItem.handledMouseOutEvent = true;
1951 oItem.handledMouseOverEvent = false;
1952
1953 }
1954
1955 }
1956
1957 if(
1958 !this._bHandledMouseOutEvent &&
1959 (
1960 (
1961 oRelatedTarget != this.element &&
1962 !Dom.isAncestor(this.element, oRelatedTarget)
1963 )
1964 || bMovingToSubmenu
1965 )
1966 ) {
1967
1968 this._bHandledMouseOutEvent = true;
1969 this._bHandledMouseOverEvent = false;
1970
1971 }
1972
1973},
1974
1975/**
1976* @method _onClick
1977* @description "click" event handler for the menu.
1978* @protected
1979* @param {String} p_sType String representing the name of the event that
1980* was fired.
1981* @param {Array} p_aArgs Array of arguments sent when the event was fired.
1982* @param {YAHOO.widget.Menu} p_oMenu Object representing the menu that
1983* fired the event.
1984*/
1985_onClick: function(p_sType, p_aArgs, p_oMenu) {
1986
1987 var oEvent = p_aArgs[0];
1988 var oItem = p_aArgs[1];
1989 var oTarget = Event.getTarget(oEvent);
1990
1991 if(oItem) {
1992
1993 var oItemCfg = oItem.cfg;
1994 var oSubmenu = oItemCfg.getProperty("submenu");
1995
1996 /*
1997 ACCESSIBILITY FEATURE FOR SCREEN READERS:
1998 Expand/collapse the submenu when the user clicks
1999 on the submenu indicator image.
2000 */
2001
2002 if(oTarget == oItem.submenuIndicator && oSubmenu) {
2003
2004 if(oSubmenu.cfg.getProperty("visible")) {
2005
2006 oSubmenu.hide();
2007
2008 }
2009 else {
2010
2011 this.clearActiveItem();
2012
2013 this.activeItem = oItem;
2014
2015 oItem.cfg.setProperty("selected", true);
2016
2017 oSubmenu.show();
2018
2019 }
2020
2021 }
2022 else {
2023
2024 var sURL = oItemCfg.getProperty("url");
2025 var bCurrentPageURL = (sURL.substr((sURL.length-1),1) == "#");
2026 var sTarget = oItemCfg.getProperty("target");
2027 var bHasTarget = (sTarget && sTarget.length > 0);
2028
2029 /*
2030 Prevent the browser from following links
2031 equal to "#"
2032 */
2033
2034 if(
2035 oTarget.tagName.toUpperCase() == "A" &&
2036 bCurrentPageURL && !bHasTarget
2037 ) {
2038
2039 Event.preventDefault(oEvent);
2040
2041 }
2042
2043 if(
2044 oTarget.tagName.toUpperCase() != "A" &&
2045 !bCurrentPageURL && !bHasTarget
2046 ) {
2047
2048 /*
2049 Follow the URL of the item regardless of
2050 whether or not the user clicked specifically
2051 on the anchor element.
2052 */
2053
2054 document.location = sURL;
2055
2056 }
2057
2058 /*
2059 If the item doesn't navigate to a URL and it doesn't have
2060 a submenu, then collapse the menu tree.
2061 */
2062
2063 if(bCurrentPageURL && !oSubmenu) {
2064
2065 var oRoot = this.getRoot();
2066
2067 if(oRoot.cfg.getProperty("position") == "static") {
2068
2069 oRoot.clearActiveItem();
2070
2071 }
2072 else {
2073
2074 oRoot.hide();
2075
2076 }
2077
2078 }
2079
2080 }
2081
2082 }
2083
2084},
2085
2086/**
2087* @method _onKeyDown
2088* @description "keydown" event handler for the menu.
2089* @protected
2090* @param {String} p_sType String representing the name of the event that
2091* was fired.
2092* @param {Array} p_aArgs Array of arguments sent when the event was fired.
2093* @param {YAHOO.widget.Menu} p_oMenu Object representing the menu that
2094* fired the event.
2095*/
2096_onKeyDown: function(p_sType, p_aArgs, p_oMenu) {
2097
2098 var oEvent = p_aArgs[0];
2099 var oItem = p_aArgs[1];
2100 var oSubmenu;
2101
2102 if(oItem) {
2103
2104 var oItemCfg = oItem.cfg;
2105 var oParentItem = this.parent;
2106 var oRoot;
2107 var oNextItem;
2108
2109 switch(oEvent.keyCode) {
2110
2111 case 38: // Up arrow
2112 case 40: // Down arrow
2113
2114 if(
2115 oItem == this.activeItem &&
2116 !oItemCfg.getProperty("selected")
2117 ) {
2118
2119 oItemCfg.setProperty("selected", true);
2120
2121 }
2122 else {
2123
2124 oNextItem = (oEvent.keyCode == 38) ?
2125 oItem.getPreviousEnabledSibling() :
2126 oItem.getNextEnabledSibling();
2127
2128 if(oNextItem) {
2129
2130 this.clearActiveItem();
2131
2132 oNextItem.cfg.setProperty("selected", true);
2133 oNextItem.focus();
2134
2135 }
2136
2137 }
2138
2139 Event.preventDefault(oEvent);
2140
2141 break;
2142
2143
2144 case 39: // Right arrow
2145
2146 oSubmenu = oItemCfg.getProperty("submenu");
2147
2148 if(oSubmenu) {
2149
2150 if(!oItemCfg.getProperty("selected")) {
2151
2152 oItemCfg.setProperty("selected", true);
2153
2154 }
2155
2156 oSubmenu.show();
2157
2158 oSubmenu.setInitialSelection();
2159
2160 }
2161 else {
2162
2163 oRoot = this.getRoot();
2164
2165 if(oRoot instanceof YAHOO.widget.MenuBar) {
2166
2167 oNextItem = oRoot.activeItem.getNextEnabledSibling();
2168
2169 if(oNextItem) {
2170
2171 oRoot.clearActiveItem();
2172
2173 oNextItem.cfg.setProperty("selected", true);
2174
2175 oSubmenu = oNextItem.cfg.getProperty("submenu");
2176
2177 if(oSubmenu) {
2178
2179 oSubmenu.show();
2180
2181 }
2182
2183 oNextItem.focus();
2184
2185 }
2186
2187 }
2188
2189 }
2190
2191
2192 Event.preventDefault(oEvent);
2193
2194 break;
2195
2196
2197 case 37: // Left arrow
2198
2199 if(oParentItem) {
2200
2201 var oParentMenu = oParentItem.parent;
2202
2203 if(oParentMenu instanceof YAHOO.widget.MenuBar) {
2204
2205 oNextItem =
2206 oParentMenu.activeItem.getPreviousEnabledSibling();
2207
2208 if(oNextItem) {
2209
2210 oParentMenu.clearActiveItem();
2211
2212 oNextItem.cfg.setProperty("selected", true);
2213
2214 oSubmenu = oNextItem.cfg.getProperty("submenu");
2215
2216 if(oSubmenu) {
2217
2218 oSubmenu.show();
2219
2220 }
2221
2222 oNextItem.focus();
2223
2224 }
2225
2226 }
2227 else {
2228
2229 this.hide();
2230
2231 oParentItem.focus();
2232
2233 }
2234
2235 }
2236
2237 Event.preventDefault(oEvent);
2238
2239 break;
2240
2241 }
2242
2243 }
2244
2245 if(oEvent.keyCode == 27) { // Esc key
2246
2247 if(this.cfg.getProperty("position") == "dynamic") {
2248
2249 this.hide();
2250
2251 if(this.parent) {
2252
2253 this.parent.focus();
2254
2255 }
2256
2257 }
2258 else if(this.activeItem) {
2259
2260 oSubmenu = this.activeItem.cfg.getProperty("submenu");
2261
2262 if(oSubmenu && oSubmenu.cfg.getProperty("visible")) {
2263
2264 oSubmenu.hide();
2265 this.activeItem.focus();
2266
2267 }
2268 else {
2269
2270 this.activeItem.cfg.setProperty("selected", false);
2271 this.activeItem.blur();
2272
2273 }
2274
2275 }
2276
2277 Event.preventDefault(oEvent);
2278
2279 }
2280
2281},
2282
2283// Private methods
2284
2285/**
2286* @method _onInit
2287* @description "init" event handler for the menu.
2288* @private
2289* @param {String} p_sType String representing the name of the event that
2290* was fired.
2291* @param {Array} p_aArgs Array of arguments sent when the event was fired.
2292* @param {YAHOO.widget.Menu} p_oMenu Object representing the menu that
2293* fired the event.
2294*/
2295_onInit: function(p_sType, p_aArgs, p_oMenu) {
2296
2297 if(
2298 (
2299 (this.parent && !this.lazyLoad) ||
2300 (!this.parent && this.cfg.getProperty("position") == "static") ||
2301 (
2302 !this.parent &&
2303 !this.lazyLoad &&
2304 this.cfg.getProperty("position") == "dynamic"
2305 )
2306 ) &&
2307 this.getItemGroups().length === 0
2308 ) {
2309
2310 if(this.srcElement) {
2311
2312 this._initSubTree();
2313
2314 }
2315
2316 if(this.itemData) {
2317
2318 this.addItems(this.itemData);
2319
2320 }
2321
2322 }
2323 else if(this.lazyLoad) {
2324
2325 this.cfg.fireQueue();
2326
2327 }
2328
2329},
2330
2331/**
2332* @method _onBeforeRender
2333* @description "beforerender" event handler for the menu. Appends all of the
2334* <code>&#60;ul&#62;</code>, <code>&#60;li&#62;</code> and their accompanying
2335* title elements to the body element of the menu.
2336* @private
2337* @param {String} p_sType String representing the name of the event that
2338* was fired.
2339* @param {Array} p_aArgs Array of arguments sent when the event was fired.
2340* @param {YAHOO.widget.Menu} p_oMenu Object representing the menu that
2341* fired the event.
2342*/
2343_onBeforeRender: function(p_sType, p_aArgs, p_oMenu) {
2344
2345 var oConfig = this.cfg;
2346 var oEl = this.element;
2347 var nListElements = this._aListElements.length;
2348
2349 if(nListElements > 0) {
2350
2351 var i = 0;
2352 var bFirstList = true;
2353 var oUL;
2354 var oGroupTitle;
2355
2356 do {
2357
2358 oUL = this._aListElements[i];
2359
2360 if(oUL) {
2361
2362 if(bFirstList) {
2363
2364 Dom.addClass(oUL, "first-of-type");
2365 bFirstList = false;
2366
2367 }
2368
2369 if(!Dom.isAncestor(oEl, oUL)) {
2370
2371 this.appendToBody(oUL);
2372
2373 }
2374
2375 oGroupTitle = this._aGroupTitleElements[i];
2376
2377 if(oGroupTitle) {
2378
2379 if(!Dom.isAncestor(oEl, oGroupTitle)) {
2380
2381 oUL.parentNode.insertBefore(oGroupTitle, oUL);
2382
2383 }
2384
2385 Dom.addClass(oUL, "hastitle");
2386
2387 }
2388
2389 }
2390
2391 i++;
2392
2393 }
2394 while(i < nListElements);
2395
2396 }
2397
2398},
2399
2400/**
2401* @method _onRender
2402* @description "render" event handler for the menu.
2403* @private
2404* @param {String} p_sType String representing the name of the event that
2405* was fired.
2406* @param {Array} p_aArgs Array of arguments sent when the event was fired.
2407* @param {YAHOO.widget.Menu} p_oMenu Object representing the menu that
2408* fired the event.
2409*/
2410_onRender: function(p_sType, p_aArgs, p_oMenu) {
2411
2412 if(this.cfg.getProperty("position") == "dynamic") {
2413
2414 var sWidth =
2415 this.element.parentNode.tagName.toUpperCase() == "BODY" ?
2416 this.element.offsetWidth : this._getOffsetWidth();
2417
2418 this.cfg.setProperty("width", (sWidth + "px"));
2419
2420 }
2421
2422},
2423
2424/**
2425* @method _onBeforeShow
2426* @description "beforeshow" event handler for the menu.
2427* @private
2428* @param {String} p_sType String representing the name of the event that
2429* was fired.
2430* @param {Array} p_aArgs Array of arguments sent when the event was fired.
2431* @param {YAHOO.widget.Menu} p_oMenu Object representing the menu that
2432* fired the event.
2433*/
2434_onBeforeShow: function(p_sType, p_aArgs, p_oMenu) {
2435
2436 if(this.lazyLoad && this.getItemGroups().length === 0) {
2437
2438 if(this.srcElement) {
2439
2440 this._initSubTree();
2441
2442 }
2443
2444 if(this.itemData) {
2445
2446 if(
2447 this.parent && this.parent.parent &&
2448 this.parent.parent.srcElement &&
2449 this.parent.parent.srcElement.tagName.toUpperCase() == "SELECT"
2450 ) {
2451
2452 var nOptions = this.itemData.length;
2453
2454 for(var n=0; n<nOptions; n++) {
2455
2456 if(this.itemData[n].tagName) {
2457
2458 this.addItem((new this.ITEM_TYPE(this.itemData[n])));
2459
2460 }
2461
2462 }
2463
2464 }
2465 else {
2466
2467 this.addItems(this.itemData);
2468
2469 }
2470
2471 }
2472
2473 if(this.srcElement) {
2474
2475 this.render();
2476
2477 }
2478 else {
2479
2480 if(this.parent) {
2481
2482 this.render(this.parent.element);
2483
2484 }
2485 else {
2486
2487 this.render(this.cfg.getProperty("container"));
2488
2489 }
2490
2491 }
2492
2493 }
2494
2495},
2496
2497/**
2498* @method _onShow
2499* @description "show" event handler for the menu.
2500* @private
2501* @param {String} p_sType String representing the name of the event that
2502* was fired.
2503* @param {Array} p_aArgs Array of arguments sent when the event was fired.
2504* @param {YAHOO.widget.Menu} p_oMenu Object representing the menu that fired
2505* the event.
2506*/
2507_onShow: function(p_sType, p_aArgs, p_oMenu) {
2508
2509 this.setInitialFocus();
2510
2511 var oParent = this.parent;
2512
2513 if(oParent) {
2514
2515 var oParentMenu = oParent.parent;
2516
2517 var aParentAlignment = oParentMenu.cfg.getProperty("submenualignment");
2518 var aAlignment = this.cfg.getProperty("submenualignment");
2519
2520 if(
2521 (aParentAlignment[0] != aAlignment[0]) &&
2522 (aParentAlignment[1] != aAlignment[1])
2523 ) {
2524
2525 this.cfg.setProperty(
2526 "submenualignment",
2527 [ aParentAlignment[0], aParentAlignment[1] ]
2528 );
2529
2530 }
2531
2532 if(
2533 !oParentMenu.cfg.getProperty("autosubmenudisplay") &&
2534 oParentMenu.cfg.getProperty("position") == "static"
2535 ) {
2536
2537 oParentMenu.cfg.setProperty("autosubmenudisplay", true);
2538
2539 /**
2540 * "click" event handler for the document
2541 * @private
2542 * @param {Event} p_oEvent Object reference for the DOM event object
2543 * passed back by the event utility (YAHOO.util.Event).
2544 */
2545 var disableAutoSubmenuDisplay = function(p_oEvent) {
2546
2547 if(
2548 p_oEvent.type == "mousedown" ||
2549 (p_oEvent.type == "keydown" && p_oEvent.keyCode == 27)
2550 ) {
2551
2552 /*
2553 Set the "autosubmenudisplay" to "false" if the user
2554 clicks outside the menu bar.
2555 */
2556
2557 var oTarget = Event.getTarget(p_oEvent);
2558
2559 if(
2560 oTarget != oParentMenu.element ||
2561 !YAHOO.util.Dom.isAncestor(oParentMenu.element, oTarget)
2562 ) {
2563
2564 oParentMenu.cfg.setProperty(
2565 "autosubmenudisplay",
2566 false
2567 );
2568
2569 Event.removeListener(
2570 document,
2571 "mousedown",
2572 disableAutoSubmenuDisplay
2573 );
2574
2575 Event.removeListener(
2576 document,
2577 "keydown",
2578 disableAutoSubmenuDisplay
2579 );
2580
2581 }
2582
2583 }
2584
2585 };
2586
2587 Event.addListener(document, "mousedown", disableAutoSubmenuDisplay);
2588 Event.addListener(document, "keydown", disableAutoSubmenuDisplay);
2589
2590 }
2591
2592 }
2593
2594},
2595
2596/**
2597* @method _onBeforeHide
2598* @description "beforehide" event handler for the menu.
2599* @private
2600* @param {String} p_sType String representing the name of the event that
2601* was fired.
2602* @param {Array} p_aArgs Array of arguments sent when the event was fired.
2603* @param {YAHOO.widget.Menu} p_oMenu Object representing the menu that fired
2604* the event.
2605*/
2606_onBeforeHide: function(p_sType, p_aArgs, p_oMenu) {
2607
2608 this.clearActiveItem(true);
2609
2610},
2611
2612/**
2613* @method _onParentMenuConfigChange
2614* @description "configchange" event handler for a submenu.
2615* @private
2616* @param {String} p_sType String representing the name of the event that
2617* was fired.
2618* @param {Array} p_aArgs Array of arguments sent when the event was fired.
2619* @param {YAHOO.widget.Menu} p_oSubmenu Object representing the submenu that
2620* subscribed to the event.
2621*/
2622_onParentMenuConfigChange: function(p_sType, p_aArgs, p_oSubmenu) {
2623
2624 var sPropertyName = p_aArgs[0][0];
2625 var oPropertyValue = p_aArgs[0][1];
2626
2627 switch(sPropertyName) {
2628
2629 case "iframe":
2630 case "constraintoviewport":
2631 case "hidedelay":
2632 case "showdelay":
2633 case "clicktohide":
2634 case "effect":
2635
2636 p_oSubmenu.cfg.setProperty(sPropertyName, oPropertyValue);
2637
2638 break;
2639
2640 }
2641
2642},
2643
2644/**
2645* @method _onParentMenuRender
2646* @description "render" event handler for a submenu. Renders a
2647* submenu in response to the firing of its parent's "render" event.
2648* @private
2649* @param {String} p_sType String representing the name of the event that
2650* was fired.
2651* @param {Array} p_aArgs Array of arguments sent when the event was fired.
2652* @param {YAHOO.widget.Menu} p_oSubmenu Object representing the submenu that
2653* subscribed to the event.
2654*/
2655_onParentMenuRender: function(p_sType, p_aArgs, p_oSubmenu) {
2656
2657 /*
2658 Set the "constraintoviewport" configuration
2659 property to match the parent Menu
2660 */
2661
2662 var oParentMenu = p_oSubmenu.parent.parent;
2663
2664 var oConfig = {
2665
2666 constraintoviewport:
2667 oParentMenu.cfg.getProperty("constraintoviewport"),
2668
2669 xy: [0,0],
2670
2671 clicktohide:
2672 oParentMenu.cfg.getProperty("clicktohide"),
2673
2674 effect:
2675 oParentMenu.cfg.getProperty("effect")
2676
2677 };
2678
2679 var nShowDelay = oParentMenu.cfg.getProperty("showdelay");
2680
2681 if(nShowDelay > 0) {
2682
2683 oConfig.showdelay = nShowDelay;
2684
2685 }
2686
2687 var nHideDelay = oParentMenu.cfg.getProperty("hidedelay");
2688
2689 if(nHideDelay > 0) {
2690
2691 oConfig.hidedelay = nHideDelay;
2692
2693 }
2694
2695 /*
2696 Only sync the "iframe" configuration property if the parent
2697 menu's "position" configuration is the same.
2698 */
2699
2700 if(
2701 this.cfg.getProperty("position") ==
2702 oParentMenu.cfg.getProperty("position")
2703 ) {
2704
2705 oConfig.iframe = oParentMenu.cfg.getProperty("iframe");
2706
2707 }
2708
2709
2710 p_oSubmenu.cfg.applyConfig(oConfig);
2711
2712 if(!this.lazyLoad) {
2713
2714 if(Dom.inDocument(this.element)) {
2715
2716 this.render();
2717
2718 }
2719 else {
2720
2721 this.render(this.parent.element);
2722
2723 }
2724
2725 }
2726
2727},
2728
2729/**
2730* @method _onSubmenuBeforeShow
2731* @description "beforeshow" event handler for a submenu.
2732* @private
2733* @param {String} p_sType String representing the name of the event that
2734* was fired.
2735* @param {Array} p_aArgs Array of arguments sent when the event was fired.
2736* @param {YAHOO.widget.Menu} p_oSubmenu Object representing the submenu that
2737* subscribed to the event.
2738*/
2739_onSubmenuBeforeShow: function(p_sType, p_aArgs, p_oSubmenu) {
2740
2741 var oParent = this.parent;
2742 var aAlignment = oParent.parent.cfg.getProperty("submenualignment");
2743
2744 this.cfg.setProperty(
2745 "context",
2746 [oParent.element, aAlignment[0], aAlignment[1]]
2747 );
2748
2749 oParent.submenuIndicator.alt = oParent.EXPANDED_SUBMENU_INDICATOR_ALT_TEXT;
2750
2751},
2752
2753/**
2754* @method _onSubmenuShow
2755* @description "show" event handler for a submenu.
2756* @private
2757* @param {String} p_sType String representing the name of the event that
2758* was fired.
2759* @param {Array} p_aArgs Array of arguments sent when the event was fired.
2760* @param {YAHOO.widget.Menu} p_oSubmenu Object representing the submenu that
2761* subscribed to the event.
2762*/
2763_onSubmenuShow: function(p_sType, p_aArgs, p_oSubmenu) {
2764
2765 var oParent = this.parent;
2766
2767 oParent.submenuIndicator.alt = oParent.EXPANDED_SUBMENU_INDICATOR_ALT_TEXT;
2768
2769},
2770
2771/**
2772* @method _onSubmenuHide
2773* @description "hide" Custom Event handler for a submenu.
2774* @private
2775* @param {String} p_sType String representing the name of the event that
2776* was fired.
2777* @param {Array} p_aArgs Array of arguments sent when the event was fired.
2778* @param {YAHOO.widget.Menu} p_oSubmenu Object representing the submenu that
2779* subscribed to the event.
2780*/
2781_onSubmenuHide: function(p_sType, p_aArgs, p_oSubmenu) {
2782
2783 var oParent = this.parent;
2784
2785 oParent.submenuIndicator.alt = oParent.COLLAPSED_SUBMENU_INDICATOR_ALT_TEXT;
2786
2787},
2788
2789/**
2790* @method _onMenuItemFocus
2791* @description "focus" event handler for the menu's items.
2792* @private
2793* @param {String} p_sType String representing the name of the event that
2794* was fired.
2795* @param {Array} p_aArgs Array of arguments sent when the event was fired.
2796* @param {YAHOO.widget.MenuItem} p_oItem Object representing the menu item
2797* that fired the event.
2798*/
2799_onMenuItemFocus: function(p_sType, p_aArgs, p_oItem) {
2800
2801 this.activeItem = p_oItem;
2802
2803},
2804
2805/**
2806* @method _onMenuItemBlur
2807* @description "blur" event handler for the menu's items.
2808* @private
2809* @param {String} p_sType String representing the name of the event
2810* that was fired.
2811* @param {Array} p_aArgs Array of arguments sent when the event was fired.
2812*/
2813_onMenuItemBlur: function(p_sType, p_aArgs) {
2814
2815 this.activeItem = null;
2816
2817},
2818
2819/**
2820* @method _onMenuItemConfigChange
2821* @description "configchange" event handler for the menu's items.
2822* @private
2823* @param {String} p_sType String representing the name of the event that
2824* was fired.
2825* @param {Array} p_aArgs Array of arguments sent when the event was fired.
2826* @param {YAHOO.widget.MenuItem} p_oItem Object representing the menu item
2827* that fired the event.
2828*/
2829_onMenuItemConfigChange: function(p_sType, p_aArgs, p_oItem) {
2830
2831 var sProperty = p_aArgs[0][0];
2832
2833 switch(sProperty) {
2834
2835 case "submenu":
2836
2837 var oSubmenu = p_aArgs[0][1];
2838
2839 if(oSubmenu) {
2840
2841 this._configureSubmenu(p_oItem);
2842
2843 }
2844
2845 break;
2846
2847 case "text":
2848 case "helptext":
2849
2850 /*
2851 A change to an item's "text" or "helptext"
2852 configuration properties requires the width of the parent
2853 menu to be recalculated.
2854 */
2855
2856 if(this.element.style.width) {
2857
2858 var sWidth = this._getOffsetWidth() + "px";
2859
2860 Dom.setStyle(this.element, "width", sWidth);
2861
2862 }
2863
2864 break;
2865
2866 }
2867
2868},
2869
2870// Public event handlers for configuration properties
2871
2872/**
2873* @method enforceConstraints
2874* @description The default event handler executed when the moveEvent is fired,
2875* if the "constraintoviewport" configuration property is set to true.
2876* @param {String} type The name of the event that was fired.
2877* @param {Array} args Collection of arguments sent when the
2878* event was fired.
2879* @param {Array} obj Array containing the current Menu instance
2880* and the item that fired the event.
2881*/
2882enforceConstraints: function(type, args, obj) {
2883
2884 var oConfig = this.cfg;
2885
2886 var pos = args[0];
2887
2888 var x = pos[0];
2889 var y = pos[1];
2890
2891 var bod = document.getElementsByTagName('body')[0];
2892 var htm = document.getElementsByTagName('html')[0];
2893
2894 var bodyOverflow = Dom.getStyle(bod, "overflow");
2895 var htmOverflow = Dom.getStyle(htm, "overflow");
2896
2897 var offsetHeight = this.element.offsetHeight;
2898 var offsetWidth = this.element.offsetWidth;
2899
2900 var viewPortWidth = Dom.getClientWidth();
2901 var viewPortHeight = Dom.getClientHeight();
2902
2903 var scrollX = window.scrollX || document.body.scrollLeft;
2904 var scrollY = window.scrollY || document.body.scrollTop;
2905
2906 var topConstraint = scrollY + 10;
2907 var leftConstraint = scrollX + 10;
2908 var bottomConstraint = scrollY + viewPortHeight - offsetHeight - 10;
2909 var rightConstraint = scrollX + viewPortWidth - offsetWidth - 10;
2910
2911 var aContext = oConfig.getProperty("context");
2912 var oContextElement = aContext ? aContext[0] : null;
2913
2914
2915 if (x < 10) {
2916
2917 x = leftConstraint;
2918
2919 } else if ((x + offsetWidth) > viewPortWidth) {
2920
2921 if(
2922 oContextElement &&
2923 ((x - oContextElement.offsetWidth) > offsetWidth)
2924 ) {
2925
2926 x = (x - (oContextElement.offsetWidth + offsetWidth));
2927
2928 }
2929 else {
2930
2931 x = rightConstraint;
2932
2933 }
2934
2935 }
2936
2937 if (y < 10) {
2938
2939 y = topConstraint;
2940
2941 } else if (y > bottomConstraint) {
2942
2943 if(oContextElement && (y > offsetHeight)) {
2944
2945 y = ((y + oContextElement.offsetHeight) - offsetHeight);
2946
2947 }
2948 else {
2949
2950 y = bottomConstraint;
2951
2952 }
2953
2954 }
2955
2956 oConfig.setProperty("x", x, true);
2957 oConfig.setProperty("y", y, true);
2958
2959},
2960
2961/**
2962* @method configVisible
2963* @description Event handler for when the "visible" configuration property
2964* the menu changes.
2965* @param {String} p_sType String representing the name of the event that
2966* was fired.
2967* @param {Array} p_aArgs Array of arguments sent when the event was fired.
2968* @param {YAHOO.widget.Menu} p_oMenu Object representing the menu that
2969* fired the event.
2970*/
2971configVisible: function(p_sType, p_aArgs, p_oMenu) {
2972
2973 if(this.cfg.getProperty("position") == "dynamic") {
2974
2975 YAHOO.widget.Menu.superclass.configVisible.call(
2976 this,
2977 p_sType,
2978 p_aArgs,
2979 p_oMenu
2980 );
2981
2982 }
2983 else {
2984
2985 var bVisible = p_aArgs[0];
2986 var sDisplay = Dom.getStyle(this.element, "display");
2987
2988 if(bVisible) {
2989
2990 if(sDisplay != "block") {
2991 this.beforeShowEvent.fire();
2992 Dom.setStyle(this.element, "display", "block");
2993 this.showEvent.fire();
2994 }
2995
2996 }
2997 else {
2998
2999 if(sDisplay == "block") {
3000 this.beforeHideEvent.fire();
3001 Dom.setStyle(this.element, "display", "none");
3002 this.hideEvent.fire();
3003 }
3004
3005 }
3006
3007 }
3008
3009},
3010
3011/**
3012* @method configPosition
3013* @description Event handler for when the "position" configuration property
3014* of the menu changes.
3015* @param {String} p_sType String representing the name of the event that
3016* was fired.
3017* @param {Array} p_aArgs Array of arguments sent when the event was fired.
3018* @param {YAHOO.widget.Menu} p_oMenu Object representing the menu that
3019* fired the event.
3020*/
3021configPosition: function(p_sType, p_aArgs, p_oMenu) {
3022
3023 var sCSSPosition = p_aArgs[0] == "static" ? "static" : "absolute";
3024 var oCfg = this.cfg;
3025
3026 Dom.setStyle(this.element, "position", sCSSPosition);
3027
3028 if(sCSSPosition == "static") {
3029
3030 /*
3031 Remove the iframe for statically positioned menus since it will
3032 intercept mouse events.
3033 */
3034
3035 oCfg.setProperty("iframe", false);
3036
3037 // Statically positioned menus are visible by default
3038
3039 Dom.setStyle(this.element, "display", "block");
3040
3041 oCfg.setProperty("visible", true);
3042
3043 }
3044 else {
3045
3046 /*
3047 Even though the "visible" property is queued to
3048 "false" by default, we need to set the "visibility" property to
3049 "hidden" since Overlay's "configVisible" implementation checks the
3050 element's "visibility" style property before deciding whether
3051 or not to show an Overlay instance.
3052 */
3053
3054 Dom.setStyle(this.element, "visibility", "hidden");
3055
3056 }
3057
3058 if(sCSSPosition == "absolute") {
3059
3060 var nZIndex = oCfg.getProperty("zindex");
3061
3062 if(!nZIndex || nZIndex === 0) {
3063
3064 nZIndex = this.parent ?
3065 (this.parent.parent.cfg.getProperty("zindex") + 1) : 1;
3066
3067 oCfg.setProperty("zindex", nZIndex);
3068
3069 }
3070
3071 }
3072
3073},
3074
3075/**
3076* @method configIframe
3077* @description Event handler for when the "iframe" configuration property of
3078* the menu changes.
3079* @param {String} p_sType String representing the name of the event that
3080* was fired.
3081* @param {Array} p_aArgs Array of arguments sent when the event was fired.
3082* @param {YAHOO.widget.Menu} p_oMenu Object representing the menu that
3083* fired the event.
3084*/
3085configIframe: function(p_sType, p_aArgs, p_oMenu) {
3086
3087 if(this.cfg.getProperty("position") == "dynamic") {
3088
3089 YAHOO.widget.Menu.superclass.configIframe.call(
3090 this,
3091 p_sType,
3092 p_aArgs,
3093 p_oMenu
3094 );
3095
3096 }
3097
3098},
3099
3100/**
3101* @method configHideDelay
3102* @description Event handler for when the "hidedelay" configuration property
3103* of the menu changes.
3104* @param {String} p_sType String representing the name of the event that
3105* was fired.
3106* @param {Array} p_aArgs Array of arguments sent when the event was fired.
3107* @param {YAHOO.widget.Menu} p_oMenu Object representing the menu that
3108* fired the event.
3109*/
3110configHideDelay: function(p_sType, p_aArgs, p_oMenu) {
3111
3112 var nHideDelay = p_aArgs[0];
3113 var oMouseOutEvent = this.mouseOutEvent;
3114 var oMouseOverEvent = this.mouseOverEvent;
3115 var oKeyDownEvent = this.keyDownEvent;
3116
3117 if(nHideDelay > 0) {
3118
3119 /*
3120 Only assign event handlers once. This way the user change
3121 the value for the hidedelay as many times as they want.
3122 */
3123
3124 if(!this._hideDelayEventHandlersAssigned) {
3125
3126 oMouseOutEvent.subscribe(this._execHideDelay, true);
3127 oMouseOverEvent.subscribe(this._cancelHideDelay, this, true);
3128 oKeyDownEvent.subscribe(this._cancelHideDelay, this, true);
3129
3130 this._hideDelayEventHandlersAssigned = true;
3131
3132 }
3133
3134 }
3135 else {
3136
3137 oMouseOutEvent.unsubscribe(this._execHideDelay, this);
3138 oMouseOverEvent.unsubscribe(this._cancelHideDelay, this);
3139 oKeyDownEvent.unsubscribe(this._cancelHideDelay, this);
3140
3141 this._hideDelayEventHandlersAssigned = false;
3142
3143 }
3144
3145},
3146
3147/**
3148* @method configContainer
3149* @description Event handler for when the "container" configuration property
3150of the menu changes.
3151* @param {String} p_sType String representing the name of the event that
3152* was fired.
3153* @param {Array} p_aArgs Array of arguments sent when the event was fired.
3154* @param {YAHOO.widget.Menu} p_oMenu Object representing the menu that
3155* fired the event.
3156*/
3157configContainer: function(p_sType, p_aArgs, p_oMenu) {
3158
3159 var oElement = p_aArgs[0];
3160
3161 if(typeof oElement == 'string') {
3162
3163 this.cfg.setProperty(
3164 "container",
3165 document.getElementById(oElement),
3166 true
3167 );
3168
3169 }
3170
3171},
3172
3173// Public methods
3174
3175/**
3176* Event handler called when the resize monitor element's "resize" evet is fired.
3177*/
3178onDomResize: function(e, obj) {
3179
3180 if(!this._handleResize) {
3181
3182 this._handleResize = true;
3183 return;
3184
3185 }
3186
3187 var oConfig = this.cfg;
3188
3189 if(oConfig.getProperty("position") == "dynamic") {
3190
3191 oConfig.setProperty("width", (this._getOffsetWidth() + "px"));
3192
3193 }
3194
3195 YAHOO.widget.Menu.superclass.onDomResize.call(this, e, obj);
3196
3197},
3198
3199/**
3200* @method initEvents
3201* @description Initializes the custom events for the menu.
3202*/
3203initEvents: function() {
3204
3205 YAHOO.widget.Menu.superclass.initEvents.call(this);
3206
3207 // Create custom events
3208
3209 var CustomEvent = YAHOO.util.CustomEvent;
3210
3211 this.mouseOverEvent = new CustomEvent("mouseOverEvent", this);
3212 this.mouseOutEvent = new CustomEvent("mouseOutEvent", this);
3213 this.mouseDownEvent = new CustomEvent("mouseDownEvent", this);
3214 this.mouseUpEvent = new CustomEvent("mouseUpEvent", this);
3215 this.clickEvent = new CustomEvent("clickEvent", this);
3216 this.keyPressEvent = new CustomEvent("keyPressEvent", this);
3217 this.keyDownEvent = new CustomEvent("keyDownEvent", this);
3218 this.keyUpEvent = new CustomEvent("keyUpEvent", this);
3219 this.itemAddedEvent = new CustomEvent("itemAddedEvent", this);
3220 this.itemRemovedEvent = new CustomEvent("itemRemovedEvent", this);
3221
3222},
3223
3224/**
3225* @method getRoot
3226* @description Finds the menu's root menu.
3227*/
3228getRoot: function() {
3229
3230 var oItem = this.parent;
3231
3232 if(oItem) {
3233
3234 var oParentMenu = oItem.parent;
3235
3236 return oParentMenu ? oParentMenu.getRoot() : this;
3237
3238 }
3239 else {
3240
3241 return this;
3242
3243 }
3244
3245},
3246
3247/**
3248* @method toString
3249* @description Returns a string representing the menu.
3250* @return {String}
3251*/
3252toString: function() {
3253
3254 return ("Menu " + this.id);
3255
3256},
3257
3258/**
3259* @method setItemGroupTitle
3260* @description Sets the title of a group of menu items.
3261* @param {String} p_sGroupTitle String specifying the title of the group.
3262* @param {Number} p_nGroupIndex Optional. Number specifying the group to which
3263* the title belongs.
3264*/
3265setItemGroupTitle: function(p_sGroupTitle, p_nGroupIndex) {
3266
3267 if(typeof p_sGroupTitle == "string" && p_sGroupTitle.length > 0) {
3268
3269 var nGroupIndex = typeof p_nGroupIndex == "number" ? p_nGroupIndex : 0;
3270 var oTitle = this._aGroupTitleElements[nGroupIndex];
3271
3272 if(oTitle) {
3273
3274 oTitle.innerHTML = p_sGroupTitle;
3275
3276 }
3277 else {
3278
3279 oTitle = document.createElement(this.GROUP_TITLE_TAG_NAME);
3280
3281 oTitle.innerHTML = p_sGroupTitle;
3282
3283 this._aGroupTitleElements[nGroupIndex] = oTitle;
3284
3285 }
3286
3287 var i = this._aGroupTitleElements.length - 1;
3288 var nFirstIndex;
3289
3290 do {
3291
3292 if(this._aGroupTitleElements[i]) {
3293
3294 Dom.removeClass(this._aGroupTitleElements[i], "first-of-type");
3295
3296 nFirstIndex = i;
3297
3298 }
3299
3300 }
3301 while(i--);
3302
3303 if(nFirstIndex !== null) {
3304
3305 Dom.addClass(
3306 this._aGroupTitleElements[nFirstIndex],
3307 "first-of-type"
3308 );
3309
3310 }
3311
3312 }
3313
3314},
3315
3316/**
3317* @method addItem
3318* @description Appends an item to the menu.
3319* @param {YAHOO.widget.MenuItem} p_oItem Object reference for the MenuItem
3320* instance to be added to the menu.
3321* @param {String} p_oItem String specifying the text of the item to be added
3322* to the menu.
3323* @param {Object} p_oItem Object literal containing a set of menu item
3324* configuration properties.
3325* @param {Number} p_nGroupIndex Optional. Number indicating the group to
3326* which the item belongs.
3327* @return {YAHOO.widget.MenuItem}
3328*/
3329addItem: function(p_oItem, p_nGroupIndex) {
3330
3331 if(p_oItem) {
3332
3333 return this._addItemToGroup(p_nGroupIndex, p_oItem);
3334
3335 }
3336
3337},
3338
3339/**
3340* @method addItems
3341* @description Adds an array of items to the menu.
3342* @param {Array} p_aItems Array of items to be added to the menu. The array
3343* can contain strings specifying the text for each item to be created, object
3344* literals specifying each of the menu item configuration properties,
3345* or MenuItem instances.
3346* @param {Number} p_nGroupIndex Optional. Number specifying the group to
3347* which the items belongs.
3348* @return {Array}
3349*/
3350addItems: function(p_aItems, p_nGroupIndex) {
3351
3352 function isArray(p_oValue) {
3353
3354 return (typeof p_oValue == "object" && p_oValue.constructor == Array);
3355
3356 }
3357
3358 if(isArray(p_aItems)) {
3359
3360 var nItems = p_aItems.length;
3361 var aItems = [];
3362 var oItem;
3363
3364 for(var i=0; i<nItems; i++) {
3365
3366 oItem = p_aItems[i];
3367
3368 if(isArray(oItem)) {
3369
3370 aItems[aItems.length] = this.addItems(oItem, i);
3371
3372 }
3373 else {
3374
3375 aItems[aItems.length] =
3376 this._addItemToGroup(p_nGroupIndex, oItem);
3377
3378 }
3379
3380 }
3381
3382 if(aItems.length) {
3383
3384 return aItems;
3385
3386 }
3387
3388 }
3389
3390},
3391
3392/**
3393* @method insertItem
3394* @description Inserts an item into the menu at the specified index.
3395* @param {YAHOO.widget.MenuItem} p_oItem Object reference for the MenuItem
3396* instance to be added to the menu.
3397* @param {String} p_oItem String specifying the text of the item to be added
3398* to the menu.
3399* @param {Object} p_oItem Object literal containing a set of menu item
3400* configuration properties.
3401* @param {Number} p_nItemIndex Number indicating the ordinal position at which
3402* the item should be added.
3403* @param {Number} p_nGroupIndex Optional. Number indicating the group to which
3404* the item belongs.
3405* @return {YAHOO.widget.MenuItem}
3406*/
3407insertItem: function(p_oItem, p_nItemIndex, p_nGroupIndex) {
3408
3409 if(p_oItem) {
3410
3411 return this._addItemToGroup(p_nGroupIndex, p_oItem, p_nItemIndex);
3412
3413 }
3414
3415},
3416
3417/**
3418* @method removeItem
3419* @description Removes the specified item from the menu.
3420* @param {YAHOO.widget.MenuItem} p_oObject Object reference for the MenuItem
3421* instance to be removed from the menu.
3422* @param {Number} p_oObject Number specifying the index of the item
3423* to be removed.
3424* @param {Number} p_nGroupIndex Optional. Number specifying the group to
3425* which the item belongs.
3426* @return {YAHOO.widget.MenuItem}
3427*/
3428removeItem: function(p_oObject, p_nGroupIndex) {
3429
3430 if(typeof p_oObject != "undefined") {
3431
3432 var oItem;
3433
3434 if(p_oObject instanceof YAHOO.widget.MenuItem) {
3435
3436 oItem = this._removeItemFromGroupByValue(p_nGroupIndex, p_oObject);
3437
3438 }
3439 else if(typeof p_oObject == "number") {
3440
3441 oItem = this._removeItemFromGroupByIndex(p_nGroupIndex, p_oObject);
3442
3443 }
3444
3445 if(oItem) {
3446
3447 oItem.destroy();
3448
3449 return oItem;
3450
3451 }
3452
3453 }
3454
3455},
3456
3457/**
3458* @method getItemGroups
3459* @description Returns a multi-dimensional array of all of the items in the menu.
3460* @return {Array}
3461*/
3462getItemGroups: function() {
3463
3464 return this._aItemGroups;
3465
3466},
3467
3468/**
3469* @method getItem
3470* @description Returns the item at the specified index.
3471* @param {Number} p_nItemIndex Number indicating the ordinal position of the
3472* item to be retrieved.
3473* @param {Number} p_nGroupIndex Optional. Number indicating the group to which
3474* the item belongs.
3475* @return {YAHOO.widget.MenuItem}
3476*/
3477getItem: function(p_nItemIndex, p_nGroupIndex) {
3478
3479 if(typeof p_nItemIndex == "number") {
3480
3481 var aGroup = this._getItemGroup(p_nGroupIndex);
3482
3483 if(aGroup) {
3484
3485 return aGroup[p_nItemIndex];
3486
3487 }
3488
3489 }
3490
3491},
3492
3493/**
3494* @method destroy
3495* @description Removes the menu's <code>&#60;div&#62;</code> element
3496* (and accompanying child nodes) from the document.
3497*/
3498destroy: function() {
3499
3500 // Remove Custom Event listeners
3501
3502 this.mouseOverEvent.unsubscribeAll();
3503 this.mouseOutEvent.unsubscribeAll();
3504 this.mouseDownEvent.unsubscribeAll();
3505 this.mouseUpEvent.unsubscribeAll();
3506 this.clickEvent.unsubscribeAll();
3507 this.keyPressEvent.unsubscribeAll();
3508 this.keyDownEvent.unsubscribeAll();
3509 this.keyUpEvent.unsubscribeAll();
3510
3511 var nItemGroups = this._aItemGroups.length;
3512 var nItems;
3513 var oItemGroup;
3514 var oItem;
3515 var i;
3516 var n;
3517
3518 // Remove all items
3519
3520 if(nItemGroups > 0) {
3521
3522 i = nItemGroups - 1;
3523
3524 do {
3525
3526 oItemGroup = this._aItemGroups[i];
3527
3528 if(oItemGroup) {
3529
3530 nItems = oItemGroup.length;
3531
3532 if(nItems > 0) {
3533
3534 n = nItems - 1;
3535
3536 do {
3537
3538 oItem = this._aItemGroups[i][n];
3539
3540 if(oItem) {
3541
3542 oItem.destroy();
3543 }
3544
3545 }
3546 while(n--);
3547
3548 }
3549
3550 }
3551
3552 }
3553 while(i--);
3554
3555 }
3556
3557 // Continue with the superclass implementation of this method
3558
3559 YAHOO.widget.Menu.superclass.destroy.call(this);
3560
3561
3562},
3563
3564/**
3565* @method setInitialFocus
3566* @description Sets focus to the menu's first enabled item.
3567*/
3568setInitialFocus: function() {
3569
3570 var oItem = this._getFirstEnabledItem();
3571
3572 if(oItem) {
3573
3574 oItem.focus();
3575 }
3576
3577},
3578
3579/**
3580* @method setInitialSelection
3581* @description Sets the "selected" configuration property of the menu's first
3582* enabled item to "true."
3583*/
3584setInitialSelection: function() {
3585
3586 var oItem = this._getFirstEnabledItem();
3587
3588 if(oItem) {
3589
3590 oItem.cfg.setProperty("selected", true);
3591 }
3592
3593},
3594
3595/**
3596* @method clearActiveItem
3597* @description Sets the "selected" configuration property of the menu's active
3598* item to "false" and hides the item's submenu.
3599* @param {Boolean} p_bBlur Boolean indicating if the menu's active item
3600* should be blurred.
3601*/
3602clearActiveItem: function(p_bBlur) {
3603
3604 if(this.cfg.getProperty("showdelay") > 0) {
3605
3606 this._cancelShowDelay();
3607
3608 }
3609
3610 var oActiveItem = this.activeItem;
3611
3612 if(oActiveItem) {
3613
3614 var oConfig = oActiveItem.cfg;
3615
3616 oConfig.setProperty("selected", false);
3617
3618 var oSubmenu = oConfig.getProperty("submenu");
3619
3620 if(oSubmenu) {
3621
3622 oSubmenu.hide();
3623
3624 }
3625
3626 if(p_bBlur) {
3627
3628 oActiveItem.blur();
3629
3630 }
3631
3632 }
3633
3634},
3635
3636/**
3637* @description Initializes the class's configurable properties which can be
3638* changed using the menu's Config object ("cfg").
3639* @method initDefaultConfig
3640*/
3641initDefaultConfig: function() {
3642
3643 YAHOO.widget.Menu.superclass.initDefaultConfig.call(this);
3644
3645 var oConfig = this.cfg;
3646
3647 // Add configuration properties
3648
3649 /*
3650 Change the default value for the "visible" configuration
3651 property to "false" by re-adding the property.
3652 */
3653
3654 /**
3655 * @config visible
3656 * @description Boolean indicating whether or not the menu is visible. If
3657 * the menu's "position" configuration property is set to "dynamic" (the
3658 * default), this property toggles the menu's <code>&#60;div&#62;</code>
3659 * element's "visibility" style property between "visible" (true) or
3660 * "hidden" (false). If the menu's "position" configuration property is
3661 * set to "static" this property toggles the menu's
3662 * <code>&#60;div&#62;</code> element's "display" style property
3663 * between "block" (true) or "none" (false).
3664 * @default false
3665 * @type Boolean
3666 */
3667 oConfig.addProperty(
3668 "visible",
3669 {
3670 value:false,
3671 handler:this.configVisible,
3672 validator:this.cfg.checkBoolean
3673 }
3674 );
3675
3676 /*
3677 Change the default value for the "constraintoviewport" configuration
3678 property to "true" by re-adding the property.
3679 */
3680
3681 /**
3682 * @config constraintoviewport
3683 * @description Boolean indicating if the menu will try to remain inside
3684 * the boundaries of the size of viewport.
3685 * @default true
3686 * @type Boolean
3687 */
3688 oConfig.addProperty(
3689 "constraintoviewport",
3690 {
3691 value:true,
3692 handler:this.configConstrainToViewport,
3693 validator:this.cfg.checkBoolean,
3694 supercedes:["iframe","x","y","xy"]
3695 }
3696 );
3697
3698 /**
3699 * @config position
3700 * @description String indicating how a menu should be positioned on the
3701 * screen. Possible values are "static" and "dynamic." Static menus are
3702 * visible by default and reside in the normal flow of the document
3703 * (CSS position: static). Dynamic menus are hidden by default, reside
3704 * out of the normal flow of the document (CSS position: absolute), and
3705 * can overlay other elements on the screen.
3706 * @default dynamic
3707 * @type String
3708 */
3709 oConfig.addProperty(
3710 "position",
3711 {
3712 value: "dynamic",
3713 handler: this.configPosition,
3714 validator: this._checkPosition,
3715 supercedes: ["visible"]
3716 }
3717 );
3718
3719 /**
3720 * @config submenualignment
3721 * @description Array defining how submenus should be aligned to their
3722 * parent menu item. The format is: [itemCorner, submenuCorner]. By default
3723 * a submenu's top left corner is aligned to its parent menu item's top
3724 * right corner.
3725 * @default ["tl","tr"]
3726 * @type Array
3727 */
3728 oConfig.addProperty("submenualignment", { value: ["tl","tr"] } );
3729
3730 /**
3731 * @config autosubmenudisplay
3732 * @description Boolean indicating if submenus are automatically made
3733 * visible when the user mouses over the menu's items.
3734 * @default true
3735 * @type Boolean
3736 */
3737 oConfig.addProperty(
3738 "autosubmenudisplay",
3739 {
3740 value: true,
3741 validator: oConfig.checkBoolean
3742 }
3743 );
3744
3745 /**
3746 * @config showdelay
3747 * @description Number indicating the time (in milliseconds) that should
3748 * expire before a submenu is made visible when the user mouses over
3749 * the menu's items.
3750 * @default 0
3751 * @type Number
3752 */
3753 oConfig.addProperty(
3754 "showdelay",
3755 {
3756 value: 0,
3757 validator: oConfig.checkNumber
3758 }
3759 );
3760
3761 /**
3762 * @config hidedelay
3763 * @description Number indicating the time (in milliseconds) that should
3764 * expire before the menu is hidden.
3765 * @default 0
3766 * @type Number
3767 */
3768 oConfig.addProperty(
3769 "hidedelay",
3770 {
3771 value: 0,
3772 validator: oConfig.checkNumber,
3773 handler: this.configHideDelay,
3774 suppressEvent: true
3775 }
3776 );
3777
3778 /**
3779 * @config clicktohide
3780 * @description Boolean indicating if the menu will automatically be
3781 * hidden if the user clicks outside of it.
3782 * @default true
3783 * @type Boolean
3784 */
3785 oConfig.addProperty(
3786 "clicktohide",
3787 {
3788 value: true,
3789 validator: oConfig.checkBoolean
3790 }
3791 );
3792
3793 /**
3794 * @config container
3795 * @description HTML element reference or string specifying the id
3796 * attribute of the HTML element that the menu's markup should be rendered into.
3797 * @type <a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/
3798 * level-one-html.html#ID-58190037">HTMLElement</a>|String
3799 * @default document.body
3800 */
3801 this.cfg.addProperty(
3802 "container",
3803 { value:document.body, handler:this.configContainer }
3804 );
3805
3806}
3807
3808}); // END YAHOO.extend
3809
3810})();
3811
3812/**
3813* The base class for all menuing containers.
3814*
3815* @param {String} p_oElement String specifying the id attribute of the
3816* <code>&#60;div&#62;</code> element of the menu module.
3817* @param {String} p_oElement String specifying the id attribute of the
3818* <code>&#60;select&#62;</code> element to be used as the data source for the
3819* menu module.
3820* @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929
3821* /level-one-html.html#ID-22445964">HTMLDivElement</a>} p_oElement Object
3822* specifying the <code>&#60;div&#62;</code> element of the menu module.
3823* @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-
3824* one-html.html#ID-94282980">HTMLSelectElement</a>} p_oElement Object
3825* specifying the <code>&#60;select&#62;</code> element to be used as the data
3826* source for the menu module.
3827* @param {Object} p_oConfig Optional. Object literal specifying the
3828* configuration for the menu module. See configuration class documentation for
3829* more details.
3830* @class MenuModule
3831* @constructor
3832* @extends YAHOO.widget.Overlay
3833* @deprecated As of version 0.12, all MenuModule functionality has been
3834* implemented directly in YAHOO.widget.Menu, making YAHOO.widget.Menu the base
3835* class for all menuing containers.
3836*/
3837YAHOO.widget.MenuModule = YAHOO.widget.Menu;
3838
3839(function() {
3840
3841var Dom = YAHOO.util.Dom;
3842var Module = YAHOO.widget.Module;
3843var Menu = YAHOO.widget.Menu;
3844
3845/**
3846* Creates an item for a menu.
3847*
3848* @param {String} p_oObject String specifying the text of the menu item.
3849* @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-
3850* one-html.html#ID-74680021">HTMLLIElement</a>} p_oObject Object specifying
3851* the <code>&#60;li&#62;</code> element of the menu item.
3852* @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-
3853* one-html.html#ID-38450247">HTMLOptGroupElement</a>} p_oObject Object
3854* specifying the <code>&#60;optgroup&#62;</code> element of the menu item.
3855* @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-
3856* one-html.html#ID-70901257">HTMLOptionElement</a>} p_oObject Object
3857* specifying the <code>&#60;option&#62;</code> element of the menu item.
3858* @param {Object} p_oConfig Optional. Object literal specifying the
3859* configuration for the menu item. See configuration class documentation
3860* for more details.
3861* @class MenuItem
3862* @constructor
3863*/
3864YAHOO.widget.MenuItem = function(p_oObject, p_oConfig) {
3865
3866 if(p_oObject) {
3867
3868 if(p_oConfig) {
3869
3870 this.parent = p_oConfig.parent;
3871 this.value = p_oConfig.value;
3872
3873 }
3874
3875 this.init(p_oObject, p_oConfig);
3876
3877 }
3878
3879};
3880
3881YAHOO.widget.MenuItem.prototype = {
3882
3883 // Constants
3884
3885 /**
3886 * @property SUBMENU_INDICATOR_IMAGE_PATH
3887 * @description String representing the path to the image to be used for the
3888 * menu item's submenu arrow indicator.
3889 * @default "nt/ic/ut/alt1/menuarorght8_nrm_1.gif"
3890 * @final
3891 * @type String
3892 */
3893 SUBMENU_INDICATOR_IMAGE_PATH: "nt/ic/ut/alt1/menuarorght8_nrm_1.gif",
3894
3895 /**
3896 * @property SELECTED_SUBMENU_INDICATOR_IMAGE_PATH
3897 * @description String representing the path to the image to be used for the
3898 * submenu arrow indicator when the menu item is selected.
3899 * @default "nt/ic/ut/alt1/menuarorght8_hov_1.gif"
3900 * @final
3901 * @type String
3902 */
3903 SELECTED_SUBMENU_INDICATOR_IMAGE_PATH:
3904 "nt/ic/ut/alt1/menuarorght8_hov_1.gif",
3905
3906 /**
3907 * @property DISABLED_SUBMENU_INDICATOR_IMAGE_PATH
3908 * @description String representing the path to the image to be used for the
3909 * submenu arrow indicator when the menu item is disabled.
3910 * @default "nt/ic/ut/alt1/menuarorght8_dim_1.gif"
3911 * @final
3912 * @type String
3913 */
3914 DISABLED_SUBMENU_INDICATOR_IMAGE_PATH:
3915 "nt/ic/ut/alt1/menuarorght8_dim_1.gif",
3916
3917 /**
3918 * @property COLLAPSED_SUBMENU_INDICATOR_ALT_TEXT
3919 * @description String representing the alt text for the image to be used
3920 * for the submenu arrow indicator.
3921 * @default "Collapsed. Click to expand."
3922 * @final
3923 * @type String
3924 */
3925 COLLAPSED_SUBMENU_INDICATOR_ALT_TEXT: "Collapsed. Click to expand.",
3926
3927 /**
3928 * @property EXPANDED_SUBMENU_INDICATOR_ALT_TEXT
3929 * @description String representing the alt text for the image to be used
3930 * for the submenu arrow indicator when the submenu is visible.
3931 * @default "Expanded. Click to collapse."
3932 * @final
3933 * @type String
3934 */
3935 EXPANDED_SUBMENU_INDICATOR_ALT_TEXT: "Expanded. Click to collapse.",
3936
3937 /**
3938 * @property DISABLED_SUBMENU_INDICATOR_ALT_TEXT
3939 * @description String representing the alt text for the image to be used
3940 * for the submenu arrow indicator when the menu item is disabled.
3941 * @default "Disabled."
3942 * @final
3943 * @type String
3944 */
3945 DISABLED_SUBMENU_INDICATOR_ALT_TEXT: "Disabled.",
3946
3947 /**
3948 * @property CHECKED_IMAGE_PATH
3949 * @description String representing the path to the image to be used for
3950 * the checked state.
3951 * @default "nt/ic/ut/bsc/menuchk8_nrm_1.gif"
3952 * @final
3953 * @type String
3954 */
3955 CHECKED_IMAGE_PATH: "nt/ic/ut/bsc/menuchk8_nrm_1.gif",
3956
3957
3958 /**
3959 * @property SELECTED_CHECKED_IMAGE_PATH
3960 * @description String representing the path to the image to be used for
3961 * the selected checked state.
3962 * @default "nt/ic/ut/bsc/menuchk8_hov_1.gif"
3963 * @final
3964 * @type String
3965 */
3966 SELECTED_CHECKED_IMAGE_PATH: "nt/ic/ut/bsc/menuchk8_hov_1.gif",
3967
3968
3969 /**
3970 * @property DISABLED_CHECKED_IMAGE_PATH
3971 * @description String representing the path to the image to be used for
3972 * the disabled checked state.
3973 * @default "nt/ic/ut/bsc/menuchk8_dim_1.gif"
3974 * @final
3975 * @type String
3976 */
3977 DISABLED_CHECKED_IMAGE_PATH: "nt/ic/ut/bsc/menuchk8_dim_1.gif",
3978
3979
3980 /**
3981 * @property CHECKED_IMAGE_ALT_TEXT
3982 * @description String representing the alt text for the image to be used
3983 * for the checked image.
3984 * @default "Checked."
3985 * @final
3986 * @type String
3987 */
3988 CHECKED_IMAGE_ALT_TEXT: "Checked.",
3989
3990
3991 /**
3992 * @property DISABLED_CHECKED_IMAGE_ALT_TEXT
3993 * @description String representing the alt text for the image to be used
3994 * for the checked image when the item is disabled.
3995 * @default "Checked. (Item disabled.)"
3996 * @final
3997 * @type String
3998 */
3999 DISABLED_CHECKED_IMAGE_ALT_TEXT: "Checked. (Item disabled.)",
4000
4001 /**
4002 * @property CSS_CLASS_NAME
4003 * @description String representing the CSS class(es) to be applied to the
4004 * <code>&#60;li&#62;</code> element of the menu item.
4005 * @default "yuimenuitem"
4006 * @final
4007 * @type String
4008 */
4009 CSS_CLASS_NAME: "yuimenuitem",
4010
4011 /**
4012 * @property SUBMENU_TYPE
4013 * @description Object representing the type of menu to instantiate and
4014 * add when parsing the child nodes of the menu item's source HTML element.
4015 * @final
4016 * @type YAHOO.widget.Menu
4017 */
4018 SUBMENU_TYPE: null,
4019
4020 /**
4021 * @property IMG_ROOT
4022 * @description String representing the prefix path to use for
4023 * non-secure images.
4024 * @default "http://us.i1.yimg.com/us.yimg.com/i/"
4025 * @type String
4026 */
4027 IMG_ROOT: "http://us.i1.yimg.com/us.yimg.com/i/",
4028
4029
4030 /**
4031 * @property IMG_ROOT_SSL
4032 * @description String representing the prefix path to use for securely
4033 * served images.
4034 * @default "https://a248.e.akamai.net/sec.yimg.com/i/"
4035 * @type String
4036 */
4037 IMG_ROOT_SSL: "https://a248.e.akamai.net/sec.yimg.com/i/",
4038
4039 // Private member variables
4040
4041 /**
4042 * @property _oAnchor
4043 * @description Object reference to the menu item's
4044 * <code>&#60;a&#62;</code> element.
4045 * @default null
4046 * @private
4047 * @type <a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-
4048 * one-html.html#ID-48250443">HTMLAnchorElement</a>
4049 */
4050 _oAnchor: null,
4051
4052
4053 /**
4054 * @property _oText
4055 * @description Object reference to the menu item's text node.
4056 * @default null
4057 * @private
4058 * @type TextNode
4059 */
4060 _oText: null,
4061
4062
4063 /**
4064 * @property _oHelpTextEM
4065 * @description Object reference to the menu item's help text
4066 * <code>&#60;em&#62;</code> element.
4067 * @default null
4068 * @private
4069 * @type <a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-
4070 * one-html.html#ID-58190037">HTMLElement</a>
4071 */
4072 _oHelpTextEM: null,
4073
4074
4075 /**
4076 * @property _oSubmenu
4077 * @description Object reference to the menu item's submenu.
4078 * @default null
4079 * @private
4080 * @type YAHOO.widget.Menu
4081 */
4082 _oSubmenu: null,
4083
4084 /**
4085 * @property _checkImage
4086 * @description Object reference to the menu item's checkmark image.
4087 * @default null
4088 * @private
4089 * @type <a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-
4090 * one-html.html#ID-17701901">HTMLImageElement</a>
4091 */
4092 _checkImage: null,
4093
4094 // Public properties
4095
4096 /**
4097 * @property constructor
4098 * @description Object reference to the menu item's constructor function.
4099 * @default YAHOO.widget.MenuItem
4100 * @type YAHOO.widget.MenuItem
4101 */
4102 constructor: YAHOO.widget.MenuItem,
4103
4104 /**
4105 * @property imageRoot
4106 * @description String representing the root path for all of the menu
4107 * item's images.
4108 * @type String
4109 */
4110 imageRoot: null,
4111
4112 /**
4113 * @property isSecure
4114 * @description Boolean representing whether or not the current browsing
4115 * context is secure (HTTPS).
4116 * @type Boolean
4117 */
4118 isSecure: Module.prototype.isSecure,
4119
4120 /**
4121 * @property index
4122 * @description Number indicating the ordinal position of the menu item in
4123 * its group.
4124 * @default null
4125 * @type Number
4126 */
4127 index: null,
4128
4129 /**
4130 * @property groupIndex
4131 * @description Number indicating the index of the group to which the menu
4132 * item belongs.
4133 * @default null
4134 * @type Number
4135 */
4136 groupIndex: null,
4137
4138 /**
4139 * @property parent
4140 * @description Object reference to the menu item's parent menu.
4141 * @default null
4142 * @type YAHOO.widget.Menu
4143 */
4144 parent: null,
4145
4146 /**
4147 * @property element
4148 * @description Object reference to the menu item's
4149 * <code>&#60;li&#62;</code> element.
4150 * @default <a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level
4151 * -one-html.html#ID-74680021">HTMLLIElement</a>
4152 * @type <a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-
4153 * one-html.html#ID-74680021">HTMLLIElement</a>
4154 */
4155 element: null,
4156
4157 /**
4158 * @property srcElement
4159 * @description Object reference to the HTML element (either
4160 * <code>&#60;li&#62;</code>, <code>&#60;optgroup&#62;</code> or
4161 * <code>&#60;option&#62;</code>) used create the menu item.
4162 * @default <a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/
4163 * level-one-html.html#ID-74680021">HTMLLIElement</a>|<a href="http://www.
4164 * w3.org/TR/2000/WD-DOM-Level-1-20000929/level-one-html.html#ID-38450247"
4165 * >HTMLOptGroupElement</a>|<a href="http://www.w3.org/TR/2000/WD-DOM-
4166 * Level-1-20000929/level-one-html.html#ID-70901257">HTMLOptionElement</a>
4167 * @type <a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-
4168 * one-html.html#ID-74680021">HTMLLIElement</a>|<a href="http://www.w3.
4169 * org/TR/2000/WD-DOM-Level-1-20000929/level-one-html.html#ID-38450247">
4170 * HTMLOptGroupElement</a>|<a href="http://www.w3.org/TR/2000/WD-DOM-
4171 * Level-1-20000929/level-one-html.html#ID-70901257">HTMLOptionElement</a>
4172 */
4173 srcElement: null,
4174
4175 /**
4176 * @property value
4177 * @description Object reference to the menu item's value.
4178 * @default null
4179 * @type Object
4180 */
4181 value: null,
4182
4183 /**
4184 * @property submenuIndicator
4185 * @description Object reference to the <code>&#60;img&#62;</code> element
4186 * used to create the submenu indicator for the menu item.
4187 * @default <a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/
4188 * level-one-html.html#ID-17701901">HTMLImageElement</a>
4189 * @type <a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/
4190 * level-one-html.html#ID-17701901">HTMLImageElement</a>
4191 */
4192 submenuIndicator: null,
4193
4194 /**
4195 * @property browser
4196 * @description String representing the browser.
4197 * @type String
4198 */
4199 browser: Module.prototype.browser,
4200
4201 // Events
4202
4203 /**
4204 * @event destroyEvent
4205 * @description Fires when the menu item's <code>&#60;li&#62;</code>
4206 * element is removed from its parent <code>&#60;ul&#62;</code> element.
4207 * @type YAHOO.util.CustomEvent
4208 */
4209 destroyEvent: null,
4210
4211 /**
4212 * @event mouseOverEvent
4213 * @description Fires when the mouse has entered the menu item. Passes
4214 * back the DOM Event object as an argument.
4215 * @type YAHOO.util.CustomEvent
4216 */
4217 mouseOverEvent: null,
4218
4219 /**
4220 * @event mouseOutEvent
4221 * @description Fires when the mouse has left the menu item. Passes back
4222 * the DOM Event object as an argument.
4223 * @type YAHOO.util.CustomEvent
4224 */
4225 mouseOutEvent: null,
4226
4227 /**
4228 * @event mouseDownEvent
4229 * @description Fires when the user mouses down on the menu item. Passes
4230 * back the DOM Event object as an argument.
4231 * @type YAHOO.util.CustomEvent
4232 */
4233 mouseDownEvent: null,
4234
4235 /**
4236 * @event mouseUpEvent
4237 * @description Fires when the user releases a mouse button while the mouse
4238 * is over the menu item. Passes back the DOM Event object as an argument.
4239 * @type YAHOO.util.CustomEvent
4240 */
4241 mouseUpEvent: null,
4242
4243 /**
4244 * @event clickEvent
4245 * @description Fires when the user clicks the on the menu item. Passes
4246 * back the DOM Event object as an argument.
4247 * @type YAHOO.util.CustomEvent
4248 */
4249 clickEvent: null,
4250
4251 /**
4252 * @event keyPressEvent
4253 * @description Fires when the user presses an alphanumeric key when the
4254 * menu item has focus. Passes back the DOM Event object as an argument.
4255 * @type YAHOO.util.CustomEvent
4256 */
4257 keyPressEvent: null,
4258
4259 /**
4260 * @event keyDownEvent
4261 * @description Fires when the user presses a key when the menu item has
4262 * focus. Passes back the DOM Event object as an argument.
4263 * @type YAHOO.util.CustomEvent
4264 */
4265 keyDownEvent: null,
4266
4267 /**
4268 * @event keyUpEvent
4269 * @description Fires when the user releases a key when the menu item has
4270 * focus. Passes back the DOM Event object as an argument.
4271 * @type YAHOO.util.CustomEvent
4272 */
4273 keyUpEvent: null,
4274
4275 /**
4276 * @event focusEvent
4277 * @description Fires when the menu item receives focus.
4278 * @type YAHOO.util.CustomEvent
4279 */
4280 focusEvent: null,
4281
4282 /**
4283 * @event blurEvent
4284 * @description Fires when the menu item loses the input focus.
4285 * @type YAHOO.util.CustomEvent
4286 */
4287 blurEvent: null,
4288
4289 /**
4290 * @method init
4291 * @description The MenuItem class's initialization method. This method is
4292 * automatically called by the constructor, and sets up all DOM references
4293 * for pre-existing markup, and creates required markup if it is not
4294 * already present.
4295 * @param {String} p_oObject String specifying the text of the menu item.
4296 * @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-
4297 * one-html.html#ID-74680021">HTMLLIElement</a>} p_oObject Object specifying
4298 * the <code>&#60;li&#62;</code> element of the menu item.
4299 * @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-
4300 * one-html.html#ID-38450247">HTMLOptGroupElement</a>} p_oObject Object
4301 * specifying the <code>&#60;optgroup&#62;</code> element of the menu item.
4302 * @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-
4303 * one-html.html#ID-70901257">HTMLOptionElement</a>} p_oObject Object
4304 * specifying the <code>&#60;option&#62;</code> element of the menu item.
4305 * @param {Object} p_oConfig Optional. Object literal specifying the
4306 * configuration for the menu item. See configuration class documentation
4307 * for more details.
4308 */
4309 init: function(p_oObject, p_oConfig) {
4310
4311 this.imageRoot = (this.isSecure) ? this.IMG_ROOT_SSL : this.IMG_ROOT;
4312
4313 if(!this.SUBMENU_TYPE) {
4314
4315 this.SUBMENU_TYPE = Menu;
4316
4317 }
4318
4319 // Create the config object
4320
4321 this.cfg = new YAHOO.util.Config(this);
4322
4323 this.initDefaultConfig();
4324
4325 var oConfig = this.cfg;
4326
4327 if(this._checkString(p_oObject)) {
4328
4329 this._createRootNodeStructure();
4330
4331 oConfig.setProperty("text", p_oObject);
4332
4333 }
4334 else if(this._checkDOMNode(p_oObject)) {
4335
4336 switch(p_oObject.tagName.toUpperCase()) {
4337
4338 case "OPTION":
4339
4340 this._createRootNodeStructure();
4341
4342 oConfig.setProperty("text", p_oObject.text);
4343
4344 this.srcElement = p_oObject;
4345
4346 break;
4347
4348 case "OPTGROUP":
4349
4350 this._createRootNodeStructure();
4351
4352 oConfig.setProperty("text", p_oObject.label);
4353
4354 this.srcElement = p_oObject;
4355
4356 this._initSubTree();
4357
4358 break;
4359
4360 case "LI":
4361
4362 // Get the anchor node (if it exists)
4363
4364 var oAnchor = this._getFirstElement(p_oObject, "A");
4365 var sURL = "#";
4366 var sTarget = null;
4367 var sText = null;
4368
4369 // Capture the "text" and/or the "URL"
4370
4371 if(oAnchor) {
4372
4373 sURL = oAnchor.getAttribute("href");
4374 sTarget = oAnchor.getAttribute("target");
4375
4376 if(oAnchor.innerText) {
4377
4378 sText = oAnchor.innerText;
4379
4380 }
4381 else {
4382
4383 var oRange = oAnchor.ownerDocument.createRange();
4384
4385 oRange.selectNodeContents(oAnchor);
4386
4387 sText = oRange.toString();
4388
4389 }
4390
4391 }
4392 else {
4393
4394 var oText = p_oObject.firstChild;
4395
4396 sText = oText.nodeValue;
4397
4398 oAnchor = document.createElement("a");
4399
4400 oAnchor.setAttribute("href", sURL);
4401
4402 p_oObject.replaceChild(oAnchor, oText);
4403
4404 oAnchor.appendChild(oText);
4405
4406 }
4407
4408 this.srcElement = p_oObject;
4409 this.element = p_oObject;
4410 this._oAnchor = oAnchor;
4411
4412
4413 // Check if emphasis has been applied to the MenuItem
4414
4415 var oEmphasisNode = this._getFirstElement(oAnchor);
4416 var bEmphasis = false;
4417 var bStrongEmphasis = false;
4418
4419 if(oEmphasisNode) {
4420
4421 // Set a reference to the text node
4422
4423 this._oText = oEmphasisNode.firstChild;
4424
4425 switch(oEmphasisNode.tagName.toUpperCase()) {
4426
4427 case "EM":
4428
4429 bEmphasis = true;
4430
4431 break;
4432
4433 case "STRONG":
4434
4435 bStrongEmphasis = true;
4436
4437 break;
4438
4439 }
4440
4441 }
4442 else {
4443
4444 // Set a reference to the text node
4445
4446 this._oText = oAnchor.firstChild;
4447
4448 }
4449
4450 /*
4451 Set these properties silently to sync up the
4452 configuration object without making changes to the
4453 element's DOM
4454 */
4455
4456 oConfig.setProperty("text", sText, true);
4457 oConfig.setProperty("url", sURL, true);
4458 oConfig.setProperty("target", sTarget, true);
4459 oConfig.setProperty("emphasis", bEmphasis, true);
4460 oConfig.setProperty(
4461 "strongemphasis",
4462 bStrongEmphasis,
4463 true
4464 );
4465
4466 this._initSubTree();
4467
4468 break;
4469
4470 }
4471
4472 }
4473
4474 if(this.element) {
4475
4476 Dom.addClass(this.element, this.CSS_CLASS_NAME);
4477
4478 // Create custom events
4479
4480 var CustomEvent = YAHOO.util.CustomEvent;
4481
4482 this.destroyEvent = new CustomEvent("destroyEvent", this);
4483 this.mouseOverEvent = new CustomEvent("mouseOverEvent", this);
4484 this.mouseOutEvent = new CustomEvent("mouseOutEvent", this);
4485 this.mouseDownEvent = new CustomEvent("mouseDownEvent", this);
4486 this.mouseUpEvent = new CustomEvent("mouseUpEvent", this);
4487 this.clickEvent = new CustomEvent("clickEvent", this);
4488 this.keyPressEvent = new CustomEvent("keyPressEvent", this);
4489 this.keyDownEvent = new CustomEvent("keyDownEvent", this);
4490 this.keyUpEvent = new CustomEvent("keyUpEvent", this);
4491 this.focusEvent = new CustomEvent("focusEvent", this);
4492 this.blurEvent = new CustomEvent("blurEvent", this);
4493
4494 if(p_oConfig) {
4495
4496 oConfig.applyConfig(p_oConfig);
4497
4498 }
4499
4500 oConfig.fireQueue();
4501
4502 }
4503
4504 },
4505
4506 // Private methods
4507
4508 /**
4509 * @method _getFirstElement
4510 * @description Returns an HTML element's first HTML element node.
4511 * @private
4512 * @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/
4513 * level-one-html.html#ID-58190037">HTMLElement</a>} p_oElement Object
4514 * reference specifying the element to be evaluated.
4515 * @param {String} p_sTagName Optional. String specifying the tagname of
4516 * the element to be retrieved.
4517 * @return {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/
4518 * level-one-html.html#ID-58190037">HTMLElement</a>}
4519 */
4520 _getFirstElement: function(p_oElement, p_sTagName) {
4521
4522 var oElement;
4523
4524 if(p_oElement.firstChild && p_oElement.firstChild.nodeType == 1) {
4525
4526 oElement = p_oElement.firstChild;
4527
4528 }
4529 else if(
4530 p_oElement.firstChild &&
4531 p_oElement.firstChild.nextSibling &&
4532 p_oElement.firstChild.nextSibling.nodeType == 1
4533 ) {
4534
4535 oElement = p_oElement.firstChild.nextSibling;
4536
4537 }
4538
4539 if(p_sTagName) {
4540
4541 return (oElement && oElement.tagName.toUpperCase() == p_sTagName) ?
4542 oElement : false;
4543
4544 }
4545
4546 return oElement;
4547
4548 },
4549
4550 /**
4551 * @method _checkString
4552 * @description Determines if an object is a string.
4553 * @private
4554 * @param {Object} p_oObject Object to be evaluated.
4555 * @return {Boolean}
4556 */
4557 _checkString: function(p_oObject) {
4558
4559 return (typeof p_oObject == "string");
4560
4561 },
4562
4563 /**
4564 * @method _checkDOMNode
4565 * @description Determines if an object is an HTML element.
4566 * @private
4567 * @param {Object} p_oObject Object to be evaluated.
4568 * @return {Boolean}
4569 */
4570 _checkDOMNode: function(p_oObject) {
4571
4572 return (p_oObject && p_oObject.tagName);
4573
4574 },
4575
4576 /**
4577 * @method _createRootNodeStructure
4578 * @description Creates the core DOM structure for the menu item.
4579 * @private
4580 */
4581 _createRootNodeStructure: function () {
4582
4583 this.element = document.createElement("li");
4584
4585 this._oText = document.createTextNode("");
4586
4587 this._oAnchor = document.createElement("a");
4588 this._oAnchor.appendChild(this._oText);
4589
4590 this.cfg.refireEvent("url");
4591
4592 this.element.appendChild(this._oAnchor);
4593
4594 },
4595
4596 /**
4597 * @method _initSubTree
4598 * @description Iterates the source element's childNodes collection and uses
4599 * the child nodes to instantiate other menus.
4600 * @private
4601 */
4602 _initSubTree: function() {
4603
4604 var oSrcEl = this.srcElement;
4605 var oConfig = this.cfg;
4606
4607 if(oSrcEl.childNodes.length > 0) {
4608
4609 if(
4610 this.parent.lazyLoad &&
4611 this.parent.srcElement &&
4612 this.parent.srcElement.tagName.toUpperCase() == "SELECT"
4613 ) {
4614
4615 oConfig.setProperty(
4616 "submenu",
4617 { id: Dom.generateId(), itemdata: oSrcEl.childNodes }
4618 );
4619
4620 }
4621 else {
4622
4623 var oNode = oSrcEl.firstChild;
4624 var aOptions = [];
4625
4626 do {
4627
4628 if(oNode && oNode.tagName) {
4629
4630 switch(oNode.tagName.toUpperCase()) {
4631
4632 case "DIV":
4633
4634 oConfig.setProperty("submenu", oNode);
4635
4636 break;
4637
4638 case "OPTION":
4639
4640 aOptions[aOptions.length] = oNode;
4641
4642 break;
4643
4644 }
4645
4646 }
4647
4648 }
4649 while((oNode = oNode.nextSibling));
4650
4651
4652 var nOptions = aOptions.length;
4653
4654 if(nOptions > 0) {
4655
4656 var oMenu = new this.SUBMENU_TYPE(Dom.generateId());
4657
4658 oConfig.setProperty("submenu", oMenu);
4659
4660 for(var n=0; n<nOptions; n++) {
4661
4662 oMenu.addItem((new oMenu.ITEM_TYPE(aOptions[n])));
4663
4664 }
4665
4666 }
4667
4668 }
4669
4670 }
4671
4672 },
4673
4674 /**
4675 * @method _preloadImage
4676 * @description Preloads an image by creating an image element from the
4677 * specified path and appending the image to the body of the document.
4678 * @private
4679 * @param {String} p_sPath String specifying the path to the image.
4680 */
4681 _preloadImage: function(p_sPath) {
4682
4683 var sPath = this.imageRoot + p_sPath;
4684
4685 if(!document.images[sPath]) {
4686
4687 var oImage = document.createElement("img");
4688 oImage.src = sPath;
4689 oImage.name = sPath;
4690 oImage.id = sPath;
4691 oImage.style.display = "none";
4692
4693 document.body.appendChild(oImage);
4694
4695 }
4696
4697 },
4698
4699 // Event handlers for configuration properties
4700
4701 /**
4702 * @method configText
4703 * @description Event handler for when the "text" configuration property of
4704 * the menu item changes.
4705 * @param {String} p_sType String representing the name of the event that
4706 * was fired.
4707 * @param {Array} p_aArgs Array of arguments sent when the event was fired.
4708 * @param {YAHOO.widget.MenuItem} p_oItem Object representing the menu item
4709 * that fired the event.
4710 */
4711 configText: function(p_sType, p_aArgs, p_oItem) {
4712
4713 var sText = p_aArgs[0];
4714
4715 if(this._oText) {
4716
4717 this._oText.nodeValue = sText;
4718
4719 }
4720
4721 },
4722
4723 /**
4724 * @method configHelpText
4725 * @description Event handler for when the "helptext" configuration property
4726 * of the menu item changes.
4727 * @param {String} p_sType String representing the name of the event that
4728 * was fired.
4729 * @param {Array} p_aArgs Array of arguments sent when the event was fired.
4730 * @param {YAHOO.widget.MenuItem} p_oItem Object representing the menu item
4731 * that fired the event.
4732 */
4733 configHelpText: function(p_sType, p_aArgs, p_oItem) {
4734
4735 var me = this;
4736 var oHelpText = p_aArgs[0];
4737 var oEl = this.element;
4738 var oConfig = this.cfg;
4739 var aNodes = [oEl, this._oAnchor];
4740 var oImg = this.submenuIndicator;
4741
4742 /**
4743 * Adds the "hashelptext" class to the necessary nodes and refires the
4744 * "selected" and "disabled" configuration events.
4745 * @private
4746 */
4747 var initHelpText = function() {
4748
4749 Dom.addClass(aNodes, "hashelptext");
4750
4751 if(oConfig.getProperty("disabled")) {
4752
4753 oConfig.refireEvent("disabled");
4754
4755 }
4756
4757 if(oConfig.getProperty("selected")) {
4758
4759 oConfig.refireEvent("selected");
4760
4761 }
4762
4763 };
4764
4765 /**
4766 * Removes the "hashelptext" class and corresponding DOM element (EM).
4767 * @private
4768 */
4769 var removeHelpText = function() {
4770
4771 Dom.removeClass(aNodes, "hashelptext");
4772
4773 oEl.removeChild(me._oHelpTextEM);
4774 me._oHelpTextEM = null;
4775
4776 };
4777
4778 if(this._checkDOMNode(oHelpText)) {
4779
4780 if(this._oHelpTextEM) {
4781
4782 this._oHelpTextEM.parentNode.replaceChild(
4783 oHelpText,
4784 this._oHelpTextEM
4785 );
4786
4787 }
4788 else {
4789
4790 this._oHelpTextEM = oHelpText;
4791
4792 oEl.insertBefore(this._oHelpTextEM, oImg);
4793
4794 }
4795
4796 initHelpText();
4797
4798 }
4799 else if(this._checkString(oHelpText)) {
4800
4801 if(oHelpText.length === 0) {
4802
4803 removeHelpText();
4804
4805 }
4806 else {
4807
4808 if(!this._oHelpTextEM) {
4809
4810 this._oHelpTextEM = document.createElement("em");
4811
4812 oEl.insertBefore(this._oHelpTextEM, oImg);
4813
4814 }
4815
4816 this._oHelpTextEM.innerHTML = oHelpText;
4817
4818 initHelpText();
4819
4820 }
4821
4822 }
4823 else if(!oHelpText && this._oHelpTextEM) {
4824
4825 removeHelpText();
4826
4827 }
4828
4829 },
4830
4831 /**
4832 * @method configURL
4833 * @description Event handler for when the "url" configuration property of
4834 * the menu item changes.
4835 * @param {String} p_sType String representing the name of the event that
4836 * was fired.
4837 * @param {Array} p_aArgs Array of arguments sent when the event was fired.
4838 * @param {YAHOO.widget.MenuItem} p_oItem Object representing the menu item
4839 * that fired the event.
4840 */
4841 configURL: function(p_sType, p_aArgs, p_oItem) {
4842
4843 var sURL = p_aArgs[0];
4844
4845 if(!sURL) {
4846
4847 sURL = "#";
4848
4849 }
4850
4851 this._oAnchor.setAttribute("href", sURL);
4852
4853 },
4854
4855 /**
4856 * @method configTarget
4857 * @description Event handler for when the "target" configuration property
4858 * of the menu item changes.
4859 * @param {String} p_sType String representing the name of the event that
4860 * was fired.
4861 * @param {Array} p_aArgs Array of arguments sent when the event was fired.
4862 * @param {YAHOO.widget.MenuItem} p_oItem Object representing the menu item
4863 * that fired the event.
4864 */
4865 configTarget: function(p_sType, p_aArgs, p_oItem) {
4866
4867 var sTarget = p_aArgs[0];
4868 var oAnchor = this._oAnchor;
4869
4870 if(sTarget && sTarget.length > 0) {
4871
4872 oAnchor.setAttribute("target", sTarget);
4873
4874 }
4875 else {
4876
4877 oAnchor.removeAttribute("target");
4878
4879 }
4880
4881 },
4882
4883 /**
4884 * @method configEmphasis
4885 * @description Event handler for when the "emphasis" configuration property
4886 * of the menu item changes.
4887 * @param {String} p_sType String representing the name of the event that
4888 * was fired.
4889 * @param {Array} p_aArgs Array of arguments sent when the event was fired.
4890 * @param {YAHOO.widget.MenuItem} p_oItem Object representing the menu item
4891 * that fired the event.
4892 */
4893 configEmphasis: function(p_sType, p_aArgs, p_oItem) {
4894
4895 var bEmphasis = p_aArgs[0];
4896 var oAnchor = this._oAnchor;
4897 var oText = this._oText;
4898 var oConfig = this.cfg;
4899 var oEM;
4900
4901 if(bEmphasis && oConfig.getProperty("strongemphasis")) {
4902
4903 oConfig.setProperty("strongemphasis", false);
4904
4905 }
4906
4907 if(oAnchor) {
4908
4909 if(bEmphasis) {
4910
4911 oEM = document.createElement("em");
4912 oEM.appendChild(oText);
4913
4914 oAnchor.appendChild(oEM);
4915
4916 }
4917 else {
4918
4919 oEM = this._getFirstElement(oAnchor, "EM");
4920
4921 oAnchor.removeChild(oEM);
4922 oAnchor.appendChild(oText);
4923
4924 }
4925
4926 }
4927
4928 },
4929
4930 /**
4931 * @method configStrongEmphasis
4932 * @description Event handler for when the "strongemphasis" configuration
4933 * property of the menu item changes.
4934 * @param {String} p_sType String representing the name of the event that
4935 * was fired.
4936 * @param {Array} p_aArgs Array of arguments sent when the event was fired.
4937 * @param {YAHOO.widget.MenuItem} p_oItem Object representing the menu item
4938 * that fired the event.
4939 */
4940 configStrongEmphasis: function(p_sType, p_aArgs, p_oItem) {
4941
4942 var bStrongEmphasis = p_aArgs[0];
4943 var oAnchor = this._oAnchor;
4944 var oText = this._oText;
4945 var oConfig = this.cfg;
4946 var oStrong;
4947
4948 if(bStrongEmphasis && oConfig.getProperty("emphasis")) {
4949
4950 oConfig.setProperty("emphasis", false);
4951
4952 }
4953
4954 if(oAnchor) {
4955
4956 if(bStrongEmphasis) {
4957
4958 oStrong = document.createElement("strong");
4959 oStrong.appendChild(oText);
4960
4961 oAnchor.appendChild(oStrong);
4962
4963 }
4964 else {
4965
4966 oStrong = this._getFirstElement(oAnchor, "STRONG");
4967
4968 oAnchor.removeChild(oStrong);
4969 oAnchor.appendChild(oText);
4970
4971 }
4972
4973 }
4974
4975 },
4976
4977 /**
4978 * @method configChecked
4979 * @description Event handler for when the "checked" configuration property
4980 * of the menu item changes.
4981 * @param {String} p_sType String representing the name of the event that
4982 * was fired.
4983 * @param {Array} p_aArgs Array of arguments sent when the event was fired.
4984 * @param {YAHOO.widget.MenuItem} p_oItem Object representing the menu item
4985 * that fired the event.
4986 */
4987 configChecked: function(p_sType, p_aArgs, p_oItem) {
4988
4989 var bChecked = p_aArgs[0];
4990 var oEl = this.element;
4991 var oConfig = this.cfg;
4992 var oImg;
4993
4994
4995 if(bChecked) {
4996
4997 this._preloadImage(this.CHECKED_IMAGE_PATH);
4998 this._preloadImage(this.SELECTED_CHECKED_IMAGE_PATH);
4999 this._preloadImage(this.DISABLED_CHECKED_IMAGE_PATH);
5000
5001 oImg = document.createElement("img");
5002 oImg.src = (this.imageRoot + this.CHECKED_IMAGE_PATH);
5003 oImg.alt = this.CHECKED_IMAGE_ALT_TEXT;
5004
5005 var oSubmenu = this.cfg.getProperty("submenu");
5006
5007 if(oSubmenu) {
5008
5009 oEl.insertBefore(oImg, oSubmenu.element);
5010
5011 }
5012 else {
5013
5014 oEl.appendChild(oImg);
5015
5016 }
5017
5018 Dom.addClass([oEl, oImg], "checked");
5019
5020 this._checkImage = oImg;
5021
5022 if(oConfig.getProperty("disabled")) {
5023
5024 oConfig.refireEvent("disabled");
5025
5026 }
5027
5028 if(oConfig.getProperty("selected")) {
5029
5030 oConfig.refireEvent("selected");
5031
5032 }
5033
5034 }
5035 else {
5036
5037 oImg = this._checkImage;
5038
5039 Dom.removeClass([oEl, oImg], "checked");
5040
5041 if(oImg) {
5042
5043 oEl.removeChild(oImg);
5044
5045 }
5046
5047 this._checkImage = null;
5048
5049 }
5050
5051 },
5052
5053 /**
5054 * @method configDisabled
5055 * @description Event handler for when the "disabled" configuration property
5056 * of the menu item changes.
5057 * @param {String} p_sType String representing the name of the event that
5058 * was fired.
5059 * @param {Array} p_aArgs Array of arguments sent when the event was fired.
5060 * @param {YAHOO.widget.MenuItem} p_oItem Object representing the menu item
5061 * that fired the event.
5062 */
5063 configDisabled: function(p_sType, p_aArgs, p_oItem) {
5064
5065 var bDisabled = p_aArgs[0];
5066 var oAnchor = this._oAnchor;
5067 var aNodes = [this.element, oAnchor];
5068 var oEM = this._oHelpTextEM;
5069 var oConfig = this.cfg;
5070 var oImg;
5071 var sImgSrc;
5072 var sImgAlt;
5073
5074 if(oEM) {
5075
5076 aNodes[2] = oEM;
5077
5078 }
5079
5080 if(this.cfg.getProperty("checked")) {
5081
5082 sImgAlt = this.CHECKED_IMAGE_ALT_TEXT;
5083 sImgSrc = this.CHECKED_IMAGE_PATH;
5084 oImg = this._checkImage;
5085
5086 if(bDisabled) {
5087
5088 sImgAlt = this.DISABLED_CHECKED_IMAGE_ALT_TEXT;
5089 sImgSrc = this.DISABLED_CHECKED_IMAGE_PATH;
5090
5091 }
5092
5093 oImg.src = document.images[(this.imageRoot + sImgSrc)].src;
5094 oImg.alt = sImgAlt;
5095
5096 }
5097
5098 oImg = this.submenuIndicator;
5099
5100 if(bDisabled) {
5101
5102 if(oConfig.getProperty("selected")) {
5103
5104 oConfig.setProperty("selected", false);
5105
5106 }
5107
5108 oAnchor.removeAttribute("href");
5109
5110 Dom.addClass(aNodes, "disabled");
5111
5112 sImgSrc = this.DISABLED_SUBMENU_INDICATOR_IMAGE_PATH;
5113 sImgAlt = this.DISABLED_SUBMENU_INDICATOR_ALT_TEXT;
5114
5115 }
5116 else {
5117
5118 oAnchor.setAttribute("href", oConfig.getProperty("url"));
5119
5120 Dom.removeClass(aNodes, "disabled");
5121
5122 sImgSrc = this.SUBMENU_INDICATOR_IMAGE_PATH;
5123 sImgAlt = this.COLLAPSED_SUBMENU_INDICATOR_ALT_TEXT;
5124
5125 }
5126
5127 if(oImg) {
5128
5129 oImg.src = this.imageRoot + sImgSrc;
5130 oImg.alt = sImgAlt;
5131
5132 }
5133
5134 },
5135
5136 /**
5137 * @method configSelected
5138 * @description Event handler for when the "selected" configuration property
5139 * of the menu item changes.
5140 * @param {String} p_sType String representing the name of the event that
5141 * was fired.
5142 * @param {Array} p_aArgs Array of arguments sent when the event was fired.
5143 * @param {YAHOO.widget.MenuItem} p_oItem Object representing the menu item
5144 * that fired the event.
5145 */
5146 configSelected: function(p_sType, p_aArgs, p_oItem) {
5147
5148 if(!this.cfg.getProperty("disabled")) {
5149
5150 var bSelected = p_aArgs[0];
5151 var oEM = this._oHelpTextEM;
5152 var aNodes = [this.element, this._oAnchor];
5153 var oImg = this.submenuIndicator;
5154 var sImgSrc;
5155
5156 if(oEM) {
5157
5158 aNodes[aNodes.length] = oEM;
5159
5160 }
5161
5162 if(oImg) {
5163
5164 aNodes[aNodes.length] = oImg;
5165
5166 }
5167
5168
5169 if(this.cfg.getProperty("checked")) {
5170
5171 sImgSrc = this.imageRoot + (bSelected ?
5172 this.SELECTED_CHECKED_IMAGE_PATH : this.CHECKED_IMAGE_PATH);
5173
5174 this._checkImage.src = document.images[sImgSrc].src;
5175
5176 }
5177
5178 if(bSelected) {
5179
5180 Dom.addClass(aNodes, "selected");
5181 sImgSrc = this.SELECTED_SUBMENU_INDICATOR_IMAGE_PATH;
5182
5183 }
5184 else {
5185
5186 Dom.removeClass(aNodes, "selected");
5187 sImgSrc = this.SUBMENU_INDICATOR_IMAGE_PATH;
5188
5189 }
5190
5191 if(oImg) {
5192
5193 oImg.src = document.images[(this.imageRoot + sImgSrc)].src;
5194
5195 }
5196
5197 }
5198
5199 },
5200
5201 /**
5202 * @method configSubmenu
5203 * @description Event handler for when the "submenu" configuration property
5204 * of the menu item changes.
5205 * @param {String} p_sType String representing the name of the event that
5206 * was fired.
5207 * @param {Array} p_aArgs Array of arguments sent when the event was fired.
5208 * @param {YAHOO.widget.MenuItem} p_oItem Object representing the menu item
5209 * that fired the event.
5210 */
5211 configSubmenu: function(p_sType, p_aArgs, p_oItem) {
5212
5213 var oEl = this.element;
5214 var oSubmenu = p_aArgs[0];
5215 var oImg = this.submenuIndicator;
5216 var oConfig = this.cfg;
5217 var aNodes = [this.element, this._oAnchor];
5218 var oMenu;
5219 var bLazyLoad = this.parent && this.parent.lazyLoad;
5220
5221 if(oSubmenu) {
5222
5223 if(oSubmenu instanceof Menu) {
5224
5225 oMenu = oSubmenu;
5226 oMenu.parent = this;
5227 oMenu.lazyLoad = bLazyLoad;
5228
5229 }
5230 else if(
5231 typeof oSubmenu == "object" &&
5232 oSubmenu.id &&
5233 !oSubmenu.nodeType
5234 ) {
5235
5236 var sSubmenuId = oSubmenu.id;
5237 var oSubmenuConfig = oSubmenu;
5238
5239 delete oSubmenu["id"];
5240
5241 oSubmenuConfig.lazyload = bLazyLoad;
5242 oSubmenuConfig.parent = this;
5243
5244 oMenu = new this.SUBMENU_TYPE(sSubmenuId, oSubmenuConfig);
5245
5246 // Set the value of the property to the Menu instance
5247
5248 this.cfg.setProperty("submenu", oMenu, true);
5249
5250 }
5251 else {
5252
5253 oMenu = new this.SUBMENU_TYPE(
5254 oSubmenu,
5255 { lazyload: bLazyLoad, parent: this }
5256 );
5257
5258 // Set the value of the property to the Menu instance
5259
5260 this.cfg.setProperty("submenu", oMenu, true);
5261
5262 }
5263
5264 if(oMenu) {
5265
5266 this._oSubmenu = oMenu;
5267
5268 if(!oImg) {
5269
5270 this._preloadImage(this.SUBMENU_INDICATOR_IMAGE_PATH);
5271 this._preloadImage(
5272 this.SELECTED_SUBMENU_INDICATOR_IMAGE_PATH
5273 );
5274
5275 this._preloadImage(
5276 this.DISABLED_SUBMENU_INDICATOR_IMAGE_PATH
5277 );
5278
5279 oImg = document.createElement("img");
5280
5281 oImg.src =
5282 (this.imageRoot + this.SUBMENU_INDICATOR_IMAGE_PATH);
5283
5284 oImg.alt = this.COLLAPSED_SUBMENU_INDICATOR_ALT_TEXT;
5285
5286 oEl.appendChild(oImg);
5287
5288 this.submenuIndicator = oImg;
5289
5290 Dom.addClass(aNodes, "hassubmenu");
5291
5292 if(oConfig.getProperty("disabled")) {
5293
5294 oConfig.refireEvent("disabled");
5295
5296 }
5297
5298 if(oConfig.getProperty("selected")) {
5299
5300 oConfig.refireEvent("selected");
5301
5302 }
5303
5304 }
5305
5306 }
5307
5308 }
5309 else {
5310
5311 Dom.removeClass(aNodes, "hassubmenu");
5312
5313 if(oImg) {
5314
5315 oEl.removeChild(oImg);
5316
5317 }
5318
5319 if(this._oSubmenu) {
5320
5321 this._oSubmenu.destroy();
5322
5323 }
5324
5325 }
5326
5327 },
5328
5329 // Public methods
5330
5331 /**
5332 * @method initDefaultConfig
5333 * @description Initializes an item's configurable properties.
5334 */
5335 initDefaultConfig : function() {
5336
5337 var oConfig = this.cfg;
5338 var CheckBoolean = oConfig.checkBoolean;
5339
5340 // Define the config properties
5341
5342 /**
5343 * @config text
5344 * @description String specifying the text label for the menu item.
5345 * When building a menu from existing HTML the value of this property
5346 * will be interpreted from the menu's markup.
5347 * @default ""
5348 * @type String
5349 */
5350 oConfig.addProperty(
5351 "text",
5352 {
5353 value: "",
5354 handler: this.configText,
5355 validator: this._checkString,
5356 suppressEvent: true
5357 }
5358 );
5359
5360
5361 /**
5362 * @config helptext
5363 * @description String specifying additional instructional text to
5364 * accompany the text for the nenu item.
5365 * @default null
5366 * @type String|<a href="http://www.w3.org/TR/
5367 * 2000/WD-DOM-Level-1-20000929/level-one-html.html#ID-58190037">
5368 * HTMLElement</a>
5369 */
5370 oConfig.addProperty("helptext", { handler: this.configHelpText });
5371
5372 /**
5373 * @config url
5374 * @description String specifying the URL for the menu item's anchor's
5375 * "href" attribute. When building a menu from existing HTML the value
5376 * of this property will be interpreted from the menu's markup.
5377 * @default "#"
5378 * @type String
5379 */
5380 oConfig.addProperty(
5381 "url",
5382 { value: "#", handler: this.configURL, suppressEvent: true }
5383 );
5384
5385 /**
5386 * @config target
5387 * @description String specifying the value for the "target" attribute
5388 * of the menu item's anchor element. <strong>Specifying a target will
5389 * require the user to click directly on the menu item's anchor node in
5390 * order to cause the browser to navigate to the specified URL.</strong>
5391 * When building a menu from existing HTML the value of this property
5392 * will be interpreted from the menu's markup.
5393 * @default null
5394 * @type String
5395 */
5396 oConfig.addProperty(
5397 "target",
5398 { handler: this.configTarget, suppressEvent: true }
5399 );
5400
5401 /**
5402 * @config emphasis
5403 * @description Boolean indicating if the text of the menu item will be
5404 * rendered with emphasis. When building a menu from existing HTML the
5405 * value of this property will be interpreted from the menu's markup.
5406 * @default false
5407 * @type Boolean
5408 */
5409 oConfig.addProperty(
5410 "emphasis",
5411 {
5412 value: false,
5413 handler: this.configEmphasis,
5414 validator: CheckBoolean,
5415 suppressEvent: true
5416 }
5417 );
5418
5419 /**
5420 * @config strongemphasis
5421 * @description Boolean indicating if the text of the menu item will be
5422 * rendered with strong emphasis. When building a menu from existing
5423 * HTML the value of this property will be interpreted from the
5424 * menu's markup.
5425 * @default false
5426 * @type Boolean
5427 */
5428 oConfig.addProperty(
5429 "strongemphasis",
5430 {
5431 value: false,
5432 handler: this.configStrongEmphasis,
5433 validator: CheckBoolean,
5434 suppressEvent: true
5435 }
5436 );
5437
5438 /**
5439 * @config checked
5440 * @description Boolean indicating if the menu item should be rendered
5441 * with a checkmark.
5442 * @default false
5443 * @type Boolean
5444 */
5445 oConfig.addProperty(
5446 "checked",
5447 {
5448 value: false,
5449 handler: this.configChecked,
5450 validator: this.cfg.checkBoolean,
5451 suppressEvent: true,
5452 supercedes:["disabled"]
5453 }
5454 );
5455
5456 /**
5457 * @config disabled
5458 * @description Boolean indicating if the menu item should be disabled.
5459 * (Disabled menu items are dimmed and will not respond to user input
5460 * or fire events.)
5461 * @default false
5462 * @type Boolean
5463 */
5464 oConfig.addProperty(
5465 "disabled",
5466 {
5467 value: false,
5468 handler: this.configDisabled,
5469 validator: CheckBoolean,
5470 suppressEvent: true
5471 }
5472 );
5473
5474 /**
5475 * @config selected
5476 * @description Boolean indicating if the menu item should
5477 * be highlighted.
5478 * @default false
5479 * @type Boolean
5480 */
5481 oConfig.addProperty(
5482 "selected",
5483 {
5484 value: false,
5485 handler: this.configSelected,
5486 validator: CheckBoolean,
5487 suppressEvent: true
5488 }
5489 );
5490
5491 /**
5492 * @config submenu
5493 * @description Object specifying the submenu to be appended to the
5494 * menu item. The value can be one of the following: <ul><li>Object
5495 * specifying a Menu instance.</li><li>Object literal specifying the
5496 * menu to be created. Format: <code>{ id: [menu id], itemdata:
5497 * [<a href="YAHOO.widget.Menu.html#itemData">array of values for
5498 * items</a>] }</code>.</li><li>String specifying the id attribute
5499 * of the <code>&#60;div&#62;</code> element of the menu.</li><li>
5500 * Object specifying the <code>&#60;div&#62;</code> element of the
5501 * menu.</li></ul>
5502 * @default null
5503 * @type Menu|String|Object|<a href="http://www.w3.org/TR/2000/
5504 * WD-DOM-Level-1-20000929/level-one-html.html#ID-58190037">
5505 * HTMLElement</a>
5506 */
5507 oConfig.addProperty("submenu", { handler: this.configSubmenu });
5508
5509 },
5510
5511 /**
5512 * @method getNextEnabledSibling
5513 * @description Finds the menu item's next enabled sibling.
5514 * @return YAHOO.widget.MenuItem
5515 */
5516 getNextEnabledSibling: function() {
5517
5518 if(this.parent instanceof Menu) {
5519
5520 var nGroupIndex = this.groupIndex;
5521
5522 /**
5523 * Finds the next item in an array.
5524 * @private
5525 * @param {p_aArray} Array to search.
5526 * @param {p_nStartIndex} Number indicating the index to
5527 * start searching the array.
5528 * @return {Object}
5529 */
5530 var getNextArrayItem = function(p_aArray, p_nStartIndex) {
5531
5532 return p_aArray[p_nStartIndex] ||
5533 getNextArrayItem(p_aArray, (p_nStartIndex+1));
5534
5535 };
5536
5537
5538 var aItemGroups = this.parent.getItemGroups();
5539 var oNextItem;
5540
5541
5542 if(this.index < (aItemGroups[nGroupIndex].length - 1)) {
5543
5544 oNextItem = getNextArrayItem(
5545 aItemGroups[nGroupIndex],
5546 (this.index+1)
5547 );
5548
5549 }
5550 else {
5551
5552 var nNextGroupIndex;
5553
5554 if(nGroupIndex < (aItemGroups.length - 1)) {
5555
5556 nNextGroupIndex = nGroupIndex + 1;
5557
5558 }
5559 else {
5560
5561 nNextGroupIndex = 0;
5562
5563 }
5564
5565 var aNextGroup = getNextArrayItem(aItemGroups, nNextGroupIndex);
5566
5567 // Retrieve the first menu item in the next group
5568
5569 oNextItem = getNextArrayItem(aNextGroup, 0);
5570
5571 }
5572
5573 return (
5574 oNextItem.cfg.getProperty("disabled") ||
5575 oNextItem.element.style.display == "none"
5576 ) ?
5577 oNextItem.getNextEnabledSibling() : oNextItem;
5578
5579 }
5580
5581 },
5582
5583 /**
5584 * @method getPreviousEnabledSibling
5585 * @description Finds the menu item's previous enabled sibling.
5586 * @return {YAHOO.widget.MenuItem}
5587 */
5588 getPreviousEnabledSibling: function() {
5589
5590 if(this.parent instanceof Menu) {
5591
5592 var nGroupIndex = this.groupIndex;
5593
5594 /**
5595 * Returns the previous item in an array
5596 * @private
5597 * @param {p_aArray} Array to search.
5598 * @param {p_nStartIndex} Number indicating the index to
5599 * start searching the array.
5600 * @return {Object}
5601 */
5602 var getPreviousArrayItem = function(p_aArray, p_nStartIndex) {
5603
5604 return p_aArray[p_nStartIndex] ||
5605 getPreviousArrayItem(p_aArray, (p_nStartIndex-1));
5606
5607 };
5608
5609 /**
5610 * Get the index of the first item in an array
5611 * @private
5612 * @param {p_aArray} Array to search.
5613 * @param {p_nStartIndex} Number indicating the index to
5614 * start searching the array.
5615 * @return {Object}
5616 */
5617 var getFirstItemIndex = function(p_aArray, p_nStartIndex) {
5618
5619 return p_aArray[p_nStartIndex] ?
5620 p_nStartIndex :
5621 getFirstItemIndex(p_aArray, (p_nStartIndex+1));
5622
5623 };
5624
5625 var aItemGroups = this.parent.getItemGroups();
5626 var oPreviousItem;
5627
5628 if(
5629 this.index > getFirstItemIndex(aItemGroups[nGroupIndex], 0)
5630 ) {
5631
5632 oPreviousItem =
5633 getPreviousArrayItem(
5634 aItemGroups[nGroupIndex],
5635 (this.index-1)
5636 );
5637
5638 }
5639 else {
5640
5641 var nPreviousGroupIndex;
5642
5643 if(nGroupIndex > getFirstItemIndex(aItemGroups, 0)) {
5644
5645 nPreviousGroupIndex = nGroupIndex - 1;
5646
5647 }
5648 else {
5649
5650 nPreviousGroupIndex = aItemGroups.length - 1;
5651
5652 }
5653
5654 var aPreviousGroup =
5655 getPreviousArrayItem(aItemGroups, nPreviousGroupIndex);
5656
5657 oPreviousItem =
5658 getPreviousArrayItem(
5659 aPreviousGroup,
5660 (aPreviousGroup.length - 1)
5661 );
5662
5663 }
5664
5665 return (
5666 oPreviousItem.cfg.getProperty("disabled") ||
5667 oPreviousItem.element.style.display == "none"
5668 ) ?
5669 oPreviousItem.getPreviousEnabledSibling() : oPreviousItem;
5670
5671 }
5672
5673 },
5674
5675 /**
5676 * @method focus
5677 * @description Causes the menu item to receive the focus and fires the
5678 * focus event.
5679 */
5680 focus: function() {
5681
5682 var oParent = this.parent;
5683 var oAnchor = this._oAnchor;
5684 var oActiveItem = oParent.activeItem;
5685
5686 if(
5687 !this.cfg.getProperty("disabled") &&
5688 oParent &&
5689 oParent.cfg.getProperty("visible") &&
5690 this.element.style.display != "none"
5691 ) {
5692
5693 if(oActiveItem) {
5694
5695 oActiveItem.blur();
5696
5697 }
5698
5699 try {
5700
5701 oAnchor.focus();
5702
5703 }
5704 catch(e) {
5705
5706 }
5707
5708 this.focusEvent.fire();
5709
5710 }
5711
5712 },
5713
5714 /**
5715 * @method blur
5716 * @description Causes the menu item to lose focus and fires the
5717 * onblur event.
5718 */
5719 blur: function() {
5720
5721 var oParent = this.parent;
5722
5723 if(
5724 !this.cfg.getProperty("disabled") &&
5725 oParent &&
5726 Dom.getStyle(oParent.element, "visibility") == "visible"
5727 ) {
5728
5729 this._oAnchor.blur();
5730
5731 this.blurEvent.fire();
5732
5733 }
5734
5735 },
5736
5737 /**
5738 * @method destroy
5739 * @description Removes the menu item's <code>&#60;li&#62;</code> element
5740 * from its parent <code>&#60;ul&#62;</code> element.
5741 */
5742 destroy: function() {
5743
5744 var oEl = this.element;
5745
5746 if(oEl) {
5747
5748 // Remove CustomEvent listeners
5749
5750 this.mouseOverEvent.unsubscribeAll();
5751 this.mouseOutEvent.unsubscribeAll();
5752 this.mouseDownEvent.unsubscribeAll();
5753 this.mouseUpEvent.unsubscribeAll();
5754 this.clickEvent.unsubscribeAll();
5755 this.keyPressEvent.unsubscribeAll();
5756 this.keyDownEvent.unsubscribeAll();
5757 this.keyUpEvent.unsubscribeAll();
5758 this.focusEvent.unsubscribeAll();
5759 this.blurEvent.unsubscribeAll();
5760 this.cfg.configChangedEvent.unsubscribeAll();
5761
5762 // Remove the element from the parent node
5763
5764 var oParentNode = oEl.parentNode;
5765
5766 if(oParentNode) {
5767
5768 oParentNode.removeChild(oEl);
5769
5770 this.destroyEvent.fire();
5771
5772 }
5773
5774 this.destroyEvent.unsubscribeAll();
5775
5776 }
5777
5778 },
5779
5780 /**
5781 * @method toString
5782 * @description Returns a string representing the menu item.
5783 * @return {String}
5784 */
5785 toString: function() {
5786
5787 return ("MenuItem: " + this.cfg.getProperty("text"));
5788
5789 }
5790
5791};
5792
5793})();
5794
5795/**
5796* Creates an item for a menu module.
5797*
5798* @param {String} p_oObject String specifying the text of the menu module item.
5799* @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-one-
5800* html.html#ID-74680021">HTMLLIElement</a>} p_oObject Object specifying the
5801* <code>&#60;li&#62;</code> element of the menu module item.
5802* @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-one-
5803* html.html#ID-38450247">HTMLOptGroupElement</a>} p_oObject Object specifying
5804* the <code>&#60;optgroup&#62;</code> element of the menu module item.
5805* @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-one-
5806* html.html#ID-70901257">HTMLOptionElement</a>} p_oObject Object specifying the
5807* <code>&#60;option&#62;</code> element of the menu module item.
5808* @param {Object} p_oConfig Optional. Object literal specifying the
5809* configuration for the menu module item. See configuration class documentation
5810* for more details.
5811* @class MenuModuleItem
5812* @constructor
5813* @deprecated As of version 0.12, all MenuModuleItem functionality has been
5814* implemented directly in YAHOO.widget.MenuItem, making YAHOO.widget.MenuItem
5815* the base class for all menu items.
5816*/
5817YAHOO.widget.MenuModuleItem = YAHOO.widget.MenuItem;
5818
5819/**
5820* Creates a list of options or commands which are made visible in response to
5821* an HTML element's "contextmenu" event ("mousedown" for Opera).
5822*
5823* @param {String} p_oElement String specifying the id attribute of the
5824* <code>&#60;div&#62;</code> element of the context menu.
5825* @param {String} p_oElement String specifying the id attribute of the
5826* <code>&#60;select&#62;</code> element to be used as the data source for the
5827* context menu.
5828* @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-one-
5829* html.html#ID-22445964">HTMLDivElement</a>} p_oElement Object specifying the
5830* <code>&#60;div&#62;</code> element of the context menu.
5831* @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-one-
5832* html.html#ID-94282980">HTMLSelectElement</a>} p_oElement Object specifying
5833* the <code>&#60;select&#62;</code> element to be used as the data source for
5834* the context menu.
5835* @param {Object} p_oConfig Optional. Object literal specifying the
5836* configuration for the context menu. See configuration class documentation
5837* for more details.
5838* @class ContextMenu
5839* @constructor
5840* @extends YAHOO.widget.Menu
5841* @namespace YAHOO.widget
5842*/
5843YAHOO.widget.ContextMenu = function(p_oElement, p_oConfig) {
5844
5845 YAHOO.widget.ContextMenu.superclass.constructor.call(
5846 this,
5847 p_oElement,
5848 p_oConfig
5849 );
5850
5851};
5852
5853YAHOO.extend(YAHOO.widget.ContextMenu, YAHOO.widget.Menu, {
5854
5855// Private properties
5856
5857/**
5858* @property _oTrigger
5859* @description Object reference to the current value of the "trigger"
5860* configuration property.
5861* @default null
5862* @private
5863* @type String|<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/leve
5864* l-one-html.html#ID-58190037">HTMLElement</a>|Array
5865*/
5866_oTrigger: null,
5867
5868// Public properties
5869
5870/**
5871* @property contextEventTarget
5872* @description Object reference for the HTML element that was the target of the
5873* "contextmenu" DOM event ("mousedown" for Opera) that triggered the display of
5874* the context menu.
5875* @default null
5876* @type <a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-one-
5877* html.html#ID-58190037">HTMLElement</a>
5878*/
5879contextEventTarget: null,
5880
5881/**
5882* @method init
5883* @description The ContextMenu class's initialization method. This method is
5884* automatically called by the constructor, and sets up all DOM references for
5885* pre-existing markup, and creates required markup if it is not already present.
5886* @param {String} p_oElement String specifying the id attribute of the
5887* <code>&#60;div&#62;</code> element of the context menu.
5888* @param {String} p_oElement String specifying the id attribute of the
5889* <code>&#60;select&#62;</code> element to be used as the data source for
5890* the context menu.
5891* @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-one-
5892* html.html#ID-22445964">HTMLDivElement</a>} p_oElement Object specifying the
5893* <code>&#60;div&#62;</code> element of the context menu.
5894* @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-one-
5895* html.html#ID-94282980">HTMLSelectElement</a>} p_oElement Object specifying
5896* the <code>&#60;select&#62;</code> element to be used as the data source for
5897* the context menu.
5898* @param {Object} p_oConfig Optional. Object literal specifying the
5899* configuration for the context menu. See configuration class documentation
5900* for more details.
5901*/
5902init: function(p_oElement, p_oConfig) {
5903
5904 if(!this.ITEM_TYPE) {
5905
5906 this.ITEM_TYPE = YAHOO.widget.ContextMenuItem;
5907
5908 }
5909
5910 // Call the init of the superclass (YAHOO.widget.Menu)
5911
5912 YAHOO.widget.ContextMenu.superclass.init.call(this, p_oElement);
5913
5914 this.beforeInitEvent.fire(YAHOO.widget.ContextMenu);
5915
5916 if(p_oConfig) {
5917
5918 this.cfg.applyConfig(p_oConfig, true);
5919
5920 }
5921
5922
5923 this.initEvent.fire(YAHOO.widget.ContextMenu);
5924
5925},
5926
5927// Private methods
5928
5929/**
5930* @method _removeEventHandlers
5931* @description Removes all of the DOM event handlers from the HTML element(s)
5932* whose "context menu" event ("click" for Opera) trigger the display of
5933* the context menu.
5934* @private
5935*/
5936_removeEventHandlers: function() {
5937
5938 var Event = YAHOO.util.Event;
5939 var oTrigger = this._oTrigger;
5940 var bOpera = (this.browser == "opera");
5941
5942 // Remove the event handlers from the trigger(s)
5943
5944 Event.removeListener(
5945 oTrigger,
5946 (bOpera ? "mousedown" : "contextmenu"),
5947 this._onTriggerContextMenu
5948 );
5949
5950 if(bOpera) {
5951
5952 Event.removeListener(oTrigger, "click", this._onTriggerClick);
5953
5954 }
5955
5956},
5957
5958// Private event handlers
5959
5960/**
5961* @method _onTriggerClick
5962* @description "click" event handler for the HTML element(s) identified as the
5963* "trigger" for the context menu. Used to cancel default behaviors in Opera.
5964* @private
5965* @param {Event} p_oEvent Object representing the DOM event object passed back
5966* by the event utility (YAHOO.util.Event).
5967* @param {YAHOO.widget.ContextMenu} p_oMenu Object representing the context
5968* menu that is handling the event.
5969*/
5970_onTriggerClick: function(p_oEvent, p_oMenu) {
5971
5972 if(p_oEvent.ctrlKey) {
5973
5974 YAHOO.util.Event.stopEvent(p_oEvent);
5975
5976 }
5977
5978},
5979
5980/**
5981* @method _onTriggerContextMenu
5982* @description "contextmenu" event handler ("mousedown" for Opera) for the HTML
5983* element(s) that trigger the display of the context menu.
5984* @private
5985* @param {Event} p_oEvent Object representing the DOM event object passed back
5986* by the event utility (YAHOO.util.Event).
5987* @param {YAHOO.widget.ContextMenu} p_oMenu Object representing the context
5988* menu that is handling the event.
5989*/
5990_onTriggerContextMenu: function(p_oEvent, p_oMenu) {
5991
5992 // Hide any other ContextMenu instances that might be visible
5993
5994 YAHOO.widget.MenuManager.hideVisible();
5995
5996 var Event = YAHOO.util.Event;
5997 var oConfig = this.cfg;
5998
5999 if(p_oEvent.type == "mousedown" && !p_oEvent.ctrlKey) {
6000
6001 return;
6002
6003 }
6004
6005 this.contextEventTarget = Event.getTarget(p_oEvent);
6006
6007 // Position and display the context menu
6008
6009 var nX = Event.getPageX(p_oEvent);
6010 var nY = Event.getPageY(p_oEvent);
6011
6012 oConfig.applyConfig( { xy:[nX, nY], visible:true } );
6013 oConfig.fireQueue();
6014
6015 /*
6016 Prevent the browser's default context menu from appearing and
6017 stop the propagation of the "contextmenu" event so that
6018 other ContextMenu instances are not displayed.
6019 */
6020
6021 Event.stopEvent(p_oEvent);
6022
6023},
6024
6025// Public methods
6026
6027/**
6028* @method toString
6029* @description Returns a string representing the context menu.
6030* @return {String}
6031*/
6032toString: function() {
6033
6034 return ("ContextMenu " + this.id);
6035
6036},
6037
6038/**
6039* @method initDefaultConfig
6040* @description Initializes the class's configurable properties which can be
6041* changed using the context menu's Config object ("cfg").
6042*/
6043initDefaultConfig: function() {
6044
6045 YAHOO.widget.ContextMenu.superclass.initDefaultConfig.call(this);
6046
6047 /**
6048 * @config trigger
6049 * @description The HTML element(s) whose "contextmenu" event ("mousedown"
6050 * for Opera) trigger the display of the context menu. Can be a string
6051 * representing the id attribute of the HTML element, an object reference
6052 * for the HTML element, or an array of strings or HTML element references.
6053 * @default null
6054 * @type String|<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/
6055 * level-one-html.html#ID-58190037">HTMLElement</a>|Array
6056 */
6057 this.cfg.addProperty("trigger", { handler: this.configTrigger });
6058
6059},
6060
6061/**
6062* @method destroy
6063* @description Removes the context menu's <code>&#60;div&#62;</code> element
6064* (and accompanying child nodes) from the document.
6065*/
6066destroy: function() {
6067
6068 // Remove the DOM event handlers from the current trigger(s)
6069
6070 this._removeEventHandlers();
6071
6072
6073 // Continue with the superclass implementation of this method
6074
6075 YAHOO.widget.ContextMenu.superclass.destroy.call(this);
6076
6077},
6078
6079// Public event handlers for configuration properties
6080
6081/**
6082* @method configTrigger
6083* @description Event handler for when the value of the "trigger" configuration
6084* property changes.
6085* @param {String} p_sType String representing the name of the event that
6086* was fired.
6087* @param {Array} p_aArgs Array of arguments sent when the event was fired.
6088* @param {YAHOO.widget.ContextMenu} p_oMenu Object representing the context
6089* menu that fired the event.
6090*/
6091configTrigger: function(p_sType, p_aArgs, p_oMenu) {
6092
6093 var Event = YAHOO.util.Event;
6094 var oTrigger = p_aArgs[0];
6095
6096 if(oTrigger) {
6097
6098 /*
6099 If there is a current "trigger" - remove the event handlers
6100 from that element(s) before assigning new ones
6101 */
6102
6103 if(this._oTrigger) {
6104
6105 this._removeEventHandlers();
6106
6107 }
6108
6109 this._oTrigger = oTrigger;
6110
6111 /*
6112 Listen for the "mousedown" event in Opera b/c it does not
6113 support the "contextmenu" event
6114 */
6115
6116 var bOpera = (this.browser == "opera");
6117
6118 Event.addListener(
6119 oTrigger,
6120 (bOpera ? "mousedown" : "contextmenu"),
6121 this._onTriggerContextMenu,
6122 this,
6123 true
6124 );
6125
6126 /*
6127 Assign a "click" event handler to the trigger element(s) for
6128 Opera to prevent default browser behaviors.
6129 */
6130
6131 if(bOpera) {
6132
6133 Event.addListener(
6134 oTrigger,
6135 "click",
6136 this._onTriggerClick,
6137 this,
6138 true
6139 );
6140
6141 }
6142
6143 }
6144 else {
6145
6146 this._removeEventHandlers();
6147
6148 }
6149
6150}
6151
6152}); // END YAHOO.extend
6153
6154/**
6155* Creates an item for a context menu.
6156*
6157* @param {String} p_oObject String specifying the text of the context menu item.
6158* @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-
6159* one-html.html#ID-74680021">HTMLLIElement</a>} p_oObject Object specifying the
6160* <code>&#60;li&#62;</code> element of the context menu item.
6161* @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-
6162* one-html.html#ID-38450247">HTMLOptGroupElement</a>} p_oObject Object
6163* specifying the <code>&#60;optgroup&#62;</code> element of the context
6164* menu item.
6165* @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-
6166* one-html.html#ID-70901257">HTMLOptionElement</a>} p_oObject Object specifying
6167* the <code>&#60;option&#62;</code> element of the context menu item.
6168* @param {Object} p_oConfig Optional. Object literal specifying the
6169* configuration for the context menu item. See configuration class
6170* documentation for more details.
6171* @class ContextMenuItem
6172* @constructor
6173* @extends YAHOO.widget.MenuItem
6174*/
6175YAHOO.widget.ContextMenuItem = function(p_oObject, p_oConfig) {
6176
6177 YAHOO.widget.ContextMenuItem.superclass.constructor.call(
6178 this,
6179 p_oObject,
6180 p_oConfig
6181 );
6182
6183};
6184
6185YAHOO.extend(YAHOO.widget.ContextMenuItem, YAHOO.widget.MenuItem, {
6186
6187/**
6188* @method init
6189* @description The ContextMenuItem class's initialization method. This method
6190* is automatically called by the constructor, and sets up all DOM references
6191* for pre-existing markup, and creates required markup if it is not
6192* already present.
6193* @param {String} p_oObject String specifying the text of the context menu item.
6194* @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-
6195* one-html.html#ID-74680021">HTMLLIElement</a>} p_oObject Object specifying the
6196* <code>&#60;li&#62;</code> element of the context menu item.
6197* @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-
6198* one-html.html#ID-38450247">HTMLOptGroupElement</a>} p_oObject Object
6199* specifying the <code>&#60;optgroup&#62;</code> element of the context
6200* menu item.
6201* @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-
6202* one-html.html#ID-70901257">HTMLOptionElement</a>} p_oObject Object specifying
6203* the <code>&#60;option&#62;</code> element of the context menu item.
6204* @param {Object} p_oConfig Optional. Object literal specifying the
6205* configuration for the context menu item. See configuration class
6206* documentation for more details.
6207*/
6208init: function(p_oObject, p_oConfig) {
6209
6210 if(!this.SUBMENU_TYPE) {
6211
6212 this.SUBMENU_TYPE = YAHOO.widget.ContextMenu;
6213
6214 }
6215
6216 /*
6217 Call the init of the superclass (YAHOO.widget.MenuItem)
6218 Note: We don't pass the user config in here yet
6219 because we only want it executed once, at the lowest
6220 subclass level.
6221 */
6222
6223 YAHOO.widget.ContextMenuItem.superclass.init.call(this, p_oObject);
6224
6225 var oConfig = this.cfg;
6226
6227 if(p_oConfig) {
6228
6229 oConfig.applyConfig(p_oConfig, true);
6230
6231 }
6232
6233 oConfig.fireQueue();
6234
6235},
6236
6237// Public methods
6238
6239/**
6240* @method toString
6241* @description Returns a string representing the context menu item.
6242* @return {String}
6243*/
6244toString: function() {
6245
6246 return ("MenuBarItem: " + this.cfg.getProperty("text"));
6247
6248}
6249
6250}); // END YAHOO.extend
6251
6252/**
6253* Horizontal collection of items, each of which can contain a submenu.
6254*
6255* @param {String} p_oElement String specifying the id attribute of the
6256* <code>&#60;div&#62;</code> element of the menu bar.
6257* @param {String} p_oElement String specifying the id attribute of the
6258* <code>&#60;select&#62;</code> element to be used as the data source for the
6259* menu bar.
6260* @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-
6261* one-html.html#ID-22445964">HTMLDivElement</a>} p_oElement Object specifying
6262* the <code>&#60;div&#62;</code> element of the menu bar.
6263* @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-
6264* one-html.html#ID-94282980">HTMLSelectElement</a>} p_oElement Object
6265* specifying the <code>&#60;select&#62;</code> element to be used as the data
6266* source for the menu bar.
6267* @param {Object} p_oConfig Optional. Object literal specifying the
6268* configuration for the menu bar. See configuration class documentation for
6269* more details.
6270* @class Menubar
6271* @constructor
6272* @extends YAHOO.widget.Menu
6273* @namespace YAHOO.widget
6274*/
6275YAHOO.widget.MenuBar = function(p_oElement, p_oConfig) {
6276
6277 YAHOO.widget.MenuBar.superclass.constructor.call(
6278 this,
6279 p_oElement,
6280 p_oConfig
6281 );
6282
6283};
6284
6285YAHOO.extend(YAHOO.widget.MenuBar, YAHOO.widget.Menu, {
6286
6287/**
6288* @method init
6289* @description The MenuBar class's initialization method. This method is
6290* automatically called by the constructor, and sets up all DOM references for
6291* pre-existing markup, and creates required markup if it is not already present.
6292* @param {String} p_oElement String specifying the id attribute of the
6293* <code>&#60;div&#62;</code> element of the menu bar.
6294* @param {String} p_oElement String specifying the id attribute of the
6295* <code>&#60;select&#62;</code> element to be used as the data source for the
6296* menu bar.
6297* @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-
6298* one-html.html#ID-22445964">HTMLDivElement</a>} p_oElement Object specifying
6299* the <code>&#60;div&#62;</code> element of the menu bar.
6300* @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-
6301* one-html.html#ID-94282980">HTMLSelectElement</a>} p_oElement Object
6302* specifying the <code>&#60;select&#62;</code> element to be used as the data
6303* source for the menu bar.
6304* @param {Object} p_oConfig Optional. Object literal specifying the
6305* configuration for the menu bar. See configuration class documentation for
6306* more details.
6307*/
6308init: function(p_oElement, p_oConfig) {
6309
6310 if(!this.ITEM_TYPE) {
6311
6312 this.ITEM_TYPE = YAHOO.widget.MenuBarItem;
6313
6314 }
6315
6316 // Call the init of the superclass (YAHOO.widget.Menu)
6317
6318 YAHOO.widget.MenuBar.superclass.init.call(this, p_oElement);
6319
6320 this.beforeInitEvent.fire(YAHOO.widget.MenuBar);
6321
6322 if(p_oConfig) {
6323
6324 this.cfg.applyConfig(p_oConfig, true);
6325
6326 }
6327
6328 this.initEvent.fire(YAHOO.widget.MenuBar);
6329
6330},
6331
6332// Constants
6333
6334/**
6335* @property CSS_CLASS_NAME
6336* @description String representing the CSS class(es) to be applied to the menu
6337* bar's <code>&#60;div&#62;</code> element.
6338* @default "yuimenubar"
6339* @final
6340* @type String
6341*/
6342CSS_CLASS_NAME: "yuimenubar",
6343
6344// Protected event handlers
6345
6346/**
6347* @method _onKeyDown
6348* @description "keydown" Custom Event handler for the menu bar.
6349* @private
6350* @param {String} p_sType String representing the name of the event that
6351* was fired.
6352* @param {Array} p_aArgs Array of arguments sent when the event was fired.
6353* @param {YAHOO.widget.MenuBar} p_oMenuBar Object representing the menu bar
6354* that fired the event.
6355*/
6356_onKeyDown: function(p_sType, p_aArgs, p_oMenuBar) {
6357
6358 var Event = YAHOO.util.Event;
6359 var oEvent = p_aArgs[0];
6360 var oItem = p_aArgs[1];
6361 var oItemCfg = oItem.cfg;
6362 var oSubmenu;
6363
6364 switch(oEvent.keyCode) {
6365
6366 case 27: // Esc key
6367
6368 if(this.cfg.getProperty("position") == "dynamic") {
6369
6370 this.hide();
6371
6372 if(this.parent) {
6373
6374 this.parent.focus();
6375
6376 }
6377
6378 }
6379 else if(this.activeItem) {
6380
6381 oSubmenu = this.activeItem.cfg.getProperty("submenu");
6382
6383 if(oSubmenu && oSubmenu.cfg.getProperty("visible")) {
6384
6385 oSubmenu.hide();
6386 this.activeItem.focus();
6387
6388 }
6389 else {
6390
6391 this.activeItem.cfg.setProperty("selected", false);
6392 this.activeItem.blur();
6393
6394 }
6395
6396 }
6397
6398
6399 Event.preventDefault(oEvent);
6400
6401 break;
6402
6403 case 37: // Left arrow
6404 case 39: // Right arrow
6405
6406 if(
6407 oItem == this.activeItem &&
6408 !oItemCfg.getProperty("selected")
6409 ) {
6410
6411 oItemCfg.setProperty("selected", true);
6412
6413 }
6414 else {
6415
6416 var oNextItem = (oEvent.keyCode == 37) ?
6417 oItem.getPreviousEnabledSibling() :
6418 oItem.getNextEnabledSibling();
6419
6420 if(oNextItem) {
6421
6422 this.clearActiveItem();
6423
6424 oNextItem.cfg.setProperty("selected", true);
6425
6426 if(this.cfg.getProperty("autosubmenudisplay")) {
6427
6428 oSubmenu = oNextItem.cfg.getProperty("submenu");
6429
6430 if(oSubmenu) {
6431
6432 oSubmenu.show();
6433 oSubmenu.activeItem.blur();
6434 oSubmenu.activeItem = null;
6435
6436 }
6437
6438 }
6439
6440 oNextItem.focus();
6441
6442 }
6443
6444 }
6445
6446 Event.preventDefault(oEvent);
6447
6448 break;
6449
6450 case 40: // Down arrow
6451
6452 if(this.activeItem != oItem) {
6453
6454 this.clearActiveItem();
6455
6456 oItemCfg.setProperty("selected", true);
6457 oItem.focus();
6458
6459 }
6460
6461 oSubmenu = oItemCfg.getProperty("submenu");
6462
6463 if(oSubmenu) {
6464
6465 if(oSubmenu.cfg.getProperty("visible")) {
6466
6467 oSubmenu.setInitialSelection();
6468 oSubmenu.setInitialFocus();
6469
6470 }
6471 else {
6472
6473 oSubmenu.show();
6474
6475 }
6476
6477 }
6478
6479 Event.preventDefault(oEvent);
6480
6481 break;
6482
6483 }
6484
6485},
6486
6487/**
6488* @method _onClick
6489* @description "click" event handler for the menu bar.
6490* @protected
6491* @param {String} p_sType String representing the name of the event that
6492* was fired.
6493* @param {Array} p_aArgs Array of arguments sent when the event was fired.
6494* @param {YAHOO.widget.MenuBar} p_oMenuBar Object representing the menu bar
6495* that fired the event.
6496*/
6497_onClick: function(p_sType, p_aArgs, p_oMenuBar) {
6498
6499 YAHOO.widget.MenuBar.superclass._onClick.call(
6500 this,
6501 p_sType,
6502 p_aArgs,
6503 p_oMenuBar
6504 );
6505
6506 var oItem = p_aArgs[1];
6507
6508 if(oItem) {
6509
6510 var Event = YAHOO.util.Event;
6511 var Dom = YAHOO.util.Dom;
6512
6513 var oEvent = p_aArgs[0];
6514 var oTarget = Event.getTarget(oEvent);
6515
6516 var oActiveItem = this.activeItem;
6517 var oConfig = this.cfg;
6518
6519 // Hide any other submenus that might be visible
6520
6521 if(oActiveItem && oActiveItem != oItem) {
6522
6523 this.clearActiveItem();
6524
6525 }
6526
6527
6528 // Select and focus the current item
6529
6530 oItem.cfg.setProperty("selected", true);
6531 oItem.focus();
6532
6533
6534 // Show the submenu for the item
6535
6536 var oSubmenu = oItem.cfg.getProperty("submenu");
6537
6538 if(oSubmenu && oTarget != oItem.submenuIndicator) {
6539
6540 if(oSubmenu.cfg.getProperty("visible")) {
6541
6542 oSubmenu.hide();
6543
6544 }
6545 else {
6546
6547 oSubmenu.show();
6548
6549 }
6550
6551 }
6552
6553 }
6554
6555},
6556
6557// Public methods
6558
6559/**
6560* @method toString
6561* @description Returns a string representing the menu bar.
6562* @return {String}
6563*/
6564toString: function() {
6565
6566 return ("MenuBar " + this.id);
6567
6568},
6569
6570/**
6571* @description Initializes the class's configurable properties which can be
6572* changed using the menu bar's Config object ("cfg").
6573* @method initDefaultConfig
6574*/
6575initDefaultConfig: function() {
6576
6577 YAHOO.widget.MenuBar.superclass.initDefaultConfig.call(this);
6578
6579 var oConfig = this.cfg;
6580
6581 // Add configuration properties
6582
6583 /*
6584 Set the default value for the "position" configuration property
6585 to "static" by re-adding the property.
6586 */
6587
6588 /**
6589 * @config position
6590 * @description String indicating how a menu bar should be positioned on the
6591 * screen. Possible values are "static" and "dynamic." Static menu bars
6592 * are visible by default and reside in the normal flow of the document
6593 * (CSS position: static). Dynamic menu bars are hidden by default, reside
6594 * out of the normal flow of the document (CSS position: absolute), and can
6595 * overlay other elements on the screen.
6596 * @default static
6597 * @type String
6598 */
6599 oConfig.addProperty(
6600 "position",
6601 {
6602 value: "static",
6603 handler: this.configPosition,
6604 validator: this._checkPosition,
6605 supercedes: ["visible"]
6606 }
6607 );
6608
6609 /*
6610 Set the default value for the "submenualignment" configuration property
6611 to ["tl","bl"] by re-adding the property.
6612 */
6613
6614 /**
6615 * @config submenualignment
6616 * @description Array defining how submenus should be aligned to their
6617 * parent menu bar item. The format is: [itemCorner, submenuCorner].
6618 * @default ["tl","bl"]
6619 * @type Array
6620 */
6621 oConfig.addProperty("submenualignment", { value: ["tl","bl"] } );
6622
6623 /*
6624 Change the default value for the "autosubmenudisplay" configuration
6625 property to "false" by re-adding the property.
6626 */
6627
6628 /**
6629 * @config autosubmenudisplay
6630 * @description Boolean indicating if submenus are automatically made
6631 * visible when the user mouses over the menu bar's items.
6632 * @default false
6633 * @type Boolean
6634 */
6635 oConfig.addProperty(
6636 "autosubmenudisplay",
6637 { value: false, validator: oConfig.checkBoolean }
6638 );
6639
6640}
6641
6642}); // END YAHOO.extend
6643
6644/**
6645* Creates an item for a menu bar.
6646*
6647* @param {String} p_oObject String specifying the text of the menu bar item.
6648* @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-
6649* one-html.html#ID-74680021">HTMLLIElement</a>} p_oObject Object specifying the
6650* <code>&#60;li&#62;</code> element of the menu bar item.
6651* @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-
6652* one-html.html#ID-38450247">HTMLOptGroupElement</a>} p_oObject Object
6653* specifying the <code>&#60;optgroup&#62;</code> element of the menu bar item.
6654* @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-
6655* one-html.html#ID-70901257">HTMLOptionElement</a>} p_oObject Object specifying
6656* the <code>&#60;option&#62;</code> element of the menu bar item.
6657* @param {Object} p_oConfig Optional. Object literal specifying the
6658* configuration for the menu bar item. See configuration class documentation
6659* for more details.
6660* @class MenuBarItem
6661* @constructor
6662* @extends YAHOO.widget.MenuItem
6663*/
6664YAHOO.widget.MenuBarItem = function(p_oObject, p_oConfig) {
6665
6666 YAHOO.widget.MenuBarItem.superclass.constructor.call(
6667 this,
6668 p_oObject,
6669 p_oConfig
6670 );
6671
6672};
6673
6674YAHOO.extend(YAHOO.widget.MenuBarItem, YAHOO.widget.MenuItem, {
6675
6676/**
6677* @method init
6678* @description The MenuBarItem class's initialization method. This method is
6679* automatically called by the constructor, and sets up all DOM references for
6680* pre-existing markup, and creates required markup if it is not already present.
6681* @param {String} p_oObject String specifying the text of the menu bar item.
6682* @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-
6683* one-html.html#ID-74680021">HTMLLIElement</a>} p_oObject Object specifying the
6684* <code>&#60;li&#62;</code> element of the menu bar item.
6685* @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-
6686* one-html.html#ID-38450247">HTMLOptGroupElement</a>} p_oObject Object
6687* specifying the <code>&#60;optgroup&#62;</code> element of the menu bar item.
6688* @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-
6689* one-html.html#ID-70901257">HTMLOptionElement</a>} p_oObject Object specifying
6690* the <code>&#60;option&#62;</code> element of the menu bar item.
6691* @param {Object} p_oConfig Optional. Object literal specifying the
6692* configuration for the menu bar item. See configuration class documentation
6693* for more details.
6694*/
6695init: function(p_oObject, p_oConfig) {
6696
6697 if(!this.SUBMENU_TYPE) {
6698
6699 this.SUBMENU_TYPE = YAHOO.widget.Menu;
6700
6701 }
6702
6703 /*
6704 Call the init of the superclass (YAHOO.widget.MenuItem)
6705 Note: We don't pass the user config in here yet
6706 because we only want it executed once, at the lowest
6707 subclass level.
6708 */
6709
6710 YAHOO.widget.MenuBarItem.superclass.init.call(this, p_oObject);
6711
6712 var oConfig = this.cfg;
6713
6714 if(p_oConfig) {
6715
6716 oConfig.applyConfig(p_oConfig, true);
6717
6718 }
6719
6720 oConfig.fireQueue();
6721
6722},
6723
6724// Constants
6725
6726/**
6727* @property CSS_CLASS_NAME
6728* @description String representing the CSS class(es) to be applied to the
6729* <code>&#60;li&#62;</code> element of the menu bar item.
6730* @default "yuimenubaritem"
6731* @final
6732* @type String
6733*/
6734CSS_CLASS_NAME: "yuimenubaritem",
6735
6736/**
6737* @property SUBMENU_INDICATOR_IMAGE_PATH
6738* @description String representing the path to the image to be used for the
6739* menu bar item's submenu arrow indicator.
6740* @default "nt/ic/ut/alt1/menuarodwn8_nrm_1.gif"
6741* @final
6742* @type String
6743*/
6744SUBMENU_INDICATOR_IMAGE_PATH: "nt/ic/ut/alt1/menuarodwn8_nrm_1.gif",
6745
6746/**
6747* @property SELECTED_SUBMENU_INDICATOR_IMAGE_PATH
6748* @description String representing the path to the image to be used for the
6749* submenu arrow indicator when the menu bar item is selected.
6750* @default "nt/ic/ut/alt1/menuarodwn8_hov_1.gif"
6751* @final
6752* @type String
6753*/
6754SELECTED_SUBMENU_INDICATOR_IMAGE_PATH: "nt/ic/ut/alt1/menuarodwn8_hov_1.gif",
6755
6756/**
6757* @property DISABLED_SUBMENU_INDICATOR_IMAGE_PATH
6758* @description String representing the path to the image to be used for the
6759* submenu arrow indicator when the menu bar item is disabled.
6760* @default "nt/ic/ut/alt1/menuarodwn8_dim_1.gif"
6761* @final
6762* @type String
6763*/
6764DISABLED_SUBMENU_INDICATOR_IMAGE_PATH: "nt/ic/ut/alt1/menuarodwn8_dim_1.gif",
6765
6766// Public methods
6767
6768/**
6769* @method toString
6770* @description Returns a string representing the menu bar item.
6771* @return {String}
6772*/
6773toString: function() {
6774
6775 return ("MenuBarItem: " + this.cfg.getProperty("text"));
6776
6777}
6778
6779}); // END YAHOO.extend
6780