PageRenderTime 73ms CodeModel.GetById 17ms app.highlight 43ms RepoModel.GetById 1ms app.codeStats 0ms

/hudson-war/src/main/webapp/scripts/yui/menu/menu-debug.js

http://github.com/hudson/hudson
JavaScript | 2598 lines | 981 code | 895 blank | 722 comment | 214 complexity | 02ce98fb12a81dca9942333550fa7f57 MD5 | raw file

Large files files are truncated, but you can click here to view the full file

   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        var m_oLogger = new YAHOO.widget.LogWriter("MenuManager");
  87    
  88    
  89    
  90        // Private methods
  91    
  92    
  93        /**
  94        * @method getMenuRootElement
  95        * @description Finds the root DIV node of a menu or the root LI node of 
  96        * a menu item.
  97        * @private
  98        * @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/
  99        * level-one-html.html#ID-58190037">HTMLElement</a>} p_oElement Object 
 100        * specifying an HTML element.
 101        */
 102        function getMenuRootElement(p_oElement) {
 103        
 104            var oParentNode;
 105    
 106            if (p_oElement && p_oElement.tagName) {
 107            
 108                switch (p_oElement.tagName.toUpperCase()) {
 109                        
 110                case "DIV":
 111    
 112                    oParentNode = p_oElement.parentNode;
 113    
 114                    // Check if the DIV is the inner "body" node of a menu
 115
 116                    if (
 117                        (
 118                            Dom.hasClass(p_oElement, "hd") ||
 119                            Dom.hasClass(p_oElement, "bd") ||
 120                            Dom.hasClass(p_oElement, "ft")
 121                        ) && 
 122                        oParentNode && 
 123                        oParentNode.tagName && 
 124                        oParentNode.tagName.toUpperCase() == "DIV") 
 125                    {
 126                    
 127                        return oParentNode;
 128                    
 129                    }
 130                    else {
 131                    
 132                        return p_oElement;
 133                    
 134                    }
 135                
 136                    break;
 137
 138                case "LI":
 139    
 140                    return p_oElement;
 141
 142                default:
 143    
 144                    oParentNode = p_oElement.parentNode;
 145    
 146                    if (oParentNode) {
 147                    
 148                        return getMenuRootElement(oParentNode);
 149                    
 150                    }
 151                
 152                    break;
 153                
 154                }
 155    
 156            }
 157            
 158        }
 159    
 160    
 161    
 162        // Private event handlers
 163    
 164    
 165        /**
 166        * @method onDOMEvent
 167        * @description Generic, global event handler for all of a menu's 
 168        * DOM-based events.  This listens for events against the document 
 169        * object.  If the target of a given event is a member of a menu or 
 170        * menu item's DOM, the instance's corresponding Custom Event is fired.
 171        * @private
 172        * @param {Event} p_oEvent Object representing the DOM event object  
 173        * passed back by the event utility (YAHOO.util.Event).
 174        */
 175        function onDOMEvent(p_oEvent) {
 176    
 177            // Get the target node of the DOM event
 178        
 179            var oTarget = Event.getTarget(p_oEvent),
 180                
 181            // See if the target of the event was a menu, or a menu item
 182    
 183            oElement = getMenuRootElement(oTarget),
 184            sCustomEventType,
 185            sTagName,
 186            sId,
 187            oMenuItem,
 188            oMenu; 
 189    
 190    
 191            if (oElement) {
 192    
 193                sTagName = oElement.tagName.toUpperCase();
 194        
 195                if (sTagName == "LI") {
 196            
 197                    sId = oElement.id;
 198            
 199                    if (sId && m_oItems[sId]) {
 200            
 201                        oMenuItem = m_oItems[sId];
 202                        oMenu = oMenuItem.parent;
 203            
 204                    }
 205                
 206                }
 207                else if (sTagName == "DIV") {
 208                
 209                    if (oElement.id) {
 210                    
 211                        oMenu = m_oMenus[oElement.id];
 212                    
 213                    }
 214                
 215                }
 216    
 217            }
 218    
 219    
 220            if (oMenu) {
 221    
 222                sCustomEventType = m_oEventTypes[p_oEvent.type];
 223    
 224    
 225                // Fire the Custom Event that corresponds the current DOM event    
 226        
 227                if (oMenuItem && !oMenuItem.cfg.getProperty("disabled")) {
 228    
 229                    oMenuItem[sCustomEventType].fire(p_oEvent);                   
 230    
 231    
 232                    if (
 233                            p_oEvent.type == "keyup" || 
 234                            p_oEvent.type == "mousedown") 
 235                    {
 236    
 237                        if (m_oFocusedMenuItem != oMenuItem) {
 238                        
 239                            if (m_oFocusedMenuItem) {
 240    
 241                                m_oFocusedMenuItem.blurEvent.fire();
 242                            
 243                            }
 244    
 245                            oMenuItem.focusEvent.fire();
 246                        
 247                        }
 248                    
 249                    }
 250    
 251                }
 252        
 253                oMenu[sCustomEventType].fire(p_oEvent, oMenuItem);
 254            
 255            }
 256            else if (p_oEvent.type == "mousedown") {
 257    
 258                if (m_oFocusedMenuItem) {
 259    
 260                    m_oFocusedMenuItem.blurEvent.fire();
 261    
 262                    m_oFocusedMenuItem = null;
 263    
 264                }
 265    
 266    
 267                /*
 268                    If the target of the event wasn't a menu, hide all 
 269                    dynamically positioned menus
 270                */
 271                
 272                for (var i in m_oVisibleMenus) {
 273        
 274                    if (YAHOO.lang.hasOwnProperty(m_oVisibleMenus, i)) {
 275        
 276                        oMenu = m_oVisibleMenus[i];
 277        
 278                        if (oMenu.cfg.getProperty("clicktohide") && 
 279                            !(oMenu instanceof YAHOO.widget.MenuBar) && 
 280                            oMenu.cfg.getProperty("position") == "dynamic") {
 281        
 282                            oMenu.hide();
 283        
 284                        }
 285                        else {
 286    
 287                            oMenu.clearActiveItem(true);
 288        
 289                        }
 290        
 291                    }
 292        
 293                } 
 294    
 295            }
 296            else if (p_oEvent.type == "keyup") { 
 297    
 298                if (m_oFocusedMenuItem) {
 299    
 300                    m_oFocusedMenuItem.blurEvent.fire();
 301    
 302                    m_oFocusedMenuItem = null;
 303    
 304                }
 305    
 306            }
 307    
 308        }
 309    
 310    
 311        /**
 312        * @method onMenuDestroy
 313        * @description "destroy" event handler for a menu.
 314        * @private
 315        * @param {String} p_sType String representing the name of the event 
 316        * that was fired.
 317        * @param {Array} p_aArgs Array of arguments sent when the event 
 318        * was fired.
 319        * @param {YAHOO.widget.Menu} p_oMenu The menu that fired the event.
 320        */
 321        function onMenuDestroy(p_sType, p_aArgs, p_oMenu) {
 322    
 323            if (m_oMenus[p_oMenu.id]) {
 324    
 325                this.removeMenu(p_oMenu);
 326    
 327            }
 328    
 329        }
 330    
 331    
 332        /**
 333        * @method onMenuFocus
 334        * @description "focus" event handler for a MenuItem instance.
 335        * @private
 336        * @param {String} p_sType String representing the name of the event 
 337        * that was fired.
 338        * @param {Array} p_aArgs Array of arguments sent when the event 
 339        * was fired.
 340        */
 341        function onMenuFocus(p_sType, p_aArgs) {
 342    
 343            var oItem = p_aArgs[0];
 344    
 345            if (oItem) {
 346    
 347                m_oFocusedMenuItem = oItem;
 348            
 349            }
 350    
 351        }
 352    
 353    
 354        /**
 355        * @method onMenuBlur
 356        * @description "blur" event handler for a MenuItem instance.
 357        * @private
 358        * @param {String} p_sType String representing the name of the event  
 359        * that was fired.
 360        * @param {Array} p_aArgs Array of arguments sent when the event 
 361        * was fired.
 362        */
 363        function onMenuBlur(p_sType, p_aArgs) {
 364    
 365            m_oFocusedMenuItem = null;
 366    
 367        }
 368    
 369    
 370    
 371        /**
 372        * @method onMenuVisibleConfigChange
 373        * @description Event handler for when the "visible" configuration  
 374        * property of a Menu instance changes.
 375        * @private
 376        * @param {String} p_sType String representing the name of the event  
 377        * that was fired.
 378        * @param {Array} p_aArgs Array of arguments sent when the event 
 379        * was fired.
 380        */
 381        function onMenuVisibleConfigChange(p_sType, p_aArgs) {
 382    
 383            var bVisible = p_aArgs[0],
 384                sId = this.id;
 385            
 386            if (bVisible) {
 387    
 388                m_oVisibleMenus[sId] = this;
 389                
 390                m_oLogger.log(
 391                            this + 
 392                            " added to the collection of visible menus.");
 393            
 394            }
 395            else if (m_oVisibleMenus[sId]) {
 396            
 397                delete m_oVisibleMenus[sId];
 398                
 399                m_oLogger.log( 
 400                            this + 
 401                            " removed from the collection of visible menus.");
 402            
 403            }
 404        
 405        }
 406    
 407    
 408        /**
 409        * @method onItemDestroy
 410        * @description "destroy" event handler for a MenuItem instance.
 411        * @private
 412        * @param {String} p_sType String representing the name of the event  
 413        * that was fired.
 414        * @param {Array} p_aArgs Array of arguments sent when the event 
 415        * was fired.
 416        */
 417        function onItemDestroy(p_sType, p_aArgs) {
 418    
 419            removeItem(this);
 420    
 421        }
 422
 423    
 424        function removeItem(p_oMenuItem) {
 425
 426            var sId = p_oMenuItem.id;
 427    
 428            if (sId && m_oItems[sId]) {
 429    
 430                if (m_oFocusedMenuItem == p_oMenuItem) {
 431    
 432                    m_oFocusedMenuItem = null;
 433    
 434                }
 435    
 436                delete m_oItems[sId];
 437                
 438                p_oMenuItem.destroyEvent.unsubscribe(onItemDestroy);
 439    
 440                m_oLogger.log(p_oMenuItem + " successfully unregistered.");
 441    
 442            }
 443
 444        }
 445    
 446    
 447        /**
 448        * @method onItemAdded
 449        * @description "itemadded" event handler for a Menu instance.
 450        * @private
 451        * @param {String} p_sType String representing the name of the event  
 452        * that was fired.
 453        * @param {Array} p_aArgs Array of arguments sent when the event 
 454        * was fired.
 455        */
 456        function onItemAdded(p_sType, p_aArgs) {
 457    
 458            var oItem = p_aArgs[0],
 459                sId;
 460    
 461            if (oItem instanceof YAHOO.widget.MenuItem) { 
 462    
 463                sId = oItem.id;
 464        
 465                if (!m_oItems[sId]) {
 466            
 467                    m_oItems[sId] = oItem;
 468        
 469                    oItem.destroyEvent.subscribe(onItemDestroy);
 470        
 471                    m_oLogger.log(oItem + " successfully registered.");
 472        
 473                }
 474    
 475            }
 476        
 477        }
 478    
 479    
 480        return {
 481    
 482            // Privileged methods
 483    
 484    
 485            /**
 486            * @method addMenu
 487            * @description Adds a menu to the collection of known menus.
 488            * @param {YAHOO.widget.Menu} p_oMenu Object specifying the Menu  
 489            * instance to be added.
 490            */
 491            addMenu: function (p_oMenu) {
 492    
 493                var oDoc;
 494    
 495                if (p_oMenu instanceof YAHOO.widget.Menu && p_oMenu.id && 
 496                    !m_oMenus[p_oMenu.id]) {
 497        
 498                    m_oMenus[p_oMenu.id] = p_oMenu;
 499                
 500            
 501                    if (!m_bInitializedEventHandlers) {
 502            
 503                        oDoc = document;
 504                
 505                        Event.on(oDoc, "mouseover", onDOMEvent, this, true);
 506                        Event.on(oDoc, "mouseout", onDOMEvent, this, true);
 507                        Event.on(oDoc, "mousedown", onDOMEvent, this, true);
 508                        Event.on(oDoc, "mouseup", onDOMEvent, this, true);
 509                        Event.on(oDoc, "click", onDOMEvent, this, true);
 510                        Event.on(oDoc, "keydown", onDOMEvent, this, true);
 511                        Event.on(oDoc, "keyup", onDOMEvent, this, true);
 512                        Event.on(oDoc, "keypress", onDOMEvent, this, true);
 513    
 514    
 515                        m_bInitializedEventHandlers = true;
 516                        
 517                        m_oLogger.log("DOM event handlers initialized.");
 518            
 519                    }
 520            
 521                    p_oMenu.cfg.subscribeToConfigEvent("visible", 
 522                        onMenuVisibleConfigChange);
 523
 524                    p_oMenu.destroyEvent.subscribe(onMenuDestroy, p_oMenu, 
 525                                            this);
 526            
 527                    p_oMenu.itemAddedEvent.subscribe(onItemAdded);
 528                    p_oMenu.focusEvent.subscribe(onMenuFocus);
 529                    p_oMenu.blurEvent.subscribe(onMenuBlur);
 530        
 531                    m_oLogger.log(p_oMenu + " successfully registered.");
 532        
 533                }
 534        
 535            },
 536    
 537        
 538            /**
 539            * @method removeMenu
 540            * @description Removes a menu from the collection of known menus.
 541            * @param {YAHOO.widget.Menu} p_oMenu Object specifying the Menu  
 542            * instance to be removed.
 543            */
 544            removeMenu: function (p_oMenu) {
 545    
 546                var sId,
 547                    aItems,
 548                    i;
 549        
 550                if (p_oMenu) {
 551    
 552                    sId = p_oMenu.id;
 553        
 554                    if (m_oMenus[sId] == p_oMenu) {
 555
 556                        // Unregister each menu item
 557
 558                        aItems = p_oMenu.getItems();
 559
 560                        if (aItems && aItems.length > 0) {
 561
 562                            i = aItems.length - 1;
 563
 564                            do {
 565
 566                                removeItem(aItems[i]);
 567
 568                            }
 569                            while (i--);
 570
 571                        }
 572
 573
 574                        // Unregister the menu
 575
 576                        delete m_oMenus[sId];
 577            
 578                        m_oLogger.log(p_oMenu + " successfully unregistered.");
 579        
 580
 581                        /*
 582                             Unregister the menu from the collection of 
 583                             visible menus
 584                        */
 585
 586                        if (m_oVisibleMenus[sId] == p_oMenu) {
 587            
 588                            delete m_oVisibleMenus[sId];
 589                            
 590                            m_oLogger.log(p_oMenu + " unregistered from the" + 
 591                                        " collection of visible menus.");
 592       
 593                        }
 594
 595
 596                        // Unsubscribe event listeners
 597
 598                        if (p_oMenu.cfg) {
 599
 600                            p_oMenu.cfg.unsubscribeFromConfigEvent("visible", 
 601                                onMenuVisibleConfigChange);
 602                            
 603                        }
 604
 605                        p_oMenu.destroyEvent.unsubscribe(onMenuDestroy, 
 606                            p_oMenu);
 607                
 608                        p_oMenu.itemAddedEvent.unsubscribe(onItemAdded);
 609                        p_oMenu.focusEvent.unsubscribe(onMenuFocus);
 610                        p_oMenu.blurEvent.unsubscribe(onMenuBlur);
 611
 612                    }
 613                
 614                }
 615    
 616            },
 617        
 618        
 619            /**
 620            * @method hideVisible
 621            * @description Hides all visible, dynamically positioned menus 
 622            * (excluding instances of YAHOO.widget.MenuBar).
 623            */
 624            hideVisible: function () {
 625        
 626                var oMenu;
 627        
 628                for (var i in m_oVisibleMenus) {
 629        
 630                    if (YAHOO.lang.hasOwnProperty(m_oVisibleMenus, i)) {
 631        
 632                        oMenu = m_oVisibleMenus[i];
 633        
 634                        if (!(oMenu instanceof YAHOO.widget.MenuBar) && 
 635                            oMenu.cfg.getProperty("position") == "dynamic") {
 636        
 637                            oMenu.hide();
 638        
 639                        }
 640        
 641                    }
 642        
 643                }        
 644    
 645            },
 646
 647
 648            /**
 649            * @method getVisible
 650            * @description Returns a collection of all visible menus registered
 651            * with the menu manger.
 652            * @return {Array}
 653            */
 654            getVisible: function () {
 655            
 656                return m_oVisibleMenus;
 657            
 658            },
 659
 660    
 661            /**
 662            * @method getMenus
 663            * @description Returns a collection of all menus registered with the 
 664            * menu manger.
 665            * @return {Array}
 666            */
 667            getMenus: function () {
 668    
 669                return m_oMenus;
 670            
 671            },
 672    
 673    
 674            /**
 675            * @method getMenu
 676            * @description Returns a menu with the specified id.
 677            * @param {String} p_sId String specifying the id of the 
 678            * <code>&#60;div&#62;</code> element representing the menu to
 679            * be retrieved.
 680            * @return {YAHOO.widget.Menu}
 681            */
 682            getMenu: function (p_sId) {
 683    
 684                var oMenu = m_oMenus[p_sId];
 685        
 686                if (oMenu) {
 687                
 688                    return oMenu;
 689                
 690                }
 691            
 692            },
 693    
 694    
 695            /**
 696            * @method getMenuItem
 697            * @description Returns a menu item with the specified id.
 698            * @param {String} p_sId String specifying the id of the 
 699            * <code>&#60;li&#62;</code> element representing the menu item to
 700            * be retrieved.
 701            * @return {YAHOO.widget.MenuItem}
 702            */
 703            getMenuItem: function (p_sId) {
 704    
 705                var oItem = m_oItems[p_sId];
 706        
 707                if (oItem) {
 708                
 709                    return oItem;
 710                
 711                }
 712            
 713            },
 714
 715
 716            /**
 717            * @method getMenuItemGroup
 718            * @description Returns an array of menu item instances whose 
 719            * corresponding <code>&#60;li&#62;</code> elements are child 
 720            * nodes of the <code>&#60;ul&#62;</code> element with the 
 721            * specified id.
 722            * @param {String} p_sId String specifying the id of the 
 723            * <code>&#60;ul&#62;</code> element representing the group of 
 724            * menu items to be retrieved.
 725            * @return {Array}
 726            */
 727            getMenuItemGroup: function (p_sId) {
 728
 729                var oUL = Dom.get(p_sId),
 730                    aItems,
 731                    oNode,
 732                    oItem,
 733                    sId;
 734    
 735
 736                if (oUL && oUL.tagName && 
 737                    oUL.tagName.toUpperCase() == "UL") {
 738
 739                    oNode = oUL.firstChild;
 740
 741                    if (oNode) {
 742
 743                        aItems = [];
 744                        
 745                        do {
 746
 747                            sId = oNode.id;
 748
 749                            if (sId) {
 750                            
 751                                oItem = this.getMenuItem(sId);
 752                                
 753                                if (oItem) {
 754                                
 755                                    aItems[aItems.length] = oItem;
 756                                
 757                                }
 758                            
 759                            }
 760                        
 761                        }
 762                        while ((oNode = oNode.nextSibling));
 763
 764
 765                        if (aItems.length > 0) {
 766
 767                            return aItems;
 768                        
 769                        }
 770
 771                    }
 772                
 773                }
 774            
 775            },
 776
 777    
 778            /**
 779            * @method getFocusedMenuItem
 780            * @description Returns a reference to the menu item that currently 
 781            * has focus.
 782            * @return {YAHOO.widget.MenuItem}
 783            */
 784            getFocusedMenuItem: function () {
 785    
 786                return m_oFocusedMenuItem;
 787    
 788            },
 789    
 790    
 791            /**
 792            * @method getFocusedMenu
 793            * @description Returns a reference to the menu that currently 
 794            * has focus.
 795            * @return {YAHOO.widget.Menu}
 796            */
 797            getFocusedMenu: function () {
 798    
 799                if (m_oFocusedMenuItem) {
 800    
 801                    return (m_oFocusedMenuItem.parent.getRoot());
 802                
 803                }
 804    
 805            },
 806    
 807        
 808            /**
 809            * @method toString
 810            * @description Returns a string representing the menu manager.
 811            * @return {String}
 812            */
 813            toString: function () {
 814            
 815                return "MenuManager";
 816            
 817            }
 818    
 819        };
 820    
 821    }();
 822
 823})();
 824
 825
 826
 827(function () {
 828
 829
 830/**
 831* The Menu class creates a container that holds a vertical list representing 
 832* a set of options or commands.  Menu is the base class for all 
 833* menu containers. 
 834* @param {String} p_oElement String specifying the id attribute of the 
 835* <code>&#60;div&#62;</code> element of the menu.
 836* @param {String} p_oElement String specifying the id attribute of the 
 837* <code>&#60;select&#62;</code> element to be used as the data source 
 838* for the menu.
 839* @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/
 840* level-one-html.html#ID-22445964">HTMLDivElement</a>} p_oElement Object 
 841* specifying the <code>&#60;div&#62;</code> element of the menu.
 842* @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/
 843* level-one-html.html#ID-94282980">HTMLSelectElement</a>} p_oElement 
 844* Object specifying the <code>&#60;select&#62;</code> element to be used as 
 845* the data source for the menu.
 846* @param {Object} p_oConfig Optional. Object literal specifying the 
 847* configuration for the menu. See configuration class documentation for 
 848* more details.
 849* @namespace YAHOO.widget
 850* @class Menu
 851* @constructor
 852* @extends YAHOO.widget.Overlay
 853*/
 854YAHOO.widget.Menu = function (p_oElement, p_oConfig) {
 855
 856    if (p_oConfig) {
 857
 858        this.parent = p_oConfig.parent;
 859        this.lazyLoad = p_oConfig.lazyLoad || p_oConfig.lazyload;
 860        this.itemData = p_oConfig.itemData || p_oConfig.itemdata;
 861
 862    }
 863
 864
 865    YAHOO.widget.Menu.superclass.constructor.call(this, p_oElement, p_oConfig);
 866
 867};
 868
 869
 870
 871/**
 872* @method checkPosition
 873* @description Checks to make sure that the value of the "position" property 
 874* is one of the supported strings. Returns true if the position is supported.
 875* @private
 876* @param {Object} p_sPosition String specifying the position of the menu.
 877* @return {Boolean}
 878*/
 879function checkPosition(p_sPosition) {
 880
 881    if (typeof p_sPosition == "string") {
 882
 883        return ("dynamic,static".indexOf((p_sPosition.toLowerCase())) != -1);
 884
 885    }
 886
 887}
 888
 889
 890var Dom = YAHOO.util.Dom,
 891    Event = YAHOO.util.Event,
 892    Module = YAHOO.widget.Module,
 893    Overlay = YAHOO.widget.Overlay,
 894    Menu = YAHOO.widget.Menu,
 895    MenuManager = YAHOO.widget.MenuManager,
 896    CustomEvent = YAHOO.util.CustomEvent,
 897    Lang = YAHOO.lang,
 898    UA = YAHOO.env.ua,
 899    
 900    m_oShadowTemplate,
 901
 902    /**
 903    * Constant representing the name of the Menu's events
 904    * @property EVENT_TYPES
 905    * @private
 906    * @final
 907    * @type Object
 908    */
 909    EVENT_TYPES = {
 910    
 911        "MOUSE_OVER": "mouseover",
 912        "MOUSE_OUT": "mouseout",
 913        "MOUSE_DOWN": "mousedown",
 914        "MOUSE_UP": "mouseup",
 915        "CLICK": "click",
 916        "KEY_PRESS": "keypress",
 917        "KEY_DOWN": "keydown",
 918        "KEY_UP": "keyup",
 919        "FOCUS": "focus",
 920        "BLUR": "blur",
 921        "ITEM_ADDED": "itemAdded",
 922        "ITEM_REMOVED": "itemRemoved"
 923    
 924    },
 925
 926
 927    /**
 928    * Constant representing the Menu's configuration properties
 929    * @property DEFAULT_CONFIG
 930    * @private
 931    * @final
 932    * @type Object
 933    */
 934    DEFAULT_CONFIG = {
 935
 936        "VISIBLE": { 
 937            key: "visible", 
 938            value: false, 
 939            validator: Lang.isBoolean
 940        }, 
 941    
 942        "CONSTRAIN_TO_VIEWPORT": {
 943            key: "constraintoviewport", 
 944            value: true, 
 945            validator: Lang.isBoolean, 
 946            supercedes: ["iframe","x","y","xy"]
 947        }, 
 948    
 949        "POSITION": { 
 950            key: "position", 
 951            value: "dynamic", 
 952            validator: checkPosition, 
 953            supercedes: ["visible", "iframe"]
 954        }, 
 955    
 956        "SUBMENU_ALIGNMENT": { 
 957            key: "submenualignment", 
 958            value: ["tl","tr"],
 959            suppressEvent: true
 960        },
 961    
 962        "AUTO_SUBMENU_DISPLAY": { 
 963            key: "autosubmenudisplay", 
 964            value: true, 
 965            validator: Lang.isBoolean,
 966            suppressEvent: true
 967        }, 
 968    
 969        "SHOW_DELAY": { 
 970            key: "showdelay", 
 971            value: 250, 
 972            validator: Lang.isNumber, 
 973            suppressEvent: true
 974        }, 
 975    
 976        "HIDE_DELAY": { 
 977            key: "hidedelay", 
 978            value: 0, 
 979            validator: Lang.isNumber, 
 980            suppressEvent: true
 981        }, 
 982    
 983        "SUBMENU_HIDE_DELAY": { 
 984            key: "submenuhidedelay", 
 985            value: 250, 
 986            validator: Lang.isNumber,
 987            suppressEvent: true
 988        }, 
 989    
 990        "CLICK_TO_HIDE": { 
 991            key: "clicktohide", 
 992            value: true, 
 993            validator: Lang.isBoolean,
 994            suppressEvent: true
 995        },
 996    
 997        "CONTAINER": { 
 998            key: "container",
 999            suppressEvent: true
1000        }, 
1001
1002        "SCROLL_INCREMENT": { 
1003            key: "scrollincrement", 
1004            value: 1, 
1005            validator: Lang.isNumber,
1006            supercedes: ["maxheight"],
1007            suppressEvent: true
1008        },
1009
1010        "MIN_SCROLL_HEIGHT": { 
1011            key: "minscrollheight", 
1012            value: 90, 
1013            validator: Lang.isNumber,
1014            supercedes: ["maxheight"],
1015            suppressEvent: true
1016        },    
1017    
1018        "MAX_HEIGHT": { 
1019            key: "maxheight", 
1020            value: 0, 
1021            validator: Lang.isNumber,
1022            supercedes: ["iframe"],
1023            suppressEvent: true
1024        }, 
1025    
1026        "CLASS_NAME": { 
1027            key: "classname", 
1028            value: null, 
1029            validator: Lang.isString,
1030            suppressEvent: true
1031        }, 
1032    
1033        "DISABLED": { 
1034            key: "disabled", 
1035            value: false, 
1036            validator: Lang.isBoolean,
1037            suppressEvent: true
1038        }
1039    
1040    };
1041
1042
1043
1044YAHOO.lang.extend(Menu, Overlay, {
1045
1046
1047// Constants
1048
1049
1050/**
1051* @property CSS_CLASS_NAME
1052* @description String representing the CSS class(es) to be applied to the 
1053* menu's <code>&#60;div&#62;</code> element.
1054* @default "yuimenu"
1055* @final
1056* @type String
1057*/
1058CSS_CLASS_NAME: "yuimenu",
1059
1060
1061/**
1062* @property ITEM_TYPE
1063* @description Object representing the type of menu item to instantiate and 
1064* add when parsing the child nodes (either <code>&#60;li&#62;</code> element, 
1065* <code>&#60;optgroup&#62;</code> element or <code>&#60;option&#62;</code>) 
1066* of the menu's source HTML element.
1067* @default YAHOO.widget.MenuItem
1068* @final
1069* @type YAHOO.widget.MenuItem
1070*/
1071ITEM_TYPE: null,
1072
1073
1074/**
1075* @property GROUP_TITLE_TAG_NAME
1076* @description String representing the tagname of the HTML element used to 
1077* title the menu's item groups.
1078* @default H6
1079* @final
1080* @type String
1081*/
1082GROUP_TITLE_TAG_NAME: "h6",
1083
1084
1085/**
1086* @property OFF_SCREEN_POSITION
1087* @description Array representing the default x and y position that a menu 
1088* should have when it is positioned outside the viewport by the 
1089* "poistionOffScreen" method.
1090* @default [-10000, -10000]
1091* @final
1092* @type Array
1093*/
1094OFF_SCREEN_POSITION: [-10000, -10000],
1095
1096
1097// Private properties
1098
1099
1100/** 
1101* @property _nHideDelayId
1102* @description Number representing the time-out setting used to cancel the 
1103* hiding of a menu.
1104* @default null
1105* @private
1106* @type Number
1107*/
1108_nHideDelayId: null,
1109
1110
1111/** 
1112* @property _nShowDelayId
1113* @description Number representing the time-out setting used to cancel the 
1114* showing of a menu.
1115* @default null
1116* @private
1117* @type Number
1118*/
1119_nShowDelayId: null,
1120
1121
1122/** 
1123* @property _nSubmenuHideDelayId
1124* @description Number representing the time-out setting used to cancel the 
1125* hiding of a submenu.
1126* @default null
1127* @private
1128* @type Number
1129*/
1130_nSubmenuHideDelayId: null,
1131
1132
1133/** 
1134* @property _nBodyScrollId
1135* @description Number representing the time-out setting used to cancel the 
1136* scrolling of the menu's body element.
1137* @default null
1138* @private
1139* @type Number
1140*/
1141_nBodyScrollId: null,
1142
1143
1144/** 
1145* @property _bHideDelayEventHandlersAssigned
1146* @description Boolean indicating if the "mouseover" and "mouseout" event 
1147* handlers used for hiding the menu via a call to "window.setTimeout" have 
1148* already been assigned.
1149* @default false
1150* @private
1151* @type Boolean
1152*/
1153_bHideDelayEventHandlersAssigned: false,
1154
1155
1156/**
1157* @property _bHandledMouseOverEvent
1158* @description Boolean indicating the current state of the menu's 
1159* "mouseover" event.
1160* @default false
1161* @private
1162* @type Boolean
1163*/
1164_bHandledMouseOverEvent: false,
1165
1166
1167/**
1168* @property _bHandledMouseOutEvent
1169* @description Boolean indicating the current state of the menu's
1170* "mouseout" event.
1171* @default false
1172* @private
1173* @type Boolean
1174*/
1175_bHandledMouseOutEvent: false,
1176
1177
1178/**
1179* @property _aGroupTitleElements
1180* @description Array of HTML element used to title groups of menu items.
1181* @default []
1182* @private
1183* @type Array
1184*/
1185_aGroupTitleElements: null,
1186
1187
1188/**
1189* @property _aItemGroups
1190* @description Multi-dimensional Array representing the menu items as they
1191* are grouped in the menu.
1192* @default []
1193* @private
1194* @type Array
1195*/
1196_aItemGroups: null,
1197
1198
1199/**
1200* @property _aListElements
1201* @description Array of <code>&#60;ul&#62;</code> elements, each of which is 
1202* the parent node for each item's <code>&#60;li&#62;</code> element.
1203* @default []
1204* @private
1205* @type Array
1206*/
1207_aListElements: null,
1208
1209
1210/**
1211* @property _nCurrentMouseX
1212* @description The current x coordinate of the mouse inside the area of 
1213* the menu.
1214* @default 0
1215* @private
1216* @type Number
1217*/
1218_nCurrentMouseX: 0,
1219
1220
1221/**
1222* @property _bStopMouseEventHandlers
1223* @description Stops "mouseover," "mouseout," and "mousemove" event handlers 
1224* from executing.
1225* @default false
1226* @private
1227* @type Boolean
1228*/
1229_bStopMouseEventHandlers: false,
1230
1231
1232/**
1233* @property _sClassName
1234* @description The current value of the "classname" configuration attribute.
1235* @default null
1236* @private
1237* @type String
1238*/
1239_sClassName: null,
1240
1241
1242
1243// Public properties
1244
1245
1246/**
1247* @property lazyLoad
1248* @description Boolean indicating if the menu's "lazy load" feature is 
1249* enabled.  If set to "true," initialization and rendering of the menu's 
1250* items will be deferred until the first time it is made visible.  This 
1251* property should be set via the constructor using the configuration 
1252* object literal.
1253* @default false
1254* @type Boolean
1255*/
1256lazyLoad: false,
1257
1258
1259/**
1260* @property itemData
1261* @description Array of items to be added to the menu.  The array can contain 
1262* strings representing the text for each item to be created, object literals 
1263* representing the menu item configuration properties, or MenuItem instances.  
1264* This property should be set via the constructor using the configuration 
1265* object literal.
1266* @default null
1267* @type Array
1268*/
1269itemData: null,
1270
1271
1272/**
1273* @property activeItem
1274* @description Object reference to the item in the menu that has is selected.
1275* @default null
1276* @type YAHOO.widget.MenuItem
1277*/
1278activeItem: null,
1279
1280
1281/**
1282* @property parent
1283* @description Object reference to the menu's parent menu or menu item.  
1284* This property can be set via the constructor using the configuration 
1285* object literal.
1286* @default null
1287* @type YAHOO.widget.MenuItem
1288*/
1289parent: null,
1290
1291
1292/**
1293* @property srcElement
1294* @description Object reference to the HTML element (either 
1295* <code>&#60;select&#62;</code> or <code>&#60;div&#62;</code>) used to 
1296* create the menu.
1297* @default null
1298* @type <a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/
1299* level-one-html.html#ID-94282980">HTMLSelectElement</a>|<a 
1300* href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-one-html.
1301* html#ID-22445964">HTMLDivElement</a>
1302*/
1303srcElement: null,
1304
1305
1306
1307// Events
1308
1309
1310/**
1311* @event mouseOverEvent
1312* @description Fires when the mouse has entered the menu.  Passes back 
1313* the DOM Event object as an argument.
1314*/
1315mouseOverEvent: null,
1316
1317
1318/**
1319* @event mouseOutEvent
1320* @description Fires when the mouse has left the menu.  Passes back the DOM 
1321* Event object as an argument.
1322* @type YAHOO.util.CustomEvent
1323*/
1324mouseOutEvent: null,
1325
1326
1327/**
1328* @event mouseDownEvent
1329* @description Fires when the user mouses down on the menu.  Passes back the 
1330* DOM Event object as an argument.
1331* @type YAHOO.util.CustomEvent
1332*/
1333mouseDownEvent: null,
1334
1335
1336/**
1337* @event mouseUpEvent
1338* @description Fires when the user releases a mouse button while the mouse is 
1339* over the menu.  Passes back the DOM Event object as an argument.
1340* @type YAHOO.util.CustomEvent
1341*/
1342mouseUpEvent: null,
1343
1344
1345/**
1346* @event clickEvent
1347* @description Fires when the user clicks the on the menu.  Passes back the 
1348* DOM Event object as an argument.
1349* @type YAHOO.util.CustomEvent
1350*/
1351clickEvent: null,
1352
1353
1354/**
1355* @event keyPressEvent
1356* @description Fires when the user presses an alphanumeric key when one of the
1357* menu's items has focus.  Passes back the DOM Event object as an argument.
1358* @type YAHOO.util.CustomEvent
1359*/
1360keyPressEvent: null,
1361
1362
1363/**
1364* @event keyDownEvent
1365* @description Fires when the user presses a key when one of the menu's items 
1366* has focus.  Passes back the DOM Event object as an argument.
1367* @type YAHOO.util.CustomEvent
1368*/
1369keyDownEvent: null,
1370
1371
1372/**
1373* @event keyUpEvent
1374* @description Fires when the user releases a key when one of the menu's items 
1375* has focus.  Passes back the DOM Event object as an argument.
1376* @type YAHOO.util.CustomEvent
1377*/
1378keyUpEvent: null,
1379
1380
1381/**
1382* @event itemAddedEvent
1383* @description Fires when an item is added to the menu.
1384* @type YAHOO.util.CustomEvent
1385*/
1386itemAddedEvent: null,
1387
1388
1389/**
1390* @event itemRemovedEvent
1391* @description Fires when an item is removed to the menu.
1392* @type YAHOO.util.CustomEvent
1393*/
1394itemRemovedEvent: null,
1395
1396
1397/**
1398* @method init
1399* @description The Menu class's initialization method. This method is 
1400* automatically called by the constructor, and sets up all DOM references 
1401* for pre-existing markup, and creates required markup if it is not 
1402* already present.
1403* @param {String} p_oElement String specifying the id attribute of the 
1404* <code>&#60;div&#62;</code> element of the menu.
1405* @param {String} p_oElement String specifying the id attribute of the 
1406* <code>&#60;select&#62;</code> element to be used as the data source 
1407* for the menu.
1408* @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/
1409* level-one-html.html#ID-22445964">HTMLDivElement</a>} p_oElement Object 
1410* specifying the <code>&#60;div&#62;</code> element of the menu.
1411* @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/
1412* level-one-html.html#ID-94282980">HTMLSelectElement</a>} p_oElement 
1413* Object specifying the <code>&#60;select&#62;</code> element to be used as 
1414* the data source for the menu.
1415* @param {Object} p_oConfig Optional. Object literal specifying the 
1416* configuration for the menu. See configuration class documentation for 
1417* more details.
1418*/
1419init: function (p_oElement, p_oConfig) {
1420
1421    this._aItemGroups = [];
1422    this._aListElements = [];
1423    this._aGroupTitleElements = [];
1424
1425    if (!this.ITEM_TYPE) {
1426
1427        this.ITEM_TYPE = YAHOO.widget.MenuItem;
1428
1429    }
1430
1431
1432    var oElement;
1433
1434    if (typeof p_oElement == "string") {
1435
1436        oElement = document.getElementById(p_oElement);
1437
1438    }
1439    else if (p_oElement.tagName) {
1440
1441        oElement = p_oElement;
1442
1443    }
1444
1445
1446    if (oElement && oElement.tagName) {
1447
1448        switch(oElement.tagName.toUpperCase()) {
1449    
1450            case "DIV":
1451
1452                this.srcElement = oElement;
1453
1454                if (!oElement.id) {
1455
1456                    oElement.setAttribute("id", Dom.generateId());
1457
1458                }
1459
1460
1461                /* 
1462                    Note: we don't pass the user config in here yet 
1463                    because we only want it executed once, at the lowest 
1464                    subclass level.
1465                */ 
1466            
1467                Menu.superclass.init.call(this, oElement);
1468
1469                this.beforeInitEvent.fire(Menu);
1470
1471                this.logger = new YAHOO.widget.LogWriter(this.toString());
1472
1473                this.logger.log("Source element: " + this.srcElement.tagName);
1474    
1475            break;
1476    
1477            case "SELECT":
1478    
1479                this.srcElement = oElement;
1480
1481    
1482                /*
1483                    The source element is not something that we can use 
1484                    outright, so we need to create a new Overlay
1485
1486                    Note: we don't pass the user config in here yet 
1487                    because we only want it executed once, at the lowest 
1488                    subclass level.
1489                */ 
1490
1491                Menu.superclass.init.call(this, Dom.generateId());
1492
1493                this.beforeInitEvent.fire(Menu);
1494
1495                this.logger = new YAHOO.widget.LogWriter(this.toString());
1496
1497                this.logger.log("Source element: " + this.srcElement.tagName);
1498
1499            break;
1500
1501        }
1502
1503    }
1504    else {
1505
1506        /* 
1507            Note: we don't pass the user config in here yet 
1508            because we only want it executed once, at the lowest 
1509            subclass level.
1510        */ 
1511    
1512        Menu.superclass.init.call(this, p_oElement);
1513
1514        this.beforeInitEvent.fire(Menu);
1515
1516        this.logger = new YAHOO.widget.LogWriter(this.toString());
1517
1518        this.logger.log("No source element found.  " +
1519            "Created element with id: " + this.id);
1520
1521    }
1522
1523
1524    if (this.element) {
1525
1526        Dom.addClass(this.element, this.CSS_CLASS_NAME);
1527
1528
1529        // Subscribe to Custom Events
1530
1531        this.initEvent.subscribe(this._onInit);
1532        this.beforeRenderEvent.subscribe(this._onBeforeRender);
1533        this.renderEvent.subscribe(this._onRender);
1534        this.renderEvent.subscribe(this.onRender);
1535        this.beforeShowEvent.subscribe(this._onBeforeShow);
1536        this.hideEvent.subscribe(this.positionOffScreen);
1537        this.showEvent.subscribe(this._onShow);
1538        this.beforeHideEvent.subscribe(this._onBeforeHide);
1539        this.mouseOverEvent.subscribe(this._onMouseOver);
1540        this.mouseOutEvent.subscribe(this._onMouseOut);
1541        this.clickEvent.subscribe(this._onClick);
1542        this.keyDownEvent.subscribe(this._onKeyDown);
1543        this.keyPressEvent.subscribe(this._onKeyPress);
1544        
1545
1546        if (UA.gecko || UA.webkit) {
1547
1548            this.cfg.subscribeToConfigEvent("y", this._onYChange);
1549
1550        }
1551
1552
1553        if (p_oConfig) {
1554    
1555            this.cfg.applyConfig(p_oConfig, true);
1556    
1557        }
1558
1559
1560        // Register the Menu instance with the MenuManager
1561
1562        MenuManager.addMenu(this);
1563        
1564
1565        this.initEvent.fire(Menu);
1566
1567    }
1568
1569},
1570
1571
1572
1573// Private methods
1574
1575
1576/**
1577* @method _initSubTree
1578* @description Iterates the childNodes of the source element to find nodes 
1579* used to instantiate menu and menu items.
1580* @private
1581*/
1582_initSubTree: function () {
1583
1584    var oSrcElement = this.srcElement,
1585        sSrcElementTagName,
1586        nGroup,
1587        sGroupTitleTagName,
1588        oNode,
1589        aListElements,
1590        nListElements,
1591        i;
1592
1593
1594    if (oSrcElement) {
1595    
1596        sSrcElementTagName = 
1597            (oSrcElement.tagName && oSrcElement.tagName.toUpperCase());
1598
1599
1600        if (sSrcElementTagName == "DIV") {
1601    
1602            //  Populate the collection of item groups and item group titles
1603    
1604            oNode = this.body.firstChild;
1605    
1606
1607            if (oNode) {
1608    
1609                nGroup = 0;
1610                sGroupTitleTagName = this.GROUP_TITLE_TAG_NAME.toUpperCase();
1611        
1612                do {
1613        
1614
1615                    if (oNode && oNode.tagName) {
1616        
1617                        switch (oNode.tagName.toUpperCase()) {
1618        
1619                            case sGroupTitleTagName:
1620                            
1621                                this._aGroupTitleElements[nGroup] = oNode;
1622        
1623                            break;
1624        
1625                            case "UL":
1626        
1627                                this._aListElements[nGroup] = oNode;
1628                                this._aItemGroups[nGroup] = [];
1629                                nGroup++;
1630        
1631                            break;
1632        
1633                        }
1634                    
1635                    }
1636        
1637                }
1638                while ((oNode = oNode.nextSibling));
1639        
1640        
1641                /*
1642                    Apply the "first-of-type" class to the first UL to mimic 
1643                    the "first-of-type" CSS3 psuedo class.
1644                */
1645        
1646                if (this._aListElements[0]) {
1647        
1648                    Dom.addClass(this._aListElements[0], "first-of-type");
1649        
1650                }
1651            
1652            }
1653    
1654        }
1655    
1656    
1657        oNode = null;
1658    
1659        this.logger.log("Searching DOM for items to initialize.");
1660    
1661
1662        if (sSrcElementTagName) {
1663    
1664            switch (sSrcElementTagName) {
1665        
1666                case "DIV":
1667
1668                    aListElements = this._aListElements;
1669                    nListElements = aListElements.length;
1670        
1671                    if (nListElements > 0) {
1672        
1673                        this.logger.log("Found " + nListElements + 
1674                            " item groups to initialize.");
1675        
1676                        i = nListElements - 1;
1677        
1678                        do {
1679        
1680                            oNode = aListElements[i].firstChild;
1681            
1682                            if (oNode) {
1683
1684                                this.logger.log("Scanning " + 
1685                                    aListElements[i].childNodes.length + 
1686                                    " child nodes for items to initialize.");
1687            
1688                                do {
1689                
1690                                    if (oNode && oNode.tagName && 
1691                                        oNode.tagName.toUpperCase() == "LI") {
1692                
1693                                        this.logger.log("Initializing " + 
1694                                            oNode.tagName + " node.");
1695        
1696                                        this.addItem(new this.ITEM_TYPE(oNode, 
1697                                                    { parent: this }), i);
1698            
1699                                    }
1700                        
1701                                }
1702                                while ((oNode = oNode.nextSibling));
1703                            
1704                            }
1705                    
1706                        }
1707                        while (i--);
1708        
1709                    }
1710        
1711                break;
1712        
1713                case "SELECT":
1714        
1715                    this.logger.log("Scanning " +  
1716                        oSrcElement.childNodes.length + 
1717                        " child nodes for items to initialize.");
1718        
1719                    oNode = oSrcElement.firstChild;
1720        
1721                    do {
1722        
1723                        if (oNode && oNode.tagName) {
1724                        
1725                            switch (oNode.tagName.toUpperCase()) {
1726            
1727                                case "OPTGROUP":
1728                                case "OPTION":
1729            
1730                                    this.logger.log("Initializing " +  
1731                                        oNode.tagName + " node.");
1732            
1733                                    this.addItem(
1734                                            new this.ITEM_TYPE(
1735                                                    oNode, 
1736                                                    { parent: this }
1737                                                )
1738                                            );
1739            
1740                                break;
1741            
1742                            }
1743    
1744                        }
1745        
1746                    }
1747                    while ((oNode = oNode.nextSibling));
1748        
1749                break;
1750        
1751            }
1752    
1753        }    
1754    
1755    }
1756
1757},
1758
1759
1760/**
1761* @method _getFirstEnabledItem
1762* @description Returns the first enabled item in the menu.
1763* @return {YAHOO.widget.MenuItem}
1764* @private
1765*/
1766_getFirstEnabledItem: function () {
1767
1768    var aItems = this.getItems(),
1769        nItems = aItems.length,
1770        oItem;
1771    
1772    for(var i=0; i<nItems; i++) {
1773
1774        oItem = aItems[i];
1775
1776        if (oItem && !oItem.cfg.getProperty("disabled") && 
1777            oItem.element.style.display != "none") {
1778
1779            return oItem;
1780
1781        }
1782    
1783    }
1784    
1785},
1786
1787
1788/**
1789* @method _addItemToGroup
1790* @description Adds a menu item to a group.
1791* @private
1792* @param {Number} p_nGroupIndex Number indicating the group to which the 
1793* item belongs.
1794* @param {YAHOO.widget.MenuItem} p_oItem Object reference for the MenuItem 
1795* instance to be added to the menu.
1796* @param {String} p_oItem String specifying the text of the item to be added 
1797* to the menu.
1798* @param {Object} p_oItem Object literal containing a set of menu item 
1799* configuration properties.
1800* @param {Number} p_nItemIndex Optional. Number indicating the index at 
1801* which the menu item should be added.
1802* @return {YAHOO.widget.MenuItem}
1803*/
1804_addItemToGroup: function (p_nGroupIndex, p_oItem, p_nItemIndex) {
1805
1806    var oItem,
1807        nGroupIndex,
1808        aGroup,
1809        oGroupItem,
1810        bAppend,
1811        oNextItemSibling,
1812        nItemIndex;
1813
1814    function getNextItemSibling(p_aArray, p_nStartIndex) {
1815
1816        return (p_aArray[p_nStartIndex] || getNextItemSibling(p_aArray, 
1817                (p_nStartIndex+1)));
1818
1819    }
1820
1821    if (p_oItem instanceof this.ITEM_TYPE) {
1822
1823        oItem = p_oItem;
1824        oItem.parent = this;
1825
1826    }
1827    else if (typeof p_oItem == "string") {
1828
1829        oItem = new this.ITEM_TYPE(p_oItem, { parent: this });
1830    
1831    }
1832    else if (typeof p_oItem == "object") {
1833
1834        p_oItem.parent = this;
1835
1836        oItem = new this.ITEM_TYPE(p_oItem.text, p_oItem);
1837
1838    }
1839
1840
1841    if (oItem) {
1842
1843        if (oItem.cfg.getProperty("selected")) {
1844
1845            this.activeItem = oItem;
1846        
1847        }
1848
1849
1850        nGroupIndex = typeof p_nGroupIndex == "number" ? p_nGroupIndex : 0;
1851        aGroup = this._getItemGroup(nGroupIndex);
1852
1853
1854
1855        if (!aGroup) {
1856
1857            aGroup = this._createItemGroup(nGroupIndex);
1858
1859        }
1860
1861
1862        if (typeof p_nItemIndex == "number") {
1863
1864            bAppend = (p_nItemIndex >= aGroup.length);            
1865
1866
1867            if (aGroup[p_nItemIndex]) {
1868    
1869                aGroup.splice(p_nItemIndex, 0, oItem);
1870    
1871            }
1872            else {
1873    
1874                aGroup[p_nItemIndex] = oItem;
1875    
1876            }
1877
1878
1879            oGroupItem = aGroup[p_nItemIndex];
1880
1881            if (oGroupItem) {
1882
1883                if (bAppend && (!oGroupItem.element.parentNode || 
1884                        oGroupItem.element.parentNode.nodeType == 11)) {
1885        
1886                    this._aListElements[nGroupIndex].appendChild(
1887                        oGroupItem.element);
1888    
1889                }
1890                else {
1891    
1892                    oNextItemSibling = getNextItemSibling(aGroup, 
1893                        (p_nItemIndex+1));
1894    
1895                    if (oNextItemSibling && (!oGroupItem.element.parentNode || 
1896    

Large files files are truncated, but you can click here to view the full file