});
asyncTest( "handle custom menu item submenu auto collapse: mouseleave", function() {
- expect( 4 );
+ expect( 5 );
var $menu = $( "#menu5" ).menu( { items: "div" } );
$menu.children( ":nth-child(7)" ).trigger( "mouseover" );
equal( $menu.find( "div[aria-expanded='true']" ).length, 2, "second submenu expanded" );
$menu.find( "div[aria-expanded='true']:first" ).trigger( "mouseleave" );
equal( $menu.find( "div[aria-expanded='true']" ).length, 1, "second submenu collapsed" );
+
+ $menu.simulate( "keydown", { keyCode: $.ui.keyCode.DOWN });
+ ok( $menu.find( ".ui-state-active" ).is( "#menu5 :nth-child(7) a" ),
+ "down keypress selected an item from the first submenu" );
+
$menu.trigger( "mouseleave" );
equal( $menu.find( "div[aria-expanded='true']" ).length, 0, "first submenu collapsed" );
start();
}, 200);
});
+
test("handle keyboard navigation on menu without scroll and without submenus", function() {
expect(12);
var element = $('#menu1').menu({
target.siblings().children( ".ui-state-active" ).removeClass( "ui-state-active" );
this.focus( event, target );
},
- "mouseleave": "_mouseleave",
- "mouseleave .ui-menu": "_mouseleave",
+ "mouseleave": "collapseAll",
+ "mouseleave .ui-menu": "collapseAll",
"mouseout .ui-menu-item": "blur",
"focus": function( event ) {
this.focus( event, $( event.target ).children( ".ui-menu-item:first" ) );
},
- "blur": "collapseAll"
+ blur: function( event ) {
+ this._delay( function() {
+ if ( ! $.contains( this.element[0], document.activeElement ) ) {
+ this.collapseAll( event );
+ }
+ }, 0);
+ }
});
this.refresh();
.position( position );
},
- collapseAll: function( event ) {
- var currentMenu = false;
- if ( event ) {
- var target = $( event.target );
- if ( target.is( "ui.menu" ) ) {
- currentMenu = target;
- } else if ( target.closest( ".ui-menu" ).length ) {
- currentMenu = target.closest( ".ui-menu" );
- }
+ collapseAll: function( event, all ) {
+
+ // if we were passed an event, look for the submenu that contains the event
+ var currentMenu = all ? this.element :
+ $( event && event.target ).closest( this.element.find( ".ui-menu" ) );
+
+ // if we found no valid submenu ancestor, use the main menu to close all sub menus anyway
+ if ( !currentMenu.length ) {
+ currentMenu = this.element;
}
this._close( currentMenu );
- if ( !currentMenu ) {
- this.blur( event );
- this.activeMenu = this.element;
- }
+ this.blur( event );
+ this.activeMenu = currentMenu;
},
+ // With no arguments, closes the currently active menu - if nothing is active
+ // it closes all menus. If passed an argument, it will search for menus BELOW
_close: function( startMenu ) {
if ( !startMenu ) {
startMenu = this.active ? this.active.parent() : this.element;
return this.element.height() < this.element.prop( "scrollHeight" );
},
- _mouseleave: function( event ) {
- this.collapseAll( event );
- this.blur();
- },
-
select: function( event ) {
+
// save active reference before collapseAll triggers blur
var ui = {
item: this.active
};
- this.collapseAll( event );
+ this.collapseAll( event, true );
this._trigger( "select", event, ui );
}
});