',
+ '',
+ '',
'{text}',
''
);
@@ -444,8 +444,9 @@ new Ext.TabPanel({
// private
findTargets : function(e){
- var item = null;
- var itemEl = e.getTarget('li', this.strip);
+ var item = null,
+ itemEl = e.getTarget('li:not(.x-tab-edge)', this.strip);
+
if(itemEl){
item = this.getComponent(itemEl.id.split(this.idDelimiter)[1]);
if(item.disabled){
@@ -473,7 +474,6 @@ new Ext.TabPanel({
if(t.close){
if (t.item.fireEvent('beforeclose', t.item) !== false) {
t.item.fireEvent('close', t.item);
- delete t.item.tabEl;
this.remove(t.item);
}
return;
@@ -505,8 +505,8 @@ new Ext.TabPanel({
}
var tabs = this.el.query(this.autoTabSelector);
for(var i = 0, len = tabs.length; i < len; i++){
- var tab = tabs[i];
- var title = tab.getAttribute('title');
+ var tab = tabs[i],
+ title = tab.getAttribute('title');
tab.removeAttribute('title');
this.add({
title: title,
@@ -517,26 +517,46 @@ new Ext.TabPanel({
// private
initTab : function(item, index){
- var before = this.strip.dom.childNodes[index];
- var p = this.getTemplateArgs(item);
- var el = before ?
+ var before = this.strip.dom.childNodes[index],
+ p = this.getTemplateArgs(item),
+ el = before ?
this.itemTpl.insertBefore(before, p) :
- this.itemTpl.append(this.strip, p);
+ this.itemTpl.append(this.strip, p),
+ cls = 'x-tab-strip-over',
+ tabEl = Ext.get(el);
- Ext.fly(el).addClassOnOver('x-tab-strip-over');
+ tabEl.hover(function(){
+ if(!item.disabled){
+ tabEl.addClass(cls);
+ }
+ }, function(){
+ tabEl.removeClass(cls);
+ });
if(item.tabTip){
- Ext.fly(el).child('span.x-tab-strip-text', true).qtip = item.tabTip;
+ tabEl.child('span.x-tab-strip-text', true).qtip = item.tabTip;
}
item.tabEl = el;
- item.on('disable', this.onItemDisabled, this);
- item.on('enable', this.onItemEnabled, this);
- item.on('titlechange', this.onItemTitleChanged, this);
- item.on('iconchange', this.onItemIconChanged, this);
- item.on('beforeshow', this.onBeforeShowItem, this);
+ // Route *keyboard triggered* click events to the tab strip mouse handler.
+ tabEl.select('a').on('click', function(e){
+ if(!e.getPageX()){
+ this.onStripMouseDown(e);
+ }
+ }, this, {preventDefault: true});
+
+ item.on({
+ scope: this,
+ disable: this.onItemDisabled,
+ enable: this.onItemEnabled,
+ titlechange: this.onItemTitleChanged,
+ iconchange: this.onItemIconChanged,
+ beforeshow: this.onBeforeShowItem
+ });
},
+
+
/**
* Provides template arguments for rendering a tab selector item in the tab strip.
* This method returns an object hash containing properties used by the TabPanel's {@link #itemTpl}
@@ -547,7 +567,7 @@ new Ext.TabPanel({
*
cls : StringThe CSS class name
* iconCls : StringA CSS class to provide appearance for an icon.
*
- * @param {BoxComponent} item The {@link Ext.BoxComponent BoxComponent} for which to create a selector element in the tab strip.
+ * @param {Ext.BoxComponent} item The {@link Ext.BoxComponent BoxComponent} for which to create a selector element in the tab strip.
* @return {Object} An object hash containing the properties required to render the selector element.
*/
getTemplateArgs : function(item) {
@@ -576,7 +596,7 @@ new Ext.TabPanel({
if(this.rendered){
var items = this.items;
this.initTab(c, items.indexOf(c));
- if(items.getCount() == 1){
+ if(items.getCount() == 1 && !this.collapsed){
this.syncSize();
}
this.delegateUpdates();
@@ -598,9 +618,15 @@ new Ext.TabPanel({
// private
onRemove : function(c){
+ var te = Ext.get(c.tabEl);
+ // check if the tabEl exists, it won't if the tab isn't rendered
+ if(te){
+ te.select('a').removeAllListeners();
+ Ext.destroy(te);
+ }
Ext.TabPanel.superclass.onRemove.call(this, c);
- Ext.destroy(Ext.get(this.getTabEl(c)));
this.stack.remove(c);
+ delete c.tabEl;
c.un('disable', this.onItemDisabled, this);
c.un('enable', this.onItemEnabled, this);
c.un('titlechange', this.onItemTitleChanged, this);
@@ -613,10 +639,12 @@ new Ext.TabPanel({
}else if(this.items.getCount() > 0){
this.setActiveTab(0);
}else{
- this.activeTab = null;
+ this.setActiveTab(null);
}
}
- this.delegateUpdates();
+ if(!this.destroying){
+ this.delegateUpdates();
+ }
},
// private
@@ -669,7 +697,8 @@ new Ext.TabPanel({
* @return {HTMLElement} The DOM node
*/
getTabEl : function(item){
- return document.getElementById(this.id + this.idDelimiter + this.getComponent(item).getItemId());
+ var c = this.getComponent(item);
+ return c ? c.tabEl : null;
},
// private
@@ -735,10 +764,10 @@ new Ext.TabPanel({
// private
autoSizeTabs : function(){
- var count = this.items.length;
- var ce = this.tabPosition != 'bottom' ? 'header' : 'footer';
- var ow = this[ce].dom.offsetWidth;
- var aw = this[ce].dom.clientWidth;
+ var count = this.items.length,
+ ce = this.tabPosition != 'bottom' ? 'header' : 'footer',
+ ow = this[ce].dom.offsetWidth,
+ aw = this[ce].dom.clientWidth;
if(!this.resizeTabs || count < 1 || !aw){ // !aw for display:none
return;
@@ -746,12 +775,12 @@ new Ext.TabPanel({
var each = Math.max(Math.min(Math.floor((aw-4) / count) - this.tabMargin, this.tabWidth), this.minTabWidth); // -4 for float errors in IE
this.lastTabWidth = each;
- var lis = this.strip.query("li:not([className^=x-tab-edge])");
+ var lis = this.strip.query('li:not(.x-tab-edge)');
for(var i = 0, len = lis.length; i < len; i++) {
- var li = lis[i];
- var inner = Ext.fly(li).child('.x-tab-strip-inner', true);
- var tw = li.offsetWidth;
- var iw = inner.offsetWidth;
+ var li = lis[i],
+ inner = Ext.fly(li).child('.x-tab-strip-inner', true),
+ tw = li.offsetWidth,
+ iw = inner.offsetWidth;
inner.style.width = (each - (tw-iw)) + 'px';
}
},
@@ -782,7 +811,7 @@ new Ext.TabPanel({
*/
setActiveTab : function(item){
item = this.getComponent(item);
- if(!item || this.fireEvent('beforetabchange', this, item, this.activeTab) === false){
+ if(this.fireEvent('beforetabchange', this, item, this.activeTab) === false){
return;
}
if(!this.rendered){
@@ -795,26 +824,27 @@ new Ext.TabPanel({
if(oldEl){
Ext.fly(oldEl).removeClass('x-tab-strip-active');
}
- this.activeTab.fireEvent('deactivate', this.activeTab);
}
- var el = this.getTabEl(item);
- Ext.fly(el).addClass('x-tab-strip-active');
- this.activeTab = item;
- this.stack.add(item);
-
- this.layout.setActiveItem(item);
- if(this.scrolling){
- this.scrollToTab(item, this.animScroll);
+ if(item){
+ var el = this.getTabEl(item);
+ Ext.fly(el).addClass('x-tab-strip-active');
+ this.activeTab = item;
+ this.stack.add(item);
+
+ this.layout.setActiveItem(item);
+ if(this.scrolling){
+ this.scrollToTab(item, this.animScroll);
+ }
}
-
- item.fireEvent('activate', item);
this.fireEvent('tabchange', this, item);
}
},
/**
- * Gets the currently active tab.
- * @return {Panel} The active tab
+ * Returns the Component which is the currently active tab. Note that before the TabPanel
+ * first activates a child Component, this method will return whatever was configured in the
+ * {@link #activeTab} config option.
+ * @return {BoxComponent} The currently active child Component if one is active, or the {@link #activeTab} config value.
*/
getActiveTab : function(){
return this.activeTab || null;
@@ -832,15 +862,14 @@ new Ext.TabPanel({
// private
autoScrollTabs : function(){
this.pos = this.tabPosition=='bottom' ? this.footer : this.header;
- var count = this.items.length;
- var ow = this.pos.dom.offsetWidth;
- var tw = this.pos.dom.clientWidth;
-
- var wrap = this.stripWrap;
- var wd = wrap.dom;
- var cw = wd.offsetWidth;
- var pos = this.getScrollPos();
- var l = this.edge.getOffsetsTo(this.stripWrap)[0] + pos;
+ var count = this.items.length,
+ ow = this.pos.dom.offsetWidth,
+ tw = this.pos.dom.clientWidth,
+ wrap = this.stripWrap,
+ wd = wrap.dom,
+ cw = wd.offsetWidth,
+ pos = this.getScrollPos(),
+ l = this.edge.getOffsetsTo(this.stripWrap)[0] + pos;
if(!this.enableTabScroll || count < 1 || cw < 20){ // 20 to prevent display:none issues
return;
@@ -952,11 +981,14 @@ new Ext.TabPanel({
*/
scrollToTab : function(item, animate){
- if(!item){ return; }
- var el = this.getTabEl(item);
- var pos = this.getScrollPos(), area = this.getScrollArea();
- var left = Ext.fly(el).getOffsetsTo(this.stripWrap)[0] + pos;
- var right = left + el.offsetWidth;
+ if(!item){
+ return;
+ }
+ var el = this.getTabEl(item),
+ pos = this.getScrollPos(),
+ area = this.getScrollArea(),
+ left = Ext.fly(el).getOffsetsTo(this.stripWrap)[0] + pos,
+ right = left + el.offsetWidth;
if(left < pos){
this.scrollTo(left, animate);
}else if(right > (pos + area)){
@@ -976,9 +1008,9 @@ new Ext.TabPanel({
var d = e.getWheelDelta()*this.wheelIncrement*-1;
e.stopEvent();
- var pos = this.getScrollPos();
- var newpos = pos + d;
- var sw = this.getScrollWidth()-this.getScrollArea();
+ var pos = this.getScrollPos(),
+ newpos = pos + d,
+ sw = this.getScrollWidth()-this.getScrollArea();
var s = Math.max(0, Math.min(sw, newpos));
if(s != pos){
@@ -988,9 +1020,9 @@ new Ext.TabPanel({
// private
onScrollRight : function(){
- var sw = this.getScrollWidth()-this.getScrollArea();
- var pos = this.getScrollPos();
- var s = Math.min(sw, pos + this.getScrollIncrement());
+ var sw = this.getScrollWidth()-this.getScrollArea(),
+ pos = this.getScrollPos(),
+ s = Math.min(sw, pos + this.getScrollIncrement());
if(s != pos){
this.scrollTo(s, this.animScroll);
}
@@ -998,8 +1030,8 @@ new Ext.TabPanel({
// private
onScrollLeft : function(){
- var pos = this.getScrollPos();
- var s = Math.max(0, pos - this.getScrollIncrement());
+ var pos = this.getScrollPos(),
+ s = Math.max(0, pos - this.getScrollIncrement());
if(s != pos){
this.scrollTo(s, this.animScroll);
}
@@ -1014,17 +1046,9 @@ new Ext.TabPanel({
// private
beforeDestroy : function() {
- if(this.items){
- this.items.each(function(item){
- if(item && item.tabEl){
- Ext.get(item.tabEl).removeAllListeners();
- item.tabEl = null;
- }
- }, this);
- }
- if(this.strip){
- this.strip.removeAllListeners();
- }
+ Ext.destroy(this.leftRepeater, this.rightRepeater);
+ this.deleteMembers('strip', 'edge', 'scrollLeft', 'scrollRight', 'stripWrap');
+ this.activeTab = null;
Ext.TabPanel.superclass.beforeDestroy.apply(this);
}
@@ -1113,6 +1137,6 @@ Ext.TabPanel.AccessStack = function(){
}
};
};
-
+
\ No newline at end of file