]> source.dussan.org Git - jquery-ui.git/commitdiff
Menu: Added Home moves to first item and End moves to last item in currently active... 397/head
authorkborchers <k_borchers@yahoo.com>
Mon, 25 Jul 2011 14:13:13 +0000 (09:13 -0500)
committerkborchers <k_borchers@yahoo.com>
Mon, 25 Jul 2011 14:13:13 +0000 (09:13 -0500)
tests/unit/menu/menu.html
tests/unit/menu/menu_events.js
ui/jquery.ui.menu.js

index c917f5c4bebdec2f178f573e4e0868ec337df39e..ec2c82e6be341c206192ff1a6fd02f58a23d7d3c 100644 (file)
@@ -31,7 +31,7 @@
                        $("#log").data("lastItem",item);
                        $('li:eq(' + item + ') a',menu).trigger("click");
                }
-       
+
 
        </script>
        <script type="text/javascript" src="menu_core.js"></script>
        <script type="text/javascript" src="menu_options.js"></script>
 
        <script type="text/javascript" src="../swarminject.js"></script>
-       
+
        <style>
                #qunit-fixture { font-size: 10pt; font-family: 'trebuchet ms', verdana, arial; }
                #list, #list1 *, #navigation, #navigation * { margin: 0; padding: 0; font-size: 12px; }
+               #menu3 { height: 250px; overflow: auto; }
+               #menu4, #menu4 ul { height: 250px; overflow: auto; }
        </style>
 </head>
 <body>
        <li class="foo"><a class="foo" href="#">Addyston</a></li>
        <li class="foo"><a class="foo" href="#">Adelphi</a></li>
 </ul>
