mirror of
https://github.com/jquery/jquery-ui.git
synced 2025-01-07 20:34:24 +00:00
parent
28dccda377
commit
aaddfbfa8b
@ -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() {
|
||||
|
73
ui/tabs.js
73
ui/tabs.js
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user