]> source.dussan.org Git - jquery-ui.git/commitdiff
Menu: Filter out non-items when typing
authorSimen Bekkhus <sbekkhus91@gmail.com>
Fri, 29 Aug 2014 12:18:47 +0000 (14:18 +0200)
committerScott González <scott.gonzalez@gmail.com>
Mon, 29 Sep 2014 18:36:46 +0000 (14:36 -0400)
Fixes #10571
Closes gh-1329

tests/unit/menu/menu.html
tests/unit/menu/menu_events.js
ui/menu.js

index 05fdcee11412fe623c9efa7f055f4d20186b65be..2aa286c69fbe061eedec96d99e9819ff802a03b7 100644 (file)
        <li>Amesville</li>
 </ul>
 
+<ul id="menu8">
+       <li class="foo">Aberdeen</li>
+       <li class="foo ui-state-disabled">Ada</li>
+       <li class="foo">Adamsville</li>
+       <li class="foo">Addyston</li>
+       <li class="foo">-</li>
+       <li class="foo">-Saarland</li>
+</ul>
+
 </div>
 </body>
 </html>
index 8fa77ab950fbf244233d9311e74afe6667271598..0a02cc01b5f172f790c1b9b65f850279150a3dcf 100644 (file)
@@ -644,4 +644,21 @@ test( "#9469: Stopping propagation in a select event should not suppress subsequ
        equal( logOutput(), "1,2", "Both select events were not triggered." );
 });
 
+asyncTest( "#10571: When typing in a menu, only menu-items should be focused", function() {
+       expect( 3 );
+
+       var element = $( "#menu8" ).menu({
+               focus: function( event, ui ) {
+                       equal( ui.item.length, 1, "There should only be one match when filtering" );
+                       ok( ui.item.hasClass( "ui-menu-item" ), "element is .ui-menu-item" );
+                       equal( ui.item.text(), "-Saarland", "element has correct text" );
+               }
+       });
+
+       setTimeout(function() {
+               element.menu( "widget" ).simulate( "keydown", { keyCode: "-".charCodeAt( 0 ) } );
+               start();
+       });
+});
+
 })( jQuery );
index 4dfa0d37a6e70b1360a56fdeb0eb860662a5283d..9664e37efbec18a41c5c5f243580db6450671700 100644 (file)
@@ -186,13 +186,9 @@ return $.widget( "ui.menu", {
        },
 
        _keydown: function( event ) {
-               var match, prev, character, skip, regex,
+               var match, prev, character, skip,
                        preventDefault = true;
 
-               function escape( value ) {
-                       return value.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" );
-               }
-
                switch ( event.keyCode ) {
                case $.ui.keyCode.PAGE_UP:
                        this.previousPage( event );
@@ -241,10 +237,7 @@ return $.widget( "ui.menu", {
                                character = prev + character;
                        }
 
-                       regex = new RegExp( "^" + escape( character ), "i" );
-                       match = this.activeMenu.find( this.options.items ).filter(function() {
-                               return regex.test( $( this ).text() );
-                       });
+                       match = this._filterMenuItems( character );
                        match = skip && match.index( this.active.next() ) !== -1 ?
                                this.active.nextAll( ".ui-menu-item" ) :
                                match;
@@ -253,10 +246,7 @@ return $.widget( "ui.menu", {
                        // to move down the menu to the first item that starts with that character
                        if ( !match.length ) {
                                character = String.fromCharCode( event.keyCode );
-                               regex = new RegExp( "^" + escape( character ), "i" );
-                               match = this.activeMenu.find( this.options.items ).filter(function() {
-                                       return regex.test( $( this ).text() );
-                               });
+                               match = this._filterMenuItems( character );
                        }
 
                        if ( match.length ) {
@@ -640,6 +630,20 @@ return $.widget( "ui.menu", {
                        this.collapseAll( event, true );
                }
                this._trigger( "select", event, ui );
+       },
+
+       _filterMenuItems: function(character) {
+               var escapedCharacter = character.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" ),
+                       regex = new RegExp( "^" + escapedCharacter, "i" );
+
+               return this.activeMenu
+                       .find( this.options.items )
+
+                       // Only match on items, not dividers or other content (#10571)
+                       .filter( ".ui-menu-item" )
+                       .filter(function() {
+                               return regex.test( $( this ).text() );
+                       });
        }
 });