Upgrade to ExtJS 3.0.0 - Released 07/06/2009
[extjs.git] / source / widgets / menu / Menu.js
diff --git a/source/widgets/menu/Menu.js b/source/widgets/menu/Menu.js
deleted file mode 100644 (file)
index 2f990a3..0000000
+++ /dev/null
@@ -1,596 +0,0 @@
-/*\r
- * Ext JS Library 2.2.1\r
- * Copyright(c) 2006-2009, Ext JS, LLC.\r
- * licensing@extjs.com\r
- * \r
- * http://extjs.com/license\r
- */\r
-\r
-/**\r
- * @class Ext.menu.Menu\r
- * @extends Ext.util.Observable\r
- * A menu object.  This is the container to which you add all other menu items.  Menu can also serve as a base class\r
- * when you want a specialized menu based off of another component (like {@link Ext.menu.DateMenu} for example).\r
- * @constructor\r
- * Creates a new Menu\r
- * @param {Object} config Configuration options\r
- */\r
-Ext.menu.Menu = function(config){\r
-    if(Ext.isArray(config)){\r
-        config = {items:config};\r
-    }\r
-    Ext.apply(this, config);\r
-    this.id = this.id || Ext.id();\r
-    this.addEvents(\r
-        /**\r
-         * @event beforeshow\r
-         * Fires before this menu is displayed\r
-         * @param {Ext.menu.Menu} this\r
-         */\r
-        'beforeshow',\r
-        /**\r
-         * @event beforehide\r
-         * Fires before this menu is hidden\r
-         * @param {Ext.menu.Menu} this\r
-         */\r
-        'beforehide',\r
-        /**\r
-         * @event show\r
-         * Fires after this menu is displayed\r
-         * @param {Ext.menu.Menu} this\r
-         */\r
-        'show',\r
-        /**\r
-         * @event hide\r
-         * Fires after this menu is hidden\r
-         * @param {Ext.menu.Menu} this\r
-         */\r
-        'hide',\r
-        /**\r
-         * @event click\r
-         * Fires when this menu is clicked (or when the enter key is pressed while it is active)\r
-         * @param {Ext.menu.Menu} this\r
-         * @param {Ext.menu.Item} menuItem The menu item that was clicked\r
-         * @param {Ext.EventObject} e\r
-         */\r
-        'click',\r
-        /**\r
-         * @event mouseover\r
-         * Fires when the mouse is hovering over this menu\r
-         * @param {Ext.menu.Menu} this\r
-         * @param {Ext.EventObject} e\r
-         * @param {Ext.menu.Item} menuItem The menu item that was clicked\r
-         */\r
-        'mouseover',\r
-        /**\r
-         * @event mouseout\r
-         * Fires when the mouse exits this menu\r
-         * @param {Ext.menu.Menu} this\r
-         * @param {Ext.EventObject} e\r
-         * @param {Ext.menu.Item} menuItem The menu item that was clicked\r
-         */\r
-        'mouseout',\r
-        /**\r
-         * @event itemclick\r
-         * Fires when a menu item contained in this menu is clicked\r
-         * @param {Ext.menu.BaseItem} baseItem The BaseItem that was clicked\r
-         * @param {Ext.EventObject} e\r
-         */\r
-        'itemclick'\r
-    );\r
-    Ext.menu.MenuMgr.register(this);\r
-    Ext.menu.Menu.superclass.constructor.call(this);\r
-    var mis = this.items;\r
-    /**\r
-     * A MixedCollection of this Menu's items\r
-     * @property items\r
-     * @type Ext.util.MixedCollection\r
-     */\r
-\r
-    this.items = new Ext.util.MixedCollection();\r
-    if(mis){\r
-        this.add.apply(this, mis);\r
-    }\r
-};\r
-\r
-Ext.extend(Ext.menu.Menu, Ext.util.Observable, {\r
-    /**\r
-     * @cfg {Object} defaults\r
-     * A config object that will be applied to all items added to this container either via the {@link #items}\r
-     * config or via the {@link #add} method.  The defaults config can contain any number of\r
-     * name/value property pairs to be added to each item, and should be valid for the types of items\r
-     * being added to the menu.\r
-     */\r
-    /**\r
-     * @cfg {Mixed} items\r
-     * An array of items to be added to this menu.  See {@link #add} for a list of valid item types.\r
-     */\r
-    /**\r
-     * @cfg {Number} minWidth The minimum width of the menu in pixels (defaults to 120)\r
-     */\r
-    minWidth : 120,\r
-    /**\r
-     * @cfg {Boolean/String} shadow True or "sides" for the default effect, "frame" for 4-way shadow, and "drop"\r
-     * for bottom-right shadow (defaults to "sides")\r
-     */\r
-    shadow : "sides",\r
-    /**\r
-     * @cfg {String} subMenuAlign The {@link Ext.Element#alignTo} anchor position value to use for submenus of\r
-     * this menu (defaults to "tl-tr?")\r
-     */\r
-    subMenuAlign : "tl-tr?",\r
-    /**\r
-     * @cfg {String} defaultAlign The default {@link Ext.Element#alignTo} anchor position value for this menu\r
-     * relative to its element of origin (defaults to "tl-bl?")\r
-     */\r
-    defaultAlign : "tl-bl?",\r
-    /**\r
-     * @cfg {Boolean} allowOtherMenus True to allow multiple menus to be displayed at the same time (defaults to false)\r
-     */\r
-    allowOtherMenus : false,\r
-    /**\r
-     * @cfg {Boolean} ignoreParentClicks True to ignore clicks on any item in this menu that is a parent item (displays\r
-     * a submenu) so that the submenu is not dismissed when clicking the parent item (defaults to false).\r
-     */\r
-    ignoreParentClicks : false,\r
-\r
-    // private\r
-    hidden:true,\r
-\r
-    // private\r
-    createEl : function(){\r
-        return new Ext.Layer({\r
-            cls: "x-menu",\r
-            shadow:this.shadow,\r
-            constrain: false,\r
-            parentEl: this.parentEl || document.body,\r
-            zindex:15000\r
-        });\r
-    },\r
-\r
-    // private\r
-    render : function(){\r
-        if(this.el){\r
-            return;\r
-        }\r
-        var el = this.el = this.createEl();\r
-\r
-        if(!this.keyNav){\r
-            this.keyNav = new Ext.menu.MenuNav(this);\r
-        }\r
-        if(this.plain){\r
-            el.addClass("x-menu-plain");\r
-        }\r
-        if(this.cls){\r
-            el.addClass(this.cls);\r
-        }\r
-        // generic focus element\r
-        this.focusEl = el.createChild({\r
-            tag: "a", cls: "x-menu-focus", href: "#", onclick: "return false;", tabIndex:"-1"\r
-        });\r
-        var ul = el.createChild({tag: "ul", cls: "x-menu-list"});\r
-        ul.on("click", this.onClick, this);\r
-        ul.on("mouseover", this.onMouseOver, this);\r
-        ul.on("mouseout", this.onMouseOut, this);\r
-        this.items.each(function(item){\r
-            var li = document.createElement("li");\r
-            li.className = "x-menu-list-item";\r
-            ul.dom.appendChild(li);\r
-            item.render(li, this);\r
-        }, this);\r
-        this.ul = ul;\r
-        this.autoWidth();\r
-    },\r
-\r
-    // private\r
-    autoWidth : function(){\r
-        var el = this.el, ul = this.ul;\r
-        if(!el){\r
-            return;\r
-        }\r
-        var w = this.width;\r
-        if(w){\r
-            el.setWidth(w);\r
-        }else if(Ext.isIE){\r
-            el.setWidth(this.minWidth);\r
-            var t = el.dom.offsetWidth; // force recalc\r
-            el.setWidth(ul.getWidth()+el.getFrameWidth("lr"));\r
-        }\r
-    },\r
-\r
-    // private\r
-    delayAutoWidth : function(){\r
-        if(this.el){\r
-            if(!this.awTask){\r
-                this.awTask = new Ext.util.DelayedTask(this.autoWidth, this);\r
-            }\r
-            this.awTask.delay(20);\r
-        }\r
-    },\r
-\r
-    // private\r
-    findTargetItem : function(e){\r
-        var t = e.getTarget(".x-menu-list-item", this.ul,  true);\r
-        if(t && t.menuItemId){\r
-            return this.items.get(t.menuItemId);\r
-        }\r
-    },\r
-\r
-    // private\r
-    onClick : function(e){\r
-        var t;\r
-        if(t = this.findTargetItem(e)){\r
-            if(t.menu && this.ignoreParentClicks){\r
-                t.expandMenu();\r
-            }else{\r
-                t.onClick(e);\r
-                this.fireEvent("click", this, t, e);\r
-            }\r
-        }\r
-    },\r
-\r
-    // private\r
-    setActiveItem : function(item, autoExpand){\r
-        if(item != this.activeItem){\r
-            if(this.activeItem){\r
-                this.activeItem.deactivate();\r
-            }\r
-            this.activeItem = item;\r
-            item.activate(autoExpand);\r
-        }else if(autoExpand){\r
-            item.expandMenu();\r
-        }\r
-    },\r
-\r
-    // private\r
-    tryActivate : function(start, step){\r
-        var items = this.items;\r
-        for(var i = start, len = items.length; i >= 0 && i < len; i+= step){\r
-            var item = items.get(i);\r
-            if(!item.disabled && item.canActivate){\r
-                this.setActiveItem(item, false);\r
-                return item;\r
-            }\r
-        }\r
-        return false;\r
-    },\r
-\r
-    // private\r
-    onMouseOver : function(e){\r
-        var t;\r
-        if(t = this.findTargetItem(e)){\r
-            if(t.canActivate && !t.disabled){\r
-                this.setActiveItem(t, true);\r
-            }\r
-        }\r
-        this.over = true;\r
-        this.fireEvent("mouseover", this, e, t);\r
-    },\r
-\r
-    // private\r
-    onMouseOut : function(e){\r
-        var t;\r
-        if(t = this.findTargetItem(e)){\r
-            if(t == this.activeItem && t.shouldDeactivate(e)){\r
-                this.activeItem.deactivate();\r
-                delete this.activeItem;\r
-            }\r
-        }\r
-        this.over = false;\r
-        this.fireEvent("mouseout", this, e, t);\r
-    },\r
-\r
-    /**\r
-     * Read-only.  Returns true if the menu is currently displayed, else false.\r
-     * @type Boolean\r
-     */\r
-    isVisible : function(){\r
-        return this.el && !this.hidden;\r
-    },\r
-\r
-    /**\r
-     * Displays this menu relative to another element\r
-     * @param {Mixed} element The element to align to\r
-     * @param {String} position (optional) The {@link Ext.Element#alignTo} anchor position to use in aligning to\r
-     * the element (defaults to this.defaultAlign)\r
-     * @param {Ext.menu.Menu} parentMenu (optional) This menu's parent menu, if applicable (defaults to undefined)\r
-     */\r
-    show : function(el, pos, parentMenu){\r
-        this.parentMenu = parentMenu;\r
-        if(!this.el){\r
-            this.render();\r
-        }\r
-        this.fireEvent("beforeshow", this);\r
-        this.showAt(this.el.getAlignToXY(el, pos || this.defaultAlign), parentMenu, false);\r
-    },\r
-\r
-    /**\r
-     * Displays this menu at a specific xy position\r
-     * @param {Array} xyPosition Contains X & Y [x, y] values for the position at which to show the menu (coordinates are page-based)\r
-     * @param {Ext.menu.Menu} parentMenu (optional) This menu's parent menu, if applicable (defaults to undefined)\r
-     */\r
-    showAt : function(xy, parentMenu, /* private: */_e){\r
-        this.parentMenu = parentMenu;\r
-        if(!this.el){\r
-            this.render();\r
-        }\r
-        if(_e !== false){\r
-            this.fireEvent("beforeshow", this);\r
-            xy = this.el.adjustForConstraints(xy);\r
-        }\r
-        this.el.setXY(xy);\r
-        this.el.show();\r
-        this.hidden = false;\r
-        this.focus();\r
-        this.fireEvent("show", this);\r
-    },\r
-\r
-\r
-\r
-    focus : function(){\r
-        if(!this.hidden){\r
-            this.doFocus.defer(50, this);\r
-        }\r
-    },\r
-\r
-    doFocus : function(){\r
-        if(!this.hidden){\r
-            this.focusEl.focus();\r
-        }\r
-    },\r
-\r
-    /**\r
-     * Hides this menu and optionally all parent menus\r
-     * @param {Boolean} deep (optional) True to hide all parent menus recursively, if any (defaults to false)\r
-     */\r
-    hide : function(deep){\r
-        if(this.el && this.isVisible()){\r
-            this.fireEvent("beforehide", this);\r
-            if(this.activeItem){\r
-                this.activeItem.deactivate();\r
-                this.activeItem = null;\r
-            }\r
-            this.el.hide();\r
-            this.hidden = true;\r
-            this.fireEvent("hide", this);\r
-        }\r
-        if(deep === true && this.parentMenu){\r
-            this.parentMenu.hide(true);\r
-        }\r
-    },\r
-\r
-    /**\r
-     * Adds one or more items of any type supported by the Menu class, or that can be converted into menu items.\r
-     * Any of the following are valid:\r
-     * <ul>\r
-     * <li>Any menu item object based on {@link Ext.menu.BaseItem}</li>\r
-     * <li>An HTMLElement object which will be converted to a menu item</li>\r
-     * <li>A menu item config object that will be created as a new menu item</li>\r
-     * <li>A string, which can either be '-' or 'separator' to add a menu separator, otherwise\r
-     * it will be converted into a {@link Ext.menu.TextItem} and added</li>\r
-     * </ul>\r
-     * Usage:\r
-     * <pre><code>\r
-// Create the menu\r
-var menu = new Ext.menu.Menu();\r
-\r
-// Create a menu item to add by reference\r
-var menuItem = new Ext.menu.Item({ text: 'New Item!' });\r
-\r
-// Add a bunch of items at once using different methods.\r
-// Only the last item added will be returned.\r
-var item = menu.add(\r
-    menuItem,                // add existing item by ref\r
-    'Dynamic Item',          // new TextItem\r
-    '-',                     // new separator\r
-    { text: 'Config Item' }  // new item by config\r
-);\r
-</code></pre>\r
-     * @param {Mixed} args One or more menu items, menu item configs or other objects that can be converted to menu items\r
-     * @return {Ext.menu.Item} The menu item that was added, or the last one if multiple items were added\r
-     */\r
-    add : function(){\r
-        var a = arguments, l = a.length, item;\r
-        for(var i = 0; i < l; i++){\r
-            var el = a[i];\r
-            if(el.render){ // some kind of Item\r
-                item = this.addItem(el);\r
-            }else if(typeof el == "string"){ // string\r
-                if(el == "separator" || el == "-"){\r
-                    item = this.addSeparator();\r
-                }else{\r
-                    item = this.addText(el);\r
-                }\r
-            }else if(el.tagName || el.el){ // element\r
-                item = this.addElement(el);\r
-            }else if(typeof el == "object"){ // must be menu item config?\r
-                Ext.applyIf(el, this.defaults);\r
-                item = this.addMenuItem(el);\r
-            }\r
-        }\r
-        return item;\r
-    },\r
-\r
-    /**\r
-     * Returns this menu's underlying {@link Ext.Element} object\r
-     * @return {Ext.Element} The element\r
-     */\r
-    getEl : function(){\r
-        if(!this.el){\r
-            this.render();\r
-        }\r
-        return this.el;\r
-    },\r
-\r
-    /**\r
-     * Adds a separator bar to the menu\r
-     * @return {Ext.menu.Item} The menu item that was added\r
-     */\r
-    addSeparator : function(){\r
-        return this.addItem(new Ext.menu.Separator());\r
-    },\r
-\r
-    /**\r
-     * Adds an {@link Ext.Element} object to the menu\r
-     * @param {Mixed} el The element or DOM node to add, or its id\r
-     * @return {Ext.menu.Item} The menu item that was added\r
-     */\r
-    addElement : function(el){\r
-        return this.addItem(new Ext.menu.BaseItem(el));\r
-    },\r
-\r
-    /**\r
-     * Adds an existing object based on {@link Ext.menu.BaseItem} to the menu\r
-     * @param {Ext.menu.Item} item The menu item to add\r
-     * @return {Ext.menu.Item} The menu item that was added\r
-     */\r
-    addItem : function(item){\r
-        this.items.add(item);\r
-        if(this.ul){\r
-            var li = document.createElement("li");\r
-            li.className = "x-menu-list-item";\r
-            this.ul.dom.appendChild(li);\r
-            item.render(li, this);\r
-            this.delayAutoWidth();\r
-        }\r
-        return item;\r
-    },\r
-\r
-    /**\r
-     * Creates a new {@link Ext.menu.Item} based an the supplied config object and adds it to the menu\r
-     * @param {Object} config A MenuItem config object\r
-     * @return {Ext.menu.Item} The menu item that was added\r
-     */\r
-    addMenuItem : function(config){\r
-        if(!(config instanceof Ext.menu.Item)){\r
-            if(typeof config.checked == "boolean"){ // must be check menu item config?\r
-                config = new Ext.menu.CheckItem(config);\r
-            }else{\r
-                config = new Ext.menu.Item(config);\r
-            }\r
-        }\r
-        return this.addItem(config);\r
-    },\r
-\r
-    /**\r
-     * Creates a new {@link Ext.menu.TextItem} with the supplied text and adds it to the menu\r
-     * @param {String} text The text to display in the menu item\r
-     * @return {Ext.menu.Item} The menu item that was added\r
-     */\r
-    addText : function(text){\r
-        return this.addItem(new Ext.menu.TextItem(text));\r
-    },\r
-\r
-    /**\r
-     * Inserts an existing object based on {@link Ext.menu.BaseItem} to the menu at a specified index\r
-     * @param {Number} index The index in the menu's list of current items where the new item should be inserted\r
-     * @param {Ext.menu.Item} item The menu item to add\r
-     * @return {Ext.menu.Item} The menu item that was added\r
-     */\r
-    insert : function(index, item){\r
-        this.items.insert(index, item);\r
-        if(this.ul){\r
-            var li = document.createElement("li");\r
-            li.className = "x-menu-list-item";\r
-            this.ul.dom.insertBefore(li, this.ul.dom.childNodes[index]);\r
-            item.render(li, this);\r
-            this.delayAutoWidth();\r
-        }\r
-        return item;\r
-    },\r
-\r
-    /**\r
-     * Removes an {@link Ext.menu.Item} from the menu and destroys the object\r
-     * @param {Ext.menu.Item} item The menu item to remove\r
-     */\r
-    remove : function(item){\r
-        this.items.removeKey(item.id);\r
-        item.destroy();\r
-    },\r
-\r
-    /**\r
-     * Removes and destroys all items in the menu\r
-     */\r
-    removeAll : function(){\r
-       if(this.items){\r
-               var f;\r
-               while(f = this.items.first()){\r
-                   this.remove(f);\r
-               }\r
-       }\r
-    },\r
-\r
-    /**\r
-     * Destroys the menu by  unregistering it from {@link Ext.menu.MenuMgr}, purging event listeners,\r
-     * removing all of the menus items, then destroying the underlying {@link Ext.Element}\r
-     */\r
-    destroy : function(){\r
-        this.beforeDestroy();\r
-        Ext.menu.MenuMgr.unregister(this);\r
-        if (this.keyNav) {\r
-               this.keyNav.disable();\r
-        }\r
-        this.removeAll();\r
-        if (this.ul) {\r
-               this.ul.removeAllListeners();\r
-        }\r
-        if (this.el) {\r
-               this.el.destroy();\r
-        }\r
-    },\r
-\r
-       // private\r
-    beforeDestroy : Ext.emptyFn\r
-\r
-});\r
-\r
-// MenuNav is a private utility class used internally by the Menu\r
-Ext.menu.MenuNav = function(menu){\r
-    Ext.menu.MenuNav.superclass.constructor.call(this, menu.el);\r
-    this.scope = this.menu = menu;\r
-};\r
-\r
-Ext.extend(Ext.menu.MenuNav, Ext.KeyNav, {\r
-    doRelay : function(e, h){\r
-        var k = e.getKey();\r
-        if(!this.menu.activeItem && e.isNavKeyPress() && k != e.SPACE && k != e.RETURN){\r
-            this.menu.tryActivate(0, 1);\r
-            return false;\r
-        }\r
-        return h.call(this.scope || this, e, this.menu);\r
-    },\r
-\r
-    up : function(e, m){\r
-        if(!m.tryActivate(m.items.indexOf(m.activeItem)-1, -1)){\r
-            m.tryActivate(m.items.length-1, -1);\r
-        }\r
-    },\r
-\r
-    down : function(e, m){\r
-        if(!m.tryActivate(m.items.indexOf(m.activeItem)+1, 1)){\r
-            m.tryActivate(0, 1);\r
-        }\r
-    },\r
-\r
-    right : function(e, m){\r
-        if(m.activeItem){\r
-            m.activeItem.expandMenu(true);\r
-        }\r
-    },\r
-\r
-    left : function(e, m){\r
-        m.hide();\r
-        if(m.parentMenu && m.parentMenu.activeItem){\r
-            m.parentMenu.activeItem.activate();\r
-        }\r
-    },\r
-\r
-    enter : function(e, m){\r
-        if(m.activeItem){\r
-            e.stopPropagation();\r
-            m.activeItem.onClick(e);\r
-            m.fireEvent("click", this, m.activeItem);\r
-            return true;\r
-        }\r
-    }\r
-});
\ No newline at end of file