+
+<ul id="menu2">
+       <li class="foo"><a class="foo" href="#">Aberdeen</a></li>
+       <li class="foo"><a class="foo" href="#">Ada</a></li>
+       <li class="foo"><a class="foo" href="#">Adamsville</a></li>
+       <li class="foo"><a class="foo" href="#">Addyston</a></li>
+       <li>
+               <a href="#">Delphi</a>
+               <ul>
+                       <li class="foo"><a class="foo" href="#">Ada</a></li>
+                       <li class="foo"><a class="foo" href="#">Saarland</a></li>
+                       <li class="foo"><a class="foo" href="#">Salzburg</a></li>
+               </ul>
+       </li>
+       <li class="foo"><a class="foo" href="#">Saarland</a></li>
+       <li>
+               <a href="#">Salzburg</a>
+               <ul>
+                       <li>
+                               <a href="#">Delphi</a>
+                               <ul>
+                                       <li class="foo"><a class="foo" href="#">Ada</a></li>
+                                       <li class="foo"><a class="foo" href="#">Saarland</a></li>
+                                       <li class="foo"><a class="foo" href="#">Salzburg</a></li>
+                               </ul>
+                       </li>
+                       <li>
+                               <a href="#">Delphi</a>
+                               <ul>
+                                       <li class="foo"><a class="foo" href="#">Ada</a></li>
+                                       <li class="foo"><a class="foo" href="#">Saarland</a></li>
+                                       <li class="foo"><a class="foo" href="#">Salzburg</a></li>
+                               </ul>
+                       </li>
+                       <li class="foo"><a class="foo" href="#">Perch</a></li>
+               </ul>
+       </li>
+</ul>
+
+<ul class="foo" id="menu3">
+       <li class="foo"><a class="foo" href="#">Aberdeen</a></li>
+       <li class="foo"><a class="foo" href="#">Ada</a></li>
+       <li class="foo"><a class="foo" href="#">Adamsville</a></li>
+       <li class="foo"><a class="foo" href="#">Addyston</a></li>
+       <li class="foo"><a class="foo" href="#">Adelphi</a></li>
+       <li class="foo"><a class="foo" href="#">Adena</a></li>
+       <li class="foo"><a class="foo" href="#">Adrian</a></li>
+       <li class="foo"><a class="foo" href="#">Akron</a></li>
+       <li class="foo"><a class="foo" href="#">Albany</a></li>
+       <li class="foo"><a class="foo" href="#">Alexandria</a></li>
+       <li class="foo"><a class="foo" href="#">Alger</a></li>
+       <li class="foo"><a class="foo" href="#">Alledonia</a></li>
+       <li class="foo"><a class="foo" href="#">Alliance</a></li>
+       <li class="foo"><a class="foo" href="#">Alpha</a></li>
+       <li class="foo"><a class="foo" href="#">Alvada</a></li>
+       <li class="foo"><a class="foo" href="#">Alvordton</a></li>
+       <li class="foo"><a class="foo" href="#">Amanda</a></li>
+       <li class="foo"><a class="foo" href="#">Amelia</a></li>
+       <li class="foo"><a class="foo" href="#">Amesville</a></li>
+       <li class="foo"><a class="foo" href="#">Aberdeen</a></li>
+       <li class="foo"><a class="foo" href="#">Ada</a></li>
+       <li class="foo"><a class="foo" href="#">Adamsville</a></li>
+       <li class="foo"><a class="foo" href="#">Addyston</a></li>
+       <li class="foo"><a class="foo" href="#">Adelphi</a></li>
+       <li class="foo"><a class="foo" href="#">Adena</a></li>
+       <li class="foo"><a class="foo" href="#">Adrian</a></li>
+       <li class="foo"><a class="foo" href="#">Akron</a></li>
+       <li class="foo"><a class="foo" href="#">Albany</a></li>
+       <li class="foo"><a class="foo" href="#">Alexandria</a></li>
+       <li class="foo"><a class="foo" href="#">Alger</a></li>
+       <li class="foo"><a class="foo" href="#">Alledonia</a></li>
+       <li class="foo"><a class="foo" href="#">Alliance</a></li>
+       <li class="foo"><a class="foo" href="#">Alpha</a></li>
+       <li class="foo"><a class="foo" href="#">Alvada</a></li>
+       <li class="foo"><a class="foo" href="#">Alvordton</a></li>
+       <li class="foo"><a class="foo" href="#">Amanda</a></li>
+       <li class="foo"><a class="foo" href="#">Amelia</a></li>
+       <li class="foo"><a class="foo" href="#">Amesville</a></li>
+</ul>
+
+<ul class="foo" id="menu4">
+       <li class="foo"><a class="foo" href="#">Aberdeen</a></li>
+       <li class="foo">
+               <a class="foo" href="#">Ada</a>
+               <ul class="foo">
+                       <li class="foo"><a class="foo" href="#">Aberdeen</a></li>
+                       <li class="foo"><a class="foo" href="#">Ada</a></li>
+                       <li class="foo"><a class="foo" href="#">Adamsville</a></li>
+                       <li class="foo"><a class="foo" href="#">Addyston</a></li>
+                       <li class="foo"><a class="foo" href="#">Adelphi</a></li>
+                       <li class="foo"><a class="foo" href="#">Adena</a></li>
+                       <li class="foo"><a class="foo" href="#">Adrian</a></li>
+                       <li class="foo"><a class="foo" href="#">Akron</a></li>
+                       <li class="foo"><a class="foo" href="#">Albany</a></li>
+                       <li class="foo"><a class="foo" href="#">Alexandria</a></li>
+                       <li class="foo"><a class="foo" href="#">Alger</a></li>
+                       <li class="foo"><a class="foo" href="#">Alledonia</a></li>
+                       <li class="foo"><a class="foo" href="#">Alliance</a></li>
+                       <li class="foo"><a class="foo" href="#">Alpha</a></li>
+                       <li class="foo"><a class="foo" href="#">Alvada</a></li>
+                       <li class="foo"><a class="foo" href="#">Alvordton</a></li>
+                       <li class="foo"><a class="foo" href="#">Amanda</a></li>
+                       <li class="foo"><a class="foo" href="#">Amelia</a></li>
+                       <li class="foo"><a class="foo" href="#">Amesville</a></li>
+                       <li class="foo"><a class="foo" href="#">Aberdeen</a></li>
+                       <li class="foo"><a class="foo" href="#">Ada</a></li>
+                       <li class="foo"><a class="foo" href="#">Adamsville</a></li>
+                       <li class="foo"><a class="foo" href="#">Addyston</a></li>
+                       <li class="foo"><a class="foo" href="#">Adelphi</a></li>
+                       <li class="foo"><a class="foo" href="#">Adena</a></li>
+                       <li class="foo"><a class="foo" href="#">Adrian</a></li>
+                       <li class="foo"><a class="foo" href="#">Akron</a></li>
+                       <li class="foo"><a class="foo" href="#">Albany</a></li>
+               </ul>
+       </li>
+       <li class="foo"><a class="foo" href="#">Adamsville</a></li>
+       <li class="foo"><a class="foo" href="#">Addyston</a></li>
+       <li class="foo"><a class="foo" href="#">Adelphi</a></li>
+       <li class="foo"><a class="foo" href="#">Adena</a></li>
+       <li class="foo"><a class="foo" href="#">Adrian</a></li>
+       <li class="foo"><a class="foo" href="#">Akron</a></li>
+       <li class="foo"><a class="foo" href="#">Albany</a></li>
+       <li class="foo"><a class="foo" href="#">Alexandria</a></li>
+       <li class="foo"><a class="foo" href="#">Alger</a></li>
+       <li class="foo"><a class="foo" href="#">Alledonia</a></li>
+       <li class="foo"><a class="foo" href="#">Alliance</a></li>
+       <li class="foo"><a class="foo" href="#">Alpha</a></li>
+       <li class="foo"><a class="foo" href="#">Alvada</a></li>
+       <li class="foo"><a class="foo" href="#">Alvordton</a></li>
+       <li class="foo"><a class="foo" href="#">Amanda</a></li>
+       <li class="foo"><a class="foo" href="#">Amelia</a></li>
+       <li class="foo"><a class="foo" href="#">Amesville</a></li>
+       <li class="foo"><a class="foo" href="#">Aberdeen</a></li>
+       <li class="foo"><a class="foo" href="#">Ada</a></li>
+       <li class="foo"><a class="foo" href="#">Adamsville</a></li>
+       <li class="foo"><a class="foo" href="#">Addyston</a></li>
+       <li class="foo"><a class="foo" href="#">Adelphi</a></li>
+       <li class="foo"><a class="foo" href="#">Adena</a></li>
+       <li class="foo"><a class="foo" href="#">Adrian</a></li>
+       <li class="foo"><a class="foo" href="#">Akron</a></li>
+       <li class="foo"><a class="foo" href="#">Albany</a></li>
+       <li class="foo"><a class="foo" href="#">Alexandria</a></li>
+       <li class="foo"><a class="foo" href="#">Alger</a></li>
+       <li class="foo"><a class="foo" href="#">Alledonia</a></li>
+       <li class="foo"><a class="foo" href="#">Alliance</a></li>
+       <li class="foo"><a class="foo" href="#">Alpha</a></li>
+       <li class="foo"><a class="foo" href="#">Alvada</a></li>
+       <li class="foo"><a class="foo" href="#">Alvordton</a></li>
+       <li class="foo"><a class="foo" href="#">Amanda</a></li>
+       <li class="foo"><a class="foo" href="#">Amelia</a></li>
+       <li class="foo"><a class="foo" href="#">Amesville</a></li>
+</ul>
+
 <div id="log"></div>
 
 </div>
