diff options
-rw-r--r-- | tests/unit/tabs/tabs.html | 9 | ||||
-rw-r--r-- | tests/unit/tabs/tabs_deprecated.html | 9 | ||||
-rw-r--r-- | tests/unit/tabs/tabs_events.js | 69 | ||||
-rwxr-xr-x | ui/jquery.ui.tabs.js | 93 |
4 files changed, 117 insertions, 63 deletions
diff --git a/tests/unit/tabs/tabs.html b/tests/unit/tabs/tabs.html index 36e30517e..3d1c78040 100644 --- a/tests/unit/tabs/tabs.html +++ b/tests/unit/tabs/tabs.html @@ -27,6 +27,15 @@ <script src="tabs_tickets.js"></script> <script> + function tabs_state( tabs ) { + var expected = $.makeArray( arguments ).slice( 1 ); + var actual = tabs.find( ".ui-tabs-nav li" ).map(function() { + return $( this ).hasClass( "ui-state-active" ) ? 1 : 0; + }).get(); + same( actual, expected ); + } + </script> + <script> // disable this stale testsuite for testswarm only var url = window.location.search; url = decodeURIComponent( url.slice( url.indexOf("swarmURL=") + 9 ) ); diff --git a/tests/unit/tabs/tabs_deprecated.html b/tests/unit/tabs/tabs_deprecated.html index f886a9b7b..b50cebebc 100644 --- a/tests/unit/tabs/tabs_deprecated.html +++ b/tests/unit/tabs/tabs_deprecated.html @@ -26,6 +26,15 @@ <script src="tabs_deprecated.js"></script> <script> + function tabs_state( tabs ) { + var expected = $.makeArray( arguments ).slice( 1 ); + var actual = tabs.find( ".ui-tabs-nav li" ).map(function() { + return $( this ).hasClass( "ui-state-active" ) ? 1 : 0; + }).get(); + same( actual, expected ); + } + </script> + <script> // disable this stale testsuite for testswarm only var url = window.location.search; url = decodeURIComponent( url.slice( url.indexOf("swarmURL=") + 9 ) ); diff --git a/tests/unit/tabs/tabs_events.js b/tests/unit/tabs/tabs_events.js index 381326533..72c6d29e1 100644 --- a/tests/unit/tabs/tabs_events.js +++ b/tests/unit/tabs/tabs_events.js @@ -1,32 +1,55 @@ -/* - * tabs_events.js - */ -(function($) { +(function( $ ) { -module("tabs: events"); +module( "tabs: events" ); -test('beforeActivate', function() { - expect(7); +test( "beforeActivate", function() { + expect( 26 ); - el = $('#tabs1').tabs({ - beforeActivate: function(event, ui) { - ok(true, 'beforeActivate triggered after initialization'); - equals(this, el[0], "context of callback"); - equals(event.type, 'tabsbeforeactivate', 'event type in callback'); - equals(ui.tab, el.find('a')[1], 'contain tab as DOM anchor element'); - equals(ui.panel, el.find('div')[1], 'contain panel as DOM div element'); - equals(ui.index, 1, 'contain index'); - } + var element = $( "#tabs1" ).tabs({ + // TODO: should be false + active: -1, + collapsible: true + }), + tabs = element.find( ".ui-tabs-nav a" ), + panels = element.find( ".ui-tabs-panel" ); + + element.one( "tabsbeforeactivate", function( event, ui ) { + equals( ui.oldTab.size(), 0 ); + equals( ui.oldPanel.size(), 0 ); + equals( ui.newTab.size(), 1 ); + strictEqual( ui.newTab[ 0 ], tabs[ 0 ] ); + equals( ui.newPanel.size(), 1 ); + strictEqual( ui.newPanel[ 0 ], panels[ 0 ] ); + tabs_state( element, 0, 0, 0 ); }); - el.tabs('option', 'active', 1); + element.tabs( "option", "active", 0 ); + tabs_state( element, 1, 0, 0 ); - el.tabs('destroy'); - el.tabs({ - beforeActivate: function(event, ui) { - equals( event.originalEvent.type, "click", "beforeActivate triggered by click" ); - } + element.one( "tabsbeforeactivate", function( event, ui ) { + equals( ui.oldTab.size(), 1 ); + strictEqual( ui.oldTab[ 0 ], tabs[ 0 ] ); + equals( ui.oldPanel.size(), 1 ); + strictEqual( ui.oldPanel[ 0 ], panels[ 0 ] ); + equals( ui.newTab.size(), 1 ); + strictEqual( ui.newTab[ 0 ], tabs[ 1 ] ); + equals( ui.newPanel.size(), 1 ); + strictEqual( ui.newPanel[ 0 ], panels[ 1 ] ); + tabs_state( element, 1, 0, 0 ); }); - el.find( "li:eq(1) a" ).simulate( "click" ); + element.tabs( "option", "active", 1 ); + tabs_state( element, 0, 1, 0 ); + + element.one( "tabsbeforeactivate", function( event, ui ) { + equals( ui.oldTab.size(), 1 ); + strictEqual( ui.oldTab[ 0 ], tabs[ 1 ] ); + equals( ui.oldPanel.size(), 1 ); + strictEqual( ui.oldPanel[ 0 ], panels[ 1 ] ); + equals( ui.newTab.size(), 0 ); + equals( ui.newPanel.size(), 0 ); + tabs_state( element, 0, 1, 0 ); + }); + element.tabs( "option", "active", false ); + tabs_state( element, 0, 0, 0 ); }); test('beforeload', function() { diff --git a/ui/jquery.ui.tabs.js b/ui/jquery.ui.tabs.js index f9926ebef..d5ed5e67e 100755 --- a/ui/jquery.ui.tabs.js +++ b/ui/jquery.ui.tabs.js @@ -104,6 +104,8 @@ $.widget( "ui.tabs", { }); this.load( o.active ); + } else { + this.active = $(); } // clean up to avoid memory leaks in certain versions of IE 6 @@ -329,55 +331,62 @@ $.widget( "ui.tabs", { }, _eventHandler: function( event ) { - event.preventDefault(); - var self = this, - o = this.options, + var that = this, + options = that.options, + active = that.active, clicked = $( event.currentTarget ), - $li = clicked.closest( "li" ), - $hide = self.element.find( self._sanitizeSelector( $( this.active ).attr( "aria-controls" ) ) ), - $show = self.element.find( self._sanitizeSelector( clicked.attr( "aria-controls" ) ) ); - - // tab is already selected, but not collapsible - if ( ( $li.hasClass( "ui-tabs-active" ) && !o.collapsible ) || - // can't switch durning an animation - self.running || - // tab is disabled - $li.hasClass( "ui-state-disabled" ) || - // tab is already loading - $li.hasClass( "ui-tabs-loading" ) || - // allow canceling by beforeActivate event - self._trigger( "beforeActivate", event, self._ui( clicked[ 0 ], $show[ 0 ] ) ) === false ) { + clickedIsActive = clicked[ 0 ] === active[ 0 ], + collapsing = clickedIsActive && options.collapsible, + toShow = collapsing ? $() : that.element.find( that._sanitizeSelector( clicked.attr( "aria-controls" ) ) ), + toHide = !active.length ? $() : that.element.find( that._sanitizeSelector( active.attr( "aria-controls" ) ) ), + tab = clicked.closest( "li" ), + eventData = { + oldTab: active, + oldPanel: toHide, + newTab: collapsing ? $() : clicked, + newPanel: toShow + }; + + event.preventDefault(); + + if ( tab.hasClass( "ui-state-disabled" ) || + // tab is already loading + tab.hasClass( "ui-tabs-loading" ) || + // can't switch durning an animation + that.running || + // click on active header, but not collapsible + ( clickedIsActive && !options.collapsible ) || + // allow canceling activation + ( that._trigger( "beforeActivate", event, eventData ) === false ) ) { clicked[ 0 ].blur(); return; } - o.active = self.anchors.index( clicked ); - - self.active = clicked; + options.active = collapsing ? false : that.anchors.index( clicked ); - if ( self.xhr ) { - self.xhr.abort(); + that.active = clicked; + if ( that.xhr ) { + that.xhr.abort(); } // if tab may be closed - if ( o.collapsible ) { - if ( $li.hasClass( "ui-tabs-active" ) ) { - o.active = -1; - self.active = null; + if ( options.collapsible ) { + if ( collapsing ) { + options.active = false; - self.element.queue( "tabs", function() { - self._hideTab( clicked, $hide ); + that.element.queue( "tabs", function() { + that._hideTab( clicked, toHide ); }).dequeue( "tabs" ); clicked[ 0 ].blur(); return; - } else if ( !$hide.length ) { - self.element.queue( "tabs", function() { - self._showTab( clicked, $show, event ); + } else if ( !toHide.length ) { + that.element.queue( "tabs", function() { + that._showTab( clicked, toShow, event ); }); // TODO make passing in node possible, see also http://dev.jqueryui.com/ticket/3171 - self.load( self.anchors.index( clicked ) ); + that.load( that.anchors.index( clicked ) ); clicked[ 0 ].blur(); return; @@ -385,17 +394,17 @@ $.widget( "ui.tabs", { } // show new tab - if ( $show.length ) { - if ( $hide.length ) { - self.element.queue( "tabs", function() { - self._hideTab( clicked, $hide ); + if ( toShow.length ) { + if ( toHide.length ) { + that.element.queue( "tabs", function() { + that._hideTab( clicked, toHide ); }); } - self.element.queue( "tabs", function() { - self._showTab( clicked, $show, event ); + that.element.queue( "tabs", function() { + that._showTab( clicked, toShow, event ); }); - self.load( self.anchors.index( clicked ) ); + that.load( that.anchors.index( clicked ) ); } else { throw "jQuery UI Tabs: Mismatching fragment identifier."; } @@ -919,7 +928,11 @@ if ( $.uiBackCompat !== false ) { return false; } if ( type === "beforeActivate" ) { - ret = _trigger.call( this, "select", event, data ); + ret = _trigger.call( this, "select", event, { + tab: data.newTab[ 0], + panel: data.newPanel[ 0 ], + index: data.newTab.closest( "li" ).index() + }); } else if ( type === "activate" ) { ret = _trigger.call( this, "show", event, data ); } |