From c6a6ef5ee6ed026ed47a96030a341a8b08a201cf Mon Sep 17 00:00:00 2001 From: David Petersen Date: Mon, 28 Mar 2011 22:28:59 -0400 Subject: [PATCH] Tabs: Deprecate select method. Fixes #7138 Tabs: Deprecate select method --- tests/unit/tabs/tabs_deprecated.js | 30 +++++++++ tests/unit/tabs/tabs_events.js | 11 ++-- tests/unit/tabs/tabs_methods.js | 31 +--------- tests/unit/tabs/tabs_options.js | 10 +-- tests/unit/tabs/tabs_tickets.js | 6 +- ui/jquery.ui.tabs.js | 99 +++++++++++++++++++----------- 6 files changed, 110 insertions(+), 77 deletions(-) diff --git a/tests/unit/tabs/tabs_deprecated.js b/tests/unit/tabs/tabs_deprecated.js index 38fa6db71..1abaa0b04 100644 --- a/tests/unit/tabs/tabs_deprecated.js +++ b/tests/unit/tabs/tabs_deprecated.js @@ -247,6 +247,36 @@ test('remove', function() { equals(el.tabs('option', 'selected'), 0, 'update selected property'); }); +test('select', function() { + expect(6); + + el = $('#tabs1').tabs(); + + el.tabs('select', 1); + equals(el.tabs('option', 'active'), 1, 'should select tab'); + + el.tabs('destroy'); + el.tabs({ collapsible: true }); + el.tabs('select', 0); + equals(el.tabs('option', 'active'), -1, 'should collapse tab passing in the already active tab'); + + el.tabs('destroy'); + el.tabs({ collapsible: true }); + el.tabs('select', -1); + equals(el.tabs('option', 'active'), -1, 'should collapse tab passing in -1'); + + el.tabs('destroy'); + el.tabs(); + el.tabs('select', 0); + equals(el.tabs('option', 'active'), 0, 'should not collapse tab if collapsible is not set to true'); + el.tabs('select', -1); + equals(el.tabs('option', 'active'), 0, 'should not collapse tab if collapsible is not set to true'); + + el.tabs('select', '#fragment-2'); + 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); diff --git a/tests/unit/tabs/tabs_events.js b/tests/unit/tabs/tabs_events.js index 4fedde842..381326533 100644 --- a/tests/unit/tabs/tabs_events.js +++ b/tests/unit/tabs/tabs_events.js @@ -8,7 +8,6 @@ module("tabs: events"); test('beforeActivate', function() { expect(7); - var eventObj; el = $('#tabs1').tabs({ beforeActivate: function(event, ui) { ok(true, 'beforeActivate triggered after initialization'); @@ -17,13 +16,17 @@ test('beforeActivate', function() { 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'); - evenObj = event; } }); - el.tabs('select', 1); + el.tabs('option', 'active', 1); + el.tabs('destroy'); + el.tabs({ + beforeActivate: function(event, ui) { + equals( event.originalEvent.type, "click", "beforeActivate triggered by click" ); + } + }); el.find( "li:eq(1) a" ).simulate( "click" ); - equals( evenObj.originalEvent.type, "click", "beforeActivate triggered by click" ); }); test('beforeload', function() { diff --git a/tests/unit/tabs/tabs_methods.js b/tests/unit/tabs/tabs_methods.js index dbb5c2d15..69dcc872e 100644 --- a/tests/unit/tabs/tabs_methods.js +++ b/tests/unit/tabs/tabs_methods.js @@ -130,35 +130,6 @@ test('disable', function() { same(el.tabs('option', 'disabled'), true, 'set to true'); }); -test('select', function() { - expect(6); - - el = $('#tabs1').tabs(); - - el.tabs('select', 1); - equals(el.tabs('option', 'active'), 1, 'should select tab'); - - el.tabs('destroy'); - el.tabs({ collapsible: true }); - el.tabs('select', 0); - equals(el.tabs('option', 'active'), -1, 'should collapse tab passing in the already active tab'); - - el.tabs('destroy'); - el.tabs({ collapsible: true }); - el.tabs('select', -1); - equals(el.tabs('option', 'active'), -1, 'should collapse tab passing in -1'); - - el.tabs('destroy'); - el.tabs(); - el.tabs('select', 0); - equals(el.tabs('option', 'active'), 0, 'should not collapse tab if collapsible is not set to true'); - el.tabs('select', -1); - equals(el.tabs('option', 'active'), 0, 'should not collapse tab if collapsible is not set to true'); - - el.tabs('select', '#fragment-2'); - equals(el.tabs('option', 'active'), 1, 'should select tab by id'); -}); - test('refresh', function() { expect(5); @@ -178,7 +149,7 @@ test('refresh', function() { ul.append('
  • Test 1
  • '); $('
    Test Panel 1
    ').insertAfter( ul ); el.tabs('refresh'); - el.tabs('select', 0); + el.tabs('option', 'active', 0); equals( el.tabs('option', 'active'), 0, 'First tab added should be auto active'); ul.append('
  • Test 2
  • '); diff --git a/tests/unit/tabs/tabs_options.js b/tests/unit/tabs/tabs_options.js index b1a7a5e78..1352a68e5 100644 --- a/tests/unit/tabs/tabs_options.js +++ b/tests/unit/tabs/tabs_options.js @@ -13,8 +13,10 @@ test('collapsible', function() { el.tabs({ collapsible: true }); equals(el.tabs('option', 'collapsible'), true, 'option set'); ok(el.is('.ui-tabs-collapsible'), 'extra class "ui-tabs-collapsible" attached'); - el.tabs('select', 0); + + el.tabs('option', 'active', false); equals($('div.ui-tabs-hide', '#tabs1').length, 3, 'all panels should be hidden'); + el.tabs('option', 'collapsible', false); ok(el.is(':not(.ui-tabs-collapsible)'), 'extra class "ui-tabs-collapsible" not attached'); @@ -37,8 +39,8 @@ test('cookie', function() { el.tabs({ active: 1, cookie: cookieObj }); equals(cookie(), 1, 'initial cookie value, from active property'); - el.tabs('select', 2); - equals(cookie(), 2, 'cookie value updated after select'); + el.tabs('option', 'active', 2); + equals(cookie(), 2, 'cookie value updated after activating'); el.tabs('destroy'); $.cookie(cookieName, 1); @@ -47,7 +49,7 @@ test('cookie', function() { el.tabs('destroy'); el.tabs({ cookie: cookieObj, collapsible: true }); - el.tabs('select', 0); + el.tabs('option', 'active', false); equals(cookie(), -1, 'cookie value for all tabs unselected'); el.tabs('destroy'); diff --git a/tests/unit/tabs/tabs_tickets.js b/tests/unit/tabs/tabs_tickets.js index 486d3b6d2..9ff4d6f92 100644 --- a/tests/unit/tabs/tabs_tickets.js +++ b/tests/unit/tabs/tabs_tickets.js @@ -13,7 +13,7 @@ test('#2715 - id containing colon', function() { ok( $('div.ui-tabs-panel:eq(0)', '#tabs2').is(':visible'), 'first panel should be visible' ); ok( $('div.ui-tabs-panel:eq(1)', '#tabs2').is(':hidden'), 'second panel should be hidden' ); - el.tabs('select', 1).tabs('select', 0); + el.tabs('option', 'active', 1).tabs('option', 'active', 0); ok( $('div.ui-tabs-panel:eq(0)', '#tabs2').is(':visible'), 'first panel should be visible' ); ok( $('div.ui-tabs-panel:eq(1)', '#tabs2').is(':hidden'), 'second panel should be hidden' ); @@ -30,10 +30,10 @@ test('#???? - panel containing inline style', function() { el = $('#tabs2').tabs(); equals(inlineStyle('height'), expected, 'init should not remove inline style'); - el.tabs('select', 1); + el.tabs('option', 'active', 1); equals(inlineStyle('height'), expected, 'show tab should not remove inline style'); - el.tabs('select', 0); + el.tabs('option', 'active', 0); equals(inlineStyle('height'), expected, 'hide tab should not remove inline style'); }); diff --git a/ui/jquery.ui.tabs.js b/ui/jquery.ui.tabs.js index 8508f0adb..b35a91e51 100755 --- a/ui/jquery.ui.tabs.js +++ b/ui/jquery.ui.tabs.js @@ -96,8 +96,8 @@ $.widget( "ui.tabs", { this.lis.removeClass( "ui-tabs-selected ui-state-active" ); // check for length avoids error when initializing empty list if ( o.active >= 0 && this.anchors.length ) { - var tab = self.anchors[ o.active ], - panel = self.element.find( self._sanitizeSelector( $( tab ).attr( "aria-controls" ) ) ); + this.active = this._findActive( o.active ); + var panel = self.element.find( self._sanitizeSelector( this.active.attr( "aria-controls" ) ) ); panel.removeClass( "ui-tabs-hide" ); @@ -105,7 +105,7 @@ $.widget( "ui.tabs", { // seems to be expected behavior that the activate callback is fired self.element.queue( "tabs", function() { - self._trigger( "activate", null, self._ui( tab, panel[ 0 ] ) ); + self._trigger( "activate", null, self._ui( self.active[ 0 ], panel[ 0 ] ) ); }); this.load( o.active ); @@ -120,10 +120,9 @@ $.widget( "ui.tabs", { _setOption: function( key, value ) { if ( key == "active" ) { - if (this.options.collapsible && value == this.options.active ) { - return; - } - this.select( value ); + // _activate() will handle invalid values and update this.option + this._activate( value ); + return } else { this.options[ key ] = value; this.refresh(); @@ -350,10 +349,10 @@ $.widget( "ui.tabs", { event.preventDefault(); var self = this, o = this.options, - el = event.currentTarget, - $li = $( el ).closest( "li" ), + clicked = $( event.currentTarget ), + $li = clicked.closest( "li" ), $hide = self.panels.filter( ":not(.ui-tabs-hide)" ), - $show = self.element.find( self._sanitizeSelector( $( el ).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-selected" ) && !o.collapsible ) || @@ -364,12 +363,14 @@ $.widget( "ui.tabs", { // tab is already loading $li.hasClass( "ui-state-processing" ) || // allow canceling by beforeActivate event - self._trigger( "beforeActivate", event, self._ui( el, $show[ 0 ] ) ) === false ) { - el.blur(); + self._trigger( "beforeActivate", event, self._ui( clicked[ 0 ], $show[ 0 ] ) ) === false ) { + clicked[ 0 ].blur(); return; } - o.active = self.anchors.index( el ); + o.active = self.anchors.index( clicked ); + + self.active = clicked; if ( self.xhr ) { self.xhr.abort(); @@ -379,16 +380,17 @@ $.widget( "ui.tabs", { if ( o.collapsible ) { if ( $li.hasClass( "ui-tabs-selected" ) ) { o.active = -1; + self.active = null; if ( o.cookie ) { self._cookie( o.active, o.cookie ); } self.element.queue( "tabs", function() { - self._hideTab( el, $hide ); + self._hideTab( clicked, $hide ); }).dequeue( "tabs" ); - el.blur(); + clicked[ 0 ].blur(); return; } else if ( !$hide.length ) { if ( o.cookie ) { @@ -396,13 +398,13 @@ $.widget( "ui.tabs", { } self.element.queue( "tabs", function() { - self._showTab( el, $show, event ); + self._showTab( clicked, $show, event ); }); // TODO make passing in node possible, see also http://dev.jqueryui.com/ticket/3171 - self.load( self.anchors.index( el ) ); + self.load( self.anchors.index( clicked ) ); - el.blur(); + clicked[ 0 ].blur(); return; } } @@ -415,14 +417,14 @@ $.widget( "ui.tabs", { if ( $show.length ) { if ( $hide.length ) { self.element.queue( "tabs", function() { - self._hideTab( el, $hide ); + self._hideTab( clicked, $hide ); }); } self.element.queue( "tabs", function() { - self._showTab( el, $show, event ); + self._showTab( clicked, $show, event ); }); - self.load( self.anchors.index( el ) ); + self.load( self.anchors.index( clicked ) ); } else { throw "jQuery UI Tabs: Mismatching fragment identifier."; } @@ -432,8 +434,31 @@ $.widget( "ui.tabs", { // in modern browsers; blur() removes focus from address bar in Firefox // which can become a usability if ( $.browser.msie ) { - el.blur(); + clicked[ 0 ].blur(); + } + }, + + _activate: function( index ) { + var active = this._findActive( index )[ 0 ]; + + // trying to activate the already active panel + if ( this.active && active === this.active[ 0 ] ) { + return; } + + // trying to collapse, simulate a click on the current active header + active = active || this.active; + + this._eventHandler({ + target: active, + currentTarget: active, + preventDefault: $.noop + }); + }, + + _findActive: function( selector ) { + return typeof selector === "number" ? this.anchors.eq( selector ) : + typeof selector === "string" ? this.anchors.filter( "[href$='" + selector + "']" ) : $(); }, _getIndex: function( index ) { @@ -539,19 +564,6 @@ $.widget( "ui.tabs", { return this; }, - select: function( index ) { - index = this._getIndex( index ); - if ( index == -1 ) { - if ( this.options.collapsible && this.options.active != -1 ) { - index = this.options.active; - } else { - return this; - } - } - this.anchors.eq( index ).trigger( this.options.event + ".tabs" ); - return this; - }, - load: function( index ) { index = this._getIndex( index ); var self = this, @@ -834,7 +846,7 @@ if ( $.uiBackCompat !== false ) { // If selected tab was removed focus tab to the right or // in case the last tab was removed the tab to the left. if ( $li.hasClass( "ui-tabs-selected" ) && this.anchors.length > 1) { - this.select( index + ( index + 1 < this.anchors.length ? 1 : -1 ) ); + this._activate( index + ( index + 1 < this.anchors.length ? 1 : -1 ) ); } o.disabled = $.map( @@ -947,6 +959,21 @@ if ( $.uiBackCompat !== false ) { } }; }( jQuery, jQuery.ui.tabs.prototype ) ); + + // select method + (function( $, prototype ) { + prototype.select = function( index ) { + index = this._getIndex( index ); + if ( index == -1 ) { + if ( this.options.collapsible && this.options.selected != -1 ) { + index = this.options.selected; + } else { + return; + } + } + this.anchors.eq( index ).trigger( this.options.event + ".tabs" ); + }; + }( jQuery, jQuery.ui.tabs.prototype ) ); } })( jQuery ); -- 2.39.5