3 Clazz.declarePackage ("swingjs.jquery");
4 c$ = Clazz.declareType (swingjs.jquery, "JQuery_UI_Core2");
5 Clazz.makeConstructor (c$,
11 // menu button autocomplete
17 * jQuery UI Menu 1.10.4
20 * Copyright 2014 jQuery Foundation and other contributors
21 * Released under the MIT license.
22 * http://jquery.org/license
24 * http://api.jqueryui.com/menu/
29 * jquery.ui.position.js
31 (function( $, undefined ) {
33 $.widget( "ui.menu", {
35 defaultElement: "<ul>",
39 submenu: "ui-icon-carat-1-e"
55 this.activeMenu = this.element;
56 // flag used to prevent firing of the click handler
57 // as the event bubbles up through nested menus
58 this.mouseHandled = false;
61 .addClass( "ui-menu ui-widget ui-widget-content ui-corner-all" )
62 .toggleClass( "ui-menu-icons", !!this.element.find( ".ui-icon" ).length )
64 role: this.options.role,
67 // need to catch all clicks on disabled menu
68 // not possible through _on
69 .bind( "click" + this.eventNamespace, $.proxy(function( event ) {
70 if ( this.options.disabled ) {
71 event.preventDefault();
75 if ( this.options.disabled ) {
77 .addClass( "ui-state-disabled" )
78 .attr( "aria-disabled", "true" );
82 // Prevent focus from sticking to links inside menu after clicking
83 // them (focus should always stay on UL during navigation).
84 "mousedown .ui-menu-item > a": function( event ) {
85 event.preventDefault();
87 "click .ui-state-disabled > a": function( event ) {
88 event.preventDefault();
90 "click .ui-menu-item:has(a)": function( event ) {
91 var target = $( event.target ).closest( ".ui-menu-item" );
92 if ( !this.mouseHandled && target.not( ".ui-state-disabled" ).length ) {
95 // Only set the mouseHandled flag if the event will bubble, see #9469.
96 if ( !event.isPropagationStopped() ) {
97 this.mouseHandled = true;
100 // Open submenu on click
101 if ( target.has( ".ui-menu" ).length ) {
102 this.expand( event );
103 } else if ( !this.element.is( ":focus" ) && $( this.document[ 0 ].activeElement ).closest( ".ui-menu" ).length ) {
105 // Redirect focus to the menu
106 this.element.trigger( "focus", [ true ] );
108 // If the active item is on the top level, let it stay active.
109 // Otherwise, blur the active item since it is no longer visible.
110 if ( this.active && this.active.parents( ".ui-menu" ).length === 1 ) {
111 clearTimeout( this.timer );
116 "mouseenter .ui-menu-item": function( event ) {
117 var target = $( event.currentTarget );
118 // Remove ui-state-active class from siblings of the newly focused menu item
119 // to avoid a jump caused by adjacent elements both having a class with a border
120 target.siblings().children( ".ui-state-active" ).removeClass( "ui-state-active" );
121 this.focus( event, target );
123 mouseleave: "collapseAll",
124 "mouseleave .ui-menu": "collapseAll",
125 focus: function( event, keepActiveItem ) {
126 // If there's already an active item, keep it active
127 // If not, activate the first item
128 var item = this.active || this.element.children( ".ui-menu-item" ).eq( 0 );
130 if ( !keepActiveItem ) {
131 this.focus( event, item );
134 blur: function( event ) {
135 this._delay(function() {
136 if ( !$.contains( this.element[0], this.document[0].activeElement ) ) {
137 this.collapseAll( event );
146 // Clicks outside of a menu collapse any open menus
147 this._on( this.document, {
148 click: function( event ) {
149 if ( !$( event.target ).closest( ".ui-menu" ).length ) {
150 this.collapseAll( event );
153 // Reset the mouseHandled flag
154 this.mouseHandled = false;
159 _destroy: function() {
160 // Destroy (sub)menus
162 .removeAttr( "aria-activedescendant" )
163 .find( ".ui-menu" ).addBack()
164 .removeClass( "ui-menu ui-widget ui-widget-content ui-corner-all ui-menu-icons" )
165 .removeAttr( "role" )
166 .removeAttr( "tabIndex" )
167 .removeAttr( "aria-labelledby" )
168 .removeAttr( "aria-expanded" )
169 .removeAttr( "aria-hidden" )
170 .removeAttr( "aria-disabled" )
174 // Destroy menu items
175 this.element.find( ".ui-menu-item" )
176 .removeClass( "ui-menu-item" )
177 .removeAttr( "role" )
178 .removeAttr( "aria-disabled" )
181 .removeClass( "ui-corner-all ui-state-hover" )
182 .removeAttr( "tabIndex" )
183 .removeAttr( "role" )
184 .removeAttr( "aria-haspopup" )
185 .children().each( function() {
186 var elem = $( this );
187 if ( elem.data( "ui-menu-submenu-carat" ) ) {
192 // Destroy menu dividers
193 this.element.find( ".ui-menu-divider" ).removeClass( "ui-menu-divider ui-widget-content" );
196 _keydown: function( event ) {
197 var match, prev, character, skip, regex,
198 preventDefault = true;
200 function escape( value ) {
201 return value.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" );
204 switch ( event.keyCode ) {
205 case $.ui.keyCode.PAGE_UP:
206 this.previousPage( event );
208 case $.ui.keyCode.PAGE_DOWN:
209 this.nextPage( event );
211 case $.ui.keyCode.HOME:
212 this._move( "first", "first", event );
214 case $.ui.keyCode.END:
215 this._move( "last", "last", event );
217 case $.ui.keyCode.UP:
218 this.previous( event );
220 case $.ui.keyCode.DOWN:
223 case $.ui.keyCode.LEFT:
224 this.collapse( event );
226 case $.ui.keyCode.RIGHT:
227 if ( this.active && !this.active.is( ".ui-state-disabled" ) ) {
228 this.expand( event );
231 case $.ui.keyCode.ENTER:
232 case $.ui.keyCode.SPACE:
233 this._activate( event );
235 case $.ui.keyCode.ESCAPE:
236 this.collapse( event );
239 preventDefault = false;
240 prev = this.previousFilter || "";
241 character = String.fromCharCode( event.keyCode );
244 clearTimeout( this.filterTimer );
246 if ( character === prev ) {
249 character = prev + character;
252 regex = new RegExp( "^" + escape( character ), "i" );
253 match = this.activeMenu.children( ".ui-menu-item" ).filter(function() {
254 return regex.test( $( this ).children( "a" ).text() );
256 match = skip && match.index( this.active.next() ) !== -1 ?
257 this.active.nextAll( ".ui-menu-item" ) :
260 // If no matches on the current filter, reset to the last character pressed
261 // to move down the menu to the first item that starts with that character
262 if ( !match.length ) {
263 character = String.fromCharCode( event.keyCode );
264 regex = new RegExp( "^" + escape( character ), "i" );
265 match = this.activeMenu.children( ".ui-menu-item" ).filter(function() {
266 return regex.test( $( this ).children( "a" ).text() );
270 if ( match.length ) {
271 this.focus( event, match );
272 if ( match.length > 1 ) {
273 this.previousFilter = character;
274 this.filterTimer = this._delay(function() {
275 delete this.previousFilter;
278 delete this.previousFilter;
281 delete this.previousFilter;
285 if ( preventDefault ) {
286 event.preventDefault();
290 _activate: function( event ) {
291 if ( !this.active.is( ".ui-state-disabled" ) ) {
292 if ( this.active.children( "a[aria-haspopup='true']" ).length ) {
293 this.expand( event );
295 this.select( event );
300 refresh: function() {
302 icon = this.options.icons.submenu,
303 submenus = this.element.find( this.options.menus );
305 this.element.toggleClass( "ui-menu-icons", !!this.element.find( ".ui-icon" ).length );
307 // Initialize nested menus
308 submenus.filter( ":not(.ui-menu)" )
309 .addClass( "ui-menu ui-widget ui-widget-content ui-corner-all" )
312 role: this.options.role,
313 "aria-hidden": "true",
314 "aria-expanded": "false"
317 var menu = $( this ),
318 item = menu.prev( "a" ),
319 submenuCarat = $( "<span>" )
320 .addClass( "ui-menu-icon ui-icon " + icon )
321 .data( "ui-menu-submenu-carat", true );
324 .attr( "aria-haspopup", "true" )
325 .prepend( submenuCarat );
326 menu.attr( "aria-labelledby", item.attr( "id" ) );
329 menus = submenus.add( this.element );
331 // Don't refresh list items that are already adapted
332 menus.children( ":not(.ui-menu-item):has(a)" )
333 .addClass( "ui-menu-item" )
334 .attr( "role", "presentation" )
337 .addClass( "ui-corner-all" )
340 role: this._itemRole()
343 // Initialize unlinked menu-items containing spaces and/or dashes only as dividers
344 menus.children( ":not(.ui-menu-item)" ).each(function() {
345 var item = $( this );
346 // hyphen, em dash, en dash
347 if ( !/[^\-\u2014\u2013\s]/.test( item.text() ) ) {
348 item.addClass( "ui-widget-content ui-menu-divider" );
352 // Add aria-disabled attribute to any disabled menu item
353 menus.children( ".ui-state-disabled" ).attr( "aria-disabled", "true" );
355 // If the active item has been removed, blur the menu
356 if ( this.active && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) {
361 _itemRole: function() {
365 }[ this.options.role ];
368 _setOption: function( key, value ) {
369 if ( key === "icons" ) {
370 this.element.find( ".ui-menu-icon" )
371 .removeClass( this.options.icons.submenu )
372 .addClass( value.submenu );
374 this._super( key, value );
377 focus: function( event, item ) {
379 this.blur( event, event && event.type === "focus" );
381 this._scrollIntoView( item );
383 this.active = item.first();
384 focused = this.active.children( "a" ).addClass( "ui-state-focus" );
385 // Only update aria-activedescendant if there's a role
386 // otherwise we assume focus is managed elsewhere
387 if ( this.options.role ) {
388 this.element.attr( "aria-activedescendant", focused.attr( "id" ) );
391 // Highlight active parent menu item, if any
394 .closest( ".ui-menu-item" )
395 .children( "a:first" )
396 .addClass( "ui-state-active" );
398 if ( event && event.type === "keydown" ) {
401 this.timer = this._delay(function() {
406 nested = item.children( ".ui-menu" );
407 if ( nested.length && event && ( /^mouse/.test( event.type ) ) ) {
408 this._startOpening(nested);
410 this.activeMenu = item.parent();
412 this._trigger( "focus", event, { item: item } );
415 _scrollIntoView: function( item ) {
416 var borderTop, paddingTop, offset, scroll, elementHeight, itemHeight;
417 if ( this._hasScroll() ) {
418 borderTop = parseFloat( $.css( this.activeMenu[0], "borderTopWidth" ) ) || 0;
419 paddingTop = parseFloat( $.css( this.activeMenu[0], "paddingTop" ) ) || 0;
420 offset = item.offset().top - this.activeMenu.offset().top - borderTop - paddingTop;
421 scroll = this.activeMenu.scrollTop();
422 elementHeight = this.activeMenu.height();
423 itemHeight = item.height();
426 this.activeMenu.scrollTop( scroll + offset );
427 } else if ( offset + itemHeight > elementHeight ) {
428 this.activeMenu.scrollTop( scroll + offset - elementHeight + itemHeight );
433 blur: function( event, fromFocus ) {
435 clearTimeout( this.timer );
438 if ( !this.active ) {
442 this.active.children( "a" ).removeClass( "ui-state-focus" );
445 this._trigger( "blur", event, { item: this.active } );
448 _startOpening: function( submenu ) {
449 clearTimeout( this.timer );
451 // Don't open if already open fixes a Firefox bug that caused a .5 pixel
452 // shift in the submenu position when mousing over the carat icon
453 if ( submenu.attr( "aria-hidden" ) !== "true" ) {
457 this.timer = this._delay(function() {
459 this._open( submenu );
463 _open: function( submenu ) {
464 var position = $.extend({
466 }, this.options.position );
468 clearTimeout( this.timer );
469 this.element.find( ".ui-menu" ).not( submenu.parents( ".ui-menu" ) )
471 .attr( "aria-hidden", "true" );
475 .removeAttr( "aria-hidden" )
476 .attr( "aria-expanded", "true" )
477 .position( position );
480 collapseAll: function( event, all ) {
481 clearTimeout( this.timer );
482 this.timer = this._delay(function() {
483 // If we were passed an event, look for the submenu that contains the event
484 var currentMenu = all ? this.element :
485 $( event && event.target ).closest( this.element.find( ".ui-menu" ) );
487 // If we found no valid submenu ancestor, use the main menu to close all sub menus anyway
488 if ( !currentMenu.length ) {
489 currentMenu = this.element;
492 this._close( currentMenu );
495 this.activeMenu = currentMenu;
499 // With no arguments, closes the currently active menu - if nothing is active
500 // it closes all menus. If passed an argument, it will search for menus BELOW
501 _close: function( startMenu ) {
503 startMenu = this.active ? this.active.parent() : this.element;
509 .attr( "aria-hidden", "true" )
510 .attr( "aria-expanded", "false" )
512 .find( "a.ui-state-active" )
513 .removeClass( "ui-state-active" );
516 collapse: function( event ) {
517 var newItem = this.active &&
518 this.active.parent().closest( ".ui-menu-item", this.element );
519 if ( newItem && newItem.length ) {
521 this.focus( event, newItem );
525 expand: function( event ) {
526 var newItem = this.active &&
528 .children( ".ui-menu " )
529 .children( ".ui-menu-item" )
532 if ( newItem && newItem.length ) {
533 this._open( newItem.parent() );
535 // Delay so Firefox will not hide activedescendant change in expanding submenu from AT
536 this._delay(function() {
537 this.focus( event, newItem );
542 next: function( event ) {
543 this._move( "next", "first", event );
546 previous: function( event ) {
547 this._move( "prev", "last", event );
550 isFirstItem: function() {
551 return this.active && !this.active.prevAll( ".ui-menu-item" ).length;
554 isLastItem: function() {
555 return this.active && !this.active.nextAll( ".ui-menu-item" ).length;
558 _move: function( direction, filter, event ) {
561 if ( direction === "first" || direction === "last" ) {
563 [ direction === "first" ? "prevAll" : "nextAll" ]( ".ui-menu-item" )
567 [ direction + "All" ]( ".ui-menu-item" )
571 if ( !next || !next.length || !this.active ) {
572 next = this.activeMenu.children( ".ui-menu-item" )[ filter ]();
575 this.focus( event, next );
578 nextPage: function( event ) {
579 var item, base, height;
581 if ( !this.active ) {
585 if ( this.isLastItem() ) {
588 if ( this._hasScroll() ) {
589 base = this.active.offset().top;
590 height = this.element.height();
591 this.active.nextAll( ".ui-menu-item" ).each(function() {
593 return item.offset().top - base - height < 0;
596 this.focus( event, item );
598 this.focus( event, this.activeMenu.children( ".ui-menu-item" )
599 [ !this.active ? "first" : "last" ]() );
603 previousPage: function( event ) {
604 var item, base, height;
605 if ( !this.active ) {
609 if ( this.isFirstItem() ) {
612 if ( this._hasScroll() ) {
613 base = this.active.offset().top;
614 height = this.element.height();
615 this.active.prevAll( ".ui-menu-item" ).each(function() {
617 return item.offset().top - base + height > 0;
620 this.focus( event, item );
622 this.focus( event, this.activeMenu.children( ".ui-menu-item" ).first() );
626 _hasScroll: function() {
627 return this.element.outerHeight() < this.element.prop( "scrollHeight" );
630 select: function( event ) {
631 // TODO: It should never be possible to not have an active item at this
632 // point, but the tests don't trigger mouseenter before click.
633 this.active = this.active || $( event.target ).closest( ".ui-menu-item" );
634 var ui = { item: this.active };
635 if ( !this.active.has( ".ui-menu" ).length ) {
636 this.collapseAll( event, true );
638 this._trigger( "select", event, ui );
646 System.out.println("coremenu failed to load jQuery.ui.menu -- jQuery version conflict?");
649 if (!jQuery.ui.button)
653 * jQuery UI Button 1.10.4
654 * http://jqueryui.com
656 * Copyright 2014 jQuery Foundation and other contributors
657 * Released under the MIT license.
658 * http://jquery.org/license
660 * http://api.jqueryui.com/button/
664 * jquery.ui.widget.js
666 (function( $, undefined ) {
669 baseClasses = "ui-button ui-widget ui-state-default ui-corner-all",
670 typeClasses = "ui-button-icons-only ui-button-icon-only ui-button-text-icons ui-button-text-icon-primary ui-button-text-icon-secondary ui-button-text-only",
671 formResetHandler = function() {
672 var form = $( this );
673 setTimeout(function() {
674 form.find( ":ui-button" ).button( "refresh" );
677 radioGroup = function( radio ) {
678 var name = radio.name,
682 name = name.replace( /'/g, "\\'" );
684 radios = $( form ).find( "[name='" + name + "']" );
686 radios = $( "[name='" + name + "']", radio.ownerDocument )
695 $.widget( "ui.button", {
697 defaultElement: "<button>",
707 _create: function() {
708 this.element.closest( "form" )
709 .unbind( "reset" + this.eventNamespace )
710 .bind( "reset" + this.eventNamespace, formResetHandler );
712 if ( typeof this.options.disabled !== "boolean" ) {
713 this.options.disabled = !!this.element.prop( "disabled" );
715 this.element.prop( "disabled", this.options.disabled );
718 this._determineButtonType();
719 this.hasTitle = !!this.buttonElement.attr( "title" );
722 options = this.options,
723 toggleButton = this.type === "checkbox" || this.type === "radio",
724 activeClass = !toggleButton ? "ui-state-active" : "";
726 if ( options.label === null ) {
727 options.label = (this.type === "input" ? this.buttonElement.val() : this.buttonElement.html());
730 this._hoverable( this.buttonElement );
733 .addClass( baseClasses )
734 .attr( "role", "button" )
735 .bind( "mouseenter" + this.eventNamespace, function() {
736 if ( options.disabled ) {
739 if ( this === lastActive ) {
740 $( this ).addClass( "ui-state-active" );
743 .bind( "mouseleave" + this.eventNamespace, function() {
744 if ( options.disabled ) {
747 $( this ).removeClass( activeClass );
749 .bind( "click" + this.eventNamespace, function( event ) {
750 if ( options.disabled ) {
751 event.preventDefault();
752 event.stopImmediatePropagation();
756 // Can't use _focusable() because the element that receives focus
757 // and the element that gets the ui-state-focus class are different
760 this.buttonElement.addClass( "ui-state-focus" );
763 this.buttonElement.removeClass( "ui-state-focus" );
767 if ( toggleButton ) {
768 this.element.bind( "change" + this.eventNamespace, function() {
773 if ( this.type === "checkbox" ) {
774 this.buttonElement.bind( "click" + this.eventNamespace, function() {
775 if ( options.disabled ) {
779 } else if ( this.type === "radio" ) {
780 this.buttonElement.bind( "click" + this.eventNamespace, function() {
781 if ( options.disabled ) {
784 $( this ).addClass( "ui-state-active" );
785 that.buttonElement.attr( "aria-pressed", "true" );
787 var radio = that.element[ 0 ];
791 return $( this ).button( "widget" )[ 0 ];
793 .removeClass( "ui-state-active" )
794 .attr( "aria-pressed", "false" );
798 .bind( "mousedown" + this.eventNamespace, function() {
799 if ( options.disabled ) {
802 $( this ).addClass( "ui-state-active" );
804 that.document.one( "mouseup", function() {
808 .bind( "mouseup" + this.eventNamespace, function() {
809 if ( options.disabled ) {
812 $( this ).removeClass( "ui-state-active" );
814 .bind( "keydown" + this.eventNamespace, function(event) {
815 if ( options.disabled ) {
818 if ( event.keyCode === $.ui.keyCode.SPACE || event.keyCode === $.ui.keyCode.ENTER ) {
819 $( this ).addClass( "ui-state-active" );
822 // see #8559, we bind to blur here in case the button element loses
823 // focus between keydown and keyup, it would be left in an "active" state
824 .bind( "keyup" + this.eventNamespace + " blur" + this.eventNamespace, function() {
825 $( this ).removeClass( "ui-state-active" );
828 if ( this.buttonElement.is("a") ) {
829 this.buttonElement.keyup(function(event) {
830 if ( event.keyCode === $.ui.keyCode.SPACE ) {
831 // TODO pass through original event correctly (just as 2nd argument doesn't work)
838 // TODO: pull out $.Widget's handling for the disabled option into
839 // $.Widget.prototype._setOptionDisabled so it's easy to proxy and can
840 // be overridden by individual plugins
841 this._setOption( "disabled", options.disabled );
845 _determineButtonType: function() {
846 var ancestor, labelSelector, checked;
848 if ( this.element.is("[type=checkbox]") ) {
849 this.type = "checkbox";
850 } else if ( this.element.is("[type=radio]") ) {
852 } else if ( this.element.is("input") ) {
855 this.type = "button";
858 if ( this.type === "checkbox" || this.type === "radio" ) {
859 // we don't search against the document in case the element
860 // is disconnected from the DOM
861 ancestor = this.element.parents().last();
862 labelSelector = "label[for='" + this.element.attr("id") + "']";
863 this.buttonElement = ancestor.find( labelSelector );
864 if ( !this.buttonElement.length ) {
865 ancestor = ancestor.length ? ancestor.siblings() : this.element.siblings();
866 this.buttonElement = ancestor.filter( labelSelector );
867 if ( !this.buttonElement.length ) {
868 this.buttonElement = ancestor.find( labelSelector );
871 this.element.addClass( "ui-helper-hidden-accessible" );
873 checked = this.element.is( ":checked" );
875 this.buttonElement.addClass( "ui-state-active" );
877 this.buttonElement.prop( "aria-pressed", checked );
879 this.buttonElement = this.element;
884 return this.buttonElement;
887 _destroy: function() {
889 .removeClass( "ui-helper-hidden-accessible" );
891 .removeClass( baseClasses + " ui-state-active " + typeClasses )
892 .removeAttr( "role" )
893 .removeAttr( "aria-pressed" )
894 .html( this.buttonElement.find(".ui-button-text").html() );
896 if ( !this.hasTitle ) {
897 this.buttonElement.removeAttr( "title" );
901 _setOption: function( key, value ) {
902 this._super( key, value );
903 if ( key === "disabled" ) {
904 this.element.prop( "disabled", !!value );
906 this.buttonElement.removeClass( "ui-state-focus" );
913 refresh: function() {
915 var isDisabled = this.element.is( "input, button" ) ? this.element.is( ":disabled" ) : this.element.hasClass( "ui-button-disabled" );
917 if ( isDisabled !== this.options.disabled ) {
918 this._setOption( "disabled", isDisabled );
920 if ( this.type === "radio" ) {
921 radioGroup( this.element[0] ).each(function() {
922 if ( $( this ).is( ":checked" ) ) {
923 $( this ).button( "widget" )
924 .addClass( "ui-state-active" )
925 .attr( "aria-pressed", "true" );
927 $( this ).button( "widget" )
928 .removeClass( "ui-state-active" )
929 .attr( "aria-pressed", "false" );
932 } else if ( this.type === "checkbox" ) {
933 if ( this.element.is( ":checked" ) ) {
935 .addClass( "ui-state-active" )
936 .attr( "aria-pressed", "true" );
939 .removeClass( "ui-state-active" )
940 .attr( "aria-pressed", "false" );
945 _resetButton: function() {
946 if ( this.type === "input" ) {
947 if ( this.options.label ) {
948 this.element.val( this.options.label );
952 var buttonElement = this.buttonElement.removeClass( typeClasses ),
953 buttonText = $( "<span></span>", this.document[0] )
954 .addClass( "ui-button-text" )
955 .html( this.options.label )
956 .appendTo( buttonElement.empty() )
958 icons = this.options.icons,
959 multipleIcons = icons.primary && icons.secondary,
962 if ( icons.primary || icons.secondary ) {
963 if ( this.options.text ) {
964 buttonClasses.push( "ui-button-text-icon" + ( multipleIcons ? "s" : ( icons.primary ? "-primary" : "-secondary" ) ) );
967 if ( icons.primary ) {
968 buttonElement.prepend( "<span class='ui-button-icon-primary ui-icon " + icons.primary + "'></span>" );
971 if ( icons.secondary ) {
972 buttonElement.append( "<span class='ui-button-icon-secondary ui-icon " + icons.secondary + "'></span>" );
975 if ( !this.options.text ) {
976 buttonClasses.push( multipleIcons ? "ui-button-icons-only" : "ui-button-icon-only" );
978 if ( !this.hasTitle ) {
979 buttonElement.attr( "title", $.trim( buttonText ) );
983 buttonClasses.push( "ui-button-text-only" );
985 buttonElement.addClass( buttonClasses.join( " " ) );
989 $.widget( "ui.buttonset", {
992 items: "button, input[type=button], input[type=submit], input[type=reset], input[type=checkbox], input[type=radio], a, :data(ui-button)"
995 _create: function() {
996 this.element.addClass( "ui-buttonset" );
1003 _setOption: function( key, value ) {
1004 if ( key === "disabled" ) {
1005 this.buttons.button( "option", key, value );
1008 this._super( key, value );
1011 refresh: function() {
1012 var rtl = this.element.css( "direction" ) === "rtl";
1014 this.buttons = this.element.find( this.options.items )
1015 .filter( ":ui-button" )
1016 .button( "refresh" )
1018 .not( ":ui-button" )
1022 return $( this ).button( "widget" )[ 0 ];
1024 .removeClass( "ui-corner-all ui-corner-left ui-corner-right" )
1026 .addClass( rtl ? "ui-corner-right" : "ui-corner-left" )
1029 .addClass( rtl ? "ui-corner-left" : "ui-corner-right" )
1034 _destroy: function() {
1035 this.element.removeClass( "ui-buttonset" );
1038 return $( this ).button( "widget" )[ 0 ];
1040 .removeClass( "ui-corner-left ui-corner-right" )
1042 .button( "destroy" );
1049 System.out.println("coremenu failed to load jQuery.ui.button -- jQuery version conflict?");
1052 if (!jQuery.ui.autocomplete)
1056 * jQuery UI Autocomplete 1.10.4
1057 * http://jqueryui.com
1059 * Copyright 2014 jQuery Foundation and other contributors
1060 * Released under the MIT license.
1061 * http://jquery.org/license
1063 * http://api.jqueryui.com/autocomplete/
1067 * jquery.ui.widget.js
1068 * jquery.ui.position.js
1071 (function( $, undefined ) {
1073 $.widget( "ui.autocomplete", {
1075 defaultElement: "<input>",
1101 _create: function() {
1102 // Some browsers only repeat keydown events, not keypress events,
1103 // so we use the suppressKeyPress flag to determine if we've already
1104 // handled the keydown event. #7269
1105 // Unfortunately the code for & in keypress is the same as the up arrow,
1106 // so we use the suppressKeyPressRepeat flag to avoid handling keypress
1107 // events when we know the keydown event was used to modify the
1108 // search term. #7799
1109 var suppressKeyPress, suppressKeyPressRepeat, suppressInput,
1110 nodeName = this.element[0].nodeName.toLowerCase(),
1111 isTextarea = nodeName === "textarea",
1112 isInput = nodeName === "input";
1115 // Textareas are always multi-line
1117 // Inputs are always single-line, even if inside a contentEditable element
1118 // IE also treats inputs as contentEditable
1120 // All other element types are determined by whether or not they're contentEditable
1121 this.element.prop( "isContentEditable" );
1123 this.valueMethod = this.element[ isTextarea || isInput ? "val" : "text" ];
1124 this.isNewMenu = true;
1127 .addClass( "ui-autocomplete-input" )
1128 .attr( "autocomplete", "off" );
1130 this._on( this.element, {
1131 keydown: function( event ) {
1132 if ( this.element.prop( "readOnly" ) ) {
1133 suppressKeyPress = true;
1134 suppressInput = true;
1135 suppressKeyPressRepeat = true;
1139 suppressKeyPress = false;
1140 suppressInput = false;
1141 suppressKeyPressRepeat = false;
1142 var keyCode = $.ui.keyCode;
1143 switch( event.keyCode ) {
1144 case keyCode.PAGE_UP:
1145 suppressKeyPress = true;
1146 this._move( "previousPage", event );
1148 case keyCode.PAGE_DOWN:
1149 suppressKeyPress = true;
1150 this._move( "nextPage", event );
1153 suppressKeyPress = true;
1154 this._keyEvent( "previous", event );
1157 suppressKeyPress = true;
1158 this._keyEvent( "next", event );
1161 case keyCode.NUMPAD_ENTER:
1162 // when menu is open and has focus
1163 if ( this.menu.active ) {
1164 // #6055 - Opera still allows the keypress to occur
1165 // which causes forms to submit
1166 suppressKeyPress = true;
1167 event.preventDefault();
1168 this.menu.select( event );
1172 if ( this.menu.active ) {
1173 this.menu.select( event );
1176 case keyCode.ESCAPE:
1177 if ( this.menu.element.is( ":visible" ) ) {
1178 this._value( this.term );
1179 this.close( event );
1180 // Different browsers have different default behavior for escape
1181 // Single press can mean undo or clear
1182 // Double press in IE means clear the whole form
1183 event.preventDefault();
1187 suppressKeyPressRepeat = true;
1188 // search timeout should be triggered before the input value is changed
1189 this._searchTimeout( event );
1193 keypress: function( event ) {
1194 if ( suppressKeyPress ) {
1195 suppressKeyPress = false;
1196 if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) {
1197 event.preventDefault();
1201 if ( suppressKeyPressRepeat ) {
1205 // replicate some key handlers to allow them to repeat in Firefox and Opera
1206 var keyCode = $.ui.keyCode;
1207 switch( event.keyCode ) {
1208 case keyCode.PAGE_UP:
1209 this._move( "previousPage", event );
1211 case keyCode.PAGE_DOWN:
1212 this._move( "nextPage", event );
1215 this._keyEvent( "previous", event );
1218 this._keyEvent( "next", event );
1222 input: function( event ) {
1223 if ( suppressInput ) {
1224 suppressInput = false;
1225 event.preventDefault();
1228 this._searchTimeout( event );
1231 this.selectedItem = null;
1232 this.previous = this._value();
1234 blur: function( event ) {
1235 if ( this.cancelBlur ) {
1236 delete this.cancelBlur;
1240 clearTimeout( this.searching );
1241 this.close( event );
1242 this._change( event );
1247 this.menu = $( "<ul>" )
1248 .addClass( "ui-autocomplete ui-front" )
1249 .appendTo( this._appendTo() )
1251 // disable ARIA support, the live region takes care of that
1257 this._on( this.menu.element, {
1258 mousedown: function( event ) {
1259 // prevent moving focus out of the text field
1260 event.preventDefault();
1262 // IE doesn't prevent moving focus even with event.preventDefault()
1263 // so we set a flag to know when we should ignore the blur event
1264 this.cancelBlur = true;
1265 this._delay(function() {
1266 delete this.cancelBlur;
1269 // clicking on the scrollbar causes focus to shift to the body
1270 // but we can't detect a mouseup or a click immediately afterward
1271 // so we have to track the next mousedown and close the menu if
1272 // the user clicks somewhere outside of the autocomplete
1273 var menuElement = this.menu.element[ 0 ];
1274 if ( !$( event.target ).closest( ".ui-menu-item" ).length ) {
1275 this._delay(function() {
1277 this.document.one( "mousedown", function( event ) {
1278 if ( event.target !== that.element[ 0 ] &&
1279 event.target !== menuElement &&
1280 !$.contains( menuElement, event.target ) ) {
1287 menufocus: function( event, ui ) {
1289 // Prevent accidental activation of menu items in Firefox (#7024 #9118)
1290 if ( this.isNewMenu ) {
1291 this.isNewMenu = false;
1292 if ( event.originalEvent && /^mouse/.test( event.originalEvent.type ) ) {
1295 this.document.one( "mousemove", function() {
1296 $( event.target ).trigger( event.originalEvent );
1303 var item = ui.item.data( "ui-autocomplete-item" );
1304 if ( false !== this._trigger( "focus", event, { item: item } ) ) {
1305 // use value to match what will end up in the input, if it was a key event
1306 if ( event.originalEvent && /^key/.test( event.originalEvent.type ) ) {
1307 this._value( item.value );
1310 // Normally the input is populated with the item's value as the
1311 // menu is navigated, causing screen readers to notice a change and
1312 // announce the item. Since the focus event was canceled, this doesn't
1313 // happen, so we update the live region so that screen readers can
1314 // still notice the change and announce it.
1315 this.liveRegion.text( item.value );
1318 menuselect: function( event, ui ) {
1319 var item = ui.item.data( "ui-autocomplete-item" ),
1320 previous = this.previous;
1322 // only trigger when focus was lost (click on menu)
1323 if ( this.element[0] !== this.document[0].activeElement ) {
1324 this.element.focus();
1325 this.previous = previous;
1326 // #6109 - IE triggers two focus events and the second
1327 // is asynchronous, so we need to reset the previous
1328 // term synchronously and asynchronously :-(
1329 this._delay(function() {
1330 this.previous = previous;
1331 this.selectedItem = item;
1335 if ( false !== this._trigger( "select", event, { item: item } ) ) {
1336 this._value( item.value );
1338 // reset the term after the select event
1339 // this allows custom select handling to work properly
1340 this.term = this._value();
1342 this.close( event );
1343 this.selectedItem = item;
1347 this.liveRegion = $( "<span>", {
1349 "aria-live": "polite"
1351 .addClass( "ui-helper-hidden-accessible" )
1352 .insertBefore( this.element );
1354 // turning off autocomplete prevents the browser from remembering the
1355 // value when navigating through history, so we re-enable autocomplete
1356 // if the page is unloaded before the widget is destroyed. #7790
1357 this._on( this.window, {
1358 beforeunload: function() {
1359 this.element.removeAttr( "autocomplete" );
1364 _destroy: function() {
1365 clearTimeout( this.searching );
1367 .removeClass( "ui-autocomplete-input" )
1368 .removeAttr( "autocomplete" );
1369 this.menu.element.remove();
1370 this.liveRegion.remove();
1373 _setOption: function( key, value ) {
1374 this._super( key, value );
1375 if ( key === "source" ) {
1378 if ( key === "appendTo" ) {
1379 this.menu.element.appendTo( this._appendTo() );
1381 if ( key === "disabled" && value && this.xhr ) {
1386 _appendTo: function() {
1387 var element = this.options.appendTo;
1390 element = element.jquery || element.nodeType ?
1392 this.document.find( element ).eq( 0 );
1396 element = this.element.closest( ".ui-front" );
1399 if ( !element.length ) {
1400 element = this.document[0].body;
1406 _initSource: function() {
1409 if ( $.isArray(this.options.source) ) {
1410 array = this.options.source;
1411 this.source = function( request, response ) {
1412 response( $.ui.autocomplete.filter( array, request.term ) );
1414 } else if ( typeof this.options.source === "string" ) {
1415 url = this.options.source;
1416 this.source = function( request, response ) {
1424 success: function( data ) {
1433 this.source = this.options.source;
1437 _searchTimeout: function( event ) {
1438 clearTimeout( this.searching );
1439 this.searching = this._delay(function() {
1440 // only search if the value has changed
1441 if ( this.term !== this._value() ) {
1442 this.selectedItem = null;
1443 this.search( null, event );
1445 }, this.options.delay );
1448 search: function( value, event ) {
1449 value = value != null ? value : this._value();
1451 // always save the actual value, not the one passed as an argument
1452 this.term = this._value();
1454 if ( value.length < this.options.minLength ) {
1455 return this.close( event );
1458 if ( this._trigger( "search", event ) === false ) {
1462 return this._search( value );
1465 _search: function( value ) {
1467 this.element.addClass( "ui-autocomplete-loading" );
1468 this.cancelSearch = false;
1470 this.source( { term: value }, this._response() );
1473 _response: function() {
1474 var index = ++this.requestIndex;
1476 return $.proxy(function( content ) {
1477 if ( index === this.requestIndex ) {
1478 this.__response( content );
1482 if ( !this.pending ) {
1483 this.element.removeClass( "ui-autocomplete-loading" );
1488 __response: function( content ) {
1490 content = this._normalize( content );
1492 this._trigger( "response", null, { content: content } );
1493 if ( !this.options.disabled && content && content.length && !this.cancelSearch ) {
1494 this._suggest( content );
1495 this._trigger( "open" );
1497 // use ._close() instead of .close() so we don't cancel future searches
1502 close: function( event ) {
1503 this.cancelSearch = true;
1504 this._close( event );
1507 _close: function( event ) {
1508 if ( this.menu.element.is( ":visible" ) ) {
1509 this.menu.element.hide();
1511 this.isNewMenu = true;
1512 this._trigger( "close", event );
1516 _change: function( event ) {
1517 if ( this.previous !== this._value() ) {
1518 this._trigger( "change", event, { item: this.selectedItem } );
1522 _normalize: function( items ) {
1523 // assume all items have the right format when the first item is complete
1524 if ( items.length && items[0].label && items[0].value ) {
1527 return $.map( items, function( item ) {
1528 if ( typeof item === "string" ) {
1535 label: item.label || item.value,
1536 value: item.value || item.label
1541 _suggest: function( items ) {
1542 var ul = this.menu.element.empty();
1543 this._renderMenu( ul, items );
1544 this.isNewMenu = true;
1545 this.menu.refresh();
1547 // size and position menu
1550 ul.position( $.extend({
1552 }, this.options.position ));
1554 if ( this.options.autoFocus ) {
1559 _resizeMenu: function() {
1560 var ul = this.menu.element;
1561 ul.outerWidth( Math.max(
1562 // Firefox wraps long text (possibly a rounding bug)
1563 // so we add 1px to avoid the wrapping (#7513)
1564 ul.width( "" ).outerWidth() + 1,
1565 this.element.outerWidth()
1569 _renderMenu: function( ul, items ) {
1571 $.each( items, function( index, item ) {
1572 that._renderItemData( ul, item );
1576 _renderItemData: function( ul, item ) {
1577 return this._renderItem( ul, item ).data( "ui-autocomplete-item", item );
1580 _renderItem: function( ul, item ) {
1582 .append( $( "<a>" ).text( item.label ) )
1586 _move: function( direction, event ) {
1587 if ( !this.menu.element.is( ":visible" ) ) {
1588 this.search( null, event );
1591 if ( this.menu.isFirstItem() && /^previous/.test( direction ) ||
1592 this.menu.isLastItem() && /^next/.test( direction ) ) {
1593 this._value( this.term );
1597 this.menu[ direction ]( event );
1600 widget: function() {
1601 return this.menu.element;
1604 _value: function() {
1605 return this.valueMethod.apply( this.element, arguments );
1608 _keyEvent: function( keyEvent, event ) {
1609 if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) {
1610 this._move( keyEvent, event );
1612 // prevents moving cursor to beginning/end of the text field in some browsers
1613 event.preventDefault();
1618 $.extend( $.ui.autocomplete, {
1619 escapeRegex: function( value ) {
1620 return value.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&");
1622 filter: function(array, term) {
1623 var matcher = new RegExp( $.ui.autocomplete.escapeRegex(term), "i" );
1624 return $.grep( array, function(value) {
1625 return matcher.test( value.label || value.value || value );
1631 // live region extension, adding a `messages` option
1632 // NOTE: This is an experimental API. We are still investigating
1633 // a full solution for string manipulation and internationalization.
1634 $.widget( "ui.autocomplete", $.ui.autocomplete, {
1637 noResults: "No search results.",
1638 results: function( amount ) {
1639 return amount + ( amount > 1 ? " results are" : " result is" ) +
1640 " available, use up and down arrow keys to navigate.";
1645 __response: function( content ) {
1647 this._superApply( arguments );
1648 if ( this.options.disabled || this.cancelSearch ) {
1651 if ( content && content.length ) {
1652 message = this.options.messages.results( content.length );
1654 message = this.options.messages.noResults;
1656 this.liveRegion.text( message );
1663 System.out.println("coremenu failed to load jQuery.ui.autocomplete -- jQuery version conflict?");