diff options
-rw-r--r-- | tests/unit/menu/menu_events.js | 19 | ||||
-rw-r--r-- | ui/jquery.ui.menu.js | 45 |
2 files changed, 48 insertions, 16 deletions
diff --git a/tests/unit/menu/menu_events.js b/tests/unit/menu/menu_events.js index 9ea54faf0..563ed7c2d 100644 --- a/tests/unit/menu/menu_events.js +++ b/tests/unit/menu/menu_events.js @@ -41,6 +41,25 @@ test( "handle blur: click", function() { $("#remove").remove(); }); +asyncTest( "handle submenu auto collapse: mouseleave", function() { + expect( 4 ); + var $menu = $( "#menu2" ).menu(); + + $menu.find( "li:nth-child(7)" ).trigger( "mouseover" ); + setTimeout(function() { + equal( $menu.find( "ul[aria-expanded='true']" ).length, 1, "first submenu expanded" ); + $menu.find( "li:nth-child(7) li:first" ).trigger( "mouseover" ); + setTimeout(function() { + equal( $menu.find( "ul[aria-expanded='true']" ).length, 2, "second submenu expanded" ); + $menu.find( "ul[aria-expanded='true']:first" ).trigger( "mouseleave" ); + equal( $menu.find( "ul[aria-expanded='true']" ).length, 1, "second submenu collapsed" ); + $menu.trigger( "mouseleave" ); + equal( $menu.find( "ul[aria-expanded='true']" ).length, 0, "first submenu collapsed" ); + start(); + }, 400); + }, 200); +}); + test("handle keyboard navigation on menu without scroll and without submenus", function() { expect(12); var element = $('#menu1').menu({ diff --git a/ui/jquery.ui.menu.js b/ui/jquery.ui.menu.js index 050112db5..bfe35efb5 100644 --- a/ui/jquery.ui.menu.js +++ b/ui/jquery.ui.menu.js @@ -61,6 +61,8 @@ $.widget( "ui.menu", { target.siblings().children( ".ui-state-active" ).removeClass( "ui-state-active" ); this.focus( event, target ); }, + "mouseleave": "_mouseleave", + "mouseleave .ui-menu": "_mouseleave", "mouseout .ui-menu-item": "blur", "focus": function( event ) { this.focus( event, $( event.target ).children( ".ui-menu-item:first" ) ); @@ -341,21 +343,30 @@ $.widget( "ui.menu", { }, collapseAll: function( event ) { - this.element - .find( "ul" ) - .hide() - .attr( "aria-hidden", "true" ) - .attr( "aria-expanded", "false" ) - .end() - .find( "a.ui-state-active" ) - .removeClass( "ui-state-active" ); + 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" ); + } + } - this.blur( event ); - this.activeMenu = this.element; + this._close( currentMenu ); + + if( !currentMenu ) { + this.blur( event ); + this.activeMenu = this.element; + } }, - _close: function() { - this.active.parent() + _close: function( startMenu ) { + if( !startMenu ) { + startMenu = this.active ? this.active.parent() : this.element; + } + + startMenu .find( "ul" ) .hide() .attr( "aria-hidden", "true" ) @@ -368,10 +379,7 @@ $.widget( "ui.menu", { collapse: function( event ) { var newItem = this.active && this.active.parents("li:not(.ui-menubar-item)").first(); if ( newItem && newItem.length ) { - this.active.parent() - .attr("aria-hidden", "true") - .attr("aria-expanded", "false") - .hide(); + this._close(); this.focus( event, newItem ); return true; } @@ -480,6 +488,11 @@ $.widget( "ui.menu", { 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 = { |