Skip to content

Commit

Permalink
Tabs: Pass appropriate data for beforeActivate event. Fixes #7136 - T…
Browse files Browse the repository at this point in the history
…abs: Rename select event to beforeActivate.
  • Loading branch information
scottgonzalez committed Apr 4, 2011
1 parent fdedf16 commit 632e6c7
Show file tree
Hide file tree
Showing 4 changed files with 117 additions and 63 deletions.
9 changes: 9 additions & 0 deletions tests/unit/tabs/tabs.html
Expand Up @@ -26,6 +26,15 @@
<script src="tabs_options.js"></script>
<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;
Expand Down
9 changes: 9 additions & 0 deletions tests/unit/tabs/tabs_deprecated.html
Expand Up @@ -25,6 +25,15 @@
<script src="tabs_tickets.js"></script>
<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;
Expand Down
69 changes: 46 additions & 23 deletions 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() {
Expand Down
93 changes: 53 additions & 40 deletions ui/jquery.ui.tabs.js
Expand Up @@ -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
Expand Down Expand Up @@ -329,73 +331,80 @@ $.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;
}
}

// 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.";
}
Expand Down Expand Up @@ -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 );
}
Expand Down

0 comments on commit 632e6c7

Please sign in to comment.