1/* 2Copyright (c) 2008, Yahoo! Inc. All rights reserved. 3Code licensed under the BSD License: 4http://developer.yahoo.net/yui/license.txt 5version: 2.5.1 6*/ 7 8 9/** 10* @module menu 11* @description <p>The Menu family of components features a collection of 12* controls that make it easy to add menus to your website or web application. 13* With the Menu Controls you can create website fly-out menus, customized 14* context menus, or application-style menu bars with just a small amount of 15* scripting.</p><p>The Menu family of controls features:</p> 16* <ul> 17* <li>Keyboard and mouse navigation.</li> 18* <li>A rich event model that provides access to all of a menu's 19* interesting moments.</li> 20* <li>Support for 21* <a href="http://en.wikipedia.org/wiki/Progressive_Enhancement">Progressive 22* Enhancement</a>; Menus can be created from simple, 23* semantic markup on the page or purely through JavaScript.</li> 24* </ul> 25* @title Menu 26* @namespace YAHOO.widget 27* @requires Event, Dom, Container 28*/ 29(function () { 30 31 var Dom = YAHOO.util.Dom, 32 Event = YAHOO.util.Event; 33 34 35 /** 36 * Singleton that manages a collection of all menus and menu items. Listens 37 * for DOM events at the document level and dispatches the events to the 38 * corresponding menu or menu item. 39 * 40 * @namespace YAHOO.widget 41 * @class MenuManager 42 * @static 43 */ 44 YAHOO.widget.MenuManager = function () { 45 46 // Private member variables 47 48 49 // Flag indicating if the DOM event handlers have been attached 50 51 var m_bInitializedEventHandlers = false, 52 53 54 // Collection of menus 55 56 m_oMenus = {}, 57 58 59 // Collection of visible menus 60 61 m_oVisibleMenus = {}, 62 63 64 // Collection of menu items 65 66 m_oItems = {}, 67 68 69 // Map of DOM event types to their equivalent CustomEvent types 70 71 m_oEventTypes = { 72 "click": "clickEvent", 73 "mousedown": "mouseDownEvent", 74 "mouseup": "mouseUpEvent", 75 "mouseover": "mouseOverEvent", 76 "mouseout": "mouseOutEvent", 77 "keydown": "keyDownEvent", 78 "keyup": "keyUpEvent", 79 "keypress": "keyPressEvent" 80 }, 81 82 83 m_oFocusedMenuItem = null; 84 85 86 87 88 89 // Private methods 90 91 92 /** 93 * @method getMenuRootElement 94 * @description Finds the root DIV node of a menu or the root LI node of 95 * a menu item. 96 * @private 97 * @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/ 98 * level-one-html.html#ID-58190037">HTMLElement</a>} p_oElement Object 99 * specifying an HTML element. 100 */ 101 function getMenuRootElement(p_oElement) { 102 103 var oParentNode; 104 105 if (p_oElement && p_oElement.tagName) { 106 107 switch (p_oElement.tagName.toUpperCase()) { 108 109 case "DIV": 110 111 oParentNode = p_oElement.parentNode; 112 113 // Check if the DIV is the inner "body" node of a menu 114 115 if ( 116 ( 117 Dom.hasClass(p_oElement, "hd") || 118 Dom.hasClass(p_oElement, "bd") || 119 Dom.hasClass(p_oElement, "ft") 120 ) && 121 oParentNode && 122 oParentNode.tagName && 123 oParentNode.tagName.toUpperCase() == "DIV") 124 { 125 126 return oParentNode; 127 128 } 129 else { 130 131 return p_oElement; 132 133 } 134 135 break; 136 137 case "LI": 138 139 return p_oElement; 140 141 default: 142 143 oParentNode = p_oElement.parentNode; 144 145 if (oParentNode) { 146 147 return getMenuRootElement(oParentNode); 148 149 } 150 151 break; 152 153 } 154 155 } 156 157 } 158 159 160 161 // Private event handlers 162 163 164 /** 165 * @method onDOMEvent
166 * @description Generic, global event handler for all of a menu's 167 * DOM-based events. This listens for events against the document 168 * object. If the target of a given event is a member of a menu or 169 * menu item's DOM, the instance's corresponding Custom Event is fired. 170 * @private 171 * @param {Event} p_oEvent Object representing the DOM event object 172 * passed back by the event utility (YAHOO.util.Event). 173 */ 174 function onDOMEvent(p_oEvent) { 175 176 // Get the target node of the DOM event 177 178 var oTarget = Event.getTarget(p_oEvent), 179 180 // See if the target of the event was a menu, or a menu item 181 182 oElement = getMenuRootElement(oTarget), 183 sCustomEventType, 184 sTagName, 185 sId, 186 oMenuItem, 187 oMenu; 188 189 190 if (oElement) { 191 192 sTagName = oElement.tagName.toUpperCase(); 193 194 if (sTagName == "LI") { 195 196 sId = oElement.id; 197 198 if (sId && m_oItems[sId]) { 199 200 oMenuItem = m_oItems[sId]; 201 oMenu = oMenuItem.parent; 202 203 } 204 205 } 206 else if (sTagName == "DIV") { 207 208 if (oElement.id) { 209 210 oMenu = m_oMenus[oElement.id]; 211 212 } 213 214 } 215 216 } 217 218 219 if (oMenu) { 220 221 sCustomEventType = m_oEventTypes[p_oEvent.type]; 222 223 224 // Fire the Custom Event that corresponds the current DOM event 225 226 if (oMenuItem && !oMenuItem.cfg.getProperty("disabled")) { 227 228 oMenuItem[sCustomEventType].fire(p_oEvent); 229 230 231 if ( 232 p_oEvent.type == "keyup" || 233 p_oEvent.type == "mousedown") 234 { 235 236 if (m_oFocusedMenuItem != oMenuItem) { 237 238 if (m_oFocusedMenuItem) { 239 240 m_oFocusedMenuItem.blurEvent.fire(); 241 242 } 243 244 oMenuItem.focusEvent.fire(); 245 246 } 247 248 } 249 250 } 251 252 oMenu[sCustomEventType].fire(p_oEvent, oMenuItem); 253 254 } 255 else if (p_oEvent.type == "mousedown") { 256 257 if (m_oFocusedMenuItem) { 258 259 m_oFocusedMenuItem.blurEvent.fire(); 260 261 m_oFocusedMenuItem = null; 262 263 } 264 265 266 /* 267 If the target of the event wasn't a menu, hide all 268 dynamically positioned menus 269 */ 270 271 for (var i in m_oVisibleMenus) { 272 273 if (YAHOO.lang.hasOwnProperty(m_oVisibleMenus, i)) { 274 275 oMenu = m_oVisibleMenus[i]; 276 277 if (oMenu.cfg.getProperty("clicktohide") && 278 !(oMenu instanceof YAHOO.widget.MenuBar) && 279 oMenu.cfg.getProperty("position") == "dynamic") { 280 281 oMenu.hide(); 282 283 } 284 else { 285 286 oMenu.clearActiveItem(true); 287 288 } 289 290 } 291 292 } 293 294 } 295 else if (p_oEvent.type == "keyup") { 296 297 if (m_oFocusedMenuItem) { 298 299 m_oFocusedMenuItem.blurEvent.fire(); 300 301 m_oFocusedMenuItem = null; 302 303 } 304 305 } 306 307 } 308 309 310 /** 311 * @method onMenuDestroy
312 * @description "destroy" event handler for a menu. 313 * @private 314 * @param {String} p_sType String representing the name of the event 315 * that was fired. 316 * @param {Array} p_aArgs Array of arguments sent when the event 317 * was fired. 318 * @param {YAHOO.widget.Menu} p_oMenu The menu that fired the event. 319 */ 320 function onMenuDestroy(p_sType, p_aArgs, p_oMenu) { 321 322 if (m_oMenus[p_oMenu.id]) { 323 324 this.removeMenu(p_oMenu); 325 326 } 327 328 } 329 330 331 /** 332 * @method onMenuFocus 333 * @description "focus" event handler for a MenuItem instance. 334 * @private 335 * @param {String} p_sType String representing the name of the event 336 * that was fired. 337 * @param {Array} p_aArgs Array of arguments sent when the event 338 * was fired. 339 */ 340 function onMenuFocus(p_sType, p_aArgs) { 341 342 var oItem = p_aArgs[0]; 343 344 if (oItem) { 345 346 m_oFocusedMenuItem = oItem; 347 348 } 349 350 } 351 352 353 /** 354 * @method onMenuBlur 355 * @description "blur" event handler for a MenuItem instance. 356 * @private 357 * @param {String} p_sType String representing the name of the event 358 * that was fired. 359 * @param {Array} p_aArgs Array of arguments sent when the event 360 * was fired. 361 */ 362 function onMenuBlur(p_sType, p_aArgs) { 363 364 m_oFocusedMenuItem = null; 365 366 } 367 368 369 370 /** 371 * @method onMenuVisibleConfigChange 372 * @description Event handler for when the "visible" configuration 373 * property of a Menu instance changes. 374 * @private 375 * @param {String} p_sType String representing the name of the event 376 * that was fired. 377 * @param {Array} p_aArgs Array of arguments sent when the event 378 * was fired. 379 */ 380 function onMenuVisibleConfigChange(p_sType, p_aArgs) { 381 382 var bVisible = p_aArgs[0], 383 sId = this.id; 384 385 if (bVisible) { 386 387 m_oVisibleMenus[sId] = this; 388 389 390 } 391 else if (m_oVisibleMenus[sId]) { 392 393 delete m_oVisibleMenus[sId]; 394 395 396 } 397 398 } 399 400 401 /** 402 * @method onItemDestroy 403 * @description "destroy" event handler for a MenuItem instance. 404 * @private 405 * @param {String} p_sType String representing the name of the event 406 * that was fired. 407 * @param {Array} p_aArgs Array of arguments sent when the event 408 * was fired. 409 */ 410 function onItemDestroy(p_sType, p_aArgs) { 411 412 removeItem(this); 413 414 } 415 416 417 function removeItem(p_oMenuItem) { 418 419 var sId = p_oMenuItem.id; 420 421 if (sId && m_oItems[sId]) { 422 423 if (m_oFocusedMenuItem == p_oMenuItem) { 424 425 m_oFocusedMenuItem = null; 426 427 } 428 429 delete m_oItems[sId]; 430 431 p_oMenuItem.destroyEvent.unsubscribe(onItemDestroy); 432 433 434 } 435 436 } 437 438 439 /** 440 * @method onItemAdded 441 * @description "itemadded" event handler for a Menu instance. 442 * @private 443 * @param {String} p_sType String representing the name of the event 444 * that was fired. 445 * @param {Array} p_aArgs Array of arguments sent when the event 446 * was fired. 447 */ 448 function onItemAdded(p_sType, p_aArgs) { 449 450 var oItem = p_aArgs[0], 451 sId; 452 453 if (oItem instanceof YAHOO.widget.MenuItem) { 454 455 sId = oItem.id; 456 457 if (!m_oItems[sId]) { 458 459 m_oItems[sId] = oItem; 460 461 oItem.destroyEvent.subscribe(onItemDestroy); 462 463 464 } 465 466 } 467 468 } 469 470 471 return { 472 473 // Privileged methods 474 475 476 /** 477 * @method addMenu
478 * @description Adds a menu to the collection of known menus. 479 * @param {YAHOO.widget.Menu} p_oMenu Object specifying the Menu 480 * instance to be added. 481 */ 482 addMenu: function (p_oMenu) { 483 484 var oDoc; 485 486 if (p_oMenu instanceof YAHOO.widget.Menu && p_oMenu.id && 487 !m_oMenus[p_oMenu.id]) { 488 489 m_oMenus[p_oMenu.id] = p_oMenu; 490 491 492 if (!m_bInitializedEventHandlers) { 493 494 oDoc = document; 495 496 Event.on(oDoc, "mouseover", onDOMEvent, this, true); 497 Event.on(oDoc, "mouseout", onDOMEvent, this, true); 498 Event.on(oDoc, "mousedown", onDOMEvent, this, true); 499 Event.on(oDoc, "mouseup", onDOMEvent, this, true); 500 Event.on(oDoc, "click", onDOMEvent, this, true); 501 Event.on(oDoc, "keydown", onDOMEvent, this, true); 502 Event.on(oDoc, "keyup", onDOMEvent, this, true); 503 Event.on(oDoc, "keypress", onDOMEvent, this, true); 504 505 506 m_bInitializedEventHandlers = true; 507 508 509 } 510 511 p_oMenu.cfg.subscribeToConfigEvent("visible", 512 onMenuVisibleConfigChange); 513 514 p_oMenu.destroyEvent.subscribe(onMenuDestroy, p_oMenu, 515 this); 516 517 p_oMenu.itemAddedEvent.subscribe(onItemAdded); 518 p_oMenu.focusEvent.subscribe(onMenuFocus); 519 p_oMenu.blurEvent.subscribe(onMenuBlur); 520 521 522 } 523 524 }, 525 526 527 /** 528 * @method removeMenu 529 * @description Removes a menu from the collection of known menus. 530 * @param {YAHOO.widget.Menu} p_oMenu Object specifying the Menu 531 * instance to be removed. 532 */ 533 removeMenu: function (p_oMenu) { 534 535 var sId, 536 aItems, 537 i; 538 539 if (p_oMenu) { 540 541 sId = p_oMenu.id; 542 543 if (m_oMenus[sId] == p_oMenu) { 544 545 // Unregister each menu item 546 547 aItems = p_oMenu.getItems(); 548 549 if (aItems && aItems.length > 0) { 550 551 i = aItems.length - 1; 552 553 do { 554 555 removeItem(aItems[i]); 556 557 } 558 while (i--); 559 560 } 561 562 563 // Unregister the menu 564 565 delete m_oMenus[sId]; 566 567 568 569 /* 570 Unregister the menu from the collection of 571 visible menus 572 */ 573 574 if (m_oVisibleMenus[sId] == p_oMenu) { 575 576 delete m_oVisibleMenus[sId]; 577 578 579 } 580 581 582 // Unsubscribe event listeners 583 584 if (p_oMenu.cfg) { 585 586 p_oMenu.cfg.unsubscribeFromConfigEvent("visible", 587 onMenuVisibleConfigChange); 588 589 } 590 591 p_oMenu.destroyEvent.unsubscribe(onMenuDestroy, 592 p_oMenu); 593 594 p_oMenu.itemAddedEvent.unsubscribe(onItemAdded); 595 p_oMenu.focusEvent.unsubscribe(onMenuFocus); 596 p_oMenu.blurEvent.unsubscribe(onMenuBlur); 597 598 } 599 600 } 601 602 }, 603 604 605 /** 606 * @method hideVisible
607 * @description Hides all visible, dynamically positioned menus 608 * (excluding instances of YAHOO.widget.MenuBar). 609 */ 610 hideVisible: function () { 611 612 var oMenu; 613 614 for (var i in m_oVisibleMenus) { 615 616 if (YAHOO.lang.hasOwnProperty(m_oVisibleMenus, i)) { 617 618 oMenu = m_oVisibleMenus[i]; 619 620 if (!(oMenu instanceof YAHOO.widget.MenuBar) && 621 oMenu.cfg.getProperty("position") == "dynamic") { 622 623 oMenu.hide(); 624 625 } 626 627 } 628 629 } 630 631 }, 632 633 634 /** 635 * @method getVisible 636 * @description Returns a collection of all visible menus registered 637 * with the menu manger. 638 * @return {Array} 639 */ 640 getVisible: function () { 641 642 return m_oVisibleMenus; 643 644 }, 645 646 647 /** 648 * @method getMenus 649 * @description Returns a collection of all menus registered with the 650 * menu manger. 651 * @return {Array} 652 */ 653 getMenus: function () { 654 655 return m_oMenus; 656 657 }, 658 659 660 /** 661 * @method getMenu 662 * @description Returns a menu with the specified id. 663 * @param {String} p_sId String specifying the id of the 664 * <code><div></code> element representing the menu to 665 * be retrieved. 666 * @return {YAHOO.widget.Menu} 667 */ 668 getMenu: function (p_sId) { 669 670 var oMenu = m_oMenus[p_sId]; 671 672 if (oMenu) { 673 674 return oMenu; 675 676 } 677 678 }, 679 680 681 /** 682 * @method getMenuItem 683 * @description Returns a menu item with the specified id. 684 * @param {String} p_sId String specifying the id of the 685 * <code><li></code> element representing the menu item to 686 * be retrieved. 687 * @return {YAHOO.widget.MenuItem} 688 */ 689 getMenuItem: function (p_sId) { 690 691 var oItem = m_oItems[p_sId]; 692 693 if (oItem) { 694 695 return oItem; 696 697 } 698 699 }, 700 701 702 /** 703 * @method getMenuItemGroup 704 * @description Returns an array of menu item instances whose 705 * corresponding <code><li></code> elements are child 706 * nodes of the <code><ul></code> element with the 707 * specified id. 708 * @param {String} p_sId String specifying the id of the 709 * <code><ul></code> element representing the group of 710 * menu items to be retrieved. 711 * @return {Array} 712 */ 713 getMenuItemGroup: function (p_sId) { 714 715 var oUL = Dom.get(p_sId), 716 aItems, 717 oNode, 718 oItem, 719 sId; 720 721 722 if (oUL && oUL.tagName && 723 oUL.tagName.toUpperCase() == "UL") { 724 725 oNode = oUL.firstChild; 726 727 if (oNode) { 728 729 aItems = []; 730 731 do { 732 733 sId = oNode.id; 734 735 if (sId) { 736 737 oItem = this.getMenuItem(sId); 738 739 if (oItem) { 740 741 aItems[aItems.length] = oItem; 742 743 } 744 745 } 746 747 } 748 while ((oNode = oNode.nextSibling)); 749 750 751 if (aItems.length > 0) { 752 753 return aItems; 754 755 } 756 757 } 758 759 } 760 761 }, 762 763 764 /** 765 * @method getFocusedMenuItem
766 * @description Returns a reference to the menu item that currently 767 * has focus. 768 * @return {YAHOO.widget.MenuItem} 769 */ 770 getFocusedMenuItem: function () { 771 772 return m_oFocusedMenuItem; 773 774 }, 775 776 777 /** 778 * @method getFocusedMenu 779 * @description Returns a reference to the menu that currently 780 * has focus. 781 * @return {YAHOO.widget.Menu} 782 */ 783 getFocusedMenu: function () { 784 785 if (m_oFocusedMenuItem) { 786 787 return (m_oFocusedMenuItem.parent.getRoot()); 788 789 } 790 791 }, 792 793 794 /** 795 * @method toString 796 * @description Returns a string representing the menu manager. 797 * @return {String} 798 */ 799 toString: function () { 800 801 return "MenuManager"; 802 803 } 804 805 }; 806 807 }(); 808 809})(); 810 811 812 813(function () { 814 815 816/** 817* The Menu class creates a container that holds a vertical list representing 818* a set of options or commands. Menu is the base class for all 819* menu containers. 820* @param {String} p_oElement String specifying the id attribute of the 821* <code><div></code> element of the menu. 822* @param {String} p_oElement String specifying the id attribute of the 823* <code><select></code> element to be used as the data source 824* for the menu. 825* @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/ 826* level-one-html.html#ID-22445964">HTMLDivElement</a>} p_oElement Object 827* specifying the <code><div></code> element of the menu. 828* @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/ 829* level-one-html.html#ID-94282980">HTMLSelectElement</a>} p_oElement 830* Object specifying the <code><select></code> element to be used as 831* the data source for the menu. 832* @param {Object} p_oConfig Optional. Object literal specifying the 833* configuration for the menu. See configuration class documentation for 834* more details. 835* @namespace YAHOO.widget 836* @class Menu 837* @constructor 838* @extends YAHOO.widget.Overlay 839*/ 840YAHOO.widget.Menu = function (p_oElement, p_oConfig) { 841 842 if (p_oConfig) { 843 844 this.parent = p_oConfig.parent; 845 this.lazyLoad = p_oConfig.lazyLoad || p_oConfig.lazyload; 846 this.itemData = p_oConfig.itemData || p_oConfig.itemdata; 847 848 } 849 850 851 YAHOO.widget.Menu.superclass.constructor.call(this, p_oElement, p_oConfig); 852 853}; 854 855 856 857/** 858* @method checkPosition 859* @description Checks to make sure that the value of the "position" property 860* is one of the supported strings. Returns true if the position is supported. 861* @private 862* @param {Object} p_sPosition String specifying the position of the menu. 863* @return {Boolean} 864*/ 865function checkPosition(p_sPosition) { 866 867 if (typeof p_sPosition == "string") { 868 869 return ("dynamic,static".indexOf((p_sPosition.toLowerCase())) != -1); 870 871 } 872 873} 874 875 876var Dom = YAHOO.util.Dom, 877 Event = YAHOO.util.Event, 878 Module = YAHOO.widget.Module, 879 Overlay = YAHOO.widget.Overlay, 880 Menu = YAHOO.widget.Menu, 881 MenuManager = YAHOO.widget.MenuManager, 882 CustomEvent = YAHOO.util.CustomEvent, 883 Lang = YAHOO.lang, 884 UA = YAHOO.env.ua, 885 886 m_oShadowTemplate, 887 888 /** 889 * Constant representing the name of the Menu's events 890 * @property EVENT_TYPES 891 * @private 892 * @final 893 * @type Object 894 */ 895 EVENT_TYPES = { 896 897 "MOUSE_OVER": "mouseover", 898 "MOUSE_OUT": "mouseout", 899 "MOUSE_DOWN": "mousedown", 900 "MOUSE_UP": "mouseup", 901 "CLICK": "click", 902 "KEY_PRESS": "keypress", 903 "KEY_DOWN": "keydown", 904 "KEY_UP": "keyup", 905 "FOCUS": "focus", 906 "BLUR": "blur", 907 "ITEM_ADDED": "itemAdded", 908 "ITEM_REMOVED": "itemRemoved" 909 910 }, 911 912 913 /** 914 * Constant representing the Menu's configuration properties 915 * @property DEFAULT_CONFIG 916 * @private 917 * @final 918 * @type Object 919 */ 920 DEFAULT_CONFIG = { 921 922 "VISIBLE": { 923 key: "visible", 924 value: false, 925 validator: Lang.isBoolean 926 }, 927 928 "CONSTRAIN_TO_VIEWPORT": { 929 key: "constraintoviewport", 930 value: true, 931 validator: Lang.isBoolean, 932 supercedes: ["iframe","x","y","xy"] 933 }, 934 935 "POSITION": { 936 key: "position", 937 value: "dynamic", 938 validator: checkPosition, 939 supercedes: ["visible", "iframe"] 940 }, 941 942 "SUBMENU_ALIGNMENT": { 943 key: "submenualignment", 944 value: ["tl","tr"], 945 suppressEvent: true 946 }, 947 948 "AUTO_SUBMENU_DISPLAY": {
949 key: "autosubmenudisplay", 950 value: true, 951 validator: Lang.isBoolean, 952 suppressEvent: true 953 }, 954 955 "SHOW_DELAY": { 956 key: "showdelay", 957 value: 250, 958 validator: Lang.isNumber, 959 suppressEvent: true 960 }, 961 962 "HIDE_DELAY": { 963 key: "hidedelay", 964 value: 0, 965 validator: Lang.isNumber, 966 suppressEvent: true 967 }, 968 969 "SUBMENU_HIDE_DELAY": { 970 key: "submenuhidedelay", 971 value: 250, 972 validator: Lang.isNumber, 973 suppressEvent: true 974 }, 975 976 "CLICK_TO_HIDE": { 977 key: "clicktohide", 978 value: true, 979 validator: Lang.isBoolean, 980 suppressEvent: true 981 }, 982 983 "CONTAINER": { 984 key: "container", 985 suppressEvent: true 986 }, 987 988 "SCROLL_INCREMENT": { 989 key: "scrollincrement", 990 value: 1, 991 validator: Lang.isNumber, 992 supercedes: ["maxheight"], 993 suppressEvent: true 994 }, 995 996 "MIN_SCROLL_HEIGHT": { 997 key: "minscrollheight", 998 value: 90, 999 validator: Lang.isNumber, 1000 supercedes: ["maxheight"], 1001 suppressEvent: true 1002 }, 1003 1004 "MAX_HEIGHT": { 1005 key: "maxheight", 1006 value: 0, 1007 validator: Lang.isNumber, 1008 supercedes: ["iframe"], 1009 suppressEvent: true 1010 }, 1011 1012 "CLASS_NAME": { 1013 key: "classname", 1014 value: null, 1015 validator: Lang.isString, 1016 suppressEvent: true 1017 }, 1018 1019 "DISABLED": { 1020 key: "disabled", 1021 value: false, 1022 validator: Lang.isBoolean, 1023 suppressEvent: true 1024 } 1025 1026 }; 1027 1028 1029 1030YAHOO.lang.extend(Menu, Overlay, { 1031 1032 1033// Constants 1034 1035 1036/** 1037* @property CSS_CLASS_NAME 1038* @description String representing the CSS class(es) to be applied to the 1039* menu's <code><div></code> element. 1040* @default "yuimenu" 1041* @final 1042* @type String 1043*/ 1044CSS_CLASS_NAME: "yuimenu", 1045 1046 1047/** 1048* @property ITEM_TYPE 1049* @description Object representing the type of menu item to instantiate and 1050* add when parsing the child nodes (either <code><li></code> element, 1051* <code><optgroup></code> element or <code><option></code>) 1052* of the menu's source HTML element. 1053* @default YAHOO.widget.MenuItem 1054* @final 1055* @type YAHOO.widget.MenuItem 1056*/ 1057ITEM_TYPE: null, 1058 1059 1060/** 1061* @property GROUP_TITLE_TAG_NAME 1062* @description String representing the tagname of the HTML element used to 1063* title the menu's item groups. 1064* @default H6 1065* @final 1066* @type String 1067*/ 1068GROUP_TITLE_TAG_NAME: "h6", 1069 1070 1071/** 1072* @property OFF_SCREEN_POSITION 1073* @description Array representing the default x and y position that a menu 1074* should have when it is positioned outside the viewport by the 1075* "poistionOffScreen" method. 1076* @default [-10000, -10000] 1077* @final 1078* @type Array 1079*/ 1080OFF_SCREEN_POSITION: [-10000, -10000], 1081 1082 1083// Private properties 1084 1085 1086/** 1087* @property _nHideDelayId 1088* @description Number representing the time-out setting used to cancel the 1089* hiding of a menu. 1090* @default null 1091* @private 1092* @type Number 1093*/ 1094_nHideDelayId: null, 1095 1096 1097/** 1098* @property _nShowDelayId 1099* @description Number representing the time-out setting used to cancel the 1100* showing of a menu. 1101* @default null 1102* @private 1103* @type Number 1104*/ 1105_nShowDelayId: null, 1106 1107 1108/** 1109* @property _nSubmenuHideDelayId 1110* @description Number representing the time-out setting used to cancel the 1111* hiding of a submenu. 1112* @default null 1113* @private 1114* @type Number 1115*/ 1116_nSubmenuHideDelayId: null, 1117 1118 1119/** 1120* @property _nBodyScrollId 1121* @description Number representing the time-out setting used to cancel the 1122* scrolling of the menu's body element. 1123* @default null 1124* @private 1125* @type Number 1126*/ 1127_nBodyScrollId: null, 1128 1129 1130/** 1131* @property _bHideDelayEventHandlersAssigned 1132* @description Boolean indicating if the "mouseover" and "mouseout" event 1133* handlers used for hiding the menu via a call to "window.setTimeout" have 1134* already been assigned. 1135* @default false 1136* @private 1137* @type Boolean 1138*/ 1139_bHideDelayEventHandlersAssigned: false, 1140 1141 1142/** 1143* @property _bHandledMouseOverEvent 1144* @description Boolean indicating the current state of the menu's
1145* "mouseover" event. 1146* @default false 1147* @private 1148* @type Boolean 1149*/ 1150_bHandledMouseOverEvent: false, 1151 1152 1153/** 1154* @property _bHandledMouseOutEvent 1155* @description Boolean indicating the current state of the menu's 1156* "mouseout" event. 1157* @default false 1158* @private 1159* @type Boolean 1160*/ 1161_bHandledMouseOutEvent: false, 1162 1163 1164/** 1165* @property _aGroupTitleElements 1166* @description Array of HTML element used to title groups of menu items. 1167* @default [] 1168* @private 1169* @type Array 1170*/ 1171_aGroupTitleElements: null, 1172 1173 1174/** 1175* @property _aItemGroups 1176* @description Multi-dimensional Array representing the menu items as they 1177* are grouped in the menu. 1178* @default [] 1179* @private 1180* @type Array 1181*/ 1182_aItemGroups: null, 1183 1184 1185/** 1186* @property _aListElements 1187* @description Array of <code><ul></code> elements, each of which is 1188* the parent node for each item's <code><li></code> element. 1189* @default [] 1190* @private 1191* @type Array 1192*/ 1193_aListElements: null, 1194 1195 1196/** 1197* @property _nCurrentMouseX 1198* @description The current x coordinate of the mouse inside the area of 1199* the menu. 1200* @default 0 1201* @private 1202* @type Number 1203*/ 1204_nCurrentMouseX: 0, 1205 1206 1207/** 1208* @property _bStopMouseEventHandlers 1209* @description Stops "mouseover," "mouseout," and "mousemove" event handlers 1210* from executing. 1211* @default false 1212* @private 1213* @type Boolean 1214*/ 1215_bStopMouseEventHandlers: false, 1216 1217 1218/** 1219* @property _sClassName 1220* @description The current value of the "classname" configuration attribute. 1221* @default null 1222* @private 1223* @type String 1224*/ 1225_sClassName: null, 1226 1227 1228 1229// Public properties 1230 1231 1232/** 1233* @property lazyLoad 1234* @description Boolean indicating if the menu's "lazy load" feature is 1235* enabled. If set to "true," initialization and rendering of the menu's 1236* items will be deferred until the first time it is made visible. This 1237* property should be set via the constructor using the configuration 1238* object literal. 1239* @default false 1240* @type Boolean 1241*/ 1242lazyLoad: false, 1243 1244 1245/** 1246* @property itemData 1247* @description Array of items to be added to the menu. The array can contain 1248* strings representing the text for each item to be created, object literals 1249* representing the menu item configuration properties, or MenuItem instances. 1250* This property should be set via the constructor using the configuration 1251* object literal. 1252* @default null 1253* @type Array 1254*/ 1255itemData: null, 1256 1257 1258/** 1259* @property activeItem 1260* @description Object reference to the item in the menu that has is selected. 1261* @default null 1262* @type YAHOO.widget.MenuItem 1263*/ 1264activeItem: null, 1265 1266 1267/** 1268* @property parent 1269* @description Object reference to the menu's parent menu or menu item. 1270* This property can be set via the constructor using the configuration 1271* object literal. 1272* @default null 1273* @type YAHOO.widget.MenuItem 1274*/ 1275parent: null, 1276 1277 1278/** 1279* @property srcElement 1280* @description Object reference to the HTML element (either 1281* <code><select></code> or <code><div></code>) used to 1282* create the menu. 1283* @default null 1284* @type <a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/ 1285* level-one-html.html#ID-94282980">HTMLSelectElement</a>|<a 1286* href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-one-html. 1287* html#ID-22445964">HTMLDivElement</a> 1288*/ 1289srcElement: null, 1290 1291 1292 1293// Events 1294 1295 1296/** 1297* @event mouseOverEvent 1298* @description Fires when the mouse has entered the menu. Passes back 1299* the DOM Event object as an argument. 1300*/ 1301mouseOverEvent: null, 1302 1303 1304/** 1305* @event mouseOutEvent 1306* @description Fires when the mouse has left the menu. Passes back the DOM 1307* Event object as an argument. 1308* @type YAHOO.util.CustomEvent 1309*/ 1310mouseOutEvent: null, 1311 1312 1313/** 1314* @event mouseDownEvent 1315* @description Fires when the user mouses down on the menu. Passes back the 1316* DOM Event object as an argument. 1317* @type YAHOO.util.CustomEvent 1318*/ 1319mouseDownEvent: null, 1320 1321 1322/** 1323* @event mouseUpEvent 1324* @description Fires when the user releases a mouse button while the mouse is 1325* over the menu. Passes back the DOM Event object as an argument. 1326* @type YAHOO.util.CustomEvent 1327*/ 1328mouseUpEvent: null, 1329 1330 1331/** 1332* @event clickEvent 1333* @description Fires when the user clicks the on the menu. Passes back the 1334* DOM Event object as an argument. 1335* @type YAHOO.util.CustomEvent 1336*/
1337clickEvent: null, 1338 1339 1340/** 1341* @event keyPressEvent 1342* @description Fires when the user presses an alphanumeric key when one of the 1343* menu's items has focus. Passes back the DOM Event object as an argument. 1344* @type YAHOO.util.CustomEvent 1345*/ 1346keyPressEvent: null, 1347 1348 1349/** 1350* @event keyDownEvent 1351* @description Fires when the user presses a key when one of the menu's items 1352* has focus. Passes back the DOM Event object as an argument. 1353* @type YAHOO.util.CustomEvent 1354*/ 1355keyDownEvent: null, 1356 1357 1358/** 1359* @event keyUpEvent 1360* @description Fires when the user releases a key when one of the menu's items 1361* has focus. Passes back the DOM Event object as an argument. 1362* @type YAHOO.util.CustomEvent 1363*/ 1364keyUpEvent: null, 1365 1366 1367/** 1368* @event itemAddedEvent 1369* @description Fires when an item is added to the menu. 1370* @type YAHOO.util.CustomEvent 1371*/ 1372itemAddedEvent: null, 1373 1374 1375/** 1376* @event itemRemovedEvent 1377* @description Fires when an item is removed to the menu. 1378* @type YAHOO.util.CustomEvent 1379*/ 1380itemRemovedEvent: null, 1381 1382 1383/** 1384* @method init 1385* @description The Menu class's initialization method. This method is 1386* automatically called by the constructor, and sets up all DOM references 1387* for pre-existing markup, and creates required markup if it is not 1388* already present. 1389* @param {String} p_oElement String specifying the id attribute of the 1390* <code><div></code> element of the menu. 1391* @param {String} p_oElement String specifying the id attribute of the 1392* <code><select></code> element to be used as the data source 1393* for the menu. 1394* @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/ 1395* level-one-html.html#ID-22445964">HTMLDivElement</a>} p_oElement Object 1396* specifying the <code><div></code> element of the menu. 1397* @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/ 1398* level-one-html.html#ID-94282980">HTMLSelectElement</a>} p_oElement 1399* Object specifying the <code><select></code> element to be used as 1400* the data source for the menu. 1401* @param {Object} p_oConfig Optional. Object literal specifying the 1402* configuration for the menu. See configuration class documentation for 1403* more details. 1404*/ 1405init: function (p_oElement, p_oConfig) { 1406 1407 this._aItemGroups = []; 1408 this._aListElements = []; 1409 this._aGroupTitleElements = []; 1410 1411 if (!this.ITEM_TYPE) { 1412 1413 this.ITEM_TYPE = YAHOO.widget.MenuItem; 1414 1415 } 1416 1417 1418 var oElement; 1419 1420 if (typeof p_oElement == "string") { 1421 1422 oElement = document.getElementById(p_oElement); 1423 1424 } 1425 else if (p_oElement.tagName) { 1426 1427 oElement = p_oElement; 1428 1429 } 1430 1431 1432 if (oElement && oElement.tagName) { 1433 1434 switch(oElement.tagName.toUpperCase()) { 1435 1436 case "DIV": 1437 1438 this.srcElement = oElement; 1439 1440 if (!oElement.id) { 1441 1442 oElement.setAttribute("id", Dom.generateId()); 1443 1444 } 1445 1446 1447 /* 1448 Note: we don't pass the user config in here yet 1449 because we only want it executed once, at the lowest 1450 subclass level. 1451 */ 1452 1453 Menu.superclass.init.call(this, oElement); 1454 1455 this.beforeInitEvent.fire(Menu); 1456 1457 1458 1459 break; 1460 1461 case "SELECT": 1462 1463 this.srcElement = oElement; 1464 1465 1466 /* 1467 The source element is not something that we can use 1468 outright, so we need to create a new Overlay 1469 1470 Note: we don't pass the user config in here yet 1471 because we only want it executed once, at the lowest 1472 subclass level. 1473 */ 1474 1475 Menu.superclass.init.call(this, Dom.generateId()); 1476 1477 this.beforeInitEvent.fire(Menu); 1478 1479 1480 1481 break; 1482 1483 } 1484 1485 } 1486 else { 1487 1488 /* 1489 Note: we don't pass the user config in here yet 1490 because we only want it executed once, at the lowest 1491 subclass level. 1492 */ 1493 1494 Menu.superclass.init.call(this, p_oElement); 1495 1496 this.beforeInitEvent.fire(Menu); 1497 1498 1499 1500 } 1501 1502 1503 if (this.element) { 1504 1505 Dom.addClass(this.element, this.CSS_CLASS_NAME); 1506 1507 1508 // Subscribe to Custom Events 1509 1510 this.initEvent.subscribe(this._onInit); 1511 this.beforeRenderEvent.subscribe(this._onBeforeRender); 1512 this.renderEvent.subscribe(this._onRender); 1513 this.renderEvent.subscribe(this.onRender); 1514 this.beforeShowEvent.subscribe(this._onBeforeShow); 1515 this.hideEvent.subscribe(this.positionOffScreen); 1516 this.showEvent.subscribe(this._onShow); 1517 this.beforeHideEvent.subscribe(this._onBeforeHide);
1518 this.mouseOverEvent.subscribe(this._onMouseOver); 1519 this.mouseOutEvent.subscribe(this._onMouseOut); 1520 this.clickEvent.subscribe(this._onClick); 1521 this.keyDownEvent.subscribe(this._onKeyDown); 1522 this.keyPressEvent.subscribe(this._onKeyPress); 1523 1524 1525 if (UA.gecko || UA.webkit) { 1526 1527 this.cfg.subscribeToConfigEvent("y", this._onYChange); 1528 1529 } 1530 1531 1532 if (p_oConfig) { 1533 1534 this.cfg.applyConfig(p_oConfig, true); 1535 1536 } 1537 1538 1539 // Register the Menu instance with the MenuManager 1540 1541 MenuManager.addMenu(this); 1542 1543 1544 this.initEvent.fire(Menu); 1545 1546 } 1547 1548}, 1549 1550 1551 1552// Private methods 1553 1554 1555/** 1556* @method _initSubTree 1557* @description Iterates the childNodes of the source element to find nodes 1558* used to instantiate menu and menu items. 1559* @private 1560*/ 1561_initSubTree: function () { 1562 1563 var oSrcElement = this.srcElement, 1564 sSrcElementTagName, 1565 nGroup, 1566 sGroupTitleTagName, 1567 oNode, 1568 aListElements, 1569 nListElements, 1570 i; 1571 1572 1573 if (oSrcElement) { 1574 1575 sSrcElementTagName = 1576 (oSrcElement.tagName && oSrcElement.tagName.toUpperCase()); 1577 1578 1579 if (sSrcElementTagName == "DIV") { 1580 1581 // Populate the collection of item groups and item group titles 1582 1583 oNode = this.body.firstChild; 1584 1585 1586 if (oNode) { 1587 1588 nGroup = 0; 1589 sGroupTitleTagName = this.GROUP_TITLE_TAG_NAME.toUpperCase(); 1590 1591 do { 1592 1593 1594 if (oNode && oNode.tagName) { 1595 1596 switch (oNode.tagName.toUpperCase()) { 1597 1598 case sGroupTitleTagName: 1599 1600 this._aGroupTitleElements[nGroup] = oNode; 1601 1602 break; 1603 1604 case "UL": 1605 1606 this._aListElements[nGroup] = oNode; 1607 this._aItemGroups[nGroup] = []; 1608 nGroup++; 1609 1610 break; 1611 1612 } 1613 1614 } 1615 1616 } 1617 while ((oNode = oNode.nextSibling)); 1618 1619 1620 /* 1621 Apply the "first-of-type" class to the first UL to mimic 1622 the "first-of-type" CSS3 psuedo class. 1623 */ 1624 1625 if (this._aListElements[0]) { 1626 1627 Dom.addClass(this._aListElements[0], "first-of-type"); 1628 1629 } 1630 1631 } 1632 1633 } 1634 1635 1636 oNode = null; 1637 1638 1639 1640 if (sSrcElementTagName) { 1641 1642 switch (sSrcElementTagName) { 1643 1644 case "DIV": 1645 1646 aListElements = this._aListElements; 1647 nListElements = aListElements.length; 1648 1649 if (nListElements > 0) { 1650 1651 1652 i = nListElements - 1; 1653 1654 do { 1655 1656 oNode = aListElements[i].firstChild; 1657 1658 if (oNode) { 1659 1660 1661 do { 1662 1663 if (oNode && oNode.tagName && 1664 oNode.tagName.toUpperCase() == "LI") { 1665 1666 1667 this.addItem(new this.ITEM_TYPE(oNode, 1668 { parent: this }), i); 1669 1670 } 1671 1672 } 1673 while ((oNode = oNode.nextSibling)); 1674 1675 } 1676 1677 } 1678 while (i--); 1679 1680 } 1681 1682 break; 1683 1684 case "SELECT": 1685 1686 1687 oNode = oSrcElement.firstChild; 1688 1689 do { 1690 1691 if (oNode && oNode.tagName) { 1692 1693 switch (oNode.tagName.toUpperCase()) { 1694 1695 case "OPTGROUP": 1696 case "OPTION": 1697 1698 1699 this.addItem( 1700 new this.ITEM_TYPE( 1701 oNode, 1702 { parent: this } 1703 ) 1704 ); 1705 1706 break; 1707 1708 } 1709 1710 } 1711 1712 } 1713 while ((oNode = oNode.nextSibling)); 1714 1715 break; 1716 1717 } 1718 1719 } 1720 1721 } 1722 1723}, 1724 1725 1726/** 1727* @method _getFirstEnabledItem 1728* @description Returns the first enabled item in the menu.
1729* @return {YAHOO.widget.MenuItem} 1730* @private 1731*/ 1732_getFirstEnabledItem: function () { 1733 1734 var aItems = this.getItems(), 1735 nItems = aItems.length, 1736 oItem; 1737 1738 for(var i=0; i<nItems; i++) { 1739 1740 oItem = aItems[i]; 1741 1742 if (oItem && !oItem.cfg.getProperty("disabled") && 1743 oItem.element.style.display != "none") { 1744 1745 return oItem; 1746 1747 } 1748 1749 } 1750 1751}, 1752 1753 1754/** 1755* @method _addItemToGroup 1756* @description Adds a menu item to a group. 1757* @private 1758* @param {Number} p_nGroupIndex Number indicating the group to which the 1759* item belongs. 1760* @param {YAHOO.widget.MenuItem} p_oItem Object reference for the MenuItem 1761* instance to be added to the menu. 1762* @param {String} p_oItem String specifying the text of the item to be added 1763* to the menu. 1764* @param {Object} p_oItem Object literal containing a set of menu item 1765* configuration properties. 1766* @param {Number} p_nItemIndex Optional. Number indicating the index at 1767* which the menu item should be added. 1768* @return {YAHOO.widget.MenuItem} 1769*/ 1770_addItemToGroup: function (p_nGroupIndex, p_oItem, p_nItemIndex) { 1771 1772 var oItem, 1773 nGroupIndex, 1774 aGroup, 1775 oGroupItem, 1776 bAppend, 1777 oNextItemSibling, 1778 nItemIndex; 1779 1780 function getNextItemSibling(p_aArray, p_nStartIndex) { 1781 1782 return (p_aArray[p_nStartIndex] || getNextItemSibling(p_aArray, 1783 (p_nStartIndex+1))); 1784 1785 } 1786 1787 if (p_oItem instanceof this.ITEM_TYPE) { 1788 1789 oItem = p_oItem; 1790 oItem.parent = this; 1791 1792 } 1793 else if (typeof p_oItem == "string") { 1794 1795 oItem = new this.ITEM_TYPE(p_oItem, { parent: this }); 1796 1797 } 1798 else if (typeof p_oItem == "object") { 1799 1800 p_oItem.parent = this; 1801 1802 oItem = new this.ITEM_TYPE(p_oItem.text, p_oItem); 1803 1804 } 1805 1806 1807 if (oItem) { 1808 1809 if (oItem.cfg.getProperty("selected")) { 1810 1811 this.activeItem = oItem; 1812 1813 } 1814 1815 1816 nGroupIndex = typeof p_nGroupIndex == "number" ? p_nGroupIndex : 0; 1817 aGroup = this._getItemGroup(nGroupIndex); 1818 1819 1820 1821 if (!aGroup) { 1822 1823 aGroup = this._createItemGroup(nGroupIndex); 1824 1825 } 1826 1827 1828 if (typeof p_nItemIndex == "number") { 1829 1830 bAppend = (p_nItemIndex >= aGroup.length); 1831 1832 1833 if (aGroup[p_nItemIndex]) { 1834 1835 aGroup.splice(p_nItemIndex, 0, oItem); 1836 1837 } 1838 else { 1839 1840 aGroup[p_nItemIndex] = oItem; 1841 1842 } 1843 1844 1845 oGroupItem = aGroup[p_nItemIndex]; 1846 1847 if (oGroupItem) { 1848 1849 if (bAppend && (!oGroupItem.element.parentNode || 1850 oGroupItem.element.parentNode.nodeType == 11)) { 1851 1852 this._aListElements[nGroupIndex].appendChild( 1853 oGroupItem.element); 1854 1855 } 1856 else { 1857 1858 oNextItemSibling = getNextItemSibling(aGroup, 1859 (p_nItemIndex+1)); 1860 1861 if (oNextItemSibling && (!oGroupItem.element.parentNode || 1862 oGroupItem.element.parentNode.nodeType == 11)) { 1863 1864 this._aListElements[nGroupIndex].insertBefore( 1865 oGroupItem.element, 1866 oNextItemSibling.element); 1867 1868 } 1869 1870 } 1871 1872 1873 oGroupItem.parent = this; 1874 1875 this._subscribeToItemEvents(oGroupItem); 1876 1877 this._configureSubmenu(oGroupItem); 1878 1879 this._updateItemProperties(nGroupIndex); 1880 1881 1882 this.itemAddedEvent.fire(oGroupItem); 1883 this.changeContentEvent.fire(); 1884 1885 return oGroupItem; 1886 1887 } 1888 1889 } 1890 else { 1891 1892 nItemIndex = aGroup.length; 1893 1894 aGroup[nItemIndex] = oItem; 1895 1896 oGroupItem = aGroup[nItemIndex]; 1897 1898 1899 if (oGroupItem) { 1900 1901 if (!Dom.isAncestor(this._aListElements[nGroupIndex], 1902 oGroupItem.element)) { 1903 1904 this._aListElements[nGroupIndex].appendChild( 1905 oGroupItem.element); 1906 1907 } 1908 1909 oGroupItem.element.setAttribute("groupindex", nGroupIndex); 1910 oGroupItem.element.setAttribute("index", nItemIndex); 1911 1912 oGroupItem.parent = this; 1913 1914 oGroupItem.index = nItemIndex; 1915 oGroupItem.groupIndex = nGroupIndex; 1916 1917 this._subscribeToItemEvents(oGroupItem); 1918 1919 this._configureSubmenu(oGroupItem); 1920 1921 if (nItemIndex === 0) { 1922 1923 Dom.addClass(oGroupItem.element, "first-of-type"); 1924 1925 } 1926 1927 1928 1929 this.itemAddedEvent.fire(oGroupItem); 1930 this.changeContentEvent.fire(); 1931 1932 return oGroupItem; 1933 1934 } 1935 1936 } 1937 1938 } 1939 1940}, 1941 1942 1943/** 1944* @method _removeItemFromGroupByIndex 1945* @description Removes a menu item from a group by index. Returns the menu 1946* item that was removed. 1947* @private 1948* @param {Number} p_nGroupIndex Number indicating the group to which the menu 1949* item belongs. 1950* @param {Number} p_nItemIndex Number indicating the index of the menu item 1951* to be removed.
1952* @return {YAHOO.widget.MenuItem} 1953*/ 1954_removeItemFromGroupByIndex: function (p_nGroupIndex, p_nItemIndex) { 1955 1956 var nGroupIndex = typeof p_nGroupIndex == "number" ? p_nGroupIndex : 0, 1957 aGroup = this._getItemGroup(nGroupIndex), 1958 aArray, 1959 oItem, 1960 oUL; 1961 1962 if (aGroup) { 1963 1964 aArray = aGroup.splice(p_nItemIndex, 1); 1965 oItem = aArray[0]; 1966 1967 if (oItem) { 1968 1969 // Update the index and className properties of each member 1970 1971 this._updateItemProperties(nGroupIndex); 1972 1973 if (aGroup.length === 0) { 1974 1975 // Remove the UL 1976 1977 oUL = this._aListElements[nGroupIndex]; 1978 1979 if (this.body && oUL) { 1980 1981 this.body.removeChild(oUL); 1982 1983 } 1984 1985 // Remove the group from the array of items 1986 1987 this._aItemGroups.splice(nGroupIndex, 1); 1988 1989 1990 // Remove the UL from the array of ULs 1991 1992 this._aListElements.splice(nGroupIndex, 1); 1993 1994 1995 /* 1996 Assign the "first-of-type" class to the new first UL 1997 in the collection 1998 */ 1999 2000 oUL = this._aListElements[0]; 2001 2002 if (oUL) { 2003 2004 Dom.addClass(oUL, "first-of-type"); 2005 2006 } 2007 2008 } 2009 2010 2011 this.itemRemovedEvent.fire(oItem); 2012 this.changeContentEvent.fire(); 2013 2014 2015 // Return a reference to the item that was removed 2016 2017 return oItem; 2018 2019 } 2020 2021 } 2022 2023}, 2024 2025 2026/** 2027* @method _removeItemFromGroupByValue 2028* @description Removes a menu item from a group by reference. Returns the 2029* menu item that was removed. 2030* @private 2031* @param {Number} p_nGroupIndex Number indicating the group to which the 2032* menu item belongs. 2033* @param {YAHOO.widget.MenuItem} p_oItem Object reference for the MenuItem 2034* instance to be removed. 2035* @return {YAHOO.widget.MenuItem} 2036*/ 2037_removeItemFromGroupByValue: function (p_nGroupIndex, p_oItem) { 2038 2039 var aGroup = this._getItemGroup(p_nGroupIndex), 2040 nItems, 2041 nItemIndex, 2042 i; 2043 2044 if (aGroup) { 2045 2046 nItems = aGroup.length; 2047 nItemIndex = -1; 2048 2049 if (nItems > 0) { 2050 2051 i = nItems-1; 2052 2053 do { 2054 2055 if (aGroup[i] == p_oItem) { 2056 2057 nItemIndex = i; 2058 break; 2059 2060 } 2061 2062 } 2063 while(i--); 2064 2065 if (nItemIndex > -1) { 2066 2067 return (this._removeItemFromGroupByIndex(p_nGroupIndex, 2068 nItemIndex)); 2069 2070 } 2071 2072 } 2073 2074 } 2075 2076}, 2077 2078 2079/** 2080* @method _updateItemProperties 2081* @description Updates the "index," "groupindex," and "className" properties 2082* of the menu items in the specified group. 2083* @private 2084* @param {Number} p_nGroupIndex Number indicating the group of items to update. 2085*/ 2086_updateItemProperties: function (p_nGroupIndex) { 2087 2088 var aGroup = this._getItemGroup(p_nGroupIndex), 2089 nItems = aGroup.length, 2090 oItem, 2091 oLI, 2092 i; 2093 2094 2095 if (nItems > 0) { 2096 2097 i = nItems - 1; 2098 2099 // Update the index and className properties of each member 2100 2101 do { 2102 2103 oItem = aGroup[i]; 2104 2105 if (oItem) { 2106 2107 oLI = oItem.element; 2108 2109 oItem.index = i; 2110 oItem.groupIndex = p_nGroupIndex; 2111 2112 oLI.setAttribute("groupindex", p_nGroupIndex); 2113 oLI.setAttribute("index", i); 2114 2115 Dom.removeClass(oLI, "first-of-type"); 2116 2117 } 2118 2119 } 2120 while(i--); 2121 2122 2123 if (oLI) { 2124 2125 Dom.addClass(oLI, "first-of-type"); 2126 2127 } 2128 2129 } 2130 2131}, 2132 2133 2134/**
2135* @method _createItemGroup 2136* @description Creates a new menu item group (array) and its associated 2137* <code><ul></code> element. Returns an aray of menu item groups. 2138* @private 2139* @param {Number} p_nIndex Number indicating the group to create. 2140* @return {Array} 2141*/ 2142_createItemGroup: function (p_nIndex) { 2143 2144 var oUL; 2145 2146 if (!this._aItemGroups[p_nIndex]) { 2147 2148 this._aItemGroups[p_nIndex] = []; 2149 2150 oUL = document.createElement("ul"); 2151 2152 this._aListElements[p_nIndex] = oUL; 2153 2154 return this._aItemGroups[p_nIndex]; 2155 2156 } 2157 2158}, 2159 2160 2161/** 2162* @method _getItemGroup 2163* @description Returns the menu item group at the specified index. 2164* @private 2165* @param {Number} p_nIndex Number indicating the index of the menu item group 2166* to be retrieved. 2167* @return {Array} 2168*/ 2169_getItemGroup: function (p_nIndex) { 2170 2171 var nIndex = ((typeof p_nIndex == "number") ? p_nIndex : 0); 2172 2173 return this._aItemGroups[nIndex]; 2174 2175}, 2176 2177 2178/** 2179* @method _configureSubmenu 2180* @description Subscribes the menu item's submenu to its parent menu's events. 2181* @private 2182* @param {YAHOO.widget.MenuItem} p_oItem Object reference for the MenuItem 2183* instance with the submenu to be configured. 2184*/ 2185_configureSubmenu: function (p_oItem) { 2186 2187 var oSubmenu = p_oItem.cfg.getProperty("submenu"); 2188 2189 if (oSubmenu) { 2190 2191 /* 2192 Listen for configuration changes to the parent menu 2193 so they they can be applied to the submenu. 2194 */ 2195 2196 this.cfg.configChangedEvent.subscribe(this._onParentMenuConfigChange, 2197 oSubmenu, true); 2198 2199 this.renderEvent.subscribe(this._onParentMenuRender, oSubmenu, true); 2200 2201 oSubmenu.beforeShowEvent.subscribe(this._onSubmenuBeforeShow); 2202 2203 } 2204 2205}, 2206 2207 2208 2209 2210/** 2211* @method _subscribeToItemEvents 2212* @description Subscribes a menu to a menu item's event. 2213* @private 2214* @param {YAHOO.widget.MenuItem} p_oItem Object reference for the MenuItem 2215* instance whose events should be subscribed to. 2216*/ 2217_subscribeToItemEvents: function (p_oItem) { 2218 2219 p_oItem.focusEvent.subscribe(this._onMenuItemFocus); 2220 2221 p_oItem.blurEvent.subscribe(this._onMenuItemBlur); 2222 2223 p_oItem.destroyEvent.subscribe(this._onMenuItemDestroy, p_oItem, this); 2224 2225 p_oItem.cfg.configChangedEvent.subscribe(this._onMenuItemConfigChange, 2226 p_oItem, this); 2227 2228}, 2229 2230 2231/** 2232* @method _onVisibleChange 2233* @description Change event handler for the the menu's "visible" configuration 2234* property. 2235* @private 2236* @param {String} p_sType String representing the name of the event that 2237* was fired. 2238* @param {Array} p_aArgs Array of arguments sent when the event was fired. 2239*/ 2240_onVisibleChange: function (p_sType, p_aArgs) { 2241 2242 var bVisible = p_aArgs[0]; 2243 2244 if (bVisible) { 2245 2246 Dom.addClass(this.element, "visible"); 2247 2248 } 2249 else { 2250 2251 Dom.removeClass(this.element, "visible"); 2252 2253 } 2254 2255}, 2256 2257 2258/**
2259* @method _cancelHideDelay 2260* @description Cancels the call to "hideMenu." 2261* @private 2262*/ 2263_cancelHideDelay: function () { 2264 2265 var oRoot = this.getRoot(); 2266 2267 if (oRoot._nHideDelayId) { 2268 2269 window.clearTimeout(oRoot._nHideDelayId); 2270 2271 } 2272 2273}, 2274 2275 2276/** 2277* @method _execHideDelay 2278* @description Hides the menu after the number of milliseconds specified by 2279* the "hidedelay" configuration property. 2280* @private 2281*/ 2282_execHideDelay: function () { 2283 2284 this._cancelHideDelay(); 2285 2286 var oRoot = this.getRoot(), 2287 me = this; 2288 2289 function hideMenu() { 2290 2291 if (oRoot.activeItem) { 2292 2293 oRoot.clearActiveItem(); 2294 2295 } 2296 2297 if (oRoot == me && !(me instanceof YAHOO.widget.MenuBar) && 2298 me.cfg.getProperty("position") == "dynamic") { 2299 2300 me.hide(); 2301 2302 } 2303 2304 } 2305 2306 2307 oRoot._nHideDelayId = 2308 window.setTimeout(hideMenu, oRoot.cfg.getProperty("hidedelay")); 2309 2310}, 2311 2312 2313/** 2314* @method _cancelShowDelay 2315* @description Cancels the call to the "showMenu." 2316* @private 2317*/ 2318_cancelShowDelay: function () { 2319 2320 var oRoot = this.getRoot(); 2321 2322 if (oRoot._nShowDelayId) { 2323 2324 window.clearTimeout(oRoot._nShowDelayId); 2325 2326 } 2327 2328}, 2329 2330 2331/** 2332* @method _execShowDelay 2333* @description Shows the menu after the number of milliseconds specified by 2334* the "showdelay" configuration property have ellapsed. 2335* @private 2336* @param {YAHOO.widget.Menu} p_oMenu Object specifying the menu that should 2337* be made visible. 2338*/ 2339_execShowDelay: function (p_oMenu) { 2340 2341 var oRoot = this.getRoot(); 2342 2343 function showMenu() { 2344 2345 if (p_oMenu.parent.cfg.getProperty("selected")) { 2346 2347 p_oMenu.show(); 2348 2349 } 2350 2351 } 2352 2353 2354 oRoot._nShowDelayId = 2355 window.setTimeout(showMenu, oRoot.cfg.getProperty("showdelay")); 2356 2357}, 2358 2359 2360/** 2361* @method _execSubmenuHideDelay 2362* @description Hides a submenu after the number of milliseconds specified by 2363* the "submenuhidedelay" configuration property have ellapsed. 2364* @private 2365* @param {YAHOO.widget.Menu} p_oSubmenu Object specifying the submenu that 2366* should be hidden. 2367* @param {Number} p_nMouseX The x coordinate of the mouse when it left 2368* the specified submenu's parent menu item. 2369* @param {Number} p_nHideDelay The number of milliseconds that should ellapse 2370* before the submenu is hidden. 2371*/ 2372_execSubmenuHideDelay: function (p_oSubmenu, p_nMouseX, p_nHideDelay) { 2373 2374 var me = this; 2375 2376 p_oSubmenu._nSubmenuHideDelayId = window.setTimeout(function () { 2377 2378 if (me._nCurrentMouseX > (p_nMouseX + 10)) { 2379 2380 p_oSubmenu._nSubmenuHideDelayId = window.setTimeout(function () { 2381 2382 p_oSubmenu.hide(); 2383 2384 }, p_nHideDelay); 2385 2386 } 2387 else { 2388 2389 p_oSubmenu.hide(); 2390 2391 } 2392 2393 }, 50); 2394 2395}, 2396 2397 2398 2399// Protected methods 2400 2401 2402/** 2403* @method _disableScrollHeader 2404* @description Disables the header used for scrolling the body of the menu. 2405* @protected 2406*/ 2407_disableScrollHeader: function () { 2408 2409 if (!this._bHeaderDisabled) { 2410 2411 Dom.addClass(this.header, "topscrollbar_disabled"); 2412 this._bHeaderDisabled = true; 2413 2414 } 2415 2416}, 2417 2418 2419/** 2420* @method _disableScrollFooter 2421* @description Disables the footer used for scrolling the body of the menu. 2422* @protected 2423*/ 2424_disableScrollFooter: function () { 2425 2426 if (!this._bFooterDisabled) { 2427 2428 Dom.addClass(this.footer, "bottomscrollbar_disabled"); 2429 this._bFooterDisabled = true; 2430 2431 } 2432 2433}, 2434 2435 2436/** 2437* @method _enableScrollHeader 2438* @description Enables the header used for scrolling the body of the menu. 2439* @protected 2440*/ 2441_enableScrollHeader: function () { 2442 2443 if (this._bHeaderDisabled) { 2444 2445 Dom.removeClass(this.header, "topscrollbar_disabled"); 2446 this._bHeaderDisabled = false; 2447 2448 } 2449 2450}, 2451 2452 2453/** 2454* @method _enableScrollFooter 2455* @description Enables the footer used for scrolling the body of the menu. 2456* @protected 2457*/ 2458_enableScrollFooter: function () { 2459 2460 if (this._bFooterDisabled) { 2461 2462 Dom.removeClass(this.footer, "bottomscrollbar_disabled"); 2463 this._bFooterDisabled = false; 2464 2465 } 2466 2467}, 2468 2469 2470/** 2471* @method _onMouseOver 2472* @description "mouseover" event handler for the menu. 2473* @protected 2474* @param {String}
2474 p_sType String representing the name of the event that 2475* was fired. 2476* @param {Array} p_aArgs Array of arguments sent when the event was fired. 2477*/ 2478_onMouseOver: function (p_sType, p_aArgs) { 2479 2480 if (this._bStopMouseEventHandlers) { 2481 2482 return false; 2483 2484 } 2485 2486 2487 var oEvent = p_aArgs[0], 2488 oItem = p_aArgs[1], 2489 oTarget = Event.getTarget(oEvent), 2490 oParentMenu, 2491 nShowDelay, 2492 bShowDelay, 2493 oActiveItem, 2494 oItemCfg, 2495 oSubmenu; 2496 2497 2498 if (!this._bHandledMouseOverEvent && (oTarget == this.element || 2499 Dom.isAncestor(this.element, oTarget))) { 2500 2501 // Menu mouseover logic 2502 2503 this._nCurrentMouseX = 0; 2504 2505 Event.on(this.element, "mousemove", this._onMouseMove, this, true); 2506 2507 2508 if (!Dom.isAncestor(oItem.element, Event.getRelatedTarget(oEvent))) { 2509 2510 this.clearActiveItem(); 2511 2512 } 2513 2514 2515 if (this.parent && this._nSubmenuHideDelayId) { 2516 2517 window.clearTimeout(this._nSubmenuHideDelayId); 2518 2519 this.parent.cfg.setProperty("selected", true); 2520 2521 oParentMenu = this.parent.parent; 2522 2523 oParentMenu._bHandledMouseOutEvent = true; 2524 oParentMenu._bHandledMouseOverEvent = false; 2525 2526 } 2527 2528 2529 this._bHandledMouseOverEvent = true; 2530 this._bHandledMouseOutEvent = false; 2531 2532 } 2533 2534 2535 if (oItem && !oItem.handledMouseOverEvent && 2536 !oItem.cfg.getProperty("disabled") && 2537 (oTarget == oItem.element || Dom.isAncestor(oItem.element, oTarget))) { 2538 2539 // Menu Item mouseover logic 2540 2541 nShowDelay = this.cfg.getProperty("showdelay");
2542 bShowDelay = (nShowDelay > 0); 2543 2544 2545 if (bShowDelay) { 2546 2547 this._cancelShowDelay(); 2548 2549 } 2550 2551 2552 oActiveItem = this.activeItem; 2553 2554 if (oActiveItem) { 2555 2556 oActiveItem.cfg.setProperty("selected", false); 2557 2558 } 2559 2560 2561 oItemCfg = oItem.cfg; 2562 2563 // Select and focus the current menu item 2564 2565 oItemCfg.setProperty("selected", true); 2566 2567 2568 if (this.hasFocus()) { 2569 2570 oItem.focus(); 2571 2572 } 2573 2574 2575 if (this.cfg.getProperty("autosubmenudisplay")) { 2576 2577 // Show the submenu this menu item 2578 2579 oSubmenu = oItemCfg.getProperty("submenu"); 2580 2581 if (oSubmenu) { 2582 2583 if (bShowDelay) { 2584 2585 this._execShowDelay(oSubmenu); 2586 2587 } 2588 else { 2589 2590 oSubmenu.show(); 2591 2592 } 2593 2594 } 2595 2596 } 2597 2598 oItem.handledMouseOverEvent = true; 2599 oItem.handledMouseOutEvent = false; 2600 2601 } 2602 2603}, 2604 2605 2606/** 2607* @method _onMouseOut 2608* @description "mouseout" event handler for the menu. 2609* @protected 2610* @param {String} p_sType String representing the name of the event that 2611* was fired. 2612* @param {Array} p_aArgs Array of arguments sent when the event was fired. 2613*/ 2614_onMouseOut: function (p_sType, p_aArgs) { 2615 2616 if (this._bStopMouseEventHandlers) { 2617 2618 return false; 2619 2620 } 2621 2622 2623 var oEvent = p_aArgs[0], 2624 oItem = p_aArgs[1], 2625 oRelatedTarget = Event.getRelatedTarget(oEvent), 2626 bMovingToSubmenu = false, 2627 oItemCfg, 2628 oSubmenu, 2629 nSubmenuHideDelay, 2630 nShowDelay; 2631 2632 2633 if (oItem && !oItem.cfg.getProperty("disabled")) { 2634 2635 oItemCfg = oItem.cfg; 2636 oSubmenu = oItemCfg.getProperty("submenu"); 2637 2638 2639 if (oSubmenu && (oRelatedTarget == oSubmenu.element || 2640 Dom.isAncestor(oSubmenu.element, oRelatedTarget))) { 2641 2642 bMovingToSubmenu = true; 2643 2644 } 2645 2646 2647 if (!oItem.handledMouseOutEvent && ((oRelatedTarget != oItem.element && 2648 !Dom.isAncestor(oItem.element, oRelatedTarget)) || 2649 bMovingToSubmenu)) { 2650 2651 // Menu Item mouseout logic 2652 2653 if (!bMovingToSubmenu) { 2654 2655 oItem.cfg.setProperty("selected", false); 2656 2657 2658 if (oSubmenu) { 2659 2660 nSubmenuHideDelay = 2661 this.cfg.getProperty("submenuhidedelay"); 2662 2663 nShowDelay = this.cfg.getProperty("showdelay"); 2664 2665 if (!(this instanceof YAHOO.widget.MenuBar) && 2666 nSubmenuHideDelay > 0 && 2667 nShowDelay >= nSubmenuHideDelay) { 2668 2669 this._execSubmenuHideDelay(oSubmenu, 2670 Event.getPageX(oEvent), 2671 nSubmenuHideDelay); 2672 2673 } 2674 else { 2675 2676 oSubmenu.hide(); 2677 2678 } 2679 2680 } 2681 2682 } 2683 2684 2685 oItem.handledMouseOutEvent = true; 2686 oItem.handledMouseOverEvent = false; 2687 2688 } 2689 2690 } 2691 2692 2693 if (!this._bHandledMouseOutEvent && ((oRelatedTarget != this.element && 2694 !Dom.isAncestor(this.element, oRelatedTarget)) || bMovingToSubmenu)) { 2695 2696 // Menu mouseout logic 2697 2698 Event.removeListener(this.element, "mousemove", this._onMouseMove); 2699 2700 this._nCurrentMouseX = Event.getPageX(oEvent); 2701 2702 this._bHandledMouseOutEvent = true; 2703 this._bHandledMouseOverEvent = false; 2704 2705 } 2706 2707}, 2708 2709 2710/** 2711* @method _onMouseMove 2712* @description "click" event handler for the menu. 2713* @protected 2714* @param {Event} p_oEvent Object representing the DOM event object passed 2715* back by the event utility (YAHOO.util.Event). 2716* @param {YAHOO.widget.Menu} p_oMenu Object representing the menu that 2717* fired the event. 2718*/ 2719_onMouseMove: function (p_oEvent, p_oMenu) { 2720 2721 if (this._bStopMouseEventHandlers) { 2722 2723 return false; 2724 2725 } 2726 2727 this._nCurrentMouseX = Event.getPageX(p_oEvent); 2728 2729}, 2730 2731 2732/** 2733* @method _onClick 2734* @description "click" event handler for the menu. 2735* @protected 2736* @param {String}
2736 p_sType String representing the name of the event that 2737* was fired. 2738* @param {Array} p_aArgs Array of arguments sent when the event was fired. 2739*/ 2740_onClick: function (p_sType, p_aArgs) { 2741 2742 var Event = YAHOO.util.Event, 2743 Dom = YAHOO.util.Dom, 2744 oEvent = p_aArgs[0], 2745 oItem = p_aArgs[1], 2746 oSubmenu, 2747 bInMenuAnchor = false, 2748 oRoot, 2749 sId, 2750 sURL, 2751 nHashPos, 2752 nLen; 2753 2754 2755 if (oItem) { 2756 2757 if (oItem.cfg.getProperty("disabled")) { 2758 2759 Event.preventDefault(oEvent); 2760 2761 } 2762 else { 2763 2764 oSubmenu = oItem.cfg.getProperty("submenu"); 2765 2766 2767 /* 2768 Check if the URL of the anchor is pointing to an element that is 2769 a child of the menu. 2770 */ 2771 2772 sURL = oItem.cfg.getProperty("url"); 2773 2774 2775 if (sURL) { 2776 2777 nHashPos = sURL.indexOf("#"); 2778 2779 nLen = sURL.length; 2780 2781 2782 if (nHashPos != -1) { 2783 2784 sURL = sURL.substr(nHashPos, nLen); 2785 2786 nLen = sURL.length; 2787 2788 2789 if (nLen > 1) { 2790 2791 sId = sURL.substr(1, nLen); 2792 2793 bInMenuAnchor = Dom.isAncestor(this.element, sId); 2794 2795 } 2796 else if (nLen === 1) { 2797 2798 bInMenuAnchor = true; 2799 2800 } 2801 2802 } 2803 2804 } 2805 2806 2807 2808 if (bInMenuAnchor && !oItem.cfg.getProperty("target")) { 2809 2810 Event.preventDefault(oEvent); 2811 2812 2813 if (UA.webkit) { 2814 2815 oItem.focus(); 2816 2817 } 2818 else { 2819 2820 oItem.focusEvent.fire(); 2821 2822 } 2823 2824 } 2825 2826 2827 if (!oSubmenu) { 2828 2829 oRoot = this.getRoot(); 2830 2831 if (oRoot instanceof YAHOO.widget.MenuBar || 2832 oRoot.cfg.getProperty("position") == "static") { 2833 2834 oRoot.clearActiveItem(); 2835 2836 } 2837 else { 2838 2839 oRoot.hide(); 2840 2841 } 2842 2843 } 2844 2845 } 2846 2847 } 2848 2849}, 2850 2851 2852/** 2853* @method _onKeyDown 2854* @description "keydown" event handler for the menu. 2855* @protected 2856* @param {String} p_sType String representing the name of the event that 2857* was fired. 2858* @param {Array} p_aArgs Array of arguments sent when the event was fired. 2859*/ 2860_onKeyDown: function (p_sType, p_aArgs) { 2861 2862 var oEvent = p_aArgs[0], 2863 oItem = p_aArgs[1], 2864 me = this, 2865 oSubmenu, 2866 oItemCfg, 2867 oParentItem, 2868 oRoot, 2869 oNextItem, 2870 oBody, 2871 nBodyScrollTop, 2872 nBodyOffsetHeight, 2873 aItems, 2874 nItems, 2875 nNextItemOffsetTop, 2876 nScrollTarget, 2877 oParentMenu; 2878 2879 2880 /* 2881 This function is called to prevent a bug in Firefox. In Firefox, 2882 moving a DOM element into a stationary mouse pointer will cause the 2883 browser to fire mouse events. This can result in the menu mouse 2884 event handlers being called uncessarily, especially when menus are 2885 moved into a stationary mouse pointer as a result of a 2886 key event handler. 2887 */ 2888 function stopMouseEventHandlers() { 2889 2890 me._bStopMouseEventHandlers = true; 2891 2892 window.setTimeout(function () { 2893 2894 me._bStopMouseEventHandlers = false; 2895 2896 }, 10); 2897 2898 } 2899 2900 2901 if (oItem && !oItem.cfg.getProperty("disabled")) { 2902 2903 oItemCfg = oItem.cfg; 2904 oParentItem = this.parent; 2905 2906 switch(oEvent.keyCode) { 2907 2908 case 38: // Up arrow 2909 case 40: // Down arrow 2910 2911 oNextItem = (oEvent.keyCode == 38) ? 2912 oItem.getPreviousEnabledSibling() : 2913 oItem.getNextEnabledSibling(); 2914 2915 if (oNextItem) { 2916 2917 this.clearActiveItem(); 2918 2919 oNextItem.cfg.setProperty("selected", true); 2920 oNextItem.focus(); 2921 2922 2923 if (this.cfg.getProperty("maxheight") > 0) { 2924 2925 oBody = this.body; 2926 nBodyScrollTop = oBody.scrollTop; 2927 nBodyOffsetHeight = oBody.offsetHeight; 2928 aItems = this.getItems(); 2929 nItems = aItems.length - 1; 2930 nNextItemOffsetTop = oNextItem.element.offsetTop; 2931 2932 2933 if (oEvent.keyCode == 40 ) { // Down 2934 2935 if (nNextItemOffsetTop >= (nBodyOffsetHeight + nBodyScrollTop)) { 2936 2937 oBody.scrollTop = nNextItemOffsetTop - nBodyOffsetHeight; 2938 2939 } 2940 else if (nNextItemOffsetTop <= nBodyScrollTop) { 2941 2942 oBody.scrollTop = 0; 2943 2944 } 2945 2946 2947 if (oNextItem == aItems[nItems]) { 2948 2949 oBody.scrollTop = oNextItem.element.offsetTop; 2950 2951 } 2952 2953 } 2954 else { // Up 2955 2956 if (nNextItemOffsetTop <= nBodyScrollTop) { 2957 2958 oBody.scrollTop = nNextItemOffsetTop - oNextItem.element.offsetHeight; 2959 2960 } 2961 else if (nNextItemOffsetTop >= (nBodyScrollTop + nBodyOffsetHeight)) { 2962 2963 oBody.scrollTop = nNextItemOffsetTop; 2964 2965 } 2966 2967 2968 if (oNextItem == aItems[0]) { 2969 2970 oBody.scrollTop = 0; 2971 2972 } 2973 2974 } 2975 2976 2977 nBodyScrollTop = oBody.scrollTop; 2978 nScrollTarget = oBody.scrollHeight - oBody.offsetHeight; 2979 2980 if (nBodyScrollTop === 0) { 2981 2982 this._disableScrollHeader(); 2983 this._enableScrollFooter(); 2984 2985 } 2986 else if (nBodyScrollTop == nScrollTarget) { 2987 2988 this._enableScrollHeader(); 2989 this._disableScrollFooter(); 2990 2991 } 2992 else { 2993 2994 this._enableScrollHeader(); 2995 this._enableScrollFooter(); 2996 2997 } 2998 2999 } 3000 3001 } 3002 3003 3004 Event.preventDefault(oEvent); 3005 3006 stopMouseEventHandlers(); 3007 3008 break; 3009 3010 3011 case 39: // Right arrow 3012 3013 oSubmenu = oItemCfg.getProperty("submenu"); 3014 3015 if (oSubmenu) { 3016
3017 if (!oItemCfg.getProperty("selected")) { 3018 3019 oItemCfg.setProperty("selected", true); 3020 3021 } 3022 3023 oSubmenu.show(); 3024 oSubmenu.setInitialFocus(); 3025 oSubmenu.setInitialSelection(); 3026 3027 } 3028 else { 3029 3030 oRoot = this.getRoot(); 3031 3032 if (oRoot instanceof YAHOO.widget.MenuBar) { 3033 3034 oNextItem = oRoot.activeItem.getNextEnabledSibling(); 3035 3036 if (oNextItem) { 3037 3038 oRoot.clearActiveItem(); 3039 3040 oNextItem.cfg.setProperty("selected", true); 3041 3042 oSubmenu = oNextItem.cfg.getProperty("submenu"); 3043 3044 if (oSubmenu) { 3045 3046 oSubmenu.show(); 3047 3048 } 3049 3050 oNextItem.focus(); 3051 3052 } 3053 3054 } 3055 3056 } 3057 3058 3059 Event.preventDefault(oEvent); 3060 3061 stopMouseEventHandlers(); 3062 3063 break; 3064 3065 3066 case 37: // Left arrow 3067 3068 if (oParentItem) { 3069 3070 oParentMenu = oParentItem.parent; 3071 3072 if (oParentMenu instanceof YAHOO.widget.MenuBar) { 3073 3074 oNextItem = 3075 oParentMenu.activeItem.getPreviousEnabledSibling(); 3076 3077 if (oNextItem) { 3078 3079 oParentMenu.clearActiveItem(); 3080 3081 oNextItem.cfg.setProperty("selected", true); 3082 3083 oSubmenu = oNextItem.cfg.getProperty("submenu"); 3084 3085 if (oSubmenu) { 3086 3087 oSubmenu.show(); 3088 3089 } 3090 3091 oNextItem.focus(); 3092 3093 } 3094 3095 } 3096 else { 3097 3098 this.hide(); 3099 3100 oParentItem.focus(); 3101 3102 } 3103 3104 } 3105 3106 Event.preventDefault(oEvent); 3107 3108 stopMouseEventHandlers(); 3109 3110 break; 3111 3112 } 3113 3114 3115 } 3116 3117 3118 if (oEvent.keyCode == 27) { // Esc key 3119 3120 if (this.cfg.getProperty("position") == "dynamic") { 3121 3122 this.hide(); 3123 3124 if (this.parent) { 3125 3126 this.parent.focus(); 3127 3128 } 3129 3130 } 3131 else if (this.activeItem) { 3132 3133 oSubmenu = this.activeItem.cfg.getProperty("submenu"); 3134 3135 if (oSubmenu && oSubmenu.cfg.getProperty("visible")) { 3136 3137 oSubmenu.hide(); 3138 this.activeItem.focus(); 3139 3140 } 3141 else { 3142 3143 this.activeItem.blur(); 3144 this.activeItem.cfg.setProperty("selected", false); 3145 3146 } 3147 3148 } 3149 3150 3151 Event.preventDefault(oEvent); 3152 3153 } 3154 3155}, 3156 3157 3158/** 3159* @method _onKeyPress 3160* @description "keypress" event handler for a Menu instance. 3161* @protected 3162* @param {String} p_sType The name of the event that was fired. 3163* @param {Array} p_aArgs Collection of arguments sent when the event 3164* was fired. 3165*/ 3166_onKeyPress: function (p_sType, p_aArgs) { 3167 3168 var oEvent = p_aArgs[0]; 3169 3170 3171 if (oEvent.keyCode == 40 || oEvent.keyCode == 38) { 3172 3173 Event.preventDefault(oEvent); 3174 3175 } 3176 3177}, 3178 3179 3180/** 3181* @method _onYChange 3182* @description "y" event handler for a Menu instance. 3183* @protected 3184* @param {String} p_sType The name of the event that was fired. 3185* @param {Array} p_aArgs Collection of arguments sent when the event 3186* was fired. 3187*/ 3188_onYChange: function (p_sType, p_aArgs) { 3189 3190 var oParent = this.parent, 3191 nScrollTop, 3192 oIFrame, 3193 nY; 3194 3195 3196 if (oParent) { 3197 3198 nScrollTop = oParent.parent.body.scrollTop; 3199 3200 3201 if (nScrollTop > 0) { 3202 3203 nY = (this.cfg.getProperty("y") - nScrollTop); 3204 3205 Dom.setY(this.element, nY); 3206 3207 oIFrame = this.iframe; 3208 3209 3210 if (oIFrame) { 3211 3212 Dom.setY(oIFrame, nY); 3213 3214 } 3215 3216 this.cfg.setProperty("y", nY, true); 3217 3218 } 3219 3220 } 3221 3222}, 3223 3224 3225/** 3226* @method _onScrollTargetMouseOver 3227* @description "mouseover" event handler for the menu's "header" and "footer" 3228* elements. Used to scroll the body of the menu up and down when the 3229* menu's "maxheight" configuration property is set to a value greater than 0. 3230* @protected 3231* @param {Event} p_oEvent Object representing the DOM event object passed 3232* back by the event utility (YAHOO.util.Event).
3233* @param {YAHOO.widget.Menu} p_oMenu Object representing the menu that 3234* fired the event. 3235*/ 3236_onScrollTargetMouseOver: function (p_oEvent, p_oMenu) { 3237 3238 this._cancelHideDelay(); 3239 3240 var oTarget = Event.getTarget(p_oEvent), 3241 oBody = this.body, 3242 me = this, 3243 nScrollIncrement = this.cfg.getProperty("scrollincrement"), 3244 nScrollTarget, 3245 fnScrollFunction; 3246 3247 3248 function scrollBodyDown() { 3249 3250 var nScrollTop = oBody.scrollTop; 3251 3252 3253 if (nScrollTop < nScrollTarget) { 3254 3255 oBody.scrollTop = (nScrollTop + nScrollIncrement); 3256 3257 me._enableScrollHeader(); 3258 3259 } 3260 else { 3261 3262 oBody.scrollTop = nScrollTarget; 3263 3264 window.clearInterval(me._nBodyScrollId); 3265 3266 me._disableScrollFooter(); 3267 3268 } 3269 3270 } 3271 3272 3273 function scrollBodyUp() { 3274 3275 var nScrollTop = oBody.scrollTop; 3276 3277 3278 if (nScrollTop > 0) { 3279 3280 oBody.scrollTop = (nScrollTop - nScrollIncrement); 3281 3282 me._enableScrollFooter(); 3283 3284 } 3285 else { 3286 3287 oBody.scrollTop = 0; 3288 3289 window.clearInterval(me._nBodyScrollId); 3290 3291 me._disableScrollHeader(); 3292 3293 } 3294 3295 } 3296 3297 3298 if (Dom.hasClass(oTarget, "hd")) { 3299 3300 fnScrollFunction = scrollBodyUp; 3301 3302 } 3303 else { 3304 3305 nScrollTarget = oBody.scrollHeight - oBody.offsetHeight; 3306 3307 fnScrollFunction = scrollBodyDown; 3308 3309 } 3310 3311 3312 this._nBodyScrollId = window.setInterval(fnScrollFunction, 10); 3313 3314}, 3315 3316 3317/** 3318* @method _onScrollTargetMouseOut 3319* @description "mouseout" event handler for the menu's "header" and "footer" 3320* elements. Used to stop scrolling the body of the menu up and down when the 3321* menu's "maxheight" configuration property is set to a value greater than 0. 3322* @protected 3323* @param {Event} p_oEvent Object representing the DOM event object passed 3324* back by the event utility (YAHOO.util.Event). 3325* @param {YAHOO.widget.Menu} p_oMenu Object representing the menu that 3326* fired the event. 3327*/ 3328_onScrollTargetMouseOut: function (p_oEvent, p_oMenu) { 3329 3330 window.clearInterval(this._nBodyScrollId); 3331 3332 this._cancelHideDelay(); 3333 3334}, 3335 3336 3337 3338// Private methods 3339 3340 3341/** 3342* @method _onInit 3343* @description "init" event handler for the menu. 3344* @private 3345* @param {String} p_sType String representing the name of the event that 3346* was fired. 3347* @param {Array} p_aArgs Array of arguments sent when the event was fired. 3348*/ 3349_onInit: function (p_sType, p_aArgs) { 3350 3351 this.cfg.subscribeToConfigEvent("visible", this._onVisibleChange); 3352 3353 var bRootMenu = !this.parent, 3354 bLazyLoad = this.lazyLoad; 3355 3356 3357 /* 3358 Automatically initialize a menu's subtree if: 3359 3360 1) This is the root menu and lazyload is off 3361 3362 2) This is the root menu, lazyload is on, but the menu is 3363 already visible 3364 3365 3) This menu is a submenu and lazyload is off 3366 */ 3367 3368 3369 3370 if (((bRootMenu && !bLazyLoad) || 3371 (bRootMenu && (this.cfg.getProperty("visible") || 3372 this.cfg.getProperty("position") == "static")) || 3373 (!bRootMenu && !bLazyLoad)) && this.getItemGroups().length === 0) { 3374 3375 if (this.srcElement) { 3376 3377 this._initSubTree(); 3378 3379 } 3380 3381 3382 if (this.itemData) { 3383 3384 this.addItems(this.itemData); 3385 3386 } 3387 3388 } 3389 else if (bLazyLoad) { 3390 3391 this.cfg.fireQueue(); 3392 3393 } 3394 3395}, 3396 3397 3398/** 3399* @method _onBeforeRender 3400* @description "beforerender" event handler for the menu. Appends all of the 3401* <code><ul></code>, <code><li></code> and their accompanying 3402* title elements to the body element of the menu. 3403* @private 3404* @param {String} p_sType String representing the name of the event that 3405* was fired. 3406* @param {Array} p_aArgs Array of arguments sent when the event was fired. 3407*/ 3408_onBeforeRender: function (p_sType, p_aArgs) { 3409 3410 var oEl = this.element, 3411 nListElements = this._aListElements.length, 3412 bFirstList = true, 3413 i = 0, 3414 oUL, 3415 oGroupTitle; 3416 3417 if (nListElements > 0) { 3418 3419 do { 3420 3421 oUL = this._aListElements[i]; 3422 3423 if (oUL) { 3424 3425 if (bFirstList) { 3426 3427 Dom.addClass(oUL, "first-of-type"); 3428 bFirstList = false;
3429 3430 } 3431 3432 3433 if (!Dom.isAncestor(oEl, oUL)) { 3434 3435 this.appendToBody(oUL); 3436 3437 } 3438 3439 3440 oGroupTitle = this._aGroupTitleElements[i]; 3441 3442 if (oGroupTitle) { 3443 3444 if (!Dom.isAncestor(oEl, oGroupTitle)) { 3445 3446 oUL.parentNode.insertBefore(oGroupTitle, oUL); 3447 3448 } 3449 3450 3451 Dom.addClass(oUL, "hastitle"); 3452 3453 } 3454 3455 } 3456 3457 i++; 3458 3459 } 3460 while(i < nListElements); 3461 3462 } 3463 3464}, 3465 3466 3467/** 3468* @method _onRender 3469* @description "render" event handler for the menu. 3470* @private 3471* @param {String} p_sType String representing the name of the event that 3472* was fired. 3473* @param {Array} p_aArgs Array of arguments sent when the event was fired. 3474*/ 3475_onRender: function (p_sType, p_aArgs) { 3476 3477 if (this.cfg.getProperty("position") == "dynamic") { 3478 3479 if (!this.cfg.getProperty("visible")) { 3480 3481 this.positionOffScreen(); 3482 3483 } 3484 3485 } 3486 3487}, 3488 3489 3490 3491 3492 3493/** 3494* @method _onBeforeShow 3495* @description "beforeshow" event handler for the menu. 3496* @private 3497* @param {String} p_sType String representing the name of the event that 3498* was fired. 3499* @param {Array} p_aArgs Array of arguments sent when the event was fired. 3500*/ 3501_onBeforeShow: function (p_sType, p_aArgs) { 3502 3503 var nOptions, 3504 n, 3505 nViewportHeight, 3506 oRegion, 3507 oSrcElement; 3508 3509 3510 if (this.lazyLoad && this.getItemGroups().length === 0) { 3511 3512 if (this.srcElement) { 3513 3514 this._initSubTree(); 3515 3516 } 3517 3518 3519 if (this.itemData) { 3520 3521 if (this.parent && this.parent.parent && 3522 this.parent.parent.srcElement && 3523 this.parent.parent.srcElement.tagName.toUpperCase() == 3524 "SELECT") { 3525 3526 nOptions = this.itemData.length; 3527 3528 for(n=0; n<nOptions; n++) { 3529 3530 if (this.itemData[n].tagName) { 3531 3532 this.addItem((new this.ITEM_TYPE(this.itemData[n]))); 3533 3534 } 3535 3536 } 3537 3538 } 3539 else { 3540 3541 this.addItems(this.itemData); 3542 3543 } 3544 3545 } 3546 3547 3548 oSrcElement = this.srcElement; 3549 3550 if (oSrcElement) { 3551 3552 if (oSrcElement.tagName.toUpperCase() == "SELECT") { 3553 3554 if (Dom.inDocument(oSrcElement)) { 3555 3556 this.render(oSrcElement.parentNode); 3557 3558 } 3559 else { 3560 3561 this.render(this.cfg.getProperty("container")); 3562 3563 } 3564 3565 } 3566 else { 3567 3568 this.render(); 3569 3570 } 3571 3572 } 3573 else { 3574 3575 if (this.parent) { 3576 3577 this.render(this.parent.element); 3578 3579 } 3580 else { 3581 3582 this.render(this.cfg.getProperty("container")); 3583 3584 } 3585 3586 } 3587 3588 } 3589 3590 3591 var nMaxHeight = this.cfg.getProperty("maxheight"), 3592 nMinScrollHeight = this.cfg.getProperty("minscrollheight"), 3593 bDynamicPos = this.cfg.getProperty("position") == "dynamic"; 3594 3595 3596 if (!this.parent && bDynamicPos) { 3597 3598 this.cfg.refireEvent("xy"); 3599 3600 } 3601 3602 3603 function clearMaxHeight() { 3604 3605 this.cfg.setProperty("maxheight", 0); 3606 3607 this.hideEvent.unsubscribe(clearMaxHeight); 3608 3609 } 3610 3611 3612 if (!(this instanceof YAHOO.widget.MenuBar) && bDynamicPos) { 3613 3614 3615 if (nMaxHeight === 0) { 3616 3617 nViewportHeight = Dom.getViewportHeight(); 3618 3619 3620 if (this.parent && 3621 this.parent.parent instanceof YAHOO.widget.MenuBar) { 3622 3623 oRegion = YAHOO.util.Region.getRegion(this.parent.element); 3624 3625 nViewportHeight = (nViewportHeight - oRegion.bottom); 3626 3627 } 3628 3629 3630 if (this.element.offsetHeight >= nViewportHeight) { 3631 3632 nMaxHeight = (nViewportHeight - (Overlay.VIEWPORT_OFFSET * 2)); 3633 3634 if (nMaxHeight < nMinScrollHeight) { 3635 3636 nMaxHeight = nMinScrollHeight; 3637 3638 } 3639 3640 this.cfg.setProperty("maxheight", nMaxHeight); 3641 3642 this.hideEvent.subscribe(clearMaxHeight); 3643 3644 } 3645 3646 } 3647 3648 } 3649 3650}, 3651 3652 3653/** 3654* @method _onShow 3655* @description "show" event handler for the menu. 3656* @private 3657* @param {String}
3657 p_sType String representing the name of the event that 3658* was fired. 3659* @param {Array} p_aArgs Array of arguments sent when the event was fired. 3660*/ 3661_onShow: function (p_sType, p_aArgs) { 3662 3663 var oParent = this.parent, 3664 oParentMenu, 3665 aParentAlignment, 3666 aAlignment; 3667 3668 3669 function disableAutoSubmenuDisplay(p_oEvent) { 3670 3671 var oTarget; 3672 3673 if (p_oEvent.type == "mousedown" || (p_oEvent.type == "keydown" && 3674 p_oEvent.keyCode == 27)) { 3675 3676 /* 3677 Set the "autosubmenudisplay" to "false" if the user 3678 clicks outside the menu bar. 3679 */ 3680 3681 oTarget = Event.getTarget(p_oEvent); 3682 3683 if (oTarget != oParentMenu.element || 3684 !Dom.isAncestor(oParentMenu.element, oTarget)) { 3685 3686 oParentMenu.cfg.setProperty("autosubmenudisplay", false); 3687 3688 Event.removeListener(document, "mousedown", 3689 disableAutoSubmenuDisplay); 3690 3691 Event.removeListener(document, "keydown", 3692 disableAutoSubmenuDisplay); 3693 3694 } 3695 3696 } 3697 3698 } 3699 3700 3701 if (oParent) { 3702 3703 oParentMenu = oParent.parent; 3704 aParentAlignment = oParentMenu.cfg.getProperty("submenualignment"); 3705 aAlignment = this.cfg.getProperty("submenualignment"); 3706 3707 3708 if ((aParentAlignment[0] != aAlignment[0]) && 3709 (aParentAlignment[1] != aAlignment[1])) { 3710 3711 this.cfg.setProperty("submenualignment", 3712 [aParentAlignment[0], aParentAlignment[1]]); 3713 3714 } 3715 3716 3717 if (!oParentMenu.cfg.getProperty("autosubmenudisplay") && 3718 (oParentMenu instanceof YAHOO.widget.MenuBar || 3719 oParentMenu.cfg.getProperty("position") == "static")) { 3720 3721 oParentMenu.cfg.setProperty("autosubmenudisplay", true); 3722 3723 Event.on(document, "mousedown", disableAutoSubmenuDisplay); 3724 Event.on(document, "keydown", disableAutoSubmenuDisplay); 3725 3726 } 3727 3728 } 3729 3730}, 3731 3732 3733/** 3734* @method _onBeforeHide 3735* @description "beforehide" event handler for the menu. 3736* @private 3737* @param {String} p_sType String representing the name of the event that 3738* was fired. 3739* @param {Array} p_aArgs Array of arguments sent when the event was fired. 3740*/ 3741_onBeforeHide: function (p_sType, p_aArgs) { 3742 3743 var oActiveItem = this.activeItem, 3744 oConfig, 3745 oSubmenu; 3746 3747 if (oActiveItem) { 3748 3749 oConfig = oActiveItem.cfg; 3750 3751 oConfig.setProperty("selected", false); 3752 3753 oSubmenu = oConfig.getProperty("submenu"); 3754 3755 if (oSubmenu) { 3756 3757 oSubmenu.hide(); 3758 3759 } 3760 3761 } 3762 3763 if (this.getRoot() == this) { 3764 3765 this.blur(); 3766 3767 } 3768 3769}, 3770 3771 3772/** 3773* @method _onParentMenuConfigChange 3774* @description "configchange" event handler for a submenu. 3775* @private 3776* @param {String} p_sType String representing the name of the event that 3777* was fired. 3778* @param {Array} p_aArgs Array of arguments sent when the event was fired. 3779* @param {YAHOO.widget.Menu} p_oSubmenu Object representing the submenu that 3780* subscribed to the event. 3781*/ 3782_onParentMenuConfigChange: function (p_sType, p_aArgs, p_oSubmenu) { 3783 3784 var sPropertyName = p_aArgs[0][0], 3785 oPropertyValue = p_aArgs[0][1]; 3786 3787 switch(sPropertyName) { 3788 3789 case "iframe": 3790 case "constraintoviewport": 3791 case "hidedelay": 3792 case "showdelay": 3793 case "submenuhidedelay": 3794 case "clicktohide": 3795 case "effect": 3796 case "classname": 3797 case "scrollincrement": 3798 case "minscrollheight": 3799 3800 p_oSubmenu.cfg.setProperty(sPropertyName, oPropertyValue); 3801 3802 break; 3803 3804 } 3805 3806}, 3807 3808 3809/** 3810* @method _onParentMenuRender 3811* @description "render" event handler for a submenu. Renders a 3812* submenu in response to the firing of its parent's "render" event. 3813* @private 3814* @param {String} p_sType String representing the name of the event that 3815* was fired. 3816* @param {Array} p_aArgs Array of arguments sent when the event was fired. 3817* @param {YAHOO.widget.Menu} p_oSubmenu Object representing the submenu that 3818* subscribed to the event. 3819*/ 3820_onParentMenuRender: function (p_sType, p_aArgs, p_oSubmenu) { 3821 3822 var oParentCfg = p_oSubmenu.parent.parent.cfg, 3823 3824 oConfig = { 3825 3826 constraintoviewport: oParentCfg.getProperty("constraintoviewport"), 3827 3828 xy: [0,0], 3829 3830 clicktohide: oParentCfg.getProperty("clicktohide"), 3831 3832 effect: oParentCfg.getProperty("effect"), 3833 3834 showdelay: oParentCfg.getProperty("showdelay"), 3835 3836 hidedelay: oParentCfg.getProperty("hidedelay"), 3837 3838 submenuhidedelay: oParentCfg.getProperty("submenuhidedelay"), 3839 3840 classname: oParentCfg.getProperty("classname"), 3841 3842 scrollincrement: oParentCfg.getProperty("scrollincrement"), 3843 3844 minscrollheight: oParentCfg.getProperty("minscrollheight"), 3845 3846 iframe: oParentCfg.getProperty("iframe") 3847 3848 }, 3849 3850 oLI; 3851 3852 3853 p_oSubmenu.cfg.applyConfig(oConfig); 3854 3855 3856 if (!this.lazyLoad) { 3857 3858 oLI = this.parent.element; 3859 3860 if (this.element.parentNode == oLI) { 3861 3862 this.render(); 3863 3864 } 3865 else { 3866 3867 this.render(oLI); 3868 3869 } 3870 3871 } 3872 3873}, 3874 3875 3876/** 3877* @method _onSubmenuBeforeShow 3878* @description "beforeshow" event handler for a submenu. 3879* @private 3880* @param {String}
3880 p_sType String representing the name of the event that 3881* was fired. 3882* @param {Array} p_aArgs Array of arguments sent when the event was fired. 3883*/ 3884_onSubmenuBeforeShow: function (p_sType, p_aArgs) { 3885 3886 var oParent = this.parent, 3887 aAlignment = oParent.parent.cfg.getProperty("submenualignment"); 3888 3889 3890 if (!this.cfg.getProperty("context")) { 3891 3892 this.cfg.setProperty("context", 3893 [oParent.element, aAlignment[0], aAlignment[1]]); 3894 3895 } 3896 else { 3897 3898 this.align(); 3899 3900 } 3901 3902}, 3903 3904 3905/** 3906* @method _onMenuItemFocus 3907* @description "focus" event handler for the menu's items. 3908* @private 3909* @param {String} p_sType String representing the name of the event that 3910* was fired. 3911* @param {Array} p_aArgs Array of arguments sent when the event was fired. 3912*/ 3913_onMenuItemFocus: function (p_sType, p_aArgs) { 3914 3915 this.parent.focusEvent.fire(this); 3916 3917}, 3918 3919 3920/** 3921* @method _onMenuItemBlur 3922* @description "blur" event handler for the menu's items. 3923* @private 3924* @param {String} p_sType String representing the name of the event 3925* that was fired. 3926* @param {Array} p_aArgs Array of arguments sent when the event was fired. 3927*/ 3928_onMenuItemBlur: function (p_sType, p_aArgs) { 3929 3930 this.parent.blurEvent.fire(this); 3931 3932}, 3933 3934 3935/** 3936* @method _onMenuItemDestroy 3937* @description "destroy" event handler for the menu's items. 3938* @private 3939* @param {String} p_sType String representing the name of the event 3940* that was fired. 3941* @param {Array} p_aArgs Array of arguments sent when the event was fired. 3942* @param {YAHOO.widget.MenuItem} p_oItem Object representing the menu item 3943* that fired the event. 3944*/ 3945_onMenuItemDestroy: function (p_sType, p_aArgs, p_oItem) { 3946 3947 this._removeItemFromGroupByValue(p_oItem.groupIndex, p_oItem); 3948 3949}, 3950 3951 3952/** 3953* @method _onMenuItemConfigChange 3954* @description "configchange" event handler for the menu's items. 3955* @private 3956* @param {String} p_sType String representing the name of the event that 3957* was fired. 3958* @param {Array} p_aArgs Array of arguments sent when the event was fired. 3959* @param {YAHOO.widget.MenuItem} p_oItem Object representing the menu item 3960* that fired the event. 3961*/ 3962_onMenuItemConfigChange: function (p_sType, p_aArgs, p_oItem) { 3963 3964 var sPropertyName = p_aArgs[0][0], 3965 oPropertyValue = p_aArgs[0][1], 3966 oSubmenu; 3967 3968 3969 switch(sPropertyName) { 3970 3971 case "selected": 3972 3973 if (oPropertyValue === true) { 3974 3975 this.activeItem = p_oItem; 3976 3977 } 3978 3979 break; 3980 3981 case "submenu": 3982 3983 oSubmenu = p_aArgs[0][1]; 3984 3985 if (oSubmenu) { 3986 3987 this._configureSubmenu(p_oItem); 3988 3989 } 3990 3991 break; 3992 3993 } 3994 3995}, 3996 3997 3998 3999// Public event handlers for configuration properties 4000 4001 4002/** 4003* @method enforceConstraints 4004* @description The default event handler executed when the moveEvent is fired, 4005* if the "constraintoviewport" configuration property is set to true. 4006* @param {String} type The name of the event that was fired. 4007* @param {Array} args Collection of arguments sent when the 4008* event was fired. 4009* @param {Array} obj Array containing the current Menu instance 4010* and the item that fired the event. 4011*/ 4012enforceConstraints: function (type, args, obj) { 4013 4014 YAHOO.widget.Menu.superclass.enforceConstraints.apply(this, arguments); 4015 4016 var oParent = this.parent, 4017 oParentMenu, 4018 nParentMenuX, 4019 nNewX, 4020 nX; 4021 4022 4023 if (oParent) { 4024 4025 oParentMenu = oParent.parent; 4026 4027 if (!(oParentMenu instanceof YAHOO.widget.MenuBar)) { 4028 4029 nParentMenuX = oParentMenu.cfg.getProperty("x"); 4030 nX = this.cfg.getProperty("x"); 4031 4032 4033 if (nX < (nParentMenuX + oParent.element.offsetWidth)) { 4034 4035 nNewX = (nParentMenuX - this.element.offsetWidth); 4036 4037 this.cfg.setProperty("x", nNewX, true); 4038 this.cfg.setProperty("xy", [nNewX, (this.cfg.getProperty("y"))], true); 4039 4040 } 4041 4042 } 4043 4044 } 4045 4046}, 4047 4048 4049/** 4050* @method configVisible 4051* @description Event handler for when the "visible" configuration property 4052* the menu changes. 4053* @param {String} p_sType String representing the name of the event that 4054* was fired. 4055* @param {Array} p_aArgs Array of arguments sent when the event was fired.
4056* @param {YAHOO.widget.Menu} p_oMenu Object representing the menu that 4057* fired the event. 4058*/ 4059configVisible: function (p_sType, p_aArgs, p_oMenu) { 4060 4061 var bVisible, 4062 sDisplay; 4063 4064 if (this.cfg.getProperty("position") == "dynamic") { 4065 4066 Menu.superclass.configVisible.call(this, p_sType, p_aArgs, p_oMenu); 4067 4068 } 4069 else { 4070 4071 bVisible = p_aArgs[0]; 4072 sDisplay = Dom.getStyle(this.element, "display"); 4073 4074 Dom.setStyle(this.element, "visibility", "visible"); 4075 4076 if (bVisible) { 4077 4078 if (sDisplay != "block") { 4079 this.beforeShowEvent.fire(); 4080 Dom.setStyle(this.element, "display", "block"); 4081 this.showEvent.fire(); 4082 } 4083 4084 } 4085 else { 4086 4087 if (sDisplay == "block") { 4088 this.beforeHideEvent.fire(); 4089 Dom.setStyle(this.element, "display", "none"); 4090 this.hideEvent.fire(); 4091 } 4092 4093 } 4094 4095 } 4096 4097}, 4098 4099 4100/** 4101* @method configPosition 4102* @description Event handler for when the "position" configuration property 4103* of the menu changes. 4104* @param {String} p_sType String representing the name of the event that 4105* was fired. 4106* @param {Array} p_aArgs Array of arguments sent when the event was fired. 4107* @param {YAHOO.widget.Menu} p_oMenu Object representing the menu that 4108* fired the event. 4109*/ 4110configPosition: function (p_sType, p_aArgs, p_oMenu) { 4111 4112 var oElement = this.element, 4113 sCSSPosition = p_aArgs[0] == "static" ? "static" : "absolute", 4114 oCfg = this.cfg, 4115 nZIndex; 4116 4117 4118 Dom.setStyle(oElement, "position", sCSSPosition); 4119 4120 4121 if (sCSSPosition == "static") { 4122 4123 // Statically positioned menus are visible by default 4124 4125 Dom.setStyle(oElement, "display", "block"); 4126 4127 oCfg.setProperty("visible", true); 4128 4129 } 4130 else { 4131 4132 /* 4133 Even though the "visible" property is queued to 4134 "false" by default, we need to set the "visibility" property to 4135 "hidden" since Overlay's "configVisible" implementation checks the 4136 element's "visibility" style property before deciding whether 4137 or not to show an Overlay instance. 4138 */ 4139 4140 Dom.setStyle(oElement, "visibility", "hidden"); 4141 4142 } 4143 4144 4145 if (sCSSPosition == "absolute") { 4146 4147 nZIndex = oCfg.getProperty("zindex"); 4148 4149 if (!nZIndex || nZIndex === 0) { 4150 4151 nZIndex = this.parent ? 4152 (this.parent.parent.cfg.getProperty("zindex") + 1) : 1; 4153 4154 oCfg.setProperty("zindex", nZIndex); 4155 4156 } 4157 4158 } 4159 4160}, 4161 4162 4163/** 4164* @method configIframe 4165* @description Event handler for when the "iframe" configuration property of 4166* the menu changes. 4167* @param {String} p_sType String representing the name of the event that 4168* was fired. 4169* @param {Array} p_aArgs Array of arguments sent when the event was fired. 4170* @param {YAHOO.widget.Menu} p_oMenu Object representing the menu that 4171* fired the event. 4172*/ 4173configIframe: function (p_sType, p_aArgs, p_oMenu) { 4174 4175 if (this.cfg.getProperty("position") == "dynamic") { 4176 4177 Menu.superclass.configIframe.call(this, p_sType, p_aArgs, p_oMenu); 4178 4179 } 4180 4181}, 4182 4183 4184/** 4185* @method configHideDelay 4186* @description Event handler for when the "hidedelay" configuration property 4187* of the menu changes. 4188* @param {String} p_sType String representing the name of the event that 4189* was fired. 4190* @param {Array} p_aArgs Array of arguments sent when the event was fired. 4191* @param {YAHOO.widget.Menu} p_oMenu Object representing the menu that 4192* fired the event. 4193*/ 4194configHideDelay: function (p_sType, p_aArgs, p_oMenu) { 4195 4196 var nHideDelay = p_aArgs[0], 4197 oMouseOutEvent = this.mouseOutEvent, 4198 oMouseOverEvent = this.mouseOverEvent, 4199 oKeyDownEvent = this.keyDownEvent; 4200 4201 if (nHideDelay > 0) { 4202 4203 /* 4204 Only assign event handlers once. This way the user change 4205 the value for the hidedelay as many times as they want. 4206 */ 4207 4208 if (!this._bHideDelayEventHandlersAssigned) { 4209 4210 oMouseOutEvent.subscribe(this._execHideDelay); 4211 oMouseOverEvent.subscribe(this._cancelHideDelay); 4212 oKeyDownEvent.subscribe(this._cancelHideDelay); 4213 4214 this._bHideDelayEventHandlersAssigned = true; 4215 4216 } 4217 4218 } 4219 else { 4220 4221 oMouseOutEvent.unsubscribe(this._execHideDelay); 4222 oMouseOverEvent.unsubscribe(this._cancelHideDelay); 4223 oKeyDownEvent.unsubscribe(this._cancelHideDelay); 4224 4225 this._bHideDelayEventHandlersAssigned = false;
4226 4227 } 4228 4229}, 4230 4231 4232/** 4233* @method configContainer 4234* @description Event handler for when the "container" configuration property 4235* of the menu changes. 4236* @param {String} p_sType String representing the name of the event that 4237* was fired. 4238* @param {Array} p_aArgs Array of arguments sent when the event was fired. 4239* @param {YAHOO.widget.Menu} p_oMenu Object representing the menu that 4240* fired the event. 4241*/ 4242configContainer: function (p_sType, p_aArgs, p_oMenu) { 4243 4244 var oElement = p_aArgs[0]; 4245 4246 if (typeof oElement == 'string') { 4247 4248 this.cfg.setProperty("container", document.getElementById(oElement), 4249 true); 4250 4251 } 4252 4253}, 4254 4255 4256/** 4257* @method _setMaxHeight 4258* @description "renderEvent" handler used to defer the setting of the 4259* "maxheight" configuration property until the menu is rendered in lazy 4260* load scenarios. 4261* @param {String} p_sType The name of the event that was fired. 4262* @param {Array} p_aArgs Collection of arguments sent when the event 4263* was fired. 4264* @param {Number} p_nMaxHeight Number representing the value to set for the 4265* "maxheight" configuration property. 4266* @private 4267*/ 4268_setMaxHeight: function (p_sType, p_aArgs, p_nMaxHeight) { 4269 4270 this.cfg.setProperty("maxheight", p_nMaxHeight); 4271 this.renderEvent.unsubscribe(this._setMaxHeight); 4272 4273}, 4274 4275 4276/** 4277* @method configMaxHeight 4278* @description Event handler for when the "maxheight" configuration property of 4279* a Menu changes. 4280* @param {String} p_sType The name of the event that was fired. 4281* @param {Array} p_aArgs Collection of arguments sent when the event 4282* was fired. 4283* @param {YAHOO.widget.Menu} p_oMenu The Menu instance fired 4284* the event. 4285*/ 4286configMaxHeight: function (p_sType, p_aArgs, p_oMenu) { 4287 4288 var nMaxHeight = p_aArgs[0], 4289 oElement = this.element, 4290 oBody = this.body, 4291 oHeader = this.header, 4292 oFooter = this.footer, 4293 fnMouseOver = this._onScrollTargetMouseOver, 4294 fnMouseOut = this._onScrollTargetMouseOut, 4295 nMinScrollHeight = this.cfg.getProperty("minscrollheight"), 4296 nHeight, 4297 nOffsetWidth, 4298 sWidth; 4299 4300 4301 if (nMaxHeight !== 0 && nMaxHeight < nMinScrollHeight) { 4302 4303 nMaxHeight = nMinScrollHeight; 4304 4305 } 4306 4307 4308 if (this.lazyLoad && !oBody) { 4309 4310 this.renderEvent.unsubscribe(this._setMaxHeight); 4311 4312 if (nMaxHeight > 0) { 4313 4314 this.renderEvent.subscribe(this._setMaxHeight, nMaxHeight, this); 4315 4316 } 4317 4318 return; 4319 4320 } 4321 4322 4323 Dom.setStyle(oBody, "height", ""); 4324 Dom.removeClass(oBody, "yui-menu-body-scrolled"); 4325 4326 4327 /* 4328 There is a bug in gecko-based browsers where an element whose 4329 "position" property is set to "absolute" and "overflow" property is set 4330 to "hidden" will not render at the correct width when its 4331 offsetParent's "position" property is also set to "absolute." It is 4332 possible to work around this bug by specifying a value for the width 4333 property in addition to overflow. 4334 4335 In IE it is also necessary to give the Menu a width when the scrollbars are 4336 rendered to prevent the Menu from rendering with a width that is 100% of 4337 the browser viewport. 4338 */ 4339 4340 var bSetWidth = ((UA.gecko && this.parent && this.parent.parent && 4341 this.parent.parent.cfg.getProperty("position") == "dynamic") || UA.ie); 4342 4343 4344 if (bSetWidth) { 4345 4346 if (!this.cfg.getProperty("width")) { 4347 4348 nOffsetWidth = oElement.offsetWidth; 4349 4350 /* 4351 Measuring the difference of the offsetWidth before and after 4352 setting the "width" style attribute allows us to compute the 4353 about of padding and borders applied to the element, which in 4354 turn allows us to set the "width" property correctly. 4355 */ 4356 4357 oElement.style.width = nOffsetWidth + "px"; 4358 4359 sWidth = (nOffsetWidth - (oElement.offsetWidth - nOffsetWidth)) + "px"; 4360 4361 this.cfg.setProperty("width", sWidth); 4362 4363 } 4364 4365 } 4366 4367 4368 if (!oHeader && !oFooter) { 4369 4370 this.setHeader(" "); 4371 this.setFooter(" "); 4372 4373 oHeader = this.header; 4374 oFooter = this.footer; 4375 4376 Dom.addClass(oHeader, "topscrollbar"); 4377 Dom.addClass(oFooter, "bottomscrollbar"); 4378 4379 oElement.insertBefore(oHeader, oBody); 4380 oElement.appendChild(oFooter); 4381 4382 } 4383 4384 4385 nHeight = (nMaxHeight - (oHeader.offsetHeight + oHeader.offsetHeight)); 4386 4387 4388 if (nHeight > 0 && (oBody.offsetHeight > nMaxHeight)) { 4389 4390 Dom.addClass(oBody, "yui-menu-body-scrolled"); 4391 Dom.setStyle(oBody, "height", (nHeight + "px")); 4392 4393 Event.on(oHeader, "mouseover", fnMouseOver, this, true); 4394 Event.on(oHeader, "mouseout", fnMouseOut, this, true); 4395 Event.on(oFooter, "mouseover", fnMouseOver, this, true); 4396 Event.on(oFooter, "mouseout", fnMouseOut, this, true); 4397 4398 this._disableScrollHeader(); 4399 this._enableScrollFooter(); 4400 4401 } 4402 else if (oHeader && oFooter) { 4403
4404 if (bSetWidth) { 4405 4406 this.cfg.setProperty("width", ""); 4407 4408 } 4409 4410 4411 this._enableScrollHeader(); 4412 this._enableScrollFooter(); 4413 4414 Event.removeListener(oHeader, "mouseover", fnMouseOver); 4415 Event.removeListener(oHeader, "mouseout", fnMouseOut); 4416 Event.removeListener(oFooter, "mouseover", fnMouseOver); 4417 Event.removeListener(oFooter, "mouseout", fnMouseOut); 4418 4419 oElement.removeChild(oHeader); 4420 oElement.removeChild(oFooter); 4421 4422 this.header = null; 4423 this.footer = null; 4424 4425 } 4426 4427 this.cfg.refireEvent("iframe"); 4428 4429}, 4430 4431 4432/** 4433* @method configClassName 4434* @description Event handler for when the "classname" configuration property of 4435* a menu changes. 4436* @param {String} p_sType The name of the event that was fired. 4437* @param {Array} p_aArgs Collection of arguments sent when the event was fired. 4438* @param {YAHOO.widget.Menu} p_oMenu The Menu instance fired the event. 4439*/ 4440configClassName: function (p_sType, p_aArgs, p_oMenu) { 4441 4442 var sClassName = p_aArgs[0]; 4443 4444 if (this._sClassName) { 4445 4446 Dom.removeClass(this.element, this._sClassName); 4447 4448 } 4449 4450 Dom.addClass(this.element, sClassName); 4451 this._sClassName = sClassName; 4452 4453}, 4454 4455 4456/** 4457* @method _onItemAdded 4458* @description "itemadded" event handler for a Menu instance. 4459* @private 4460* @param {String} p_sType The name of the event that was fired. 4461* @param {Array} p_aArgs Collection of arguments sent when the event 4462* was fired. 4463*/ 4464_onItemAdded: function (p_sType, p_aArgs) { 4465 4466 var oItem = p_aArgs[0]; 4467 4468 if (oItem) { 4469 4470 oItem.cfg.setProperty("disabled", true); 4471 4472 } 4473 4474}, 4475 4476 4477/** 4478* @method configDisabled 4479* @description Event handler for when the "disabled" configuration property of 4480* a menu changes. 4481* @param {String} p_sType The name of the event that was fired. 4482* @param {Array} p_aArgs Collection of arguments sent when the event was fired. 4483* @param {YAHOO.widget.Menu} p_oMenu The Menu instance fired the event. 4484*/ 4485configDisabled: function (p_sType, p_aArgs, p_oMenu) { 4486 4487 var bDisabled = p_aArgs[0], 4488 aItems = this.getItems(), 4489 nItems, 4490 i; 4491 4492 if (Lang.isArray(aItems)) { 4493 4494 nItems = aItems.length; 4495 4496 if (nItems > 0) { 4497 4498 i = nItems - 1; 4499 4500 do { 4501 4502 aItems[i].cfg.setProperty("disabled", bDisabled); 4503 4504 } 4505 while (i--); 4506 4507 } 4508 4509 4510 if (bDisabled) { 4511 4512 this.clearActiveItem(true); 4513 4514 Dom.addClass(this.element, "disabled"); 4515 4516 this.itemAddedEvent.subscribe(this._onItemAdded); 4517 4518 } 4519 else { 4520 4521 Dom.removeClass(this.element, "disabled"); 4522 4523 this.itemAddedEvent.unsubscribe(this._onItemAdded); 4524 4525 } 4526 4527 } 4528 4529}, 4530 4531 4532/** 4533* @method onRender 4534* @description "render" event handler for the menu. 4535* @param {String} p_sType String representing the name of the event that 4536* was fired. 4537* @param {Array} p_aArgs Array of arguments sent when the event was fired. 4538*/ 4539onRender: function (p_sType, p_aArgs) { 4540 4541 function sizeShadow() { 4542 4543 var oElement = this.element, 4544 oShadow = this._shadow; 4545 4546 if (oShadow && oElement) { 4547 4548 oShadow.style.width = (oElement.offsetWidth + 6) + "px"; 4549 oShadow.style.height = (oElement.offsetHeight + 1) + "px"; 4550 4551 } 4552 4553 } 4554 4555 4556 function replaceShadow() { 4557 4558 this.element.appendChild(this._shadow); 4559 4560 } 4561 4562 4563 function addShadowVisibleClass() { 4564 4565 Dom.addClass(this._shadow, "yui-menu-shadow-visible"); 4566 4567 } 4568 4569 4570 function removeShadowVisibleClass() { 4571 4572 Dom.removeClass(this._shadow, "yui-menu-shadow-visible"); 4573 4574 } 4575 4576 4577 function createShadow() { 4578 4579 var oShadow = this._shadow, 4580 oElement, 4581 me; 4582 4583 if (!oShadow) { 4584 4585 oElement = this.element; 4586 me = this; 4587 4588 if (!m_oShadowTemplate) { 4589 4590 m_oShadowTemplate = document.createElement("div"); 4591 m_oShadowTemplate.className = 4592 "yui-menu-shadow yui-menu-shadow-visible"; 4593 4594 } 4595 4596 oShadow = m_oShadowTemplate.cloneNode(false); 4597 4598 oElement.appendChild(oShadow); 4599 4600 this._shadow = oShadow; 4601 4602 this.beforeShowEvent.subscribe(addShadowVisibleClass); 4603 this.beforeHideEvent.subscribe(removeShadowVisibleClass); 4604 4605 if (UA.ie) { 4606 4607 /* 4608 Need to call sizeShadow & syncIframe via setTimeout for 4609 IE 7 Quirks Mode and IE 6 Standards Mode and Quirks Mode 4610 or the shadow and iframe shim will not be sized and 4611 positioned properly. 4612 */ 4613 4614 window.setTimeout(function () { 4615 4616 sizeShadow.call(me); 4617 me.syncIframe(); 4618 4619 }, 0); 4620 4621 this.cfg.subscribeToConfigEvent("width", sizeShadow); 4622 this.cfg.subscribeToConfigEvent("height", sizeShadow); 4623 this.cfg.subscribeToConfigEvent("maxheight", sizeShadow); 4624 this.changeContentEvent.subscribe(sizeShadow); 4625 4626 Module.textResizeEvent.subscribe(sizeShadow, me, true); 4627 4628 this.destroyEvent.subscribe(function () { 4629 4630 Module.textResizeEvent.unsubscribe(sizeShadow, me); 4631 4632 }); 4633 4634 } 4635 4636 this.cfg.subscribeToConfigEvent("maxheight", replaceShadow); 4637 4638 } 4639 4640 } 4641 4642 4643 function onBeforeShow() { 4644 4645 createShadow.call(this); 4646 4647 this.beforeShowEvent.unsubscribe(onBeforeShow); 4648 4649 } 4650 4651 4652 if (this.cfg.getProperty("position") == "dynamic") { 4653 4654 if (this.cfg.getProperty("visible")) { 4655 4656 createShadow.call(this); 4657 4658 } 4659 else { 4660 4661 this.beforeShowEvent.subscribe(onBeforeShow); 4662 4663 } 4664 4665 } 4666 4667}, 4668 4669 4670// Public methods 4671 4672 4673/** 4674* @method initEvents 4675* @description Initializes the custom events for the menu. 4676*/ 4677initEvents: function () { 4678 4679 Menu.superclass.initEvents.call(this); 4680 4681 // Create custom events 4682 4683 var SIGNATURE = CustomEvent.LIST; 4684 4685 this.mouseOverEvent = this.createEvent(EVENT_TYPES.MOUSE_OVER);
4686 this.mouseOverEvent.signature = SIGNATURE; 4687 4688 this.mouseOutEvent = this.createEvent(EVENT_TYPES.MOUSE_OUT); 4689 this.mouseOutEvent.signature = SIGNATURE; 4690 4691 this.mouseDownEvent = this.createEvent(EVENT_TYPES.MOUSE_DOWN); 4692 this.mouseDownEvent.signature = SIGNATURE; 4693 4694 this.mouseUpEvent = this.createEvent(EVENT_TYPES.MOUSE_UP); 4695 this.mouseUpEvent.signature = SIGNATURE; 4696 4697 this.clickEvent = this.createEvent(EVENT_TYPES.CLICK); 4698 this.clickEvent.signature = SIGNATURE; 4699 4700 this.keyPressEvent = this.createEvent(EVENT_TYPES.KEY_PRESS); 4701 this.keyPressEvent.signature = SIGNATURE; 4702 4703 this.keyDownEvent = this.createEvent(EVENT_TYPES.KEY_DOWN); 4704 this.keyDownEvent.signature = SIGNATURE; 4705 4706 this.keyUpEvent = this.createEvent(EVENT_TYPES.KEY_UP); 4707 this.keyUpEvent.signature = SIGNATURE; 4708 4709 this.focusEvent = this.createEvent(EVENT_TYPES.FOCUS); 4710 this.focusEvent.signature = SIGNATURE; 4711 4712 this.blurEvent = this.createEvent(EVENT_TYPES.BLUR); 4713 this.blurEvent.signature = SIGNATURE; 4714 4715 this.itemAddedEvent = this.createEvent(EVENT_TYPES.ITEM_ADDED); 4716 this.itemAddedEvent.signature = SIGNATURE; 4717 4718 this.itemRemovedEvent = this.createEvent(EVENT_TYPES.ITEM_REMOVED); 4719 this.itemRemovedEvent.signature = SIGNATURE; 4720 4721}, 4722 4723 4724/** 4725* @method positionOffScreen 4726* @description Positions the menu outside of the boundaries of the browser's 4727* viewport. Called automatically when a menu is hidden to ensure that 4728* it doesn't force the browser to render uncessary scrollbars. 4729*/ 4730positionOffScreen: function () { 4731 4732 var oIFrame = this.iframe, 4733 aPos = this.OFF_SCREEN_POSITION; 4734 4735 Dom.setXY(this.element, aPos); 4736 4737 if (oIFrame) { 4738 4739 Dom.setXY(oIFrame, aPos); 4740 4741 } 4742 4743}, 4744 4745 4746/** 4747* @method getRoot 4748* @description Finds the menu's root menu. 4749*/ 4750getRoot: function () { 4751 4752 var oItem = this.parent, 4753 oParentMenu; 4754 4755 if (oItem) { 4756 4757 oParentMenu = oItem.parent; 4758 4759 return oParentMenu ? oParentMenu.getRoot() : this; 4760 4761 } 4762 else { 4763 4764 return this; 4765 4766 } 4767 4768}, 4769 4770 4771/** 4772* @method toString 4773* @description Returns a string representing the menu. 4774* @return {String} 4775*/ 4776toString: function () { 4777 4778 var sReturnVal = "Menu", 4779 sId = this.id; 4780 4781 if (sId) { 4782 4783 sReturnVal += (" " + sId); 4784 4785 } 4786 4787 return sReturnVal; 4788 4789}, 4790 4791 4792/** 4793* @method setItemGroupTitle 4794* @description Sets the title of a group of menu items. 4795* @param {String} p_sGroupTitle String specifying the title of the group. 4796* @param {Number} p_nGroupIndex Optional. Number specifying the group to which 4797* the title belongs. 4798*/ 4799setItemGroupTitle: function (p_sGroupTitle, p_nGroupIndex) { 4800 4801 var nGroupIndex, 4802 oTitle, 4803 i, 4804 nFirstIndex; 4805 4806 if (typeof p_sGroupTitle == "string" && p_sGroupTitle.length > 0) { 4807 4808 nGroupIndex = typeof p_nGroupIndex == "number" ? p_nGroupIndex : 0; 4809 oTitle = this._aGroupTitleElements[nGroupIndex]; 4810 4811 4812 if (oTitle) { 4813 4814 oTitle.innerHTML = p_sGroupTitle; 4815 4816 } 4817 else { 4818 4819 oTitle = document.createElement(this.GROUP_TITLE_TAG_NAME); 4820 4821 oTitle.innerHTML = p_sGroupTitle; 4822 4823 this._aGroupTitleElements[nGroupIndex] = oTitle; 4824 4825 } 4826 4827 4828 i = this._aGroupTitleElements.length - 1; 4829 4830 do { 4831 4832 if (this._aGroupTitleElements[i]) { 4833 4834 Dom.removeClass(this._aGroupTitleElements[i], "first-of-type"); 4835 4836 nFirstIndex = i; 4837 4838 } 4839 4840 } 4841 while(i--); 4842 4843 4844 if (nFirstIndex !== null) { 4845 4846 Dom.addClass(this._aGroupTitleElements[nFirstIndex], 4847 "first-of-type"); 4848 4849 } 4850 4851 this.changeContentEvent.fire(); 4852 4853 } 4854 4855}, 4856 4857 4858 4859/** 4860* @method addItem 4861* @description Appends an item to the menu. 4862* @param {YAHOO.widget.MenuItem} p_oItem Object reference for the MenuItem 4863* instance to be added to the menu. 4864* @param {String} p_oItem String specifying the text of the item to be added 4865* to the menu. 4866* @param {Object} p_oItem Object literal containing a set of menu item 4867* configuration properties. 4868* @param {Number} p_nGroupIndex Optional. Number indicating the group to 4869* which the item belongs.
4870* @return {YAHOO.widget.MenuItem} 4871*/ 4872addItem: function (p_oItem, p_nGroupIndex) { 4873 4874 if (p_oItem) { 4875 4876 return this._addItemToGroup(p_nGroupIndex, p_oItem); 4877 4878 } 4879 4880}, 4881 4882 4883/** 4884* @method addItems 4885* @description Adds an array of items to the menu. 4886* @param {Array} p_aItems Array of items to be added to the menu. The array 4887* can contain strings specifying the text for each item to be created, object 4888* literals specifying each of the menu item configuration properties, 4889* or MenuItem instances. 4890* @param {Number} p_nGroupIndex Optional. Number specifying the group to 4891* which the items belongs. 4892* @return {Array} 4893*/ 4894addItems: function (p_aItems, p_nGroupIndex) { 4895 4896 var nItems, 4897 aItems, 4898 oItem, 4899 i; 4900 4901 if (Lang.isArray(p_aItems)) { 4902 4903 nItems = p_aItems.length; 4904 aItems = []; 4905 4906 for(i=0; i<nItems; i++) { 4907 4908 oItem = p_aItems[i]; 4909 4910 if (oItem) { 4911 4912 if (Lang.isArray(oItem)) { 4913 4914 aItems[aItems.length] = this.addItems(oItem, i); 4915 4916 } 4917 else { 4918 4919 aItems[aItems.length] = 4920 this._addItemToGroup(p_nGroupIndex, oItem); 4921 4922 } 4923 4924 } 4925 4926 } 4927 4928 4929 if (aItems.length) { 4930 4931 return aItems; 4932 4933 } 4934 4935 } 4936 4937}, 4938 4939 4940/** 4941* @method insertItem 4942* @description Inserts an item into the menu at the specified index. 4943* @param {YAHOO.widget.MenuItem} p_oItem Object reference for the MenuItem 4944* instance to be added to the menu. 4945* @param {String} p_oItem String specifying the text of the item to be added 4946* to the menu. 4947* @param {Object} p_oItem Object literal containing a set of menu item 4948* configuration properties. 4949* @param {Number} p_nItemIndex Number indicating the ordinal position at which 4950* the item should be added. 4951* @param {Number} p_nGroupIndex Optional. Number indicating the group to which 4952* the item belongs. 4953* @return {YAHOO.widget.MenuItem} 4954*/ 4955insertItem: function (p_oItem, p_nItemIndex, p_nGroupIndex) { 4956 4957 if (p_oItem) { 4958 4959 return this._addItemToGroup(p_nGroupIndex, p_oItem, p_nItemIndex); 4960 4961 } 4962 4963}, 4964 4965 4966/** 4967* @method removeItem 4968* @description Removes the specified item from the menu. 4969* @param {YAHOO.widget.MenuItem} p_oObject Object reference for the MenuItem 4970* instance to be removed from the menu. 4971* @param {Number} p_oObject Number specifying the index of the item 4972* to be removed. 4973* @param {Number} p_nGroupIndex Optional. Number specifying the group to 4974* which the item belongs. 4975* @return {YAHOO.widget.MenuItem} 4976*/ 4977removeItem: function (p_oObject, p_nGroupIndex) { 4978 4979 var oItem; 4980 4981 if (typeof p_oObject != "undefined") { 4982 4983 if (p_oObject instanceof YAHOO.widget.MenuItem) { 4984 4985 oItem = this._removeItemFromGroupByValue(p_nGroupIndex, p_oObject); 4986 4987 } 4988 else if (typeof p_oObject == "number") { 4989 4990 oItem = this._removeItemFromGroupByIndex(p_nGroupIndex, p_oObject); 4991 4992 } 4993 4994 if (oItem) { 4995 4996 oItem.destroy(); 4997 4998 4999 return oItem; 5000 5001 } 5002 5003 } 5004 5005}, 5006 5007 5008/** 5009* @method getItems 5010* @description Returns an array of all of the items in the menu. 5011* @return {Array} 5012*/ 5013getItems: function () { 5014 5015 var aGroups = this._aItemGroups, 5016 nGroups, 5017 aItems = []; 5018 5019 if (Lang.isArray(aGroups)) { 5020 5021 nGroups = aGroups.length; 5022 5023 return ((nGroups == 1) ? aGroups[0] : 5024 (Array.prototype.concat.apply(aItems, aGroups))); 5025 5026 } 5027 5028}, 5029 5030 5031/** 5032* @method getItemGroups 5033* @description Multi-dimensional Array representing the menu items as they 5034* are grouped in the menu. 5035* @return {Array} 5036*/ 5037getItemGroups: function () { 5038 5039 return this._aItemGroups; 5040 5041}, 5042 5043 5044/** 5045* @method getItem 5046* @description Returns the item at the specified index. 5047* @param {Number} p_nItemIndex Number indicating the ordinal position of the 5048* item to be retrieved. 5049* @param {Number} p_nGroupIndex Optional. Number indicating the group to which 5050* the item belongs. 5051* @return {YAHOO.widget.MenuItem} 5052*/ 5053getItem: function (p_nItemIndex, p_nGroupIndex) { 5054 5055 var aGroup; 5056 5057 if (typeof p_nItemIndex == "number") { 5058 5059 aGroup = this._getItemGroup(p_nGroupIndex); 5060 5061 if (aGroup) { 5062 5063 return aGroup[p_nItemIndex]; 5064 5065 } 5066 5067 } 5068 5069}, 5070 5071 5072/** 5073* @method getSubmenus 5074* @description Returns an array of all of the submenus that are immediate 5075* children of the menu. 5076* @return {Array} 5077*/ 5078getSubmenus: function () { 5079 5080 var aItems = this.getItems(), 5081 nItems = aItems.length, 5082 aSubmenus, 5083 oSubmenu, 5084 oItem, 5085 i; 5086 5087 5088 if (nItems > 0) { 5089 5090 aSubmenus = []; 5091 5092 for(i=0; i<nItems; i++) { 5093 5094 oItem = aItems[i]; 5095 5096 if (oItem) { 5097 5098 oSubmenu = oItem.cfg.getProperty("submenu"); 5099 5100 if (oSubmenu) { 5101 5102 aSubmenus[aSubmenus.length] = oSubmenu;
5103 5104 } 5105 5106 } 5107 5108 } 5109 5110 } 5111 5112 return aSubmenus; 5113 5114}, 5115 5116 5117/** 5118* @method clearContent 5119* @description Removes all of the content from the menu, including the menu 5120* items, group titles, header and footer. 5121*/ 5122clearContent: function () { 5123 5124 var aItems = this.getItems(), 5125 nItems = aItems.length, 5126 oElement = this.element, 5127 oBody = this.body, 5128 oHeader = this.header, 5129 oFooter = this.footer, 5130 oItem, 5131 oSubmenu, 5132 i; 5133 5134 5135 if (nItems > 0) { 5136 5137 i = nItems - 1; 5138 5139 do { 5140 5141 oItem = aItems[i]; 5142 5143 if (oItem) { 5144 5145 oSubmenu = oItem.cfg.getProperty("submenu"); 5146 5147 if (oSubmenu) { 5148 5149 this.cfg.configChangedEvent.unsubscribe( 5150 this._onParentMenuConfigChange, oSubmenu); 5151 5152 this.renderEvent.unsubscribe(this._onParentMenuRender, 5153 oSubmenu); 5154 5155 } 5156 5157 this.removeItem(oItem); 5158 5159 } 5160 5161 } 5162 while(i--); 5163 5164 } 5165 5166 5167 if (oHeader) { 5168 5169 Event.purgeElement(oHeader); 5170 oElement.removeChild(oHeader); 5171 5172 } 5173 5174 5175 if (oFooter) { 5176 5177 Event.purgeElement(oFooter); 5178 oElement.removeChild(oFooter); 5179 } 5180 5181 5182 if (oBody) { 5183 5184 Event.purgeElement(oBody); 5185 5186 oBody.innerHTML = ""; 5187 5188 } 5189 5190 this.activeItem = null; 5191 5192 this._aItemGroups = []; 5193 this._aListElements = []; 5194 this._aGroupTitleElements = []; 5195 5196 this.cfg.setProperty("width", null); 5197 5198}, 5199 5200 5201/** 5202* @method destroy 5203* @description Removes the menu's <code><div></code> element 5204* (and accompanying child nodes) from the document. 5205*/ 5206destroy: function () { 5207 5208 // Remove all items 5209 5210 this.clearContent(); 5211 5212 this._aItemGroups = null; 5213 this._aListElements = null; 5214 this._aGroupTitleElements = null; 5215 5216 5217 // Continue with the superclass implementation of this method 5218 5219 Menu.superclass.destroy.call(this); 5220 5221 5222}, 5223 5224 5225/** 5226* @method setInitialFocus 5227* @description Sets focus to the menu's first enabled item. 5228*/ 5229setInitialFocus: function () { 5230 5231 var oItem = this._getFirstEnabledItem(); 5232 5233 if (oItem) { 5234 5235 oItem.focus(); 5236 5237 } 5238 5239}, 5240 5241 5242/** 5243* @method setInitialSelection 5244* @description Sets the "selected" configuration property of the menu's first 5245* enabled item to "true." 5246*/ 5247setInitialSelection: function () { 5248 5249 var oItem = this._getFirstEnabledItem(); 5250 5251 if (oItem) { 5252 5253 oItem.cfg.setProperty("selected", true); 5254 } 5255 5256}, 5257 5258 5259/** 5260* @method clearActiveItem 5261* @description Sets the "selected" configuration property of the menu's active 5262* item to "false" and hides the item's submenu. 5263* @param {Boolean} p_bBlur Boolean indicating if the menu's active item 5264* should be blurred. 5265*/ 5266clearActiveItem: function (p_bBlur) { 5267 5268 if (this.cfg.getProperty("showdelay") > 0) { 5269 5270 this._cancelShowDelay(); 5271 5272 } 5273 5274 5275 var oActiveItem = this.activeItem, 5276 oConfig, 5277 oSubmenu; 5278 5279 if (oActiveItem) { 5280 5281 oConfig = oActiveItem.cfg; 5282 5283 if (p_bBlur) { 5284 5285 oActiveItem.blur(); 5286 5287 } 5288 5289 oConfig.setProperty("selected", false); 5290 5291 oSubmenu = oConfig.getProperty("submenu"); 5292 5293 if (oSubmenu) { 5294 5295 oSubmenu.hide(); 5296 5297 } 5298 5299 this.activeItem = null; 5300 5301 } 5302 5303}, 5304 5305 5306/** 5307* @method focus 5308* @description Causes the menu to receive focus and fires the "focus" event. 5309*/ 5310focus: function () { 5311 5312 if (!this.hasFocus()) { 5313 5314 this.setInitialFocus(); 5315 5316 } 5317 5318}, 5319 5320 5321/** 5322* @method blur 5323* @description Causes the menu to lose focus and fires the "blur" event. 5324*/ 5325blur: function () { 5326 5327 var oItem; 5328 5329 if (this.hasFocus()) { 5330 5331 oItem = MenuManager.getFocusedMenuItem(); 5332 5333 if (oItem) { 5334 5335 oItem.blur(); 5336 5337 } 5338 5339 } 5340 5341}, 5342 5343 5344/** 5345* @method hasFocus 5346* @description Returns a boolean indicating whether or not the menu has focus. 5347* @return {Boolean} 5348*/ 5349hasFocus: function () { 5350 5351 return (MenuManager.getFocusedMenu() == this.getRoot()); 5352 5353}, 5354 5355 5356/** 5357* Adds the specified CustomEvent subscriber to the menu and each of 5358* its submenus. 5359* @method subscribe 5360* @param p_type {string} the type, or name of the event 5361* @param p_fn {function} the function to exectute when the event fires 5362* @param p_obj {Object} An object to be passed along when the event 5363* fires 5364* @param p_override {boolean} If true, the obj passed in becomes the 5365* execution scope of the listener 5366*/ 5367subscribe: function () { 5368 5369 function onItemAdded(p_sType, p_aArgs, p_oObject) { 5370
5371 var oItem = p_aArgs[0], 5372 oSubmenu = oItem.cfg.getProperty("submenu"); 5373 5374 if (oSubmenu) { 5375 5376 oSubmenu.subscribe.apply(oSubmenu, p_oObject); 5377 5378 } 5379 5380 } 5381 5382 5383 function onSubmenuAdded(p_sType, p_aArgs, p_oObject) { 5384 5385 var oSubmenu = this.cfg.getProperty("submenu"); 5386 5387 if (oSubmenu) { 5388 5389 oSubmenu.subscribe.apply(oSubmenu, p_oObject); 5390 5391 } 5392 5393 } 5394 5395 5396 Menu.superclass.subscribe.apply(this, arguments); 5397 Menu.superclass.subscribe.call(this, "itemAdded", onItemAdded, arguments); 5398 5399 5400 var aItems = this.getItems(), 5401 nItems, 5402 oItem, 5403 oSubmenu, 5404 i; 5405 5406 5407 if (aItems) { 5408 5409 nItems = aItems.length; 5410 5411 if (nItems > 0) { 5412 5413 i = nItems - 1; 5414 5415 do { 5416 5417 oItem = aItems[i]; 5418 5419 oSubmenu = oItem.cfg.getProperty("submenu"); 5420 5421 if (oSubmenu) { 5422 5423 oSubmenu.subscribe.apply(oSubmenu, arguments); 5424 5425 } 5426 else { 5427 5428 oItem.cfg.subscribeToConfigEvent("submenu", onSubmenuAdded, arguments); 5429 5430 } 5431 5432 } 5433 while (i--); 5434 5435 } 5436 5437 } 5438 5439}, 5440 5441 5442/** 5443* @description Initializes the class's configurable properties which can be 5444* changed using the menu's Config object ("cfg"). 5445* @method initDefaultConfig 5446*/ 5447initDefaultConfig: function () { 5448 5449 Menu.superclass.initDefaultConfig.call(this); 5450 5451 var oConfig = this.cfg; 5452 5453 5454 // Module documentation overrides 5455 5456 /** 5457 * @config effect 5458 * @description Object or array of objects representing the ContainerEffect 5459 * classes that are active for animating the container. When set this 5460 * property is automatically applied to all submenus. 5461 * @type Object 5462 * @default null 5463 */ 5464 5465 // Overlay documentation overrides 5466 5467 5468 /** 5469 * @config x 5470 * @description Number representing the absolute x-coordinate position of 5471 * the Menu. This property is only applied when the "position" 5472 * configuration property is set to dynamic. 5473 * @type Number 5474 * @default null 5475 */ 5476 5477 5478 /** 5479 * @config y
5480 * @description Number representing the absolute y-coordinate position of 5481 * the Menu. This property is only applied when the "position" 5482 * configuration property is set to dynamic. 5483 * @type Number 5484 * @default null 5485 */ 5486 5487 5488 /** 5489 * @description Array of the absolute x and y positions of the Menu. This 5490 * property is only applied when the "position" configuration property is 5491 * set to dynamic. 5492 * @config xy 5493 * @type Number[] 5494 * @default null 5495 */ 5496 5497 5498 /** 5499 * @config context 5500 * @description Array of context arguments for context-sensitive positioning. 5501 * The format is: [id or element, element corner, context corner]. 5502 * For example, setting this property to ["img1", "tl", "bl"] would 5503 * align the Mnu's top left corner to the context element's 5504 * bottom left corner. This property is only applied when the "position" 5505 * configuration property is set to dynamic. 5506 * @type Array 5507 * @default null 5508 */ 5509 5510 5511 /** 5512 * @config fixedcenter 5513 * @description Boolean indicating if the Menu should be anchored to the 5514 * center of the viewport. This property is only applied when the 5515 * "position" configuration property is set to dynamic. 5516 * @type Boolean 5517 * @default false 5518 */ 5519 5520 5521 /** 5522 * @config zindex 5523 * @description Number representing the CSS z-index of the Menu. This 5524 * property is only applied when the "position" configuration property is 5525 * set to dynamic. 5526 * @type Number 5527 * @default null 5528 */ 5529 5530 5531 /** 5532 * @config iframe 5533 * @description Boolean indicating whether or not the Menu should 5534 * have an IFRAME shim; used to prevent SELECT elements from 5535 * poking through an Overlay instance in IE6. When set to "true", 5536 * the iframe shim is created when the Menu instance is intially 5537 * made visible. This property is only applied when the "position" 5538 * configuration property is set to dynamic and is automatically applied 5539 * to all submenus. 5540 * @type Boolean 5541 * @default true for IE6 and below, false for all other browsers. 5542 */ 5543 5544 5545 // Add configuration attributes 5546 5547 /* 5548 Change the default value for the "visible" configuration 5549 property to "false" by re-adding the property. 5550 */ 5551 5552 /** 5553 * @config visible 5554 * @description Boolean indicating whether or not the menu is visible. If 5555 * the menu's "position" configuration property is set to "dynamic" (the 5556 * default), this property toggles the menu's <code><div></code> 5557 * element's "visibility" style property between "visible" (true) or 5558 * "hidden" (false). If the menu's "position" configuration property is 5559 * set to "static" this property toggles the menu's 5560 * <code><div></code> element's "display" style property 5561 * between "block" (true) or "none" (false). 5562 * @default false 5563 * @type Boolean 5564 */ 5565 oConfig.addProperty( 5566 DEFAULT_CONFIG.VISIBLE.key, 5567 { 5568 handler: this.configVisible, 5569 value: DEFAULT_CONFIG.VISIBLE.value, 5570 validator: DEFAULT_CONFIG.VISIBLE.validator 5571 } 5572 ); 5573 5574 5575 /* 5576 Change the default value for the "constraintoviewport" configuration 5577 property to "true" by re-adding the property. 5578 */ 5579 5580 /** 5581 * @config constraintoviewport 5582 * @description Boolean indicating if the menu will try to remain inside 5583 * the boundaries of the size of viewport. This property is only applied 5584 * when the "position" configuration property is set to dynamic and is 5585 * automatically applied to all submenus. 5586 * @default true 5587 * @type Boolean 5588 */ 5589 oConfig.addProperty( 5590 DEFAULT_CONFIG.CONSTRAIN_TO_VIEWPORT.key, 5591 { 5592 handler: this.configConstrainToViewport, 5593 value: DEFAULT_CONFIG.CONSTRAIN_TO_VIEWPORT.value, 5594 validator: DEFAULT_CONFIG.CONSTRAIN_TO_VIEWPORT.validator, 5595 supercedes: DEFAULT_CONFIG.CONSTRAIN_TO_VIEWPORT.supercedes 5596 } 5597 ); 5598 5599 5600 /** 5601 * @config position 5602 * @description String indicating how a menu should be positioned on the 5603 * screen. Possible values are "static" and "dynamic." Static menus are 5604 * visible by default and reside in the normal flow of the document 5605 * (CSS position: static). Dynamic menus are hidden by default, reside 5606 * out of the normal flow of the document (CSS position: absolute), and 5607 * can overlay other elements on the screen. 5608 * @default dynamic
5609 * @type String 5610 */ 5611 oConfig.addProperty( 5612 DEFAULT_CONFIG.POSITION.key, 5613 { 5614 handler: this.configPosition, 5615 value: DEFAULT_CONFIG.POSITION.value, 5616 validator: DEFAULT_CONFIG.POSITION.validator, 5617 supercedes: DEFAULT_CONFIG.POSITION.supercedes 5618 } 5619 ); 5620 5621 5622 /** 5623 * @config submenualignment 5624 * @description Array defining how submenus should be aligned to their 5625 * parent menu item. The format is: [itemCorner, submenuCorner]. By default 5626 * a submenu's top left corner is aligned to its parent menu item's top 5627 * right corner. 5628 * @default ["tl","tr"] 5629 * @type Array 5630 */ 5631 oConfig.addProperty( 5632 DEFAULT_CONFIG.SUBMENU_ALIGNMENT.key, 5633 { 5634 value: DEFAULT_CONFIG.SUBMENU_ALIGNMENT.value, 5635 suppressEvent: DEFAULT_CONFIG.SUBMENU_ALIGNMENT.suppressEvent 5636 } 5637 ); 5638 5639 5640 /** 5641 * @config autosubmenudisplay 5642 * @description Boolean indicating if submenus are automatically made 5643 * visible when the user mouses over the menu's items. 5644 * @default true 5645 * @type Boolean 5646 */ 5647 oConfig.addProperty( 5648 DEFAULT_CONFIG.AUTO_SUBMENU_DISPLAY.key, 5649 { 5650 value: DEFAULT_CONFIG.AUTO_SUBMENU_DISPLAY.value, 5651 validator: DEFAULT_CONFIG.AUTO_SUBMENU_DISPLAY.validator, 5652 suppressEvent: DEFAULT_CONFIG.AUTO_SUBMENU_DISPLAY.suppressEvent 5653 } 5654 ); 5655 5656 5657 /** 5658 * @config showdelay 5659 * @description Number indicating the time (in milliseconds) that should 5660 * expire before a submenu is made visible when the user mouses over 5661 * the menu's items. This property is only applied when the "position" 5662 * configuration property is set to dynamic and is automatically applied 5663 * to all submenus. 5664 * @default 250 5665 * @type Number 5666 */ 5667 oConfig.addProperty( 5668 DEFAULT_CONFIG.SHOW_DELAY.key, 5669 { 5670 value: DEFAULT_CONFIG.SHOW_DELAY.value, 5671 validator: DEFAULT_CONFIG.SHOW_DELAY.validator, 5672 suppressEvent: DEFAULT_CONFIG.SHOW_DELAY.suppressEvent 5673 } 5674 ); 5675 5676 5677 /** 5678 * @config hidedelay 5679 * @description Number indicating the time (in milliseconds) that should 5680 * expire before the menu is hidden. This property is only applied when 5681 * the "position" configuration property is set to dynamic and is 5682 * automatically applied to all submenus. 5683 * @default 0 5684 * @type Number 5685 */ 5686 oConfig.addProperty( 5687 DEFAULT_CONFIG.HIDE_DELAY.key, 5688 { 5689 handler: this.configHideDelay, 5690 value: DEFAULT_CONFIG.HIDE_DELAY.value, 5691 validator: DEFAULT_CONFIG.HIDE_DELAY.validator, 5692 suppressEvent: DEFAULT_CONFIG.HIDE_DELAY.suppressEvent 5693 } 5694 ); 5695 5696 5697 /** 5698 * @config submenuhidedelay 5699 * @description Number indicating the time (in milliseconds) that should 5700 * expire before a submenu is hidden when the user mouses out of a menu item 5701 * heading in the direction of a submenu. The value must be greater than or 5702 * equal to the value specified for the "showdelay" configuration property. 5703 * This property is only applied when the "position" configuration property 5704 * is set to dynamic and is automatically applied to all submenus. 5705 * @default 250 5706 * @type Number 5707 */ 5708 oConfig.addProperty( 5709 DEFAULT_CONFIG.SUBMENU_HIDE_DELAY.key, 5710 { 5711 value: DEFAULT_CONFIG.SUBMENU_HIDE_DELAY.value, 5712 validator: DEFAULT_CONFIG.SUBMENU_HIDE_DELAY.validator, 5713 suppressEvent: DEFAULT_CONFIG.SUBMENU_HIDE_DELAY.suppressEvent 5714 } 5715 ); 5716 5717 5718 /** 5719 * @config clicktohide 5720 * @description Boolean indicating if the menu will automatically be 5721 * hidden if the user clicks outside of it. This property is only 5722 * applied when the "position" configuration property is set to dynamic 5723 * and is automatically applied to all submenus. 5724 * @default true 5725 * @type Boolean 5726 */ 5727 oConfig.addProperty( 5728 DEFAULT_CONFIG.CLICK_TO_HIDE.key, 5729 { 5730 value: DEFAULT_CONFIG.CLICK_TO_HIDE.value, 5731 validator: DEFAULT_CONFIG.CLICK_TO_HIDE.validator, 5732 suppressEvent: DEFAULT_CONFIG.CLICK_TO_HIDE.suppressEvent 5733 } 5734 ); 5735 5736 5737 /** 5738 * @config container 5739 * @description HTML element reference or string specifying the id 5740 * attribute of the HTML element that the menu's markup should be 5741 * rendered into. 5742 * @type <a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/ 5743 * level-one-html.html#ID-58190037">HTMLElement</a>|String 5744 * @default document.body 5745 */ 5746 oConfig.addProperty( 5747 DEFAULT_CONFIG.CONTAINER.key, 5748 { 5749 handler: this.configContainer, 5750 value: document.body, 5751 suppressEvent: DEFAULT_CONFIG.CONTAINER.suppressEvent 5752 } 5753 ); 5754 5755 5756 /** 5757 * @config scrollincrement
5758 * @description Number used to control the scroll speed of a menu. Used to 5759 * increment the "scrollTop" property of the menu's body by when a menu's 5760 * content is scrolling. When set this property is automatically applied 5761 * to all submenus. 5762 * @default 1 5763 * @type Number 5764 */ 5765 oConfig.addProperty( 5766 DEFAULT_CONFIG.SCROLL_INCREMENT.key, 5767 { 5768 value: DEFAULT_CONFIG.SCROLL_INCREMENT.value, 5769 validator: DEFAULT_CONFIG.SCROLL_INCREMENT.validator, 5770 supercedes: DEFAULT_CONFIG.SCROLL_INCREMENT.supercedes, 5771 suppressEvent: DEFAULT_CONFIG.SCROLL_INCREMENT.suppressEvent 5772 } 5773 ); 5774 5775 5776 /** 5777 * @config minscrollheight 5778 * @description Number defining the minimum threshold for the "maxheight" 5779 * configuration property. When set this property is automatically applied 5780 * to all submenus. 5781 * @default 90 5782 * @type Number 5783 */ 5784 oConfig.addProperty( 5785 DEFAULT_CONFIG.MIN_SCROLL_HEIGHT.key, 5786 { 5787 value: DEFAULT_CONFIG.MIN_SCROLL_HEIGHT.value, 5788 validator: DEFAULT_CONFIG.MIN_SCROLL_HEIGHT.validator, 5789 supercedes: DEFAULT_CONFIG.MIN_SCROLL_HEIGHT.supercedes, 5790 suppressEvent: DEFAULT_CONFIG.MIN_SCROLL_HEIGHT.suppressEvent 5791 } 5792 ); 5793 5794 5795 /** 5796 * @config maxheight 5797 * @description Number defining the maximum height (in pixels) for a menu's 5798 * body element (<code><div class="bd"<</code>). Once a menu's body 5799 * exceeds this height, the contents of the body are scrolled to maintain 5800 * this value. This value cannot be set lower than the value of the 5801 * "minscrollheight" configuration property. 5802 * @default 0 5803 * @type Number 5804 */ 5805 oConfig.addProperty( 5806 DEFAULT_CONFIG.MAX_HEIGHT.key, 5807 { 5808 handler: this.configMaxHeight, 5809 value: DEFAULT_CONFIG.MAX_HEIGHT.value, 5810 validator: DEFAULT_CONFIG.MAX_HEIGHT.validator, 5811 suppressEvent: DEFAULT_CONFIG.MAX_HEIGHT.suppressEvent, 5812 supercedes: DEFAULT_CONFIG.MAX_HEIGHT.supercedes 5813 } 5814 ); 5815 5816 5817 /** 5818 * @config classname 5819 * @description String representing the CSS class to be applied to the 5820 * menu's root <code><div></code> element. The specified class(es) 5821 * are appended in addition to the default class as specified by the menu's 5822 * CSS_CLASS_NAME constant. When set this property is automatically 5823 * applied to all submenus. 5824 * @default null
5825 * @type String 5826 */ 5827 oConfig.addProperty( 5828 DEFAULT_CONFIG.CLASS_NAME.key, 5829 { 5830 handler: this.configClassName, 5831 value: DEFAULT_CONFIG.CLASS_NAME.value, 5832 validator: DEFAULT_CONFIG.CLASS_NAME.validator, 5833 supercedes: DEFAULT_CONFIG.CLASS_NAME.supercedes 5834 } 5835 ); 5836 5837 5838 /** 5839 * @config disabled 5840 * @description Boolean indicating if the menu should be disabled. 5841 * Disabling a menu disables each of its items. (Disabled menu items are 5842 * dimmed and will not respond to user input or fire events.) Disabled 5843 * menus have a corresponding "disabled" CSS class applied to their root 5844 * <code><div></code> element. 5845 * @default false 5846 * @type Boolean 5847 */ 5848 oConfig.addProperty( 5849 DEFAULT_CONFIG.DISABLED.key, 5850 { 5851 handler: this.configDisabled, 5852 value: DEFAULT_CONFIG.DISABLED.value, 5853 validator: DEFAULT_CONFIG.DISABLED.validator, 5854 suppressEvent: DEFAULT_CONFIG.DISABLED.suppressEvent 5855 } 5856 ); 5857 5858} 5859 5860}); // END YAHOO.lang.extend 5861 5862})(); 5863 5864 5865 5866(function () { 5867 5868 5869/** 5870* Creates an item for a menu. 5871* 5872* @param {String} p_oObject String specifying the text of the menu item. 5873* @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level- 5874* one-html.html#ID-74680021">HTMLLIElement</a>} p_oObject Object specifying 5875* the <code><li></code> element of the menu item. 5876* @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level- 5877* one-html.html#ID-38450247">HTMLOptGroupElement</a>} p_oObject Object 5878* specifying the <code><optgroup></code> element of the menu item. 5879* @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level- 5880* one-html.html#ID-70901257">HTMLOptionElement</a>} p_oObject Object 5881* specifying the <code><option></code> element of the menu item. 5882* @param {Object} p_oConfig Optional. Object literal specifying the 5883* configuration for the menu item. See configuration class documentation 5884* for more details. 5885* @class MenuItem 5886* @constructor 5887*/ 5888YAHOO.widget.MenuItem = function (p_oObject, p_oConfig) { 5889 5890 if (p_oObject) { 5891 5892 if (p_oConfig) { 5893 5894 this.parent = p_oConfig.parent; 5895 this.value = p_oConfig.value; 5896 this.id = p_oConfig.id; 5897 5898 } 5899 5900 this.init(p_oObject, p_oConfig); 5901 5902 } 5903 5904}; 5905 5906 5907var Dom = YAHOO.util.Dom, 5908 Module = YAHOO.widget.Module, 5909 Menu = YAHOO.widget.Menu, 5910 MenuItem = YAHOO.widget.MenuItem, 5911 CustomEvent = YAHOO.util.CustomEvent, 5912 Lang = YAHOO.lang, 5913 5914 m_oMenuItemTemplate, 5915 5916 /** 5917 * Constant representing the name of the MenuItem's events 5918 * @property EVENT_TYPES 5919 * @private 5920 * @final 5921 * @type Object 5922 */ 5923 EVENT_TYPES = { 5924 5925 "MOUSE_OVER": "mouseover", 5926 "MOUSE_OUT": "mouseout", 5927 "MOUSE_DOWN": "mousedown", 5928 "MOUSE_UP": "mouseup", 5929 "CLICK": "click", 5930 "KEY_PRESS": "keypress", 5931 "KEY_DOWN": "keydown", 5932 "KEY_UP": "keyup", 5933 "ITEM_ADDED": "itemAdded", 5934 "ITEM_REMOVED": "itemRemoved", 5935 "FOCUS": "focus", 5936 "BLUR": "blur", 5937 "DESTROY": "destroy" 5938 5939 }, 5940 5941 /** 5942 * Constant representing the MenuItem's configuration properties 5943 * @property DEFAULT_CONFIG 5944 * @private 5945 * @final 5946 * @type Object 5947 */ 5948 DEFAULT_CONFIG = { 5949 5950 "TEXT": { 5951 key: "text", 5952 value: "", 5953 validator: Lang.isString, 5954 suppressEvent: true 5955 }, 5956 5957 "HELP_TEXT": { 5958 key: "helptext", 5959 supercedes: ["text"], 5960 suppressEvent: true 5961 }, 5962 5963 "URL": { 5964 key: "url", 5965 value: "#", 5966 suppressEvent: true 5967 }, 5968 5969 "TARGET": { 5970 key: "target", 5971 suppressEvent: true 5972 }, 5973 5974 "EMPHASIS": { 5975 key: "emphasis", 5976 value: false, 5977 validator: Lang.isBoolean, 5978 suppressEvent: true, 5979 supercedes: ["text"] 5980 }, 5981 5982 "STRONG_EMPHASIS": { 5983 key: "strongemphasis", 5984 value: false, 5985 validator: Lang.isBoolean, 5986 suppressEvent: true, 5987 supercedes: ["text"] 5988 }, 5989 5990 "CHECKED": { 5991 key: "checked", 5992 value: false, 5993 validator: Lang.isBoolean, 5994 suppressEvent: true, 5995 supercedes: ["disabled", "selected"] 5996 }, 5997 5998 "SUBMENU": { 5999 key: "submenu", 6000 suppressEvent: true, 6001 supercedes: ["disabled", "selected"] 6002 }, 6003 6004 "DISABLED": { 6005 key: "disabled", 6006 value: false, 6007 validator: Lang.isBoolean, 6008 suppressEvent: true, 6009 supercedes: ["text", "selected"] 6010 }, 6011 6012 "SELECTED": { 6013 key: "selected", 6014 value: false, 6015 validator: Lang.isBoolean, 6016 suppressEvent: true 6017 }, 6018 6019 "ONCLICK": { 6020 key: "onclick", 6021 suppressEvent: true 6022 }, 6023 6024 "CLASS_NAME": { 6025 key: "classname", 6026 value: null, 6027 validator: Lang.isString, 6028 suppressEvent: true 6029 } 6030 6031 }; 6032 6033 6034MenuItem.prototype = { 6035 6036 /** 6037 * @property CSS_CLASS_NAME
6038 * @description String representing the CSS class(es) to be applied to the 6039 * <code><li></code> element of the menu item. 6040 * @default "yuimenuitem" 6041 * @final 6042 * @type String 6043 */ 6044 CSS_CLASS_NAME: "yuimenuitem", 6045 6046 6047 /** 6048 * @property CSS_LABEL_CLASS_NAME 6049 * @description String representing the CSS class(es) to be applied to the 6050 * menu item's <code><a></code> element. 6051 * @default "yuimenuitemlabel" 6052 * @final 6053 * @type String 6054 */ 6055 CSS_LABEL_CLASS_NAME: "yuimenuitemlabel", 6056 6057 6058 /** 6059 * @property SUBMENU_TYPE 6060 * @description Object representing the type of menu to instantiate and 6061 * add when parsing the child nodes of the menu item's source HTML element. 6062 * @final 6063 * @type YAHOO.widget.Menu 6064 */ 6065 SUBMENU_TYPE: null, 6066 6067 6068 6069 // Private member variables 6070 6071 6072 /** 6073 * @property _oAnchor 6074 * @description Object reference to the menu item's 6075 * <code><a></code> element. 6076 * @default null 6077 * @private 6078 * @type <a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level- 6079 * one-html.html#ID-48250443">HTMLAnchorElement</a> 6080 */ 6081 _oAnchor: null, 6082 6083 6084 /** 6085 * @property _oHelpTextEM 6086 * @description Object reference to the menu item's help text 6087 * <code><em></code> element. 6088 * @default null 6089 * @private 6090 * @type <a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level- 6091 * one-html.html#ID-58190037">HTMLElement</a> 6092 */ 6093 _oHelpTextEM: null, 6094 6095 6096 /** 6097 * @property _oSubmenu 6098 * @description Object reference to the menu item's submenu. 6099 * @default null 6100 * @private 6101 * @type YAHOO.widget.Menu 6102 */ 6103 _oSubmenu: null, 6104 6105 6106 /** 6107 * @property _oOnclickAttributeValue 6108 * @description Object reference to the menu item's current value for the 6109 * "onclick" configuration attribute. 6110 * @default null 6111 * @private 6112 * @type Object 6113 */ 6114 _oOnclickAttributeValue: null, 6115 6116 6117 /** 6118 * @property _sClassName 6119 * @description The current value of the "classname" configuration attribute. 6120 * @default null 6121 * @private
6122 * @type String 6123 */ 6124 _sClassName: null, 6125 6126 6127 6128 // Public properties 6129 6130 6131 /** 6132 * @property constructor 6133 * @description Object reference to the menu item's constructor function. 6134 * @default YAHOO.widget.MenuItem 6135 * @type YAHOO.widget.MenuItem 6136 */ 6137 constructor: MenuItem, 6138 6139 6140 /** 6141 * @property index 6142 * @description Number indicating the ordinal position of the menu item in 6143 * its group. 6144 * @default null 6145 * @type Number 6146 */ 6147 index: null, 6148 6149 6150 /** 6151 * @property groupIndex 6152 * @description Number indicating the index of the group to which the menu 6153 * item belongs. 6154 * @default null 6155 * @type Number 6156 */ 6157 groupIndex: null, 6158 6159 6160 /** 6161 * @property parent 6162 * @description Object reference to the menu item's parent menu. 6163 * @default null 6164 * @type YAHOO.widget.Menu 6165 */ 6166 parent: null, 6167 6168 6169 /** 6170 * @property element 6171 * @description Object reference to the menu item's 6172 * <code><li></code> element. 6173 * @default <a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level 6174 * -one-html.html#ID-74680021">HTMLLIElement</a> 6175 * @type <a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level- 6176 * one-html.html#ID-74680021">HTMLLIElement</a> 6177 */ 6178 element: null, 6179 6180 6181 /** 6182 * @property srcElement 6183 * @description Object reference to the HTML element (either 6184 * <code><li></code>, <code><optgroup></code> or 6185 * <code><option></code>) used create the menu item. 6186 * @default <a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/ 6187 * level-one-html.html#ID-74680021">HTMLLIElement</a>|<a href="http://www. 6188 * w3.org/TR/2000/WD-DOM-Level-1-20000929/level-one-html.html#ID-38450247" 6189 * >HTMLOptGroupElement</a>|<a href="http://www.w3.org/TR/2000/WD-DOM- 6190 * Level-1-20000929/level-one-html.html#ID-70901257">HTMLOptionElement</a> 6191 * @type <a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level- 6192 * one-html.html#ID-74680021">HTMLLIElement</a>|<a href="http://www.w3. 6193 * org/TR/2000/WD-DOM-Level-1-20000929/level-one-html.html#ID-38450247"> 6194 * HTMLOptGroupElement</a>|<a href="http://www.w3.org/TR/2000/WD-DOM- 6195 * Level-1-20000929/level-one-html.html#ID-70901257">HTMLOptionElement</a> 6196 */ 6197 srcElement: null, 6198 6199 6200 /** 6201 * @property value 6202 * @description Object reference to the menu item's value. 6203 * @default null 6204 * @type Object 6205 */ 6206 value: null, 6207 6208 6209 /** 6210 * @property browser 6211 * @deprecated Use YAHOO.env.ua 6212 * @description String representing the browser. 6213 * @type String 6214 */ 6215 browser: Module.prototype.browser, 6216 6217 6218 /** 6219 * @property id 6220 * @description Id of the menu item's root <code><li></code> 6221 * element. This property should be set via the constructor using the 6222 * configuration object literal. If an id is not specified, then one will 6223 * be created using the "generateId" method of the Dom utility. 6224 * @default null
6225 * @type String 6226 */ 6227 id: null, 6228 6229 6230 6231 // Events 6232 6233 6234 /** 6235 * @event destroyEvent 6236 * @description Fires when the menu item's <code><li></code> 6237 * element is removed from its parent <code><ul></code> element. 6238 * @type YAHOO.util.CustomEvent 6239 */ 6240 destroyEvent: null, 6241 6242 6243 /** 6244 * @event mouseOverEvent 6245 * @description Fires when the mouse has entered the menu item. Passes 6246 * back the DOM Event object as an argument. 6247 * @type YAHOO.util.CustomEvent 6248 */ 6249 mouseOverEvent: null, 6250 6251 6252 /** 6253 * @event mouseOutEvent 6254 * @description Fires when the mouse has left the menu item. Passes back 6255 * the DOM Event object as an argument. 6256 * @type YAHOO.util.CustomEvent 6257 */ 6258 mouseOutEvent: null, 6259 6260 6261 /** 6262 * @event mouseDownEvent 6263 * @description Fires when the user mouses down on the menu item. Passes 6264 * back the DOM Event object as an argument. 6265 * @type YAHOO.util.CustomEvent 6266 */ 6267 mouseDownEvent: null, 6268 6269 6270 /** 6271 * @event mouseUpEvent 6272 * @description Fires when the user releases a mouse button while the mouse 6273 * is over the menu item. Passes back the DOM Event object as an argument. 6274 * @type YAHOO.util.CustomEvent 6275 */ 6276 mouseUpEvent: null, 6277 6278 6279 /** 6280 * @event clickEvent 6281 * @description Fires when the user clicks the on the menu item. Passes 6282 * back the DOM Event object as an argument. 6283 * @type YAHOO.util.CustomEvent 6284 */ 6285 clickEvent: null, 6286 6287 6288 /** 6289 * @event keyPressEvent 6290 * @description Fires when the user presses an alphanumeric key when the 6291 * menu item has focus. Passes back the DOM Event object as an argument. 6292 * @type YAHOO.util.CustomEvent 6293 */ 6294 keyPressEvent: null, 6295 6296 6297 /** 6298 * @event keyDownEvent 6299 * @description Fires when the user presses a key when the menu item has 6300 * focus. Passes back the DOM Event object as an argument. 6301 * @type YAHOO.util.CustomEvent 6302 */ 6303 keyDownEvent: null, 6304 6305 6306 /** 6307 * @event keyUpEvent 6308 * @description Fires when the user releases a key when the menu item has 6309 * focus. Passes back the DOM Event object as an argument. 6310 * @type YAHOO.util.CustomEvent 6311 */ 6312 keyUpEvent: null, 6313 6314 6315 /** 6316 * @event focusEvent 6317 * @description Fires when the menu item receives focus. 6318 * @type YAHOO.util.CustomEvent 6319 */ 6320 focusEvent: null, 6321 6322 6323 /** 6324 * @event blurEvent 6325 * @description Fires when the menu item loses the input focus. 6326 * @type YAHOO.util.CustomEvent 6327 */ 6328 blurEvent: null, 6329 6330 6331 /** 6332 * @method init 6333 * @description The MenuItem class's initialization method. This method is 6334 * automatically called by the constructor, and sets up all DOM references 6335 * for pre-existing markup, and creates required markup if it is not 6336 * already present. 6337 * @param {String} p_oObject String specifying the text of the menu item. 6338 * @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level- 6339 * one-html.html#ID-74680021">HTMLLIElement</a>} p_oObject Object specifying 6340 * the <code><li></code> element of the menu item. 6341 * @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level- 6342 * one-html.html#ID-38450247">HTMLOptGroupElement</a>} p_oObject Object 6343 * specifying the <code><optgroup></code> element of the menu item. 6344 * @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level- 6345 * one-html.html#ID-70901257">HTMLOptionElement</a>} p_oObject Object 6346 * specifying the <code><option></code> element of the menu item. 6347 * @param {Object} p_oConfig Optional. Object literal specifying the 6348 * configuration for the menu item. See configuration class documentation 6349 * for more details. 6350 */ 6351 init: function (p_oObject, p_oConfig) { 6352 6353 6354 if (!this.SUBMENU_TYPE) { 6355 6356 this.SUBMENU_TYPE = Menu; 6357 6358 } 6359 6360 6361 // Create the config object 6362 6363 this.cfg = new YAHOO.util.Config(this); 6364 6365 this.initDefaultConfig(); 6366 6367 var SIGNATURE = CustomEvent.LIST, 6368 oConfig = this.cfg, 6369 sURL = "#", 6370 oAnchor, 6371 sTarget, 6372 sText, 6373 sId; 6374 6375 6376 if (Lang.isString(p_oObject)) { 6377 6378 this._createRootNodeStructure(); 6379 6380 oConfig.queueProperty("text", p_oObject); 6381 6382 } 6383 else if (p_oObject && p_oObject.tagName) { 6384 6385 switch(p_oObject.tagName.toUpperCase()) { 6386 6387 case "OPTION": 6388 6389 this._createRootNodeStructure(); 6390 6391 oConfig.queueProperty("text", p_oObject.text); 6392 oConfig.queueProperty("disabled", p_oObject.disabled); 6393 6394 this.value = p_oObject.value; 6395 6396 this.srcElement = p_oObject; 6397 6398 break; 6399 6400 case "OPTGROUP": 6401 6402 this._createRootNodeStructure(); 6403 6404 oConfig.queueProperty("text", p_oObject.label); 6405 oConfig.queueProperty("disabled", p_oObject.disabled); 6406 6407 this.srcElement = p_oObject; 6408 6409 this._initSubTree(); 6410 6411 break; 6412 6413 case "LI": 6414
6415 // Get the anchor node (if it exists) 6416 6417 oAnchor = Dom.getFirstChild(p_oObject); 6418 6419 6420 // Capture the "text" and/or the "URL" 6421 6422 if (oAnchor) { 6423 6424 sURL = oAnchor.getAttribute("href", 2); 6425 sTarget = oAnchor.getAttribute("target"); 6426 6427 sText = oAnchor.innerHTML; 6428 6429 } 6430 6431 this.srcElement = p_oObject; 6432 this.element = p_oObject; 6433 this._oAnchor = oAnchor; 6434 6435 /* 6436 Set these properties silently to sync up the 6437 configuration object without making changes to the 6438 element's DOM 6439 */ 6440 6441 oConfig.setProperty("text", sText, true); 6442 oConfig.setProperty("url", sURL, true); 6443 oConfig.setProperty("target", sTarget, true); 6444 6445 this._initSubTree(); 6446 6447 break; 6448 6449 } 6450 6451 } 6452 6453 6454 if (this.element) { 6455 6456 sId = (this.srcElement || this.element).id; 6457 6458 if (!sId) { 6459 6460 sId = this.id || Dom.generateId(); 6461 6462 this.element.id = sId; 6463 6464 } 6465 6466 this.id = sId; 6467 6468 6469 Dom.addClass(this.element, this.CSS_CLASS_NAME); 6470 Dom.addClass(this._oAnchor, this.CSS_LABEL_CLASS_NAME); 6471 6472 6473 // Create custom events 6474 6475 this.mouseOverEvent = this.createEvent(EVENT_TYPES.MOUSE_OVER); 6476 this.mouseOverEvent.signature = SIGNATURE; 6477 6478 this.mouseOutEvent = this.createEvent(EVENT_TYPES.MOUSE_OUT); 6479 this.mouseOutEvent.signature = SIGNATURE; 6480 6481 this.mouseDownEvent = this.createEvent(EVENT_TYPES.MOUSE_DOWN); 6482 this.mouseDownEvent.signature = SIGNATURE; 6483 6484 this.mouseUpEvent = this.createEvent(EVENT_TYPES.MOUSE_UP); 6485 this.mouseUpEvent.signature = SIGNATURE; 6486 6487 this.clickEvent = this.createEvent(EVENT_TYPES.CLICK); 6488 this.clickEvent.signature = SIGNATURE; 6489 6490 this.keyPressEvent = this.createEvent(EVENT_TYPES.KEY_PRESS); 6491 this.keyPressEvent.signature = SIGNATURE; 6492 6493 this.keyDownEvent = this.createEvent(EVENT_TYPES.KEY_DOWN); 6494 this.keyDownEvent.signature = SIGNATURE; 6495 6496 this.keyUpEvent = this.createEvent(EVENT_TYPES.KEY_UP); 6497 this.keyUpEvent.signature = SIGNATURE; 6498 6499 this.focusEvent = this.createEvent(EVENT_TYPES.FOCUS); 6500 this.focusEvent.signature = SIGNATURE; 6501 6502 this.blurEvent = this.createEvent(EVENT_TYPES.BLUR); 6503 this.blurEvent.signature = SIGNATURE; 6504 6505 this.destroyEvent = this.createEvent(EVENT_TYPES.DESTROY); 6506 this.destroyEvent.signature = SIGNATURE; 6507 6508 if (p_oConfig) { 6509 6510 oConfig.applyConfig(p_oConfig); 6511 6512 } 6513 6514 oConfig.fireQueue(); 6515 6516 } 6517 6518 }, 6519 6520 6521 6522 // Private methods 6523 6524 6525 /** 6526 * @method _createRootNodeStructure 6527 * @description Creates the core DOM structure for the menu item. 6528 * @private 6529 */ 6530 _createRootNodeStructure: function () { 6531 6532 var oElement, 6533 oAnchor; 6534 6535 if (!m_oMenuItemTemplate) { 6536 6537 m_oMenuItemTemplate = document.createElement("li"); 6538 m_oMenuItemTemplate.innerHTML = "<a href=\"#\"></a>"; 6539 6540 } 6541 6542 oElement = m_oMenuItemTemplate.cloneNode(true); 6543 oElement.className = this.CSS_CLASS_NAME; 6544 6545 oAnchor = oElement.firstChild; 6546 oAnchor.className = this.CSS_LABEL_CLASS_NAME; 6547 6548 this.element = oElement; 6549 this._oAnchor = oAnchor; 6550 6551 }, 6552 6553 6554 /** 6555 * @method _initSubTree 6556 * @description Iterates the source element's childNodes collection and uses 6557 * the child nodes to instantiate other menus. 6558 * @private 6559 */ 6560 _initSubTree: function () { 6561 6562 var oSrcEl = this.srcElement, 6563 oConfig = this.cfg, 6564 oNode, 6565 aOptions, 6566 nOptions, 6567 oMenu, 6568 n; 6569 6570 6571 if (oSrcEl.childNodes.length > 0) { 6572 6573 if (this.parent.lazyLoad && this.parent.srcElement && 6574 this.parent.srcElement.tagName.toUpperCase() == "SELECT") { 6575 6576 oConfig.setProperty( 6577 "submenu", 6578 { id: Dom.generateId(), itemdata: oSrcEl.childNodes } 6579 ); 6580 6581 } 6582 else { 6583 6584 oNode = oSrcEl.firstChild; 6585 aOptions = []; 6586 6587 do { 6588 6589 if (oNode && oNode.tagName) { 6590 6591 switch(oNode.tagName.toUpperCase()) { 6592 6593 case "DIV": 6594 6595 oConfig.setProperty("submenu", oNode); 6596 6597 break; 6598 6599 case "OPTION": 6600 6601 aOptions[aOptions.length] = oNode; 6602 6603 break; 6604 6605 } 6606 6607 } 6608 6609 } 6610 while((oNode = oNode.nextSibling)); 6611 6612 6613 nOptions = aOptions.length; 6614 6615 if (nOptions > 0) { 6616 6617 oMenu = new this.SUBMENU_TYPE(Dom.generateId()); 6618 6619 oConfig.setProperty("submenu", oMenu); 6620 6621 for(n=0; n<nOptions; n++) { 6622 6623 oMenu.addItem((new oMenu.ITEM_TYPE(aOptions[n]))); 6624 6625 } 6626 6627 } 6628 6629 } 6630 6631 } 6632 6633 }, 6634 6635 6636 6637 // Event handlers for configuration properties 6638 6639 6640 /** 6641 * @method configText
6642 * @description Event handler for when the "text" configuration property of 6643 * the menu item changes. 6644 * @param {String} p_sType String representing the name of the event that 6645 * was fired. 6646 * @param {Array} p_aArgs Array of arguments sent when the event was fired. 6647 * @param {YAHOO.widget.MenuItem} p_oItem Object representing the menu item 6648 * that fired the event. 6649 */ 6650 configText: function (p_sType, p_aArgs, p_oItem) { 6651 6652 var sText = p_aArgs[0], 6653 oConfig = this.cfg, 6654 oAnchor = this._oAnchor, 6655 sHelpText = oConfig.getProperty("helptext"), 6656 sHelpTextHTML = "", 6657 sEmphasisStartTag = "", 6658 sEmphasisEndTag = ""; 6659 6660 6661 if (sText) { 6662 6663 6664 if (sHelpText) { 6665 6666 sHelpTextHTML = "<em class=\"helptext\">" + sHelpText + "</em>"; 6667 6668 } 6669 6670 6671 if (oConfig.getProperty("emphasis")) { 6672 6673 sEmphasisStartTag = "<em>"; 6674 sEmphasisEndTag = "</em>"; 6675 6676 } 6677 6678 6679 if (oConfig.getProperty("strongemphasis")) { 6680 6681 sEmphasisStartTag = "<strong>"; 6682 sEmphasisEndTag = "</strong>"; 6683 6684 } 6685 6686 6687 oAnchor.innerHTML = (sEmphasisStartTag + sText + 6688 sEmphasisEndTag + sHelpTextHTML); 6689 6690 } 6691 6692 }, 6693 6694 6695 /** 6696 * @method configHelpText 6697 * @description Event handler for when the "helptext" configuration property 6698 * of the menu item changes. 6699 * @param {String} p_sType String representing the name of the event that 6700 * was fired. 6701 * @param {Array} p_aArgs Array of arguments sent when the event was fired. 6702 * @param {YAHOO.widget.MenuItem} p_oItem Object representing the menu item 6703 * that fired the event. 6704 */ 6705 configHelpText: function (p_sType, p_aArgs, p_oItem) { 6706 6707 this.cfg.refireEvent("text"); 6708 6709 }, 6710 6711 6712 /** 6713 * @method configURL 6714 * @description Event handler for when the "url" configuration property of 6715 * the menu item changes. 6716 * @param {String} p_sType String representing the name of the event that 6717 * was fired. 6718 * @param {Array} p_aArgs Array of arguments sent when the event was fired. 6719 * @param {YAHOO.widget.MenuItem} p_oItem Object representing the menu item 6720 * that fired the event. 6721 */ 6722 configURL: function (p_sType, p_aArgs, p_oItem) { 6723 6724 var sURL = p_aArgs[0]; 6725 6726 if (!sURL) { 6727 6728 sURL = "#"; 6729 6730 } 6731 6732 var oAnchor = this._oAnchor; 6733 6734 if (YAHOO.env.ua.opera) { 6735 6736 oAnchor.removeAttribute("href"); 6737 6738 } 6739 6740 oAnchor.setAttribute("href", sURL); 6741 6742 }, 6743 6744 6745 /** 6746 * @method configTarget 6747 * @description Event handler for when the "target" configuration property 6748 * of the menu item changes. 6749 * @param {String} p_sType String representing the name of the event that 6750 * was fired. 6751 * @param {Array} p_aArgs Array of arguments sent when the event was fired. 6752 * @param {YAHOO.widget.MenuItem} p_oItem Object representing the menu item 6753 * that fired the event. 6754 */ 6755 configTarget: function (p_sType, p_aArgs, p_oItem) { 6756 6757 var sTarget = p_aArgs[0], 6758 oAnchor = this._oAnchor; 6759 6760 if (sTarget && sTarget.length > 0) { 6761 6762 oAnchor.setAttribute("target", sTarget); 6763 6764 } 6765 else { 6766 6767 oAnchor.removeAttribute("target"); 6768 6769 } 6770 6771 }, 6772 6773 6774 /** 6775 * @method configEmphasis 6776 * @description Event handler for when the "emphasis" configuration property 6777 * of the menu item changes. 6778 * @param {String} p_sType String representing the name of the event that 6779 * was fired. 6780 * @param {Array} p_aArgs Array of arguments sent when the event was fired. 6781 * @param {YAHOO.widget.MenuItem} p_oItem Object representing the menu item 6782 * that fired the event. 6783 */ 6784 configEmphasis: function (p_sType, p_aArgs, p_oItem) { 6785 6786 var bEmphasis = p_aArgs[0], 6787 oConfig = this.cfg; 6788 6789 6790 if (bEmphasis && oConfig.getProperty("strongemphasis")) { 6791 6792 oConfig.setProperty("strongemphasis", false); 6793 6794 } 6795 6796 6797 oConfig.refireEvent("text"); 6798 6799 }, 6800 6801 6802 /** 6803 * @method configStrongEmphasis
6804 * @description Event handler for when the "strongemphasis" configuration 6805 * property of the menu item changes. 6806 * @param {String} p_sType String representing the name of the event that 6807 * was fired. 6808 * @param {Array} p_aArgs Array of arguments sent when the event was fired. 6809 * @param {YAHOO.widget.MenuItem} p_oItem Object representing the menu item 6810 * that fired the event. 6811 */ 6812 configStrongEmphasis: function (p_sType, p_aArgs, p_oItem) { 6813 6814 var bStrongEmphasis = p_aArgs[0], 6815 oConfig = this.cfg; 6816 6817 6818 if (bStrongEmphasis && oConfig.getProperty("emphasis")) { 6819 6820 oConfig.setProperty("emphasis", false); 6821 6822 } 6823 6824 oConfig.refireEvent("text"); 6825 6826 }, 6827 6828 6829 /** 6830 * @method configChecked 6831 * @description Event handler for when the "checked" configuration property 6832 * of the menu item changes. 6833 * @param {String} p_sType String representing the name of the event that 6834 * was fired. 6835 * @param {Array} p_aArgs Array of arguments sent when the event was fired. 6836 * @param {YAHOO.widget.MenuItem} p_oItem Object representing the menu item 6837 * that fired the event. 6838 */ 6839 configChecked: function (p_sType, p_aArgs, p_oItem) { 6840 6841 var bChecked = p_aArgs[0], 6842 oElement = this.element, 6843 oAnchor = this._oAnchor, 6844 oConfig = this.cfg, 6845 sState = "-checked", 6846 sClassName = this.CSS_CLASS_NAME + sState, 6847 sLabelClassName = this.CSS_LABEL_CLASS_NAME + sState; 6848 6849 6850 if (bChecked) { 6851 6852 Dom.addClass(oElement, sClassName); 6853 Dom.addClass(oAnchor, sLabelClassName); 6854 6855 } 6856 else { 6857 6858 Dom.removeClass(oElement, sClassName); 6859 Dom.removeClass(oAnchor, sLabelClassName); 6860 6861 } 6862 6863 6864 oConfig.refireEvent("text"); 6865 6866 6867 if (oConfig.getProperty("disabled")) { 6868 6869 oConfig.refireEvent("disabled"); 6870 6871 } 6872 6873 6874 if (oConfig.getProperty("selected")) { 6875 6876 oConfig.refireEvent("selected"); 6877 6878 } 6879 6880 }, 6881 6882 6883 6884 /** 6885 * @method configDisabled 6886 * @description Event handler for when the "disabled" configuration property 6887 * of the menu item changes. 6888 * @param {String} p_sType String representing the name of the event that 6889 * was fired. 6890 * @param {Array} p_aArgs Array of arguments sent when the event was fired. 6891 * @param {YAHOO.widget.MenuItem} p_oItem Object representing the menu item 6892 * that fired the event. 6893 */ 6894 configDisabled: function (p_sType, p_aArgs, p_oItem) { 6895 6896 var bDisabled = p_aArgs[0], 6897 oConfig = this.cfg, 6898 oSubmenu = oConfig.getProperty("submenu"), 6899 bChecked = oConfig.getProperty("checked"), 6900 oElement = this.element, 6901 oAnchor = this._oAnchor, 6902 sState = "-disabled", 6903 sCheckedState = "-checked" + sState, 6904 sSubmenuState = "-hassubmenu" + sState, 6905 sClassName = this.CSS_CLASS_NAME + sState, 6906 sLabelClassName = this.CSS_LABEL_CLASS_NAME + sState, 6907 sCheckedClassName = this.CSS_CLASS_NAME + sCheckedState, 6908 sLabelCheckedClassName = this.CSS_LABEL_CLASS_NAME + sCheckedState, 6909 sSubmenuClassName = this.CSS_CLASS_NAME + sSubmenuState, 6910 sLabelSubmenuClassName = this.CSS_LABEL_CLASS_NAME + sSubmenuState; 6911 6912 6913 if (bDisabled) { 6914 6915 if (oConfig.getProperty("selected")) { 6916 6917 oConfig.setProperty("selected", false); 6918 6919 } 6920 6921 Dom.addClass(oElement, sClassName); 6922 Dom.addClass(oAnchor, sLabelClassName); 6923 6924 6925 if (oSubmenu) { 6926 6927 Dom.addClass(oElement, sSubmenuClassName); 6928 Dom.addClass(oAnchor, sLabelSubmenuClassName); 6929 6930 } 6931 6932 6933 if (bChecked) { 6934 6935 Dom.addClass(oElement, sCheckedClassName); 6936 Dom.addClass(oAnchor, sLabelCheckedClassName); 6937 6938 } 6939 6940 } 6941 else { 6942 6943 Dom.removeClass(oElement, sClassName); 6944 Dom.removeClass(oAnchor, sLabelClassName); 6945 6946 6947 if (oSubmenu) { 6948 6949 Dom.removeClass(oElement, sSubmenuClassName); 6950 Dom.removeClass(oAnchor, sLabelSubmenuClassName); 6951 6952 } 6953 6954 6955 if (bChecked) { 6956 6957 Dom.removeClass(oElement, sCheckedClassName); 6958 Dom.removeClass(oAnchor, sLabelCheckedClassName); 6959 6960 } 6961 6962 } 6963 6964 }, 6965 6966 6967 /** 6968 * @method configSelected
6969 * @description Event handler for when the "selected" configuration property 6970 * of the menu item changes. 6971 * @param {String} p_sType String representing the name of the event that 6972 * was fired. 6973 * @param {Array} p_aArgs Array of arguments sent when the event was fired. 6974 * @param {YAHOO.widget.MenuItem} p_oItem Object representing the menu item 6975 * that fired the event. 6976 */ 6977 configSelected: function (p_sType, p_aArgs, p_oItem) { 6978 6979 var oConfig = this.cfg, 6980 bSelected = p_aArgs[0], 6981 oElement = this.element, 6982 oAnchor = this._oAnchor, 6983 bChecked = oConfig.getProperty("checked"), 6984 oSubmenu = oConfig.getProperty("submenu"), 6985 sState = "-selected", 6986 sCheckedState = "-checked" + sState, 6987 sSubmenuState = "-hassubmenu" + sState, 6988 sClassName = this.CSS_CLASS_NAME + sState, 6989 sLabelClassName = this.CSS_LABEL_CLASS_NAME + sState, 6990 sCheckedClassName = this.CSS_CLASS_NAME + sCheckedState, 6991 sLabelCheckedClassName = this.CSS_LABEL_CLASS_NAME + sCheckedState, 6992 sSubmenuClassName = this.CSS_CLASS_NAME + sSubmenuState, 6993 sLabelSubmenuClassName = this.CSS_LABEL_CLASS_NAME + sSubmenuState; 6994 6995 6996 if (YAHOO.env.ua.opera) { 6997 6998 oAnchor.blur(); 6999 7000 } 7001 7002 7003 if (bSelected && !oConfig.getProperty("disabled")) { 7004 7005 Dom.addClass(oElement, sClassName); 7006 Dom.addClass(oAnchor, sLabelClassName); 7007 7008 7009 if (oSubmenu) { 7010 7011 Dom.addClass(oElement, sSubmenuClassName); 7012 Dom.addClass(oAnchor, sLabelSubmenuClassName); 7013 7014 } 7015 7016 7017 if (bChecked) { 7018 7019 Dom.addClass(oElement, sCheckedClassName); 7020 Dom.addClass(oAnchor, sLabelCheckedClassName); 7021 7022 } 7023 7024 } 7025 else { 7026 7027 Dom.removeClass(oElement, sClassName); 7028 Dom.removeClass(oAnchor, sLabelClassName); 7029 7030 7031 if (oSubmenu) { 7032 7033 Dom.removeClass(oElement, sSubmenuClassName); 7034 Dom.removeClass(oAnchor, sLabelSubmenuClassName); 7035 7036 } 7037 7038 7039 if (bChecked) { 7040 7041 Dom.removeClass(oElement, sCheckedClassName); 7042 Dom.removeClass(oAnchor, sLabelCheckedClassName); 7043 7044 } 7045 7046 } 7047 7048 7049 if (this.hasFocus() && YAHOO.env.ua.opera) { 7050 7051 oAnchor.focus(); 7052 7053 } 7054 7055 }, 7056 7057 7058 /** 7059 * @method _onSubmenuBeforeHide 7060 * @description "beforehide" Custom Event handler for a submenu. 7061 * @private 7062 * @param {String} p_sType String representing the name of the event that 7063 * was fired. 7064 * @param {Array} p_aArgs Array of arguments sent when the event was fired. 7065 */ 7066 _onSubmenuBeforeHide: function (p_sType, p_aArgs) { 7067 7068 var oItem = this.parent, 7069 oMenu; 7070 7071 function onHide() { 7072 7073 oItem._oAnchor.blur(); 7074 oMenu.beforeHideEvent.unsubscribe(onHide); 7075 7076 } 7077 7078 7079 if (oItem.hasFocus()) { 7080 7081 oMenu = oItem.parent; 7082 7083 oMenu.beforeHideEvent.subscribe(onHide); 7084 7085 } 7086 7087 }, 7088 7089 7090 /** 7091 * @method configSubmenu 7092 * @description Event handler for when the "submenu" configuration property 7093 * of the menu item changes. 7094 * @param {String} p_sType String representing the name of the event that 7095 * was fired. 7096 * @param {Array} p_aArgs Array of arguments sent when the event was fired. 7097 * @param {YAHOO.widget.MenuItem} p_oItem Object representing the menu item 7098 * that fired the event. 7099 */ 7100 configSubmenu: function (p_sType, p_aArgs, p_oItem) { 7101 7102 var oSubmenu = p_aArgs[0], 7103 oConfig = this.cfg, 7104 oElement = this.element, 7105 oAnchor = this._oAnchor, 7106 bLazyLoad = this.parent && this.parent.lazyLoad, 7107 sState = "-hassubmenu", 7108 sClassName = this.CSS_CLASS_NAME + sState, 7109 sLabelClassName = this.CSS_LABEL_CLASS_NAME + sState, 7110 oMenu, 7111 sSubmenuId, 7112 oSubmenuConfig; 7113 7114 7115 if (oSubmenu) { 7116 7117 if (oSubmenu instanceof Menu) { 7118 7119 oMenu = oSubmenu;
7120 oMenu.parent = this; 7121 oMenu.lazyLoad = bLazyLoad; 7122 7123 } 7124 else if (typeof oSubmenu == "object" && oSubmenu.id && 7125 !oSubmenu.nodeType) { 7126 7127 sSubmenuId = oSubmenu.id; 7128 oSubmenuConfig = oSubmenu; 7129 7130 oSubmenuConfig.lazyload = bLazyLoad; 7131 oSubmenuConfig.parent = this; 7132 7133 oMenu = new this.SUBMENU_TYPE(sSubmenuId, oSubmenuConfig); 7134 7135 7136 // Set the value of the property to the Menu instance 7137 7138 oConfig.setProperty("submenu", oMenu, true); 7139 7140 } 7141 else { 7142 7143 oMenu = new this.SUBMENU_TYPE(oSubmenu, 7144 { lazyload: bLazyLoad, parent: this }); 7145 7146 7147 // Set the value of the property to the Menu instance 7148 7149 oConfig.setProperty("submenu", oMenu, true); 7150 7151 } 7152 7153 7154 if (oMenu) { 7155 7156 Dom.addClass(oElement, sClassName); 7157 Dom.addClass(oAnchor, sLabelClassName); 7158 7159 this._oSubmenu = oMenu; 7160 7161 if (YAHOO.env.ua.opera) { 7162 7163 oMenu.beforeHideEvent.subscribe(this._onSubmenuBeforeHide); 7164 7165 } 7166 7167 } 7168 7169 } 7170 else { 7171 7172 Dom.removeClass(oElement, sClassName); 7173 Dom.removeClass(oAnchor, sLabelClassName); 7174 7175 if (this._oSubmenu) { 7176 7177 this._oSubmenu.destroy(); 7178 7179 } 7180 7181 } 7182 7183 7184 if (oConfig.getProperty("disabled")) { 7185 7186 oConfig.refireEvent("disabled"); 7187 7188 } 7189 7190 7191 if (oConfig.getProperty("selected")) { 7192 7193 oConfig.refireEvent("selected"); 7194 7195 } 7196 7197 }, 7198 7199 7200 /** 7201 * @method configOnClick 7202 * @description Event handler for when the "onclick" configuration property 7203 * of the menu item changes. 7204 * @param {String} p_sType String representing the name of the event that 7205 * was fired. 7206 * @param {Array} p_aArgs Array of arguments sent when the event was fired. 7207 * @param {YAHOO.widget.MenuItem} p_oItem Object representing the menu item 7208 * that fired the event. 7209 */ 7210 configOnClick: function (p_sType, p_aArgs, p_oItem) { 7211 7212 var oObject = p_aArgs[0]; 7213 7214 /* 7215 Remove any existing listeners if a "click" event handler has 7216 already been specified. 7217 */ 7218 7219 if (this._oOnclickAttributeValue && 7220 (this._oOnclickAttributeValue != oObject)) { 7221 7222 this.clickEvent.unsubscribe(this._oOnclickAttributeValue.fn, 7223 this._oOnclickAttributeValue.obj); 7224 7225 this._oOnclickAttributeValue = null; 7226 7227 } 7228 7229 7230 if (!this._oOnclickAttributeValue && typeof oObject == "object" && 7231 typeof oObject.fn == "function") { 7232 7233 this.clickEvent.subscribe(oObject.fn, 7234 ((!YAHOO.lang.isUndefined(oObject.obj)) ? oObject.obj : this), 7235 oObject.scope); 7236 7237 this._oOnclickAttributeValue = oObject; 7238 7239 } 7240 7241 }, 7242 7243 7244 /** 7245 * @method configClassName 7246 * @description Event handler for when the "classname" configuration 7247 * property of a menu item changes. 7248 * @param {String} p_sType String representing the name of the event that 7249 * was fired. 7250 * @param {Array} p_aArgs Array of arguments sent when the event was fired. 7251 * @param {YAHOO.widget.MenuItem} p_oItem Object representing the menu item 7252 * that fired the event. 7253 */ 7254 configClassName: function (p_sType, p_aArgs, p_oItem) { 7255 7256 var sClassName = p_aArgs[0]; 7257 7258 if (this._sClassName) { 7259 7260 Dom.removeClass(this.element, this._sClassName); 7261 7262 } 7263 7264 Dom.addClass(this.element, sClassName); 7265 this._sClassName = sClassName; 7266 7267 }, 7268 7269 7270 7271 // Public methods 7272 7273 7274 /** 7275 * @method initDefaultConfig 7276 * @description Initializes an item's configurable properties. 7277 */ 7278 initDefaultConfig : function () { 7279 7280 var oConfig = this.cfg; 7281 7282 7283 // Define the configuration attributes 7284 7285 /** 7286 * @config text
7287 * @description String specifying the text label for the menu item. 7288 * When building a menu from existing HTML the value of this property 7289 * will be interpreted from the menu's markup. 7290 * @default "" 7291 * @type String 7292 */ 7293 oConfig.addProperty( 7294 DEFAULT_CONFIG.TEXT.key, 7295 { 7296 handler: this.configText, 7297 value: DEFAULT_CONFIG.TEXT.value, 7298 validator: DEFAULT_CONFIG.TEXT.validator, 7299 suppressEvent: DEFAULT_CONFIG.TEXT.suppressEvent 7300 } 7301 ); 7302 7303 7304 /** 7305 * @config helptext 7306 * @description String specifying additional instructional text to 7307 * accompany the text for the menu item. 7308 * @deprecated Use "text" configuration property to add help text markup. 7309 * For example: <code>oMenuItem.cfg.setProperty("text", "Copy <em 7310 * class=\"helptext\">Ctrl + C</em>");</code> 7311 * @default null 7312 * @type String|<a href="http://www.w3.org/TR/ 7313 * 2000/WD-DOM-Level-1-20000929/level-one-html.html#ID-58190037"> 7314 * HTMLElement</a> 7315 */ 7316 oConfig.addProperty( 7317 DEFAULT_CONFIG.HELP_TEXT.key, 7318 { 7319 handler: this.configHelpText, 7320 supercedes: DEFAULT_CONFIG.HELP_TEXT.supercedes, 7321 suppressEvent: DEFAULT_CONFIG.HELP_TEXT.suppressEvent 7322 } 7323 ); 7324 7325 7326 /** 7327 * @config url 7328 * @description String specifying the URL for the menu item's anchor's 7329 * "href" attribute. When building a menu from existing HTML the value 7330 * of this property will be interpreted from the menu's markup. 7331 * @default "#"
7332 * @type String 7333 */ 7334 oConfig.addProperty( 7335 DEFAULT_CONFIG.URL.key, 7336 { 7337 handler: this.configURL, 7338 value: DEFAULT_CONFIG.URL.value, 7339 suppressEvent: DEFAULT_CONFIG.URL.suppressEvent 7340 } 7341 ); 7342 7343 7344 /** 7345 * @config target 7346 * @description String specifying the value for the "target" attribute 7347 * of the menu item's anchor element. <strong>Specifying a target will 7348 * require the user to click directly on the menu item's anchor node in 7349 * order to cause the browser to navigate to the specified URL.</strong> 7350 * When building a menu from existing HTML the value of this property 7351 * will be interpreted from the menu's markup. 7352 * @default null 7353 * @type String 7354 */ 7355 oConfig.addProperty( 7356 DEFAULT_CONFIG.TARGET.key, 7357 { 7358 handler: this.configTarget, 7359 suppressEvent: DEFAULT_CONFIG.TARGET.suppressEvent 7360 } 7361 ); 7362 7363 7364 /** 7365 * @config emphasis 7366 * @description Boolean indicating if the text of the menu item will be 7367 * rendered with emphasis. 7368 * @deprecated Use "text" configuration property to add emphasis. 7369 * For example: <code>oMenuItem.cfg.setProperty("text", "<em>Some 7370 * Text</em>");</code> 7371 * @default false 7372 * @type Boolean 7373 */ 7374 oConfig.addProperty( 7375 DEFAULT_CONFIG.EMPHASIS.key, 7376 { 7377 handler: this.configEmphasis, 7378 value: DEFAULT_CONFIG.EMPHASIS.value, 7379 validator: DEFAULT_CONFIG.EMPHASIS.validator, 7380 suppressEvent: DEFAULT_CONFIG.EMPHASIS.suppressEvent, 7381 supercedes: DEFAULT_CONFIG.EMPHASIS.supercedes 7382 } 7383 ); 7384 7385 7386 /** 7387 * @config strongemphasis 7388 * @description Boolean indicating if the text of the menu item will be 7389 * rendered with strong emphasis. 7390 * @deprecated Use "text" configuration property to add strong emphasis. 7391 * For example: <code>oMenuItem.cfg.setProperty("text", "<strong> 7392 * Some Text</strong>");</code> 7393 * @default false 7394 * @type Boolean 7395 */ 7396 oConfig.addProperty( 7397 DEFAULT_CONFIG.STRONG_EMPHASIS.key, 7398 { 7399 handler: this.configStrongEmphasis, 7400 value: DEFAULT_CONFIG.STRONG_EMPHASIS.value, 7401 validator: DEFAULT_CONFIG.STRONG_EMPHASIS.validator, 7402 suppressEvent: DEFAULT_CONFIG.STRONG_EMPHASIS.suppressEvent, 7403 supercedes: DEFAULT_CONFIG.STRONG_EMPHASIS.supercedes 7404 } 7405 ); 7406 7407 7408 /** 7409 * @config checked 7410 * @description Boolean indicating if the menu item should be rendered 7411 * with a checkmark. 7412 * @default false 7413 * @type Boolean 7414 */ 7415 oConfig.addProperty( 7416 DEFAULT_CONFIG.CHECKED.key, 7417 { 7418 handler: this.configChecked, 7419 value: DEFAULT_CONFIG.CHECKED.value, 7420 validator: DEFAULT_CONFIG.CHECKED.validator, 7421 suppressEvent: DEFAULT_CONFIG.CHECKED.suppressEvent, 7422 supercedes: DEFAULT_CONFIG.CHECKED.supercedes 7423 } 7424 ); 7425 7426 7427 /** 7428 * @config disabled 7429 * @description Boolean indicating if the menu item should be disabled. 7430 * (Disabled menu items are dimmed and will not respond to user input 7431 * or fire events.) 7432 * @default false 7433 * @type Boolean 7434 */ 7435 oConfig.addProperty( 7436 DEFAULT_CONFIG.DISABLED.key, 7437 { 7438 handler: this.configDisabled, 7439 value: DEFAULT_CONFIG.DISABLED.value, 7440 validator: DEFAULT_CONFIG.DISABLED.validator, 7441 suppressEvent: DEFAULT_CONFIG.DISABLED.suppressEvent 7442 } 7443 ); 7444 7445 7446 /** 7447 * @config selected 7448 * @description Boolean indicating if the menu item should 7449 * be highlighted. 7450 * @default false 7451 * @type Boolean 7452 */ 7453 oConfig.addProperty( 7454 DEFAULT_CONFIG.SELECTED.key, 7455 { 7456 handler: this.configSelected, 7457 value: DEFAULT_CONFIG.SELECTED.value, 7458 validator: DEFAULT_CONFIG.SELECTED.validator, 7459 suppressEvent: DEFAULT_CONFIG.SELECTED.suppressEvent 7460 } 7461 ); 7462 7463 7464 /** 7465 * @config submenu
7466 * @description Object specifying the submenu to be appended to the 7467 * menu item. The value can be one of the following: <ul><li>Object 7468 * specifying a Menu instance.</li><li>Object literal specifying the 7469 * menu to be created. Format: <code>{ id: [menu id], itemdata: 7470 * [<a href="YAHOO.widget.Menu.html#itemData">array of values for 7471 * items</a>] }</code>.</li><li>String specifying the id attribute 7472 * of the <code><div></code> element of the menu.</li><li> 7473 * Object specifying the <code><div></code> element of the 7474 * menu.</li></ul> 7475 * @default null 7476 * @type Menu|String|Object|<a href="http://www.w3.org/TR/2000/ 7477 * WD-DOM-Level-1-20000929/level-one-html.html#ID-58190037"> 7478 * HTMLElement</a> 7479 */ 7480 oConfig.addProperty( 7481 DEFAULT_CONFIG.SUBMENU.key, 7482 { 7483 handler: this.configSubmenu, 7484 supercedes: DEFAULT_CONFIG.SUBMENU.supercedes, 7485 suppressEvent: DEFAULT_CONFIG.SUBMENU.suppressEvent 7486 } 7487 ); 7488 7489 7490 /** 7491 * @config onclick 7492 * @description Object literal representing the code to be executed when 7493 * the item is clicked. Format:<br> <code> {<br> 7494 * <strong>fn:</strong> Function, // The handler to call when 7495 * the event fires.<br> <strong>obj:</strong> Object, // An 7496 * object to pass back to the handler.<br> <strong>scope:</strong> 7497 * Object // The object to use for the scope of the handler. 7498 * <br> } </code> 7499 * @type Object 7500 * @default null 7501 */ 7502 oConfig.addProperty( 7503 DEFAULT_CONFIG.ONCLICK.key, 7504 { 7505 handler: this.configOnClick, 7506 suppressEvent: DEFAULT_CONFIG.ONCLICK.suppressEvent 7507 } 7508 ); 7509 7510 7511 /** 7512 * @config classname 7513 * @description CSS class to be applied to the menu item's root 7514 * <code><li></code> element. The specified class(es) are 7515 * appended in addition to the default class as specified by the menu 7516 * item's CSS_CLASS_NAME constant. 7517 * @default null
7518 * @type String 7519 */ 7520 oConfig.addProperty( 7521 DEFAULT_CONFIG.CLASS_NAME.key, 7522 { 7523 handler: this.configClassName, 7524 value: DEFAULT_CONFIG.CLASS_NAME.value, 7525 validator: DEFAULT_CONFIG.CLASS_NAME.validator, 7526 suppressEvent: DEFAULT_CONFIG.CLASS_NAME.suppressEvent 7527 } 7528 ); 7529 7530 }, 7531 7532 7533 /** 7534 * @method getNextEnabledSibling 7535 * @description Finds the menu item's next enabled sibling. 7536 * @return YAHOO.widget.MenuItem 7537 */ 7538 getNextEnabledSibling: function () { 7539 7540 var nGroupIndex, 7541 aItemGroups, 7542 oNextItem, 7543 nNextGroupIndex, 7544 aNextGroup; 7545 7546 function getNextArrayItem(p_aArray, p_nStartIndex) { 7547 7548 return p_aArray[p_nStartIndex] || 7549 getNextArrayItem(p_aArray, (p_nStartIndex+1)); 7550 7551 } 7552 7553 if (this.parent instanceof Menu) { 7554 7555 nGroupIndex = this.groupIndex; 7556 7557 aItemGroups = this.parent.getItemGroups(); 7558 7559 if (this.index < (aItemGroups[nGroupIndex].length - 1)) { 7560 7561 oNextItem = getNextArrayItem(aItemGroups[nGroupIndex], 7562 (this.index+1)); 7563 7564 } 7565 else { 7566 7567 if (nGroupIndex < (aItemGroups.length - 1)) { 7568 7569 nNextGroupIndex = nGroupIndex + 1; 7570 7571 } 7572 else { 7573 7574 nNextGroupIndex = 0; 7575 7576 } 7577 7578 aNextGroup = getNextArrayItem(aItemGroups, nNextGroupIndex); 7579 7580 // Retrieve the first menu item in the next group 7581 7582 oNextItem = getNextArrayItem(aNextGroup, 0); 7583 7584 } 7585 7586 return (oNextItem.cfg.getProperty("disabled") || 7587 oNextItem.element.style.display == "none") ? 7588 oNextItem.getNextEnabledSibling() : oNextItem; 7589 7590 } 7591 7592 }, 7593 7594 7595 /** 7596 * @method getPreviousEnabledSibling 7597 * @description Finds the menu item's previous enabled sibling. 7598 * @return {YAHOO.widget.MenuItem} 7599 */ 7600 getPreviousEnabledSibling: function () { 7601 7602 var nGroupIndex, 7603 aItemGroups, 7604 oPreviousItem, 7605 nPreviousGroupIndex, 7606 aPreviousGroup; 7607 7608 function getPreviousArrayItem(p_aArray, p_nStartIndex) { 7609 7610 return p_aArray[p_nStartIndex] || 7611 getPreviousArrayItem(p_aArray, (p_nStartIndex-1)); 7612 7613 } 7614 7615 function getFirstItemIndex(p_aArray, p_nStartIndex) { 7616 7617 return p_aArray[p_nStartIndex] ? p_nStartIndex : 7618 getFirstItemIndex(p_aArray, (p_nStartIndex+1)); 7619 7620 } 7621 7622 if (this.parent instanceof Menu) { 7623 7624 nGroupIndex = this.groupIndex; 7625 aItemGroups = this.parent.getItemGroups(); 7626 7627 7628 if (this.index > getFirstItemIndex(aItemGroups[nGroupIndex], 0)) { 7629 7630 oPreviousItem = getPreviousArrayItem(aItemGroups[nGroupIndex], 7631 (this.index-1)); 7632 7633 } 7634 else { 7635 7636 if (nGroupIndex > getFirstItemIndex(aItemGroups, 0)) { 7637 7638 nPreviousGroupIndex = nGroupIndex - 1; 7639 7640 } 7641 else { 7642 7643 nPreviousGroupIndex = aItemGroups.length - 1; 7644 7645 } 7646 7647 aPreviousGroup = getPreviousArrayItem(aItemGroups, 7648 nPreviousGroupIndex); 7649 7650 oPreviousItem = getPreviousArrayItem(aPreviousGroup, 7651 (aPreviousGroup.length - 1)); 7652 7653 } 7654 7655 return (oPreviousItem.cfg.getProperty("disabled") || 7656 oPreviousItem.element.style.display == "none") ? 7657 oPreviousItem.getPreviousEnabledSibling() : oPreviousItem; 7658 7659 } 7660 7661 }, 7662 7663 7664 /** 7665 * @method focus 7666 * @description Causes the menu item to receive the focus and fires the 7667 * focus event. 7668 */ 7669 focus: function () { 7670 7671 var oParent = this.parent, 7672 oAnchor = this._oAnchor, 7673 oActiveItem = oParent.activeItem, 7674 me = this; 7675 7676 7677 function setFocus() { 7678 7679 try { 7680 7681 if (YAHOO.env.ua.ie && !document.hasFocus()) { 7682 7683 return; 7684 7685 } 7686 7687 if (oActiveItem) { 7688 7689 oActiveItem.blurEvent.fire(); 7690 7691 } 7692 7693 oAnchor.focus(); 7694 7695 me.focusEvent.fire(); 7696 7697 } 7698 catch(e) { 7699 7700 } 7701 7702 } 7703 7704 7705 if (!this.cfg.getProperty("disabled") && oParent && 7706 oParent.cfg.getProperty("visible") && 7707 this.element.style.display != "none") { 7708 7709 7710 /* 7711 Setting focus via a timer fixes a race condition in Firefox, IE 7712 and Opera where the browser viewport jumps as it trys to 7713 position and focus the menu. 7714 */ 7715 7716 window.setTimeout(setFocus, 0); 7717 7718 } 7719 7720 }, 7721 7722 7723 /** 7724 * @method blur
7725 * @description Causes the menu item to lose focus and fires the 7726 * blur event. 7727 */ 7728 blur: function () { 7729 7730 var oParent = this.parent; 7731 7732 if (!this.cfg.getProperty("disabled") && oParent && 7733 oParent.cfg.getProperty("visible")) { 7734 7735 7736 var me = this; 7737 7738 window.setTimeout(function () { 7739 7740 try { 7741 7742 me._oAnchor.blur(); 7743 me.blurEvent.fire(); 7744 7745 } 7746 catch (e) { 7747 7748 } 7749 7750 }, 0); 7751 7752 } 7753 7754 }, 7755 7756 7757 /** 7758 * @method hasFocus 7759 * @description Returns a boolean indicating whether or not the menu item 7760 * has focus. 7761 * @return {Boolean} 7762 */ 7763 hasFocus: function () { 7764 7765 return (YAHOO.widget.MenuManager.getFocusedMenuItem() == this); 7766 7767 }, 7768 7769 7770 /** 7771 * @method destroy 7772 * @description Removes the menu item's <code><li></code> element 7773 * from its parent <code><ul></code> element. 7774 */ 7775 destroy: function () { 7776 7777 var oEl = this.element, 7778 oSubmenu, 7779 oParentNode; 7780 7781 if (oEl) { 7782 7783 7784 // If the item has a submenu, destroy it first 7785 7786 oSubmenu = this.cfg.getProperty("submenu"); 7787 7788 if (oSubmenu) { 7789 7790 oSubmenu.destroy(); 7791 7792 } 7793 7794 7795 // Remove CustomEvent listeners 7796 7797 this.mouseOverEvent.unsubscribeAll(); 7798 this.mouseOutEvent.unsubscribeAll(); 7799 this.mouseDownEvent.unsubscribeAll(); 7800 this.mouseUpEvent.unsubscribeAll(); 7801 this.clickEvent.unsubscribeAll(); 7802 this.keyPressEvent.unsubscribeAll(); 7803 this.keyDownEvent.unsubscribeAll(); 7804 this.keyUpEvent.unsubscribeAll(); 7805 this.focusEvent.unsubscribeAll(); 7806 this.blurEvent.unsubscribeAll(); 7807 this.cfg.configChangedEvent.unsubscribeAll(); 7808 7809 7810 // Remove the element from the parent node 7811 7812 oParentNode = oEl.parentNode; 7813 7814 if (oParentNode) { 7815 7816 oParentNode.removeChild(oEl); 7817 7818 this.destroyEvent.fire(); 7819 7820 } 7821 7822 this.destroyEvent.unsubscribeAll(); 7823 7824 } 7825 7826 }, 7827 7828 7829 /** 7830 * @method toString 7831 * @description Returns a string representing the menu item. 7832 * @return {String} 7833 */ 7834 toString: function () { 7835 7836 var sReturnVal = "MenuItem", 7837 sId = this.id; 7838 7839 if (sId) { 7840 7841 sReturnVal += (" " + sId); 7842 7843 } 7844 7845 return sReturnVal; 7846 7847 } 7848 7849}; 7850 7851Lang.augmentProto(MenuItem, YAHOO.util.EventProvider); 7852 7853})(); 7854(function () { 7855 7856 7857/** 7858* Creates a list of options or commands which are made visible in response to 7859* an HTML element's "contextmenu" event ("mousedown" for Opera). 7860* 7861* @param {String} p_oElement String specifying the id attribute of the 7862* <code><div></code> element of the context menu. 7863* @param {String} p_oElement String specifying the id attribute of the 7864* <code><select></code> element to be used as the data source for the 7865* context menu. 7866* @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-one- 7867* html.html#ID-22445964">HTMLDivElement</a>} p_oElement Object specifying the 7868* <code><div></code> element of the context menu. 7869* @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-one- 7870* html.html#ID-94282980">HTMLSelectElement</a>} p_oElement Object specifying 7871* the <code><select></code> element to be used as the data source for 7872* the context menu. 7873* @param {Object} p_oConfig Optional. Object literal specifying the 7874* configuration for the context menu. See configuration class documentation 7875* for more details. 7876* @class ContextMenu 7877* @constructor 7878* @extends YAHOO.widget.Menu 7879* @namespace YAHOO.widget 7880*/ 7881YAHOO.widget.ContextMenu = function(p_oElement, p_oConfig) { 7882 7883 YAHOO.widget.ContextMenu.superclass.constructor.call(this, 7884 p_oElement, p_oConfig); 7885 7886}; 7887 7888 7889var Event = YAHOO.util.Event, 7890 ContextMenu = YAHOO.widget.ContextMenu, 7891 7892 7893 7894 /** 7895 * Constant representing the name of the ContextMenu's events 7896 * @property EVENT_TYPES 7897 * @private 7898 * @final 7899 * @type Object 7900 */ 7901 EVENT_TYPES = { 7902 7903 "TRIGGER_CONTEXT_MENU": "triggerContextMenu", 7904 "CONTEXT_MENU": (YAHOO.env.ua.opera ? "mousedown" : "contextmenu"), 7905 "CLICK": "click" 7906 7907 }, 7908 7909 7910 /** 7911 * Constant representing the ContextMenu's configuration properties 7912 * @property DEFAULT_CONFIG 7913 * @private 7914 * @final 7915 * @type Object 7916 */ 7917 DEFAULT_CONFIG = { 7918 7919 "TRIGGER": { 7920 key: "trigger", 7921 suppressEvent: true 7922 } 7923 7924 }; 7925 7926 7927/** 7928* @method position 7929* @description "beforeShow" event handler used to position the contextmenu. 7930* @private 7931* @param {String}
7931 p_sType String representing the name of the event that 7932* was fired. 7933* @param {Array} p_aArgs Array of arguments sent when the event was fired. 7934* @param {Array} p_aPos Array representing the xy position for the context menu. 7935*/ 7936function position(p_sType, p_aArgs, p_aPos) { 7937 7938 this.cfg.setProperty("xy", p_aPos); 7939 7940 this.beforeShowEvent.unsubscribe(position, p_aPos); 7941 7942} 7943 7944 7945YAHOO.lang.extend(ContextMenu, YAHOO.widget.Menu, { 7946 7947 7948 7949// Private properties 7950 7951 7952/** 7953* @property _oTrigger 7954* @description Object reference to the current value of the "trigger" 7955* configuration property. 7956* @default null 7957* @private 7958* @type String|<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/leve 7959* l-one-html.html#ID-58190037">HTMLElement</a>|Array 7960*/ 7961_oTrigger: null, 7962 7963 7964/** 7965* @property _bCancelled 7966* @description Boolean indicating if the display of the context menu should 7967* be cancelled. 7968* @default false 7969* @private 7970* @type Boolean 7971*/ 7972_bCancelled: false, 7973 7974 7975 7976// Public properties 7977 7978 7979/** 7980* @property contextEventTarget 7981* @description Object reference for the HTML element that was the target of the 7982* "contextmenu" DOM event ("mousedown" for Opera) that triggered the display of 7983* the context menu. 7984* @default null 7985* @type <a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-one- 7986* html.html#ID-58190037">HTMLElement</a> 7987*/ 7988contextEventTarget: null, 7989 7990 7991 7992// Events 7993 7994 7995/** 7996* @event triggerContextMenuEvent 7997* @description Custom Event wrapper for the "contextmenu" DOM event
7998* ("mousedown" for Opera) fired by the element(s) that trigger the display of 7999* the context menu. 8000*/ 8001triggerContextMenuEvent: null, 8002 8003 8004 8005/** 8006* @method init 8007* @description The ContextMenu class's initialization method. This method is 8008* automatically called by the constructor, and sets up all DOM references for 8009* pre-existing markup, and creates required markup if it is not already present. 8010* @param {String} p_oElement String specifying the id attribute of the 8011* <code><div></code> element of the context menu. 8012* @param {String} p_oElement String specifying the id attribute of the 8013* <code><select></code> element to be used as the data source for 8014* the context menu. 8015* @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-one- 8016* html.html#ID-22445964">HTMLDivElement</a>} p_oElement Object specifying the 8017* <code><div></code> element of the context menu. 8018* @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-one- 8019* html.html#ID-94282980">HTMLSelectElement</a>} p_oElement Object specifying 8020* the <code><select></code> element to be used as the data source for 8021* the context menu. 8022* @param {Object} p_oConfig Optional. Object literal specifying the 8023* configuration for the context menu. See configuration class documentation 8024* for more details. 8025*/ 8026init: function(p_oElement, p_oConfig) { 8027 8028 8029 // Call the init of the superclass (YAHOO.widget.Menu) 8030 8031 ContextMenu.superclass.init.call(this, p_oElement); 8032 8033 8034 this.beforeInitEvent.fire(ContextMenu); 8035 8036 8037 if(p_oConfig) { 8038 8039 this.cfg.applyConfig(p_oConfig, true); 8040 8041 } 8042 8043 8044 this.initEvent.fire(ContextMenu); 8045 8046}, 8047 8048 8049/** 8050* @method initEvents 8051* @description Initializes the custom events for the context menu. 8052*/ 8053initEvents: function() { 8054 8055 ContextMenu.superclass.initEvents.call(this); 8056 8057 // Create custom events 8058 8059 this.triggerContextMenuEvent = 8060 this.createEvent(EVENT_TYPES.TRIGGER_CONTEXT_MENU); 8061 8062 this.triggerContextMenuEvent.signature = YAHOO.util.CustomEvent.LIST; 8063 8064}, 8065 8066 8067/** 8068* @method cancel 8069* @description Cancels the display of the context menu. 8070*/ 8071cancel: function() { 8072 8073 this._bCancelled = true; 8074 8075}, 8076 8077 8078 8079// Private methods 8080 8081 8082/** 8083* @method _removeEventHandlers 8084* @description Removes all of the DOM event handlers from the HTML element(s) 8085* whose "context menu" event ("click" for Opera) trigger the display of 8086* the context menu. 8087* @private 8088*/ 8089_removeEventHandlers: function() { 8090 8091 var oTrigger = this._oTrigger; 8092 8093 8094 // Remove the event handlers from the trigger(s) 8095 8096 if (oTrigger) { 8097 8098 Event.removeListener(oTrigger, EVENT_TYPES.CONTEXT_MENU, 8099 this._onTriggerContextMenu); 8100 8101 if(YAHOO.env.ua.opera) { 8102 8103 Event.removeListener(oTrigger, EVENT_TYPES.CLICK, 8104 this._onTriggerClick); 8105 8106 } 8107 8108 } 8109 8110}, 8111 8112 8113 8114// Private event handlers 8115 8116 8117 8118/** 8119* @method _onTriggerClick 8120* @description "click" event handler for the HTML element(s) identified as the 8121* "trigger" for the context menu. Used to cancel default behaviors in Opera. 8122* @private 8123* @param {Event} p_oEvent Object representing the DOM event object passed back 8124* by the event utility (YAHOO.util.Event). 8125* @param {YAHOO.widget.ContextMenu} p_oMenu Object representing the context 8126* menu that is handling the event. 8127*/ 8128_onTriggerClick: function(p_oEvent, p_oMenu) { 8129 8130 if(p_oEvent.ctrlKey) { 8131 8132 Event.stopEvent(p_oEvent); 8133 8134 } 8135 8136}, 8137 8138 8139/** 8140* @method _onTriggerContextMenu 8141* @description "contextmenu" event handler ("mousedown" for Opera) for the HTML 8142* element(s) that trigger the display of the context menu. 8143* @private 8144* @param {Event} p_oEvent Object representing the DOM event object passed back 8145* by the event utility (YAHOO.util.Event). 8146* @param {YAHOO.widget.ContextMenu} p_oMenu Object representing the context 8147* menu that is handling the event. 8148*/ 8149_onTriggerContextMenu: function(p_oEvent, p_oMenu) { 8150 8151 if (p_oEvent.type == "mousedown" && !p_oEvent.ctrlKey) { 8152 8153 return; 8154 8155 } 8156 8157 8158 var aXY; 8159 8160 8161 /* 8162 Prevent the browser's default context menu from appearing and 8163 stop the propagation of the "contextmenu" event so that 8164 other ContextMenu instances are not displayed. 8165 */ 8166 8167 Event.stopEvent(p_oEvent); 8168 8169 8170 this.contextEventTarget = Event.getTarget(p_oEvent); 8171 8172 this.triggerContextMenuEvent.fire(p_oEvent); 8173 8174 8175 // Hide any other Menu instances that might be visible 8176
8177 YAHOO.widget.MenuManager.hideVisible(); 8178 8179 8180 8181 if(!this._bCancelled) { 8182 8183 // Position and display the context menu 8184 8185 aXY = Event.getXY(p_oEvent); 8186 8187 8188 if (!YAHOO.util.Dom.inDocument(this.element)) { 8189 8190 this.beforeShowEvent.subscribe(position, aXY); 8191 8192 } 8193 else { 8194 8195 this.cfg.setProperty("xy", aXY); 8196 8197 } 8198 8199 8200 this.show(); 8201 8202 } 8203 8204 this._bCancelled = false; 8205 8206}, 8207 8208 8209 8210// Public methods 8211 8212 8213/** 8214* @method toString 8215* @description Returns a string representing the context menu. 8216* @return {String} 8217*/ 8218toString: function() { 8219 8220 var sReturnVal = "ContextMenu", 8221 sId = this.id; 8222 8223 if(sId) { 8224 8225 sReturnVal += (" " + sId); 8226 8227 } 8228 8229 return sReturnVal; 8230 8231}, 8232 8233 8234/** 8235* @method initDefaultConfig 8236* @description Initializes the class's configurable properties which can be 8237* changed using the context menu's Config object ("cfg"). 8238*/ 8239initDefaultConfig: function() { 8240 8241 ContextMenu.superclass.initDefaultConfig.call(this); 8242 8243 /** 8244 * @config trigger 8245 * @description The HTML element(s) whose "contextmenu" event ("mousedown" 8246 * for Opera) trigger the display of the context menu. Can be a string 8247 * representing the id attribute of the HTML element, an object reference 8248 * for the HTML element, or an array of strings or HTML element references. 8249 * @default null
8250 * @type String|<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/ 8251 * level-one-html.html#ID-58190037">HTMLElement</a>|Array 8252 */ 8253 this.cfg.addProperty(DEFAULT_CONFIG.TRIGGER.key, 8254 { 8255 handler: this.configTrigger, 8256 suppressEvent: DEFAULT_CONFIG.TRIGGER.suppressEvent 8257 } 8258 ); 8259 8260}, 8261 8262 8263/** 8264* @method destroy 8265* @description Removes the context menu's <code><div></code> element 8266* (and accompanying child nodes) from the document. 8267*/ 8268destroy: function() { 8269 8270 // Remove the DOM event handlers from the current trigger(s) 8271 8272 this._removeEventHandlers(); 8273 8274 8275 // Continue with the superclass implementation of this method 8276 8277 ContextMenu.superclass.destroy.call(this); 8278 8279}, 8280 8281 8282 8283// Public event handlers for configuration properties 8284 8285 8286/** 8287* @method configTrigger 8288* @description Event handler for when the value of the "trigger" configuration 8289* property changes. 8290* @param {String} p_sType String representing the name of the event that 8291* was fired. 8292* @param {Array} p_aArgs Array of arguments sent when the event was fired. 8293* @param {YAHOO.widget.ContextMenu} p_oMenu Object representing the context 8294* menu that fired the event. 8295*/ 8296configTrigger: function(p_sType, p_aArgs, p_oMenu) { 8297 8298 var oTrigger = p_aArgs[0]; 8299 8300 if(oTrigger) { 8301 8302 /* 8303 If there is a current "trigger" - remove the event handlers 8304 from that element(s) before assigning new ones 8305 */ 8306 8307 if(this._oTrigger) { 8308 8309 this._removeEventHandlers(); 8310 8311 } 8312 8313 this._oTrigger = oTrigger; 8314 8315 8316 /* 8317 Listen for the "mousedown" event in Opera b/c it does not 8318 support the "contextmenu" event 8319 */ 8320 8321 Event.on(oTrigger, EVENT_TYPES.CONTEXT_MENU, 8322 this._onTriggerContextMenu, this, true); 8323 8324 8325 /* 8326 Assign a "click" event handler to the trigger element(s) for 8327 Opera to prevent default browser behaviors. 8328 */ 8329 8330 if(YAHOO.env.ua.opera) { 8331 8332 Event.on(oTrigger, EVENT_TYPES.CLICK, this._onTriggerClick, 8333 this, true); 8334 8335 } 8336 8337 } 8338 else { 8339 8340 this._removeEventHandlers(); 8341 8342 } 8343 8344} 8345 8346}); // END YAHOO.lang.extend 8347 8348}()); 8349 8350 8351 8352/** 8353* Creates an item for a context menu. 8354* 8355* @param {String} p_oObject String specifying the text of the context menu item. 8356* @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level- 8357* one-html.html#ID-74680021">HTMLLIElement</a>} p_oObject Object specifying the 8358* <code><li></code> element of the context menu item. 8359* @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level- 8360* one-html.html#ID-38450247">HTMLOptGroupElement</a>} p_oObject Object 8361* specifying the <code><optgroup></code> element of the context 8362* menu item. 8363* @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level- 8364* one-html.html#ID-70901257">HTMLOptionElement</a>} p_oObject Object specifying 8365* the <code><option></code> element of the context menu item. 8366* @param {Object} p_oConfig Optional. Object literal specifying the 8367* configuration for the context menu item. See configuration class 8368* documentation for more details. 8369* @class ContextMenuItem 8370* @constructor 8371* @extends YAHOO.widget.MenuItem 8372* @deprecated As of version 2.4.0 items for YAHOO.widget.ContextMenu instances 8373* are of type YAHOO.widget.MenuItem. 8374*/ 8375YAHOO.widget.ContextMenuItem = YAHOO.widget.MenuItem; 8376(function () { 8377 8378 8379/** 8380* Horizontal collection of items, each of which can contain a submenu. 8381* 8382* @param {String} p_oElement String specifying the id attribute of the 8383* <code><div></code> element of the menu bar. 8384* @param {String} p_oElement String specifying the id attribute of the 8385* <code><select></code> element to be used as the data source for the 8386* menu bar. 8387* @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level- 8388* one-html.html#ID-22445964">HTMLDivElement</a>} p_oElement Object specifying 8389* the <code><div></code> element of the menu bar. 8390* @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level- 8391* one-html.html#ID-94282980">HTMLSelectElement</a>} p_oElement Object 8392* specifying the <code><select></code> element to be used as the data 8393* source for the menu bar. 8394* @param {Object} p_oConfig Optional. Object literal specifying the 8395* configuration for the menu bar. See configuration class documentation for 8396* more details. 8397* @class MenuBar 8398* @constructor
8399* @extends YAHOO.widget.Menu 8400* @namespace YAHOO.widget 8401*/ 8402YAHOO.widget.MenuBar = function(p_oElement, p_oConfig) { 8403 8404 YAHOO.widget.MenuBar.superclass.constructor.call(this, 8405 p_oElement, p_oConfig); 8406 8407}; 8408 8409 8410/** 8411* @method checkPosition 8412* @description Checks to make sure that the value of the "position" property 8413* is one of the supported strings. Returns true if the position is supported. 8414* @private 8415* @param {Object} p_sPosition String specifying the position of the menu. 8416* @return {Boolean} 8417*/ 8418function checkPosition(p_sPosition) { 8419 8420 if (typeof p_sPosition == "string") { 8421 8422 return ("dynamic,static".indexOf((p_sPosition.toLowerCase())) != -1); 8423 8424 } 8425 8426} 8427 8428 8429var Event = YAHOO.util.Event, 8430 MenuBar = YAHOO.widget.MenuBar, 8431 8432 /** 8433 * Constant representing the MenuBar's configuration properties 8434 * @property DEFAULT_CONFIG 8435 * @private 8436 * @final 8437 * @type Object 8438 */ 8439 DEFAULT_CONFIG = { 8440 8441 "POSITION": { 8442 key: "position", 8443 value: "static", 8444 validator: checkPosition, 8445 supercedes: ["visible"] 8446 }, 8447 8448 "SUBMENU_ALIGNMENT": { 8449 key: "submenualignment", 8450 value: ["tl","bl"], 8451 suppressEvent: true 8452 }, 8453 8454 "AUTO_SUBMENU_DISPLAY": { 8455 key: "autosubmenudisplay", 8456 value: false, 8457 validator: YAHOO.lang.isBoolean, 8458 suppressEvent: true 8459 } 8460 8461 }; 8462 8463 8464 8465YAHOO.lang.extend(MenuBar, YAHOO.widget.Menu, { 8466 8467/** 8468* @method init 8469* @description The MenuBar class's initialization method. This method is 8470* automatically called by the constructor, and sets up all DOM references for 8471* pre-existing markup, and creates required markup if it is not already present. 8472* @param {String} p_oElement String specifying the id attribute of the 8473* <code><div></code> element of the menu bar. 8474* @param {String} p_oElement String specifying the id attribute of the 8475* <code><select></code> element to be used as the data source for the 8476* menu bar. 8477* @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level- 8478* one-html.html#ID-22445964">HTMLDivElement</a>} p_oElement Object specifying 8479* the <code><div></code> element of the menu bar. 8480* @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level- 8481* one-html.html#ID-94282980">HTMLSelectElement</a>} p_oElement Object 8482* specifying the <code><select></code> element to be used as the data 8483* source for the menu bar. 8484* @param {Object} p_oConfig Optional. Object literal specifying the 8485* configuration for the menu bar. See configuration class documentation for 8486* more details. 8487*/ 8488init: function(p_oElement, p_oConfig) { 8489 8490 if(!this.ITEM_TYPE) { 8491 8492 this.ITEM_TYPE = YAHOO.widget.MenuBarItem; 8493 8494 } 8495 8496 8497 // Call the init of the superclass (YAHOO.widget.Menu) 8498 8499 MenuBar.superclass.init.call(this, p_oElement); 8500 8501 8502 this.beforeInitEvent.fire(MenuBar); 8503 8504 8505 if(p_oConfig) { 8506 8507 this.cfg.applyConfig(p_oConfig, true); 8508 8509 } 8510 8511 this.initEvent.fire(MenuBar); 8512 8513}, 8514 8515 8516 8517// Constants 8518 8519 8520/** 8521* @property CSS_CLASS_NAME 8522* @description String representing the CSS class(es) to be applied to the menu 8523* bar's <code><div></code> element. 8524* @default "yuimenubar" 8525* @final 8526* @type String 8527*/ 8528CSS_CLASS_NAME: "yuimenubar", 8529 8530 8531 8532// Protected event handlers 8533 8534 8535/** 8536* @method _onKeyDown 8537* @description "keydown" Custom Event handler for the menu bar. 8538* @private 8539* @param {String} p_sType String representing the name of the event that 8540* was fired. 8541* @param {Array} p_aArgs Array of arguments sent when the event was fired. 8542* @param {YAHOO.widget.MenuBar} p_oMenuBar Object representing the menu bar 8543* that fired the event. 8544*/ 8545_onKeyDown: function(p_sType, p_aArgs, p_oMenuBar) { 8546 8547 var oEvent = p_aArgs[0], 8548 oItem = p_aArgs[1], 8549 oSubmenu, 8550 oItemCfg, 8551 oNextItem; 8552 8553 8554 if(oItem && !oItem.cfg.getProperty("disabled")) { 8555 8556 oItemCfg = oItem.cfg; 8557 8558 switch(oEvent.keyCode) { 8559 8560 case 37: // Left arrow 8561 case 39: // Right arrow 8562 8563 if(oItem == this.activeItem && 8564 !oItemCfg.getProperty("selected")) { 8565 8566 oItemCfg.setProperty("selected", true); 8567 8568 } 8569 else { 8570 8571 oNextItem = (oEvent.keyCode == 37) ? 8572 oItem.getPreviousEnabledSibling() : 8573 oItem.getNextEnabledSibling(); 8574 8575 if(oNextItem) { 8576 8577 this.clearActiveItem(); 8578 8579 oNextItem.cfg.setProperty("selected", true); 8580 8581
8582 if(this.cfg.getProperty("autosubmenudisplay")) { 8583 8584 oSubmenu = oNextItem.cfg.getProperty("submenu"); 8585 8586 if(oSubmenu) { 8587 8588 oSubmenu.show(); 8589 8590 } 8591 8592 } 8593 8594 oNextItem.focus(); 8595 8596 } 8597 8598 } 8599 8600 Event.preventDefault(oEvent); 8601 8602 break; 8603 8604 case 40: // Down arrow 8605 8606 if(this.activeItem != oItem) { 8607 8608 this.clearActiveItem(); 8609 8610 oItemCfg.setProperty("selected", true); 8611 oItem.focus(); 8612 8613 } 8614 8615 oSubmenu = oItemCfg.getProperty("submenu"); 8616 8617 if(oSubmenu) { 8618 8619 if(oSubmenu.cfg.getProperty("visible")) { 8620 8621 oSubmenu.setInitialSelection(); 8622 oSubmenu.setInitialFocus(); 8623 8624 } 8625 else { 8626 8627 oSubmenu.show(); 8628 8629 } 8630 8631 } 8632 8633 Event.preventDefault(oEvent); 8634 8635 break; 8636 8637 } 8638 8639 } 8640 8641 8642 if(oEvent.keyCode == 27 && this.activeItem) { // Esc key 8643 8644 oSubmenu = this.activeItem.cfg.getProperty("submenu"); 8645 8646 if(oSubmenu && oSubmenu.cfg.getProperty("visible")) { 8647 8648 oSubmenu.hide(); 8649 this.activeItem.focus(); 8650 8651 } 8652 else { 8653 8654 this.activeItem.cfg.setProperty("selected", false); 8655 this.activeItem.blur(); 8656 8657 } 8658 8659 Event.preventDefault(oEvent); 8660 8661 } 8662 8663}, 8664 8665 8666/** 8667* @method _onClick 8668* @description "click" event handler for the menu bar. 8669* @protected 8670* @param {String} p_sType String representing the name of the event that 8671* was fired. 8672* @param {Array} p_aArgs Array of arguments sent when the event was fired. 8673* @param {YAHOO.widget.MenuBar} p_oMenuBar Object representing the menu bar 8674* that fired the event. 8675*/ 8676_onClick: function(p_sType, p_aArgs, p_oMenuBar) { 8677 8678 MenuBar.superclass._onClick.call(this, p_sType, p_aArgs, p_oMenuBar); 8679 8680 var oItem = p_aArgs[1], 8681 oEvent, 8682 oTarget, 8683 oActiveItem, 8684 oConfig, 8685 oSubmenu; 8686 8687 8688 if(oItem && !oItem.cfg.getProperty("disabled")) { 8689 8690 oEvent = p_aArgs[0]; 8691 oTarget = Event.getTarget(oEvent); 8692 oActiveItem = this.activeItem; 8693 oConfig = this.cfg; 8694 8695 8696 // Hide any other submenus that might be visible 8697 8698 if(oActiveItem && oActiveItem != oItem) { 8699 8700 this.clearActiveItem(); 8701 8702 } 8703 8704 8705 oItem.cfg.setProperty("selected", true); 8706 8707 8708 // Show the submenu for the item 8709 8710 oSubmenu = oItem.cfg.getProperty("submenu"); 8711 8712 8713 if(oSubmenu) { 8714 8715 if(oSubmenu.cfg.getProperty("visible")) { 8716 8717 oSubmenu.hide(); 8718 8719 } 8720 else { 8721 8722 oSubmenu.show(); 8723 8724 } 8725 8726 } 8727 8728 } 8729 8730}, 8731 8732 8733 8734// Public methods 8735 8736 8737/** 8738* @method toString 8739* @description Returns a string representing the menu bar. 8740* @return {String} 8741*/ 8742toString: function() { 8743 8744 var sReturnVal = "MenuBar", 8745 sId = this.id; 8746 8747 if(sId) { 8748 8749 sReturnVal += (" " + sId); 8750 8751 } 8752 8753 return sReturnVal; 8754 8755}, 8756 8757 8758/** 8759* @description Initializes the class's configurable properties which can be 8760* changed using the menu bar's Config object ("cfg"). 8761* @method initDefaultConfig 8762*/ 8763initDefaultConfig: function() { 8764 8765 MenuBar.superclass.initDefaultConfig.call(this); 8766 8767 var oConfig = this.cfg; 8768 8769 // Add configuration properties 8770 8771 8772 /* 8773 Set the default value for the "position" configuration property 8774 to "static" by re-adding the property. 8775 */ 8776 8777 8778 /** 8779 * @config position
8780 * @description String indicating how a menu bar should be positioned on the 8781 * screen. Possible values are "static" and "dynamic." Static menu bars 8782 * are visible by default and reside in the normal flow of the document 8783 * (CSS position: static). Dynamic menu bars are hidden by default, reside 8784 * out of the normal flow of the document (CSS position: absolute), and can 8785 * overlay other elements on the screen. 8786 * @default static 8787 * @type String 8788 */ 8789 oConfig.addProperty( 8790 DEFAULT_CONFIG.POSITION.key, 8791 { 8792 handler: this.configPosition, 8793 value: DEFAULT_CONFIG.POSITION.value, 8794 validator: DEFAULT_CONFIG.POSITION.validator, 8795 supercedes: DEFAULT_CONFIG.POSITION.supercedes 8796 } 8797 ); 8798 8799 8800 /* 8801 Set the default value for the "submenualignment" configuration property 8802 to ["tl","bl"] by re-adding the property. 8803 */ 8804 8805 /** 8806 * @config submenualignment 8807 * @description Array defining how submenus should be aligned to their 8808 * parent menu bar item. The format is: [itemCorner, submenuCorner]. 8809 * @default ["tl","bl"] 8810 * @type Array 8811 */ 8812 oConfig.addProperty( 8813 DEFAULT_CONFIG.SUBMENU_ALIGNMENT.key, 8814 { 8815 value: DEFAULT_CONFIG.SUBMENU_ALIGNMENT.value, 8816 suppressEvent: DEFAULT_CONFIG.SUBMENU_ALIGNMENT.suppressEvent 8817 } 8818 ); 8819 8820 8821 /* 8822 Change the default value for the "autosubmenudisplay" configuration 8823 property to "false" by re-adding the property. 8824 */ 8825 8826 /** 8827 * @config autosubmenudisplay 8828 * @description Boolean indicating if submenus are automatically made 8829 * visible when the user mouses over the menu bar's items. 8830 * @default false 8831 * @type Boolean 8832 */ 8833 oConfig.addProperty( 8834 DEFAULT_CONFIG.AUTO_SUBMENU_DISPLAY.key, 8835 { 8836 value: DEFAULT_CONFIG.AUTO_SUBMENU_DISPLAY.value, 8837 validator: DEFAULT_CONFIG.AUTO_SUBMENU_DISPLAY.validator, 8838 suppressEvent: DEFAULT_CONFIG.AUTO_SUBMENU_DISPLAY.suppressEvent 8839 } 8840 ); 8841 8842} 8843 8844}); // END YAHOO.lang.extend 8845 8846}()); 8847 8848 8849 8850/** 8851* Creates an item for a menu bar. 8852* 8853* @param {String} p_oObject String specifying the text of the menu bar item. 8854* @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level- 8855* one-html.html#ID-74680021">HTMLLIElement</a>} p_oObject Object specifying the 8856* <code><li></code> element of the menu bar item. 8857* @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level- 8858* one-html.html#ID-38450247">HTMLOptGroupElement</a>} p_oObject Object 8859* specifying the <code><optgroup></code> element of the menu bar item. 8860* @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level- 8861* one-html.html#ID-70901257">HTMLOptionElement</a>} p_oObject Object specifying 8862* the <code><option></code> element of the menu bar item. 8863* @param {Object} p_oConfig Optional. Object literal specifying the 8864* configuration for the menu bar item. See configuration class documentation 8865* for more details. 8866* @class MenuBarItem 8867* @constructor 8868* @extends YAHOO.widget.MenuItem 8869*/ 8870YAHOO.widget.MenuBarItem = function(p_oObject, p_oConfig) { 8871 8872 YAHOO.widget.MenuBarItem.superclass.constructor.call(this, 8873 p_oObject, p_oConfig); 8874 8875}; 8876 8877YAHOO.lang.extend(YAHOO.widget.MenuBarItem, YAHOO.widget.MenuItem, { 8878 8879 8880 8881/** 8882* @method init 8883* @description The MenuBarItem class's initialization method. This method is 8884* automatically called by the constructor, and sets up all DOM references for 8885* pre-existing markup, and creates required markup if it is not already present. 8886* @param {String} p_oObject String specifying the text of the menu bar item. 8887* @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level- 8888* one-html.html#ID-74680021">HTMLLIElement</a>} p_oObject Object specifying the 8889* <code><li></code> element of the menu bar item. 8890* @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level- 8891* one-html.html#ID-38450247">HTMLOptGroupElement</a>} p_oObject Object 8892* specifying the <code><optgroup></code> element of the menu bar item. 8893* @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level- 8894* one-html.html#ID-70901257">HTMLOptionElement</a>} p_oObject Object specifying 8895* the <code><option></code> element of the menu bar item. 8896* @param {Object} p_oConfig Optional. Object literal specifying the 8897* configuration for the menu bar item. See configuration class documentation 8898* for more details. 8899*/ 8900init: function(p_oObject, p_oConfig) { 8901 8902 if(!this.SUBMENU_TYPE) { 8903
8904 this.SUBMENU_TYPE = YAHOO.widget.Menu; 8905 8906 } 8907 8908 8909 /* 8910 Call the init of the superclass (YAHOO.widget.MenuItem) 8911 Note: We don't pass the user config in here yet 8912 because we only want it executed once, at the lowest 8913 subclass level. 8914 */ 8915 8916 YAHOO.widget.MenuBarItem.superclass.init.call(this, p_oObject); 8917 8918 8919 var oConfig = this.cfg; 8920 8921 if(p_oConfig) { 8922 8923 oConfig.applyConfig(p_oConfig, true); 8924 8925 } 8926 8927 oConfig.fireQueue(); 8928 8929}, 8930 8931 8932 8933// Constants 8934 8935 8936/** 8937* @property CSS_CLASS_NAME 8938* @description String representing the CSS class(es) to be applied to the 8939* <code><li></code> element of the menu bar item. 8940* @default "yuimenubaritem" 8941* @final 8942* @type String 8943*/ 8944CSS_CLASS_NAME: "yuimenubaritem", 8945 8946 8947/** 8948* @property CSS_LABEL_CLASS_NAME 8949* @description String representing the CSS class(es) to be applied to the 8950* menu bar item's <code><a></code> element. 8951* @default "yuimenubaritemlabel" 8952* @final 8953* @type String 8954*/ 8955CSS_LABEL_CLASS_NAME: "yuimenubaritemlabel", 8956 8957 8958 8959// Public methods 8960 8961 8962/** 8963* @method toString 8964* @description Returns a string representing the menu bar item. 8965* @return {String} 8966*/ 8967toString: function() { 8968 8969 var sReturnVal = "MenuBarItem"; 8970 8971 if(this.cfg && this.cfg.getProperty("text")) { 8972 8973 sReturnVal += (": " + this.cfg.getProperty("text")); 8974 8975 } 8976 8977 return sReturnVal; 8978 8979} 8980 8981}); // END YAHOO.lang.extend 8982YAHOO.register("menu", YAHOO.widget.Menu, {version: "2.5.1", build: "984"});
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.