[ Index ] |
PHP Cross Reference of WordPress Trunk (Updated Daily) |
[Summary view] [Print] [Text view]
1 /*! jQuery UI - v1.13.3 - 2024-04-26 2 * https://jqueryui.com 3 * Includes: widget.js, position.js, data.js, disable-selection.js, effect.js, effects/effect-blind.js, effects/effect-bounce.js, effects/effect-clip.js, effects/effect-drop.js, effects/effect-explode.js, effects/effect-fade.js, effects/effect-fold.js, effects/effect-highlight.js, effects/effect-puff.js, effects/effect-pulsate.js, effects/effect-scale.js, effects/effect-shake.js, effects/effect-size.js, effects/effect-slide.js, effects/effect-transfer.js, focusable.js, form-reset-mixin.js, jquery-patch.js, keycode.js, labels.js, scroll-parent.js, tabbable.js, unique-id.js, widgets/accordion.js, widgets/autocomplete.js, widgets/button.js, widgets/checkboxradio.js, widgets/controlgroup.js, widgets/datepicker.js, widgets/dialog.js, widgets/draggable.js, widgets/droppable.js, widgets/menu.js, widgets/mouse.js, widgets/progressbar.js, widgets/resizable.js, widgets/selectable.js, widgets/selectmenu.js, widgets/slider.js, widgets/sortable.js, widgets/spinner.js, widgets/tabs.js, widgets/tooltip.js 4 * Copyright jQuery Foundation and other contributors; Licensed MIT */ 5 ( function( factory ) { 6 "use strict"; 7 8 if ( typeof define === "function" && define.amd ) { 9 10 // AMD. Register as an anonymous module. 11 define( [ "jquery" ], factory ); 12 } else { 13 14 // Browser globals 15 factory( jQuery ); 16 } 17 } ( function( $ ) { 18 "use strict"; 19 20 // Source: version.js 21 $.ui = $.ui || {}; 22 23 $.ui.version = "1.13.3"; 24 25 // Source: data.js 26 /*! 27 * jQuery UI :data 1.13.3 28 * https://jqueryui.com 29 * 30 * Copyright OpenJS Foundation and other contributors 31 * Released under the MIT license. 32 * https://jquery.org/license 33 */ 34 35 //>>label: :data Selector 36 //>>group: Core 37 //>>description: Selects elements which have data stored under the specified key. 38 //>>docs: https://api.jqueryui.com/data-selector/ 39 40 $.extend( $.expr.pseudos, { 41 data: $.expr.createPseudo ? 42 $.expr.createPseudo( function( dataName ) { 43 return function( elem ) { 44 return !!$.data( elem, dataName ); 45 }; 46 } ) : 47 48 // Support: jQuery <1.8 49 function( elem, i, match ) { 50 return !!$.data( elem, match[ 3 ] ); 51 } 52 } ); 53 54 // Source: disable-selection.js 55 /*! 56 * jQuery UI Disable Selection 1.13.3 57 * https://jqueryui.com 58 * 59 * Copyright OpenJS Foundation and other contributors 60 * Released under the MIT license. 61 * https://jquery.org/license 62 */ 63 64 //>>label: disableSelection 65 //>>group: Core 66 //>>description: Disable selection of text content within the set of matched elements. 67 //>>docs: https://api.jqueryui.com/disableSelection/ 68 69 // This file is deprecated 70 $.fn.extend( { 71 disableSelection: ( function() { 72 var eventType = "onselectstart" in document.createElement( "div" ) ? 73 "selectstart" : 74 "mousedown"; 75 76 return function() { 77 return this.on( eventType + ".ui-disableSelection", function( event ) { 78 event.preventDefault(); 79 } ); 80 }; 81 } )(), 82 83 enableSelection: function() { 84 return this.off( ".ui-disableSelection" ); 85 } 86 } ); 87 88 // Source: focusable.js 89 /*! 90 * jQuery UI Focusable 1.13.3 91 * https://jqueryui.com 92 * 93 * Copyright OpenJS Foundation and other contributors 94 * Released under the MIT license. 95 * https://jquery.org/license 96 */ 97 98 //>>label: :focusable Selector 99 //>>group: Core 100 //>>description: Selects elements which can be focused. 101 //>>docs: https://api.jqueryui.com/focusable-selector/ 102 103 // Selectors 104 $.ui.focusable = function( element, hasTabindex ) { 105 var map, mapName, img, focusableIfVisible, fieldset, 106 nodeName = element.nodeName.toLowerCase(); 107 108 if ( "area" === nodeName ) { 109 map = element.parentNode; 110 mapName = map.name; 111 if ( !element.href || !mapName || map.nodeName.toLowerCase() !== "map" ) { 112 return false; 113 } 114 img = $( "img[usemap='#" + mapName + "']" ); 115 return img.length > 0 && img.is( ":visible" ); 116 } 117 118 if ( /^(input|select|textarea|button|object)$/.test( nodeName ) ) { 119 focusableIfVisible = !element.disabled; 120 121 if ( focusableIfVisible ) { 122 123 // Form controls within a disabled fieldset are disabled. 124 // However, controls within the fieldset's legend do not get disabled. 125 // Since controls generally aren't placed inside legends, we skip 126 // this portion of the check. 127 fieldset = $( element ).closest( "fieldset" )[ 0 ]; 128 if ( fieldset ) { 129 focusableIfVisible = !fieldset.disabled; 130 } 131 } 132 } else if ( "a" === nodeName ) { 133 focusableIfVisible = element.href || hasTabindex; 134 } else { 135 focusableIfVisible = hasTabindex; 136 } 137 138 return focusableIfVisible && $( element ).is( ":visible" ) && visible( $( element ) ); 139 }; 140 141 // Support: IE 8 only 142 // IE 8 doesn't resolve inherit to visible/hidden for computed values 143 function visible( element ) { 144 var visibility = element.css( "visibility" ); 145 while ( visibility === "inherit" ) { 146 element = element.parent(); 147 visibility = element.css( "visibility" ); 148 } 149 return visibility === "visible"; 150 } 151 152 $.extend( $.expr.pseudos, { 153 focusable: function( element ) { 154 return $.ui.focusable( element, $.attr( element, "tabindex" ) != null ); 155 } 156 } ); 157 158 // Support: IE8 Only 159 // IE8 does not support the form attribute and when it is supplied. It overwrites the form prop 160 // with a string, so we need to find the proper form. 161 $.fn._form = function() { 162 return typeof this[ 0 ].form === "string" ? this.closest( "form" ) : $( this[ 0 ].form ); 163 }; 164 165 // Source: form-reset-mixin.js 166 /*! 167 * jQuery UI Form Reset Mixin 1.13.3 168 * https://jqueryui.com 169 * 170 * Copyright OpenJS Foundation and other contributors 171 * Released under the MIT license. 172 * https://jquery.org/license 173 */ 174 175 //>>label: Form Reset Mixin 176 //>>group: Core 177 //>>description: Refresh input widgets when their form is reset 178 //>>docs: https://api.jqueryui.com/form-reset-mixin/ 179 180 $.ui.formResetMixin = { 181 _formResetHandler: function() { 182 var form = $( this ); 183 184 // Wait for the form reset to actually happen before refreshing 185 setTimeout( function() { 186 var instances = form.data( "ui-form-reset-instances" ); 187 $.each( instances, function() { 188 this.refresh(); 189 } ); 190 } ); 191 }, 192 193 _bindFormResetHandler: function() { 194 this.form = this.element._form(); 195 if ( !this.form.length ) { 196 return; 197 } 198 199 var instances = this.form.data( "ui-form-reset-instances" ) || []; 200 if ( !instances.length ) { 201 202 // We don't use _on() here because we use a single event handler per form 203 this.form.on( "reset.ui-form-reset", this._formResetHandler ); 204 } 205 instances.push( this ); 206 this.form.data( "ui-form-reset-instances", instances ); 207 }, 208 209 _unbindFormResetHandler: function() { 210 if ( !this.form.length ) { 211 return; 212 } 213 214 var instances = this.form.data( "ui-form-reset-instances" ); 215 instances.splice( $.inArray( this, instances ), 1 ); 216 if ( instances.length ) { 217 this.form.data( "ui-form-reset-instances", instances ); 218 } else { 219 this.form 220 .removeData( "ui-form-reset-instances" ) 221 .off( "reset.ui-form-reset" ); 222 } 223 } 224 }; 225 226 // Source: ie.js 227 // This file is deprecated 228 $.ui.ie = !!/msie [\w.]+/.exec( navigator.userAgent.toLowerCase() ); 229 230 // Source: jquery-patch.js 231 /*! 232 * jQuery UI Support for jQuery core 1.8.x and newer 1.13.3 233 * https://jqueryui.com 234 * 235 * Copyright OpenJS Foundation and other contributors 236 * Released under the MIT license. 237 * https://jquery.org/license 238 * 239 */ 240 241 //>>label: jQuery 1.8+ Support 242 //>>group: Core 243 //>>description: Support version 1.8.x and newer of jQuery core 244 245 // Support: jQuery 1.9.x or older 246 // $.expr[ ":" ] is deprecated. 247 if ( !$.expr.pseudos ) { 248 $.expr.pseudos = $.expr[ ":" ]; 249 } 250 251 // Support: jQuery 1.11.x or older 252 // $.unique has been renamed to $.uniqueSort 253 if ( !$.uniqueSort ) { 254 $.uniqueSort = $.unique; 255 } 256 257 // Support: jQuery 2.2.x or older. 258 // This method has been defined in jQuery 3.0.0. 259 // Code from https://github.com/jquery/jquery/blob/e539bac79e666bba95bba86d690b4e609dca2286/src/selector/escapeSelector.js 260 if ( !$.escapeSelector ) { 261 262 // CSS string/identifier serialization 263 // https://drafts.csswg.org/cssom/#common-serializing-idioms 264 var rcssescape = /([\0-\x1f\x7f]|^-?\d)|^-$|[^\x80-\uFFFF\w-]/g; 265 266 var fcssescape = function( ch, asCodePoint ) { 267 if ( asCodePoint ) { 268 269 // U+0000 NULL becomes U+FFFD REPLACEMENT CHARACTER 270 if ( ch === "\0" ) { 271 return "\uFFFD"; 272 } 273 274 // Control characters and (dependent upon position) numbers get escaped as code points 275 return ch.slice( 0, -1 ) + "\\" + ch.charCodeAt( ch.length - 1 ).toString( 16 ) + " "; 276 } 277 278 // Other potentially-special ASCII characters get backslash-escaped 279 return "\\" + ch; 280 }; 281 282 $.escapeSelector = function( sel ) { 283 return ( sel + "" ).replace( rcssescape, fcssescape ); 284 }; 285 } 286 287 // Support: jQuery 3.4.x or older 288 // These methods have been defined in jQuery 3.5.0. 289 if ( !$.fn.even || !$.fn.odd ) { 290 $.fn.extend( { 291 even: function() { 292 return this.filter( function( i ) { 293 return i % 2 === 0; 294 } ); 295 }, 296 odd: function() { 297 return this.filter( function( i ) { 298 return i % 2 === 1; 299 } ); 300 } 301 } ); 302 } 303 304 // Source: keycode.js 305 /*! 306 * jQuery UI Keycode 1.13.3 307 * https://jqueryui.com 308 * 309 * Copyright OpenJS Foundation and other contributors 310 * Released under the MIT license. 311 * https://jquery.org/license 312 */ 313 314 //>>label: Keycode 315 //>>group: Core 316 //>>description: Provide keycodes as keynames 317 //>>docs: https://api.jqueryui.com/jQuery.ui.keyCode/ 318 319 $.ui.keyCode = { 320 BACKSPACE: 8, 321 COMMA: 188, 322 DELETE: 46, 323 DOWN: 40, 324 END: 35, 325 ENTER: 13, 326 ESCAPE: 27, 327 HOME: 36, 328 LEFT: 37, 329 PAGE_DOWN: 34, 330 PAGE_UP: 33, 331 PERIOD: 190, 332 RIGHT: 39, 333 SPACE: 32, 334 TAB: 9, 335 UP: 38 336 }; 337 338 // Source: labels.js 339 /*! 340 * jQuery UI Labels 1.13.3 341 * https://jqueryui.com 342 * 343 * Copyright OpenJS Foundation and other contributors 344 * Released under the MIT license. 345 * https://jquery.org/license 346 */ 347 348 //>>label: labels 349 //>>group: Core 350 //>>description: Find all the labels associated with a given input 351 //>>docs: https://api.jqueryui.com/labels/ 352 353 $.fn.labels = function() { 354 var ancestor, selector, id, labels, ancestors; 355 356 if ( !this.length ) { 357 return this.pushStack( [] ); 358 } 359 360 // Check control.labels first 361 if ( this[ 0 ].labels && this[ 0 ].labels.length ) { 362 return this.pushStack( this[ 0 ].labels ); 363 } 364 365 // Support: IE <= 11, FF <= 37, Android <= 2.3 only 366 // Above browsers do not support control.labels. Everything below is to support them 367 // as well as document fragments. control.labels does not work on document fragments 368 labels = this.eq( 0 ).parents( "label" ); 369 370 // Look for the label based on the id 371 id = this.attr( "id" ); 372 if ( id ) { 373 374 // We don't search against the document in case the element 375 // is disconnected from the DOM 376 ancestor = this.eq( 0 ).parents().last(); 377 378 // Get a full set of top level ancestors 379 ancestors = ancestor.add( ancestor.length ? ancestor.siblings() : this.siblings() ); 380 381 // Create a selector for the label based on the id 382 selector = "label[for='" + $.escapeSelector( id ) + "']"; 383 384 labels = labels.add( ancestors.find( selector ).addBack( selector ) ); 385 386 } 387 388 // Return whatever we have found for labels 389 return this.pushStack( labels ); 390 }; 391 392 // Source: plugin.js 393 // $.ui.plugin is deprecated. Use $.widget() extensions instead. 394 $.ui.plugin = { 395 add: function( module, option, set ) { 396 var i, 397 proto = $.ui[ module ].prototype; 398 for ( i in set ) { 399 proto.plugins[ i ] = proto.plugins[ i ] || []; 400 proto.plugins[ i ].push( [ option, set[ i ] ] ); 401 } 402 }, 403 call: function( instance, name, args, allowDisconnected ) { 404 var i, 405 set = instance.plugins[ name ]; 406 407 if ( !set ) { 408 return; 409 } 410 411 if ( !allowDisconnected && ( !instance.element[ 0 ].parentNode || 412 instance.element[ 0 ].parentNode.nodeType === 11 ) ) { 413 return; 414 } 415 416 for ( i = 0; i < set.length; i++ ) { 417 if ( instance.options[ set[ i ][ 0 ] ] ) { 418 set[ i ][ 1 ].apply( instance.element, args ); 419 } 420 } 421 } 422 }; 423 424 // Source: position.js 425 /*! 426 * jQuery UI Position 1.13.3 427 * https://jqueryui.com 428 * 429 * Copyright OpenJS Foundation and other contributors 430 * Released under the MIT license. 431 * https://jquery.org/license 432 * 433 * https://api.jqueryui.com/position/ 434 */ 435 436 //>>label: Position 437 //>>group: Core 438 //>>description: Positions elements relative to other elements. 439 //>>docs: https://api.jqueryui.com/position/ 440 //>>demos: https://jqueryui.com/position/ 441 442 ( function() { 443 var cachedScrollbarWidth, 444 max = Math.max, 445 abs = Math.abs, 446 rhorizontal = /left|center|right/, 447 rvertical = /top|center|bottom/, 448 roffset = /[\+\-]\d+(\.[\d]+)?%?/, 449 rposition = /^\w+/, 450 rpercent = /%$/, 451 _position = $.fn.position; 452 453 function getOffsets( offsets, width, height ) { 454 return [ 455 parseFloat( offsets[ 0 ] ) * ( rpercent.test( offsets[ 0 ] ) ? width / 100 : 1 ), 456 parseFloat( offsets[ 1 ] ) * ( rpercent.test( offsets[ 1 ] ) ? height / 100 : 1 ) 457 ]; 458 } 459 460 function parseCss( element, property ) { 461 return parseInt( $.css( element, property ), 10 ) || 0; 462 } 463 464 function isWindow( obj ) { 465 return obj != null && obj === obj.window; 466 } 467 468 function getDimensions( elem ) { 469 var raw = elem[ 0 ]; 470 if ( raw.nodeType === 9 ) { 471 return { 472 width: elem.width(), 473 height: elem.height(), 474 offset: { top: 0, left: 0 } 475 }; 476 } 477 if ( isWindow( raw ) ) { 478 return { 479 width: elem.width(), 480 height: elem.height(), 481 offset: { top: elem.scrollTop(), left: elem.scrollLeft() } 482 }; 483 } 484 if ( raw.preventDefault ) { 485 return { 486 width: 0, 487 height: 0, 488 offset: { top: raw.pageY, left: raw.pageX } 489 }; 490 } 491 return { 492 width: elem.outerWidth(), 493 height: elem.outerHeight(), 494 offset: elem.offset() 495 }; 496 } 497 498 $.position = { 499 scrollbarWidth: function() { 500 if ( cachedScrollbarWidth !== undefined ) { 501 return cachedScrollbarWidth; 502 } 503 var w1, w2, 504 div = $( "<div style=" + 505 "'display:block;position:absolute;width:200px;height:200px;overflow:hidden;'>" + 506 "<div style='height:300px;width:auto;'></div></div>" ), 507 innerDiv = div.children()[ 0 ]; 508 509 $( "body" ).append( div ); 510 w1 = innerDiv.offsetWidth; 511 div.css( "overflow", "scroll" ); 512 513 w2 = innerDiv.offsetWidth; 514 515 if ( w1 === w2 ) { 516 w2 = div[ 0 ].clientWidth; 517 } 518 519 div.remove(); 520 521 return ( cachedScrollbarWidth = w1 - w2 ); 522 }, 523 getScrollInfo: function( within ) { 524 var overflowX = within.isWindow || within.isDocument ? "" : 525 within.element.css( "overflow-x" ), 526 overflowY = within.isWindow || within.isDocument ? "" : 527 within.element.css( "overflow-y" ), 528 hasOverflowX = overflowX === "scroll" || 529 ( overflowX === "auto" && within.width < within.element[ 0 ].scrollWidth ), 530 hasOverflowY = overflowY === "scroll" || 531 ( overflowY === "auto" && within.height < within.element[ 0 ].scrollHeight ); 532 return { 533 width: hasOverflowY ? $.position.scrollbarWidth() : 0, 534 height: hasOverflowX ? $.position.scrollbarWidth() : 0 535 }; 536 }, 537 getWithinInfo: function( element ) { 538 var withinElement = $( element || window ), 539 isElemWindow = isWindow( withinElement[ 0 ] ), 540 isDocument = !!withinElement[ 0 ] && withinElement[ 0 ].nodeType === 9, 541 hasOffset = !isElemWindow && !isDocument; 542 return { 543 element: withinElement, 544 isWindow: isElemWindow, 545 isDocument: isDocument, 546 offset: hasOffset ? $( element ).offset() : { left: 0, top: 0 }, 547 scrollLeft: withinElement.scrollLeft(), 548 scrollTop: withinElement.scrollTop(), 549 width: withinElement.outerWidth(), 550 height: withinElement.outerHeight() 551 }; 552 } 553 }; 554 555 $.fn.position = function( options ) { 556 if ( !options || !options.of ) { 557 return _position.apply( this, arguments ); 558 } 559 560 // Make a copy, we don't want to modify arguments 561 options = $.extend( {}, options ); 562 563 var atOffset, targetWidth, targetHeight, targetOffset, basePosition, dimensions, 564 565 // Make sure string options are treated as CSS selectors 566 target = typeof options.of === "string" ? 567 $( document ).find( options.of ) : 568 $( options.of ), 569 570 within = $.position.getWithinInfo( options.within ), 571 scrollInfo = $.position.getScrollInfo( within ), 572 collision = ( options.collision || "flip" ).split( " " ), 573 offsets = {}; 574 575 dimensions = getDimensions( target ); 576 if ( target[ 0 ].preventDefault ) { 577 578 // Force left top to allow flipping 579 options.at = "left top"; 580 } 581 targetWidth = dimensions.width; 582 targetHeight = dimensions.height; 583 targetOffset = dimensions.offset; 584 585 // Clone to reuse original targetOffset later 586 basePosition = $.extend( {}, targetOffset ); 587 588 // Force my and at to have valid horizontal and vertical positions 589 // if a value is missing or invalid, it will be converted to center 590 $.each( [ "my", "at" ], function() { 591 var pos = ( options[ this ] || "" ).split( " " ), 592 horizontalOffset, 593 verticalOffset; 594 595 if ( pos.length === 1 ) { 596 pos = rhorizontal.test( pos[ 0 ] ) ? 597 pos.concat( [ "center" ] ) : 598 rvertical.test( pos[ 0 ] ) ? 599 [ "center" ].concat( pos ) : 600 [ "center", "center" ]; 601 } 602 pos[ 0 ] = rhorizontal.test( pos[ 0 ] ) ? pos[ 0 ] : "center"; 603 pos[ 1 ] = rvertical.test( pos[ 1 ] ) ? pos[ 1 ] : "center"; 604 605 // Calculate offsets 606 horizontalOffset = roffset.exec( pos[ 0 ] ); 607 verticalOffset = roffset.exec( pos[ 1 ] ); 608 offsets[ this ] = [ 609 horizontalOffset ? horizontalOffset[ 0 ] : 0, 610 verticalOffset ? verticalOffset[ 0 ] : 0 611 ]; 612 613 // Reduce to just the positions without the offsets 614 options[ this ] = [ 615 rposition.exec( pos[ 0 ] )[ 0 ], 616 rposition.exec( pos[ 1 ] )[ 0 ] 617 ]; 618 } ); 619 620 // Normalize collision option 621 if ( collision.length === 1 ) { 622 collision[ 1 ] = collision[ 0 ]; 623 } 624 625 if ( options.at[ 0 ] === "right" ) { 626 basePosition.left += targetWidth; 627 } else if ( options.at[ 0 ] === "center" ) { 628 basePosition.left += targetWidth / 2; 629 } 630 631 if ( options.at[ 1 ] === "bottom" ) { 632 basePosition.top += targetHeight; 633 } else if ( options.at[ 1 ] === "center" ) { 634 basePosition.top += targetHeight / 2; 635 } 636 637 atOffset = getOffsets( offsets.at, targetWidth, targetHeight ); 638 basePosition.left += atOffset[ 0 ]; 639 basePosition.top += atOffset[ 1 ]; 640 641 return this.each( function() { 642 var collisionPosition, using, 643 elem = $( this ), 644 elemWidth = elem.outerWidth(), 645 elemHeight = elem.outerHeight(), 646 marginLeft = parseCss( this, "marginLeft" ), 647 marginTop = parseCss( this, "marginTop" ), 648 collisionWidth = elemWidth + marginLeft + parseCss( this, "marginRight" ) + 649 scrollInfo.width, 650 collisionHeight = elemHeight + marginTop + parseCss( this, "marginBottom" ) + 651 scrollInfo.height, 652 position = $.extend( {}, basePosition ), 653 myOffset = getOffsets( offsets.my, elem.outerWidth(), elem.outerHeight() ); 654 655 if ( options.my[ 0 ] === "right" ) { 656 position.left -= elemWidth; 657 } else if ( options.my[ 0 ] === "center" ) { 658 position.left -= elemWidth / 2; 659 } 660 661 if ( options.my[ 1 ] === "bottom" ) { 662 position.top -= elemHeight; 663 } else if ( options.my[ 1 ] === "center" ) { 664 position.top -= elemHeight / 2; 665 } 666 667 position.left += myOffset[ 0 ]; 668 position.top += myOffset[ 1 ]; 669 670 collisionPosition = { 671 marginLeft: marginLeft, 672 marginTop: marginTop 673 }; 674 675 $.each( [ "left", "top" ], function( i, dir ) { 676 if ( $.ui.position[ collision[ i ] ] ) { 677 $.ui.position[ collision[ i ] ][ dir ]( position, { 678 targetWidth: targetWidth, 679 targetHeight: targetHeight, 680 elemWidth: elemWidth, 681 elemHeight: elemHeight, 682 collisionPosition: collisionPosition, 683 collisionWidth: collisionWidth, 684 collisionHeight: collisionHeight, 685 offset: [ atOffset[ 0 ] + myOffset[ 0 ], atOffset [ 1 ] + myOffset[ 1 ] ], 686 my: options.my, 687 at: options.at, 688 within: within, 689 elem: elem 690 } ); 691 } 692 } ); 693 694 if ( options.using ) { 695 696 // Adds feedback as second argument to using callback, if present 697 using = function( props ) { 698 var left = targetOffset.left - position.left, 699 right = left + targetWidth - elemWidth, 700 top = targetOffset.top - position.top, 701 bottom = top + targetHeight - elemHeight, 702 feedback = { 703 target: { 704 element: target, 705 left: targetOffset.left, 706 top: targetOffset.top, 707 width: targetWidth, 708 height: targetHeight 709 }, 710 element: { 711 element: elem, 712 left: position.left, 713 top: position.top, 714 width: elemWidth, 715 height: elemHeight 716 }, 717 horizontal: right < 0 ? "left" : left > 0 ? "right" : "center", 718 vertical: bottom < 0 ? "top" : top > 0 ? "bottom" : "middle" 719 }; 720 if ( targetWidth < elemWidth && abs( left + right ) < targetWidth ) { 721 feedback.horizontal = "center"; 722 } 723 if ( targetHeight < elemHeight && abs( top + bottom ) < targetHeight ) { 724 feedback.vertical = "middle"; 725 } 726 if ( max( abs( left ), abs( right ) ) > max( abs( top ), abs( bottom ) ) ) { 727 feedback.important = "horizontal"; 728 } else { 729 feedback.important = "vertical"; 730 } 731 options.using.call( this, props, feedback ); 732 }; 733 } 734 735 elem.offset( $.extend( position, { using: using } ) ); 736 } ); 737 }; 738 739 $.ui.position = { 740 fit: { 741 left: function( position, data ) { 742 var within = data.within, 743 withinOffset = within.isWindow ? within.scrollLeft : within.offset.left, 744 outerWidth = within.width, 745 collisionPosLeft = position.left - data.collisionPosition.marginLeft, 746 overLeft = withinOffset - collisionPosLeft, 747 overRight = collisionPosLeft + data.collisionWidth - outerWidth - withinOffset, 748 newOverRight; 749 750 // Element is wider than within 751 if ( data.collisionWidth > outerWidth ) { 752 753 // Element is initially over the left side of within 754 if ( overLeft > 0 && overRight <= 0 ) { 755 newOverRight = position.left + overLeft + data.collisionWidth - outerWidth - 756 withinOffset; 757 position.left += overLeft - newOverRight; 758 759 // Element is initially over right side of within 760 } else if ( overRight > 0 && overLeft <= 0 ) { 761 position.left = withinOffset; 762 763 // Element is initially over both left and right sides of within 764 } else { 765 if ( overLeft > overRight ) { 766 position.left = withinOffset + outerWidth - data.collisionWidth; 767 } else { 768 position.left = withinOffset; 769 } 770 } 771 772 // Too far left -> align with left edge 773 } else if ( overLeft > 0 ) { 774 position.left += overLeft; 775 776 // Too far right -> align with right edge 777 } else if ( overRight > 0 ) { 778 position.left -= overRight; 779 780 // Adjust based on position and margin 781 } else { 782 position.left = max( position.left - collisionPosLeft, position.left ); 783 } 784 }, 785 top: function( position, data ) { 786 var within = data.within, 787 withinOffset = within.isWindow ? within.scrollTop : within.offset.top, 788 outerHeight = data.within.height, 789 collisionPosTop = position.top - data.collisionPosition.marginTop, 790 overTop = withinOffset - collisionPosTop, 791 overBottom = collisionPosTop + data.collisionHeight - outerHeight - withinOffset, 792 newOverBottom; 793 794 // Element is taller than within 795 if ( data.collisionHeight > outerHeight ) { 796 797 // Element is initially over the top of within 798 if ( overTop > 0 && overBottom <= 0 ) { 799 newOverBottom = position.top + overTop + data.collisionHeight - outerHeight - 800 withinOffset; 801 position.top += overTop - newOverBottom; 802 803 // Element is initially over bottom of within 804 } else if ( overBottom > 0 && overTop <= 0 ) { 805 position.top = withinOffset; 806 807 // Element is initially over both top and bottom of within 808 } else { 809 if ( overTop > overBottom ) { 810 position.top = withinOffset + outerHeight - data.collisionHeight; 811 } else { 812 position.top = withinOffset; 813 } 814 } 815 816 // Too far up -> align with top 817 } else if ( overTop > 0 ) { 818 position.top += overTop; 819 820 // Too far down -> align with bottom edge 821 } else if ( overBottom > 0 ) { 822 position.top -= overBottom; 823 824 // Adjust based on position and margin 825 } else { 826 position.top = max( position.top - collisionPosTop, position.top ); 827 } 828 } 829 }, 830 flip: { 831 left: function( position, data ) { 832 var within = data.within, 833 withinOffset = within.offset.left + within.scrollLeft, 834 outerWidth = within.width, 835 offsetLeft = within.isWindow ? within.scrollLeft : within.offset.left, 836 collisionPosLeft = position.left - data.collisionPosition.marginLeft, 837 overLeft = collisionPosLeft - offsetLeft, 838 overRight = collisionPosLeft + data.collisionWidth - outerWidth - offsetLeft, 839 myOffset = data.my[ 0 ] === "left" ? 840 -data.elemWidth : 841 data.my[ 0 ] === "right" ? 842 data.elemWidth : 843 0, 844 atOffset = data.at[ 0 ] === "left" ? 845 data.targetWidth : 846 data.at[ 0 ] === "right" ? 847 -data.targetWidth : 848 0, 849 offset = -2 * data.offset[ 0 ], 850 newOverRight, 851 newOverLeft; 852 853 if ( overLeft < 0 ) { 854 newOverRight = position.left + myOffset + atOffset + offset + data.collisionWidth - 855 outerWidth - withinOffset; 856 if ( newOverRight < 0 || newOverRight < abs( overLeft ) ) { 857 position.left += myOffset + atOffset + offset; 858 } 859 } else if ( overRight > 0 ) { 860 newOverLeft = position.left - data.collisionPosition.marginLeft + myOffset + 861 atOffset + offset - offsetLeft; 862 if ( newOverLeft > 0 || abs( newOverLeft ) < overRight ) { 863 position.left += myOffset + atOffset + offset; 864 } 865 } 866 }, 867 top: function( position, data ) { 868 var within = data.within, 869 withinOffset = within.offset.top + within.scrollTop, 870 outerHeight = within.height, 871 offsetTop = within.isWindow ? within.scrollTop : within.offset.top, 872 collisionPosTop = position.top - data.collisionPosition.marginTop, 873 overTop = collisionPosTop - offsetTop, 874 overBottom = collisionPosTop + data.collisionHeight - outerHeight - offsetTop, 875 top = data.my[ 1 ] === "top", 876 myOffset = top ? 877 -data.elemHeight : 878 data.my[ 1 ] === "bottom" ? 879 data.elemHeight : 880 0, 881 atOffset = data.at[ 1 ] === "top" ? 882 data.targetHeight : 883 data.at[ 1 ] === "bottom" ? 884 -data.targetHeight : 885 0, 886 offset = -2 * data.offset[ 1 ], 887 newOverTop, 888 newOverBottom; 889 if ( overTop < 0 ) { 890 newOverBottom = position.top + myOffset + atOffset + offset + data.collisionHeight - 891 outerHeight - withinOffset; 892 if ( newOverBottom < 0 || newOverBottom < abs( overTop ) ) { 893 position.top += myOffset + atOffset + offset; 894 } 895 } else if ( overBottom > 0 ) { 896 newOverTop = position.top - data.collisionPosition.marginTop + myOffset + atOffset + 897 offset - offsetTop; 898 if ( newOverTop > 0 || abs( newOverTop ) < overBottom ) { 899 position.top += myOffset + atOffset + offset; 900 } 901 } 902 } 903 }, 904 flipfit: { 905 left: function() { 906 $.ui.position.flip.left.apply( this, arguments ); 907 $.ui.position.fit.left.apply( this, arguments ); 908 }, 909 top: function() { 910 $.ui.position.flip.top.apply( this, arguments ); 911 $.ui.position.fit.top.apply( this, arguments ); 912 } 913 } 914 }; 915 916 } )(); 917 918 // Source: safe-active-element.js 919 $.ui.safeActiveElement = function( document ) { 920 var activeElement; 921 922 // Support: IE 9 only 923 // IE9 throws an "Unspecified error" accessing document.activeElement from an <iframe> 924 try { 925 activeElement = document.activeElement; 926 } catch ( error ) { 927 activeElement = document.body; 928 } 929 930 // Support: IE 9 - 11 only 931 // IE may return null instead of an element 932 // Interestingly, this only seems to occur when NOT in an iframe 933 if ( !activeElement ) { 934 activeElement = document.body; 935 } 936 937 // Support: IE 11 only 938 // IE11 returns a seemingly empty object in some cases when accessing 939 // document.activeElement from an <iframe> 940 if ( !activeElement.nodeName ) { 941 activeElement = document.body; 942 } 943 944 return activeElement; 945 }; 946 947 // Source: safe-blur.js 948 $.ui.safeBlur = function( element ) { 949 950 // Support: IE9 - 10 only 951 // If the <body> is blurred, IE will switch windows, see #9420 952 if ( element && element.nodeName.toLowerCase() !== "body" ) { 953 $( element ).trigger( "blur" ); 954 } 955 }; 956 957 // Source: scroll-parent.js 958 /*! 959 * jQuery UI Scroll Parent 1.13.3 960 * https://jqueryui.com 961 * 962 * Copyright OpenJS Foundation and other contributors 963 * Released under the MIT license. 964 * https://jquery.org/license 965 */ 966 967 //>>label: scrollParent 968 //>>group: Core 969 //>>description: Get the closest ancestor element that is scrollable. 970 //>>docs: https://api.jqueryui.com/scrollParent/ 971 972 $.fn.scrollParent = function( includeHidden ) { 973 var position = this.css( "position" ), 974 excludeStaticParent = position === "absolute", 975 overflowRegex = includeHidden ? /(auto|scroll|hidden)/ : /(auto|scroll)/, 976 scrollParent = this.parents().filter( function() { 977 var parent = $( this ); 978 if ( excludeStaticParent && parent.css( "position" ) === "static" ) { 979 return false; 980 } 981 return overflowRegex.test( parent.css( "overflow" ) + parent.css( "overflow-y" ) + 982 parent.css( "overflow-x" ) ); 983 } ).eq( 0 ); 984 985 return position === "fixed" || !scrollParent.length ? 986 $( this[ 0 ].ownerDocument || document ) : 987 scrollParent; 988 }; 989 990 // Source: tabbable.js 991 /*! 992 * jQuery UI Tabbable 1.13.3 993 * https://jqueryui.com 994 * 995 * Copyright OpenJS Foundation and other contributors 996 * Released under the MIT license. 997 * https://jquery.org/license 998 */ 999 1000 //>>label: :tabbable Selector 1001 //>>group: Core 1002 //>>description: Selects elements which can be tabbed to. 1003 //>>docs: https://api.jqueryui.com/tabbable-selector/ 1004 1005 $.extend( $.expr.pseudos, { 1006 tabbable: function( element ) { 1007 var tabIndex = $.attr( element, "tabindex" ), 1008 hasTabindex = tabIndex != null; 1009 return ( !hasTabindex || tabIndex >= 0 ) && $.ui.focusable( element, hasTabindex ); 1010 } 1011 } ); 1012 1013 // Source: unique-id.js 1014 /*! 1015 * jQuery UI Unique ID 1.13.3 1016 * https://jqueryui.com 1017 * 1018 * Copyright OpenJS Foundation and other contributors 1019 * Released under the MIT license. 1020 * https://jquery.org/license 1021 */ 1022 1023 //>>label: uniqueId 1024 //>>group: Core 1025 //>>description: Functions to generate and remove uniqueId's 1026 //>>docs: https://api.jqueryui.com/uniqueId/ 1027 1028 $.fn.extend( { 1029 uniqueId: ( function() { 1030 var uuid = 0; 1031 1032 return function() { 1033 return this.each( function() { 1034 if ( !this.id ) { 1035 this.id = "ui-id-" + ( ++uuid ); 1036 } 1037 } ); 1038 }; 1039 } )(), 1040 1041 removeUniqueId: function() { 1042 return this.each( function() { 1043 if ( /^ui-id-\d+$/.test( this.id ) ) { 1044 $( this ).removeAttr( "id" ); 1045 } 1046 } ); 1047 } 1048 } ); 1049 1050 // Source: widget.js 1051 /*! 1052 * jQuery UI Widget 1.13.3 1053 * https://jqueryui.com 1054 * 1055 * Copyright OpenJS Foundation and other contributors 1056 * Released under the MIT license. 1057 * https://jquery.org/license 1058 */ 1059 1060 //>>label: Widget 1061 //>>group: Core 1062 //>>description: Provides a factory for creating stateful widgets with a common API. 1063 //>>docs: https://api.jqueryui.com/jQuery.widget/ 1064 //>>demos: https://jqueryui.com/widget/ 1065 1066 var widgetUuid = 0; 1067 var widgetHasOwnProperty = Array.prototype.hasOwnProperty; 1068 var widgetSlice = Array.prototype.slice; 1069 1070 $.cleanData = ( function( orig ) { 1071 return function( elems ) { 1072 var events, elem, i; 1073 for ( i = 0; ( elem = elems[ i ] ) != null; i++ ) { 1074 1075 // Only trigger remove when necessary to save time 1076 events = $._data( elem, "events" ); 1077 if ( events && events.remove ) { 1078 $( elem ).triggerHandler( "remove" ); 1079 } 1080 } 1081 orig( elems ); 1082 }; 1083 } )( $.cleanData ); 1084 1085 $.widget = function( name, base, prototype ) { 1086 var existingConstructor, constructor, basePrototype; 1087 1088 // ProxiedPrototype allows the provided prototype to remain unmodified 1089 // so that it can be used as a mixin for multiple widgets (#8876) 1090 var proxiedPrototype = {}; 1091 1092 var namespace = name.split( "." )[ 0 ]; 1093 name = name.split( "." )[ 1 ]; 1094 var fullName = namespace + "-" + name; 1095 1096 if ( !prototype ) { 1097 prototype = base; 1098 base = $.Widget; 1099 } 1100 1101 if ( Array.isArray( prototype ) ) { 1102 prototype = $.extend.apply( null, [ {} ].concat( prototype ) ); 1103 } 1104 1105 // Create selector for plugin 1106 $.expr.pseudos[ fullName.toLowerCase() ] = function( elem ) { 1107 return !!$.data( elem, fullName ); 1108 }; 1109 1110 $[ namespace ] = $[ namespace ] || {}; 1111 existingConstructor = $[ namespace ][ name ]; 1112 constructor = $[ namespace ][ name ] = function( options, element ) { 1113 1114 // Allow instantiation without "new" keyword 1115 if ( !this || !this._createWidget ) { 1116 return new constructor( options, element ); 1117 } 1118 1119 // Allow instantiation without initializing for simple inheritance 1120 // must use "new" keyword (the code above always passes args) 1121 if ( arguments.length ) { 1122 this._createWidget( options, element ); 1123 } 1124 }; 1125 1126 // Extend with the existing constructor to carry over any static properties 1127 $.extend( constructor, existingConstructor, { 1128 version: prototype.version, 1129 1130 // Copy the object used to create the prototype in case we need to 1131 // redefine the widget later 1132 _proto: $.extend( {}, prototype ), 1133 1134 // Track widgets that inherit from this widget in case this widget is 1135 // redefined after a widget inherits from it 1136 _childConstructors: [] 1137 } ); 1138 1139 basePrototype = new base(); 1140 1141 // We need to make the options hash a property directly on the new instance 1142 // otherwise we'll modify the options hash on the prototype that we're 1143 // inheriting from 1144 basePrototype.options = $.widget.extend( {}, basePrototype.options ); 1145 $.each( prototype, function( prop, value ) { 1146 if ( typeof value !== "function" ) { 1147 proxiedPrototype[ prop ] = value; 1148 return; 1149 } 1150 proxiedPrototype[ prop ] = ( function() { 1151 function _super() { 1152 return base.prototype[ prop ].apply( this, arguments ); 1153 } 1154 1155 function _superApply( args ) { 1156 return base.prototype[ prop ].apply( this, args ); 1157 } 1158 1159 return function() { 1160 var __super = this._super; 1161 var __superApply = this._superApply; 1162 var returnValue; 1163 1164 this._super = _super; 1165 this._superApply = _superApply; 1166 1167 returnValue = value.apply( this, arguments ); 1168 1169 this._super = __super; 1170 this._superApply = __superApply; 1171 1172 return returnValue; 1173 }; 1174 } )(); 1175 } ); 1176 constructor.prototype = $.widget.extend( basePrototype, { 1177 1178 // TODO: remove support for widgetEventPrefix 1179 // always use the name + a colon as the prefix, e.g., draggable:start 1180 // don't prefix for widgets that aren't DOM-based 1181 widgetEventPrefix: existingConstructor ? ( basePrototype.widgetEventPrefix || name ) : name 1182 }, proxiedPrototype, { 1183 constructor: constructor, 1184 namespace: namespace, 1185 widgetName: name, 1186 widgetFullName: fullName 1187 } ); 1188 1189 // If this widget is being redefined then we need to find all widgets that 1190 // are inheriting from it and redefine all of them so that they inherit from 1191 // the new version of this widget. We're essentially trying to replace one 1192 // level in the prototype chain. 1193 if ( existingConstructor ) { 1194 $.each( existingConstructor._childConstructors, function( i, child ) { 1195 var childPrototype = child.prototype; 1196 1197 // Redefine the child widget using the same prototype that was 1198 // originally used, but inherit from the new version of the base 1199 $.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor, 1200 child._proto ); 1201 } ); 1202 1203 // Remove the list of existing child constructors from the old constructor 1204 // so the old child constructors can be garbage collected 1205 delete existingConstructor._childConstructors; 1206 } else { 1207 base._childConstructors.push( constructor ); 1208 } 1209 1210 $.widget.bridge( name, constructor ); 1211 1212 return constructor; 1213 }; 1214 1215 $.widget.extend = function( target ) { 1216 var input = widgetSlice.call( arguments, 1 ); 1217 var inputIndex = 0; 1218 var inputLength = input.length; 1219 var key; 1220 var value; 1221 1222 for ( ; inputIndex < inputLength; inputIndex++ ) { 1223 for ( key in input[ inputIndex ] ) { 1224 value = input[ inputIndex ][ key ]; 1225 if ( widgetHasOwnProperty.call( input[ inputIndex ], key ) && value !== undefined ) { 1226 1227 // Clone objects 1228 if ( $.isPlainObject( value ) ) { 1229 target[ key ] = $.isPlainObject( target[ key ] ) ? 1230 $.widget.extend( {}, target[ key ], value ) : 1231 1232 // Don't extend strings, arrays, etc. with objects 1233 $.widget.extend( {}, value ); 1234 1235 // Copy everything else by reference 1236 } else { 1237 target[ key ] = value; 1238 } 1239 } 1240 } 1241 } 1242 return target; 1243 }; 1244 1245 $.widget.bridge = function( name, object ) { 1246 var fullName = object.prototype.widgetFullName || name; 1247 $.fn[ name ] = function( options ) { 1248 var isMethodCall = typeof options === "string"; 1249 var args = widgetSlice.call( arguments, 1 ); 1250 var returnValue = this; 1251 1252 if ( isMethodCall ) { 1253 1254 // If this is an empty collection, we need to have the instance method 1255 // return undefined instead of the jQuery instance 1256 if ( !this.length && options === "instance" ) { 1257 returnValue = undefined; 1258 } else { 1259 this.each( function() { 1260 var methodValue; 1261 var instance = $.data( this, fullName ); 1262 1263 if ( options === "instance" ) { 1264 returnValue = instance; 1265 return false; 1266 } 1267 1268 if ( !instance ) { 1269 return $.error( "cannot call methods on " + name + 1270 " prior to initialization; " + 1271 "attempted to call method '" + options + "'" ); 1272 } 1273 1274 if ( typeof instance[ options ] !== "function" || 1275 options.charAt( 0 ) === "_" ) { 1276 return $.error( "no such method '" + options + "' for " + name + 1277 " widget instance" ); 1278 } 1279 1280 methodValue = instance[ options ].apply( instance, args ); 1281 1282 if ( methodValue !== instance && methodValue !== undefined ) { 1283 returnValue = methodValue && methodValue.jquery ? 1284 returnValue.pushStack( methodValue.get() ) : 1285 methodValue; 1286 return false; 1287 } 1288 } ); 1289 } 1290 } else { 1291 1292 // Allow multiple hashes to be passed on init 1293 if ( args.length ) { 1294 options = $.widget.extend.apply( null, [ options ].concat( args ) ); 1295 } 1296 1297 this.each( function() { 1298 var instance = $.data( this, fullName ); 1299 if ( instance ) { 1300 instance.option( options || {} ); 1301 if ( instance._init ) { 1302 instance._init(); 1303 } 1304 } else { 1305 $.data( this, fullName, new object( options, this ) ); 1306 } 1307 } ); 1308 } 1309 1310 return returnValue; 1311 }; 1312 }; 1313 1314 $.Widget = function( /* options, element */ ) {}; 1315 $.Widget._childConstructors = []; 1316 1317 $.Widget.prototype = { 1318 widgetName: "widget", 1319 widgetEventPrefix: "", 1320 defaultElement: "<div>", 1321 1322 options: { 1323 classes: {}, 1324 disabled: false, 1325 1326 // Callbacks 1327 create: null 1328 }, 1329 1330 _createWidget: function( options, element ) { 1331 element = $( element || this.defaultElement || this )[ 0 ]; 1332 this.element = $( element ); 1333 this.uuid = widgetUuid++; 1334 this.eventNamespace = "." + this.widgetName + this.uuid; 1335 1336 this.bindings = $(); 1337 this.hoverable = $(); 1338 this.focusable = $(); 1339 this.classesElementLookup = {}; 1340 1341 if ( element !== this ) { 1342 $.data( element, this.widgetFullName, this ); 1343 this._on( true, this.element, { 1344 remove: function( event ) { 1345 if ( event.target === element ) { 1346 this.destroy(); 1347 } 1348 } 1349 } ); 1350 this.document = $( element.style ? 1351 1352 // Element within the document 1353 element.ownerDocument : 1354 1355 // Element is window or document 1356 element.document || element ); 1357 this.window = $( this.document[ 0 ].defaultView || this.document[ 0 ].parentWindow ); 1358 } 1359 1360 this.options = $.widget.extend( {}, 1361 this.options, 1362 this._getCreateOptions(), 1363 options ); 1364 1365 this._create(); 1366 1367 if ( this.options.disabled ) { 1368 this._setOptionDisabled( this.options.disabled ); 1369 } 1370 1371 this._trigger( "create", null, this._getCreateEventData() ); 1372 this._init(); 1373 }, 1374 1375 _getCreateOptions: function() { 1376 return {}; 1377 }, 1378 1379 _getCreateEventData: $.noop, 1380 1381 _create: $.noop, 1382 1383 _init: $.noop, 1384 1385 destroy: function() { 1386 var that = this; 1387 1388 this._destroy(); 1389 $.each( this.classesElementLookup, function( key, value ) { 1390 that._removeClass( value, key ); 1391 } ); 1392 1393 // We can probably remove the unbind calls in 2.0 1394 // all event bindings should go through this._on() 1395 this.element 1396 .off( this.eventNamespace ) 1397 .removeData( this.widgetFullName ); 1398 this.widget() 1399 .off( this.eventNamespace ) 1400 .removeAttr( "aria-disabled" ); 1401 1402 // Clean up events and states 1403 this.bindings.off( this.eventNamespace ); 1404 }, 1405 1406 _destroy: $.noop, 1407 1408 widget: function() { 1409 return this.element; 1410 }, 1411 1412 option: function( key, value ) { 1413 var options = key; 1414 var parts; 1415 var curOption; 1416 var i; 1417 1418 if ( arguments.length === 0 ) { 1419 1420 // Don't return a reference to the internal hash 1421 return $.widget.extend( {}, this.options ); 1422 } 1423 1424 if ( typeof key === "string" ) { 1425 1426 // Handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } } 1427 options = {}; 1428 parts = key.split( "." ); 1429 key = parts.shift(); 1430 if ( parts.length ) { 1431 curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] ); 1432 for ( i = 0; i < parts.length - 1; i++ ) { 1433 curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {}; 1434 curOption = curOption[ parts[ i ] ]; 1435 } 1436 key = parts.pop(); 1437 if ( arguments.length === 1 ) { 1438 return curOption[ key ] === undefined ? null : curOption[ key ]; 1439 } 1440 curOption[ key ] = value; 1441 } else { 1442 if ( arguments.length === 1 ) { 1443 return this.options[ key ] === undefined ? null : this.options[ key ]; 1444 } 1445 options[ key ] = value; 1446 } 1447 } 1448 1449 this._setOptions( options ); 1450 1451 return this; 1452 }, 1453 1454 _setOptions: function( options ) { 1455 var key; 1456 1457 for ( key in options ) { 1458 this._setOption( key, options[ key ] ); 1459 } 1460 1461 return this; 1462 }, 1463 1464 _setOption: function( key, value ) { 1465 if ( key === "classes" ) { 1466 this._setOptionClasses( value ); 1467 } 1468 1469 this.options[ key ] = value; 1470 1471 if ( key === "disabled" ) { 1472 this._setOptionDisabled( value ); 1473 } 1474 1475 return this; 1476 }, 1477 1478 _setOptionClasses: function( value ) { 1479 var classKey, elements, currentElements; 1480 1481 for ( classKey in value ) { 1482 currentElements = this.classesElementLookup[ classKey ]; 1483 if ( value[ classKey ] === this.options.classes[ classKey ] || 1484 !currentElements || 1485 !currentElements.length ) { 1486 continue; 1487 } 1488 1489 // We are doing this to create a new jQuery object because the _removeClass() call 1490 // on the next line is going to destroy the reference to the current elements being 1491 // tracked. We need to save a copy of this collection so that we can add the new classes 1492 // below. 1493 elements = $( currentElements.get() ); 1494 this._removeClass( currentElements, classKey ); 1495 1496 // We don't use _addClass() here, because that uses this.options.classes 1497 // for generating the string of classes. We want to use the value passed in from 1498 // _setOption(), this is the new value of the classes option which was passed to 1499 // _setOption(). We pass this value directly to _classes(). 1500 elements.addClass( this._classes( { 1501 element: elements, 1502 keys: classKey, 1503 classes: value, 1504 add: true 1505 } ) ); 1506 } 1507 }, 1508 1509 _setOptionDisabled: function( value ) { 1510 this._toggleClass( this.widget(), this.widgetFullName + "-disabled", null, !!value ); 1511 1512 // If the widget is becoming disabled, then nothing is interactive 1513 if ( value ) { 1514 this._removeClass( this.hoverable, null, "ui-state-hover" ); 1515 this._removeClass( this.focusable, null, "ui-state-focus" ); 1516 } 1517 }, 1518 1519 enable: function() { 1520 return this._setOptions( { disabled: false } ); 1521 }, 1522 1523 disable: function() { 1524 return this._setOptions( { disabled: true } ); 1525 }, 1526 1527 _classes: function( options ) { 1528 var full = []; 1529 var that = this; 1530 1531 options = $.extend( { 1532 element: this.element, 1533 classes: this.options.classes || {} 1534 }, options ); 1535 1536 function bindRemoveEvent() { 1537 var nodesToBind = []; 1538 1539 options.element.each( function( _, element ) { 1540 var isTracked = $.map( that.classesElementLookup, function( elements ) { 1541 return elements; 1542 } ) 1543 .some( function( elements ) { 1544 return elements.is( element ); 1545 } ); 1546 1547 if ( !isTracked ) { 1548 nodesToBind.push( element ); 1549 } 1550 } ); 1551 1552 that._on( $( nodesToBind ), { 1553 remove: "_untrackClassesElement" 1554 } ); 1555 } 1556 1557 function processClassString( classes, checkOption ) { 1558 var current, i; 1559 for ( i = 0; i < classes.length; i++ ) { 1560 current = that.classesElementLookup[ classes[ i ] ] || $(); 1561 if ( options.add ) { 1562 bindRemoveEvent(); 1563 current = $( $.uniqueSort( current.get().concat( options.element.get() ) ) ); 1564 } else { 1565 current = $( current.not( options.element ).get() ); 1566 } 1567 that.classesElementLookup[ classes[ i ] ] = current; 1568 full.push( classes[ i ] ); 1569 if ( checkOption && options.classes[ classes[ i ] ] ) { 1570 full.push( options.classes[ classes[ i ] ] ); 1571 } 1572 } 1573 } 1574 1575 if ( options.keys ) { 1576 processClassString( options.keys.match( /\S+/g ) || [], true ); 1577 } 1578 if ( options.extra ) { 1579 processClassString( options.extra.match( /\S+/g ) || [] ); 1580 } 1581 1582 return full.join( " " ); 1583 }, 1584 1585 _untrackClassesElement: function( event ) { 1586 var that = this; 1587 $.each( that.classesElementLookup, function( key, value ) { 1588 if ( $.inArray( event.target, value ) !== -1 ) { 1589 that.classesElementLookup[ key ] = $( value.not( event.target ).get() ); 1590 } 1591 } ); 1592 1593 this._off( $( event.target ) ); 1594 }, 1595 1596 _removeClass: function( element, keys, extra ) { 1597 return this._toggleClass( element, keys, extra, false ); 1598 }, 1599 1600 _addClass: function( element, keys, extra ) { 1601 return this._toggleClass( element, keys, extra, true ); 1602 }, 1603 1604 _toggleClass: function( element, keys, extra, add ) { 1605 add = ( typeof add === "boolean" ) ? add : extra; 1606 var shift = ( typeof element === "string" || element === null ), 1607 options = { 1608 extra: shift ? keys : extra, 1609 keys: shift ? element : keys, 1610 element: shift ? this.element : element, 1611 add: add 1612 }; 1613 options.element.toggleClass( this._classes( options ), add ); 1614 return this; 1615 }, 1616 1617 _on: function( suppressDisabledCheck, element, handlers ) { 1618 var delegateElement; 1619 var instance = this; 1620 1621 // No suppressDisabledCheck flag, shuffle arguments 1622 if ( typeof suppressDisabledCheck !== "boolean" ) { 1623 handlers = element; 1624 element = suppressDisabledCheck; 1625 suppressDisabledCheck = false; 1626 } 1627 1628 // No element argument, shuffle and use this.element 1629 if ( !handlers ) { 1630 handlers = element; 1631 element = this.element; 1632 delegateElement = this.widget(); 1633 } else { 1634 element = delegateElement = $( element ); 1635 this.bindings = this.bindings.add( element ); 1636 } 1637 1638 $.each( handlers, function( event, handler ) { 1639 function handlerProxy() { 1640 1641 // Allow widgets to customize the disabled handling 1642 // - disabled as an array instead of boolean 1643 // - disabled class as method for disabling individual parts 1644 if ( !suppressDisabledCheck && 1645 ( instance.options.disabled === true || 1646 $( this ).hasClass( "ui-state-disabled" ) ) ) { 1647 return; 1648 } 1649 return ( typeof handler === "string" ? instance[ handler ] : handler ) 1650 .apply( instance, arguments ); 1651 } 1652 1653 // Copy the guid so direct unbinding works 1654 if ( typeof handler !== "string" ) { 1655 handlerProxy.guid = handler.guid = 1656 handler.guid || handlerProxy.guid || $.guid++; 1657 } 1658 1659 var match = event.match( /^([\w:-]*)\s*(.*)$/ ); 1660 var eventName = match[ 1 ] + instance.eventNamespace; 1661 var selector = match[ 2 ]; 1662 1663 if ( selector ) { 1664 delegateElement.on( eventName, selector, handlerProxy ); 1665 } else { 1666 element.on( eventName, handlerProxy ); 1667 } 1668 } ); 1669 }, 1670 1671 _off: function( element, eventName ) { 1672 eventName = ( eventName || "" ).split( " " ).join( this.eventNamespace + " " ) + 1673 this.eventNamespace; 1674 element.off( eventName ); 1675 1676 // Clear the stack to avoid memory leaks (#10056) 1677 this.bindings = $( this.bindings.not( element ).get() ); 1678 this.focusable = $( this.focusable.not( element ).get() ); 1679 this.hoverable = $( this.hoverable.not( element ).get() ); 1680 }, 1681 1682 _delay: function( handler, delay ) { 1683 function handlerProxy() { 1684 return ( typeof handler === "string" ? instance[ handler ] : handler ) 1685 .apply( instance, arguments ); 1686 } 1687 var instance = this; 1688 return setTimeout( handlerProxy, delay || 0 ); 1689 }, 1690 1691 _hoverable: function( element ) { 1692 this.hoverable = this.hoverable.add( element ); 1693 this._on( element, { 1694 mouseenter: function( event ) { 1695 this._addClass( $( event.currentTarget ), null, "ui-state-hover" ); 1696 }, 1697 mouseleave: function( event ) { 1698 this._removeClass( $( event.currentTarget ), null, "ui-state-hover" ); 1699 } 1700 } ); 1701 }, 1702 1703 _focusable: function( element ) { 1704 this.focusable = this.focusable.add( element ); 1705 this._on( element, { 1706 focusin: function( event ) { 1707 this._addClass( $( event.currentTarget ), null, "ui-state-focus" ); 1708 }, 1709 focusout: function( event ) { 1710 this._removeClass( $( event.currentTarget ), null, "ui-state-focus" ); 1711 } 1712 } ); 1713 }, 1714 1715 _trigger: function( type, event, data ) { 1716 var prop, orig; 1717 var callback = this.options[ type ]; 1718 1719 data = data || {}; 1720 event = $.Event( event ); 1721 event.type = ( type === this.widgetEventPrefix ? 1722 type : 1723 this.widgetEventPrefix + type ).toLowerCase(); 1724 1725 // The original event may come from any element 1726 // so we need to reset the target on the new event 1727 event.target = this.element[ 0 ]; 1728 1729 // Copy original event properties over to the new event 1730 orig = event.originalEvent; 1731 if ( orig ) { 1732 for ( prop in orig ) { 1733 if ( !( prop in event ) ) { 1734 event[ prop ] = orig[ prop ]; 1735 } 1736 } 1737 } 1738 1739 this.element.trigger( event, data ); 1740 return !( typeof callback === "function" && 1741 callback.apply( this.element[ 0 ], [ event ].concat( data ) ) === false || 1742 event.isDefaultPrevented() ); 1743 } 1744 }; 1745 1746 $.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) { 1747 $.Widget.prototype[ "_" + method ] = function( element, options, callback ) { 1748 if ( typeof options === "string" ) { 1749 options = { effect: options }; 1750 } 1751 1752 var hasOptions; 1753 var effectName = !options ? 1754 method : 1755 options === true || typeof options === "number" ? 1756 defaultEffect : 1757 options.effect || defaultEffect; 1758 1759 options = options || {}; 1760 if ( typeof options === "number" ) { 1761 options = { duration: options }; 1762 } else if ( options === true ) { 1763 options = {}; 1764 } 1765 1766 hasOptions = !$.isEmptyObject( options ); 1767 options.complete = callback; 1768 1769 if ( options.delay ) { 1770 element.delay( options.delay ); 1771 } 1772 1773 if ( hasOptions && $.effects && $.effects.effect[ effectName ] ) { 1774 element[ method ]( options ); 1775 } else if ( effectName !== method && element[ effectName ] ) { 1776 element[ effectName ]( options.duration, options.easing, callback ); 1777 } else { 1778 element.queue( function( next ) { 1779 $( this )[ method ](); 1780 if ( callback ) { 1781 callback.call( element[ 0 ] ); 1782 } 1783 next(); 1784 } ); 1785 } 1786 }; 1787 } ); 1788 1789 1790 } ) );
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated : Thu Nov 21 08:20:01 2024 | Cross-referenced by PHPXref |