Tabs: Suppress automatic activation when navigating with COMMAND

Fixes #9621
Closes gh-1383
(cherry picked from commit 6a242ab4eb)
This commit is contained in:
Scott González 2014-11-03 15:06:12 -05:00
parent dc2c948dd6
commit 9dd1e733f3
2 changed files with 194 additions and 166 deletions

View File

@ -299,197 +299,224 @@ asyncTest( "keyboard support - LEFT, RIGHT, UP, DOWN, HOME, END, SPACE, ENTER",
setTimeout( step1, 1 ); setTimeout( step1, 1 );
}); });
asyncTest( "keyboard support - CTRL navigation", function() { // Navigation with CTRL and COMMAND (both behave the same)
expect( 115 ); $.each({
var element = $( "#tabs1" ).tabs(), ctrl: "CTRL",
tabs = element.find( ".ui-tabs-nav li" ), meta: "COMMAND"
panels = element.find( ".ui-tabs-panel" ), }, function( modifier, label ) {
keyCode = $.ui.keyCode; asyncTest( "keyboard support - " + label + " navigation", function() {
expect( 115 );
var element = $( "#tabs1" ).tabs(),
tabs = element.find( ".ui-tabs-nav li" ),
panels = element.find( ".ui-tabs-panel" ),
keyCode = $.ui.keyCode;
element.tabs( "instance" ).delay = 50; element.tabs( "instance" ).delay = 50;
equal( tabs.filter( ".ui-state-focus" ).length, 0, "no tabs focused on init" ); equal( tabs.filter( ".ui-state-focus" ).length, 0, "no tabs focused on init" );
tabs.eq( 0 ).simulate( "focus" ); tabs.eq( 0 ).simulate( "focus" );
// down // down
function step1() { function step1() {
ok( tabs.eq( 0 ).is( ".ui-state-focus" ), "first tab has focus" ); var eventProperties = { keyCode: keyCode.DOWN };
equal( tabs.eq( 0 ).attr( "aria-selected" ), "true", "first tab has aria-selected=true" ); eventProperties[ modifier + "Key" ] = true;
ok( panels.eq( 0 ).is( ":visible" ), "first panel is visible" );
tabs.eq( 0 ).simulate( "keydown", { keyCode: keyCode.DOWN, ctrlKey: true } ); ok( tabs.eq( 0 ).is( ".ui-state-focus" ), "first tab has focus" );
ok( tabs.eq( 1 ).is( ".ui-state-focus" ), "DOWN moves focus to next tab" ); equal( tabs.eq( 0 ).attr( "aria-selected" ), "true", "first tab has aria-selected=true" );
ok( !tabs.eq( 0 ).is( ".ui-state-focus" ), "first tab is no longer focused" ); ok( panels.eq( 0 ).is( ":visible" ), "first panel is visible" );
equal( tabs.eq( 1 ).attr( "aria-selected" ), "false", "second tab has aria-selected=false" );
equal( tabs.eq( 0 ).attr( "aria-selected" ), "true", "first tab has aria-selected=true" );
ok( panels.eq( 1 ).is( ":hidden" ), "second panel is still hidden" );
equal( tabs.eq( 1 ).attr( "aria-expanded" ), "false", "second tab has aria-expanded=false" );
equal( panels.eq( 1 ).attr( "aria-hidden" ), "true", "second panel has aria-hidden=true" );
ok( panels.eq( 0 ).is( ":visible" ), "first panel is still visible" );
equal( tabs.eq( 0 ).attr( "aria-expanded" ), "true", "first tab has aria-expanded=true" );
equal( panels.eq( 0 ).attr( "aria-hidden" ), "false", "first panel has aria-hidden=false" );
setTimeout( step2, 100 ); tabs.eq( 0 ).simulate( "keydown", eventProperties );
} ok( tabs.eq( 1 ).is( ".ui-state-focus" ), "DOWN moves focus to next tab" );
ok( !tabs.eq( 0 ).is( ".ui-state-focus" ), "first tab is no longer focused" );
equal( tabs.eq( 1 ).attr( "aria-selected" ), "false", "second tab has aria-selected=false" );
equal( tabs.eq( 0 ).attr( "aria-selected" ), "true", "first tab has aria-selected=true" );
ok( panels.eq( 1 ).is( ":hidden" ), "second panel is still hidden" );
equal( tabs.eq( 1 ).attr( "aria-expanded" ), "false", "second tab has aria-expanded=false" );
equal( panels.eq( 1 ).attr( "aria-hidden" ), "true", "second panel has aria-hidden=true" );
ok( panels.eq( 0 ).is( ":visible" ), "first panel is still visible" );
equal( tabs.eq( 0 ).attr( "aria-expanded" ), "true", "first tab has aria-expanded=true" );
equal( panels.eq( 0 ).attr( "aria-hidden" ), "false", "first panel has aria-hidden=false" );
// right setTimeout( step2, 100 );
function step2() { }
equal( tabs.eq( 0 ).attr( "aria-selected" ), "true", "first tab has aria-selected=true" );
ok( panels.eq( 0 ).is( ":visible" ), "first panel is visible" );
equal( tabs.eq( 0 ).attr( "aria-expanded" ), "true", "first tab has aria-expanded=true" );
equal( panels.eq( 0 ).attr( "aria-hidden" ), "false", "first panel has aria-hidden=false" );
ok( panels.eq( 1 ).is( ":hidden" ), "second panel is hidden" );
equal( tabs.eq( 1 ).attr( "aria-expanded" ), "false", "second tab has aria-expanded=false" );
equal( panels.eq( 1 ).attr( "aria-hidden" ), "true", "second panel has aria-hidden=true" );
tabs.eq( 1 ).simulate( "keydown", { keyCode: keyCode.RIGHT, ctrlKey: true } ); // right
ok( tabs.eq( 2 ).is( ".ui-state-focus" ), "RIGHT moves focus to next tab" ); function step2() {
equal( tabs.eq( 2 ).attr( "aria-selected" ), "false", "third tab has aria-selected=false" ); var eventProperties = { keyCode: keyCode.RIGHT };
equal( tabs.eq( 0 ).attr( "aria-selected" ), "true", "first tab has aria-selected=true" ); eventProperties[ modifier + "Key" ] = true;
ok( panels.eq( 2 ).is( ":hidden" ), "third panel is still hidden" );
equal( tabs.eq( 2 ).attr( "aria-expanded" ), "false", "third tab has aria-expanded=false" );
equal( panels.eq( 2 ).attr( "aria-hidden" ), "true", "third panel has aria-hidden=true" );
ok( panels.eq( 0 ).is( ":visible" ), "first panel is still visible" );
equal( tabs.eq( 0 ).attr( "aria-expanded" ), "true", "first tab has aria-expanded=true" );
equal( panels.eq( 0 ).attr( "aria-hidden" ), "false", "first panel has aria-hidden=false" );
setTimeout( step3, 100 ); equal( tabs.eq( 0 ).attr( "aria-selected" ), "true", "first tab has aria-selected=true" );
} ok( panels.eq( 0 ).is( ":visible" ), "first panel is visible" );
equal( tabs.eq( 0 ).attr( "aria-expanded" ), "true", "first tab has aria-expanded=true" );
equal( panels.eq( 0 ).attr( "aria-hidden" ), "false", "first panel has aria-hidden=false" );
ok( panels.eq( 1 ).is( ":hidden" ), "second panel is hidden" );
equal( tabs.eq( 1 ).attr( "aria-expanded" ), "false", "second tab has aria-expanded=false" );
equal( panels.eq( 1 ).attr( "aria-hidden" ), "true", "second panel has aria-hidden=true" );
// down (wrap) tabs.eq( 1 ).simulate( "keydown", eventProperties );
function step3() { ok( tabs.eq( 2 ).is( ".ui-state-focus" ), "RIGHT moves focus to next tab" );
equal( tabs.eq( 0 ).attr( "aria-selected" ), "true", "first tab has aria-selected=true" ); equal( tabs.eq( 2 ).attr( "aria-selected" ), "false", "third tab has aria-selected=false" );
ok( panels.eq( 0 ).is( ":visible" ), "first panel is visible" ); equal( tabs.eq( 0 ).attr( "aria-selected" ), "true", "first tab has aria-selected=true" );
equal( tabs.eq( 0 ).attr( "aria-expanded" ), "true", "first tab has aria-expanded=true" ); ok( panels.eq( 2 ).is( ":hidden" ), "third panel is still hidden" );
equal( panels.eq( 0 ).attr( "aria-hidden" ), "false", "first panel has aria-hidden=false" ); equal( tabs.eq( 2 ).attr( "aria-expanded" ), "false", "third tab has aria-expanded=false" );
ok( panels.eq( 2 ).is( ":hidden" ), "third panel is hidden" ); equal( panels.eq( 2 ).attr( "aria-hidden" ), "true", "third panel has aria-hidden=true" );
equal( tabs.eq( 2 ).attr( "aria-expanded" ), "false", "third tab has aria-expanded=false" ); ok( panels.eq( 0 ).is( ":visible" ), "first panel is still visible" );
equal( panels.eq( 2 ).attr( "aria-hidden" ), "true", "third panel has aria-hidden=true" ); equal( tabs.eq( 0 ).attr( "aria-expanded" ), "true", "first tab has aria-expanded=true" );
equal( panels.eq( 0 ).attr( "aria-hidden" ), "false", "first panel has aria-hidden=false" );
tabs.eq( 2 ).simulate( "keydown", { keyCode: keyCode.DOWN, ctrlKey: true } ); setTimeout( step3, 100 );
ok( tabs.eq( 0 ).is( ".ui-state-focus" ), "DOWN wraps focus to first tab" ); }
equal( tabs.eq( 0 ).attr( "aria-selected" ), "true", "first tab has aria-selected=true" );
ok( panels.eq( 0 ).is( ":visible" ), "first panel is still visible" );
equal( tabs.eq( 0 ).attr( "aria-expanded" ), "true", "first tab has aria-expanded=true" );
equal( panels.eq( 0 ).attr( "aria-hidden" ), "false", "first panel has aria-hidden=false" );
setTimeout( step4, 100 ); // down (wrap)
} function step3() {
var eventProperties = { keyCode: keyCode.DOWN };
eventProperties[ modifier + "Key" ] = true;
// up (wrap) equal( tabs.eq( 0 ).attr( "aria-selected" ), "true", "first tab has aria-selected=true" );
function step4() { ok( panels.eq( 0 ).is( ":visible" ), "first panel is visible" );
equal( tabs.eq( 0 ).attr( "aria-selected" ), "true", "first tab has aria-selected=true" ); equal( tabs.eq( 0 ).attr( "aria-expanded" ), "true", "first tab has aria-expanded=true" );
ok( panels.eq( 0 ).is( ":visible" ), "first panel is visible" ); equal( panels.eq( 0 ).attr( "aria-hidden" ), "false", "first panel has aria-hidden=false" );
equal( tabs.eq( 0 ).attr( "aria-expanded" ), "true", "first tab has aria-expanded=true" ); ok( panels.eq( 2 ).is( ":hidden" ), "third panel is hidden" );
equal( panels.eq( 0 ).attr( "aria-hidden" ), "false", "first panel has aria-hidden=false" ); equal( tabs.eq( 2 ).attr( "aria-expanded" ), "false", "third tab has aria-expanded=false" );
equal( panels.eq( 2 ).attr( "aria-hidden" ), "true", "third panel has aria-hidden=true" );
tabs.eq( 0 ).simulate( "keydown", { keyCode: keyCode.UP, ctrlKey: true } ); tabs.eq( 2 ).simulate( "keydown", eventProperties );
ok( tabs.eq( 2 ).is( ".ui-state-focus" ), "UP wraps focus to last tab" ); ok( tabs.eq( 0 ).is( ".ui-state-focus" ), "DOWN wraps focus to first tab" );
equal( tabs.eq( 2 ).attr( "aria-selected" ), "false", "third tab has aria-selected=false" ); equal( tabs.eq( 0 ).attr( "aria-selected" ), "true", "first tab has aria-selected=true" );
equal( tabs.eq( 0 ).attr( "aria-selected" ), "true", "first tab has aria-selected=true" ); ok( panels.eq( 0 ).is( ":visible" ), "first panel is still visible" );
ok( panels.eq( 2 ).is( ":hidden" ), "third panel is still hidden" ); equal( tabs.eq( 0 ).attr( "aria-expanded" ), "true", "first tab has aria-expanded=true" );
equal( tabs.eq( 2 ).attr( "aria-expanded" ), "false", "third tab has aria-expanded=false" ); equal( panels.eq( 0 ).attr( "aria-hidden" ), "false", "first panel has aria-hidden=false" );
equal( panels.eq( 2 ).attr( "aria-hidden" ), "true", "third panel has aria-hidden=true" );
ok( panels.eq( 0 ).is( ":visible" ), "first panel is still visible" );
equal( tabs.eq( 0 ).attr( "aria-expanded" ), "true", "first tab has aria-expanded=true" );
equal( panels.eq( 0 ).attr( "aria-hidden" ), "false", "first panel has aria-hidden=false" );
setTimeout( step5, 100 ); setTimeout( step4, 100 );
} }
// left // up (wrap)
function step5() { function step4() {
equal( tabs.eq( 0 ).attr( "aria-selected" ), "true", "first tab has aria-selected=true" ); var eventProperties = { keyCode: keyCode.UP };
ok( panels.eq( 0 ).is( ":visible" ), "first panel is visible" ); eventProperties[ modifier + "Key" ] = true;
equal( tabs.eq( 0 ).attr( "aria-expanded" ), "true", "first tab has aria-expanded=true" );
equal( panels.eq( 0 ).attr( "aria-hidden" ), "false", "first panel has aria-hidden=false" );
ok( panels.eq( 2 ).is( ":hidden" ), "third panel is hidden" );
equal( tabs.eq( 2 ).attr( "aria-expanded" ), "false", "third tab has aria-expanded=false" );
equal( panels.eq( 2 ).attr( "aria-hidden" ), "true", "third panel has aria-hidden=true" );
tabs.eq( 2 ).simulate( "keydown", { keyCode: keyCode.LEFT, ctrlKey: true } ); equal( tabs.eq( 0 ).attr( "aria-selected" ), "true", "first tab has aria-selected=true" );
ok( tabs.eq( 1 ).is( ".ui-state-focus" ), "LEFT moves focus to previous tab" ); ok( panels.eq( 0 ).is( ":visible" ), "first panel is visible" );
equal( tabs.eq( 1 ).attr( "aria-selected" ), "false", "second tab has aria-selected=false" ); equal( tabs.eq( 0 ).attr( "aria-expanded" ), "true", "first tab has aria-expanded=true" );
equal( tabs.eq( 0 ).attr( "aria-selected" ), "true", "first tab has aria-selected=true" ); equal( panels.eq( 0 ).attr( "aria-hidden" ), "false", "first panel has aria-hidden=false" );
ok( panels.eq( 1 ).is( ":hidden" ), "second panel is still hidden" );
equal( tabs.eq( 1 ).attr( "aria-expanded" ), "false", "second tab has aria-expanded=false" );
equal( panels.eq( 1 ).attr( "aria-hidden" ), "true", "second panel has aria-hidden=true" );
ok( panels.eq( 0 ).is( ":visible" ), "first panel is still visible" );
equal( tabs.eq( 0 ).attr( "aria-expanded" ), "true", "first tab has aria-expanded=true" );
equal( panels.eq( 0 ).attr( "aria-hidden" ), "false", "first panel has aria-hidden=false" );
setTimeout( step6, 100 ); tabs.eq( 0 ).simulate( "keydown", eventProperties );
} ok( tabs.eq( 2 ).is( ".ui-state-focus" ), "UP wraps focus to last tab" );
equal( tabs.eq( 2 ).attr( "aria-selected" ), "false", "third tab has aria-selected=false" );
equal( tabs.eq( 0 ).attr( "aria-selected" ), "true", "first tab has aria-selected=true" );
ok( panels.eq( 2 ).is( ":hidden" ), "third panel is still hidden" );
equal( tabs.eq( 2 ).attr( "aria-expanded" ), "false", "third tab has aria-expanded=false" );
equal( panels.eq( 2 ).attr( "aria-hidden" ), "true", "third panel has aria-hidden=true" );
ok( panels.eq( 0 ).is( ":visible" ), "first panel is still visible" );
equal( tabs.eq( 0 ).attr( "aria-expanded" ), "true", "first tab has aria-expanded=true" );
equal( panels.eq( 0 ).attr( "aria-hidden" ), "false", "first panel has aria-hidden=false" );
// home setTimeout( step5, 100 );
function step6() { }
equal( tabs.eq( 0 ).attr( "aria-selected" ), "true", "first tab has aria-selected=true" );
ok( panels.eq( 0 ).is( ":visible" ), "first panel is visible" );
equal( tabs.eq( 0 ).attr( "aria-expanded" ), "true", "first tab has aria-expanded=true" );
equal( panels.eq( 0 ).attr( "aria-hidden" ), "false", "first panel has aria-hidden=false" );
ok( panels.eq( 1 ).is( ":hidden" ), "second panel is hidden" );
equal( tabs.eq( 1 ).attr( "aria-expanded" ), "false", "second tab has aria-expanded=false" );
equal( panels.eq( 1 ).attr( "aria-hidden" ), "true", "second panel has aria-hidden=true" );
tabs.eq( 1 ).simulate( "keydown", { keyCode: keyCode.HOME, ctrlKey: true } ); // left
ok( tabs.eq( 0 ).is( ".ui-state-focus" ), "HOME moves focus to first tab" ); function step5() {
equal( tabs.eq( 0 ).attr( "aria-selected" ), "true", "first tab has aria-selected=true" ); var eventProperties = { keyCode: keyCode.LEFT };
equal( tabs.eq( 1 ).attr( "aria-selected" ), "false", "second tab has aria-selected=false" ); eventProperties[ modifier + "Key" ] = true;
ok( panels.eq( 1 ).is( ":hidden" ), "second panel is still hidden" );
equal( tabs.eq( 1 ).attr( "aria-expanded" ), "false", "second tab has aria-expanded=false" );
equal( panels.eq( 1 ).attr( "aria-hidden" ), "true", "second panel has aria-hidden=true" );
ok( panels.eq( 0 ).is( ":visible" ), "first panel is still visible" );
equal( tabs.eq( 0 ).attr( "aria-expanded" ), "true", "first tab has aria-expanded=true" );
equal( panels.eq( 0 ).attr( "aria-hidden" ), "false", "first panel has aria-hidden=false" );
setTimeout( step7, 100 ); equal( tabs.eq( 0 ).attr( "aria-selected" ), "true", "first tab has aria-selected=true" );
} ok( panels.eq( 0 ).is( ":visible" ), "first panel is visible" );
equal( tabs.eq( 0 ).attr( "aria-expanded" ), "true", "first tab has aria-expanded=true" );
equal( panels.eq( 0 ).attr( "aria-hidden" ), "false", "first panel has aria-hidden=false" );
ok( panels.eq( 2 ).is( ":hidden" ), "third panel is hidden" );
equal( tabs.eq( 2 ).attr( "aria-expanded" ), "false", "third tab has aria-expanded=false" );
equal( panels.eq( 2 ).attr( "aria-hidden" ), "true", "third panel has aria-hidden=true" );
// end tabs.eq( 2 ).simulate( "keydown", eventProperties );
function step7() { ok( tabs.eq( 1 ).is( ".ui-state-focus" ), "LEFT moves focus to previous tab" );
equal( tabs.eq( 0 ).attr( "aria-selected" ), "true", "first tab has aria-selected=true" ); equal( tabs.eq( 1 ).attr( "aria-selected" ), "false", "second tab has aria-selected=false" );
ok( panels.eq( 0 ).is( ":visible" ), "first panel is visible" ); equal( tabs.eq( 0 ).attr( "aria-selected" ), "true", "first tab has aria-selected=true" );
equal( tabs.eq( 0 ).attr( "aria-expanded" ), "true", "first tab has aria-expanded=true" ); ok( panels.eq( 1 ).is( ":hidden" ), "second panel is still hidden" );
equal( panels.eq( 0 ).attr( "aria-hidden" ), "false", "first panel has aria-hidden=false" ); equal( tabs.eq( 1 ).attr( "aria-expanded" ), "false", "second tab has aria-expanded=false" );
equal( panels.eq( 1 ).attr( "aria-hidden" ), "true", "second panel has aria-hidden=true" );
ok( panels.eq( 0 ).is( ":visible" ), "first panel is still visible" );
equal( tabs.eq( 0 ).attr( "aria-expanded" ), "true", "first tab has aria-expanded=true" );
equal( panels.eq( 0 ).attr( "aria-hidden" ), "false", "first panel has aria-hidden=false" );
tabs.eq( 0 ).simulate( "keydown", { keyCode: keyCode.END, ctrlKey: true } ); setTimeout( step6, 100 );
ok( tabs.eq( 2 ).is( ".ui-state-focus" ), "END moves focus to last tab" ); }
equal( tabs.eq( 2 ).attr( "aria-selected" ), "false", "third tab has aria-selected=false" );
equal( tabs.eq( 0 ).attr( "aria-selected" ), "true", "first tab has aria-selected=true" );
ok( panels.eq( 2 ).is( ":hidden" ), "third panel is still hidden" );
equal( tabs.eq( 2 ).attr( "aria-expanded" ), "false", "third tab has aria-expanded=false" );
equal( panels.eq( 2 ).attr( "aria-hidden" ), "true", "third panel has aria-hidden=true" );
ok( panels.eq( 0 ).is( ":visible" ), "first panel is still visible" );
equal( tabs.eq( 0 ).attr( "aria-expanded" ), "true", "first tab has aria-expanded=true" );
equal( panels.eq( 0 ).attr( "aria-hidden" ), "false", "first panel has aria-hidden=false" );
setTimeout( step8, 100 ); // home
} function step6() {
var eventProperties = { keyCode: keyCode.HOME };
eventProperties[ modifier + "Key" ] = true;
// space equal( tabs.eq( 0 ).attr( "aria-selected" ), "true", "first tab has aria-selected=true" );
function step8() { ok( panels.eq( 0 ).is( ":visible" ), "first panel is visible" );
equal( tabs.eq( 0 ).attr( "aria-selected" ), "true", "first tab has aria-selected=true" ); equal( tabs.eq( 0 ).attr( "aria-expanded" ), "true", "first tab has aria-expanded=true" );
ok( panels.eq( 0 ).is( ":visible" ), "first panel is visible" ); equal( panels.eq( 0 ).attr( "aria-hidden" ), "false", "first panel has aria-hidden=false" );
equal( tabs.eq( 0 ).attr( "aria-expanded" ), "true", "first tab has aria-expanded=true" ); ok( panels.eq( 1 ).is( ":hidden" ), "second panel is hidden" );
equal( panels.eq( 0 ).attr( "aria-hidden" ), "false", "first panel has aria-hidden=false" ); equal( tabs.eq( 1 ).attr( "aria-expanded" ), "false", "second tab has aria-expanded=false" );
ok( panels.eq( 2 ).is( ":hidden" ), "third panel is hidden" ); equal( panels.eq( 1 ).attr( "aria-hidden" ), "true", "second panel has aria-hidden=true" );
equal( tabs.eq( 2 ).attr( "aria-expanded" ), "false", "third tab has aria-expanded=false" );
equal( panels.eq( 2 ).attr( "aria-hidden" ), "true", "third panel has aria-hidden=true" );
tabs.eq( 2 ).simulate( "keydown", { keyCode: keyCode.SPACE } ); tabs.eq( 1 ).simulate( "keydown", eventProperties );
equal( tabs.eq( 2 ).attr( "aria-selected" ), "true", "third tab has aria-selected=true" ); ok( tabs.eq( 0 ).is( ".ui-state-focus" ), "HOME moves focus to first tab" );
equal( tabs.eq( 0 ).attr( "aria-selected" ), "false", "first tab has aria-selected=false" ); equal( tabs.eq( 0 ).attr( "aria-selected" ), "true", "first tab has aria-selected=true" );
ok( panels.eq( 2 ).is( ":visible" ), "third panel is visible" ); equal( tabs.eq( 1 ).attr( "aria-selected" ), "false", "second tab has aria-selected=false" );
equal( tabs.eq( 2 ).attr( "aria-expanded" ), "true", "third tab has aria-expanded=true" ); ok( panels.eq( 1 ).is( ":hidden" ), "second panel is still hidden" );
equal( panels.eq( 2 ).attr( "aria-hidden" ), "false", "third panel has aria-hidden=false" ); equal( tabs.eq( 1 ).attr( "aria-expanded" ), "false", "second tab has aria-expanded=false" );
ok( panels.eq( 0 ).is( ":hidden" ), "first panel is hidden" ); equal( panels.eq( 1 ).attr( "aria-hidden" ), "true", "second panel has aria-hidden=true" );
equal( tabs.eq( 0 ).attr( "aria-expanded" ), "false", "first tab has aria-expanded=false" ); ok( panels.eq( 0 ).is( ":visible" ), "first panel is still visible" );
equal( panels.eq( 0 ).attr( "aria-hidden" ), "true", "first panel has aria-hidden=true" ); equal( tabs.eq( 0 ).attr( "aria-expanded" ), "true", "first tab has aria-expanded=true" );
equal( panels.eq( 0 ).attr( "aria-hidden" ), "false", "first panel has aria-hidden=false" );
setTimeout( start, 1 ); setTimeout( step7, 100 );
} }
setTimeout( step1, 1 ); // end
function step7() {
var eventProperties = { keyCode: keyCode.END };
eventProperties[ modifier + "Key" ] = true;
equal( tabs.eq( 0 ).attr( "aria-selected" ), "true", "first tab has aria-selected=true" );
ok( panels.eq( 0 ).is( ":visible" ), "first panel is visible" );
equal( tabs.eq( 0 ).attr( "aria-expanded" ), "true", "first tab has aria-expanded=true" );
equal( panels.eq( 0 ).attr( "aria-hidden" ), "false", "first panel has aria-hidden=false" );
tabs.eq( 0 ).simulate( "keydown", eventProperties );
ok( tabs.eq( 2 ).is( ".ui-state-focus" ), "END moves focus to last tab" );
equal( tabs.eq( 2 ).attr( "aria-selected" ), "false", "third tab has aria-selected=false" );
equal( tabs.eq( 0 ).attr( "aria-selected" ), "true", "first tab has aria-selected=true" );
ok( panels.eq( 2 ).is( ":hidden" ), "third panel is still hidden" );
equal( tabs.eq( 2 ).attr( "aria-expanded" ), "false", "third tab has aria-expanded=false" );
equal( panels.eq( 2 ).attr( "aria-hidden" ), "true", "third panel has aria-hidden=true" );
ok( panels.eq( 0 ).is( ":visible" ), "first panel is still visible" );
equal( tabs.eq( 0 ).attr( "aria-expanded" ), "true", "first tab has aria-expanded=true" );
equal( panels.eq( 0 ).attr( "aria-hidden" ), "false", "first panel has aria-hidden=false" );
setTimeout( step8, 100 );
}
// space
function step8() {
equal( tabs.eq( 0 ).attr( "aria-selected" ), "true", "first tab has aria-selected=true" );
ok( panels.eq( 0 ).is( ":visible" ), "first panel is visible" );
equal( tabs.eq( 0 ).attr( "aria-expanded" ), "true", "first tab has aria-expanded=true" );
equal( panels.eq( 0 ).attr( "aria-hidden" ), "false", "first panel has aria-hidden=false" );
ok( panels.eq( 2 ).is( ":hidden" ), "third panel is hidden" );
equal( tabs.eq( 2 ).attr( "aria-expanded" ), "false", "third tab has aria-expanded=false" );
equal( panels.eq( 2 ).attr( "aria-hidden" ), "true", "third panel has aria-hidden=true" );
tabs.eq( 2 ).simulate( "keydown", { keyCode: keyCode.SPACE } );
equal( tabs.eq( 2 ).attr( "aria-selected" ), "true", "third tab has aria-selected=true" );
equal( tabs.eq( 0 ).attr( "aria-selected" ), "false", "first tab has aria-selected=false" );
ok( panels.eq( 2 ).is( ":visible" ), "third panel is visible" );
equal( tabs.eq( 2 ).attr( "aria-expanded" ), "true", "third tab has aria-expanded=true" );
equal( panels.eq( 2 ).attr( "aria-hidden" ), "false", "third panel has aria-hidden=false" );
ok( panels.eq( 0 ).is( ":hidden" ), "first panel is hidden" );
equal( tabs.eq( 0 ).attr( "aria-expanded" ), "false", "first tab has aria-expanded=false" );
equal( panels.eq( 0 ).attr( "aria-hidden" ), "true", "first panel has aria-hidden=true" );
setTimeout( start, 1 );
}
setTimeout( step1, 1 );
});
}); });
asyncTest( "keyboard support - CTRL+UP, ALT+PAGE_DOWN, ALT+PAGE_UP", function() { asyncTest( "keyboard support - CTRL+UP, ALT+PAGE_DOWN, ALT+PAGE_UP", function() {

View File

@ -201,8 +201,9 @@ return $.widget( "ui.tabs", {
clearTimeout( this.activating ); clearTimeout( this.activating );
selectedIndex = this._focusNextTab( selectedIndex, goingForward ); selectedIndex = this._focusNextTab( selectedIndex, goingForward );
// Navigating with control key will prevent automatic activation // Navigating with control/command key will prevent automatic activation
if ( !event.ctrlKey ) { if ( !event.ctrlKey && !event.metaKey ) {
// Update aria-selected immediately so that AT think the tab is already selected. // Update aria-selected immediately so that AT think the tab is already selected.
// Otherwise AT may confuse the user by stating that they need to activate the tab, // Otherwise AT may confuse the user by stating that they need to activate the tab,
// but the tab will already be activated by the time the announcement finishes. // but the tab will already be activated by the time the announcement finishes.