3 var log = TestHelpers.menu.log,
4 logOutput = TestHelpers.menu.logOutput,
5 click = TestHelpers.menu.click;
7 module( "menu: events", {
9 TestHelpers.menu.clearLog();
13 test( "handle click on menu", function() {
15 var element = $( "#menu1" ).menu({
21 click( $( "#menu1" ), "1" );
23 click( element, "2" );
24 click( $( "#menu1" ), "3" );
25 click( element, "1" );
26 equal( logOutput(), "click,1,afterclick,2,3,1", "Click order not valid." );
29 test( "handle click on custom item menu", function() {
31 var element = $( "#menu5" ).menu({
38 click( $( "#menu5" ), "1" );
40 click( element, "2" );
41 click( $( "#menu5" ), "3" );
42 click( element, "1" );
43 equal( logOutput(), "click,1,afterclick,2,3,1", "Click order not valid." );
46 asyncTest( "handle blur", function() {
48 var blurHandled = false,
49 element = $( "#menu1" ).menu({
50 blur: function( event ) {
51 // Ignore duplicate blur event fired by IE
54 equal( event.type, "menublur", "blur event.type is 'menublur'" );
59 click( element, "1" );
60 setTimeout(function() {
62 setTimeout(function() {
68 asyncTest( "handle blur via click outside", function() {
70 var blurHandled = false,
71 element = $( "#menu1" ).menu({
72 blur: function( event ) {
73 // Ignore duplicate blur event fired by IE
76 equal( event.type, "menublur", "blur event.type is 'menublur'" );
81 click( element, "1" );
82 setTimeout(function() {
83 $( "<a>", { id: "remove"} ).appendTo( "body" ).trigger( "click" );
84 setTimeout(function() {
90 asyncTest( "handle focus of menu with active item", function() {
92 var element = $( "#menu1" ).menu({
93 focus: function( event ) {
94 log( $( event.target ).find( ".ui-state-focus" ).parent().index() );
100 setTimeout(function() {
101 element.simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } );
102 element.simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } );
104 setTimeout(function() {
106 setTimeout(function() {
107 equal( logOutput(), "focus,0,1,2,2", "current active item remains active" );
114 asyncTest( "handle submenu auto collapse: mouseleave", function() {
116 var element = $( "#menu2" ).menu(),
117 event = $.Event( "mouseenter" );
119 function menumouseleave1() {
120 equal( element.find( "ul[aria-expanded='true']" ).length, 1, "first submenu expanded" );
121 element.menu( "focus", event, element.find( "li:nth-child(7) li:first" ) );
122 setTimeout( menumouseleave2, 350 );
124 function menumouseleave2() {
125 equal( element.find( "ul[aria-expanded='true']" ).length, 2, "second submenu expanded" );
126 element.find( "ul[aria-expanded='true']:first" ).trigger( "mouseleave" );
127 setTimeout( menumouseleave3, 350 );
129 function menumouseleave3() {
130 equal( element.find( "ul[aria-expanded='true']" ).length, 1, "second submenu collapsed" );
131 element.trigger( "mouseleave" );
132 setTimeout( menumouseleave4, 350 );
134 function menumouseleave4() {
135 equal( element.find( "ul[aria-expanded='true']" ).length, 0, "first submenu collapsed" );
139 element.find( "li:nth-child(7)" ).trigger( "mouseenter" );
140 setTimeout( menumouseleave1, 350 );
143 asyncTest( "handle submenu auto collapse: mouseleave", function() {
145 var element = $( "#menu5" ).menu({ menus: "div" }),
146 event = $.Event( "mouseenter" );
148 function menumouseleave1() {
149 equal( element.find( "div[aria-expanded='true']" ).length, 1, "first submenu expanded" );
150 element.menu( "focus", event, element.find( ":nth-child(7)" ).find( "div" ).eq( 0 ).children().eq( 0 ) );
151 setTimeout( menumouseleave2, 350 );
153 function menumouseleave2() {
154 equal( element.find( "div[aria-expanded='true']" ).length, 2, "second submenu expanded" );
155 element.find( "div[aria-expanded='true']:first" ).trigger( "mouseleave" );
156 setTimeout( menumouseleave3, 350 );
158 function menumouseleave3() {
159 equal( element.find( "div[aria-expanded='true']" ).length, 1, "second submenu collapsed" );
160 element.trigger( "mouseleave" );
161 setTimeout( menumouseleave4, 350 );
163 function menumouseleave4() {
164 equal( element.find( "div[aria-expanded='true']" ).length, 0, "first submenu collapsed" );
168 element.find( ":nth-child(7)" ).trigger( "mouseenter" );
169 setTimeout( menumouseleave1, 350 );
173 asyncTest( "handle keyboard navigation on menu without scroll and without submenus", function() {
175 var element = $( "#menu1" ).menu({
176 select: function( event, ui ) {
177 log( $( ui.item[0] ).text() );
179 focus: function( event ) {
180 log( $( event.target ).find( ".ui-state-focus" ).parent().index() );
184 log( "keydown", true );
186 setTimeout(function() {
187 element.simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } );
188 element.simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } );
189 equal( logOutput(), "keydown,0,1,2", "Keydown DOWN" );
191 log( "keydown", true );
192 element.simulate( "keydown", { keyCode: $.ui.keyCode.UP } );
193 equal( logOutput(), "keydown,1", "Keydown UP" );
195 log( "keydown", true );
196 element.simulate( "keydown", { keyCode: $.ui.keyCode.LEFT } );
197 equal( logOutput(), "keydown", "Keydown LEFT (no effect)" );
199 log( "keydown", true );
200 element.simulate( "keydown", { keyCode: $.ui.keyCode.RIGHT } );
201 equal( logOutput(), "keydown", "Keydown RIGHT (no effect)" );
203 log( "keydown", true );
204 element.simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_DOWN } );
205 equal( logOutput(), "keydown,4", "Keydown PAGE_DOWN" );
207 log( "keydown", true );
208 element.simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_DOWN } );
209 equal( logOutput(), "keydown", "Keydown PAGE_DOWN (no effect)" );
211 log( "keydown", true );
212 element.simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_UP } );
213 equal( logOutput(), "keydown,0", "Keydown PAGE_UP" );
215 log( "keydown", true );
216 element.simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_UP } );
217 equal( logOutput(), "keydown", "Keydown PAGE_UP (no effect)" );
219 log( "keydown", true );
220 element.simulate( "keydown", { keyCode: $.ui.keyCode.END } );
221 equal( logOutput(), "keydown,4", "Keydown END" );
223 log( "keydown", true );
224 element.simulate( "keydown", { keyCode: $.ui.keyCode.HOME } );
225 equal( logOutput(), "keydown,0", "Keydown HOME" );
227 log( "keydown", true );
228 element.simulate( "keydown", { keyCode: $.ui.keyCode.ESCAPE } );
229 equal( logOutput(), "keydown", "Keydown ESCAPE (no effect)" );
231 log( "keydown", true );
232 element.simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } );
233 equal( logOutput(), "keydown,Aberdeen", "Keydown ENTER" );
239 asyncTest( "handle keyboard navigation on menu without scroll and with submenus", function() {
241 var element = $( "#menu2" ).menu({
242 select: function( event, ui ) {
243 log( $( ui.item[0] ).text() );
245 focus: function( event ) {
246 log( $( event.target ).find( ".ui-state-focus" ).parent().index() );
250 log( "keydown", true );
251 element.one( "menufocus", function() {
252 element.simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } );
253 element.simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } );
254 equal( logOutput(), "keydown,1,2", "Keydown DOWN" );
255 setTimeout( menukeyboard1, 50 );
259 function menukeyboard1() {
260 log( "keydown", true );
261 element.simulate( "keydown", { keyCode: $.ui.keyCode.UP } );
262 element.simulate( "keydown", { keyCode: $.ui.keyCode.UP } );
263 equal( logOutput(), "keydown,1,0", "Keydown UP" );
265 log( "keydown", true );
266 element.simulate( "keydown", { keyCode: $.ui.keyCode.LEFT } );
267 equal( logOutput(), "keydown", "Keydown LEFT (no effect)" );
269 log( "keydown", true );
270 element.simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } );
271 element.simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } );
272 element.simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } );
273 element.simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } );
274 element.simulate( "keydown", { keyCode: $.ui.keyCode.RIGHT } );
276 setTimeout(function() {
277 equal( logOutput(), "keydown,1,2,3,4,0", "Keydown RIGHT (open submenu)" );
278 setTimeout( menukeyboard2, 50 );
282 function menukeyboard2() {
283 log( "keydown", true );
284 element.simulate( "keydown", { keyCode: $.ui.keyCode.LEFT } );
285 equal( logOutput(), "keydown,4", "Keydown LEFT (close submenu)" );
288 element.simulate( "keydown", { keyCode: $.ui.keyCode.RIGHT } );
289 setTimeout( menukeyboard3, 50 );
292 function menukeyboard3() {
293 log( "keydown", true );
294 element.simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_DOWN } );
295 equal( logOutput(), "keydown,2", "Keydown PAGE_DOWN" );
297 log( "keydown", true );
298 element.simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_DOWN } );
299 equal( logOutput(), "keydown", "Keydown PAGE_DOWN (no effect)" );
301 log( "keydown", true );
302 element.simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_UP } );
303 equal( logOutput(), "keydown,0", "Keydown PAGE_UP" );
305 log( "keydown", true );
306 element.simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_UP } );
307 equal( logOutput(), "keydown", "Keydown PAGE_UP (no effect)" );
309 log( "keydown", true );
310 element.simulate( "keydown", { keyCode: $.ui.keyCode.END } );
311 equal( logOutput(), "keydown,2", "Keydown END" );
313 log( "keydown", true );
314 element.simulate( "keydown", { keyCode: $.ui.keyCode.HOME } );
315 equal( logOutput(), "keydown,0", "Keydown HOME" );
317 log( "keydown", true );
318 element.simulate( "keydown", { keyCode: $.ui.keyCode.ESCAPE } );
319 equal( logOutput(), "keydown,4", "Keydown ESCAPE (close submenu)" );
321 log( "keydown", true );
322 element.simulate( "keydown", { keyCode: $.ui.keyCode.SPACE } );
323 setTimeout( menukeyboard4, 50 );
326 function menukeyboard4() {
327 equal( logOutput(), "keydown,0", "Keydown SPACE (open submenu)" );
329 log( "keydown", true );
330 element.simulate( "keydown", { keyCode: $.ui.keyCode.ESCAPE } );
331 equal( logOutput(), "keydown,4", "Keydown ESCAPE (close submenu)" );
333 log( "keydown", true );
334 element.simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } );
335 element.simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } );
336 element.simulate( "keydown", { keyCode: $.ui.keyCode.RIGHT } );
337 setTimeout( function() {
338 element.simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } );
339 element.simulate( "keydown", { keyCode: $.ui.keyCode.RIGHT } );
340 setTimeout( function() {
341 element.simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } );
342 element.simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } );
343 element.simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } );
344 equal( logOutput(), "keydown,5,6,0,1,0,2,4,0", "Keydown skip dividers and items without anchors" );
346 log( "keydown", true );
347 element.simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } );
348 setTimeout( menukeyboard6, 50 );
353 function menukeyboard6() {
354 equal( logOutput(), "keydown,Ada", "Keydown ENTER (open submenu)" );
359 asyncTest( "handle keyboard navigation on menu with scroll and without submenus", function() {
361 var element = $( "#menu3" ).menu({
362 select: function( event, ui ) {
363 log( $( ui.item[0] ).text() );
365 focus: function( event ) {
366 log( $( event.target ).find( ".ui-state-focus" ).parent().index());
370 log( "keydown", true );
372 setTimeout(function() {
373 element.simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } );
374 element.simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } );
375 equal( logOutput(), "keydown,0,1,2", "Keydown DOWN" );
377 log( "keydown", true );
378 element.simulate( "keydown", { keyCode: $.ui.keyCode.UP } );
379 element.simulate( "keydown", { keyCode: $.ui.keyCode.UP } );
380 equal( logOutput(), "keydown,1,0", "Keydown UP" );
382 log( "keydown", true );
383 element.simulate( "keydown", { keyCode: $.ui.keyCode.LEFT } );
384 equal( logOutput(), "keydown", "Keydown LEFT (no effect)" );
386 log( "keydown", true );
387 element.simulate( "keydown", { keyCode: $.ui.keyCode.RIGHT } );
388 equal( logOutput(), "keydown", "Keydown RIGHT (no effect)" );
390 log( "keydown", true );
391 element.simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_DOWN } );
392 equal( logOutput(), "keydown,10", "Keydown PAGE_DOWN" );
394 log( "keydown", true );
395 element.simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_DOWN } );
396 equal( logOutput(), "keydown,20", "Keydown PAGE_DOWN" );
398 log( "keydown", true );
399 element.simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_UP } );
400 equal( logOutput(), "keydown,10", "Keydown PAGE_UP" );
402 log( "keydown", true );
403 element.simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_UP } );
404 equal( logOutput(), "keydown,0", "Keydown PAGE_UP" );
406 log( "keydown", true );
407 element.simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_UP } );
408 equal( logOutput(), "keydown", "Keydown PAGE_UP (no effect)" );
410 log( "keydown", true );
411 element.simulate( "keydown", { keyCode: $.ui.keyCode.END } );
412 equal( logOutput(), "keydown,37", "Keydown END" );
414 log( "keydown", true );
415 element.simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_DOWN } );
416 equal( logOutput(), "keydown", "Keydown PAGE_DOWN (no effect)" );
418 log( "keydown", true );
419 element.simulate( "keydown", { keyCode: $.ui.keyCode.HOME } );
420 equal( logOutput(), "keydown,0", "Keydown HOME" );
422 log( "keydown", true );
423 element.simulate( "keydown", { keyCode: $.ui.keyCode.ESCAPE } );
424 equal( logOutput(), "keydown", "Keydown ESCAPE (no effect)" );
426 log( "keydown", true );
427 element.simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } );
428 equal( logOutput(), "keydown,Aberdeen", "Keydown ENTER" );
434 asyncTest( "handle keyboard navigation on menu with scroll and with submenus", function() {
436 var element = $( "#menu4" ).menu({
437 select: function( event, ui ) {
438 log( $( ui.item[0] ).text() );
440 focus: function( event ) {
441 log( $( event.target ).find( ".ui-state-focus" ).parent().index());
445 log( "keydown", true );
446 element.one( "menufocus", function() {
447 element.simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } );
448 element.simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } );
449 equal( logOutput(), "keydown,1,2", "Keydown DOWN" );
450 setTimeout( menukeyboard1, 50 );
454 function menukeyboard1() {
455 log( "keydown", true );
456 element.simulate( "keydown", { keyCode: $.ui.keyCode.UP } );
457 element.simulate( "keydown", { keyCode: $.ui.keyCode.UP } );
458 equal( logOutput(), "keydown,1,0", "Keydown UP" );
460 log( "keydown", true );
461 element.simulate( "keydown", { keyCode: $.ui.keyCode.LEFT } );
462 equal( logOutput(), "keydown", "Keydown LEFT (no effect)" );
464 log( "keydown", true );
465 element.simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } );
466 element.simulate( "keydown", { keyCode: $.ui.keyCode.RIGHT } );
468 setTimeout( function() {
469 equal( logOutput(), "keydown,1,0", "Keydown RIGHT (open submenu)" );
471 setTimeout( menukeyboard2, 50 );
474 function menukeyboard2() {
475 log( "keydown", true );
476 element.simulate( "keydown", { keyCode: $.ui.keyCode.LEFT } );
477 equal( logOutput(), "keydown,1", "Keydown LEFT (close submenu)" );
480 element.simulate( "keydown", { keyCode: $.ui.keyCode.RIGHT } );
481 setTimeout( menukeyboard3, 50 );
484 function menukeyboard3() {
485 log( "keydown", true );
486 element.simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_DOWN } );
487 equal( logOutput(), "keydown,10", "Keydown PAGE_DOWN" );
489 log( "keydown", true );
490 element.simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_DOWN } );
491 equal( logOutput(), "keydown,20", "Keydown PAGE_DOWN" );
493 log( "keydown", true );
494 element.simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_UP } );
495 equal( logOutput(), "keydown,10", "Keydown PAGE_UP" );
497 log( "keydown", true );
498 element.simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_UP } );
499 equal( logOutput(), "keydown,0", "Keydown PAGE_UP" );
501 log( "keydown", true );
502 element.simulate( "keydown", { keyCode: $.ui.keyCode.END } );
503 equal( logOutput(), "keydown,27", "Keydown END" );
505 log( "keydown", true );
506 element.simulate( "keydown", { keyCode: $.ui.keyCode.HOME } );
507 equal( logOutput(), "keydown,0", "Keydown HOME" );
509 log( "keydown", true );
510 element.simulate( "keydown", { keyCode: $.ui.keyCode.ESCAPE } );
511 equal( logOutput(), "keydown,1", "Keydown ESCAPE (close submenu)" );
513 log( "keydown", true );
514 element.simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } );
515 setTimeout( menukeyboard4, 50 );
518 function menukeyboard4() {
519 equal( logOutput(), "keydown,0", "Keydown ENTER (open submenu)" );
521 log( "keydown", true );
522 element.simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } );
523 equal( logOutput(), "keydown,Aberdeen", "Keydown ENTER (select item)" );
529 asyncTest( "handle keyboard navigation and mouse click on menu with disabled items", function() {
531 var element = $( "#menu6" ).menu({
532 select: function( event, ui ) {
533 log( $( ui.item[0] ).text() );
535 focus: function( event ) {
536 log( $( event.target ).find( ".ui-state-focus" ).parent().index());
540 log( "keydown", true );
541 element.one( "menufocus", function() {
542 element.simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } );
543 element.simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } );
544 equal( logOutput(), "keydown,1", "Keydown focus but not select disabled item" );
545 setTimeout( menukeyboard1, 50 );
549 function menukeyboard1() {
550 log( "keydown", true );
551 element.simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } );
552 element.simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } );
553 element.simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } );
554 equal( logOutput(), "keydown,2,3,4", "Keydown focus disabled item with submenu" );
556 log( "keydown", true );
557 element.simulate( "keydown", { keyCode: $.ui.keyCode.LEFT } );
558 equal( logOutput(), "keydown", "Keydown LEFT (no effect)" );
560 log( "keydown", true );
561 element.simulate( "keydown", { keyCode: $.ui.keyCode.RIGHT } );
563 setTimeout( function() {
564 equal( logOutput(), "keydown", "Keydown RIGHT (no effect on disabled sub-menu)" );
566 log( "keydown", true );
567 element.simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } );
569 setTimeout( function() {
570 equal( logOutput(), "keydown", "Keydown ENTER (no effect on disabled sub-menu)" );
571 log( "click", true );
572 click( element, "1" );
573 equal( logOutput(), "click", "Click disabled item (no effect)" );
580 asyncTest( "handle keyboard navigation with spelling of menu items", function() {
582 var element = $( "#menu2" ).menu({
583 focus: function( event ) {
584 log( $( event.target ).find( ".ui-state-focus" ).parent().index() );
588 log( "keydown", true );
589 element.one( "menufocus", function() {
590 element.simulate( "keydown", { keyCode: 65 } );
591 element.simulate( "keydown", { keyCode: 68 } );
592 element.simulate( "keydown", { keyCode: 68 } );
593 equal( logOutput(), "keydown,0,1,3", "Keydown focus Addyston by spelling the first 3 letters" );
594 element.simulate( "keydown", { keyCode: 68 } );
595 equal( logOutput(), "keydown,0,1,3,4", "Keydown focus Delphi by repeating the 'd' again" );