index 2f713acf8513ea5f62df087a533c6695915444ed..b949c827dc1914671bbda43f2d007c85b02c03c1 100644 (file)
@@ -42,4 +42,309 @@ test( "handle blur: click", function() {
        $("#remove").remove();
 });
 
+test("handle keyboard navigation on menu without scroll and without submenus", function() {
+       expect(12);
+       var element = $('#menu1').menu({
+               select: function(event, ui) {
+                       log($(ui.item[0]).text());
+               },
+               focus: function( event, ui ) {
+                       log($(event.target).find(".ui-state-focus").parent().index());
+               }
+       });
+
+       log("keydown",true);
+       element.simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } );
+       element.simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } );
+       equals( $("#log").html(), "1,0,keydown,", "Keydown DOWN");
+
+       log("keydown",true);
+       element.simulate( "keydown", { keyCode: $.ui.keyCode.UP } );
+       equals( $("#log").html(), "0,keydown,", "Keydown UP");
+
+       log("keydown",true);
+       element.simulate( "keydown", { keyCode: $.ui.keyCode.LEFT } );
+       equals( $("#log").html(), "keydown,", "Keydown LEFT (no effect)");
+
+       log("keydown",true);
+       element.simulate( "keydown", { keyCode: $.ui.keyCode.RIGHT } );
+       equals( $("#log").html(), "keydown,", "Keydown RIGHT (no effect)");
+
+       log("keydown",true);
+       element.simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_DOWN } );
+       equals( $("#log").html(), "4,keydown,", "Keydown PAGE_DOWN");
+
+       log("keydown",true);
+       element.simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_DOWN } );
+       equals( $("#log").html(), "keydown,", "Keydown PAGE_DOWN (no effect)");
+
+       log("keydown",true);
+       element.simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_UP } );
+       equals( $("#log").html(), "0,keydown,", "Keydown PAGE_UP");
+
+       log("keydown",true);
+       element.simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_UP } );
+       equals( $("#log").html(), "keydown,", "Keydown PAGE_UP (no effect)");
+
+       log("keydown",true);
+       element.simulate( "keydown", { keyCode: $.ui.keyCode.END } );
+       equals( $("#log").html(), "4,keydown,", "Keydown END");
+
+       log("keydown",true);
+       element.simulate( "keydown", { keyCode: $.ui.keyCode.HOME } );
+       equals( $("#log").html(), "0,keydown,", "Keydown HOME");
+
+       log("keydown",true);
+       element.simulate( "keydown", { keyCode: $.ui.keyCode.ESCAPE } );
+       equals( $("#log").html(), "keydown,", "Keydown ESCAPE (no effect)");
+
+       log("keydown",true);
+       element.simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } );
+       equals( $("#log").html(), "Aberdeen,keydown,", "Keydown ENTER");
+});
+
+asyncTest("handle keyboard navigation on menu without scroll and with submenus", function() {
+       expect(14);
+       var element = $('#menu2').menu({
+               select: function(event, ui) {
+                       log($(ui.item[0]).text());
+               },
+               focus: function( event, ui ) {
+                       log($(event.target).find(".ui-state-focus").parent().index());
+               }
+       });
+
+       log("keydown",true);
+       element.simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } );
+       element.simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } );
+       equals( $("#log").html(), "1,0,keydown,", "Keydown DOWN");
+
+       log("keydown",true);
+       element.simulate( "keydown", { keyCode: $.ui.keyCode.UP } );
+       equals( $("#log").html(), "0,keydown,", "Keydown UP");
+
+       log("keydown",true);
+       element.simulate( "keydown", { keyCode: $.ui.keyCode.LEFT } );
+       equals( $("#log").html(), "keydown,", "Keydown LEFT (no effect)");
+
+       log("keydown",true);
+       element.simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } );
+       element.simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } );
+       element.simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } );
+       element.simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } );
+       element.simulate( "keydown", { keyCode: $.ui.keyCode.RIGHT } );
+
+       setTimeout( function() {
+               equals( $("#log").html(), "0,4,3,2,1,keydown,", "Keydown RIGHT (open submenu)");
+       }, 50);
+
+       setTimeout( function() {
+               log("keydown",true);
+               element.simulate( "keydown", { keyCode: $.ui.keyCode.LEFT } );
+               equals( $("#log").html(), "4,keydown,", "Keydown LEFT (close submenu)");
+
+               //re-open submenu
+               element.simulate( "keydown", { keyCode: $.ui.keyCode.RIGHT } );
+
+               setTimeout( function() {
+                       log("keydown",true);
+                       element.simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_DOWN } );
+                       equals( $("#log").html(), "2,keydown,", "Keydown PAGE_DOWN");
+
+                       log("keydown",true);
+                       element.simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_DOWN } );
+                       equals( $("#log").html(), "keydown,", "Keydown PAGE_DOWN (no effect)");
+
+                       log("keydown",true);
+                       element.simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_UP } );
+                       equals( $("#log").html(), "0,keydown,", "Keydown PAGE_UP");
+
+                       log("keydown",true);
+                       element.simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_UP } );
+                       equals( $("#log").html(), "keydown,", "Keydown PAGE_UP (no effect)");
+
+                       log("keydown",true);
+                       element.simulate( "keydown", { keyCode: $.ui.keyCode.END } );
+                       equals( $("#log").html(), "2,keydown,", "Keydown END");
+
+                       log("keydown",true);
+                       element.simulate( "keydown", { keyCode: $.ui.keyCode.HOME } );
+                       equals( $("#log").html(), "0,keydown,", "Keydown HOME");
+
+                       log("keydown",true);
+                       element.simulate( "keydown", { keyCode: $.ui.keyCode.ESCAPE } );
+                       equals( $("#log").html(), "4,keydown,", "Keydown ESCAPE (close submenu)");
+
+                       log("keydown",true);
+                       element.simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } );
+
+                       setTimeout( function() {
+                               equals( $("#log").html(), "0,keydown,", "Keydown ENTER (open submenu)");
+
+                               log("keydown",true);
+                               element.simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } );
+                               equals( $("#log").html(), "Ada,keydown,", "Keydown ENTER (select item)");
+
+                               start();
+                       }, 200);
+               }, 150);
+       }, 100);
+
+});
+
+test("handle keyboard navigation on menu with scroll and without submenus", function() {
+       expect(14);
+       var element = $('#menu3').menu({
+               select: function(event, ui) {
+                       log($(ui.item[0]).text());
+               },
+               focus: function( event, ui ) {
+                       log($(event.target).find(".ui-state-focus").parent().index());
+               }
+       });
+
+       log("keydown",true);
+       element.simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } );
+       element.simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } );
+       equals( $("#log").html(), "1,0,keydown,", "Keydown DOWN");
+
+       log("keydown",true);
+       element.simulate( "keydown", { keyCode: $.ui.keyCode.UP } );
+       equals( $("#log").html(), "0,keydown,", "Keydown UP");
+
+       log("keydown",true);
+       element.simulate( "keydown", { keyCode: $.ui.keyCode.LEFT } );
+       equals( $("#log").html(), "keydown,", "Keydown LEFT (no effect)");
+
+       log("keydown",true);
+       element.simulate( "keydown", { keyCode: $.ui.keyCode.RIGHT } );
+       equals( $("#log").html(), "keydown,", "Keydown RIGHT (no effect)");
+
+       log("keydown",true);
+       element.simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_DOWN } );
+       equals( $("#log").html(), "10,keydown,", "Keydown PAGE_DOWN");
+
+       log("keydown",true);
+       element.simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_DOWN } );
+       equals( $("#log").html(), "20,keydown,", "Keydown PAGE_DOWN");
+
+       log("keydown",true);
+       element.simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_UP } );
+       equals( $("#log").html(), "10,keydown,", "Keydown PAGE_UP");
+
+       log("keydown",true);
+       element.simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_UP } );
+       equals( $("#log").html(), "0,keydown,", "Keydown PAGE_UP");
+
+       log("keydown",true);
+       element.simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_UP } );
+       equals( $("#log").html(), "keydown,", "Keydown PAGE_UP (no effect)");
+
+       log("keydown",true);
+       element.simulate( "keydown", { keyCode: $.ui.keyCode.END } );
+       equals( $("#log").html(), "37,keydown,", "Keydown END");
+
+       log("keydown",true);
+       element.simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_DOWN } );
+       equals( $("#log").html(), "keydown,", "Keydown PAGE_DOWN (no effect)");
+
+       log("keydown",true);
+       element.simulate( "keydown", { keyCode: $.ui.keyCode.HOME } );
+       equals( $("#log").html(), "0,keydown,", "Keydown HOME");
+
+       log("keydown",true);
+       element.simulate( "keydown", { keyCode: $.ui.keyCode.ESCAPE } );
+       equals( $("#log").html(), "keydown,", "Keydown ESCAPE (no effect)");
+
+       log("keydown",true);
+       element.simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } );
+       equals( $("#log").html(), "Aberdeen,keydown,", "Keydown ENTER");
+});
+
+asyncTest("handle keyboard navigation on menu with scroll and with submenus", function() {
+       expect(14);
+       var element = $('#menu4').menu({
+               select: function(event, ui) {
+                       log($(ui.item[0]).text());
+               },
+               focus: function( event, ui ) {
+                       log($(event.target).find(".ui-state-focus").parent().index());
+               }
+       });
+
+       log("keydown",true);
+       element.simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } );
+       element.simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } );
+       equals( $("#log").html(), "1,0,keydown,", "Keydown DOWN");
+
+       log("keydown",true);
+       element.simulate( "keydown", { keyCode: $.ui.keyCode.UP } );
+       equals( $("#log").html(), "0,keydown,", "Keydown UP");
+
+       log("keydown",true);
+       element.simulate( "keydown", { keyCode: $.ui.keyCode.LEFT } );
+       equals( $("#log").html(), "keydown,", "Keydown LEFT (no effect)");
+
+       log("keydown",true);
+       element.simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } );
+       element.simulate( "keydown", { keyCode: $.ui.keyCode.RIGHT } );
+
+       setTimeout( function() {
+               equals( $("#log").html(), "0,1,keydown,", "Keydown RIGHT (open submenu)");
+       }, 50);
+
+       setTimeout( function() {
+               log("keydown",true);
+               element.simulate( "keydown", { keyCode: $.ui.keyCode.LEFT } );
+               equals( $("#log").html(), "1,keydown,", "Keydown LEFT (close submenu)");
+
+               //re-open submenu
+               element.simulate( "keydown", { keyCode: $.ui.keyCode.RIGHT } );
+
+               setTimeout( function() {
+                       log("keydown",true);
+                       element.simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_DOWN } );
+                       equals( $("#log").html(), "10,keydown,", "Keydown PAGE_DOWN");
+
+                       log("keydown",true);
+                       element.simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_DOWN } );
+                       equals( $("#log").html(), "20,keydown,", "Keydown PAGE_DOWN");
+
+                       log("keydown",true);
+                       element.simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_UP } );
+                       equals( $("#log").html(), "10,keydown,", "Keydown PAGE_UP");
+
+                       log("keydown",true);
+                       element.simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_UP } );
+                       equals( $("#log").html(), "0,keydown,", "Keydown PAGE_UP");
+
+                       log("keydown",true);
+                       element.simulate( "keydown", { keyCode: $.ui.keyCode.END } );
+                       equals( $("#log").html(), "27,keydown,", "Keydown END");
+
+                       log("keydown",true);
+                       element.simulate( "keydown", { keyCode: $.ui.keyCode.HOME } );
+                       equals( $("#log").html(), "0,keydown,", "Keydown HOME");
+
+                       log("keydown",true);
+                       element.simulate( "keydown", { keyCode: $.ui.keyCode.ESCAPE } );
+                       equals( $("#log").html(), "1,keydown,", "Keydown ESCAPE (close submenu)");
+
+                       log("keydown",true);
+                       element.simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } );
+
+                       setTimeout( function() {
+                               equals( $("#log").html(), "0,keydown,", "Keydown ENTER (open submenu)");
+
+                               log("keydown",true);
+                               element.simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } );
+                               equals( $("#log").html(), "Aberdeen,keydown,", "Keydown ENTER (select item)");
+
+                               start();
+                       }, 200);
+               }, 150);
+       }, 100);
+
+});
+
 })(jQuery);
