Skip to content

Commit e162fdd

Browse files
committed
Menu: Don't move focus from the active item on click. Fixes #8552 - selected value overwritten/not correctly set.
1 parent 6abb107 commit e162fdd

File tree

2 files changed

+32
-21
lines changed

2 files changed

+32
-21
lines changed

tests/unit/menu/menu_events.js

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -57,13 +57,15 @@ asyncTest( "handle blur", function() {
5757
});
5858

5959
click( element, "1" );
60-
setTimeout( function() {
60+
setTimeout(function() {
6161
element.blur();
62-
start();
63-
}, 350 );
62+
setTimeout(function() {
63+
start();
64+
}, 350 );
65+
});
6466
});
6567

66-
asyncTest( "handle blur on click", function() {
68+
asyncTest( "handle blur via click outside", function() {
6769
expect( 1 );
6870
var blurHandled = false,
6971
element = $( "#menu1" ).menu({
@@ -77,10 +79,12 @@ asyncTest( "handle blur on click", function() {
7779
});
7880

7981
click( element, "1" );
80-
setTimeout( function() {
82+
setTimeout(function() {
8183
$( "<a>", { id: "remove"} ).appendTo( "body" ).trigger( "click" );
82-
start();
83-
}, 350 );
84+
setTimeout(function() {
85+
start();
86+
}, 350 );
87+
});
8488
});
8589

8690
test( "handle focus of menu with active item", function() {

ui/jquery.ui.menu.js

Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -72,17 +72,23 @@ $.widget( "ui.menu", {
7272
event.preventDefault();
7373
},
7474
"click .ui-menu-item:has(a)": function( event ) {
75-
var target = $( event.target );
76-
if ( !mouseHandled && target.closest( ".ui-menu-item" ).not( ".ui-state-disabled" ).length ) {
75+
var target = $( event.target ).closest( ".ui-menu-item" );
76+
if ( !mouseHandled && target.not( ".ui-state-disabled" ).length ) {
7777
mouseHandled = true;
7878

7979
this.select( event );
8080
// Open submenu on click
81-
if ( this.element.has( ".ui-menu" ).length ) {
81+
if ( target.has( ".ui-menu" ).length ) {
8282
this.expand( event );
83-
} else if ( !this.element.is(":focus") ) {
83+
} else if ( !this.element.is( ":focus" ) ) {
8484
// Redirect focus to the menu
85-
this.element.focus();
85+
this.element.trigger( "focus", [ true ] );
86+
87+
// If the active item is on the top level, let it stay active.
88+
// Otherwise, blur the active item since it is no longer visible.
89+
if ( this.active && this.active.parents( ".ui-menu" ).length === 1 ) {
90+
clearTimeout( this.timer );
91+
}
8692
}
8793
}
8894
},
@@ -95,12 +101,14 @@ $.widget( "ui.menu", {
95101
},
96102
mouseleave: "collapseAll",
97103
"mouseleave .ui-menu": "collapseAll",
98-
focus: function( event ) {
104+
focus: function( event, keepActiveItem ) {
99105
// If there's already an active item, keep it active
100106
// If not, activate the first item
101107
var item = this.active || this.element.children( ".ui-menu-item" ).eq( 0 );
102108

103-
this.focus( event, item );
109+
if ( !keepActiveItem ) {
110+
this.focus( event, item );
111+
}
104112
},
105113
blur: function( event ) {
106114
this._delay(function() {
@@ -195,7 +203,7 @@ $.widget( "ui.menu", {
195203
this.collapse( event );
196204
break;
197205
case $.ui.keyCode.RIGHT:
198-
if ( !this.active.is( ".ui-state-disabled" ) ) {
206+
if ( this.active && !this.active.is( ".ui-state-disabled" ) ) {
199207
this.expand( event );
200208
}
201209
break;
@@ -587,12 +595,11 @@ $.widget( "ui.menu", {
587595
},
588596

589597
select: function( event ) {
590-
// Save active reference before collapseAll triggers blur
591-
var ui = {
592-
// Selecting a menu item removes the active item causing multiple clicks to be missing an item
593-
item: this.active || $( event.target ).closest( ".ui-menu-item" )
594-
};
595-
if ( !ui.item.has( ".ui-menu" ).length ) {
598+
// TODO: It should never be possible to not have an active item at this
599+
// point, but the tests don't trigger mouseenter before click.
600+
this.active = this.active || $( event.target ).closest( ".ui-menu-item" );
601+
var ui = { item: this.active };
602+
if ( !this.active.has( ".ui-menu" ).length ) {
596603
this.collapseAll( event, true );
597604
}
598605
this._trigger( "select", event, ui );

0 commit comments

Comments
 (0)