[ Index ]

PHP Cross Reference of WordPress

title

Body

[close]

/wp-includes/js/jquery/ui/ -> core.js (source)

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


Generated: Sat Sep 18 01:00:04 2021 Cross-referenced by PHPXref 0.7.1