Skip to content

Commit c770605

Browse files
committed
Menu: Ignore bubbled mouseenter events on parent items
Test uses QUnit 2.x API - inconsistent with the other tests, but also a good reference. Fixes #11641 Closes gh-1535
1 parent 2d0f05b commit c770605

File tree

2 files changed

+52
-1
lines changed

2 files changed

+52
-1
lines changed

tests/unit/menu/menu_events.js

+42
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,48 @@ asyncTest( "handle focus of menu with active item", function() {
111111
});
112112
});
113113

114+
test( "handle mouseenter on nested menu item", function( assert ) {
115+
assert.expect( 8 );
116+
$.ui.menu.prototype.delay = 1;
117+
var activeItem,
118+
done = assert.async(),
119+
element = $( "#menu2" ).menu();
120+
121+
element
122+
.menu( "previous" )
123+
.menu( "expand" );
124+
125+
function checkSubmenus() {
126+
equal( element.find( "ul[aria-expanded='true']" ).length, 2, "both submenus expanded" );
127+
}
128+
function menumouseenter1() {
129+
element.menu( "expand" );
130+
setTimeout( menumouseenter2, 25 );
131+
}
132+
function menumouseenter2() {
133+
checkSubmenus();
134+
activeItem = $( "#" + element.attr( "aria-activedescendant" ) );
135+
assert.hasClasses( activeItem, "ui-state-active" );
136+
activeItem.trigger( "mouseleave" );
137+
setTimeout( menumouseenter3, 25 );
138+
}
139+
function menumouseenter3() {
140+
checkSubmenus();
141+
assert.lacksClasses( activeItem, "ui-state-active" );
142+
activeItem.trigger( "mouseenter" );
143+
setTimeout( menumouseenter4, 25 );
144+
}
145+
function menumouseenter4() {
146+
checkSubmenus();
147+
activeItem.parents( ".ui-menu-item" ).each( function( index, item ) {
148+
assert.hasClasses( $( item ).children( ".ui-menu-item-wrapper" ), "ui-state-active" );
149+
} );
150+
$.ui.menu.prototype.delay = 300;
151+
done();
152+
}
153+
setTimeout( menumouseenter1, 25 );
154+
} );
155+
114156
asyncTest( "handle submenu auto collapse: mouseleave, default markup", function() {
115157
expect( 4 );
116158
$.ui.menu.prototype.delay = 1;

ui/menu.js

+10-1
Original file line numberDiff line numberDiff line change
@@ -108,13 +108,22 @@ return $.widget( "ui.menu", {
108108
}
109109
},
110110
"mouseenter .ui-menu-item": function( event ) {
111+
111112
// Ignore mouse events while typeahead is active, see #10458.
112113
// Prevents focusing the wrong item when typeahead causes a scroll while the mouse
113114
// is over an item in the menu
114115
if ( this.previousFilter ) {
115116
return;
116117
}
117-
var target = $( event.currentTarget );
118+
119+
var actualTarget = $( event.target ).closest( ".ui-menu-item" ),
120+
target = $( event.currentTarget );
121+
122+
// Ignore bubbled events on parent items, see #11641
123+
if ( actualTarget[ 0 ] !== target[ 0 ] ) {
124+
return;
125+
}
126+
118127
// Remove ui-state-active class from siblings of the newly focused menu item
119128
// to avoid a jump caused by adjacent elements both having a class with a border
120129
this._removeClass( target.siblings().children( ".ui-state-active" ),

0 commit comments

Comments
 (0)