3 var state = TestHelpers.tabs.state;
5 module( "tabs: core" );
7 test( "markup structure", function() {
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,
13 ".ui-tabs-panel elements exist, correct number" );
18 "multiple lists, ul first": "#tabs4",
19 "multiple lists, ol first": "#tabs5",
20 "empty list": "#tabs6"
21 }, function( type, selector ) {
22 test( "markup structure: " + type, function() {
24 var element = $( selector ).tabs();
25 ok( element.hasClass( "ui-tabs" ), "main element is .ui-tabs" );
26 ok( $( selector + "-list" ).hasClass( "ui-tabs-nav" ),
27 "list item is .ui-tabs-nav" );
31 // #5893 - Sublist in the tab list are considered as tab
32 test( "nested list", function() {
35 var element = $( "#tabs6" ).tabs();
36 equal( element.data( "ui-tabs" ).anchors.length, 2, "should contain 2 tab" );
39 test( "disconnected from DOM", function() {
42 var element = $( "#tabs1" ).remove().tabs();
43 equal( element.find( ".ui-tabs-nav" ).length, 1, "should initialize nav" );
44 equal( element.find( ".ui-tabs-panel" ).length, 3, "should initialize panels" );
47 test( "non-tab list items", function() {
50 var element = $( "#tabs9" ).tabs();
51 equal( element.tabs( "option", "active" ), 0, "defaults to first tab" );
52 equal( element.find( ".ui-tabs-nav li.ui-state-active" ).index(), 1,
53 "first actual tab is active" );
56 test( "aria-controls", function() {
58 var element = $( "#tabs1" ).tabs(),
59 tabs = element.find( ".ui-tabs-nav li" );
60 tabs.each(function() {
62 anchor = tab.find( ".ui-tabs-anchor" );
63 equal( anchor.prop( "hash" ).substring( 1 ), tab.attr( "aria-controls" ) );
66 element = $( "#tabs2" ).tabs();
67 tabs = element.find( ".ui-tabs-nav li" );
68 equal( tabs.eq( 0 ).attr( "aria-controls" ), "colon:test" );
69 equal( tabs.eq( 1 ).attr( "aria-controls" ), "inline-style" );
70 ok( /^ui-tabs-\d+$/.test( tabs.eq( 2 ).attr( "aria-controls" ) ), "generated id" );
71 equal( tabs.eq( 3 ).attr( "aria-controls" ), "custom-id" );
74 test( "accessibility", function() {
76 var element = $( "#tabs1" ).tabs({
80 tabs = element.find( ".ui-tabs-nav li" ),
81 anchors = tabs.find( ".ui-tabs-anchor" ),
82 panels = element.find( ".ui-tabs-panel" );
84 equal( element.find( ".ui-tabs-nav" ).attr( "role" ), "tablist", "tablist role" );
85 tabs.each(function( index ) {
86 var tab = tabs.eq( index ),
87 anchor = anchors.eq( index ),
88 anchorId = anchor.attr( "id" ),
89 panel = panels.eq( index );
90 equal( tab.attr( "role" ), "tab", "tab " + index + " role" );
91 equal( tab.attr( "aria-labelledby" ), anchorId, "tab " + index + " aria-labelledby" );
92 equal( anchor.attr( "role" ), "presentation", "anchor " + index + " role" );
93 equal( anchor.attr( "tabindex" ), -1, "anchor " + index + " tabindex" );
94 equal( panel.attr( "role" ), "tabpanel", "panel " + index + " role" );
95 equal( panel.attr( "aria-labelledby" ), anchorId, "panel " + index + " aria-labelledby" );
98 equal( tabs.eq( 1 ).attr( "aria-selected" ), "true", "active tab has aria-selected=true" );
99 equal( tabs.eq( 1 ).attr( "tabindex" ), 0, "active tab has tabindex=0" );
100 equal( tabs.eq( 1 ).attr( "aria-disabled" ), null, "enabled tab does not have aria-disabled" );
101 equal( panels.eq( 1 ).attr( "aria-expanded" ), "true", "active panel has aria-expanded=true" );
102 equal( panels.eq( 1 ).attr( "aria-hidden" ), "false", "active panel has aria-hidden=false" );
103 equal( tabs.eq( 0 ).attr( "aria-selected" ), "false", "inactive tab has aria-selected=false" );
104 equal( tabs.eq( 0 ).attr( "tabindex" ), -1, "inactive tab has tabindex=-1" );
105 equal( tabs.eq( 0 ).attr( "aria-disabled" ), null, "enabled tab does not have aria-disabled" );
106 equal( panels.eq( 0 ).attr( "aria-expanded" ), "false", "inactive panel has aria-expanded=false" );
107 equal( panels.eq( 0 ).attr( "aria-hidden" ), "true", "inactive panel has aria-hidden=true" );
108 equal( tabs.eq( 2 ).attr( "aria-selected" ), "false", "inactive tab has aria-selected=false" );
109 equal( tabs.eq( 2 ).attr( "tabindex" ), -1, "inactive tab has tabindex=-1" );
110 equal( tabs.eq( 2 ).attr( "aria-disabled" ), "true", "disabled tab has aria-disabled=true" );
111 equal( panels.eq( 2 ).attr( "aria-expanded" ), "false", "inactive panel has aria-expanded=false" );
112 equal( panels.eq( 2 ).attr( "aria-hidden" ), "true", "inactive panel has aria-hidden=true" );
114 element.tabs( "option", "active", 0 );
115 equal( tabs.eq( 0 ).attr( "aria-selected" ), "true", "active tab has aria-selected=true" );
116 equal( tabs.eq( 0 ).attr( "tabindex" ), 0, "active tab has tabindex=0" );
117 equal( tabs.eq( 0 ).attr( "aria-disabled" ), null, "enabled tab does not have aria-disabled" );
118 equal( panels.eq( 0 ).attr( "aria-expanded" ), "true", "active panel has aria-expanded=true" );
119 equal( panels.eq( 0 ).attr( "aria-hidden" ), "false", "active panel has aria-hidden=false" );
120 equal( tabs.eq( 1 ).attr( "aria-selected" ), "false", "inactive tab has aria-selected=false" );
121 equal( tabs.eq( 1 ).attr( "tabindex" ), -1, "inactive tab has tabindex=-1" );
122 equal( tabs.eq( 1 ).attr( "aria-disabled" ), null, "enabled tab does not have aria-disabled" );
123 equal( panels.eq( 1 ).attr( "aria-expanded" ), "false", "inactive panel has aria-expanded=false" );
124 equal( panels.eq( 1 ).attr( "aria-hidden" ), "true", "inactive panel has aria-hidden=true" );
125 equal( tabs.eq( 2 ).attr( "aria-selected" ), "false", "inactive tab has aria-selected=false" );
126 equal( tabs.eq( 2 ).attr( "tabindex" ), -1, "inactive tab has tabindex=-1" );
127 equal( tabs.eq( 2 ).attr( "aria-disabled" ), "true", "disabled tab has aria-disabled=true" );
128 equal( panels.eq( 2 ).attr( "aria-expanded" ), "false", "inactive panel has aria-expanded=false" );
129 equal( panels.eq( 2 ).attr( "aria-hidden" ), "true", "inactive panel has aria-hidden=true" );
132 asyncTest( "accessibility - ajax", function() {
134 var element = $( "#tabs2" ).tabs(),
135 panel = $( "#custom-id" );
137 equal( panel.attr( "aria-live" ), "polite", "remote panel has aria-live" );
138 equal( panel.attr( "aria-busy" ), null, "does not have aria-busy on init" );
139 element.tabs( "option", "active", 3 );
140 equal( panel.attr( "aria-busy" ), "true", "panel has aria-busy during load" );
141 element.one( "tabsload", function() {
142 setTimeout(function() {
143 equal( panel.attr( "aria-busy" ), null, "panel does not have aria-busy after load" );
149 asyncTest( "keyboard support - LEFT, RIGHT, UP, DOWN, HOME, END, SPACE, ENTER", function() {
151 var element = $( "#tabs1" ).tabs({
154 tabs = element.find( ".ui-tabs-nav li" ),
155 panels = element.find( ".ui-tabs-panel" ),
156 keyCode = $.ui.keyCode;
158 element.data( "ui-tabs" ).delay = 50;
160 equal( tabs.filter( ".ui-state-focus" ).length, 0, "no tabs focused on init" );
161 tabs.eq( 0 ).simulate( "focus" );
163 // down, right, down (wrap), up (wrap)
165 ok( tabs.eq( 0 ).is( ".ui-state-focus" ), "first tab has focus" );
166 equal( tabs.eq( 0 ).attr( "aria-selected" ), "true", "first tab has aria-selected=true" );
167 ok( panels.eq( 0 ).is( ":visible" ), "first panel is visible" );
169 tabs.eq( 0 ).simulate( "keydown", { keyCode: keyCode.DOWN } );
170 ok( tabs.eq( 1 ).is( ".ui-state-focus" ), "DOWN moves focus to next tab" );
171 ok( !tabs.eq( 0 ).is( ".ui-state-focus" ), "first tab is no longer focused" );
172 equal( tabs.eq( 1 ).attr( "aria-selected" ), "true", "second tab has aria-selected=true" );
173 equal( tabs.eq( 0 ).attr( "aria-selected" ), "false", "first tab has aria-selected=false" );
174 ok( panels.eq( 1 ).is( ":hidden" ), "second panel is still hidden" );
175 equal( panels.eq( 1 ).attr( "aria-expanded" ), "false", "second panel has aria-expanded=false" );
176 equal( panels.eq( 1 ).attr( "aria-hidden" ), "true", "second panel has aria-hidden=true" );
177 ok( panels.eq( 0 ).is( ":visible" ), "first panel is still visible" );
178 equal( panels.eq( 0 ).attr( "aria-expanded" ), "true", "first panel has aria-expanded=true" );
179 equal( panels.eq( 0 ).attr( "aria-hidden" ), "false", "first panel has aria-hidden=false" );
181 tabs.eq( 1 ).simulate( "keydown", { keyCode: keyCode.RIGHT } );
182 ok( tabs.eq( 2 ).is( ".ui-state-focus" ), "RIGHT moves focus to next tab" );
183 equal( tabs.eq( 2 ).attr( "aria-selected" ), "true", "third tab has aria-selected=true" );
184 equal( tabs.eq( 1 ).attr( "aria-selected" ), "false", "second tab has aria-selected=false" );
185 ok( panels.eq( 2 ).is( ":hidden" ), "third panel is still hidden" );
186 equal( panels.eq( 2 ).attr( "aria-expanded" ), "false", "third panel has aria-expanded=false" );
187 equal( panels.eq( 2 ).attr( "aria-hidden" ), "true", "third panel has aria-hidden=true" );
188 ok( panels.eq( 0 ).is( ":visible" ), "first panel is still visible" );
189 equal( panels.eq( 0 ).attr( "aria-expanded" ), "true", "first panel has aria-expanded=true" );
190 equal( panels.eq( 0 ).attr( "aria-hidden" ), "false", "first panel has aria-hidden=false" );
192 tabs.eq( 2 ).simulate( "keydown", { keyCode: keyCode.DOWN } );
193 ok( tabs.eq( 0 ).is( ".ui-state-focus" ), "DOWN wraps focus to first tab" );
194 equal( tabs.eq( 0 ).attr( "aria-selected" ), "true", "first tab has aria-selected=true" );
195 equal( tabs.eq( 2 ).attr( "aria-selected" ), "false", "third tab has aria-selected=false" );
196 ok( panels.eq( 0 ).is( ":visible" ), "first panel is still visible" );
197 equal( panels.eq( 0 ).attr( "aria-expanded" ), "true", "first panel has aria-expanded=true" );
198 equal( panels.eq( 0 ).attr( "aria-hidden" ), "false", "first panel has aria-hidden=false" );
200 tabs.eq( 0 ).simulate( "keydown", { keyCode: keyCode.UP } );
201 ok( tabs.eq( 2 ).is( ".ui-state-focus" ), "UP wraps focus to last tab" );
202 equal( tabs.eq( 2 ).attr( "aria-selected" ), "true", "third tab has aria-selected=true" );
203 equal( tabs.eq( 0 ).attr( "aria-selected" ), "false", "first tab has aria-selected=false" );
204 ok( panels.eq( 2 ).is( ":hidden" ), "third panel is still hidden" );
205 equal( panels.eq( 2 ).attr( "aria-expanded" ), "false", "third panel has aria-expanded=false" );
206 equal( panels.eq( 2 ).attr( "aria-hidden" ), "true", "third panel has aria-hidden=true" );
207 ok( panels.eq( 0 ).is( ":visible" ), "first panel is still visible" );
208 equal( panels.eq( 0 ).attr( "aria-expanded" ), "true", "first panel has aria-expanded=true" );
209 equal( panels.eq( 0 ).attr( "aria-hidden" ), "false", "first panel has aria-hidden=false" );
211 setTimeout( step2, 100 );
216 equal( tabs.eq( 2 ).attr( "aria-selected" ), "true", "third tab has aria-selected=true" );
217 equal( tabs.eq( 0 ).attr( "aria-selected" ), "false", "first tab has aria-selected=false" );
218 ok( panels.eq( 2 ).is( ":visible" ), "third panel is visible" );
219 equal( panels.eq( 2 ).attr( "aria-expanded" ), "true", "third panel has aria-expanded=true" );
220 equal( panels.eq( 2 ).attr( "aria-hidden" ), "false", "third panel has aria-hidden=false" );
221 ok( panels.eq( 0 ).is( ":hidden" ), "first panel is hidden" );
222 equal( panels.eq( 0 ).attr( "aria-expanded" ), "false", "first panel has aria-expanded=false" );
223 equal( panels.eq( 0 ).attr( "aria-hidden" ), "true", "first panel has aria-hidden=true" );
225 tabs.eq( 2 ).simulate( "keydown", { keyCode: keyCode.LEFT } );
226 ok( tabs.eq( 1 ).is( ".ui-state-focus" ), "LEFT moves focus to previous tab" );
227 equal( tabs.eq( 1 ).attr( "aria-selected" ), "true", "second tab has aria-selected=true" );
228 equal( tabs.eq( 2 ).attr( "aria-selected" ), "false", "third tab has aria-selected=false" );
229 ok( panels.eq( 1 ).is( ":hidden" ), "second panel is still hidden" );
230 equal( panels.eq( 1 ).attr( "aria-expanded" ), "false", "second panel has aria-expanded=false" );
231 equal( panels.eq( 1 ).attr( "aria-hidden" ), "true", "second panel has aria-hidden=true" );
232 ok( panels.eq( 2 ).is( ":visible" ), "third panel is still visible" );
233 equal( panels.eq( 2 ).attr( "aria-expanded" ), "true", "third panel has aria-expanded=true" );
234 equal( panels.eq( 2 ).attr( "aria-hidden" ), "false", "third panel has aria-hidden=false" );
236 tabs.eq( 1 ).simulate( "keydown", { keyCode: keyCode.HOME } );
237 ok( tabs.eq( 0 ).is( ".ui-state-focus" ), "HOME moves focus to first tab" );
238 equal( tabs.eq( 0 ).attr( "aria-selected" ), "true", "first tab has aria-selected=true" );
239 equal( tabs.eq( 1 ).attr( "aria-selected" ), "false", "second tab has aria-selected=false" );
240 ok( panels.eq( 0 ).is( ":hidden" ), "first panel is still hidden" );
241 equal( panels.eq( 0 ).attr( "aria-expanded" ), "false", "first panel has aria-expanded=false" );
242 equal( panels.eq( 0 ).attr( "aria-hidden" ), "true", "first panel has aria-hidden=true" );
243 ok( panels.eq( 2 ).is( ":visible" ), "third panel is still visible" );
244 equal( panels.eq( 2 ).attr( "aria-expanded" ), "true", "third panel has aria-expanded=true" );
245 equal( panels.eq( 2 ).attr( "aria-hidden" ), "false", "third panel has aria-hidden=false" );
247 // SPACE activates, cancels delay
248 tabs.eq( 0 ).simulate( "keydown", { keyCode: keyCode.SPACE } );
249 setTimeout( step3, 1 );
254 equal( tabs.eq( 0 ).attr( "aria-selected" ), "true", "first tab has aria-selected=true" );
255 equal( tabs.eq( 2 ).attr( "aria-selected" ), "false", "third tab has aria-selected=false" );
256 ok( panels.eq( 0 ).is( ":visible" ), "first panel is visible" );
257 equal( panels.eq( 0 ).attr( "aria-expanded" ), "true", "first panel has aria-expanded=true" );
258 equal( panels.eq( 0 ).attr( "aria-hidden" ), "false", "first panel has aria-hidden=false" );
259 ok( panels.eq( 2 ).is( ":hidden" ), "third panel is hidden" );
260 equal( panels.eq( 2 ).attr( "aria-expanded" ), "false", "third panel has aria-expanded=false" );
261 equal( panels.eq( 2 ).attr( "aria-hidden" ), "true", "third panel has aria-hidden=true" );
263 tabs.eq( 0 ).simulate( "keydown", { keyCode: keyCode.END } );
264 ok( tabs.eq( 2 ).is( ".ui-state-focus" ), "END moves focus to last tab" );
265 equal( tabs.eq( 2 ).attr( "aria-selected" ), "true", "third tab has aria-selected=true" );
266 equal( tabs.eq( 0 ).attr( "aria-selected" ), "false", "first tab has aria-selected=false" );
267 ok( panels.eq( 2 ).is( ":hidden" ), "third panel is still hidden" );
268 equal( panels.eq( 2 ).attr( "aria-expanded" ), "false", "third panel has aria-expanded=false" );
269 equal( panels.eq( 2 ).attr( "aria-hidden" ), "true", "third panel has aria-hidden=true" );
270 ok( panels.eq( 0 ).is( ":visible" ), "first panel is still visible" );
271 equal( panels.eq( 0 ).attr( "aria-expanded" ), "true", "first panel has aria-expanded=true" );
272 equal( panels.eq( 0 ).attr( "aria-hidden" ), "false", "first panel has aria-hidden=false" );
274 // ENTER activates, cancels delay
275 tabs.eq( 0 ).simulate( "keydown", { keyCode: keyCode.ENTER } );
276 setTimeout( step4, 1 );
281 equal( tabs.eq( 2 ).attr( "aria-selected" ), "true", "third tab has aria-selected=true" );
282 ok( panels.eq( 2 ).is( ":visible" ), "third panel is visible" );
283 equal( panels.eq( 2 ).attr( "aria-expanded" ), "true", "third panel has aria-expanded=true" );
284 equal( panels.eq( 2 ).attr( "aria-hidden" ), "false", "third panel has aria-hidden=false" );
285 ok( panels.eq( 0 ).is( ":hidden" ), "first panel is hidden" );
286 equal( panels.eq( 0 ).attr( "aria-expanded" ), "false", "first panel has aria-expanded=false" );
287 equal( panels.eq( 0 ).attr( "aria-hidden" ), "true", "first panel has aria-hidden=true" );
289 // ENTER collapses if active
290 tabs.eq( 2 ).simulate( "keydown", { keyCode: keyCode.ENTER } );
291 equal( tabs.eq( 2 ).attr( "aria-selected" ), "false", "third tab has aria-selected=false" );
292 ok( panels.eq( 2 ).is( ":hidden" ), "third panel is hidden" );
293 equal( panels.eq( 2 ).attr( "aria-expanded" ), "false", "third panel has aria-expanded=false" );
294 equal( panels.eq( 2 ).attr( "aria-hidden" ), "true", "third panel has aria-hidden=true" );
296 setTimeout( start, 1 );
299 setTimeout( step1, 1 );
302 asyncTest( "keyboard support - CTRL navigation", function() {
304 var element = $( "#tabs1" ).tabs(),
305 tabs = element.find( ".ui-tabs-nav li" ),
306 panels = element.find( ".ui-tabs-panel" ),
307 keyCode = $.ui.keyCode;
309 element.data( "ui-tabs" ).delay = 50;
311 equal( tabs.filter( ".ui-state-focus" ).length, 0, "no tabs focused on init" );
312 tabs.eq( 0 ).simulate( "focus" );
316 ok( tabs.eq( 0 ).is( ".ui-state-focus" ), "first tab has focus" );
317 equal( tabs.eq( 0 ).attr( "aria-selected" ), "true", "first tab has aria-selected=true" );
318 ok( panels.eq( 0 ).is( ":visible" ), "first panel is visible" );
320 tabs.eq( 0 ).simulate( "keydown", { keyCode: keyCode.DOWN, ctrlKey: true } );
321 ok( tabs.eq( 1 ).is( ".ui-state-focus" ), "DOWN moves focus to next tab" );
322 ok( !tabs.eq( 0 ).is( ".ui-state-focus" ), "first tab is no longer focused" );
323 equal( tabs.eq( 1 ).attr( "aria-selected" ), "false", "second tab has aria-selected=false" );
324 equal( tabs.eq( 0 ).attr( "aria-selected" ), "true", "first tab has aria-selected=true" );
325 ok( panels.eq( 1 ).is( ":hidden" ), "second panel is still hidden" );
326 equal( panels.eq( 1 ).attr( "aria-expanded" ), "false", "second panel has aria-expanded=false" );
327 equal( panels.eq( 1 ).attr( "aria-hidden" ), "true", "second panel has aria-hidden=true" );
328 ok( panels.eq( 0 ).is( ":visible" ), "first panel is still visible" );
329 equal( panels.eq( 0 ).attr( "aria-expanded" ), "true", "first panel has aria-expanded=true" );
330 equal( panels.eq( 0 ).attr( "aria-hidden" ), "false", "first panel has aria-hidden=false" );
332 setTimeout( step2, 100 );
337 equal( tabs.eq( 0 ).attr( "aria-selected" ), "true", "first tab has aria-selected=true" );
338 ok( panels.eq( 0 ).is( ":visible" ), "first panel is visible" );
339 equal( panels.eq( 0 ).attr( "aria-expanded" ), "true", "first panel has aria-expanded=true" );
340 equal( panels.eq( 0 ).attr( "aria-hidden" ), "false", "first panel has aria-hidden=false" );
341 ok( panels.eq( 1 ).is( ":hidden" ), "second panel is hidden" );
342 equal( panels.eq( 1 ).attr( "aria-expanded" ), "false", "second panel has aria-expanded=false" );
343 equal( panels.eq( 1 ).attr( "aria-hidden" ), "true", "second panel has aria-hidden=true" );
345 tabs.eq( 1 ).simulate( "keydown", { keyCode: keyCode.RIGHT, ctrlKey: true } );
346 ok( tabs.eq( 2 ).is( ".ui-state-focus" ), "RIGHT moves focus to next tab" );
347 equal( tabs.eq( 2 ).attr( "aria-selected" ), "false", "third tab has aria-selected=false" );
348 equal( tabs.eq( 0 ).attr( "aria-selected" ), "true", "first tab has aria-selected=true" );
349 ok( panels.eq( 2 ).is( ":hidden" ), "third panel is still hidden" );
350 equal( panels.eq( 2 ).attr( "aria-expanded" ), "false", "third panel has aria-expanded=false" );
351 equal( panels.eq( 2 ).attr( "aria-hidden" ), "true", "third panel has aria-hidden=true" );
352 ok( panels.eq( 0 ).is( ":visible" ), "first panel is still visible" );
353 equal( panels.eq( 0 ).attr( "aria-expanded" ), "true", "first panel has aria-expanded=true" );
354 equal( panels.eq( 0 ).attr( "aria-hidden" ), "false", "first panel has aria-hidden=false" );
356 setTimeout( step3, 100 );
361 equal( tabs.eq( 0 ).attr( "aria-selected" ), "true", "first tab has aria-selected=true" );
362 ok( panels.eq( 0 ).is( ":visible" ), "first panel is visible" );
363 equal( panels.eq( 0 ).attr( "aria-expanded" ), "true", "first panel has aria-expanded=true" );
364 equal( panels.eq( 0 ).attr( "aria-hidden" ), "false", "first panel has aria-hidden=false" );
365 ok( panels.eq( 2 ).is( ":hidden" ), "third panel is hidden" );
366 equal( panels.eq( 2 ).attr( "aria-expanded" ), "false", "third panel has aria-expanded=false" );
367 equal( panels.eq( 2 ).attr( "aria-hidden" ), "true", "third panel has aria-hidden=true" );
369 tabs.eq( 2 ).simulate( "keydown", { keyCode: keyCode.DOWN, ctrlKey: true } );
370 ok( tabs.eq( 0 ).is( ".ui-state-focus" ), "DOWN wraps focus to first tab" );
371 equal( tabs.eq( 0 ).attr( "aria-selected" ), "true", "first tab has aria-selected=true" );
372 ok( panels.eq( 0 ).is( ":visible" ), "first panel is still visible" );
373 equal( panels.eq( 0 ).attr( "aria-expanded" ), "true", "first panel has aria-expanded=true" );
374 equal( panels.eq( 0 ).attr( "aria-hidden" ), "false", "first panel has aria-hidden=false" );
376 setTimeout( step4, 100 );
381 equal( tabs.eq( 0 ).attr( "aria-selected" ), "true", "first tab has aria-selected=true" );
382 ok( panels.eq( 0 ).is( ":visible" ), "first panel is visible" );
383 equal( panels.eq( 0 ).attr( "aria-expanded" ), "true", "first panel has aria-expanded=true" );
384 equal( panels.eq( 0 ).attr( "aria-hidden" ), "false", "first panel has aria-hidden=false" );
386 tabs.eq( 0 ).simulate( "keydown", { keyCode: keyCode.UP, ctrlKey: true } );
387 ok( tabs.eq( 2 ).is( ".ui-state-focus" ), "UP wraps focus to last tab" );
388 equal( tabs.eq( 2 ).attr( "aria-selected" ), "false", "third tab has aria-selected=false" );
389 equal( tabs.eq( 0 ).attr( "aria-selected" ), "true", "first tab has aria-selected=true" );
390 ok( panels.eq( 2 ).is( ":hidden" ), "third panel is still hidden" );
391 equal( panels.eq( 2 ).attr( "aria-expanded" ), "false", "third panel has aria-expanded=false" );
392 equal( panels.eq( 2 ).attr( "aria-hidden" ), "true", "third panel has aria-hidden=true" );
393 ok( panels.eq( 0 ).is( ":visible" ), "first panel is still visible" );
394 equal( panels.eq( 0 ).attr( "aria-expanded" ), "true", "first panel has aria-expanded=true" );
395 equal( panels.eq( 0 ).attr( "aria-hidden" ), "false", "first panel has aria-hidden=false" );
397 setTimeout( step5, 100 );
402 equal( tabs.eq( 0 ).attr( "aria-selected" ), "true", "first tab has aria-selected=true" );
403 ok( panels.eq( 0 ).is( ":visible" ), "first panel is visible" );
404 equal( panels.eq( 0 ).attr( "aria-expanded" ), "true", "first panel has aria-expanded=true" );
405 equal( panels.eq( 0 ).attr( "aria-hidden" ), "false", "first panel has aria-hidden=false" );
406 ok( panels.eq( 2 ).is( ":hidden" ), "third panel is hidden" );
407 equal( panels.eq( 2 ).attr( "aria-expanded" ), "false", "third panel has aria-expanded=false" );
408 equal( panels.eq( 2 ).attr( "aria-hidden" ), "true", "third panel has aria-hidden=true" );
410 tabs.eq( 2 ).simulate( "keydown", { keyCode: keyCode.LEFT, ctrlKey: true } );
411 ok( tabs.eq( 1 ).is( ".ui-state-focus" ), "LEFT moves focus to previous tab" );
412 equal( tabs.eq( 1 ).attr( "aria-selected" ), "false", "second tab has aria-selected=false" );
413 equal( tabs.eq( 0 ).attr( "aria-selected" ), "true", "first tab has aria-selected=true" );
414 ok( panels.eq( 1 ).is( ":hidden" ), "second panel is still hidden" );
415 equal( panels.eq( 1 ).attr( "aria-expanded" ), "false", "second panel has aria-expanded=false" );
416 equal( panels.eq( 1 ).attr( "aria-hidden" ), "true", "second panel has aria-hidden=true" );
417 ok( panels.eq( 0 ).is( ":visible" ), "first panel is still visible" );
418 equal( panels.eq( 0 ).attr( "aria-expanded" ), "true", "first panel has aria-expanded=true" );
419 equal( panels.eq( 0 ).attr( "aria-hidden" ), "false", "first panel has aria-hidden=false" );
421 setTimeout( step6, 100 );
426 equal( tabs.eq( 0 ).attr( "aria-selected" ), "true", "first tab has aria-selected=true" );
427 ok( panels.eq( 0 ).is( ":visible" ), "first panel is visible" );
428 equal( panels.eq( 0 ).attr( "aria-expanded" ), "true", "first panel has aria-expanded=true" );
429 equal( panels.eq( 0 ).attr( "aria-hidden" ), "false", "first panel has aria-hidden=false" );
430 ok( panels.eq( 1 ).is( ":hidden" ), "second panel is hidden" );
431 equal( panels.eq( 1 ).attr( "aria-expanded" ), "false", "second panel has aria-expanded=false" );
432 equal( panels.eq( 1 ).attr( "aria-hidden" ), "true", "second panel has aria-hidden=true" );
434 tabs.eq( 1 ).simulate( "keydown", { keyCode: keyCode.HOME, ctrlKey: true } );
435 ok( tabs.eq( 0 ).is( ".ui-state-focus" ), "HOME moves focus to first tab" );
436 equal( tabs.eq( 0 ).attr( "aria-selected" ), "true", "first tab has aria-selected=true" );
437 equal( tabs.eq( 1 ).attr( "aria-selected" ), "false", "second tab has aria-selected=false" );
438 ok( panels.eq( 1 ).is( ":hidden" ), "second panel is still hidden" );
439 equal( panels.eq( 1 ).attr( "aria-expanded" ), "false", "second panel has aria-expanded=false" );
440 equal( panels.eq( 1 ).attr( "aria-hidden" ), "true", "second panel has aria-hidden=true" );
441 ok( panels.eq( 0 ).is( ":visible" ), "first panel is still visible" );
442 equal( panels.eq( 0 ).attr( "aria-expanded" ), "true", "first panel has aria-expanded=true" );
443 equal( panels.eq( 0 ).attr( "aria-hidden" ), "false", "first panel has aria-hidden=false" );
445 setTimeout( step7, 100 );
450 equal( tabs.eq( 0 ).attr( "aria-selected" ), "true", "first tab has aria-selected=true" );
451 ok( panels.eq( 0 ).is( ":visible" ), "first panel is visible" );
452 equal( panels.eq( 0 ).attr( "aria-expanded" ), "true", "first panel has aria-expanded=true" );
453 equal( panels.eq( 0 ).attr( "aria-hidden" ), "false", "first panel has aria-hidden=false" );
455 tabs.eq( 0 ).simulate( "keydown", { keyCode: keyCode.END, ctrlKey: true } );
456 ok( tabs.eq( 2 ).is( ".ui-state-focus" ), "END moves focus to last tab" );
457 equal( tabs.eq( 2 ).attr( "aria-selected" ), "false", "third tab has aria-selected=false" );
458 equal( tabs.eq( 0 ).attr( "aria-selected" ), "true", "first tab has aria-selected=true" );
459 ok( panels.eq( 2 ).is( ":hidden" ), "third panel is still hidden" );
460 equal( panels.eq( 2 ).attr( "aria-expanded" ), "false", "third panel has aria-expanded=false" );
461 equal( panels.eq( 2 ).attr( "aria-hidden" ), "true", "third panel has aria-hidden=true" );
462 ok( panels.eq( 0 ).is( ":visible" ), "first panel is still visible" );
463 equal( panels.eq( 0 ).attr( "aria-expanded" ), "true", "first panel has aria-expanded=true" );
464 equal( panels.eq( 0 ).attr( "aria-hidden" ), "false", "first panel has aria-hidden=false" );
466 setTimeout( step8, 100 );
471 equal( tabs.eq( 0 ).attr( "aria-selected" ), "true", "first tab has aria-selected=true" );
472 ok( panels.eq( 0 ).is( ":visible" ), "first panel is visible" );
473 equal( panels.eq( 0 ).attr( "aria-expanded" ), "true", "first panel has aria-expanded=true" );
474 equal( panels.eq( 0 ).attr( "aria-hidden" ), "false", "first panel has aria-hidden=false" );
475 ok( panels.eq( 2 ).is( ":hidden" ), "third panel is hidden" );
476 equal( panels.eq( 2 ).attr( "aria-expanded" ), "false", "third panel has aria-expanded=false" );
477 equal( panels.eq( 2 ).attr( "aria-hidden" ), "true", "third panel has aria-hidden=true" );
479 tabs.eq( 2 ).simulate( "keydown", { keyCode: keyCode.SPACE } );
480 equal( tabs.eq( 2 ).attr( "aria-selected" ), "true", "third tab has aria-selected=true" );
481 equal( tabs.eq( 0 ).attr( "aria-selected" ), "false", "first tab has aria-selected=false" );
482 ok( panels.eq( 2 ).is( ":visible" ), "third panel is visible" );
483 equal( panels.eq( 2 ).attr( "aria-expanded" ), "true", "third panel has aria-expanded=true" );
484 equal( panels.eq( 2 ).attr( "aria-hidden" ), "false", "third panel has aria-hidden=false" );
485 ok( panels.eq( 0 ).is( ":hidden" ), "first panel is hidden" );
486 equal( panels.eq( 0 ).attr( "aria-expanded" ), "false", "first panel has aria-expanded=false" );
487 equal( panels.eq( 0 ).attr( "aria-hidden" ), "true", "first panel has aria-hidden=true" );
489 setTimeout( start, 1 );
492 setTimeout( step1, 1 );
495 asyncTest( "keyboard support - CTRL+UP, ALT+PAGE_DOWN, ALT+PAGE_UP", function() {
497 var element = $( "#tabs1" ).tabs(),
498 tabs = element.find( ".ui-tabs-nav li" ),
499 panels = element.find( ".ui-tabs-panel" ),
500 keyCode = $.ui.keyCode;
502 equal( tabs.filter( ".ui-state-focus" ).length, 0, "no tabs focused on init" );
503 panels.attr( "tabindex", -1 );
504 panels.eq( 0 ).simulate( "focus" );
507 strictEqual( document.activeElement, panels[ 0 ], "first panel is activeElement" );
509 panels.eq( 0 ).simulate( "keydown", { keyCode: keyCode.PAGE_DOWN, altKey: true } );
510 strictEqual( document.activeElement, tabs[ 1 ], "second tab is activeElement" );
511 ok( tabs.eq( 1 ).is( ".ui-state-focus" ), "ALT+PAGE_DOWN moves focus to next tab" );
512 equal( tabs.eq( 1 ).attr( "aria-selected" ), "true", "second tab has aria-selected=true" );
513 ok( panels.eq( 1 ).is( ":visible" ), "second panel is visible" );
514 equal( panels.eq( 1 ).attr( "aria-expanded" ), "true", "second panel has aria-expanded=true" );
515 equal( panels.eq( 1 ).attr( "aria-hidden" ), "false", "second panel has aria-hidden=false" );
516 ok( panels.eq( 0 ).is( ":hidden" ), "first panel is hidden" );
517 equal( panels.eq( 0 ).attr( "aria-expanded" ), "false", "first panel has aria-expanded=false" );
518 equal( panels.eq( 0 ).attr( "aria-hidden" ), "true", "first panel has aria-hidden=true" );
520 tabs.eq( 1 ).simulate( "keydown", { keyCode: keyCode.PAGE_DOWN, altKey: true } );
521 strictEqual( document.activeElement, tabs[ 2 ], "third tab is activeElement" );
522 ok( tabs.eq( 2 ).is( ".ui-state-focus" ), "ALT+PAGE_DOWN moves focus to next tab" );
523 equal( tabs.eq( 2 ).attr( "aria-selected" ), "true", "third tab has aria-selected=true" );
524 ok( panels.eq( 2 ).is( ":visible" ), "third panel is visible" );
525 equal( panels.eq( 2 ).attr( "aria-expanded" ), "true", "third panel has aria-expanded=true" );
526 equal( panels.eq( 2 ).attr( "aria-hidden" ), "false", "third panel has aria-hidden=false" );
527 ok( panels.eq( 1 ).is( ":hidden" ), "second panel is hidden" );
528 equal( panels.eq( 1 ).attr( "aria-expanded" ), "false", "second panel has aria-expanded=false" );
529 equal( panels.eq( 1 ).attr( "aria-hidden" ), "true", "second panel has aria-hidden=true" );
531 tabs.eq( 2 ).simulate( "keydown", { keyCode: keyCode.PAGE_DOWN, altKey: true } );
532 strictEqual( document.activeElement, tabs[ 0 ], "first tab is activeElement" );
533 ok( tabs.eq( 0 ).is( ".ui-state-focus" ), "ALT+PAGE_DOWN wraps focus to first tab" );
534 equal( tabs.eq( 0 ).attr( "aria-selected" ), "true", "first tab has aria-selected=true" );
535 ok( panels.eq( 0 ).is( ":visible" ), "first panel is visible" );
536 equal( panels.eq( 0 ).attr( "aria-expanded" ), "true", "first panel has aria-expanded=true" );
537 equal( panels.eq( 0 ).attr( "aria-hidden" ), "false", "first panel has aria-hidden=false" );
538 ok( panels.eq( 2 ).is( ":hidden" ), "third panel is hidden" );
539 equal( panels.eq( 2 ).attr( "aria-expanded" ), "false", "third panel has aria-expanded=false" );
540 equal( panels.eq( 2 ).attr( "aria-hidden" ), "true", "third panel has aria-hidden=true" );
542 panels.eq( 0 ).simulate( "focus" );
543 setTimeout( step2, 1 );
547 strictEqual( document.activeElement, panels[ 0 ], "first panel is activeElement" );
549 panels.eq( 0 ).simulate( "keydown", { keyCode: keyCode.PAGE_UP, altKey: true } );
550 strictEqual( document.activeElement, tabs[ 2 ], "third tab is activeElement" );
551 ok( tabs.eq( 2 ).is( ".ui-state-focus" ), "ALT+PAGE_UP wraps focus to last tab" );
552 equal( tabs.eq( 2 ).attr( "aria-selected" ), "true", "third tab has aria-selected=true" );
553 ok( panels.eq( 2 ).is( ":visible" ), "third panel is visible" );
554 equal( panels.eq( 2 ).attr( "aria-expanded" ), "true", "third panel has aria-expanded=true" );
555 equal( panels.eq( 2 ).attr( "aria-hidden" ), "false", "third panel has aria-hidden=false" );
556 ok( panels.eq( 0 ).is( ":hidden" ), "first panel is hidden" );
557 equal( panels.eq( 0 ).attr( "aria-expanded" ), "false", "first panel has aria-expanded=false" );
558 equal( panels.eq( 0 ).attr( "aria-hidden" ), "true", "first panel has aria-hidden=true" );
560 tabs.eq( 2 ).simulate( "keydown", { keyCode: keyCode.PAGE_UP, altKey: true } );
561 strictEqual( document.activeElement, tabs[ 1 ], "second tab is activeElement" );
562 ok( tabs.eq( 1 ).is( ".ui-state-focus" ), "ALT+PAGE_UP moves focus to previous tab" );
563 equal( tabs.eq( 1 ).attr( "aria-selected" ), "true", "second tab has aria-selected=true" );
564 ok( panels.eq( 1 ).is( ":visible" ), "second panel is visible" );
565 equal( panels.eq( 1 ).attr( "aria-expanded" ), "true", "second panel has aria-expanded=true" );
566 equal( panels.eq( 1 ).attr( "aria-hidden" ), "false", "second panel has aria-hidden=false" );
567 ok( panels.eq( 2 ).is( ":hidden" ), "third panel is hidden" );
568 equal( panels.eq( 2 ).attr( "aria-expanded" ), "false", "third panel has aria-expanded=false" );
569 equal( panels.eq( 2 ).attr( "aria-hidden" ), "true", "third panel has aria-hidden=true" );
571 panels.eq( 1 ).simulate( "focus" );
572 setTimeout( step3, 1 );
576 strictEqual( document.activeElement, panels[ 1 ], "second panel is activeElement" );
578 panels.eq( 1 ).simulate( "keydown", { keyCode: keyCode.UP, ctrlKey: true } );
579 strictEqual( document.activeElement, tabs[ 1 ], "second tab is activeElement" );
581 setTimeout( start, 1 );
584 setTimeout( step1, 1 );
587 test( "#3627 - Ajax tab with url containing a fragment identifier fails to load", function() {
592 beforeLoad: function( event, ui ) {
593 event.preventDefault();
594 ok( /test.html$/.test( ui.ajaxSettings.url ), "should ignore fragment identifier" );
599 test( "#4033 - IE expands hash to full url and misinterprets tab as ajax", function() {
602 var element = $("<div><ul><li><a href='#tab'>Tab</a></li></ul><div id='tab'></div></div>");
603 element.appendTo("#qunit-fixture");
605 beforeLoad: function() {
606 event.preventDefault();
607 ok( false, "should not be an ajax tab" );
611 equal( element.find(".ui-tabs-nav li").attr("aria-controls"), "tab", "aria-contorls attribute is correct" );