Tabs: Cleaned up add and remove methods.

This commit is contained in:
Scott González 2011-04-28 21:35:04 -04:00
parent c3d9bd0700
commit 1bacdec6be
4 changed files with 93 additions and 62 deletions

View File

@ -34,7 +34,7 @@
panel = $( $.ui.tabs.prototype._sanitizeSelector( panel = $( $.ui.tabs.prototype._sanitizeSelector(
"#" + tab.find( "a" ).attr( "aria-controls" ) ) ), "#" + tab.find( "a" ).attr( "aria-controls" ) ) ),
tabIsActive = tab.hasClass( "ui-state-active" ), tabIsActive = tab.hasClass( "ui-state-active" ),
panelIsActive = panel.is( ":visible" ); panelIsActive = panel.css( "display" ) !== "none";
if ( tabIsActive && panelIsActive ) { if ( tabIsActive && panelIsActive ) {
return 1; return 1;

View File

@ -33,7 +33,7 @@
panel = $( $.ui.tabs.prototype._sanitizeSelector( panel = $( $.ui.tabs.prototype._sanitizeSelector(
"#" + tab.find( "a" ).attr( "aria-controls" ) ) ), "#" + tab.find( "a" ).attr( "aria-controls" ) ) ),
tabIsActive = tab.hasClass( "ui-state-active" ), tabIsActive = tab.hasClass( "ui-state-active" ),
panelIsActive = panel.is( ":visible" ); panelIsActive = panel.css( "display" ) !== "none";
if ( tabIsActive && panelIsActive ) { if ( tabIsActive && panelIsActive ) {
return 1; return 1;

View File

@ -247,42 +247,78 @@ test('select', function() {
equals( evenObj.originalEvent.type, "click", "select triggered by click" ); equals( evenObj.originalEvent.type, "click", "select triggered by click" );
}); });
module("tabs (deprecated): methods"); module( "tabs (deprecated): methods" );
test('add', function() { test( "add", function() {
expect(4); expect( 18 );
el = $('#tabs1').tabs(); var element = $( "#tabs1" ).tabs();
el.tabs('add', '#new', 'New'); tabs_state( element, 1, 0, 0 );
var added = $('li:last', el).simulate('mouseover'); // add without index
ok(added.is('.ui-state-hover'), 'should add mouseover handler to added tab'); element.tabs( "add", "#new", "New" );
added.simulate('mouseout'); tabs_state( element, 1, 0, 0, 0 );
var other = $('li:first', el).simulate('mouseover'); var tab = element.find( ".ui-tabs-nav li" ).last(),
ok(other.is('.ui-state-hover'), 'should not remove mouseover handler from existing tab'); anchor = tab.find( "a" );
other.simulate('mouseout'); equals( tab.text(), "New", "label" );
equals( anchor.attr( "href" ), "#new", "href" );
equals( anchor.attr( "aria-controls" ), "new", "aria-controls" );
ok( !tab.hasClass( "ui-state-hover" ), "not hovered" );
anchor.simulate( "mouseover" );
ok( tab.hasClass( "ui-state-hover" ), "hovered" );
anchor.simulate( "click" );
tabs_state( element, 0, 0, 0, 1 );
equals($('a', added).attr('href'), '#new', 'should not expand href to full url of current page'); // add remote tab with index
element.tabs( "add", "data/test.html", "New Remote", 1 );
tabs_state( element, 0, 0, 0, 0, 1 );
tab = element.find( ".ui-tabs-nav li" ).eq( 1 );
anchor = tab.find( "a" );
equals( tab.text(), "New Remote", "label" );
equals( anchor.attr( "href" ), "data/test.html", "href" );
ok( /^ui-tabs-\d+$/.test( anchor.attr( "aria-controls" ) ), "aria controls" );
ok( !tab.hasClass( "ui-state-hover" ), "not hovered" );
anchor.simulate( "mouseover" );
ok( tab.hasClass( "ui-state-hover" ), "hovered" );
anchor.simulate( "click" );
tabs_state( element, 0, 1, 0, 0, 0 );
ok(false, "missing test - untested code is broken code."); // add to empty tab set
element = $( "<div><ul></ul></div>" ).tabs();
equals( element.tabs( "option", "active" ), false, "active: false on init" );
element.tabs( "add", "#first", "First" );
tabs_state( element, 1 );
equals( element.tabs( "option", "active" ), 0, "active: 0 after add" );
}); });
test('remove', function() { test( "#5069 - ui.tabs.add creates two tab panels when using a full URL", function() {
expect(4); expect( 2 );
el = $('#tabs1').tabs(); var element = $( "#tabs2" ).tabs();
equals( element.children( "div" ).length, element.find( ".ui-tabs-nav li" ).length );
element.tabs( "add", "/new", "New" );
equals( element.children( "div" ).length, element.find( ".ui-tabs-nav li" ).length );
});
el.tabs('remove', 0); test( "remove", function() {
equals(el.tabs('length'), 2, 'remove tab'); expect( 8 );
equals($('li a[href$="fragment-1"]', el).length, 0, 'remove associated list item');
equals($('#fragment-1').length, 0, 'remove associated panel');
// TODO delete tab -> focus tab to right var element = $( "#tabs1" ).tabs({ active: 1 });
// TODO delete last tab -> focus tab to left tabs_state( element, 0, 1, 0 );
el.tabs('select', 1); element.tabs( "remove", 1 );
el.tabs('remove', 1); tabs_state( element, 0, 1 );
equals(el.tabs('option', 'selected'), 0, 'update selected property'); equals( element.tabs( "option", "active" ), 1 );
equals( element.find( ".ui-tabs-nav li a[href$='fragment-2']" ).length, 0,
"remove correct list item" );
equals( element.find( "#fragment-2" ).length, 0, "remove correct panel" );
element.tabs( "remove", 1 );
tabs_state( element, 1 );
equals( element.tabs( "option", "active"), 0 );
element.tabs( "remove", 0 );
equals( element.tabs( "option", "active" ), false );
}); });
test('select', function() { test('select', function() {
@ -314,17 +350,6 @@ test('select', function() {
equals(el.tabs('option', 'active'), 1, 'should select tab by id'); equals(el.tabs('option', 'active'), 1, 'should select tab by id');
}); });
test('#5069 - ui.tabs.add creates two tab panels when using a full URL', function() {
// http://dev.jqueryui.com/ticket/5069
expect(2);
el = $('#tabs2').tabs();
equals(el.children('div').length, el.find('> ul > li').length, 'After creation, number of panels should be equal to number of tabs');
el.tabs('add', '/ajax_html_echo', 'Test');
equals(el.children('div').length, el.find('> ul > li').length, 'After add, number of panels should be equal to number of tabs');
});
test( "length", function() { test( "length", function() {
expect( 2 ); expect( 2 );

54
ui/jquery.ui.tabs.js vendored
View File

@ -826,33 +826,39 @@ if ( $.uiBackCompat !== false ) {
index = this.anchors.length; index = this.anchors.length;
} }
var self = this, var options = this.options,
o = this.options, li = $( options.tabTemplate
$li = $( o.tabTemplate.replace( /#\{href\}/g, url ).replace( /#\{label\}/g, label ) ), .replace( /#\{href\}/g, url )
id = !url.indexOf( "#" ) ? url.replace( "#", "" ) : this._tabId( $( "a", $li )[ 0 ] ); .replace( /#\{label\}/g, label ) ),
id = !url.indexOf( "#" ) ?
url.replace( "#", "" ) :
this._tabId( li.find( "a" )[ 0 ] );
$li.addClass( "ui-state-default ui-corner-top" ).data( "destroy.tabs", true ); li.addClass( "ui-state-default ui-corner-top" ).data( "destroy.tabs", true );
li.find( "a" ).attr( "aria-controls", id );
// try to find an existing element before creating a new one // try to find an existing element before creating a new one
var $panel = self.element.find( "#" + id ); var panel = this.element.find( "#" + id );
if ( !$panel.length ) { if ( !panel.length ) {
$panel = self._createPanel( id ); panel = this._createPanel( id );
} }
$panel.addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" ).hide(); panel.addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" ).hide();
if ( index >= this.lis.length ) { if ( index >= this.lis.length ) {
$li.appendTo( this.list ); li.appendTo( this.list );
$panel.appendTo( this.list[ 0 ].parentNode ); panel.appendTo( this.list[ 0 ].parentNode );
} else { } else {
$li.insertBefore( this.lis[ index ] ); li.insertBefore( this.lis[ index ] );
$panel.insertBefore( this.panels[ index ] ); panel.insertBefore( this.panels[ index ] );
} }
options.disabled = $.map( options.disabled, function( n ) {
o.disabled = $.map( o.disabled, function( n, i ) {
return n >= index ? ++n : n; return n >= index ? ++n : n;
}); });
this.refresh(); this.refresh();
if ( this.lis.length === 1 && options.active === false ) {
this.option( "active", 0 );
}
this._trigger( "add", null, this._ui( this.anchors[ index ], this.panels[ index ] ) ); this._trigger( "add", null, this._ui( this.anchors[ index ], this.panels[ index ] ) );
return this; return this;
@ -860,27 +866,27 @@ if ( $.uiBackCompat !== false ) {
prototype.remove = function( index ) { prototype.remove = function( index ) {
index = this._getIndex( index ); index = this._getIndex( index );
var o = this.options, var options = this.options,
$li = this.lis.eq( index ).remove(), tab = this.lis.eq( index ).remove(),
$panel = this.panels.eq( index ).remove(); panel = this.panels.eq( index ).remove();
// If selected tab was removed focus tab to the right or // If selected tab was removed focus tab to the right or
// in case the last tab was removed the tab to the left. // in case the last tab was removed the tab to the left.
if ( $li.hasClass( "ui-tabs-active" ) && this.anchors.length > 1) { if ( tab.hasClass( "ui-tabs-active" ) && this.anchors.length > 1) {
this._activate( index + ( index + 1 < this.anchors.length ? 1 : -1 ) ); this._activate( index + ( index + 1 < this.anchors.length ? 1 : -1 ) );
} }
o.disabled = $.map( options.disabled = $.map(
$.grep( o.disabled, function(n, i) { $.grep( options.disabled, function( n ) {
return n != index; return n !== index;
}), }),
function( n, i ) { function( n ) {
return n >= index ? --n : n; return n >= index ? --n : n;
}); });
this.refresh(); this.refresh();
this._trigger( "remove", null, this._ui( $li.find( "a" )[ 0 ], $panel[ 0 ] ) ); this._trigger( "remove", null, this._ui( tab.find( "a" )[ 0 ], panel[ 0 ] ) );
return this; return this;
}; };
}( jQuery, jQuery.ui.tabs.prototype ) ); }( jQuery, jQuery.ui.tabs.prototype ) );