vendor: 1,774 bytes, lines 1-69
1/*! jQuery UI - v1.13.2 - 2024-02-19 2* http://jqueryui.com 3* Includes: widget.js, position.js, keycode.js, unique-id.js, widgets/autocomplete.js, widgets/menu.js 4* Copyright jQuery Foundation and other contributors; Licensed MIT */ 5 6( function( factory ) { 7 "use strict"; 8 9 if ( typeof define === "function" && define.amd ) { 10 11 // AMD. Register as an anonymous module. 12 define( [ "jquery" ], factory ); 13 } else { 14 15 // Browser globals 16 factory( jQuery ); 17 } 18} )( function( $ ) { 19"use strict"; 20 21$.ui = $.ui || {}; 22 23var version = $.ui.version = "1.13.2"; 24 25 26/*! 27 * jQuery UI Widget 1.13.2 28 * http://jqueryui.com 29 * 30 * Copyright jQuery Foundation and other contributors 31 * Released under the MIT license. 32 * http://jquery.org/license 33 */ 34 35//>>label: Widget 36//>>group: Core 37//>>description: Provides a factory for creating stateful widgets with a common API. 38//>>docs: http://api.jqueryui.com/jQuery.widget/ 39//>>demos: http://jqueryui.com/widget/ 40 41 42var widgetUuid = 0; 43var widgetHasOwnProperty = Array.prototype.hasOwnProperty; 44var widgetSlice = Array.prototype.slice; 45 46$.cleanData = ( function( orig ) { 47 return function( elems ) { 48 var events, elem, i; 49 for ( i = 0; ( elem = elems[ i ] ) != null; i++ ) { 50 51 // Only trigger remove when necessary to save time 52 events = $._data( elem, "events" ); 53 if ( events && events.remove ) { 54 $( elem ).triggerHandler( "remove" ); 55 } 56 } 57 orig( elems ); 58 }; 59} )( $.cleanData ); 60 61$.widget = function( name, base, prototype ) { 62 var existingConstructor, constructor, basePrototype; 63 64 // ProxiedPrototype allows the provided prototype to remain unmodified 65 // so that it can be used as a mixin for multiple widgets (#8876) 66 var proxiedPrototype = {}; 67 68 var namespace = name.split( "." )[ 0 ]; 69 name = name.split( "." )[ 1 ];
vendor: 18,823 bytes, lines 69-769
69 70 var fullName = namespace + "-" + name; 71 72 if ( !prototype ) { 73 prototype = base; 74 base = $.Widget; 75 } 76 77 if ( Array.isArray( prototype ) ) { 78 prototype = $.extend.apply( null, [ {} ].concat( prototype ) ); 79 } 80 81 // Create selector for plugin 82 $.expr.pseudos[ fullName.toLowerCase() ] = function( elem ) { 83 return !!$.data( elem, fullName ); 84 }; 85 86 $[ namespace ] = $[ namespace ] || {}; 87 existingConstructor = $[ namespace ][ name ]; 88 constructor = $[ namespace ][ name ] = function( options, element ) { 89 90 // Allow instantiation without "new" keyword 91 if ( !this || !this._createWidget ) { 92 return new constructor( options, element ); 93 } 94 95 // Allow instantiation without initializing for simple inheritance 96 // must use "new" keyword (the code above always passes args) 97 if ( arguments.length ) { 98 this._createWidget( options, element ); 99 } 100 }; 101 102 // Extend with the existing constructor to carry over any static properties 103 $.extend( constructor, existingConstructor, { 104 version: prototype.version, 105 106 // Copy the object used to create the prototype in case we need to 107 // redefine the widget later 108 _proto: $.extend( {}, prototype ), 109 110 // Track widgets that inherit from this widget in case this widget is 111 // redefined after a widget inherits from it 112 _childConstructors: [] 113 } ); 114 115 basePrototype = new base(); 116 117 // We need to make the options hash a property directly on the new instance 118 // otherwise we'll modify the options hash on the prototype that we're 119 // inheriting from 120 basePrototype.options = $.widget.extend( {}, basePrototype.options ); 121 $.each( prototype, function( prop, value ) { 122 if ( typeof value !== "function" ) { 123 proxiedPrototype[ prop ] = value; 124 return; 125 } 126 proxiedPrototype[ prop ] = ( function() { 127 function _super() { 128 return base.prototype[ prop ].apply( this, arguments ); 129 } 130 131 function _superApply( args ) { 132 return base.prototype[ prop ].apply( this, args ); 133 } 134 135 return function() { 136 var __super = this._super; 137 var __superApply = this._superApply; 138 var returnValue; 139 140 this._super = _super; 141 this._superApply = _superApply; 142 143 returnValue = value.apply( this, arguments ); 144 145 this._super = __super; 146 this._superApply = __superApply; 147 148 return returnValue; 149 }; 150 } )(); 151 } ); 152 constructor.prototype = $.widget.extend( basePrototype, { 153 154 // TODO: remove support for widgetEventPrefix 155 // always use the name + a colon as the prefix, e.g., draggable:start 156 // don't prefix for widgets that aren't DOM-based 157 widgetEventPrefix: existingConstructor ? ( basePrototype.widgetEventPrefix || name ) : name 158 }, proxiedPrototype, { 159 constructor: constructor, 160 namespace: namespace, 161 widgetName: name, 162 widgetFullName: fullName 163 } ); 164 165 // If this widget is being redefined then we need to find all widgets that 166 // are inheriting from it and redefine all of them so that they inherit from 167 // the new version of this widget. We're essentially trying to replace one 168 // level in the prototype chain. 169 if ( existingConstructor ) { 170 $.each( existingConstructor._childConstructors, function( i, child ) { 171 var childPrototype = child.prototype; 172 173 // Redefine the child widget using the same prototype that was 174 // originally used, but inherit from the new version of the base 175 $.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor, 176 child._proto ); 177 } ); 178 179 // Remove the list of existing child constructors from the old constructor 180 // so the old child constructors can be garbage collected 181 delete existingConstructor._childConstructors; 182 } else { 183 base._childConstructors.push( constructor ); 184 } 185 186 $.widget.bridge( name, constructor ); 187 188 return constructor; 189}; 190 191$.widget.extend = function( target ) { 192 var input = widgetSlice.call( arguments, 1 ); 193 var inputIndex = 0; 194 var inputLength = input.length; 195 var key; 196 var value; 197 198 for ( ; inputIndex < inputLength; inputIndex++ ) { 199 for ( key in input[ inputIndex ] ) { 200 value = input[ inputIndex ][ key ]; 201 if ( widgetHasOwnProperty.call( input[ inputIndex ], key ) && value !== undefined ) { 202 203 // Clone objects 204 if ( $.isPlainObject( value ) ) { 205 target[ key ] = $.isPlainObject( target[ key ] ) ? 206 $.widget.extend( {}, target[ key ], value ) : 207 208 // Don't extend strings, arrays, etc. with objects 209 $.widget.extend( {}, value ); 210 211 // Copy everything else by reference 212 } else { 213 target[ key ] = value; 214 } 215 } 216 } 217 } 218 return target; 219}; 220 221$.widget.bridge = function( name, object ) { 222 var fullName = object.prototype.widgetFullName || name; 223 $.fn[ name ] = function( options ) { 224 var isMethodCall = typeof options === "string"; 225 var args = widgetSlice.call( arguments, 1 ); 226 var returnValue = this; 227 228 if ( isMethodCall ) { 229 230 // If this is an empty collection, we need to have the instance method 231 // return undefined instead of the jQuery instance 232 if ( !this.length && options === "instance" ) { 233 returnValue = undefined; 234 } else { 235 this.each( function() { 236 var methodValue; 237 var instance = $.data( this, fullName ); 238 239 if ( options === "instance" ) { 240 returnValue = instance; 241 return false; 242 } 243 244 if ( !instance ) { 245 return $.error( "cannot call methods on " + name + 246 " prior to initialization; " + 247 "attempted to call method '" + options + "'" ); 248 } 249 250 if ( typeof instance[ options ] !== "function" || 251 options.charAt( 0 ) === "_" ) { 252 return $.error( "no such method '" + options + "' for " + name + 253 " widget instance" ); 254 } 255 256 methodValue = instance[ options ].apply( instance, args ); 257 258 if ( methodValue !== instance && methodValue !== undefined ) { 259 returnValue = methodValue && methodValue.jquery ? 260 returnValue.pushStack( methodValue.get() ) : 261 methodValue; 262 return false; 263 } 264 } ); 265 } 266 } else { 267 268 // Allow multiple hashes to be passed on init 269 if ( args.length ) { 270 options = $.widget.extend.apply( null, [ options ].concat( args ) ); 271 } 272 273 this.each( function() { 274 var instance = $.data( this, fullName ); 275 if ( instance ) { 276 instance.option( options || {} ); 277 if ( instance._init ) { 278 instance._init(); 279 } 280 } else { 281 $.data( this, fullName, new object( options, this ) ); 282 } 283 } ); 284 } 285 286 return returnValue; 287 }; 288}; 289 290$.Widget = function( /* options, element */ ) {}; 291$.Widget._childConstructors = []; 292 293$.Widget.prototype = { 294 widgetName: "widget", 295 widgetEventPrefix: "", 296 defaultElement: "<div>", 297 298 options: { 299 classes: {}, 300 disabled: false, 301 302 // Callbacks 303 create: null 304 }, 305 306 _createWidget: function( options, element ) { 307 element = $( element || this.defaultElement || this )[ 0 ]; 308 this.element = $( element ); 309 this.uuid = widgetUuid++; 310 this.eventNamespace = "." + this.widgetName + this.uuid; 311 312 this.bindings = $(); 313 this.hoverable = $(); 314 this.focusable = $(); 315 this.classesElementLookup = {}; 316 317 if ( element !== this ) { 318 $.data( element, this.widgetFullName, this ); 319 this._on( true, this.element, { 320 remove: function( event ) { 321 if ( event.target === element ) { 322 this.destroy(); 323 } 324 } 325 } ); 326 this.document = $( element.style ? 327 328 // Element within the document 329 element.ownerDocument : 330 331 // Element is window or document 332 element.document || element ); 333 this.window = $( this.document[ 0 ].defaultView || this.document[ 0 ].parentWindow ); 334 } 335 336 this.options = $.widget.extend( {}, 337 this.options, 338 this._getCreateOptions(), 339 options ); 340 341 this._create(); 342 343 if ( this.options.disabled ) { 344 this._setOptionDisabled( this.options.disabled ); 345 } 346 347 this._trigger( "create", null, this._getCreateEventData() ); 348 this._init(); 349 }, 350 351 _getCreateOptions: function() { 352 return {}; 353 }, 354 355 _getCreateEventData: $.noop, 356 357 _create: $.noop, 358 359 _init: $.noop, 360 361 destroy: function() { 362 var that = this; 363 364 this._destroy(); 365 $.each( this.classesElementLookup, function( key, value ) { 366 that._removeClass( value, key ); 367 } ); 368 369 // We can probably remove the unbind calls in 2.0 370 // all event bindings should go through this._on() 371 this.element 372 .off( this.eventNamespace ) 373 .removeData( this.widgetFullName ); 374 this.widget() 375 .off( this.eventNamespace ) 376 .removeAttr( "aria-disabled" ); 377 378 // Clean up events and states 379 this.bindings.off( this.eventNamespace ); 380 }, 381 382 _destroy: $.noop, 383 384 widget: function() { 385 return this.element; 386 }, 387 388 option: function( key, value ) { 389 var options = key; 390 var parts; 391 var curOption; 392 var i; 393 394 if ( arguments.length === 0 ) { 395 396 // Don't return a reference to the internal hash 397 return $.widget.extend( {}, this.options ); 398 } 399 400 if ( typeof key === "string" ) { 401 402 // Handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } } 403 options = {}; 404 parts = key.split( "." ); 405 key = parts.shift(); 406 if ( parts.length ) { 407 curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] ); 408 for ( i = 0; i < parts.length - 1; i++ ) { 409 curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {}; 410 curOption = curOption[ parts[ i ] ]; 411 } 412 key = parts.pop(); 413 if ( arguments.length === 1 ) { 414 return curOption[ key ] === undefined ? null : curOption[ key ]; 415 } 416 curOption[ key ] = value; 417 } else { 418 if ( arguments.length === 1 ) { 419 return this.options[ key ] === undefined ? null : this.options[ key ]; 420 } 421 options[ key ] = value; 422 } 423 } 424 425 this._setOptions( options ); 426 427 return this; 428 }, 429 430 _setOptions: function( options ) { 431 var key; 432 433 for ( key in options ) { 434 this._setOption( key, options[ key ] ); 435 } 436 437 return this; 438 }, 439 440 _setOption: function( key, value ) { 441 if ( key === "classes" ) { 442 this._setOptionClasses( value ); 443 } 444 445 this.options[ key ] = value; 446 447 if ( key === "disabled" ) { 448 this._setOptionDisabled( value ); 449 } 450 451 return this; 452 }, 453 454 _setOptionClasses: function( value ) { 455 var classKey, elements, currentElements; 456 457 for ( classKey in value ) { 458 currentElements = this.classesElementLookup[ classKey ]; 459 if ( value[ classKey ] === this.options.classes[ classKey ] || 460 !currentElements || 461 !currentElements.length ) { 462 continue; 463 } 464 465 // We are doing this to create a new jQuery object because the _removeClass() call 466 // on the next line is going to destroy the reference to the current elements being 467 // tracked. We need to save a copy of this collection so that we can add the new classes 468 // below. 469 elements = $( currentElements.get() ); 470 this._removeClass( currentElements, classKey ); 471 472 // We don't use _addClass() here, because that uses this.options.classes 473 // for generating the string of classes. We want to use the value passed in from 474 // _setOption(), this is the new value of the classes option which was passed to 475 // _setOption(). We pass this value directly to _classes(). 476 elements.addClass( this._classes( { 477 element: elements, 478 keys: classKey, 479 classes: value, 480 add: true 481 } ) ); 482 } 483 }, 484 485 _setOptionDisabled: function( value ) { 486 this._toggleClass( this.widget(), this.widgetFullName + "-disabled", null, !!value ); 487 488 // If the widget is becoming disabled, then nothing is interactive 489 if ( value ) { 490 this._removeClass( this.hoverable, null, "ui-state-hover" ); 491 this._removeClass( this.focusable, null, "ui-state-focus" ); 492 } 493 }, 494 495 enable: function() { 496 return this._setOptions( { disabled: false } ); 497 }, 498 499 disable: function() { 500 return this._setOptions( { disabled: true } ); 501 }, 502 503 _classes: function( options ) { 504 var full = []; 505 var that = this; 506 507 options = $.extend( { 508 element: this.element, 509 classes: this.options.classes || {} 510 }, options ); 511 512 function bindRemoveEvent() { 513 var nodesToBind = []; 514 515 options.element.each( function( _, element ) { 516 var isTracked = $.map( that.classesElementLookup, function( elements ) { 517 return elements; 518 } ) 519 .some( function( elements ) { 520 return elements.is( element ); 521 } ); 522 523 if ( !isTracked ) { 524 nodesToBind.push( element ); 525 } 526 } ); 527 528 that._on( $( nodesToBind ), { 529 remove: "_untrackClassesElement" 530 } ); 531 } 532 533 function processClassString( classes, checkOption ) { 534 var current, i; 535 for ( i = 0; i < classes.length; i++ ) { 536 current = that.classesElementLookup[ classes[ i ] ] || $(); 537 if ( options.add ) { 538 bindRemoveEvent(); 539 current = $( $.uniqueSort( current.get().concat( options.element.get() ) ) ); 540 } else { 541 current = $( current.not( options.element ).get() ); 542 } 543 that.classesElementLookup[ classes[ i ] ] = current; 544 full.push( classes[ i ] ); 545 if ( checkOption && options.classes[ classes[ i ] ] ) { 546 full.push( options.classes[ classes[ i ] ] ); 547 } 548 } 549 } 550 551 if ( options.keys ) { 552 processClassString( options.keys.match( /\S+/g ) || [], true ); 553 } 554 if ( options.extra ) { 555 processClassString( options.extra.match( /\S+/g ) || [] ); 556 } 557 558 return full.join( " " ); 559 }, 560 561 _untrackClassesElement: function( event ) { 562 var that = this; 563 $.each( that.classesElementLookup, function( key, value ) { 564 if ( $.inArray( event.target, value ) !== -1 ) { 565 that.classesElementLookup[ key ] = $( value.not( event.target ).get() ); 566 } 567 } ); 568 569 this._off( $( event.target ) ); 570 }, 571 572 _removeClass: function( element, keys, extra ) { 573 return this._toggleClass( element, keys, extra, false ); 574 }, 575 576 _addClass: function( element, keys, extra ) { 577 return this._toggleClass( element, keys, extra, true ); 578 }, 579 580 _toggleClass: function( element, keys, extra, add ) { 581 add = ( typeof add === "boolean" ) ? add : extra; 582 var shift = ( typeof element === "string" || element === null ), 583 options = { 584 extra: shift ? keys : extra, 585 keys: shift ? element : keys, 586 element: shift ? this.element : element, 587 add: add 588 }; 589 options.element.toggleClass( this._classes( options ), add ); 590 return this; 591 }, 592 593 _on: function( suppressDisabledCheck, element, handlers ) { 594 var delegateElement; 595 var instance = this; 596 597 // No suppressDisabledCheck flag, shuffle arguments 598 if ( typeof suppressDisabledCheck !== "boolean" ) { 599 handlers = element; 600 element = suppressDisabledCheck; 601 suppressDisabledCheck = false; 602 } 603 604 // No element argument, shuffle and use this.element 605 if ( !handlers ) { 606 handlers = element; 607 element = this.element; 608 delegateElement = this.widget(); 609 } else { 610 element = delegateElement = $( element ); 611 this.bindings = this.bindings.add( element ); 612 } 613 614 $.each( handlers, function( event, handler ) { 615 function handlerProxy() { 616 617 // Allow widgets to customize the disabled handling 618 // - disabled as an array instead of boolean 619 // - disabled class as method for disabling individual parts 620 if ( !suppressDisabledCheck && 621 ( instance.options.disabled === true || 622 $( this ).hasClass( "ui-state-disabled" ) ) ) { 623 return; 624 } 625 return ( typeof handler === "string" ? instance[ handler ] : handler ) 626 .apply( instance, arguments ); 627 } 628 629 // Copy the guid so direct unbinding works 630 if ( typeof handler !== "string" ) { 631 handlerProxy.guid = handler.guid = 632 handler.guid || handlerProxy.guid || $.guid++; 633 } 634 635 var match = event.match( /^([\w:-]*)\s*(.*)$/ ); 636 var eventName = match[ 1 ] + instance.eventNamespace; 637 var selector = match[ 2 ]; 638 639 if ( selector ) { 640 delegateElement.on( eventName, selector, handlerProxy ); 641 } else { 642 element.on( eventName, handlerProxy ); 643 } 644 } ); 645 }, 646 647 _off: function( element, eventName ) { 648 eventName = ( eventName || "" ).split( " " ).join( this.eventNamespace + " " ) + 649 this.eventNamespace; 650 element.off( eventName ); 651 652 // Clear the stack to avoid memory leaks (#10056) 653 this.bindings = $( this.bindings.not( element ).get() ); 654 this.focusable = $( this.focusable.not( element ).get() ); 655 this.hoverable = $( this.hoverable.not( element ).get() ); 656 }, 657 658 _delay: function( handler, delay ) { 659 function handlerProxy() { 660 return ( typeof handler === "string" ? instance[ handler ] : handler ) 661 .apply( instance, arguments ); 662 } 663 var instance = this; 664 return setTimeout( handlerProxy, delay || 0 ); 665 }, 666 667 _hoverable: function( element ) { 668 this.hoverable = this.hoverable.add( element ); 669 this._on( element, { 670 mouseenter: function( event ) { 671 this._addClass( $( event.currentTarget ), null, "ui-state-hover" ); 672 }, 673 mouseleave: function( event ) { 674 this._removeClass( $( event.currentTarget ), null, "ui-state-hover" ); 675 } 676 } ); 677 }, 678 679 _focusable: function( element ) { 680 this.focusable = this.focusable.add( element ); 681 this._on( element, { 682 focusin: function( event ) { 683 this._addClass( $( event.currentTarget ), null, "ui-state-focus" ); 684 }, 685 focusout: function( event ) { 686 this._removeClass( $( event.currentTarget ), null, "ui-state-focus" ); 687 } 688 } ); 689 }, 690 691 _trigger: function( type, event, data ) { 692 var prop, orig; 693 var callback = this.options[ type ]; 694 695 data = data || {}; 696 event = $.Event( event ); 697 event.type = ( type === this.widgetEventPrefix ? 698 type : 699 this.widgetEventPrefix + type ).toLowerCase(); 700 701 // The original event may come from any element 702 // so we need to reset the target on the new event 703 event.target = this.element[ 0 ]; 704 705 // Copy original event properties over to the new event 706 orig = event.originalEvent; 707 if ( orig ) { 708 for ( prop in orig ) { 709 if ( !( prop in event ) ) { 710 event[ prop ] = orig[ prop ]; 711 } 712 } 713 } 714 715 this.element.trigger( event, data ); 716 return !( typeof callback === "function" && 717 callback.apply( this.element[ 0 ], [ event ].concat( data ) ) === false || 718 event.isDefaultPrevented() ); 719 } 720}; 721 722$.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) { 723 $.Widget.prototype[ "_" + method ] = function( element, options, callback ) { 724 if ( typeof options === "string" ) { 725 options = { effect: options }; 726 } 727 728 var hasOptions; 729 var effectName = !options ? 730 method : 731 options === true || typeof options === "number" ? 732 defaultEffect : 733 options.effect || defaultEffect; 734 735 options = options || {}; 736 if ( typeof options === "number" ) { 737 options = { duration: options }; 738 } else if ( options === true ) { 739 options = {}; 740 } 741 742 hasOptions = !$.isEmptyObject( options ); 743 options.complete = callback; 744 745 if ( options.delay ) { 746 element.delay( options.delay ); 747 } 748 749 if ( hasOptions && $.effects && $.effects.effect[ effectName ] ) { 750 element[ method ]( options ); 751 } else if ( effectName !== method && element[ effectName ] ) { 752 element[ effectName ]( options.duration, options.easing, callback ); 753 } else { 754 element.queue( function( next ) { 755 $( this )[ method ](); 756 if ( callback ) { 757 callback.call( element[ 0 ] ); 758 } 759 next(); 760 } ); 761 } 762 }; 763} ); 764 765var widget = $.widget; 766 767 768/*! 769 * jQuery UI Position 1.1
vendor: 3,858 bytes, lines 769-912
7693.2 770 * http://jqueryui.com 771 * 772 * Copyright jQuery Foundation and other contributors 773 * Released under the MIT license. 774 * http://jquery.org/license 775 * 776 * http://api.jqueryui.com/position/ 777 */ 778 779//>>label: Position 780//>>group: Core 781//>>description: Positions elements relative to other elements. 782//>>docs: http://api.jqueryui.com/position/ 783//>>demos: http://jqueryui.com/position/ 784 785 786( function() { 787var cachedScrollbarWidth, 788 max = Math.max, 789 abs = Math.abs, 790 rhorizontal = /left|center|right/, 791 rvertical = /top|center|bottom/, 792 roffset = /[\+\-]\d+(\.[\d]+)?%?/, 793 rposition = /^\w+/, 794 rpercent = /%$/, 795 _position = $.fn.position; 796 797function getOffsets( offsets, width, height ) { 798 return [ 799 parseFloat( offsets[ 0 ] ) * ( rpercent.test( offsets[ 0 ] ) ? width / 100 : 1 ), 800 parseFloat( offsets[ 1 ] ) * ( rpercent.test( offsets[ 1 ] ) ? height / 100 : 1 ) 801 ]; 802} 803 804function parseCss( element, property ) { 805 return parseInt( $.css( element, property ), 10 ) || 0; 806} 807 808function isWindow( obj ) { 809 return obj != null && obj === obj.window; 810} 811 812function getDimensions( elem ) { 813 var raw = elem[ 0 ]; 814 if ( raw.nodeType === 9 ) { 815 return { 816 width: elem.width(), 817 height: elem.height(), 818 offset: { top: 0, left: 0 } 819 }; 820 } 821 if ( isWindow( raw ) ) { 822 return { 823 width: elem.width(), 824 height: elem.height(), 825 offset: { top: elem.scrollTop(), left: elem.scrollLeft() } 826 }; 827 } 828 if ( raw.preventDefault ) { 829 return { 830 width: 0, 831 height: 0, 832 offset: { top: raw.pageY, left: raw.pageX } 833 }; 834 } 835 return { 836 width: elem.outerWidth(), 837 height: elem.outerHeight(), 838 offset: elem.offset() 839 }; 840} 841 842$.position = { 843 scrollbarWidth: function() { 844 if ( cachedScrollbarWidth !== undefined ) { 845 return cachedScrollbarWidth; 846 } 847 var w1, w2, 848 div = $( "<div style=" + 849 "'display:block;position:absolute;width:200px;height:200px;overflow:hidden;'>" + 850 "<div style='height:300px;width:auto;'></div></div>" ), 851 innerDiv = div.children()[ 0 ]; 852 853 $( "body" ).append( div ); 854 w1 = innerDiv.offsetWidth; 855 div.css( "overflow", "scroll" ); 856 857 w2 = innerDiv.offsetWidth; 858 859 if ( w1 === w2 ) { 860 w2 = div[ 0 ].clientWidth; 861 } 862 863 div.remove(); 864 865 return ( cachedScrollbarWidth = w1 - w2 ); 866 }, 867 getScrollInfo: function( within ) { 868 var overflowX = within.isWindow || within.isDocument ? "" : 869 within.element.css( "overflow-x" ), 870 overflowY = within.isWindow || within.isDocument ? "" : 871 within.element.css( "overflow-y" ), 872 hasOverflowX = overflowX === "scroll" || 873 ( overflowX === "auto" && within.width < within.element[ 0 ].scrollWidth ), 874 hasOverflowY = overflowY === "scroll" || 875 ( overflowY === "auto" && within.height < within.element[ 0 ].scrollHeight ); 876 return { 877 width: hasOverflowY ? $.position.scrollbarWidth() : 0, 878 height: hasOverflowX ? $.position.scrollbarWidth() : 0 879 }; 880 }, 881 getWithinInfo: function( element ) { 882 var withinElement = $( element || window ), 883 isElemWindow = isWindow( withinElement[ 0 ] ), 884 isDocument = !!withinElement[ 0 ] && withinElement[ 0 ].nodeType === 9, 885 hasOffset = !isElemWindow && !isDocument; 886 return { 887 element: withinElement, 888 isWindow: isElemWindow, 889 isDocument: isDocument, 890 offset: hasOffset ? $( element ).offset() : { left: 0, top: 0 }, 891 scrollLeft: withinElement.scrollLeft(), 892 scrollTop: withinElement.scrollTop(), 893 width: withinElement.outerWidth(), 894 height: withinElement.outerHeight() 895 }; 896 } 897}; 898 899$.fn.position = function( options ) { 900 if ( !options || !options.of ) { 901 return _position.apply( this, arguments ); 902 } 903 904 // Make a copy, we don't want to modify arguments 905 options = $.extend( {}, options ); 906 907 var atOffset, targetWidth, targetHeight, targetOffset, basePosition, dimensions, 908 909 // Make sure string options are treated as CSS selectors 910 target = typeof options.of === "string" ? 911 $( document ).find( options.of ) : 912 $( options.of ),
vendor: 10,983 bytes, lines 913-1266
913 914 within = $.position.getWithinInfo( options.within ), 915 scrollInfo = $.position.getScrollInfo( within ), 916 collision = ( options.collision || "flip" ).split( " " ), 917 offsets = {}; 918 919 dimensions = getDimensions( target ); 920 if ( target[ 0 ].preventDefault ) { 921 922 // Force left top to allow flipping 923 options.at = "left top"; 924 } 925 targetWidth = dimensions.width; 926 targetHeight = dimensions.height; 927 targetOffset = dimensions.offset; 928 929 // Clone to reuse original targetOffset later 930 basePosition = $.extend( {}, targetOffset ); 931 932 // Force my and at to have valid horizontal and vertical positions 933 // if a value is missing or invalid, it will be converted to center 934 $.each( [ "my", "at" ], function() { 935 var pos = ( options[ this ] || "" ).split( " " ), 936 horizontalOffset, 937 verticalOffset; 938 939 if ( pos.length === 1 ) { 940 pos = rhorizontal.test( pos[ 0 ] ) ? 941 pos.concat( [ "center" ] ) : 942 rvertical.test( pos[ 0 ] ) ? 943 [ "center" ].concat( pos ) : 944 [ "center", "center" ]; 945 } 946 pos[ 0 ] = rhorizontal.test( pos[ 0 ] ) ? pos[ 0 ] : "center"; 947 pos[ 1 ] = rvertical.test( pos[ 1 ] ) ? pos[ 1 ] : "center"; 948 949 // Calculate offsets 950 horizontalOffset = roffset.exec( pos[ 0 ] ); 951 verticalOffset = roffset.exec( pos[ 1 ] ); 952 offsets[ this ] = [ 953 horizontalOffset ? horizontalOffset[ 0 ] : 0, 954 verticalOffset ? verticalOffset[ 0 ] : 0 955 ]; 956 957 // Reduce to just the positions without the offsets 958 options[ this ] = [ 959 rposition.exec( pos[ 0 ] )[ 0 ], 960 rposition.exec( pos[ 1 ] )[ 0 ] 961 ]; 962 } ); 963 964 // Normalize collision option 965 if ( collision.length === 1 ) { 966 collision[ 1 ] = collision[ 0 ]; 967 } 968 969 if ( options.at[ 0 ] === "right" ) { 970 basePosition.left += targetWidth; 971 } else if ( options.at[ 0 ] === "center" ) { 972 basePosition.left += targetWidth / 2; 973 } 974 975 if ( options.at[ 1 ] === "bottom" ) { 976 basePosition.top += targetHeight; 977 } else if ( options.at[ 1 ] === "center" ) { 978 basePosition.top += targetHeight / 2; 979 } 980 981 atOffset = getOffsets( offsets.at, targetWidth, targetHeight ); 982 basePosition.left += atOffset[ 0 ]; 983 basePosition.top += atOffset[ 1 ]; 984 985 return this.each( function() { 986 var collisionPosition, using, 987 elem = $( this ), 988 elemWidth = elem.outerWidth(), 989 elemHeight = elem.outerHeight(), 990 marginLeft = parseCss( this, "marginLeft" ), 991 marginTop = parseCss( this, "marginTop" ), 992 collisionWidth = elemWidth + marginLeft + parseCss( this, "marginRight" ) + 993 scrollInfo.width, 994 collisionHeight = elemHeight + marginTop + parseCss( this, "marginBottom" ) + 995 scrollInfo.height, 996 position = $.extend( {}, basePosition ), 997 myOffset = getOffsets( offsets.my, elem.outerWidth(), elem.outerHeight() ); 998 999 if ( options.my[ 0 ] === "right" ) { 1000 position.left -= elemWidth; 1001 } else if ( options.my[ 0 ] === "center" ) { 1002 position.left -= elemWidth / 2; 1003 } 1004 1005 if ( options.my[ 1 ] === "bottom" ) { 1006 position.top -= elemHeight; 1007 } else if ( options.my[ 1 ] === "center" ) { 1008 position.top -= elemHeight / 2; 1009 } 1010 1011 position.left += myOffset[ 0 ]; 1012 position.top += myOffset[ 1 ]; 1013 1014 collisionPosition = { 1015 marginLeft: marginLeft, 1016 marginTop: marginTop 1017 }; 1018 1019 $.each( [ "left", "top" ], function( i, dir ) { 1020 if ( $.ui.position[ collision[ i ] ] ) { 1021 $.ui.position[ collision[ i ] ][ dir ]( position, { 1022 targetWidth: targetWidth, 1023 targetHeight: targetHeight, 1024 elemWidth: elemWidth, 1025 elemHeight: elemHeight, 1026 collisionPosition: collisionPosition, 1027 collisionWidth: collisionWidth, 1028 collisionHeight: collisionHeight, 1029 offset: [ atOffset[ 0 ] + myOffset[ 0 ], atOffset [ 1 ] + myOffset[ 1 ] ], 1030 my: options.my, 1031 at: options.at, 1032 within: within, 1033 elem: elem 1034 } ); 1035 } 1036 } ); 1037 1038 if ( options.using ) { 1039 1040 // Adds feedback as second argument to using callback, if present 1041 using = function( props ) { 1042 var left = targetOffset.left - position.left, 1043 right = left + targetWidth - elemWidth, 1044 top = targetOffset.top - position.top, 1045 bottom = top + targetHeight - elemHeight, 1046 feedback = { 1047 target: { 1048 element: target, 1049 left: targetOffset.left, 1050 top: targetOffset.top, 1051 width: targetWidth, 1052 height: targetHeight 1053 }, 1054 element: { 1055 element: elem, 1056 left: position.left, 1057 top: position.top, 1058 width: elemWidth, 1059 height: elemHeight 1060 }, 1061 horizontal: right < 0 ? "left" : left > 0 ? "right" : "center", 1062 vertical: bottom < 0 ? "top" : top > 0 ? "bottom" : "middle" 1063 }; 1064 if ( targetWidth < elemWidth && abs( left + right ) < targetWidth ) { 1065 feedback.horizontal = "center"; 1066 } 1067 if ( targetHeight < elemHeight && abs( top + bottom ) < targetHeight ) { 1068 feedback.vertical = "middle"; 1069 } 1070 if ( max( abs( left ), abs( right ) ) > max( abs( top ), abs( bottom ) ) ) { 1071 feedback.important = "horizontal"; 1072 } else { 1073 feedback.important = "vertical"; 1074 } 1075 options.using.call( this, props, feedback ); 1076 }; 1077 } 1078 1079 elem.offset( $.extend( position, { using: using } ) ); 1080 } ); 1081}; 1082 1083$.ui.position = { 1084 fit: { 1085 left: function( position, data ) { 1086 var within = data.within, 1087 withinOffset = within.isWindow ? within.scrollLeft : within.offset.left, 1088 outerWidth = within.width, 1089 collisionPosLeft = position.left - data.collisionPosition.marginLeft, 1090 overLeft = withinOffset - collisionPosLeft, 1091 overRight = collisionPosLeft + data.collisionWidth - outerWidth - withinOffset, 1092 newOverRight; 1093 1094 // Element is wider than within 1095 if ( data.collisionWidth > outerWidth ) { 1096 1097 // Element is initially over the left side of within 1098 if ( overLeft > 0 && overRight <= 0 ) { 1099 newOverRight = position.left + overLeft + data.collisionWidth - outerWidth - 1100 withinOffset; 1101 position.left += overLeft - newOverRight; 1102 1103 // Element is initially over right side of within 1104 } else if ( overRight > 0 && overLeft <= 0 ) { 1105 position.left = withinOffset; 1106 1107 // Element is initially over both left and right sides of within 1108 } else { 1109 if ( overLeft > overRight ) { 1110 position.left = withinOffset + outerWidth - data.collisionWidth; 1111 } else { 1112 position.left = withinOffset; 1113 } 1114 } 1115 1116 // Too far left -> align with left edge 1117 } else if ( overLeft > 0 ) { 1118 position.left += overLeft; 1119 1120 // Too far right -> align with right edge 1121 } else if ( overRight > 0 ) { 1122 position.left -= overRight; 1123 1124 // Adjust based on position and margin 1125 } else { 1126 position.left = max( position.left - collisionPosLeft, position.left ); 1127 } 1128 }, 1129 top: function( position, data ) { 1130 var within = data.within, 1131 withinOffset = within.isWindow ? within.scrollTop : within.offset.top, 1132 outerHeight = data.within.height, 1133 collisionPosTop = position.top - data.collisionPosition.marginTop, 1134 overTop = withinOffset - collisionPosTop, 1135 overBottom = collisionPosTop + data.collisionHeight - outerHeight - withinOffset, 1136 newOverBottom; 1137 1138 // Element is taller than within 1139 if ( data.collisionHeight > outerHeight ) { 1140 1141 // Element is initially over the top of within 1142 if ( overTop > 0 && overBottom <= 0 ) { 1143 newOverBottom = position.top + overTop + data.collisionHeight - outerHeight - 1144 withinOffset; 1145 position.top += overTop - newOverBottom; 1146 1147 // Element is initially over bottom of within 1148 } else if ( overBottom > 0 && overTop <= 0 ) { 1149 position.top = withinOffset; 1150 1151 // Element is initially over both top and bottom of within 1152 } else { 1153 if ( overTop > overBottom ) { 1154 position.top = withinOffset + outerHeight - data.collisionHeight; 1155 } else { 1156 position.top = withinOffset; 1157 } 1158 } 1159 1160 // Too far up -> align with top 1161 } else if ( overTop > 0 ) { 1162 position.top += overTop; 1163 1164 // Too far down -> align with bottom edge 1165 } else if ( overBottom > 0 ) { 1166 position.top -= overBottom; 1167 1168 // Adjust based on position and margin 1169 } else { 1170 position.top = max( position.top - collisionPosTop, position.top ); 1171 } 1172 } 1173 }, 1174 flip: { 1175 left: function( position, data ) { 1176 var within = data.within, 1177 withinOffset = within.offset.left + within.scrollLeft, 1178 outerWidth = within.width, 1179 offsetLeft = within.isWindow ? within.scrollLeft : within.offset.left, 1180 collisionPosLeft = position.left - data.collisionPosition.marginLeft, 1181 overLeft = collisionPosLeft - offsetLeft, 1182 overRight = collisionPosLeft + data.collisionWidth - outerWidth - offsetLeft, 1183 myOffset = data.my[ 0 ] === "left" ? 1184 -data.elemWidth : 1185 data.my[ 0 ] === "right" ? 1186 data.elemWidth : 1187 0, 1188 atOffset = data.at[ 0 ] === "left" ? 1189 data.targetWidth : 1190 data.at[ 0 ] === "right" ? 1191 -data.targetWidth : 1192 0, 1193 offset = -2 * data.offset[ 0 ], 1194 newOverRight, 1195 newOverLeft; 1196 1197 if ( overLeft < 0 ) { 1198 newOverRight = position.left + myOffset + atOffset + offset + data.collisionWidth - 1199 outerWidth - withinOffset; 1200 if ( newOverRight < 0 || newOverRight < abs( overLeft ) ) { 1201 position.left += myOffset + atOffset + offset; 1202 } 1203 } else if ( overRight > 0 ) { 1204 newOverLeft = position.left - data.collisionPosition.marginLeft + myOffset + 1205 atOffset + offset - offsetLeft; 1206 if ( newOverLeft > 0 || abs( newOverLeft ) < overRight ) { 1207 position.left += myOffset + atOffset + offset; 1208 } 1209 } 1210 }, 1211 top: function( position, data ) { 1212 var within = data.within, 1213 withinOffset = within.offset.top + within.scrollTop, 1214 outerHeight = within.height, 1215 offsetTop = within.isWindow ? within.scrollTop : within.offset.top, 1216 collisionPosTop = position.top - data.collisionPosition.marginTop, 1217 overTop = collisionPosTop - offsetTop, 1218 overBottom = collisionPosTop + data.collisionHeight - outerHeight - offsetTop, 1219 top = data.my[ 1 ] === "top", 1220 myOffset = top ? 1221 -data.elemHeight : 1222 data.my[ 1 ] === "bottom" ? 1223 data.elemHeight : 1224 0, 1225 atOffset = data.at[ 1 ] === "top" ? 1226 data.targetHeight : 1227 data.at[ 1 ] === "bottom" ? 1228 -data.targetHeight : 1229 0, 1230 offset = -2 * data.offset[ 1 ], 1231 newOverTop, 1232 newOverBottom; 1233 if ( overTop < 0 ) { 1234 newOverBottom = position.top + myOffset + atOffset + offset + data.collisionHeight - 1235 outerHeight - withinOffset; 1236 if ( newOverBottom < 0 || newOverBottom < abs( overTop ) ) { 1237 position.top += myOffset + atOffset + offset; 1238 } 1239 } else if ( overBottom > 0 ) { 1240 newOverTop = position.top - data.collisionPosition.marginTop + myOffset + atOffset + 1241 offset - offsetTop; 1242 if ( newOverTop > 0 || abs( newOverTop ) < overBottom ) { 1243 position.top += myOffset + atOffset + offset; 1244 } 1245 } 1246 } 1247 }, 1248 flipfit: { 1249 left: function() { 1250 $.ui.position.flip.left.apply( this, arguments ); 1251 $.ui.position.fit.left.apply( this, arguments ); 1252 }, 1253 top: function() { 1254 $.ui.position.flip.top.apply( this, arguments ); 1255 $.ui.position.fit.top.apply( this, arguments ); 1256 } 1257 } 1258}; 1259 1260} )(); 1261 1262var position = $.ui.position; 1263 1264 1265/*! 1266 * jQuery UI
vendor: 6,652 bytes, lines 1266-1541
1266Keycode 1.13.2 1267 * http://jqueryui.com 1268 * 1269 * Copyright jQuery Foundation and other contributors 1270 * Released under the MIT license. 1271 * http://jquery.org/license 1272 */ 1273 1274//>>label: Keycode 1275//>>group: Core 1276//>>description: Provide keycodes as keynames 1277//>>docs: http://api.jqueryui.com/jQuery.ui.keyCode/ 1278 1279 1280var keycode = $.ui.keyCode = { 1281 BACKSPACE: 8, 1282 COMMA: 188, 1283 DELETE: 46, 1284 DOWN: 40, 1285 END: 35, 1286 ENTER: 13, 1287 ESCAPE: 27, 1288 HOME: 36, 1289 LEFT: 37, 1290 PAGE_DOWN: 34, 1291 PAGE_UP: 33, 1292 PERIOD: 190, 1293 RIGHT: 39, 1294 SPACE: 32, 1295 TAB: 9, 1296 UP: 38 1297}; 1298 1299 1300/*! 1301 * jQuery UI Unique ID 1.13.2 1302 * http://jqueryui.com 1303 * 1304 * Copyright jQuery Foundation and other contributors 1305 * Released under the MIT license. 1306 * http://jquery.org/license 1307 */ 1308 1309//>>label: uniqueId 1310//>>group: Core 1311//>>description: Functions to generate and remove uniqueId's 1312//>>docs: http://api.jqueryui.com/uniqueId/ 1313 1314 1315var uniqueId = $.fn.extend( { 1316 uniqueId: ( function() { 1317 var uuid = 0; 1318 1319 return function() { 1320 return this.each( function() { 1321 if ( !this.id ) { 1322 this.id = "ui-id-" + ( ++uuid ); 1323 } 1324 } ); 1325 }; 1326 } )(), 1327 1328 removeUniqueId: function() { 1329 return this.each( function() { 1330 if ( /^ui-id-\d+$/.test( this.id ) ) { 1331 $( this ).removeAttr( "id" ); 1332 } 1333 } ); 1334 } 1335} ); 1336 1337 1338 1339var safeActiveElement = $.ui.safeActiveElement = function( document ) { 1340 var activeElement; 1341 1342 // Support: IE 9 only 1343 // IE9 throws an "Unspecified error" accessing document.activeElement from an <iframe> 1344 try { 1345 activeElement = document.activeElement; 1346 } catch ( error ) { 1347 activeElement = document.body; 1348 } 1349 1350 // Support: IE 9 - 11 only 1351 // IE may return null instead of an element 1352 // Interestingly, this only seems to occur when NOT in an iframe 1353 if ( !activeElement ) { 1354 activeElement = document.body; 1355 } 1356 1357 // Support: IE 11 only 1358 // IE11 returns a seemingly empty object in some cases when accessing 1359 // document.activeElement from an <iframe> 1360 if ( !activeElement.nodeName ) { 1361 activeElement = document.body; 1362 } 1363 1364 return activeElement; 1365}; 1366 1367 1368/*! 1369 * jQuery UI Menu 1.13.2 1370 * http://jqueryui.com 1371 * 1372 * Copyright jQuery Foundation and other contributors 1373 * Released under the MIT license. 1374 * http://jquery.org/license 1375 */ 1376 1377//>>label: Menu 1378//>>group: Widgets 1379//>>description: Creates nestable menus. 1380//>>docs: http://api.jqueryui.com/menu/ 1381//>>demos: http://jqueryui.com/menu/ 1382//>>css.structure: ../../themes/base/core.css 1383//>>css.structure: ../../themes/base/menu.css 1384//>>css.theme: ../../themes/base/theme.css 1385 1386 1387var widgetsMenu = $.widget( "ui.menu", { 1388 version: "1.13.2", 1389 defaultElement: "<ul>", 1390 delay: 300, 1391 options: { 1392 icons: { 1393 submenu: "ui-icon-caret-1-e" 1394 }, 1395 items: "> *", 1396 menus: "ul", 1397 position: { 1398 my: "left top", 1399 at: "right top" 1400 }, 1401 role: "menu", 1402 1403 // Callbacks 1404 blur: null, 1405 focus: null, 1406 select: null 1407 }, 1408 1409 _create: function() { 1410 this.activeMenu = this.element; 1411 1412 // Flag used to prevent firing of the click handler 1413 // as the event bubbles up through nested menus 1414 this.mouseHandled = false; 1415 this.lastMousePosition = { x: null, y: null }; 1416 this.element 1417 .uniqueId() 1418 .attr( { 1419 role: this.options.role, 1420 tabIndex: 0 1421 } ); 1422 1423 this._addClass( "ui-menu", "ui-widget ui-widget-content" ); 1424 this._on( { 1425 1426 // Prevent focus from sticking to links inside menu after clicking 1427 // them (focus should always stay on UL during navigation). 1428 "mousedown .ui-menu-item": function( event ) { 1429 event.preventDefault(); 1430 1431 this._activateItem( event ); 1432 }, 1433 "click .ui-menu-item": function( event ) { 1434 var target = $( event.target ); 1435 var active = $( $.ui.safeActiveElement( this.document[ 0 ] ) ); 1436 if ( !this.mouseHandled && target.not( ".ui-state-disabled" ).length ) { 1437 this.select( event ); 1438 1439 // Only set the mouseHandled flag if the event will bubble, see #9469. 1440 if ( !event.isPropagationStopped() ) { 1441 this.mouseHandled = true; 1442 } 1443 1444 // Open submenu on click 1445 if ( target.has( ".ui-menu" ).length ) { 1446 this.expand( event ); 1447 } else if ( !this.element.is( ":focus" ) && 1448 active.closest( ".ui-menu" ).length ) { 1449 1450 // Redirect focus to the menu 1451 this.element.trigger( "focus", [ true ] ); 1452 1453 // If the active item is on the top level, let it stay active. 1454 // Otherwise, blur the active item since it is no longer visible. 1455 if ( this.active && this.active.parents( ".ui-menu" ).length === 1 ) { 1456 clearTimeout( this.timer ); 1457 } 1458 } 1459 } 1460 }, 1461 "mouseenter .ui-menu-item": "_activateItem", 1462 "mousemove .ui-menu-item": "_activateItem", 1463 mouseleave: "collapseAll", 1464 "mouseleave .ui-menu": "collapseAll", 1465 focus: function( event, keepActiveItem ) { 1466 1467 // If there's already an active item, keep it active 1468 // If not, activate the first item 1469 var item = this.active || this._menuItems().first(); 1470 1471 if ( !keepActiveItem ) { 1472 this.focus( event, item ); 1473 } 1474 }, 1475 blur: function( event ) { 1476 this._delay( function() { 1477 var notContained = !$.contains( 1478 this.element[ 0 ], 1479 $.ui.safeActiveElement( this.document[ 0 ] ) 1480 ); 1481 if ( notContained ) { 1482 this.collapseAll( event ); 1483 } 1484 } ); 1485 }, 1486 keydown: "_keydown" 1487 } ); 1488 1489 this.refresh(); 1490 1491 // Clicks outside of a menu collapse any open menus 1492 this._on( this.document, { 1493 click: function( event ) { 1494 if ( this._closeOnDocumentClick( event ) ) { 1495 this.collapseAll( event, true ); 1496 } 1497 1498 // Reset the mouseHandled flag 1499 this.mouseHandled = false; 1500 } 1501 } ); 1502 }, 1503 1504 _activateItem: function( event ) { 1505 1506 // Ignore mouse events while typeahead is active, see #10458. 1507 // Prevents focusing the wrong item when typeahead causes a scroll while the mouse 1508 // is over an item in the menu 1509 if ( this.previousFilter ) { 1510 return; 1511 } 1512 1513 // If the mouse didn't actually move, but the page was scrolled, ignore the event (#9356) 1514 if ( event.clientX === this.lastMousePosition.x && 1515 event.clientY === this.lastMousePosition.y ) { 1516 return; 1517 } 1518 1519 this.lastMousePosition = { 1520 x: event.clientX, 1521 y: event.clientY 1522 }; 1523 1524 var actualTarget = $( event.target ).closest( ".ui-menu-item" ), 1525 target = $( event.currentTarget ); 1526 1527 // Ignore bubbled events on parent items, see #11641 1528 if ( actualTarget[ 0 ] !== target[ 0 ] ) { 1529 return; 1530 } 1531 1532 // If the item is already active, there's nothing to do 1533 if ( target.is( ".ui-state-active" ) ) { 1534 return; 1535 } 1536 1537 // Remove ui-state-active class from siblings of the newly focused menu item 1538 // to avoid a jump caused by adjacent elements both having a class with a border 1539 this._removeClass( target.siblings().children( ".ui-state-active" ), 1540 null, "ui-state-active" ); 1541 this.focus( event, target
vendor: 8,513 bytes, lines 1541-1856
1541 ); 1542 }, 1543 1544 _destroy: function() { 1545 var items = this.element.find( ".ui-menu-item" ) 1546 .removeAttr( "role aria-disabled" ), 1547 submenus = items.children( ".ui-menu-item-wrapper" ) 1548 .removeUniqueId() 1549 .removeAttr( "tabIndex role aria-haspopup" ); 1550 1551 // Destroy (sub)menus 1552 this.element 1553 .removeAttr( "aria-activedescendant" ) 1554 .find( ".ui-menu" ).addBack() 1555 .removeAttr( "role aria-labelledby aria-expanded aria-hidden aria-disabled " + 1556 "tabIndex" ) 1557 .removeUniqueId() 1558 .show(); 1559 1560 submenus.children().each( function() { 1561 var elem = $( this ); 1562 if ( elem.data( "ui-menu-submenu-caret" ) ) { 1563 elem.remove(); 1564 } 1565 } ); 1566 }, 1567 1568 _keydown: function( event ) { 1569 var match, prev, character, skip, 1570 preventDefault = true; 1571 1572 switch ( event.keyCode ) { 1573 case $.ui.keyCode.PAGE_UP: 1574 this.previousPage( event ); 1575 break; 1576 case $.ui.keyCode.PAGE_DOWN: 1577 this.nextPage( event ); 1578 break; 1579 case $.ui.keyCode.HOME: 1580 this._move( "first", "first", event ); 1581 break; 1582 case $.ui.keyCode.END: 1583 this._move( "last", "last", event ); 1584 break; 1585 case $.ui.keyCode.UP: 1586 this.previous( event ); 1587 break; 1588 case $.ui.keyCode.DOWN: 1589 this.next( event ); 1590 break; 1591 case $.ui.keyCode.LEFT: 1592 this.collapse( event ); 1593 break; 1594 case $.ui.keyCode.RIGHT: 1595 if ( this.active && !this.active.is( ".ui-state-disabled" ) ) { 1596 this.expand( event ); 1597 } 1598 break; 1599 case $.ui.keyCode.ENTER: 1600 case $.ui.keyCode.SPACE: 1601 this._activate( event ); 1602 break; 1603 case $.ui.keyCode.ESCAPE: 1604 this.collapse( event ); 1605 break; 1606 default: 1607 preventDefault = false; 1608 prev = this.previousFilter || ""; 1609 skip = false; 1610 1611 // Support number pad values 1612 character = event.keyCode >= 96 && event.keyCode <= 105 ? 1613 ( event.keyCode - 96 ).toString() : String.fromCharCode( event.keyCode ); 1614 1615 clearTimeout( this.filterTimer ); 1616 1617 if ( character === prev ) { 1618 skip = true; 1619 } else { 1620 character = prev + character; 1621 } 1622 1623 match = this._filterMenuItems( character ); 1624 match = skip && match.index( this.active.next() ) !== -1 ? 1625 this.active.nextAll( ".ui-menu-item" ) : 1626 match; 1627 1628 // If no matches on the current filter, reset to the last character pressed 1629 // to move down the menu to the first item that starts with that character 1630 if ( !match.length ) { 1631 character = String.fromCharCode( event.keyCode ); 1632 match = this._filterMenuItems( character ); 1633 } 1634 1635 if ( match.length ) { 1636 this.focus( event, match ); 1637 this.previousFilter = character; 1638 this.filterTimer = this._delay( function() { 1639 delete this.previousFilter; 1640 }, 1000 ); 1641 } else { 1642 delete this.previousFilter; 1643 } 1644 } 1645 1646 if ( preventDefault ) { 1647 event.preventDefault(); 1648 } 1649 }, 1650 1651 _activate: function( event ) { 1652 if ( this.active && !this.active.is( ".ui-state-disabled" ) ) { 1653 if ( this.active.children( "[aria-haspopup='true']" ).length ) { 1654 this.expand( event ); 1655 } else { 1656 this.select( event ); 1657 } 1658 } 1659 }, 1660 1661 refresh: function() { 1662 var menus, items, newSubmenus, newItems, newWrappers, 1663 that = this, 1664 icon = this.options.icons.submenu, 1665 submenus = this.element.find( this.options.menus ); 1666 1667 this._toggleClass( "ui-menu-icons", null, !!this.element.find( ".ui-icon" ).length ); 1668 1669 // Initialize nested menus 1670 newSubmenus = submenus.filter( ":not(.ui-menu)" ) 1671 .hide() 1672 .attr( { 1673 role: this.options.role, 1674 "aria-hidden": "true", 1675 "aria-expanded": "false" 1676 } ) 1677 .each( function() { 1678 var menu = $( this ), 1679 item = menu.prev(), 1680 submenuCaret = $( "<span>" ).data( "ui-menu-submenu-caret", true ); 1681 1682 that._addClass( submenuCaret, "ui-menu-icon", "ui-icon " + icon ); 1683 item 1684 .attr( "aria-haspopup", "true" ) 1685 .prepend( submenuCaret ); 1686 menu.attr( "aria-labelledby", item.attr( "id" ) ); 1687 } ); 1688 1689 this._addClass( newSubmenus, "ui-menu", "ui-widget ui-widget-content ui-front" ); 1690 1691 menus = submenus.add( this.element ); 1692 items = menus.find( this.options.items ); 1693 1694 // Initialize menu-items containing spaces and/or dashes only as dividers 1695 items.not( ".ui-menu-item" ).each( function() { 1696 var item = $( this ); 1697 if ( that._isDivider( item ) ) { 1698 that._addClass( item, "ui-menu-divider", "ui-widget-content" ); 1699 } 1700 } ); 1701 1702 // Don't refresh list items that are already adapted 1703 newItems = items.not( ".ui-menu-item, .ui-menu-divider" ); 1704 newWrappers = newItems.children() 1705 .not( ".ui-menu" ) 1706 .uniqueId() 1707 .attr( { 1708 tabIndex: -1, 1709 role: this._itemRole() 1710 } ); 1711 this._addClass( newItems, "ui-menu-item" ) 1712 ._addClass( newWrappers, "ui-menu-item-wrapper" ); 1713 1714 // Add aria-disabled attribute to any disabled menu item 1715 items.filter( ".ui-state-disabled" ).attr( "aria-disabled", "true" ); 1716 1717 // If the active item has been removed, blur the menu 1718 if ( this.active && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) { 1719 this.blur(); 1720 } 1721 }, 1722 1723 _itemRole: function() { 1724 return { 1725 menu: "menuitem", 1726 listbox: "option" 1727 }[ this.options.role ]; 1728 }, 1729 1730 _setOption: function( key, value ) { 1731 if ( key === "icons" ) { 1732 var icons = this.element.find( ".ui-menu-icon" ); 1733 this._removeClass( icons, null, this.options.icons.submenu ) 1734 ._addClass( icons, null, value.submenu ); 1735 } 1736 this._super( key, value ); 1737 }, 1738 1739 _setOptionDisabled: function( value ) { 1740 this._super( value ); 1741 1742 this.element.attr( "aria-disabled", String( value ) ); 1743 this._toggleClass( null, "ui-state-disabled", !!value ); 1744 }, 1745 1746 focus: function( event, item ) { 1747 var nested, focused, activeParent; 1748 this.blur( event, event && event.type === "focus" ); 1749 1750 this._scrollIntoView( item ); 1751 1752 this.active = item.first(); 1753 1754 focused = this.active.children( ".ui-menu-item-wrapper" ); 1755 this._addClass( focused, null, "ui-state-active" ); 1756 1757 // Only update aria-activedescendant if there's a role 1758 // otherwise we assume focus is managed elsewhere 1759 if ( this.options.role ) { 1760 this.element.attr( "aria-activedescendant", focused.attr( "id" ) ); 1761 } 1762 1763 // Highlight active parent menu item, if any 1764 activeParent = this.active 1765 .parent() 1766 .closest( ".ui-menu-item" ) 1767 .children( ".ui-menu-item-wrapper" ); 1768 this._addClass( activeParent, null, "ui-state-active" ); 1769 1770 if ( event && event.type === "keydown" ) { 1771 this._close(); 1772 } else { 1773 this.timer = this._delay( function() { 1774 this._close(); 1775 }, this.delay ); 1776 } 1777 1778 nested = item.children( ".ui-menu" ); 1779 if ( nested.length && event && ( /^mouse/.test( event.type ) ) ) { 1780 this._startOpening( nested ); 1781 } 1782 this.activeMenu = item.parent(); 1783 1784 this._trigger( "focus", event, { item: item } ); 1785 }, 1786 1787 _scrollIntoView: function( item ) { 1788 var borderTop, paddingTop, offset, scroll, elementHeight, itemHeight; 1789 if ( this._hasScroll() ) { 1790 borderTop = parseFloat( $.css( this.activeMenu[ 0 ], "borderTopWidth" ) ) || 0; 1791 paddingTop = parseFloat( $.css( this.activeMenu[ 0 ], "paddingTop" ) ) || 0; 1792 offset = item.offset().top - this.activeMenu.offset().top - borderTop - paddingTop; 1793 scroll = this.activeMenu.scrollTop(); 1794 elementHeight = this.activeMenu.height(); 1795 itemHeight = item.outerHeight(); 1796 1797 if ( offset < 0 ) { 1798 this.activeMenu.scrollTop( scroll + offset ); 1799 } else if ( offset + itemHeight > elementHeight ) { 1800 this.activeMenu.scrollTop( scroll + offset - elementHeight + itemHeight ); 1801 } 1802 } 1803 }, 1804 1805 blur: function( event, fromFocus ) { 1806 if ( !fromFocus ) { 1807 clearTimeout( this.timer ); 1808 } 1809 1810 if ( !this.active ) { 1811 return; 1812 } 1813 1814 this._removeClass( this.active.children( ".ui-menu-item-wrapper" ), 1815 null, "ui-state-active" ); 1816 1817 this._trigger( "blur", event, { item: this.active } ); 1818 this.active = null; 1819 }, 1820 1821 _startOpening: function( submenu ) { 1822 clearTimeout( this.timer ); 1823 1824 // Don't open if already open fixes a Firefox bug that caused a .5 pixel 1825 // shift in the submenu position when mousing over the caret icon 1826 if ( submenu.attr( "aria-hidden" ) !== "true" ) { 1827 return; 1828 } 1829 1830 this.timer = this._delay( function() { 1831 this._close(); 1832 this._open( submenu ); 1833 }, this.delay ); 1834 }, 1835 1836 _open: function( submenu ) { 1837 var position = $.extend( { 1838 of: this.active 1839 }, this.options.position ); 1840 1841 clearTimeout( this.timer ); 1842 this.element.find( ".ui-menu" ).not( submenu.parents( ".ui-menu" ) ) 1843 .hide() 1844 .attr( "aria-hidden", "true" ); 1845 1846 submenu 1847 .show() 1848 .removeAttr( "aria-hidden" ) 1849 .attr( "aria-expanded", "true" ) 1850 .position( position ); 1851 }, 1852 1853 collapseAll: function( event, all ) { 1854 clearTimeout( this.timer ); 1855 this.timer = this._delay( function() { 1856
vendor: 5,432 bytes, lines 1857-2060
1857 // If we were passed an event, look for the submenu that contains the event 1858 var currentMenu = all ? this.element : 1859 $( event && event.target ).closest( this.element.find( ".ui-menu" ) ); 1860 1861 // If we found no valid submenu ancestor, use the main menu to close all 1862 // sub menus anyway 1863 if ( !currentMenu.length ) { 1864 currentMenu = this.element; 1865 } 1866 1867 this._close( currentMenu ); 1868 1869 this.blur( event ); 1870 1871 // Work around active item staying active after menu is blurred 1872 this._removeClass( currentMenu.find( ".ui-state-active" ), null, "ui-state-active" ); 1873 1874 this.activeMenu = currentMenu; 1875 }, all ? 0 : this.delay ); 1876 }, 1877 1878 // With no arguments, closes the currently active menu - if nothing is active 1879 // it closes all menus. If passed an argument, it will search for menus BELOW 1880 _close: function( startMenu ) { 1881 if ( !startMenu ) { 1882 startMenu = this.active ? this.active.parent() : this.element; 1883 } 1884 1885 startMenu.find( ".ui-menu" ) 1886 .hide() 1887 .attr( "aria-hidden", "true" ) 1888 .attr( "aria-expanded", "false" ); 1889 }, 1890 1891 _closeOnDocumentClick: function( event ) { 1892 return !$( event.target ).closest( ".ui-menu" ).length; 1893 }, 1894 1895 _isDivider: function( item ) { 1896 1897 // Match hyphen, em dash, en dash 1898 return !/[^\-\u2014\u2013\s]/.test( item.text() ); 1899 }, 1900 1901 collapse: function( event ) { 1902 var newItem = this.active && 1903 this.active.parent().closest( ".ui-menu-item", this.element ); 1904 if ( newItem && newItem.length ) { 1905 this._close(); 1906 this.focus( event, newItem ); 1907 } 1908 }, 1909 1910 expand: function( event ) { 1911 var newItem = this.active && this._menuItems( this.active.children( ".ui-menu" ) ).first(); 1912 1913 if ( newItem && newItem.length ) { 1914 this._open( newItem.parent() ); 1915 1916 // Delay so Firefox will not hide activedescendant change in expanding submenu from AT 1917 this._delay( function() { 1918 this.focus( event, newItem ); 1919 } ); 1920 } 1921 }, 1922 1923 next: function( event ) { 1924 this._move( "next", "first", event ); 1925 }, 1926 1927 previous: function( event ) { 1928 this._move( "prev", "last", event ); 1929 }, 1930 1931 isFirstItem: function() { 1932 return this.active && !this.active.prevAll( ".ui-menu-item" ).length; 1933 }, 1934 1935 isLastItem: function() { 1936 return this.active && !this.active.nextAll( ".ui-menu-item" ).length; 1937 }, 1938 1939 _menuItems: function( menu ) { 1940 return ( menu || this.element ) 1941 .find( this.options.items ) 1942 .filter( ".ui-menu-item" ); 1943 }, 1944 1945 _move: function( direction, filter, event ) { 1946 var next; 1947 if ( this.active ) { 1948 if ( direction === "first" || direction === "last" ) { 1949 next = this.active 1950 [ direction === "first" ? "prevAll" : "nextAll" ]( ".ui-menu-item" ) 1951 .last(); 1952 } else { 1953 next = this.active 1954 [ direction + "All" ]( ".ui-menu-item" ) 1955 .first(); 1956 } 1957 } 1958 if ( !next || !next.length || !this.active ) { 1959 next = this._menuItems( this.activeMenu )[ filter ](); 1960 } 1961 1962 this.focus( event, next ); 1963 }, 1964 1965 nextPage: function( event ) { 1966 var item, base, height; 1967 1968 if ( !this.active ) { 1969 this.next( event ); 1970 return; 1971 } 1972 if ( this.isLastItem() ) { 1973 return; 1974 } 1975 if ( this._hasScroll() ) { 1976 base = this.active.offset().top; 1977 height = this.element.innerHeight(); 1978 1979 // jQuery 3.2 doesn't include scrollbars in innerHeight, add it back. 1980 if ( $.fn.jquery.indexOf( "3.2." ) === 0 ) { 1981 height += this.element[ 0 ].offsetHeight - this.element.outerHeight(); 1982 } 1983 1984 this.active.nextAll( ".ui-menu-item" ).each( function() { 1985 item = $( this ); 1986 return item.offset().top - base - height < 0; 1987 } ); 1988 1989 this.focus( event, item ); 1990 } else { 1991 this.focus( event, this._menuItems( this.activeMenu ) 1992 [ !this.active ? "first" : "last" ]() ); 1993 } 1994 }, 1995 1996 previousPage: function( event ) { 1997 var item, base, height; 1998 if ( !this.active ) { 1999 this.next( event ); 2000 return; 2001 } 2002 if ( this.isFirstItem() ) { 2003 return; 2004 } 2005 if ( this._hasScroll() ) { 2006 base = this.active.offset().top; 2007 height = this.element.innerHeight(); 2008 2009 // jQuery 3.2 doesn't include scrollbars in innerHeight, add it back. 2010 if ( $.fn.jquery.indexOf( "3.2." ) === 0 ) { 2011 height += this.element[ 0 ].offsetHeight - this.element.outerHeight(); 2012 } 2013 2014 this.active.prevAll( ".ui-menu-item" ).each( function() { 2015 item = $( this ); 2016 return item.offset().top - base + height > 0; 2017 } ); 2018 2019 this.focus( event, item ); 2020 } else { 2021 this.focus( event, this._menuItems( this.activeMenu ).first() ); 2022 } 2023 }, 2024 2025 _hasScroll: function() { 2026 return this.element.outerHeight() < this.element.prop( "scrollHeight" ); 2027 }, 2028 2029 select: function( event ) { 2030 2031 // TODO: It should never be possible to not have an active item at this 2032 // point, but the tests don't trigger mouseenter before click. 2033 this.active = this.active || $( event.target ).closest( ".ui-menu-item" ); 2034 var ui = { item: this.active }; 2035 if ( !this.active.has( ".ui-menu" ).length ) { 2036 this.collapseAll( event, true ); 2037 } 2038 this._trigger( "select", event, ui ); 2039 }, 2040 2041 _filterMenuItems: function( character ) { 2042 var escapedCharacter = character.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" ), 2043 regex = new RegExp( "^" + escapedCharacter, "i" ); 2044 2045 return this.activeMenu 2046 .find( this.options.items ) 2047 2048 // Only match on items, not dividers or other content (#10571) 2049 .filter( ".ui-menu-item" ) 2050 .filter( function() { 2051 return regex.test( 2052 String.prototype.trim.call( 2053 $( this ).children( ".ui-menu-item-wrapper" ).text() ) ); 2054 } ); 2055 } 2056} ); 2057 2058 2059/*! 2060 * jQuery UI Autocomplete 1.1
20603.2 2061 * http://jqueryui.com 2062 * 2063 * Copyright jQuery Foundation and other contributors 2064 * Released under the MIT license. 2065 * http://jquery.org/license 2066 */ 2067 2068//>>label: Autocomplete 2069//>>group: Widgets 2070//>>description: Lists suggested words as the user is typing. 2071//>>docs: http://api.jqueryui.com/autocomplete/ 2072//>>demos: http://jqueryui.com/autocomplete/ 2073//>>css.structure: ../../themes/base/core.css 2074//>>css.structure: ../../themes/base/autocomplete.css 2075//>>css.theme: ../../themes/base/theme.css 2076 2077 2078$.widget( "ui.autocomplete", { 2079 version: "1.13.2
vendor: 16,586 bytes, lines 2079-2714
2079", 2080 defaultElement: "<input>", 2081 options: { 2082 appendTo: null, 2083 autoFocus: false, 2084 delay: 300, 2085 minLength: 1, 2086 position: { 2087 my: "left top", 2088 at: "left bottom", 2089 collision: "none" 2090 }, 2091 source: null, 2092 2093 // Callbacks 2094 change: null, 2095 close: null, 2096 focus: null, 2097 open: null, 2098 response: null, 2099 search: null, 2100 select: null 2101 }, 2102 2103 requestIndex: 0, 2104 pending: 0, 2105 liveRegionTimer: null, 2106 2107 _create: function() { 2108 2109 // Some browsers only repeat keydown events, not keypress events, 2110 // so we use the suppressKeyPress flag to determine if we've already 2111 // handled the keydown event. #7269 2112 // Unfortunately the code for & in keypress is the same as the up arrow, 2113 // so we use the suppressKeyPressRepeat flag to avoid handling keypress 2114 // events when we know the keydown event was used to modify the 2115 // search term. #7799 2116 var suppressKeyPress, suppressKeyPressRepeat, suppressInput, 2117 nodeName = this.element[ 0 ].nodeName.toLowerCase(), 2118 isTextarea = nodeName === "textarea", 2119 isInput = nodeName === "input"; 2120 2121 // Textareas are always multi-line 2122 // Inputs are always single-line, even if inside a contentEditable element 2123 // IE also treats inputs as contentEditable 2124 // All other element types are determined by whether or not they're contentEditable 2125 this.isMultiLine = isTextarea || !isInput && this._isContentEditable( this.element ); 2126 2127 this.valueMethod = this.element[ isTextarea || isInput ? "val" : "text" ]; 2128 this.isNewMenu = true; 2129 2130 this._addClass( "ui-autocomplete-input" ); 2131 this.element.attr( "autocomplete", "off" ); 2132 2133 this._on( this.element, { 2134 keydown: function( event ) { 2135 if ( this.element.prop( "readOnly" ) ) { 2136 suppressKeyPress = true; 2137 suppressInput = true; 2138 suppressKeyPressRepeat = true; 2139 return; 2140 } 2141 2142 suppressKeyPress = false; 2143 suppressInput = false; 2144 suppressKeyPressRepeat = false; 2145 var keyCode = $.ui.keyCode; 2146 switch ( event.keyCode ) { 2147 case keyCode.PAGE_UP: 2148 suppressKeyPress = true; 2149 this._move( "previousPage", event ); 2150 break; 2151 case keyCode.PAGE_DOWN: 2152 suppressKeyPress = true; 2153 this._move( "nextPage", event ); 2154 break; 2155 case keyCode.UP: 2156 suppressKeyPress = true; 2157 this._keyEvent( "previous", event ); 2158 break; 2159 case keyCode.DOWN: 2160 suppressKeyPress = true; 2161 this._keyEvent( "next", event ); 2162 break; 2163 case keyCode.ENTER: 2164 2165 // when menu is open and has focus 2166 if ( this.menu.active ) { 2167 2168 // #6055 - Opera still allows the keypress to occur 2169 // which causes forms to submit 2170 suppressKeyPress = true; 2171 event.preventDefault(); 2172 this.menu.select( event ); 2173 } 2174 break; 2175 case keyCode.TAB: 2176 if ( this.menu.active ) { 2177 this.menu.select( event ); 2178 } 2179 break; 2180 case keyCode.ESCAPE: 2181 if ( this.menu.element.is( ":visible" ) ) { 2182 if ( !this.isMultiLine ) { 2183 this._value( this.term ); 2184 } 2185 this.close( event ); 2186 2187 // Different browsers have different default behavior for escape 2188 // Single press can mean undo or clear 2189 // Double press in IE means clear the whole form 2190 event.preventDefault(); 2191 } 2192 break; 2193 default: 2194 suppressKeyPressRepeat = true; 2195 2196 // search timeout should be triggered before the input value is changed 2197 this._searchTimeout( event ); 2198 break; 2199 } 2200 }, 2201 keypress: function( event ) { 2202 if ( suppressKeyPress ) { 2203 suppressKeyPress = false; 2204 if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) { 2205 event.preventDefault(); 2206 } 2207 return; 2208 } 2209 if ( suppressKeyPressRepeat ) { 2210 return; 2211 } 2212 2213 // Replicate some key handlers to allow them to repeat in Firefox and Opera 2214 var keyCode = $.ui.keyCode; 2215 switch ( event.keyCode ) { 2216 case keyCode.PAGE_UP: 2217 this._move( "previousPage", event ); 2218 break; 2219 case keyCode.PAGE_DOWN: 2220 this._move( "nextPage", event ); 2221 break; 2222 case keyCode.UP: 2223 this._keyEvent( "previous", event ); 2224 break; 2225 case keyCode.DOWN: 2226 this._keyEvent( "next", event ); 2227 break; 2228 } 2229 }, 2230 input: function( event ) { 2231 if ( suppressInput ) { 2232 suppressInput = false; 2233 event.preventDefault(); 2234 return; 2235 } 2236 this._searchTimeout( event ); 2237 }, 2238 focus: function() { 2239 this.selectedItem = null; 2240 this.previous = this._value(); 2241 }, 2242 blur: function( event ) { 2243 clearTimeout( this.searching ); 2244 this.close( event ); 2245 this._change( event ); 2246 } 2247 } ); 2248 2249 this._initSource(); 2250 this.menu = $( "<ul>" ) 2251 .appendTo( this._appendTo() ) 2252 .menu( { 2253 2254 // disable ARIA support, the live region takes care of that 2255 role: null 2256 } ) 2257 .hide() 2258 2259 // Support: IE 11 only, Edge <= 14 2260 // For other browsers, we preventDefault() on the mousedown event 2261 // to keep the dropdown from taking focus from the input. This doesn't 2262 // work for IE/Edge, causing problems with selection and scrolling (#9638) 2263 // Happily, IE and Edge support an "unselectable" attribute that 2264 // prevents an element from receiving focus, exactly what we want here. 2265 .attr( { 2266 "unselectable": "on" 2267 } ) 2268 .menu( "instance" ); 2269 2270 this._addClass( this.menu.element, "ui-autocomplete", "ui-front" ); 2271 this._on( this.menu.element, { 2272 mousedown: function( event ) { 2273 2274 // Prevent moving focus out of the text field 2275 event.preventDefault(); 2276 }, 2277 menufocus: function( event, ui ) { 2278 var label, item; 2279 2280 // support: Firefox 2281 // Prevent accidental activation of menu items in Firefox (#7024 #9118) 2282 if ( this.isNewMenu ) { 2283 this.isNewMenu = false; 2284 if ( event.originalEvent && /^mouse/.test( event.originalEvent.type ) ) { 2285 this.menu.blur(); 2286 2287 this.document.one( "mousemove", function() { 2288 $( event.target ).trigger( event.originalEvent ); 2289 } ); 2290 2291 return; 2292 } 2293 } 2294 2295 item = ui.item.data( "ui-autocomplete-item" ); 2296 if ( false !== this._trigger( "focus", event, { item: item } ) ) { 2297 2298 // use value to match what will end up in the input, if it was a key event 2299 if ( event.originalEvent && /^key/.test( event.originalEvent.type ) ) { 2300 this._value( item.value ); 2301 } 2302 } 2303 2304 // Announce the value in the liveRegion 2305 label = ui.item.attr( "aria-label" ) || item.value; 2306 if ( label && String.prototype.trim.call( label ).length ) { 2307 clearTimeout( this.liveRegionTimer ); 2308 this.liveRegionTimer = this._delay( function() { 2309 this.liveRegion.html( $( "<div>" ).text( label ) ); 2310 }, 100 ); 2311 } 2312 }, 2313 menuselect: function( event, ui ) { 2314 var item = ui.item.data( "ui-autocomplete-item" ), 2315 previous = this.previous; 2316 2317 // Only trigger when focus was lost (click on menu) 2318 if ( this.element[ 0 ] !== $.ui.safeActiveElement( this.document[ 0 ] ) ) { 2319 this.element.trigger( "focus" ); 2320 this.previous = previous; 2321 2322 // #6109 - IE triggers two focus events and the second 2323 // is asynchronous, so we need to reset the previous 2324 // term synchronously and asynchronously :-( 2325 this._delay( function() { 2326 this.previous = previous; 2327 this.selectedItem = item; 2328 } ); 2329 } 2330 2331 if ( false !== this._trigger( "select", event, { item: item } ) ) { 2332 this._value( item.value ); 2333 } 2334 2335 // reset the term after the select event 2336 // this allows custom select handling to work properly 2337 this.term = this._value(); 2338 2339 this.close( event ); 2340 this.selectedItem = item; 2341 } 2342 } ); 2343 2344 this.liveRegion = $( "<div>", { 2345 role: "status", 2346 "aria-live": "assertive", 2347 "aria-relevant": "additions" 2348 } ) 2349 .appendTo( this.document[ 0 ].body ); 2350 2351 this._addClass( this.liveRegion, null, "ui-helper-hidden-accessible" ); 2352 2353 // Turning off autocomplete prevents the browser from remembering the 2354 // value when navigating through history, so we re-enable autocomplete 2355 // if the page is unloaded before the widget is destroyed. #7790 2356 this._on( this.window, { 2357 beforeunload: function() { 2358 this.element.removeAttr( "autocomplete" ); 2359 } 2360 } ); 2361 }, 2362 2363 _destroy: function() { 2364 clearTimeout( this.searching ); 2365 this.element.removeAttr( "autocomplete" ); 2366 this.menu.element.remove(); 2367 this.liveRegion.remove(); 2368 }, 2369 2370 _setOption: function( key, value ) { 2371 this._super( key, value ); 2372 if ( key === "source" ) { 2373 this._initSource(); 2374 } 2375 if ( key === "appendTo" ) { 2376 this.menu.element.appendTo( this._appendTo() ); 2377 } 2378 if ( key === "disabled" && value && this.xhr ) { 2379 this.xhr.abort(); 2380 } 2381 }, 2382 2383 _isEventTargetInWidget: function( event ) { 2384 var menuElement = this.menu.element[ 0 ]; 2385 2386 return event.target === this.element[ 0 ] || 2387 event.target === menuElement || 2388 $.contains( menuElement, event.target ); 2389 }, 2390 2391 _closeOnClickOutside: function( event ) { 2392 if ( !this._isEventTargetInWidget( event ) ) { 2393 this.close(); 2394 } 2395 }, 2396 2397 _appendTo: function() { 2398 var element = this.options.appendTo; 2399 2400 if ( element ) { 2401 element = element.jquery || element.nodeType ? 2402 $( element ) : 2403 this.document.find( element ).eq( 0 ); 2404 } 2405 2406 if ( !element || !element[ 0 ] ) { 2407 element = this.element.closest( ".ui-front, dialog" ); 2408 } 2409 2410 if ( !element.length ) { 2411 element = this.document[ 0 ].body; 2412 } 2413 2414 return element; 2415 }, 2416 2417 _initSource: function() { 2418 var array, url, 2419 that = this; 2420 if ( Array.isArray( this.options.source ) ) { 2421 array = this.options.source; 2422 this.source = function( request, response ) { 2423 response( $.ui.autocomplete.filter( array, request.term ) ); 2424 }; 2425 } else if ( typeof this.options.source === "string" ) { 2426 url = this.options.source; 2427 this.source = function( request, response ) { 2428 if ( that.xhr ) { 2429 that.xhr.abort(); 2430 } 2431 that.xhr = $.ajax( { 2432 url: url, 2433 data: request, 2434 dataType: "json", 2435 success: function( data ) { 2436 response( data ); 2437 }, 2438 error: function() { 2439 response( [] ); 2440 } 2441 } ); 2442 }; 2443 } else { 2444 this.source = this.options.source; 2445 } 2446 }, 2447 2448 _searchTimeout: function( event ) { 2449 clearTimeout( this.searching ); 2450 this.searching = this._delay( function() { 2451 2452 // Search if the value has changed, or if the user retypes the same value (see #7434) 2453 var equalValues = this.term === this._value(), 2454 menuVisible = this.menu.element.is( ":visible" ), 2455 modifierKey = event.altKey || event.ctrlKey || event.metaKey || event.shiftKey; 2456 2457 if ( !equalValues || ( equalValues && !menuVisible && !modifierKey ) ) { 2458 this.selectedItem = null; 2459 this.search( null, event ); 2460 } 2461 }, this.options.delay ); 2462 }, 2463 2464 search: function( value, event ) { 2465 value = value != null ? value : this._value(); 2466 2467 // Always save the actual value, not the one passed as an argument 2468 this.term = this._value(); 2469 2470 if ( value.length < this.options.minLength ) { 2471 return this.close( event ); 2472 } 2473 2474 if ( this._trigger( "search", event ) === false ) { 2475 return; 2476 } 2477 2478 return this._search( value ); 2479 }, 2480 2481 _search: function( value ) { 2482 this.pending++; 2483 this._addClass( "ui-autocomplete-loading" ); 2484 this.cancelSearch = false; 2485 2486 this.source( { term: value }, this._response() ); 2487 }, 2488 2489 _response: function() { 2490 var index = ++this.requestIndex; 2491 2492 return function( content ) { 2493 if ( index === this.requestIndex ) { 2494 this.__response( content ); 2495 } 2496 2497 this.pending--; 2498 if ( !this.pending ) { 2499 this._removeClass( "ui-autocomplete-loading" ); 2500 } 2501 }.bind( this ); 2502 }, 2503 2504 __response: function( content ) { 2505 if ( content ) { 2506 content = this._normalize( content ); 2507 } 2508 this._trigger( "response", null, { content: content } ); 2509 if ( !this.options.disabled && content && content.length && !this.cancelSearch ) { 2510 this._suggest( content ); 2511 this._trigger( "open" ); 2512 } else { 2513 2514 // use ._close() instead of .close() so we don't cancel future searches 2515 this._close(); 2516 } 2517 }, 2518 2519 close: function( event ) { 2520 this.cancelSearch = true; 2521 this._close( event ); 2522 }, 2523 2524 _close: function( event ) { 2525 2526 // Remove the handler that closes the menu on outside clicks 2527 this._off( this.document, "mousedown" ); 2528 2529 if ( this.menu.element.is( ":visible" ) ) { 2530 this.menu.element.hide(); 2531 this.menu.blur(); 2532 this.isNewMenu = true; 2533 this._trigger( "close", event ); 2534 } 2535 }, 2536 2537 _change: function( event ) { 2538 if ( this.previous !== this._value() ) { 2539 this._trigger( "change", event, { item: this.selectedItem } ); 2540 } 2541 }, 2542 2543 _normalize: function( items ) { 2544 2545 // assume all items have the right format when the first item is complete 2546 if ( items.length && items[ 0 ].label && items[ 0 ].value ) { 2547 return items; 2548 } 2549 return $.map( items, function( item ) { 2550 if ( typeof item === "string" ) { 2551 return { 2552 label: item, 2553 value: item 2554 }; 2555 } 2556 return $.extend( {}, item, { 2557 label: item.label || item.value, 2558 value: item.value || item.label 2559 } ); 2560 } ); 2561 }, 2562 2563 _suggest: function( items ) { 2564 var ul = this.menu.element.empty(); 2565 this._renderMenu( ul, items ); 2566 this.isNewMenu = true; 2567 this.menu.refresh(); 2568 2569 // Size and position menu 2570 ul.show(); 2571 this._resizeMenu(); 2572 ul.position( $.extend( { 2573 of: this.element 2574 }, this.options.position ) ); 2575 2576 if ( this.options.autoFocus ) { 2577 this.menu.next(); 2578 } 2579 2580 // Listen for interactions outside of the widget (#6642) 2581 this._on( this.document, { 2582 mousedown: "_closeOnClickOutside" 2583 } ); 2584 }, 2585 2586 _resizeMenu: function() { 2587 var ul = this.menu.element; 2588 ul.outerWidth( Math.max( 2589 2590 // Firefox wraps long text (possibly a rounding bug) 2591 // so we add 1px to avoid the wrapping (#7513) 2592 ul.width( "" ).outerWidth() + 1, 2593 this.element.outerWidth() 2594 ) ); 2595 }, 2596 2597 _renderMenu: function( ul, items ) { 2598 var that = this; 2599 $.each( items, function( index, item ) { 2600 that._renderItemData( ul, item ); 2601 } ); 2602 }, 2603 2604 _renderItemData: function( ul, item ) { 2605 return this._renderItem( ul, item ).data( "ui-autocomplete-item", item ); 2606 }, 2607 2608 _renderItem: function( ul, item ) { 2609 return $( "<li>" ) 2610 .append( $( "<div>" ).text( item.label ) ) 2611 .appendTo( ul ); 2612 }, 2613 2614 _move: function( direction, event ) { 2615 if ( !this.menu.element.is( ":visible" ) ) { 2616 this.search( null, event ); 2617 return; 2618 } 2619 if ( this.menu.isFirstItem() && /^previous/.test( direction ) || 2620 this.menu.isLastItem() && /^next/.test( direction ) ) { 2621 2622 if ( !this.isMultiLine ) { 2623 this._value( this.term ); 2624 } 2625 2626 this.menu.blur(); 2627 return; 2628 } 2629 this.menu[ direction ]( event ); 2630 }, 2631 2632 widget: function() { 2633 return this.menu.element; 2634 }, 2635 2636 _value: function() { 2637 return this.valueMethod.apply( this.element, arguments ); 2638 }, 2639 2640 _keyEvent: function( keyEvent, event ) { 2641 if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) { 2642 this._move( keyEvent, event ); 2643 2644 // Prevents moving cursor to beginning/end of the text field in some browsers 2645 event.preventDefault(); 2646 } 2647 }, 2648 2649 // Support: Chrome <=50 2650 // We should be able to just use this.element.prop( "isContentEditable" ) 2651 // but hidden elements always report false in Chrome. 2652 // https://code.google.com/p/chromium/issues/detail?id=313082 2653 _isContentEditable: function( element ) { 2654 if ( !element.length ) { 2655 return false; 2656 } 2657 2658 var editable = element.prop( "contentEditable" ); 2659 2660 if ( editable === "inherit" ) { 2661 return this._isContentEditable( element.parent() ); 2662 } 2663 2664 return editable === "true"; 2665 } 2666} ); 2667 2668$.extend( $.ui.autocomplete, { 2669 escapeRegex: function( value ) { 2670 return value.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" ); 2671 }, 2672 filter: function( array, term ) { 2673 var matcher = new RegExp( $.ui.autocomplete.escapeRegex( term ), "i" ); 2674 return $.grep( array, function( value ) { 2675 return matcher.test( value.label || value.value || value ); 2676 } ); 2677 } 2678} ); 2679 2680// Live region extension, adding a `messages` option 2681// NOTE: This is an experimental API. We are still investigating 2682// a full solution for string manipulation and internationalization. 2683$.widget( "ui.autocomplete", $.ui.autocomplete, { 2684 options: { 2685 messages: { 2686 noResults: "No search results.", 2687 results: function( amount ) { 2688 return amount + ( amount > 1 ? " results are" : " result is" ) + 2689 " available, use up and down arrow keys to navigate."; 2690 } 2691 } 2692 }, 2693 2694 __response: function( content ) { 2695 var message; 2696 this._superApply( arguments ); 2697 if ( this.options.disabled || this.cancelSearch ) { 2698 return; 2699 } 2700 if ( content && content.length ) { 2701 message = this.options.messages.results( content.length ); 2702 } else { 2703 message = this.options.messages.noResults; 2704 } 2705 clearTimeout( this.liveRegionTimer ); 2706 this.liveRegionTimer = this._delay( function() { 2707 this.liveRegion.html( $( "<div>" ).text( message ) ); 2708 }, 100 ); 2709 } 2710} ); 2711 2712var widgetsAutocomplete = $.ui.autocomplete; 2713 2714
2715 2716 2717} );
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.