integration/back-office/lib/jquery-ui/ui/jquery.ui.menu.js
changeset 2 78f71aa0a477
parent 1 b95aebb070b5
child 3 54f80d24f469
child 6 547b3ddedf7f
equal deleted inserted replaced
1:b95aebb070b5 2:78f71aa0a477
     1 /*!
       
     2  * jQuery UI Menu 1.10.3
       
     3  * http://jqueryui.com
       
     4  *
       
     5  * Copyright 2013 jQuery Foundation and other contributors
       
     6  * Released under the MIT license.
       
     7  * http://jquery.org/license
       
     8  *
       
     9  * http://api.jqueryui.com/menu/
       
    10  *
       
    11  * Depends:
       
    12  *	jquery.ui.core.js
       
    13  *	jquery.ui.widget.js
       
    14  *	jquery.ui.position.js
       
    15  */
       
    16 (function( $, undefined ) {
       
    17 
       
    18 $.widget( "ui.menu", {
       
    19 	version: "1.10.3",
       
    20 	defaultElement: "<ul>",
       
    21 	delay: 300,
       
    22 	options: {
       
    23 		icons: {
       
    24 			submenu: "ui-icon-carat-1-e"
       
    25 		},
       
    26 		menus: "ul",
       
    27 		position: {
       
    28 			my: "left top",
       
    29 			at: "right top"
       
    30 		},
       
    31 		role: "menu",
       
    32 
       
    33 		// callbacks
       
    34 		blur: null,
       
    35 		focus: null,
       
    36 		select: null
       
    37 	},
       
    38 
       
    39 	_create: function() {
       
    40 		this.activeMenu = this.element;
       
    41 		// flag used to prevent firing of the click handler
       
    42 		// as the event bubbles up through nested menus
       
    43 		this.mouseHandled = false;
       
    44 		this.element
       
    45 			.uniqueId()
       
    46 			.addClass( "ui-menu ui-widget ui-widget-content ui-corner-all" )
       
    47 			.toggleClass( "ui-menu-icons", !!this.element.find( ".ui-icon" ).length )
       
    48 			.attr({
       
    49 				role: this.options.role,
       
    50 				tabIndex: 0
       
    51 			})
       
    52 			// need to catch all clicks on disabled menu
       
    53 			// not possible through _on
       
    54 			.bind( "click" + this.eventNamespace, $.proxy(function( event ) {
       
    55 				if ( this.options.disabled ) {
       
    56 					event.preventDefault();
       
    57 				}
       
    58 			}, this ));
       
    59 
       
    60 		if ( this.options.disabled ) {
       
    61 			this.element
       
    62 				.addClass( "ui-state-disabled" )
       
    63 				.attr( "aria-disabled", "true" );
       
    64 		}
       
    65 
       
    66 		this._on({
       
    67 			// Prevent focus from sticking to links inside menu after clicking
       
    68 			// them (focus should always stay on UL during navigation).
       
    69 			"mousedown .ui-menu-item > a": function( event ) {
       
    70 				event.preventDefault();
       
    71 			},
       
    72 			"click .ui-state-disabled > a": function( event ) {
       
    73 				event.preventDefault();
       
    74 			},
       
    75 			"click .ui-menu-item:has(a)": function( event ) {
       
    76 				var target = $( event.target ).closest( ".ui-menu-item" );
       
    77 				if ( !this.mouseHandled && target.not( ".ui-state-disabled" ).length ) {
       
    78 					this.mouseHandled = true;
       
    79 
       
    80 					this.select( event );
       
    81 					// Open submenu on click
       
    82 					if ( target.has( ".ui-menu" ).length ) {
       
    83 						this.expand( event );
       
    84 					} else if ( !this.element.is( ":focus" ) ) {
       
    85 						// Redirect focus to the menu
       
    86 						this.element.trigger( "focus", [ true ] );
       
    87 
       
    88 						// If the active item is on the top level, let it stay active.
       
    89 						// Otherwise, blur the active item since it is no longer visible.
       
    90 						if ( this.active && this.active.parents( ".ui-menu" ).length === 1 ) {
       
    91 							clearTimeout( this.timer );
       
    92 						}
       
    93 					}
       
    94 				}
       
    95 			},
       
    96 			"mouseenter .ui-menu-item": function( event ) {
       
    97 				var target = $( event.currentTarget );
       
    98 				// Remove ui-state-active class from siblings of the newly focused menu item
       
    99 				// to avoid a jump caused by adjacent elements both having a class with a border
       
   100 				target.siblings().children( ".ui-state-active" ).removeClass( "ui-state-active" );
       
   101 				this.focus( event, target );
       
   102 			},
       
   103 			mouseleave: "collapseAll",
       
   104 			"mouseleave .ui-menu": "collapseAll",
       
   105 			focus: function( event, keepActiveItem ) {
       
   106 				// If there's already an active item, keep it active
       
   107 				// If not, activate the first item
       
   108 				var item = this.active || this.element.children( ".ui-menu-item" ).eq( 0 );
       
   109 
       
   110 				if ( !keepActiveItem ) {
       
   111 					this.focus( event, item );
       
   112 				}
       
   113 			},
       
   114 			blur: function( event ) {
       
   115 				this._delay(function() {
       
   116 					if ( !$.contains( this.element[0], this.document[0].activeElement ) ) {
       
   117 						this.collapseAll( event );
       
   118 					}
       
   119 				});
       
   120 			},
       
   121 			keydown: "_keydown"
       
   122 		});
       
   123 
       
   124 		this.refresh();
       
   125 
       
   126 		// Clicks outside of a menu collapse any open menus
       
   127 		this._on( this.document, {
       
   128 			click: function( event ) {
       
   129 				if ( !$( event.target ).closest( ".ui-menu" ).length ) {
       
   130 					this.collapseAll( event );
       
   131 				}
       
   132 
       
   133 				// Reset the mouseHandled flag
       
   134 				this.mouseHandled = false;
       
   135 			}
       
   136 		});
       
   137 	},
       
   138 
       
   139 	_destroy: function() {
       
   140 		// Destroy (sub)menus
       
   141 		this.element
       
   142 			.removeAttr( "aria-activedescendant" )
       
   143 			.find( ".ui-menu" ).addBack()
       
   144 				.removeClass( "ui-menu ui-widget ui-widget-content ui-corner-all ui-menu-icons" )
       
   145 				.removeAttr( "role" )
       
   146 				.removeAttr( "tabIndex" )
       
   147 				.removeAttr( "aria-labelledby" )
       
   148 				.removeAttr( "aria-expanded" )
       
   149 				.removeAttr( "aria-hidden" )
       
   150 				.removeAttr( "aria-disabled" )
       
   151 				.removeUniqueId()
       
   152 				.show();
       
   153 
       
   154 		// Destroy menu items
       
   155 		this.element.find( ".ui-menu-item" )
       
   156 			.removeClass( "ui-menu-item" )
       
   157 			.removeAttr( "role" )
       
   158 			.removeAttr( "aria-disabled" )
       
   159 			.children( "a" )
       
   160 				.removeUniqueId()
       
   161 				.removeClass( "ui-corner-all ui-state-hover" )
       
   162 				.removeAttr( "tabIndex" )
       
   163 				.removeAttr( "role" )
       
   164 				.removeAttr( "aria-haspopup" )
       
   165 				.children().each( function() {
       
   166 					var elem = $( this );
       
   167 					if ( elem.data( "ui-menu-submenu-carat" ) ) {
       
   168 						elem.remove();
       
   169 					}
       
   170 				});
       
   171 
       
   172 		// Destroy menu dividers
       
   173 		this.element.find( ".ui-menu-divider" ).removeClass( "ui-menu-divider ui-widget-content" );
       
   174 	},
       
   175 
       
   176 	_keydown: function( event ) {
       
   177 		/*jshint maxcomplexity:20*/
       
   178 		var match, prev, character, skip, regex,
       
   179 			preventDefault = true;
       
   180 
       
   181 		function escape( value ) {
       
   182 			return value.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" );
       
   183 		}
       
   184 
       
   185 		switch ( event.keyCode ) {
       
   186 		case $.ui.keyCode.PAGE_UP:
       
   187 			this.previousPage( event );
       
   188 			break;
       
   189 		case $.ui.keyCode.PAGE_DOWN:
       
   190 			this.nextPage( event );
       
   191 			break;
       
   192 		case $.ui.keyCode.HOME:
       
   193 			this._move( "first", "first", event );
       
   194 			break;
       
   195 		case $.ui.keyCode.END:
       
   196 			this._move( "last", "last", event );
       
   197 			break;
       
   198 		case $.ui.keyCode.UP:
       
   199 			this.previous( event );
       
   200 			break;
       
   201 		case $.ui.keyCode.DOWN:
       
   202 			this.next( event );
       
   203 			break;
       
   204 		case $.ui.keyCode.LEFT:
       
   205 			this.collapse( event );
       
   206 			break;
       
   207 		case $.ui.keyCode.RIGHT:
       
   208 			if ( this.active && !this.active.is( ".ui-state-disabled" ) ) {
       
   209 				this.expand( event );
       
   210 			}
       
   211 			break;
       
   212 		case $.ui.keyCode.ENTER:
       
   213 		case $.ui.keyCode.SPACE:
       
   214 			this._activate( event );
       
   215 			break;
       
   216 		case $.ui.keyCode.ESCAPE:
       
   217 			this.collapse( event );
       
   218 			break;
       
   219 		default:
       
   220 			preventDefault = false;
       
   221 			prev = this.previousFilter || "";
       
   222 			character = String.fromCharCode( event.keyCode );
       
   223 			skip = false;
       
   224 
       
   225 			clearTimeout( this.filterTimer );
       
   226 
       
   227 			if ( character === prev ) {
       
   228 				skip = true;
       
   229 			} else {
       
   230 				character = prev + character;
       
   231 			}
       
   232 
       
   233 			regex = new RegExp( "^" + escape( character ), "i" );
       
   234 			match = this.activeMenu.children( ".ui-menu-item" ).filter(function() {
       
   235 				return regex.test( $( this ).children( "a" ).text() );
       
   236 			});
       
   237 			match = skip && match.index( this.active.next() ) !== -1 ?
       
   238 				this.active.nextAll( ".ui-menu-item" ) :
       
   239 				match;
       
   240 
       
   241 			// If no matches on the current filter, reset to the last character pressed
       
   242 			// to move down the menu to the first item that starts with that character
       
   243 			if ( !match.length ) {
       
   244 				character = String.fromCharCode( event.keyCode );
       
   245 				regex = new RegExp( "^" + escape( character ), "i" );
       
   246 				match = this.activeMenu.children( ".ui-menu-item" ).filter(function() {
       
   247 					return regex.test( $( this ).children( "a" ).text() );
       
   248 				});
       
   249 			}
       
   250 
       
   251 			if ( match.length ) {
       
   252 				this.focus( event, match );
       
   253 				if ( match.length > 1 ) {
       
   254 					this.previousFilter = character;
       
   255 					this.filterTimer = this._delay(function() {
       
   256 						delete this.previousFilter;
       
   257 					}, 1000 );
       
   258 				} else {
       
   259 					delete this.previousFilter;
       
   260 				}
       
   261 			} else {
       
   262 				delete this.previousFilter;
       
   263 			}
       
   264 		}
       
   265 
       
   266 		if ( preventDefault ) {
       
   267 			event.preventDefault();
       
   268 		}
       
   269 	},
       
   270 
       
   271 	_activate: function( event ) {
       
   272 		if ( !this.active.is( ".ui-state-disabled" ) ) {
       
   273 			if ( this.active.children( "a[aria-haspopup='true']" ).length ) {
       
   274 				this.expand( event );
       
   275 			} else {
       
   276 				this.select( event );
       
   277 			}
       
   278 		}
       
   279 	},
       
   280 
       
   281 	refresh: function() {
       
   282 		var menus,
       
   283 			icon = this.options.icons.submenu,
       
   284 			submenus = this.element.find( this.options.menus );
       
   285 
       
   286 		// Initialize nested menus
       
   287 		submenus.filter( ":not(.ui-menu)" )
       
   288 			.addClass( "ui-menu ui-widget ui-widget-content ui-corner-all" )
       
   289 			.hide()
       
   290 			.attr({
       
   291 				role: this.options.role,
       
   292 				"aria-hidden": "true",
       
   293 				"aria-expanded": "false"
       
   294 			})
       
   295 			.each(function() {
       
   296 				var menu = $( this ),
       
   297 					item = menu.prev( "a" ),
       
   298 					submenuCarat = $( "<span>" )
       
   299 						.addClass( "ui-menu-icon ui-icon " + icon )
       
   300 						.data( "ui-menu-submenu-carat", true );
       
   301 
       
   302 				item
       
   303 					.attr( "aria-haspopup", "true" )
       
   304 					.prepend( submenuCarat );
       
   305 				menu.attr( "aria-labelledby", item.attr( "id" ) );
       
   306 			});
       
   307 
       
   308 		menus = submenus.add( this.element );
       
   309 
       
   310 		// Don't refresh list items that are already adapted
       
   311 		menus.children( ":not(.ui-menu-item):has(a)" )
       
   312 			.addClass( "ui-menu-item" )
       
   313 			.attr( "role", "presentation" )
       
   314 			.children( "a" )
       
   315 				.uniqueId()
       
   316 				.addClass( "ui-corner-all" )
       
   317 				.attr({
       
   318 					tabIndex: -1,
       
   319 					role: this._itemRole()
       
   320 				});
       
   321 
       
   322 		// Initialize unlinked menu-items containing spaces and/or dashes only as dividers
       
   323 		menus.children( ":not(.ui-menu-item)" ).each(function() {
       
   324 			var item = $( this );
       
   325 			// hyphen, em dash, en dash
       
   326 			if ( !/[^\-\u2014\u2013\s]/.test( item.text() ) ) {
       
   327 				item.addClass( "ui-widget-content ui-menu-divider" );
       
   328 			}
       
   329 		});
       
   330 
       
   331 		// Add aria-disabled attribute to any disabled menu item
       
   332 		menus.children( ".ui-state-disabled" ).attr( "aria-disabled", "true" );
       
   333 
       
   334 		// If the active item has been removed, blur the menu
       
   335 		if ( this.active && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) {
       
   336 			this.blur();
       
   337 		}
       
   338 	},
       
   339 
       
   340 	_itemRole: function() {
       
   341 		return {
       
   342 			menu: "menuitem",
       
   343 			listbox: "option"
       
   344 		}[ this.options.role ];
       
   345 	},
       
   346 
       
   347 	_setOption: function( key, value ) {
       
   348 		if ( key === "icons" ) {
       
   349 			this.element.find( ".ui-menu-icon" )
       
   350 				.removeClass( this.options.icons.submenu )
       
   351 				.addClass( value.submenu );
       
   352 		}
       
   353 		this._super( key, value );
       
   354 	},
       
   355 
       
   356 	focus: function( event, item ) {
       
   357 		var nested, focused;
       
   358 		this.blur( event, event && event.type === "focus" );
       
   359 
       
   360 		this._scrollIntoView( item );
       
   361 
       
   362 		this.active = item.first();
       
   363 		focused = this.active.children( "a" ).addClass( "ui-state-focus" );
       
   364 		// Only update aria-activedescendant if there's a role
       
   365 		// otherwise we assume focus is managed elsewhere
       
   366 		if ( this.options.role ) {
       
   367 			this.element.attr( "aria-activedescendant", focused.attr( "id" ) );
       
   368 		}
       
   369 
       
   370 		// Highlight active parent menu item, if any
       
   371 		this.active
       
   372 			.parent()
       
   373 			.closest( ".ui-menu-item" )
       
   374 			.children( "a:first" )
       
   375 			.addClass( "ui-state-active" );
       
   376 
       
   377 		if ( event && event.type === "keydown" ) {
       
   378 			this._close();
       
   379 		} else {
       
   380 			this.timer = this._delay(function() {
       
   381 				this._close();
       
   382 			}, this.delay );
       
   383 		}
       
   384 
       
   385 		nested = item.children( ".ui-menu" );
       
   386 		if ( nested.length && ( /^mouse/.test( event.type ) ) ) {
       
   387 			this._startOpening(nested);
       
   388 		}
       
   389 		this.activeMenu = item.parent();
       
   390 
       
   391 		this._trigger( "focus", event, { item: item } );
       
   392 	},
       
   393 
       
   394 	_scrollIntoView: function( item ) {
       
   395 		var borderTop, paddingTop, offset, scroll, elementHeight, itemHeight;
       
   396 		if ( this._hasScroll() ) {
       
   397 			borderTop = parseFloat( $.css( this.activeMenu[0], "borderTopWidth" ) ) || 0;
       
   398 			paddingTop = parseFloat( $.css( this.activeMenu[0], "paddingTop" ) ) || 0;
       
   399 			offset = item.offset().top - this.activeMenu.offset().top - borderTop - paddingTop;
       
   400 			scroll = this.activeMenu.scrollTop();
       
   401 			elementHeight = this.activeMenu.height();
       
   402 			itemHeight = item.height();
       
   403 
       
   404 			if ( offset < 0 ) {
       
   405 				this.activeMenu.scrollTop( scroll + offset );
       
   406 			} else if ( offset + itemHeight > elementHeight ) {
       
   407 				this.activeMenu.scrollTop( scroll + offset - elementHeight + itemHeight );
       
   408 			}
       
   409 		}
       
   410 	},
       
   411 
       
   412 	blur: function( event, fromFocus ) {
       
   413 		if ( !fromFocus ) {
       
   414 			clearTimeout( this.timer );
       
   415 		}
       
   416 
       
   417 		if ( !this.active ) {
       
   418 			return;
       
   419 		}
       
   420 
       
   421 		this.active.children( "a" ).removeClass( "ui-state-focus" );
       
   422 		this.active = null;
       
   423 
       
   424 		this._trigger( "blur", event, { item: this.active } );
       
   425 	},
       
   426 
       
   427 	_startOpening: function( submenu ) {
       
   428 		clearTimeout( this.timer );
       
   429 
       
   430 		// Don't open if already open fixes a Firefox bug that caused a .5 pixel
       
   431 		// shift in the submenu position when mousing over the carat icon
       
   432 		if ( submenu.attr( "aria-hidden" ) !== "true" ) {
       
   433 			return;
       
   434 		}
       
   435 
       
   436 		this.timer = this._delay(function() {
       
   437 			this._close();
       
   438 			this._open( submenu );
       
   439 		}, this.delay );
       
   440 	},
       
   441 
       
   442 	_open: function( submenu ) {
       
   443 		var position = $.extend({
       
   444 			of: this.active
       
   445 		}, this.options.position );
       
   446 
       
   447 		clearTimeout( this.timer );
       
   448 		this.element.find( ".ui-menu" ).not( submenu.parents( ".ui-menu" ) )
       
   449 			.hide()
       
   450 			.attr( "aria-hidden", "true" );
       
   451 
       
   452 		submenu
       
   453 			.show()
       
   454 			.removeAttr( "aria-hidden" )
       
   455 			.attr( "aria-expanded", "true" )
       
   456 			.position( position );
       
   457 	},
       
   458 
       
   459 	collapseAll: function( event, all ) {
       
   460 		clearTimeout( this.timer );
       
   461 		this.timer = this._delay(function() {
       
   462 			// If we were passed an event, look for the submenu that contains the event
       
   463 			var currentMenu = all ? this.element :
       
   464 				$( event && event.target ).closest( this.element.find( ".ui-menu" ) );
       
   465 
       
   466 			// If we found no valid submenu ancestor, use the main menu to close all sub menus anyway
       
   467 			if ( !currentMenu.length ) {
       
   468 				currentMenu = this.element;
       
   469 			}
       
   470 
       
   471 			this._close( currentMenu );
       
   472 
       
   473 			this.blur( event );
       
   474 			this.activeMenu = currentMenu;
       
   475 		}, this.delay );
       
   476 	},
       
   477 
       
   478 	// With no arguments, closes the currently active menu - if nothing is active
       
   479 	// it closes all menus.  If passed an argument, it will search for menus BELOW
       
   480 	_close: function( startMenu ) {
       
   481 		if ( !startMenu ) {
       
   482 			startMenu = this.active ? this.active.parent() : this.element;
       
   483 		}
       
   484 
       
   485 		startMenu
       
   486 			.find( ".ui-menu" )
       
   487 				.hide()
       
   488 				.attr( "aria-hidden", "true" )
       
   489 				.attr( "aria-expanded", "false" )
       
   490 			.end()
       
   491 			.find( "a.ui-state-active" )
       
   492 				.removeClass( "ui-state-active" );
       
   493 	},
       
   494 
       
   495 	collapse: function( event ) {
       
   496 		var newItem = this.active &&
       
   497 			this.active.parent().closest( ".ui-menu-item", this.element );
       
   498 		if ( newItem && newItem.length ) {
       
   499 			this._close();
       
   500 			this.focus( event, newItem );
       
   501 		}
       
   502 	},
       
   503 
       
   504 	expand: function( event ) {
       
   505 		var newItem = this.active &&
       
   506 			this.active
       
   507 				.children( ".ui-menu " )
       
   508 				.children( ".ui-menu-item" )
       
   509 				.first();
       
   510 
       
   511 		if ( newItem && newItem.length ) {
       
   512 			this._open( newItem.parent() );
       
   513 
       
   514 			// Delay so Firefox will not hide activedescendant change in expanding submenu from AT
       
   515 			this._delay(function() {
       
   516 				this.focus( event, newItem );
       
   517 			});
       
   518 		}
       
   519 	},
       
   520 
       
   521 	next: function( event ) {
       
   522 		this._move( "next", "first", event );
       
   523 	},
       
   524 
       
   525 	previous: function( event ) {
       
   526 		this._move( "prev", "last", event );
       
   527 	},
       
   528 
       
   529 	isFirstItem: function() {
       
   530 		return this.active && !this.active.prevAll( ".ui-menu-item" ).length;
       
   531 	},
       
   532 
       
   533 	isLastItem: function() {
       
   534 		return this.active && !this.active.nextAll( ".ui-menu-item" ).length;
       
   535 	},
       
   536 
       
   537 	_move: function( direction, filter, event ) {
       
   538 		var next;
       
   539 		if ( this.active ) {
       
   540 			if ( direction === "first" || direction === "last" ) {
       
   541 				next = this.active
       
   542 					[ direction === "first" ? "prevAll" : "nextAll" ]( ".ui-menu-item" )
       
   543 					.eq( -1 );
       
   544 			} else {
       
   545 				next = this.active
       
   546 					[ direction + "All" ]( ".ui-menu-item" )
       
   547 					.eq( 0 );
       
   548 			}
       
   549 		}
       
   550 		if ( !next || !next.length || !this.active ) {
       
   551 			next = this.activeMenu.children( ".ui-menu-item" )[ filter ]();
       
   552 		}
       
   553 
       
   554 		this.focus( event, next );
       
   555 	},
       
   556 
       
   557 	nextPage: function( event ) {
       
   558 		var item, base, height;
       
   559 
       
   560 		if ( !this.active ) {
       
   561 			this.next( event );
       
   562 			return;
       
   563 		}
       
   564 		if ( this.isLastItem() ) {
       
   565 			return;
       
   566 		}
       
   567 		if ( this._hasScroll() ) {
       
   568 			base = this.active.offset().top;
       
   569 			height = this.element.height();
       
   570 			this.active.nextAll( ".ui-menu-item" ).each(function() {
       
   571 				item = $( this );
       
   572 				return item.offset().top - base - height < 0;
       
   573 			});
       
   574 
       
   575 			this.focus( event, item );
       
   576 		} else {
       
   577 			this.focus( event, this.activeMenu.children( ".ui-menu-item" )
       
   578 				[ !this.active ? "first" : "last" ]() );
       
   579 		}
       
   580 	},
       
   581 
       
   582 	previousPage: function( event ) {
       
   583 		var item, base, height;
       
   584 		if ( !this.active ) {
       
   585 			this.next( event );
       
   586 			return;
       
   587 		}
       
   588 		if ( this.isFirstItem() ) {
       
   589 			return;
       
   590 		}
       
   591 		if ( this._hasScroll() ) {
       
   592 			base = this.active.offset().top;
       
   593 			height = this.element.height();
       
   594 			this.active.prevAll( ".ui-menu-item" ).each(function() {
       
   595 				item = $( this );
       
   596 				return item.offset().top - base + height > 0;
       
   597 			});
       
   598 
       
   599 			this.focus( event, item );
       
   600 		} else {
       
   601 			this.focus( event, this.activeMenu.children( ".ui-menu-item" ).first() );
       
   602 		}
       
   603 	},
       
   604 
       
   605 	_hasScroll: function() {
       
   606 		return this.element.outerHeight() < this.element.prop( "scrollHeight" );
       
   607 	},
       
   608 
       
   609 	select: function( event ) {
       
   610 		// TODO: It should never be possible to not have an active item at this
       
   611 		// point, but the tests don't trigger mouseenter before click.
       
   612 		this.active = this.active || $( event.target ).closest( ".ui-menu-item" );
       
   613 		var ui = { item: this.active };
       
   614 		if ( !this.active.has( ".ui-menu" ).length ) {
       
   615 			this.collapseAll( event, true );
       
   616 		}
       
   617 		this._trigger( "select", event, ui );
       
   618 	}
       
   619 });
       
   620 
       
   621 }( jQuery ));