From c770605db05347edfa9c6224aebd42974092ed22 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Jo=CC=88rn=20Zaefferer?= Date: Wed, 8 Apr 2015 16:09:17 +0200 Subject: [PATCH] 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 --- tests/unit/menu/menu_events.js | 42 ++++++++++++++++++++++++++++++++++ ui/menu.js | 11 ++++++++- 2 files changed, 52 insertions(+), 1 deletion(-) diff --git a/tests/unit/menu/menu_events.js b/tests/unit/menu/menu_events.js index 4985e0677..bda2d6050 100644 --- a/tests/unit/menu/menu_events.js +++ b/tests/unit/menu/menu_events.js @@ -111,6 +111,48 @@ asyncTest( "handle focus of menu with active item", function() { }); }); +test( "handle mouseenter on nested menu item", function( assert ) { + assert.expect( 8 ); + $.ui.menu.prototype.delay = 1; + var activeItem, + done = assert.async(), + element = $( "#menu2" ).menu(); + + element + .menu( "previous" ) + .menu( "expand" ); + + function checkSubmenus() { + equal( element.find( "ul[aria-expanded='true']" ).length, 2, "both submenus expanded" ); + } + function menumouseenter1() { + element.menu( "expand" ); + setTimeout( menumouseenter2, 25 ); + } + function menumouseenter2() { + checkSubmenus(); + activeItem = $( "#" + element.attr( "aria-activedescendant" ) ); + assert.hasClasses( activeItem, "ui-state-active" ); + activeItem.trigger( "mouseleave" ); + setTimeout( menumouseenter3, 25 ); + } + function menumouseenter3() { + checkSubmenus(); + assert.lacksClasses( activeItem, "ui-state-active" ); + activeItem.trigger( "mouseenter" ); + setTimeout( menumouseenter4, 25 ); + } + function menumouseenter4() { + checkSubmenus(); + activeItem.parents( ".ui-menu-item" ).each( function( index, item ) { + assert.hasClasses( $( item ).children( ".ui-menu-item-wrapper" ), "ui-state-active" ); + } ); + $.ui.menu.prototype.delay = 300; + done(); + } + setTimeout( menumouseenter1, 25 ); +} ); + asyncTest( "handle submenu auto collapse: mouseleave, default markup", function() { expect( 4 ); $.ui.menu.prototype.delay = 1; diff --git a/ui/menu.js b/ui/menu.js index 3df6cb204..89281e4f0 100644 --- a/ui/menu.js +++ b/ui/menu.js @@ -108,13 +108,22 @@ return $.widget( "ui.menu", { } }, "mouseenter .ui-menu-item": function( event ) { + // Ignore mouse events while typeahead is active, see #10458. // Prevents focusing the wrong item when typeahead causes a scroll while the mouse // is over an item in the menu if ( this.previousFilter ) { return; } - var target = $( event.currentTarget ); + + var actualTarget = $( event.target ).closest( ".ui-menu-item" ), + target = $( event.currentTarget ); + + // Ignore bubbled events on parent items, see #11641 + if ( actualTarget[ 0 ] !== target[ 0 ] ) { + return; + } + // Remove ui-state-active class from siblings of the newly focused menu item // to avoid a jump caused by adjacent elements both having a class with a border this._removeClass( target.siblings().children( ".ui-state-active" ), -- 2.39.5