Skip to content

Commit ecf672b

Browse files
committed
Tabs: Add classes option
1 parent 73f1e27 commit ecf672b

File tree

5 files changed

+98
-44
lines changed

5 files changed

+98
-44
lines changed

tests/unit/tabs/tabs_common.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,16 @@
11
TestHelpers.commonWidgetTests( "tabs", {
22
defaults: {
33
active: null,
4+
classes: {
5+
"ui-tabs": "ui-corner-all",
6+
"ui-tabs-collapsible": "",
7+
"ui-tabs-active": "",
8+
"ui-tabs-nav": "ui-corner-all",
9+
"ui-tab": "ui-corner-top",
10+
"ui-tabs-anchor": "",
11+
"ui-tabs-panel": "ui-corner-bottom",
12+
"ui-tabs-loading": ""
13+
},
414
collapsible: false,
515
disabled: false,
616
event: "click",

tests/unit/tabs/tabs_core.js

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,25 @@ var state = TestHelpers.tabs.state;
55
module( "tabs: core" );
66

77
test( "markup structure", function() {
8-
expect( 3 );
9-
var element = $( "#tabs1" ).tabs();
10-
ok( element.hasClass( "ui-tabs" ), "main element is .ui-tabs" );
11-
ok( element.find( "ul" ).hasClass( "ui-tabs-nav" ), "list item is .ui-tabs-nav" );
12-
equal( element.find( ".ui-tabs-panel" ).length, 3,
8+
expect( 7 );
9+
var element = $( "#tabs1" ).tabs(),
10+
ul = element.find( "ul.ui-tabs-nav" ),
11+
tabs = ul.find( "li" ),
12+
active = tabs.eq( 0 );
13+
14+
ok( element.is( ".ui-tabs.ui-widget.ui-widget-content.ui-corner-all" ),
15+
"main element has proper classes" );
16+
ok( !element.hasClass( "ui-tabs-collapsible" ), "main element is not .ui-tabs-collapsible" );
17+
18+
ok( ul.is( ".ui-tabs-nav.ui-widget-header.ui-corner-all" ), "list has proper classes" );
19+
20+
ok( tabs.is( ".ui-tab.ui-corner-top.ui-state-default" ), "tabs have proper classes" );
21+
22+
ok( element.find( "a" ).hasClass( "ui-tabs-anchor" ), "link item is .ui-tabs-anchor" );
23+
24+
ok( active.is( ".ui-tabs-active.ui-state-active" ), "active item has proper classes" );
25+
26+
equal( element.find( ".ui-tabs-panel.ui-widget-content.ui-corner-bottom" ).length, 3,
1327
".ui-tabs-panel elements exist, correct number" );
1428
});
1529

@@ -130,17 +144,20 @@ test( "accessibility", function() {
130144
});
131145

132146
asyncTest( "accessibility - ajax", function() {
133-
expect( 4 );
147+
expect( 6 );
134148
var element = $( "#tabs2" ).tabs(),
149+
tab = element.find( ".ui-tabs-nav li" ).eq( 3 ),
135150
panel = $( "#custom-id" );
136151

137152
equal( panel.attr( "aria-live" ), "polite", "remote panel has aria-live" );
138153
equal( panel.attr( "aria-busy" ), null, "does not have aria-busy on init" );
139154
element.tabs( "option", "active", 3 );
140155
equal( panel.attr( "aria-busy" ), "true", "panel has aria-busy during load" );
156+
ok( tab.hasClass( "ui-tabs-loading" ), "tab is .ui-tabs-loading during load" );
141157
element.one( "tabsload", function() {
142158
setTimeout(function() {
143159
equal( panel.attr( "aria-busy" ), null, "panel does not have aria-busy after load" );
160+
ok( !tab.hasClass( "ui-tabs-loading" ), "tab is not .ui-tabs-loading after load" );
144161
start();
145162
}, 1 );
146163
});

tests/unit/tabs/tabs_methods.js

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,22 @@ test( "destroy", function() {
1515
});
1616
});
1717

18+
asyncTest( "destroy - ajax", function() {
19+
expect( 1 );
20+
domEqual( "#tabs2", function( done ) {
21+
var element = $( "#tabs2" ).tabs({
22+
load: function() {
23+
setTimeout(function() {
24+
element.tabs( "destroy" );
25+
done();
26+
start();
27+
});
28+
}
29+
});
30+
element.tabs( "option", "active", 2 );
31+
});
32+
});
33+
1834
test( "enable", function() {
1935
expect( 8 );
2036

tests/unit/tabs/tabs_options.js

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,12 +123,13 @@ test( "{ collapsible: false }", function() {
123123
});
124124

125125
test( "{ collapsible: true }", function() {
126-
expect( 6 );
126+
expect( 9 );
127127

128128
var element = $( "#tabs1" ).tabs({
129129
active: 1,
130130
collapsible: true
131131
});
132+
ok( element.hasClass( "ui-tabs-collapsible" ), "main element is .ui-tabs-collapsible" );
132133

133134
element.tabs( "option", "active", false );
134135
equal( element.tabs( "option", "active" ), false );
@@ -141,6 +142,12 @@ test( "{ collapsible: true }", function() {
141142
element.find( ".ui-state-active .ui-tabs-anchor" ).click();
142143
equal( element.tabs( "option", "active" ), false );
143144
state( element, 0, 0, 0 );
145+
146+
element.tabs( "option", "collapsible", false );
147+
ok( !element.hasClass( "ui-tabs-collapsible" ), "main element is not .ui-tabs-collapsible" );
148+
149+
element.tabs( "option", "collapsible", true );
150+
ok( element.hasClass( "ui-tabs-collapsible" ), "main element is .ui-tabs-collapsible" );
144151
});
145152

146153
test( "disabled", function() {

ui/tabs.js

Lines changed: 41 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,16 @@ return $.widget( "ui.tabs", {
2929
delay: 300,
3030
options: {
3131
active: null,
32+
classes: {
33+
"ui-tabs": "ui-corner-all",
34+
"ui-tabs-collapsible": "",
35+
"ui-tabs-active": "",
36+
"ui-tabs-nav": "ui-corner-all",
37+
"ui-tab": "ui-corner-top",
38+
"ui-tabs-anchor": "",
39+
"ui-tabs-panel": "ui-corner-bottom",
40+
"ui-tabs-loading": ""
41+
},
3242
collapsible: false,
3343
event: "click",
3444
heightStyle: "content",
@@ -69,9 +79,8 @@ return $.widget( "ui.tabs", {
6979

7080
this.running = false;
7181

72-
this.element
73-
.addClass( "ui-tabs ui-widget ui-widget-content ui-corner-all" )
74-
.toggleClass( "ui-tabs-collapsible", options.collapsible );
82+
this._addClass( "ui-tabs", "ui-widget ui-widget-content" );
83+
this[ ( options.collapsible ? "_add" : "_remove" ) + "Class" ]( "ui-tabs-collapsible" );
7584

7685
this._processTabs();
7786
options.active = this._initialActive();
@@ -278,7 +287,7 @@ return $.widget( "ui.tabs", {
278287
this._super( key, value);
279288

280289
if ( key === "collapsible" ) {
281-
this.element.toggleClass( "ui-tabs-collapsible", value );
290+
this[ ( value ? "_add" : "_remove" ) + "Class" ]( "ui-tabs-collapsible" );
282291
// Setting collapsible: false while collapsed; open first panel
283292
if ( !value && this.options.active === false ) {
284293
this._activate( 0 );
@@ -354,12 +363,13 @@ return $.widget( "ui.tabs", {
354363
this.tabs.eq( 0 ).attr( "tabIndex", 0 );
355364
} else {
356365
this.active
357-
.addClass( "ui-tabs-active ui-state-active" )
358366
.attr({
359367
"aria-selected": "true",
360368
"aria-expanded": "true",
361369
tabIndex: 0
362370
});
371+
372+
this._addClass( this.active, "ui-tabs-active", "ui-state-active" );
363373
this._getPanelForTab( this.active )
364374
.show()
365375
.attr({
@@ -374,12 +384,13 @@ return $.widget( "ui.tabs", {
374384
prevAnchors = this.anchors,
375385
prevPanels = this.panels;
376386

377-
this.tablist = this._getList()
378-
.addClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" )
379-
.attr( "role", "tablist" )
387+
this.tablist = this._getList().attr( "role", "tablist" );
388+
389+
this._addClass( this.tablist, "ui-tabs-nav",
390+
"ui-helper-reset ui-helper-clearfix ui-widget-header" );
380391

381392
// Prevent users from focusing disabled tabs via click
382-
.delegate( "> li", "mousedown" + this.eventNamespace, function( event ) {
393+
this.tablist.delegate( "> li", "mousedown" + this.eventNamespace, function( event ) {
383394
if ( $( this ).is( ".ui-state-disabled" ) ) {
384395
event.preventDefault();
385396
}
@@ -398,21 +409,20 @@ return $.widget( "ui.tabs", {
398409
});
399410

400411
this.tabs = this.tablist.find( "> li:has(a[href])" )
401-
.addClass( "ui-state-default ui-corner-top" )
402412
.attr({
403413
role: "tab",
404414
tabIndex: -1
405415
});
416+
this._addClass( this.tabs, "ui-tab", "ui-state-default" );
406417

407418
this.anchors = this.tabs.map(function() {
408419
return $( "a", this )[ 0 ];
409420
})
410-
.addClass( "ui-tabs-anchor" )
411421
.attr({
412422
role: "presentation",
413423
tabIndex: -1
414424
});
415-
425+
this._addClass( this.anchors, "ui-tabs-anchor" );
416426
this.panels = $();
417427

418428
this.anchors.each(function( i, anchor ) {
@@ -453,9 +463,8 @@ return $.widget( "ui.tabs", {
453463
panel.attr( "aria-labelledby", anchorId );
454464
});
455465

456-
this.panels
457-
.addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" )
458-
.attr( "role", "tabpanel" );
466+
this.panels.attr( "role", "tabpanel" );
467+
this._addClass( this.panels, "ui-tabs-panel", "ui-widget-content" );
459468

460469
// Avoid memory leaks (#10056)
461470
if ( prevTabs ) {
@@ -471,10 +480,7 @@ return $.widget( "ui.tabs", {
471480
},
472481

473482
_createPanel: function( id ) {
474-
return $( "<div>" )
475-
.attr( "id", id )
476-
.addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" )
477-
.data( "ui-tabs-destroy", true );
483+
return $( "<div>" ).attr( "id", id ).data( "ui-tabs-destroy", true );
478484
},
479485

480486
_setupDisabled: function( disabled ) {
@@ -621,7 +627,7 @@ return $.widget( "ui.tabs", {
621627
}
622628

623629
function show() {
624-
eventData.newTab.closest( "li" ).addClass( "ui-tabs-active ui-state-active" );
630+
that._addClass( eventData.newTab.closest( "li" ), "ui-tabs-active", "ui-state-active" );
625631

626632
if ( toShow.length && that.options.show ) {
627633
that._show( toShow, that.options.show, complete );
@@ -634,11 +640,13 @@ return $.widget( "ui.tabs", {
634640
// start out by hiding, then showing, then completing
635641
if ( toHide.length && this.options.hide ) {
636642
this._hide( toHide, this.options.hide, function() {
637-
eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" );
643+
that._removeClass( eventData.oldTab.closest( "li" ),
644+
"ui-tabs-active", "ui-state-active" );
638645
show();
639646
});
640647
} else {
641-
eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" );
648+
this._removeClass( eventData.oldTab.closest( "li" ),
649+
"ui-tabs-active", "ui-state-active" );
642650
toHide.hide();
643651
show();
644652
}
@@ -704,31 +712,25 @@ return $.widget( "ui.tabs", {
704712
},
705713

706714
_destroy: function() {
715+
var that = this;
707716
if ( this.xhr ) {
708717
this.xhr.abort();
709718
}
710719

711-
this.element.removeClass( "ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible" );
712-
713-
this.tablist
714-
.removeClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" )
715-
.removeAttr( "role" );
720+
this._removeClass( "ui-tabs ui-tabs-collapsible", "ui-widget ui-widget-content" );
721+
this._removeClass( this.tablist, "ui-tabs-nav",
722+
"ui-helper-reset ui-helper-clearfix ui-widget-header" );
723+
this._removeClass( this.anchors, "ui-tabs-anchor" );
716724

717-
this.anchors
718-
.removeClass( "ui-tabs-anchor" )
719-
.removeAttr( "role" )
720-
.removeAttr( "tabIndex" )
721-
.removeUniqueId();
725+
this.tablist.removeAttr( "role" ).unbind( this.eventNamespace );
722726

723-
this.tablist.unbind( this.eventNamespace );
727+
this.anchors.removeAttr( "role" ).removeAttr( "tabIndex" ).removeUniqueId();
724728

725729
this.tabs.add( this.panels ).each(function() {
726730
if ( $.data( this, "ui-tabs-destroy" ) ) {
727731
$( this ).remove();
728732
} else {
729733
$( this )
730-
.removeClass( "ui-state-default ui-state-active ui-state-disabled " +
731-
"ui-corner-top ui-corner-bottom ui-widget-content ui-tabs-active ui-tabs-panel" )
732734
.removeAttr( "tabIndex" )
733735
.removeAttr( "aria-live" )
734736
.removeAttr( "aria-busy" )
@@ -737,6 +739,8 @@ return $.widget( "ui.tabs", {
737739
.removeAttr( "aria-hidden" )
738740
.removeAttr( "aria-expanded" )
739741
.removeAttr( "role" );
742+
that._removeClass( $( this ), "ui-tabs-active ui-tab ui-tabs-panel",
743+
"ui-state-default ui-state-active ui-state-disabled ui-widget-content" );
740744
}
741745
});
742746

@@ -826,7 +830,7 @@ return $.widget( "ui.tabs", {
826830
// jQuery <1.8 returns false if the request is canceled in beforeSend,
827831
// but as of 1.8, $.ajax() always returns a jqXHR object.
828832
if ( this.xhr && this.xhr.statusText !== "canceled" ) {
829-
tab.addClass( "ui-tabs-loading" );
833+
this._addClass( tab, "ui-tabs-loading" );
830834
panel.attr( "aria-busy", "true" );
831835

832836
this.xhr
@@ -846,7 +850,7 @@ return $.widget( "ui.tabs", {
846850
that.panels.stop( false, true );
847851
}
848852

849-
tab.removeClass( "ui-tabs-loading" );
853+
that._removeClass( tab, "ui-tabs-loading" );
850854
panel.removeAttr( "aria-busy" );
851855

852856
if ( jqXHR === that.xhr ) {

0 commit comments

Comments
 (0)