Menu: Handle mouse movement mixed with keyboard navigation

Fixes #9357
Closes gh-1805
This commit is contained in:
Scott González 2017-04-18 13:57:23 -04:00
parent a3e953b495
commit 7d992ae29d

View File

@ -78,6 +78,8 @@ return $.widget( "ui.menu", {
// them (focus should always stay on UL during navigation). // them (focus should always stay on UL during navigation).
"mousedown .ui-menu-item": function( event ) { "mousedown .ui-menu-item": function( event ) {
event.preventDefault(); event.preventDefault();
this._activateItem( event );
}, },
"click .ui-menu-item": function( event ) { "click .ui-menu-item": function( event ) {
var target = $( event.target ); var target = $( event.target );
@ -107,29 +109,8 @@ return $.widget( "ui.menu", {
} }
} }
}, },
"mouseenter .ui-menu-item": function( event ) { "mouseenter .ui-menu-item": "_activateItem",
"mousemove .ui-menu-item": "_activateItem",
// 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 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" ),
null, "ui-state-active" );
this.focus( event, target );
},
mouseleave: "collapseAll", mouseleave: "collapseAll",
"mouseleave .ui-menu": "collapseAll", "mouseleave .ui-menu": "collapseAll",
focus: function( event, keepActiveItem ) { focus: function( event, keepActiveItem ) {
@ -171,6 +152,35 @@ return $.widget( "ui.menu", {
} ); } );
}, },
_activateItem: 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 actualTarget = $( event.target ).closest( ".ui-menu-item" ),
target = $( event.currentTarget );
// Ignore bubbled events on parent items, see #11641
if ( actualTarget[ 0 ] !== target[ 0 ] ) {
return;
}
// If the item is already active, there's nothing to do
if ( target.is( ".ui-state-active" ) ) {
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" ),
null, "ui-state-active" );
this.focus( event, target );
},
_destroy: function() { _destroy: function() {
var items = this.element.find( ".ui-menu-item" ) var items = this.element.find( ".ui-menu-item" )
.removeAttr( "role aria-disabled" ), .removeAttr( "role aria-disabled" ),