Skip to content

Commit ae0c4e4

Browse files
committed
Merge remote branch 'kborchers/menu_autoCollapse'
2 parents bf26bf1 + 94317d7 commit ae0c4e4

File tree

2 files changed

+48
-16
lines changed

2 files changed

+48
-16
lines changed

tests/unit/menu/menu_events.js

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,25 @@ test( "handle blur: click", function() {
4141
$("#remove").remove();
4242
});
4343

44+
asyncTest( "handle submenu auto collapse: mouseleave", function() {
45+
expect( 4 );
46+
var $menu = $( "#menu2" ).menu();
47+
48+
$menu.find( "li:nth-child(7)" ).trigger( "mouseover" );
49+
setTimeout(function() {
50+
equal( $menu.find( "ul[aria-expanded='true']" ).length, 1, "first submenu expanded" );
51+
$menu.find( "li:nth-child(7) li:first" ).trigger( "mouseover" );
52+
setTimeout(function() {
53+
equal( $menu.find( "ul[aria-expanded='true']" ).length, 2, "second submenu expanded" );
54+
$menu.find( "ul[aria-expanded='true']:first" ).trigger( "mouseleave" );
55+
equal( $menu.find( "ul[aria-expanded='true']" ).length, 1, "second submenu collapsed" );
56+
$menu.trigger( "mouseleave" );
57+
equal( $menu.find( "ul[aria-expanded='true']" ).length, 0, "first submenu collapsed" );
58+
start();
59+
}, 400);
60+
}, 200);
61+
});
62+
4463
test("handle keyboard navigation on menu without scroll and without submenus", function() {
4564
expect(12);
4665
var element = $('#menu1').menu({

ui/jquery.ui.menu.js

Lines changed: 29 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,8 @@ $.widget( "ui.menu", {
6161
target.siblings().children( ".ui-state-active" ).removeClass( "ui-state-active" );
6262
this.focus( event, target );
6363
},
64+
"mouseleave": "_mouseleave",
65+
"mouseleave .ui-menu": "_mouseleave",
6466
"mouseout .ui-menu-item": "blur",
6567
"focus": function( event ) {
6668
this.focus( event, $( event.target ).children( ".ui-menu-item:first" ) );
@@ -341,21 +343,30 @@ $.widget( "ui.menu", {
341343
},
342344

343345
collapseAll: function( event ) {
344-
this.element
345-
.find( "ul" )
346-
.hide()
347-
.attr( "aria-hidden", "true" )
348-
.attr( "aria-expanded", "false" )
349-
.end()
350-
.find( "a.ui-state-active" )
351-
.removeClass( "ui-state-active" );
346+
var currentMenu = false;
347+
if ( event ) {
348+
var target = $( event.target );
349+
if ( target.is( "ui.menu" ) ) {
350+
currentMenu = target;
351+
} else if ( target.closest( ".ui-menu" ).length ) {
352+
currentMenu = target.closest( ".ui-menu" );
353+
}
354+
}
352355

353-
this.blur( event );
354-
this.activeMenu = this.element;
356+
this._close( currentMenu );
357+
358+
if( !currentMenu ) {
359+
this.blur( event );
360+
this.activeMenu = this.element;
361+
}
355362
},
356363

357-
_close: function() {
358-
this.active.parent()
364+
_close: function( startMenu ) {
365+
if( !startMenu ) {
366+
startMenu = this.active ? this.active.parent() : this.element;
367+
}
368+
369+
startMenu
359370
.find( "ul" )
360371
.hide()
361372
.attr( "aria-hidden", "true" )
@@ -368,10 +379,7 @@ $.widget( "ui.menu", {
368379
collapse: function( event ) {
369380
var newItem = this.active && this.active.parents("li:not(.ui-menubar-item)").first();
370381
if ( newItem && newItem.length ) {
371-
this.active.parent()
372-
.attr("aria-hidden", "true")
373-
.attr("aria-expanded", "false")
374-
.hide();
382+
this._close();
375383
this.focus( event, newItem );
376384
return true;
377385
}
@@ -480,6 +488,11 @@ $.widget( "ui.menu", {
480488
return this.element.height() < this.element.prop( "scrollHeight" );
481489
},
482490

491+
_mouseleave: function( event ) {
492+
this.collapseAll( event );
493+
this.blur();
494+
},
495+
483496
select: function( event ) {
484497
// save active reference before collapseAll triggers blur
485498
var ui = {

0 commit comments

Comments
 (0)