wp/wp-includes/js/jquery/ui/menu.js
changeset 19 3d72ae0968f4
parent 18 be944660c56a
child 21 48c4eec2b7e6
equal deleted inserted replaced
18:be944660c56a 19:3d72ae0968f4
     1 /*!
     1 /*!
     2  * jQuery UI Menu 1.12.1
     2  * jQuery UI Menu 1.13.1
     3  * http://jqueryui.com
     3  * http://jqueryui.com
     4  *
     4  *
     5  * Copyright jQuery Foundation and other contributors
     5  * Copyright jQuery Foundation and other contributors
     6  * Released under the MIT license.
     6  * Released under the MIT license.
     7  * http://jquery.org/license
     7  * http://jquery.org/license
    15 //>>css.structure: ../../themes/base/core.css
    15 //>>css.structure: ../../themes/base/core.css
    16 //>>css.structure: ../../themes/base/menu.css
    16 //>>css.structure: ../../themes/base/menu.css
    17 //>>css.theme: ../../themes/base/theme.css
    17 //>>css.theme: ../../themes/base/theme.css
    18 
    18 
    19 ( function( factory ) {
    19 ( function( factory ) {
       
    20 	"use strict";
       
    21 
    20 	if ( typeof define === "function" && define.amd ) {
    22 	if ( typeof define === "function" && define.amd ) {
    21 
    23 
    22 		// AMD. Register as an anonymous module.
    24 		// AMD. Register as an anonymous module.
    23 		define( [
    25 		define( [
    24 			"jquery",
    26 			"jquery",
    27 	} else {
    29 	} else {
    28 
    30 
    29 		// Browser globals
    31 		// Browser globals
    30 		factory( jQuery );
    32 		factory( jQuery );
    31 	}
    33 	}
    32 }( function( $ ) {
    34 } )( function( $ ) {
       
    35 "use strict";
    33 
    36 
    34 return $.widget( "ui.menu", {
    37 return $.widget( "ui.menu", {
    35 	version: "1.12.1",
    38 	version: "1.13.1",
    36 	defaultElement: "<ul>",
    39 	defaultElement: "<ul>",
    37 	delay: 300,
    40 	delay: 300,
    38 	options: {
    41 	options: {
    39 		icons: {
    42 		icons: {
    40 			submenu: "ui-icon-caret-1-e"
    43 			submenu: "ui-icon-caret-1-e"
    57 		this.activeMenu = this.element;
    60 		this.activeMenu = this.element;
    58 
    61 
    59 		// Flag used to prevent firing of the click handler
    62 		// Flag used to prevent firing of the click handler
    60 		// as the event bubbles up through nested menus
    63 		// as the event bubbles up through nested menus
    61 		this.mouseHandled = false;
    64 		this.mouseHandled = false;
       
    65 		this.lastMousePosition = { x: null, y: null };
    62 		this.element
    66 		this.element
    63 			.uniqueId()
    67 			.uniqueId()
    64 			.attr( {
    68 			.attr( {
    65 				role: this.options.role,
    69 				role: this.options.role,
    66 				tabIndex: 0
    70 				tabIndex: 0
    71 
    75 
    72 			// Prevent focus from sticking to links inside menu after clicking
    76 			// Prevent focus from sticking to links inside menu after clicking
    73 			// them (focus should always stay on UL during navigation).
    77 			// them (focus should always stay on UL during navigation).
    74 			"mousedown .ui-menu-item": function( event ) {
    78 			"mousedown .ui-menu-item": function( event ) {
    75 				event.preventDefault();
    79 				event.preventDefault();
       
    80 
       
    81 				this._activateItem( event );
    76 			},
    82 			},
    77 			"click .ui-menu-item": function( event ) {
    83 			"click .ui-menu-item": function( event ) {
    78 				var target = $( event.target );
    84 				var target = $( event.target );
    79 				var active = $( $.ui.safeActiveElement( this.document[ 0 ] ) );
    85 				var active = $( $.ui.safeActiveElement( this.document[ 0 ] ) );
    80 				if ( !this.mouseHandled && target.not( ".ui-state-disabled" ).length ) {
    86 				if ( !this.mouseHandled && target.not( ".ui-state-disabled" ).length ) {
    87 
    93 
    88 					// Open submenu on click
    94 					// Open submenu on click
    89 					if ( target.has( ".ui-menu" ).length ) {
    95 					if ( target.has( ".ui-menu" ).length ) {
    90 						this.expand( event );
    96 						this.expand( event );
    91 					} else if ( !this.element.is( ":focus" ) &&
    97 					} else if ( !this.element.is( ":focus" ) &&
    92 							active.closest( ".ui-menu" ).length ) {
    98 						active.closest( ".ui-menu" ).length ) {
    93 
    99 
    94 						// Redirect focus to the menu
   100 						// Redirect focus to the menu
    95 						this.element.trigger( "focus", [ true ] );
   101 						this.element.trigger( "focus", [ true ] );
    96 
   102 
    97 						// If the active item is on the top level, let it stay active.
   103 						// If the active item is on the top level, let it stay active.
   100 							clearTimeout( this.timer );
   106 							clearTimeout( this.timer );
   101 						}
   107 						}
   102 					}
   108 					}
   103 				}
   109 				}
   104 			},
   110 			},
   105 			"mouseenter .ui-menu-item": function( event ) {
   111 			"mouseenter .ui-menu-item": "_activateItem",
   106 
   112 			"mousemove .ui-menu-item": "_activateItem",
   107 				// Ignore mouse events while typeahead is active, see #10458.
       
   108 				// Prevents focusing the wrong item when typeahead causes a scroll while the mouse
       
   109 				// is over an item in the menu
       
   110 				if ( this.previousFilter ) {
       
   111 					return;
       
   112 				}
       
   113 
       
   114 				var actualTarget = $( event.target ).closest( ".ui-menu-item" ),
       
   115 					target = $( event.currentTarget );
       
   116 
       
   117 				// Ignore bubbled events on parent items, see #11641
       
   118 				if ( actualTarget[ 0 ] !== target[ 0 ] ) {
       
   119 					return;
       
   120 				}
       
   121 
       
   122 				// Remove ui-state-active class from siblings of the newly focused menu item
       
   123 				// to avoid a jump caused by adjacent elements both having a class with a border
       
   124 				this._removeClass( target.siblings().children( ".ui-state-active" ),
       
   125 					null, "ui-state-active" );
       
   126 				this.focus( event, target );
       
   127 			},
       
   128 			mouseleave: "collapseAll",
   113 			mouseleave: "collapseAll",
   129 			"mouseleave .ui-menu": "collapseAll",
   114 			"mouseleave .ui-menu": "collapseAll",
   130 			focus: function( event, keepActiveItem ) {
   115 			focus: function( event, keepActiveItem ) {
   131 
   116 
   132 				// If there's already an active item, keep it active
   117 				// If there's already an active item, keep it active
   133 				// If not, activate the first item
   118 				// If not, activate the first item
   134 				var item = this.active || this.element.find( this.options.items ).eq( 0 );
   119 				var item = this.active || this._menuItems().first();
   135 
   120 
   136 				if ( !keepActiveItem ) {
   121 				if ( !keepActiveItem ) {
   137 					this.focus( event, item );
   122 					this.focus( event, item );
   138 				}
   123 				}
   139 			},
   124 			},
   155 
   140 
   156 		// Clicks outside of a menu collapse any open menus
   141 		// Clicks outside of a menu collapse any open menus
   157 		this._on( this.document, {
   142 		this._on( this.document, {
   158 			click: function( event ) {
   143 			click: function( event ) {
   159 				if ( this._closeOnDocumentClick( event ) ) {
   144 				if ( this._closeOnDocumentClick( event ) ) {
   160 					this.collapseAll( event );
   145 					this.collapseAll( event, true );
   161 				}
   146 				}
   162 
   147 
   163 				// Reset the mouseHandled flag
   148 				// Reset the mouseHandled flag
   164 				this.mouseHandled = false;
   149 				this.mouseHandled = false;
   165 			}
   150 			}
   166 		} );
   151 		} );
       
   152 	},
       
   153 
       
   154 	_activateItem: function( event ) {
       
   155 
       
   156 		// Ignore mouse events while typeahead is active, see #10458.
       
   157 		// Prevents focusing the wrong item when typeahead causes a scroll while the mouse
       
   158 		// is over an item in the menu
       
   159 		if ( this.previousFilter ) {
       
   160 			return;
       
   161 		}
       
   162 
       
   163 		// If the mouse didn't actually move, but the page was scrolled, ignore the event (#9356)
       
   164 		if ( event.clientX === this.lastMousePosition.x &&
       
   165 			event.clientY === this.lastMousePosition.y ) {
       
   166 			return;
       
   167 		}
       
   168 
       
   169 		this.lastMousePosition = {
       
   170 			x: event.clientX,
       
   171 			y: event.clientY
       
   172 		};
       
   173 
       
   174 		var actualTarget = $( event.target ).closest( ".ui-menu-item" ),
       
   175 			target = $( event.currentTarget );
       
   176 
       
   177 		// Ignore bubbled events on parent items, see #11641
       
   178 		if ( actualTarget[ 0 ] !== target[ 0 ] ) {
       
   179 			return;
       
   180 		}
       
   181 
       
   182 		// If the item is already active, there's nothing to do
       
   183 		if ( target.is( ".ui-state-active" ) ) {
       
   184 			return;
       
   185 		}
       
   186 
       
   187 		// Remove ui-state-active class from siblings of the newly focused menu item
       
   188 		// to avoid a jump caused by adjacent elements both having a class with a border
       
   189 		this._removeClass( target.siblings().children( ".ui-state-active" ),
       
   190 			null, "ui-state-active" );
       
   191 		this.focus( event, target );
   167 	},
   192 	},
   168 
   193 
   169 	_destroy: function() {
   194 	_destroy: function() {
   170 		var items = this.element.find( ".ui-menu-item" )
   195 		var items = this.element.find( ".ui-menu-item" )
   171 				.removeAttr( "role aria-disabled" ),
   196 				.removeAttr( "role aria-disabled" ),
   175 
   200 
   176 		// Destroy (sub)menus
   201 		// Destroy (sub)menus
   177 		this.element
   202 		this.element
   178 			.removeAttr( "aria-activedescendant" )
   203 			.removeAttr( "aria-activedescendant" )
   179 			.find( ".ui-menu" ).addBack()
   204 			.find( ".ui-menu" ).addBack()
   180 				.removeAttr( "role aria-labelledby aria-expanded aria-hidden aria-disabled " +
   205 			.removeAttr( "role aria-labelledby aria-expanded aria-hidden aria-disabled " +
   181 					"tabIndex" )
   206 				"tabIndex" )
   182 				.removeUniqueId()
   207 			.removeUniqueId()
   183 				.show();
   208 			.show();
   184 
   209 
   185 		submenus.children().each( function() {
   210 		submenus.children().each( function() {
   186 			var elem = $( this );
   211 			var elem = $( this );
   187 			if ( elem.data( "ui-menu-submenu-caret" ) ) {
   212 			if ( elem.data( "ui-menu-submenu-caret" ) ) {
   188 				elem.remove();
   213 				elem.remove();
   193 	_keydown: function( event ) {
   218 	_keydown: function( event ) {
   194 		var match, prev, character, skip,
   219 		var match, prev, character, skip,
   195 			preventDefault = true;
   220 			preventDefault = true;
   196 
   221 
   197 		switch ( event.keyCode ) {
   222 		switch ( event.keyCode ) {
   198 		case $.ui.keyCode.PAGE_UP:
   223 			case $.ui.keyCode.PAGE_UP:
   199 			this.previousPage( event );
   224 				this.previousPage( event );
   200 			break;
   225 				break;
   201 		case $.ui.keyCode.PAGE_DOWN:
   226 			case $.ui.keyCode.PAGE_DOWN:
   202 			this.nextPage( event );
   227 				this.nextPage( event );
   203 			break;
   228 				break;
   204 		case $.ui.keyCode.HOME:
   229 			case $.ui.keyCode.HOME:
   205 			this._move( "first", "first", event );
   230 				this._move( "first", "first", event );
   206 			break;
   231 				break;
   207 		case $.ui.keyCode.END:
   232 			case $.ui.keyCode.END:
   208 			this._move( "last", "last", event );
   233 				this._move( "last", "last", event );
   209 			break;
   234 				break;
   210 		case $.ui.keyCode.UP:
   235 			case $.ui.keyCode.UP:
   211 			this.previous( event );
   236 				this.previous( event );
   212 			break;
   237 				break;
   213 		case $.ui.keyCode.DOWN:
   238 			case $.ui.keyCode.DOWN:
   214 			this.next( event );
   239 				this.next( event );
   215 			break;
   240 				break;
   216 		case $.ui.keyCode.LEFT:
   241 			case $.ui.keyCode.LEFT:
   217 			this.collapse( event );
   242 				this.collapse( event );
   218 			break;
   243 				break;
   219 		case $.ui.keyCode.RIGHT:
   244 			case $.ui.keyCode.RIGHT:
   220 			if ( this.active && !this.active.is( ".ui-state-disabled" ) ) {
   245 				if ( this.active && !this.active.is( ".ui-state-disabled" ) ) {
   221 				this.expand( event );
   246 					this.expand( event );
   222 			}
   247 				}
   223 			break;
   248 				break;
   224 		case $.ui.keyCode.ENTER:
   249 			case $.ui.keyCode.ENTER:
   225 		case $.ui.keyCode.SPACE:
   250 			case $.ui.keyCode.SPACE:
   226 			this._activate( event );
   251 				this._activate( event );
   227 			break;
   252 				break;
   228 		case $.ui.keyCode.ESCAPE:
   253 			case $.ui.keyCode.ESCAPE:
   229 			this.collapse( event );
   254 				this.collapse( event );
   230 			break;
   255 				break;
   231 		default:
   256 			default:
   232 			preventDefault = false;
   257 				preventDefault = false;
   233 			prev = this.previousFilter || "";
   258 				prev = this.previousFilter || "";
   234 			skip = false;
   259 				skip = false;
   235 
   260 
   236 			// Support number pad values
   261 				// Support number pad values
   237 			character = event.keyCode >= 96 && event.keyCode <= 105 ?
   262 				character = event.keyCode >= 96 && event.keyCode <= 105 ?
   238 				( event.keyCode - 96 ).toString() : String.fromCharCode( event.keyCode );
   263 					( event.keyCode - 96 ).toString() : String.fromCharCode( event.keyCode );
   239 
   264 
   240 			clearTimeout( this.filterTimer );
   265 				clearTimeout( this.filterTimer );
   241 
   266 
   242 			if ( character === prev ) {
   267 				if ( character === prev ) {
   243 				skip = true;
   268 					skip = true;
   244 			} else {
   269 				} else {
   245 				character = prev + character;
   270 					character = prev + character;
   246 			}
   271 				}
   247 
   272 
   248 			match = this._filterMenuItems( character );
       
   249 			match = skip && match.index( this.active.next() ) !== -1 ?
       
   250 				this.active.nextAll( ".ui-menu-item" ) :
       
   251 				match;
       
   252 
       
   253 			// If no matches on the current filter, reset to the last character pressed
       
   254 			// to move down the menu to the first item that starts with that character
       
   255 			if ( !match.length ) {
       
   256 				character = String.fromCharCode( event.keyCode );
       
   257 				match = this._filterMenuItems( character );
   273 				match = this._filterMenuItems( character );
   258 			}
   274 				match = skip && match.index( this.active.next() ) !== -1 ?
   259 
   275 					this.active.nextAll( ".ui-menu-item" ) :
   260 			if ( match.length ) {
   276 					match;
   261 				this.focus( event, match );
   277 
   262 				this.previousFilter = character;
   278 				// If no matches on the current filter, reset to the last character pressed
   263 				this.filterTimer = this._delay( function() {
   279 				// to move down the menu to the first item that starts with that character
       
   280 				if ( !match.length ) {
       
   281 					character = String.fromCharCode( event.keyCode );
       
   282 					match = this._filterMenuItems( character );
       
   283 				}
       
   284 
       
   285 				if ( match.length ) {
       
   286 					this.focus( event, match );
       
   287 					this.previousFilter = character;
       
   288 					this.filterTimer = this._delay( function() {
       
   289 						delete this.previousFilter;
       
   290 					}, 1000 );
       
   291 				} else {
   264 					delete this.previousFilter;
   292 					delete this.previousFilter;
   265 				}, 1000 );
   293 				}
   266 			} else {
       
   267 				delete this.previousFilter;
       
   268 			}
       
   269 		}
   294 		}
   270 
   295 
   271 		if ( preventDefault ) {
   296 		if ( preventDefault ) {
   272 			event.preventDefault();
   297 			event.preventDefault();
   273 		}
   298 		}
   326 
   351 
   327 		// Don't refresh list items that are already adapted
   352 		// Don't refresh list items that are already adapted
   328 		newItems = items.not( ".ui-menu-item, .ui-menu-divider" );
   353 		newItems = items.not( ".ui-menu-item, .ui-menu-divider" );
   329 		newWrappers = newItems.children()
   354 		newWrappers = newItems.children()
   330 			.not( ".ui-menu" )
   355 			.not( ".ui-menu" )
   331 				.uniqueId()
   356 			.uniqueId()
   332 				.attr( {
   357 			.attr( {
   333 					tabIndex: -1,
   358 				tabIndex: -1,
   334 					role: this._itemRole()
   359 				role: this._itemRole()
   335 				} );
   360 			} );
   336 		this._addClass( newItems, "ui-menu-item" )
   361 		this._addClass( newItems, "ui-menu-item" )
   337 			._addClass( newWrappers, "ui-menu-item-wrapper" );
   362 			._addClass( newWrappers, "ui-menu-item-wrapper" );
   338 
   363 
   339 		// Add aria-disabled attribute to any disabled menu item
   364 		// Add aria-disabled attribute to any disabled menu item
   340 		items.filter( ".ui-state-disabled" ).attr( "aria-disabled", "true" );
   365 		items.filter( ".ui-state-disabled" ).attr( "aria-disabled", "true" );
   386 		}
   411 		}
   387 
   412 
   388 		// Highlight active parent menu item, if any
   413 		// Highlight active parent menu item, if any
   389 		activeParent = this.active
   414 		activeParent = this.active
   390 			.parent()
   415 			.parent()
   391 				.closest( ".ui-menu-item" )
   416 			.closest( ".ui-menu-item" )
   392 					.children( ".ui-menu-item-wrapper" );
   417 			.children( ".ui-menu-item-wrapper" );
   393 		this._addClass( activeParent, null, "ui-state-active" );
   418 		this._addClass( activeParent, null, "ui-state-active" );
   394 
   419 
   395 		if ( event && event.type === "keydown" ) {
   420 		if ( event && event.type === "keydown" ) {
   396 			this._close();
   421 			this._close();
   397 		} else {
   422 		} else {
   495 
   520 
   496 			// Work around active item staying active after menu is blurred
   521 			// Work around active item staying active after menu is blurred
   497 			this._removeClass( currentMenu.find( ".ui-state-active" ), null, "ui-state-active" );
   522 			this._removeClass( currentMenu.find( ".ui-state-active" ), null, "ui-state-active" );
   498 
   523 
   499 			this.activeMenu = currentMenu;
   524 			this.activeMenu = currentMenu;
   500 		}, this.delay );
   525 		}, all ? 0 : this.delay );
   501 	},
   526 	},
   502 
   527 
   503 	// With no arguments, closes the currently active menu - if nothing is active
   528 	// With no arguments, closes the currently active menu - if nothing is active
   504 	// it closes all menus.  If passed an argument, it will search for menus BELOW
   529 	// it closes all menus.  If passed an argument, it will search for menus BELOW
   505 	_close: function( startMenu ) {
   530 	_close: function( startMenu ) {
   531 			this.focus( event, newItem );
   556 			this.focus( event, newItem );
   532 		}
   557 		}
   533 	},
   558 	},
   534 
   559 
   535 	expand: function( event ) {
   560 	expand: function( event ) {
   536 		var newItem = this.active &&
   561 		var newItem = this.active && this._menuItems( this.active.children( ".ui-menu" ) ).first();
   537 			this.active
       
   538 				.children( ".ui-menu " )
       
   539 					.find( this.options.items )
       
   540 						.first();
       
   541 
   562 
   542 		if ( newItem && newItem.length ) {
   563 		if ( newItem && newItem.length ) {
   543 			this._open( newItem.parent() );
   564 			this._open( newItem.parent() );
   544 
   565 
   545 			// Delay so Firefox will not hide activedescendant change in expanding submenu from AT
   566 			// Delay so Firefox will not hide activedescendant change in expanding submenu from AT
   561 		return this.active && !this.active.prevAll( ".ui-menu-item" ).length;
   582 		return this.active && !this.active.prevAll( ".ui-menu-item" ).length;
   562 	},
   583 	},
   563 
   584 
   564 	isLastItem: function() {
   585 	isLastItem: function() {
   565 		return this.active && !this.active.nextAll( ".ui-menu-item" ).length;
   586 		return this.active && !this.active.nextAll( ".ui-menu-item" ).length;
       
   587 	},
       
   588 
       
   589 	_menuItems: function( menu ) {
       
   590 		return ( menu || this.element )
       
   591 			.find( this.options.items )
       
   592 			.filter( ".ui-menu-item" );
   566 	},
   593 	},
   567 
   594 
   568 	_move: function( direction, filter, event ) {
   595 	_move: function( direction, filter, event ) {
   569 		var next;
   596 		var next;
   570 		if ( this.active ) {
   597 		if ( this.active ) {
   571 			if ( direction === "first" || direction === "last" ) {
   598 			if ( direction === "first" || direction === "last" ) {
   572 				next = this.active
   599 				next = this.active
   573 					[ direction === "first" ? "prevAll" : "nextAll" ]( ".ui-menu-item" )
   600 					[ direction === "first" ? "prevAll" : "nextAll" ]( ".ui-menu-item" )
   574 					.eq( -1 );
   601 					.last();
   575 			} else {
   602 			} else {
   576 				next = this.active
   603 				next = this.active
   577 					[ direction + "All" ]( ".ui-menu-item" )
   604 					[ direction + "All" ]( ".ui-menu-item" )
   578 					.eq( 0 );
   605 					.first();
   579 			}
   606 			}
   580 		}
   607 		}
   581 		if ( !next || !next.length || !this.active ) {
   608 		if ( !next || !next.length || !this.active ) {
   582 			next = this.activeMenu.find( this.options.items )[ filter ]();
   609 			next = this._menuItems( this.activeMenu )[ filter ]();
   583 		}
   610 		}
   584 
   611 
   585 		this.focus( event, next );
   612 		this.focus( event, next );
   586 	},
   613 	},
   587 
   614 
   595 		if ( this.isLastItem() ) {
   622 		if ( this.isLastItem() ) {
   596 			return;
   623 			return;
   597 		}
   624 		}
   598 		if ( this._hasScroll() ) {
   625 		if ( this._hasScroll() ) {
   599 			base = this.active.offset().top;
   626 			base = this.active.offset().top;
   600 			height = this.element.height();
   627 			height = this.element.innerHeight();
       
   628 
       
   629 			// jQuery 3.2 doesn't include scrollbars in innerHeight, add it back.
       
   630 			if ( $.fn.jquery.indexOf( "3.2." ) === 0 ) {
       
   631 				height += this.element[ 0 ].offsetHeight - this.element.outerHeight();
       
   632 			}
       
   633 
   601 			this.active.nextAll( ".ui-menu-item" ).each( function() {
   634 			this.active.nextAll( ".ui-menu-item" ).each( function() {
   602 				item = $( this );
   635 				item = $( this );
   603 				return item.offset().top - base - height < 0;
   636 				return item.offset().top - base - height < 0;
   604 			} );
   637 			} );
   605 
   638 
   606 			this.focus( event, item );
   639 			this.focus( event, item );
   607 		} else {
   640 		} else {
   608 			this.focus( event, this.activeMenu.find( this.options.items )
   641 			this.focus( event, this._menuItems( this.activeMenu )
   609 				[ !this.active ? "first" : "last" ]() );
   642 				[ !this.active ? "first" : "last" ]() );
   610 		}
   643 		}
   611 	},
   644 	},
   612 
   645 
   613 	previousPage: function( event ) {
   646 	previousPage: function( event ) {
   619 		if ( this.isFirstItem() ) {
   652 		if ( this.isFirstItem() ) {
   620 			return;
   653 			return;
   621 		}
   654 		}
   622 		if ( this._hasScroll() ) {
   655 		if ( this._hasScroll() ) {
   623 			base = this.active.offset().top;
   656 			base = this.active.offset().top;
   624 			height = this.element.height();
   657 			height = this.element.innerHeight();
       
   658 
       
   659 			// jQuery 3.2 doesn't include scrollbars in innerHeight, add it back.
       
   660 			if ( $.fn.jquery.indexOf( "3.2." ) === 0 ) {
       
   661 				height += this.element[ 0 ].offsetHeight - this.element.outerHeight();
       
   662 			}
       
   663 
   625 			this.active.prevAll( ".ui-menu-item" ).each( function() {
   664 			this.active.prevAll( ".ui-menu-item" ).each( function() {
   626 				item = $( this );
   665 				item = $( this );
   627 				return item.offset().top - base + height > 0;
   666 				return item.offset().top - base + height > 0;
   628 			} );
   667 			} );
   629 
   668 
   630 			this.focus( event, item );
   669 			this.focus( event, item );
   631 		} else {
   670 		} else {
   632 			this.focus( event, this.activeMenu.find( this.options.items ).first() );
   671 			this.focus( event, this._menuItems( this.activeMenu ).first() );
   633 		}
   672 		}
   634 	},
   673 	},
   635 
   674 
   636 	_hasScroll: function() {
   675 	_hasScroll: function() {
   637 		return this.element.outerHeight() < this.element.prop( "scrollHeight" );
   676 		return this.element.outerHeight() < this.element.prop( "scrollHeight" );
   654 			regex = new RegExp( "^" + escapedCharacter, "i" );
   693 			regex = new RegExp( "^" + escapedCharacter, "i" );
   655 
   694 
   656 		return this.activeMenu
   695 		return this.activeMenu
   657 			.find( this.options.items )
   696 			.find( this.options.items )
   658 
   697 
   659 				// Only match on items, not dividers or other content (#10571)
   698 			// Only match on items, not dividers or other content (#10571)
   660 				.filter( ".ui-menu-item" )
   699 			.filter( ".ui-menu-item" )
   661 					.filter( function() {
   700 			.filter( function() {
   662 						return regex.test(
   701 				return regex.test(
   663 							$.trim( $( this ).children( ".ui-menu-item-wrapper" ).text() ) );
   702 					String.prototype.trim.call(
   664 					} );
   703 						$( this ).children( ".ui-menu-item-wrapper" ).text() ) );
       
   704 			} );
   665 	}
   705 	}
   666 } );
   706 } );
   667 
   707 
   668 } ) );
   708 } );