Permalink
Browse files

Tabs: Add classes option

Ref #7053
Ref gh-1411
  • Loading branch information...
1 parent 28dccda commit aaddfbfa8b3bdb0374540d7dd1e13a708bdb00aa @arschmitz arschmitz committed Dec 3, 2014
@@ -9,6 +9,7 @@
<script src="../../../external/qunit/qunit.js"></script>
<script src="../../../external/jquery-simulate/jquery.simulate.js"></script>
<script src="../testsuite.js"></script>
+ <script src="../../../external/qunit-assert-classes/qunit-assert-classes.js"></script>
<script>
TestHelpers.loadResources({
css: [ "core", "tabs" ],
@@ -1,7 +1,12 @@
TestHelpers.commonWidgetTests( "tabs", {
defaults: {
active: null,
- classes: {},
+ classes: {
+ "ui-tabs": "ui-corner-all",
+ "ui-tabs-nav": "ui-corner-all",
+ "ui-tab": "ui-corner-top",
+ "ui-tabs-panel": "ui-corner-bottom"
+ },
collapsible: false,
disabled: false,
event: "click",
@@ -4,13 +4,32 @@ var state = TestHelpers.tabs.state;
module( "tabs: core" );
-test( "markup structure", function() {
- expect( 3 );
- var element = $( "#tabs1" ).tabs();
- ok( element.hasClass( "ui-tabs" ), "main element is .ui-tabs" );
- ok( element.find( "ul" ).hasClass( "ui-tabs-nav" ), "list item is .ui-tabs-nav" );
- equal( element.find( ".ui-tabs-panel" ).length, 3,
- ".ui-tabs-panel elements exist, correct number" );
+test( "markup structure", function( assert ) {
+ expect( 17 );
+ var element = $( "#tabs1" ).tabs(),
+ tabList = element.find( "ul, ol" ),
+ tabs = tabList.find( "li" ),
+ active = tabs.eq( 0 ),
+ anchors = tabs.find( "a" ),
+ panels = element.find( ".ui-tabs-panel" );
+
+ assert.hasClasses( element, "ui-tabs ui-widget ui-widget-content" );
+ assert.lacksClasses( element, "ui-tabs-collapsible" );
+ assert.hasClasses( tabList, "ui-tabs-nav ui-widget-header" );
+ equal( tabList.length, 1, "The widget contains exactly one tab list" );
+ assert.hasClasses( tabs[ 0 ], "ui-tab" );
+ assert.hasClasses( tabs[ 1 ], "ui-tab" );
+ assert.hasClasses( tabs[ 2 ], "ui-tab" );
+ equal( tabs.length, 3, "There are exactly three tabs" );
+ assert.hasClasses( anchors[ 0 ], "ui-tabs-anchor" );
+ assert.hasClasses( anchors[ 1 ], "ui-tabs-anchor" );
+ assert.hasClasses( anchors[ 2 ], "ui-tabs-anchor" );
+ equal( anchors.length, 3, "There are exactly 3 anchors" );
+ assert.hasClasses( active, "ui-tabs-active" );
+ assert.hasClasses( panels[ 0 ], "ui-tabs-panel ui-widget-content" );
+ assert.hasClasses( panels[ 1 ], "ui-tabs-panel ui-widget-content" );
+ assert.hasClasses( panels[ 2 ], "ui-tabs-panel ui-widget-content" );
+ equal( panels.length, 3, "There are exactly 3 tab panels" );
});
$.each({
@@ -129,18 +148,21 @@ test( "accessibility", function() {
equal( panels.eq( 2 ).attr( "aria-hidden" ), "true", "inactive panel has aria-hidden=true" );
});
-asyncTest( "accessibility - ajax", function() {
- expect( 4 );
+asyncTest( "accessibility - ajax", function( assert ) {
+ expect( 6 );
var element = $( "#tabs2" ).tabs(),
+ tab = element.find( ".ui-tabs-nav li" ).eq( 3 ),
panel = $( "#custom-id" );
equal( panel.attr( "aria-live" ), "polite", "remote panel has aria-live" );
equal( panel.attr( "aria-busy" ), null, "does not have aria-busy on init" );
element.tabs( "option", "active", 3 );
+ assert.hasClasses( tab, "ui-tabs-loading" );
equal( panel.attr( "aria-busy" ), "true", "panel has aria-busy during load" );
element.one( "tabsload", function() {
setTimeout(function() {
equal( panel.attr( "aria-busy" ), null, "panel does not have aria-busy after load" );
+ assert.lacksClasses( tab, "ui-tabs-loading" );
start();
}, 1 );
});
@@ -15,6 +15,22 @@ test( "destroy", function() {
});
});
+asyncTest( "destroy - ajax", function() {
+ expect( 1 );
+ domEqual( "#tabs2", function( done ) {
+ var element = $( "#tabs2" ).tabs({
+ load: function() {
+ setTimeout(function() {
+ element.tabs( "destroy" );
+ done();
+ start();
+ });
+ }
+ });
+ element.tabs( "option", "active", 2 );
+ });
+});
+
test( "enable", function() {
expect( 8 );
@@ -107,28 +107,14 @@ test( "active - mismatched tab/panel order", function() {
location.hash = "#";
});
-test( "{ collapsible: false }", function() {
- expect( 4 );
-
- var element = $( "#tabs1" ).tabs({
- active: 1
- });
- element.tabs( "option", "active", false );
- equal( element.tabs( "option", "active" ), 1 );
- state( element, 0, 1, 0 );
-
- element.find( ".ui-state-active .ui-tabs-anchor" ).eq( 1 ).click();
- equal( element.tabs( "option", "active" ), 1 );
- state( element, 0, 1, 0 );
-});
-
-test( "{ collapsible: true }", function() {
- expect( 6 );
+test( "collapsible", function() {
+ expect( 13 );
var element = $( "#tabs1" ).tabs({
active: 1,
collapsible: true
});
+ ok( element.hasClass( "ui-tabs-collapsible" ), "main element is .ui-tabs-collapsible" );
element.tabs( "option", "active", false );
equal( element.tabs( "option", "active" ), false );
@@ -141,6 +127,24 @@ test( "{ collapsible: true }", function() {
element.find( ".ui-state-active .ui-tabs-anchor" ).click();
equal( element.tabs( "option", "active" ), false );
state( element, 0, 0, 0 );
+
+ element.tabs( "option", "collapsible", false );
+ ok( !element.hasClass( "ui-tabs-collapsible" ), "main element is not .ui-tabs-collapsible" );
+
+ element.tabs( "option", "collapsible", true );
+ ok( element.hasClass( "ui-tabs-collapsible" ), "main element is .ui-tabs-collapsible" );
+
+ element.tabs({
+ active: 1,
+ collapsible: false
+ });
+ element.tabs( "option", "active", false );
+ equal( element.tabs( "option", "active" ), 1 );
+ state( element, 0, 1, 0 );
+
+ element.find( ".ui-state-active .ui-tabs-anchor" ).eq( 1 ).click();
+ equal( element.tabs( "option", "active" ), 1 );
+ state( element, 0, 1, 0 );
});
test( "disabled", function() {
View
@@ -37,6 +37,12 @@ return $.widget( "ui.tabs", {
delay: 300,
options: {
active: null,
+ classes: {
+ "ui-tabs": "ui-corner-all",
+ "ui-tabs-nav": "ui-corner-all",
+ "ui-tab": "ui-corner-top",
+ "ui-tabs-panel": "ui-corner-bottom"
+ },
collapsible: false,
event: "click",
heightStyle: "content",
@@ -77,9 +83,8 @@ return $.widget( "ui.tabs", {
this.running = false;
- this.element
- .addClass( "ui-tabs ui-widget ui-widget-content ui-corner-all" )
- .toggleClass( "ui-tabs-collapsible", options.collapsible );
+ this._addClass( "ui-tabs", "ui-widget ui-widget-content" );
+ this._toggleClass( "ui-tabs-collapsible", null, options.collapsible );
this._processTabs();
options.active = this._initialActive();
@@ -286,7 +291,8 @@ return $.widget( "ui.tabs", {
this._super( key, value);
if ( key === "collapsible" ) {
- this.element.toggleClass( "ui-tabs-collapsible", value );
+ this._toggleClass( "ui-tabs-collapsible", null, value );
+
// Setting collapsible: false while collapsed; open first panel
if ( !value && this.options.active === false ) {
this._activate( 0 );
@@ -362,12 +368,12 @@ return $.widget( "ui.tabs", {
this.tabs.eq( 0 ).attr( "tabIndex", 0 );
} else {
this.active
- .addClass( "ui-tabs-active ui-state-active" )
.attr({
"aria-selected": "true",
"aria-expanded": "true",
tabIndex: 0
});
+ this._addClass( this.active, "ui-tabs-active", "ui-state-active" );
this._getPanelForTab( this.active )
.show()
.attr({
@@ -382,11 +388,12 @@ return $.widget( "ui.tabs", {
prevAnchors = this.anchors,
prevPanels = this.panels;
- this.tablist = this._getList()
- .addClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" )
- .attr( "role", "tablist" )
+ this.tablist = this._getList().attr( "role", "tablist" );
+ this._addClass( this.tablist, "ui-tabs-nav",
+ "ui-helper-reset ui-helper-clearfix ui-widget-header" );
- // Prevent users from focusing disabled tabs via click
+ // Prevent users from focusing disabled tabs via click
+ this.tablist
.delegate( "> li", "mousedown" + this.eventNamespace, function( event ) {
if ( $( this ).is( ".ui-state-disabled" ) ) {
event.preventDefault();
@@ -406,20 +413,20 @@ return $.widget( "ui.tabs", {
});
this.tabs = this.tablist.find( "> li:has(a[href])" )
- .addClass( "ui-state-default ui-corner-top" )
.attr({
role: "tab",
tabIndex: -1
});
+ this._addClass( this.tabs, "ui-tab", "ui-state-default" );
this.anchors = this.tabs.map(function() {
return $( "a", this )[ 0 ];
})
- .addClass( "ui-tabs-anchor" )
.attr({
role: "presentation",
tabIndex: -1
});
+ this._addClass( this.anchors, "ui-tabs-anchor" );
this.panels = $();
@@ -461,9 +468,8 @@ return $.widget( "ui.tabs", {
panel.attr( "aria-labelledby", anchorId );
});
- this.panels
- .addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" )
- .attr( "role", "tabpanel" );
+ this.panels.attr( "role", "tabpanel" );
+ this._addClass( this.panels, "ui-tabs-panel", "ui-widget-content" );
// Avoid memory leaks (#10056)
if ( prevTabs ) {
@@ -481,11 +487,12 @@ return $.widget( "ui.tabs", {
_createPanel: function( id ) {
return $( "<div>" )
.attr( "id", id )
- .addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" )
.data( "ui-tabs-destroy", true );
},
_setupDisabled: function( disabled ) {
+ var currentItem, li, i;
+
if ( $.isArray( disabled ) ) {
if ( !disabled.length ) {
disabled = false;
@@ -495,15 +502,14 @@ return $.widget( "ui.tabs", {
}
// disable tabs
- for ( var i = 0, li; ( li = this.tabs[ i ] ); i++ ) {
+ for ( i = 0; ( li = this.tabs[ i ] ); i++ ) {
+ currentItem = $( li );
if ( disabled === true || $.inArray( i, disabled ) !== -1 ) {
- $( li )
- .addClass( "ui-state-disabled" )
- .attr( "aria-disabled", "true" );
+ currentItem.attr( "aria-disabled", "true" );
+ this._addClass( currentItem, null, "ui-state-disabled" );
} else {
- $( li )
- .removeClass( "ui-state-disabled" )
- .removeAttr( "aria-disabled" );
+ currentItem.removeAttr( "aria-disabled" );
+ this._removeClass( currentItem, null, "ui-state-disabled" );
}
}
@@ -629,7 +635,7 @@ return $.widget( "ui.tabs", {
}
function show() {
- eventData.newTab.closest( "li" ).addClass( "ui-tabs-active ui-state-active" );
+ that._addClass( eventData.newTab.closest( "li" ), "ui-tabs-active", "ui-state-active" );
if ( toShow.length && that.options.show ) {
that._show( toShow, that.options.show, complete );
@@ -642,11 +648,13 @@ return $.widget( "ui.tabs", {
// start out by hiding, then showing, then completing
if ( toHide.length && this.options.hide ) {
this._hide( toHide, this.options.hide, function() {
- eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" );
+ that._removeClass( eventData.oldTab.closest( "li" ),
+ "ui-tabs-active", "ui-state-active" );
show();
});
} else {
- eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" );
+ this._removeClass( eventData.oldTab.closest( "li" ),
+ "ui-tabs-active", "ui-state-active" );
toHide.hide();
show();
}
@@ -716,27 +724,20 @@ return $.widget( "ui.tabs", {
this.xhr.abort();
}
- this.element.removeClass( "ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible" );
-
this.tablist
- .removeClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" )
- .removeAttr( "role" );
+ .removeAttr( "role" )
+ .unbind( this.eventNamespace );
this.anchors
- .removeClass( "ui-tabs-anchor" )
.removeAttr( "role" )
.removeAttr( "tabIndex" )
.removeUniqueId();
- this.tablist.unbind( this.eventNamespace );
-
this.tabs.add( this.panels ).each(function() {
if ( $.data( this, "ui-tabs-destroy" ) ) {
$( this ).remove();
} else {
$( this )
- .removeClass( "ui-state-default ui-state-active ui-state-disabled " +
- "ui-corner-top ui-corner-bottom ui-widget-content ui-tabs-active ui-tabs-panel" )
.removeAttr( "tabIndex" )
.removeAttr( "aria-live" )
.removeAttr( "aria-busy" )
@@ -827,7 +828,7 @@ return $.widget( "ui.tabs", {
that.panels.stop( false, true );
}
- tab.removeClass( "ui-tabs-loading" );
+ that._removeClass( tab, "ui-tabs-loading" );
panel.removeAttr( "aria-busy" );
if ( jqXHR === that.xhr ) {
@@ -846,7 +847,7 @@ return $.widget( "ui.tabs", {
// jQuery <1.8 returns false if the request is canceled in beforeSend,
// but as of 1.8, $.ajax() always returns a jqXHR object.
if ( this.xhr && this.xhr.statusText !== "canceled" ) {
- tab.addClass( "ui-tabs-loading" );
+ this._addClass( tab, "ui-tabs-loading" );
panel.attr( "aria-busy", "true" );
this.xhr

0 comments on commit aaddfbf

Please sign in to comment.