index 4717946f10b8ea51659035de73eceb6248d9cc44..66f874290edc84918edf72281a4df9271038f919 100644 (file)
@@ -89,6 +89,16 @@ $.widget( "ui.menu", {
                                event.preventDefault();
                                event.stopImmediatePropagation();
                                break;
+                       case $.ui.keyCode.HOME:
+                               self._move( "first", "first", event );
+                               event.preventDefault();
+                               event.stopImmediatePropagation();
+                               break;
+                       case $.ui.keyCode.END:
+                               self._move( "last", "last", event );
+                               event.preventDefault();
+                               event.stopImmediatePropagation();
+                               break;
                        case $.ui.keyCode.UP:
                                self.previous( event );
                                event.preventDefault();
@@ -252,17 +262,17 @@ $.widget( "ui.menu", {
                this.blur( event );
 
                if ( this._hasScroll() ) {
-                       var borderTop = parseFloat( $.curCSS( this.element[0], "borderTopWidth", true ) ) || 0,
-                               paddingTop = parseFloat( $.curCSS( this.element[0], "paddingTop", true ) ) || 0,
-                               offset = item.offset().top - this.element.offset().top - borderTop - paddingTop,
-                               scroll = this.element.scrollTop(),
-                               elementHeight = this.element.height(),
+                       var borderTop = parseFloat( $.curCSS( this.activeMenu[0], "borderTopWidth", true ) ) || 0,
+                               paddingTop = parseFloat( $.curCSS( this.activeMenu[0], "paddingTop", true ) ) || 0,
+                               offset = item.offset().top - this.activeMenu.offset().top - borderTop - paddingTop,
+                               scroll = this.activeMenu.scrollTop(),
+                               elementHeight = this.activeMenu.height(),
                                itemHeight = item.height();
 
                        if ( offset < 0 ) {
-                               this.element.scrollTop( scroll + offset );
+                               this.activeMenu.scrollTop( scroll + offset );
                        } else if ( offset + itemHeight > elementHeight ) {
-                               this.element.scrollTop( scroll + offset - elementHeight + itemHeight );
+                               this.activeMenu.scrollTop( scroll + offset - elementHeight + itemHeight );
                        }
                }
 
@@ -391,11 +401,11 @@ $.widget( "ui.menu", {
        },
 
        next: function(event) {
-               this._move( "next", ".ui-menu-item", "first", event );
+               this._move( "next", "first", event );
        },
 
        previous: function(event) {
-               this._move( "prev", ".ui-menu-item", "last", event );
+               this._move( "prev", "last", event );
        },
 
        first: function() {
@@ -406,25 +416,36 @@ $.widget( "ui.menu", {
                return this.active && !this.active.nextAll( ".ui-menu-item" ).length;
        },
 
-       _move: function( direction, edge, filter, event ) {
+       _move: function( direction, filter, event ) {
                if ( !this.active ) {
-                       this.focus( event, this.activeMenu.children( edge )[ filter ]() );
+                       this.focus( event, this.activeMenu.children( ".ui-menu-item" )[ filter ]() );
                        return;
                }
-               var next = this.active[ direction + "All" ]( ".ui-menu-item" ).eq( 0 );
+
+               var next;
+               if ( direction === "first" || direction === "last" ) {
+                       next = this.active[ direction === "first" ? "prevAll" : "nextAll" ]( ".ui-menu-item" ).eq( -1 );
+               } else {
+                       next = this.active[ direction + "All" ]( ".ui-menu-item" ).eq( 0 );
+               }
+
                if ( next.length ) {
                        this.focus( event, next );
                } else {
-                       this.focus( event, this.activeMenu.children( edge )[ filter ]() );
+                       this.focus( event, this.activeMenu.children( ".ui-menu-item" )[ filter ]() );
                }
        },
 
        nextPage: function( event ) {
                if ( this._hasScroll() ) {
-                       if ( !this.active || this.last() ) {
+                       if ( !this.active ) {
                                this.focus( event, this.activeMenu.children( ".ui-menu-item" ).first() );
                                return;
                        }
+                       if ( this.last() ) {
+                               return;
+                       }
+
                        var base = this.active.offset().top,
                                height = this.element.height(),
                                result;
@@ -436,14 +457,17 @@ $.widget( "ui.menu", {
                        this.focus( event, result );
                } else {
                        this.focus( event, this.activeMenu.children( ".ui-menu-item" )
-                               [ !this.active || this.last() ? "first" : "last" ]() );
+                               [ !this.active ? "first" : "last" ]() );
                }
        },
 
        previousPage: function( event ) {
                if ( this._hasScroll() ) {
-                       if ( !this.active || this.first() ) {
-                               this.focus( event, this.activeMenu.children( ".ui-menu-item" ).last() );
+                       if ( !this.active ) {
+                               this.focus( event, this.activeMenu.children( ".ui-menu-item" ).first() );
+                               return;
+                       }
+                       if ( this.first() ) {
                                return;
                        }
 
@@ -457,8 +481,7 @@ $.widget( "ui.menu", {
 
                        this.focus( event, result );
                } else {
-                       this.focus( event, this.activeMenu.children( ".ui-menu-item" )
-                               [ !this.active || this.first() ? ":last" : ":first" ]() );
+                       this.focus( event, this.activeMenu.children( ".ui-menu-item" ).first() );
                }
        },