X-Git-Url: http://git.ithinksw.org/extjs.git/blobdiff_plain/c930e9176a5a85509c5b0230e2bff5c22a591432..25ef3491bd9ae007ff1fc2b0d7943e6eaaccf775:/src/widgets/menu/Menu.js diff --git a/src/widgets/menu/Menu.js b/src/widgets/menu/Menu.js index 04b4874c..3a348b1f 100644 --- a/src/widgets/menu/Menu.js +++ b/src/widgets/menu/Menu.js @@ -1,5 +1,5 @@ /*! - * Ext JS Library 3.0.0 + * Ext JS Library 3.0.3 * Copyright(c) 2006-2009 Ext JS, LLC * licensing@extjs.com * http://www.extjs.com/license @@ -10,10 +10,13 @@ *
Layout manager used by {@link Ext.menu.Menu}. Generally this class should not need to be used directly.
*/ Ext.layout.MenuLayout = Ext.extend(Ext.layout.ContainerLayout, { - monitorResize: true, + monitorResize : true, setContainer : function(ct){ this.monitorResize = !ct.floating; + // This event is only fired by the menu in IE, used so we don't couple + // the menu with the layout. + ct.on('autosize', this.doAutoSize, this); Ext.layout.MenuLayout.superclass.setContainer.call(this, ct); }, @@ -40,13 +43,14 @@ this.itemTpl.append(target, a, true)); // Link the containingBy default, a Menu configured as floating:true
+ * will be rendered as an {@link Ext.Layer} (an absolutely positioned,
+ * floating Component with zindex=15000).
+ * If configured as floating:false
, the Menu may be
+ * used as child item of another Container instead of a free-floating
+ * {@link Ext.Layer Layer}.
*/
- floating: true, // Render as a Layer by default
+ floating : true,
// private
- hidden: true,
- layout: 'menu',
- hideMode: 'offsets', // Important for laying out Components
- scrollerHeight: 8,
- autoLayout: true, // Provided for backwards compat
- defaultType: 'menuitem',
-
- initComponent: function(){
+ hidden : true,
+
+ /**
+ * @cfg {String/Object} layout
+ * This class assigns a default layout (layout:'menu'
).
+ * Developers may override this configuration option if another layout is required.
+ * See {@link Ext.Container#layout} for additional information.
+ */
+ layout : 'menu',
+ hideMode : 'offsets', // Important for laying out Components
+ scrollerHeight : 8,
+ autoLayout : true, // Provided for backwards compat
+ defaultType : 'menuitem',
+
+ initComponent : function(){
if(Ext.isArray(this.initialConfig)){
Ext.apply(this, {items:this.initialConfig});
}
@@ -300,7 +320,7 @@ Ext.menu.Menu = Ext.extend(Ext.Container, {
// private
findTargetItem : function(e){
- var t = e.getTarget(".x-menu-list-item", this.ul, true);
+ var t = e.getTarget('.x-menu-list-item', this.ul, true);
if(t && t.menuItemId){
return this.items.get(t.menuItemId);
}
@@ -312,13 +332,13 @@ Ext.menu.Menu = Ext.extend(Ext.Container, {
if(t){
if(t.isFormField){
this.setActiveItem(t);
- }else{
+ }else if(t instanceof Ext.menu.BaseItem){
if(t.menu && this.ignoreParentClicks){
t.expandMenu();
e.preventDefault();
}else if(t.onClick){
t.onClick(e);
- this.fireEvent("click", this, t, e);
+ this.fireEvent('click', this, t, e);
}
}
}
@@ -338,7 +358,7 @@ Ext.menu.Menu = Ext.extend(Ext.Container, {
}
},
- deactivateActive: function(){
+ deactivateActive : function(){
var a = this.activeItem;
if(a){
if(a.isFormField){
@@ -375,7 +395,7 @@ Ext.menu.Menu = Ext.extend(Ext.Container, {
}
}
this.over = true;
- this.fireEvent("mouseover", this, e, t);
+ this.fireEvent('mouseover', this, e, t);
},
// private
@@ -388,11 +408,11 @@ Ext.menu.Menu = Ext.extend(Ext.Container, {
}
}
this.over = false;
- this.fireEvent("mouseout", this, e, t);
+ this.fireEvent('mouseout', this, e, t);
},
// private
- onScroll: function(e, t){
+ onScroll : function(e, t){
if(e){
e.stopEvent();
}
@@ -404,7 +424,7 @@ Ext.menu.Menu = Ext.extend(Ext.Container, {
},
// private
- onScrollerIn: function(e, t){
+ onScrollerIn : function(e, t){
var ul = this.ul.dom, top = Ext.fly(t).is('.x-menu-scroller-top');
if(top ? ul.scrollTop > 0 : ul.scrollTop + this.activeMax < ul.scrollHeight){
Ext.fly(t).addClass(['x-menu-item-active', 'x-menu-scroller-active']);
@@ -412,12 +432,13 @@ Ext.menu.Menu = Ext.extend(Ext.Container, {
},
// private
- onScrollerOut: function(e, t){
+ onScrollerOut : function(e, t){
Ext.fly(t).removeClass(['x-menu-item-active', 'x-menu-scroller-active']);
},
/**
- * Displays this menu relative to another element
+ * If {@link #floating}=true
, shows this menu relative to
+ * another element using {@link #showat}, otherwise uses {@link Ext.Component#show}.
* @param {Mixed} element The element to align to
* @param {String} position (optional) The {@link Ext.Element#alignTo} anchor position to use in aligning to
* the element (defaults to this.defaultAlign)
@@ -430,42 +451,51 @@ Ext.menu.Menu = Ext.extend(Ext.Container, {
this.render();
this.doLayout(false, true);
}
- if(this.fireEvent('beforeshow', this) !== false){
- this.showAt(this.el.getAlignToXY(el, pos || this.defaultAlign, this.defaultOffsets), parentMenu, false);
- }
+ this.showAt(this.el.getAlignToXY(el, pos || this.defaultAlign, this.defaultOffsets), parentMenu);
}else{
Ext.menu.Menu.superclass.show.call(this);
}
},
/**
- * Displays this menu at a specific xy position
+ * Displays this menu at a specific xy position and fires the 'show' event if a
+ * handler for the 'beforeshow' event does not return false cancelling the operation.
* @param {Array} xyPosition Contains X & Y [x, y] values for the position at which to show the menu (coordinates are page-based)
* @param {Ext.menu.Menu} parentMenu (optional) This menu's parent menu, if applicable (defaults to undefined)
*/
- showAt : function(xy, parentMenu, /* private: */_e){
- this.parentMenu = parentMenu;
- if(!this.el){
- this.render();
- }
- this.el.setXY(xy);
- if(this.enableScrolling){
- this.constrainScroll(xy[1]);
- }
- this.el.show();
- Ext.menu.Menu.superclass.onShow.call(this);
- if(Ext.isIE){
- this.layout.doAutoSize();
- if(!Ext.isIE8){
- this.el.repaint();
+ showAt : function(xy, parentMenu){
+ if(this.fireEvent('beforeshow', this) !== false){
+ this.parentMenu = parentMenu;
+ if(!this.el){
+ this.render();
+ }
+ if(this.enableScrolling){
+ // set the position so we can figure out the constrain value.
+ this.el.setXY(xy);
+ //constrain the value, keep the y coordinate the same
+ this.constrainScroll(xy[1]);
+ xy = [this.el.adjustForConstraints(xy)[0], xy[1]];
+ }else{
+ //constrain to the viewport.
+ xy = this.el.adjustForConstraints(xy);
}
+ this.el.setXY(xy);
+ this.el.show();
+ Ext.menu.Menu.superclass.onShow.call(this);
+ if(Ext.isIE){
+ // internal event, used so we don't couple the layout to the menu
+ this.fireEvent('autosize', this);
+ if(!Ext.isIE8){
+ this.el.repaint();
+ }
+ }
+ this.hidden = false;
+ this.focus();
+ this.fireEvent('show', this);
}
- this.hidden = false;
- this.focus();
- this.fireEvent("show", this);
},
- constrainScroll: function(y){
+ constrainScroll : function(y){
var max, full = this.ul.setHeight('auto').getHeight();
if(this.floating){
max = this.maxHeight ? this.maxHeight : Ext.fly(this.el.dom.parentNode).getViewSize().height - y;
@@ -484,7 +514,7 @@ Ext.menu.Menu = Ext.extend(Ext.Container, {
this.ul.dom.scrollTop = 0;
},
- createScrollers: function(){
+ createScrollers : function(){
if(!this.scroller){
this.scroller = {
pos: 0,
@@ -514,7 +544,7 @@ Ext.menu.Menu = Ext.extend(Ext.Container, {
}
},
- onLayout: function(){
+ onLayout : function(){
if(this.isVisible()){
if(this.enableScrolling){
this.constrainScroll(this.el.getTop());
@@ -548,19 +578,24 @@ Ext.menu.Menu = Ext.extend(Ext.Container, {
},
// private
- onHide: function(){
+ onHide : function(){
Ext.menu.Menu.superclass.onHide.call(this);
this.deactivateActive();
if(this.el && this.floating){
this.el.hide();
}
- if(this.deepHide === true && this.parentMenu){
- this.parentMenu.hide(true);
+ var pm = this.parentMenu;
+ if(this.deepHide === true && pm){
+ if(pm.floating){
+ pm.hide(true);
+ }else{
+ pm.deactivateActive();
+ }
}
},
// private
- lookupComponent: function(c){
+ lookupComponent : function(c){
if(Ext.isString(c)){
c = (c == 'separator' || c == '-') ? new Ext.menu.Separator() : new Ext.menu.TextItem(c);
this.applyDefaults(c);
@@ -593,7 +628,7 @@ Ext.menu.Menu = Ext.extend(Ext.Container, {
},
// private
- getMenuItem: function(config){
+ getMenuItem : function(config){
if(!config.isXType){
if(!config.xtype && Ext.isBoolean(config.checked)){
return new Ext.menu.CheckItem(config)
@@ -659,6 +694,11 @@ Ext.menu.Menu = Ext.extend(Ext.Container, {
if(s){
Ext.destroy(s.topRepeater, s.bottomRepeater, s.top, s.bottom);
}
+ Ext.destroy(
+ this.el,
+ this.focusEl,
+ this.ul
+ );
}
});
@@ -677,7 +717,7 @@ Ext.menu.MenuNav = Ext.extend(Ext.KeyNav, function(){
}
}
return {
- constructor: function(menu){
+ constructor : function(menu){
Ext.menu.MenuNav.superclass.constructor.call(this, menu.el);
this.scope = this.menu = menu;
},
@@ -725,9 +765,9 @@ Ext.menu.MenuNav = Ext.extend(Ext.KeyNav, function(){
if(m.activeItem){
e.stopPropagation();
m.activeItem.onClick(e);
- m.fireEvent("click", this, m.activeItem);
+ m.fireEvent('click', this, m.activeItem);
return true;
}
}
};
-}());
\ No newline at end of file
+}());