Skip to content

Commit e3e5a9f

Browse files
SimenBscottgonzalez
authored andcommitted
Menu: Filter out non-items when typing
Fixes #10571 Closes gh-1329
1 parent b20387a commit e3e5a9f

File tree

3 files changed

+43
-13
lines changed

3 files changed

+43
-13
lines changed

tests/unit/menu/menu.html

+9
Original file line numberDiff line numberDiff line change
@@ -306,6 +306,15 @@
306306
<li>Amesville</li>
307307
</ul>
308308

309+
<ul id="menu8">
310+
<li class="foo">Aberdeen</li>
311+
<li class="foo ui-state-disabled">Ada</li>
312+
<li class="foo">Adamsville</li>
313+
<li class="foo">Addyston</li>
314+
<li class="foo">-</li>
315+
<li class="foo">-Saarland</li>
316+
</ul>
317+
309318
</div>
310319
</body>
311320
</html>

tests/unit/menu/menu_events.js

+17
Original file line numberDiff line numberDiff line change
@@ -644,4 +644,21 @@ test( "#9469: Stopping propagation in a select event should not suppress subsequ
644644
equal( logOutput(), "1,2", "Both select events were not triggered." );
645645
});
646646

647+
asyncTest( "#10571: When typing in a menu, only menu-items should be focused", function() {
648+
expect( 3 );
649+
650+
var element = $( "#menu8" ).menu({
651+
focus: function( event, ui ) {
652+
equal( ui.item.length, 1, "There should only be one match when filtering" );
653+
ok( ui.item.hasClass( "ui-menu-item" ), "element is .ui-menu-item" );
654+
equal( ui.item.text(), "-Saarland", "element has correct text" );
655+
}
656+
});
657+
658+
setTimeout(function() {
659+
element.menu( "widget" ).simulate( "keydown", { keyCode: "-".charCodeAt( 0 ) } );
660+
start();
661+
});
662+
});
663+
647664
})( jQuery );

ui/menu.js

+17-13
Original file line numberDiff line numberDiff line change
@@ -186,13 +186,9 @@ return $.widget( "ui.menu", {
186186
},
187187

188188
_keydown: function( event ) {
189-
var match, prev, character, skip, regex,
189+
var match, prev, character, skip,
190190
preventDefault = true;
191191

192-
function escape( value ) {
193-
return value.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" );
194-
}
195-
196192
switch ( event.keyCode ) {
197193
case $.ui.keyCode.PAGE_UP:
198194
this.previousPage( event );
@@ -241,10 +237,7 @@ return $.widget( "ui.menu", {
241237
character = prev + character;
242238
}
243239

244-
regex = new RegExp( "^" + escape( character ), "i" );
245-
match = this.activeMenu.find( this.options.items ).filter(function() {
246-
return regex.test( $( this ).text() );
247-
});
240+
match = this._filterMenuItems( character );
248241
match = skip && match.index( this.active.next() ) !== -1 ?
249242
this.active.nextAll( ".ui-menu-item" ) :
250243
match;
@@ -253,10 +246,7 @@ return $.widget( "ui.menu", {
253246
// to move down the menu to the first item that starts with that character
254247
if ( !match.length ) {
255248
character = String.fromCharCode( event.keyCode );
256-
regex = new RegExp( "^" + escape( character ), "i" );
257-
match = this.activeMenu.find( this.options.items ).filter(function() {
258-
return regex.test( $( this ).text() );
259-
});
249+
match = this._filterMenuItems( character );
260250
}
261251

262252
if ( match.length ) {
@@ -640,6 +630,20 @@ return $.widget( "ui.menu", {
640630
this.collapseAll( event, true );
641631
}
642632
this._trigger( "select", event, ui );
633+
},
634+
635+
_filterMenuItems: function(character) {
636+
var escapedCharacter = character.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" ),
637+
regex = new RegExp( "^" + escapedCharacter, "i" );
638+
639+
return this.activeMenu
640+
.find( this.options.items )
641+
642+
// Only match on items, not dividers or other content (#10571)
643+
.filter( ".ui-menu-item" )
644+
.filter(function() {
645+
return regex.test( $( this ).text() );
646+
});
643647
}
644648
});
645649

0 commit comments

Comments
 (0)