[ Index ]

PHP Cross Reference of MediaWiki-1.24.0

title

Body

[close]

/resources/lib/jquery.ui/ -> jquery.ui.widget.js (source)

   1  /*!
   2   * jQuery UI Widget 1.9.2
   3   * http://jqueryui.com
   4   *
   5   * Copyright 2012 jQuery Foundation and other contributors
   6   * Released under the MIT license.
   7   * http://jquery.org/license
   8   *
   9   * http://api.jqueryui.com/jQuery.widget/
  10   */
  11  (function( $, undefined ) {
  12  
  13  var uuid = 0,
  14      slice = Array.prototype.slice,
  15      _cleanData = $.cleanData;
  16  $.cleanData = function( elems ) {
  17      for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
  18          try {
  19              $( elem ).triggerHandler( "remove" );
  20          // http://bugs.jquery.com/ticket/8235
  21          } catch( e ) {}
  22      }
  23      _cleanData( elems );
  24  };
  25  
  26  $.widget = function( name, base, prototype ) {
  27      var fullName, existingConstructor, constructor, basePrototype,
  28          namespace = name.split( "." )[ 0 ];
  29  
  30      name = name.split( "." )[ 1 ];
  31      fullName = namespace + "-" + name;
  32  
  33      if ( !prototype ) {
  34          prototype = base;
  35          base = $.Widget;
  36      }
  37  
  38      // create selector for plugin
  39      $.expr[ ":" ][ fullName.toLowerCase() ] = function( elem ) {
  40          return !!$.data( elem, fullName );
  41      };
  42  
  43      $[ namespace ] = $[ namespace ] || {};
  44      existingConstructor = $[ namespace ][ name ];
  45      constructor = $[ namespace ][ name ] = function( options, element ) {
  46          // allow instantiation without "new" keyword
  47          if ( !this._createWidget ) {
  48              return new constructor( options, element );
  49          }
  50  
  51          // allow instantiation without initializing for simple inheritance
  52          // must use "new" keyword (the code above always passes args)
  53          if ( arguments.length ) {
  54              this._createWidget( options, element );
  55          }
  56      };
  57      // extend with the existing constructor to carry over any static properties
  58      $.extend( constructor, existingConstructor, {
  59          version: prototype.version,
  60          // copy the object used to create the prototype in case we need to
  61          // redefine the widget later
  62          _proto: $.extend( {}, prototype ),
  63          // track widgets that inherit from this widget in case this widget is
  64          // redefined after a widget inherits from it
  65          _childConstructors: []
  66      });
  67  
  68      basePrototype = new base();
  69      // we need to make the options hash a property directly on the new instance
  70      // otherwise we'll modify the options hash on the prototype that we're
  71      // inheriting from
  72      basePrototype.options = $.widget.extend( {}, basePrototype.options );
  73      $.each( prototype, function( prop, value ) {
  74          if ( $.isFunction( value ) ) {
  75              prototype[ prop ] = (function() {
  76                  var _super = function() {
  77                          return base.prototype[ prop ].apply( this, arguments );
  78                      },
  79                      _superApply = function( args ) {
  80                          return base.prototype[ prop ].apply( this, args );
  81                      };
  82                  return function() {
  83                      var __super = this._super,
  84                          __superApply = this._superApply,
  85                          returnValue;
  86  
  87                      this._super = _super;
  88                      this._superApply = _superApply;
  89  
  90                      returnValue = value.apply( this, arguments );
  91  
  92                      this._super = __super;
  93                      this._superApply = __superApply;
  94  
  95                      return returnValue;
  96                  };
  97              })();
  98          }
  99      });
 100      constructor.prototype = $.widget.extend( basePrototype, {
 101          // TODO: remove support for widgetEventPrefix
 102          // always use the name + a colon as the prefix, e.g., draggable:start
 103          // don't prefix for widgets that aren't DOM-based
 104          widgetEventPrefix: existingConstructor ? basePrototype.widgetEventPrefix : name
 105      }, prototype, {
 106          constructor: constructor,
 107          namespace: namespace,
 108          widgetName: name,
 109          // TODO remove widgetBaseClass, see #8155
 110          widgetBaseClass: fullName,
 111          widgetFullName: fullName
 112      });
 113  
 114      // If this widget is being redefined then we need to find all widgets that
 115      // are inheriting from it and redefine all of them so that they inherit from
 116      // the new version of this widget. We're essentially trying to replace one
 117      // level in the prototype chain.
 118      if ( existingConstructor ) {
 119          $.each( existingConstructor._childConstructors, function( i, child ) {
 120              var childPrototype = child.prototype;
 121  
 122              // redefine the child widget using the same prototype that was
 123              // originally used, but inherit from the new version of the base
 124              $.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor, child._proto );
 125          });
 126          // remove the list of existing child constructors from the old constructor
 127          // so the old child constructors can be garbage collected
 128          delete existingConstructor._childConstructors;
 129      } else {
 130          base._childConstructors.push( constructor );
 131      }
 132  
 133      $.widget.bridge( name, constructor );
 134  };
 135  
 136  $.widget.extend = function( target ) {
 137      var input = slice.call( arguments, 1 ),
 138          inputIndex = 0,
 139          inputLength = input.length,
 140          key,
 141          value;
 142      for ( ; inputIndex < inputLength; inputIndex++ ) {
 143          for ( key in input[ inputIndex ] ) {
 144              value = input[ inputIndex ][ key ];
 145              if ( input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) {
 146                  // Clone objects
 147                  if ( $.isPlainObject( value ) ) {
 148                      target[ key ] = $.isPlainObject( target[ key ] ) ?
 149                          $.widget.extend( {}, target[ key ], value ) :
 150                          // Don't extend strings, arrays, etc. with objects
 151                          $.widget.extend( {}, value );
 152                  // Copy everything else by reference
 153                  } else {
 154                      target[ key ] = value;
 155                  }
 156              }
 157          }
 158      }
 159      return target;
 160  };
 161  
 162  $.widget.bridge = function( name, object ) {
 163      var fullName = object.prototype.widgetFullName || name;
 164      $.fn[ name ] = function( options ) {
 165          var isMethodCall = typeof options === "string",
 166              args = slice.call( arguments, 1 ),
 167              returnValue = this;
 168  
 169          // allow multiple hashes to be passed on init
 170          options = !isMethodCall && args.length ?
 171              $.widget.extend.apply( null, [ options ].concat(args) ) :
 172              options;
 173  
 174          if ( isMethodCall ) {
 175              this.each(function() {
 176                  var methodValue,
 177                      instance = $.data( this, fullName );
 178                  if ( !instance ) {
 179                      return $.error( "cannot call methods on " + name + " prior to initialization; " +
 180                          "attempted to call method '" + options + "'" );
 181                  }
 182                  if ( !$.isFunction( instance[options] ) || options.charAt( 0 ) === "_" ) {
 183                      return $.error( "no such method '" + options + "' for " + name + " widget instance" );
 184                  }
 185                  methodValue = instance[ options ].apply( instance, args );
 186                  if ( methodValue !== instance && methodValue !== undefined ) {
 187                      returnValue = methodValue && methodValue.jquery ?
 188                          returnValue.pushStack( methodValue.get() ) :
 189                          methodValue;
 190                      return false;
 191                  }
 192              });
 193          } else {
 194              this.each(function() {
 195                  var instance = $.data( this, fullName );
 196                  if ( instance ) {
 197                      instance.option( options || {} )._init();
 198                  } else {
 199                      $.data( this, fullName, new object( options, this ) );
 200                  }
 201              });
 202          }
 203  
 204          return returnValue;
 205      };
 206  };
 207  
 208  $.Widget = function( /* options, element */ ) {};
 209  $.Widget._childConstructors = [];
 210  
 211  $.Widget.prototype = {
 212      widgetName: "widget",
 213      widgetEventPrefix: "",
 214      defaultElement: "<div>",
 215      options: {
 216          disabled: false,
 217  
 218          // callbacks
 219          create: null
 220      },
 221      _createWidget: function( options, element ) {
 222          element = $( element || this.defaultElement || this )[ 0 ];
 223          this.element = $( element );
 224          this.uuid = uuid++;
 225          this.eventNamespace = "." + this.widgetName + this.uuid;
 226          this.options = $.widget.extend( {},
 227              this.options,
 228              this._getCreateOptions(),
 229              options );
 230  
 231          this.bindings = $();
 232          this.hoverable = $();
 233          this.focusable = $();
 234  
 235          if ( element !== this ) {
 236              // 1.9 BC for #7810
 237              // TODO remove dual storage
 238              $.data( element, this.widgetName, this );
 239              $.data( element, this.widgetFullName, this );
 240              this._on( true, this.element, {
 241                  remove: function( event ) {
 242                      if ( event.target === element ) {
 243                          this.destroy();
 244                      }
 245                  }
 246              });
 247              this.document = $( element.style ?
 248                  // element within the document
 249                  element.ownerDocument :
 250                  // element is window or document
 251                  element.document || element );
 252              this.window = $( this.document[0].defaultView || this.document[0].parentWindow );
 253          }
 254  
 255          this._create();
 256          this._trigger( "create", null, this._getCreateEventData() );
 257          this._init();
 258      },
 259      _getCreateOptions: $.noop,
 260      _getCreateEventData: $.noop,
 261      _create: $.noop,
 262      _init: $.noop,
 263  
 264      destroy: function() {
 265          this._destroy();
 266          // we can probably remove the unbind calls in 2.0
 267          // all event bindings should go through this._on()
 268          this.element
 269              .unbind( this.eventNamespace )
 270              // 1.9 BC for #7810
 271              // TODO remove dual storage
 272              .removeData( this.widgetName )
 273              .removeData( this.widgetFullName )
 274              // support: jquery <1.6.3
 275              // http://bugs.jquery.com/ticket/9413
 276              .removeData( $.camelCase( this.widgetFullName ) );
 277          this.widget()
 278              .unbind( this.eventNamespace )
 279              .removeAttr( "aria-disabled" )
 280              .removeClass(
 281                  this.widgetFullName + "-disabled " +
 282                  "ui-state-disabled" );
 283  
 284          // clean up events and states
 285          this.bindings.unbind( this.eventNamespace );
 286          this.hoverable.removeClass( "ui-state-hover" );
 287          this.focusable.removeClass( "ui-state-focus" );
 288      },
 289      _destroy: $.noop,
 290  
 291      widget: function() {
 292          return this.element;
 293      },
 294  
 295      option: function( key, value ) {
 296          var options = key,
 297              parts,
 298              curOption,
 299              i;
 300  
 301          if ( arguments.length === 0 ) {
 302              // don't return a reference to the internal hash
 303              return $.widget.extend( {}, this.options );
 304          }
 305  
 306          if ( typeof key === "string" ) {
 307              // handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } }
 308              options = {};
 309              parts = key.split( "." );
 310              key = parts.shift();
 311              if ( parts.length ) {
 312                  curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] );
 313                  for ( i = 0; i < parts.length - 1; i++ ) {
 314                      curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {};
 315                      curOption = curOption[ parts[ i ] ];
 316                  }
 317                  key = parts.pop();
 318                  if ( value === undefined ) {
 319                      return curOption[ key ] === undefined ? null : curOption[ key ];
 320                  }
 321                  curOption[ key ] = value;
 322              } else {
 323                  if ( value === undefined ) {
 324                      return this.options[ key ] === undefined ? null : this.options[ key ];
 325                  }
 326                  options[ key ] = value;
 327              }
 328          }
 329  
 330          this._setOptions( options );
 331  
 332          return this;
 333      },
 334      _setOptions: function( options ) {
 335          var key;
 336  
 337          for ( key in options ) {
 338              this._setOption( key, options[ key ] );
 339          }
 340  
 341          return this;
 342      },
 343      _setOption: function( key, value ) {
 344          this.options[ key ] = value;
 345  
 346          if ( key === "disabled" ) {
 347              this.widget()
 348                  .toggleClass( this.widgetFullName + "-disabled ui-state-disabled", !!value )
 349                  .attr( "aria-disabled", value );
 350              this.hoverable.removeClass( "ui-state-hover" );
 351              this.focusable.removeClass( "ui-state-focus" );
 352          }
 353  
 354          return this;
 355      },
 356  
 357      enable: function() {
 358          return this._setOption( "disabled", false );
 359      },
 360      disable: function() {
 361          return this._setOption( "disabled", true );
 362      },
 363  
 364      _on: function( suppressDisabledCheck, element, handlers ) {
 365          var delegateElement,
 366              instance = this;
 367  
 368          // no suppressDisabledCheck flag, shuffle arguments
 369          if ( typeof suppressDisabledCheck !== "boolean" ) {
 370              handlers = element;
 371              element = suppressDisabledCheck;
 372              suppressDisabledCheck = false;
 373          }
 374  
 375          // no element argument, shuffle and use this.element
 376          if ( !handlers ) {
 377              handlers = element;
 378              element = this.element;
 379              delegateElement = this.widget();
 380          } else {
 381              // accept selectors, DOM elements
 382              element = delegateElement = $( element );
 383              this.bindings = this.bindings.add( element );
 384          }
 385  
 386          $.each( handlers, function( event, handler ) {
 387  			function handlerProxy() {
 388                  // allow widgets to customize the disabled handling
 389                  // - disabled as an array instead of boolean
 390                  // - disabled class as method for disabling individual parts
 391                  if ( !suppressDisabledCheck &&
 392                          ( instance.options.disabled === true ||
 393                              $( this ).hasClass( "ui-state-disabled" ) ) ) {
 394                      return;
 395                  }
 396                  return ( typeof handler === "string" ? instance[ handler ] : handler )
 397                      .apply( instance, arguments );
 398              }
 399  
 400              // copy the guid so direct unbinding works
 401              if ( typeof handler !== "string" ) {
 402                  handlerProxy.guid = handler.guid =
 403                      handler.guid || handlerProxy.guid || $.guid++;
 404              }
 405  
 406              var match = event.match( /^(\w+)\s*(.*)$/ ),
 407                  eventName = match[1] + instance.eventNamespace,
 408                  selector = match[2];
 409              if ( selector ) {
 410                  delegateElement.delegate( selector, eventName, handlerProxy );
 411              } else {
 412                  element.bind( eventName, handlerProxy );
 413              }
 414          });
 415      },
 416  
 417      _off: function( element, eventName ) {
 418          eventName = (eventName || "").split( " " ).join( this.eventNamespace + " " ) + this.eventNamespace;
 419          element.unbind( eventName ).undelegate( eventName );
 420      },
 421  
 422      _delay: function( handler, delay ) {
 423  		function handlerProxy() {
 424              return ( typeof handler === "string" ? instance[ handler ] : handler )
 425                  .apply( instance, arguments );
 426          }
 427          var instance = this;
 428          return setTimeout( handlerProxy, delay || 0 );
 429      },
 430  
 431      _hoverable: function( element ) {
 432          this.hoverable = this.hoverable.add( element );
 433          this._on( element, {
 434              mouseenter: function( event ) {
 435                  $( event.currentTarget ).addClass( "ui-state-hover" );
 436              },
 437              mouseleave: function( event ) {
 438                  $( event.currentTarget ).removeClass( "ui-state-hover" );
 439              }
 440          });
 441      },
 442  
 443      _focusable: function( element ) {
 444          this.focusable = this.focusable.add( element );
 445          this._on( element, {
 446              focusin: function( event ) {
 447                  $( event.currentTarget ).addClass( "ui-state-focus" );
 448              },
 449              focusout: function( event ) {
 450                  $( event.currentTarget ).removeClass( "ui-state-focus" );
 451              }
 452          });
 453      },
 454  
 455      _trigger: function( type, event, data ) {
 456          var prop, orig,
 457              callback = this.options[ type ];
 458  
 459          data = data || {};
 460          event = $.Event( event );
 461          event.type = ( type === this.widgetEventPrefix ?
 462              type :
 463              this.widgetEventPrefix + type ).toLowerCase();
 464          // the original event may come from any element
 465          // so we need to reset the target on the new event
 466          event.target = this.element[ 0 ];
 467  
 468          // copy original event properties over to the new event
 469          orig = event.originalEvent;
 470          if ( orig ) {
 471              for ( prop in orig ) {
 472                  if ( !( prop in event ) ) {
 473                      event[ prop ] = orig[ prop ];
 474                  }
 475              }
 476          }
 477  
 478          this.element.trigger( event, data );
 479          return !( $.isFunction( callback ) &&
 480              callback.apply( this.element[0], [ event ].concat( data ) ) === false ||
 481              event.isDefaultPrevented() );
 482      }
 483  };
 484  
 485  $.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) {
 486      $.Widget.prototype[ "_" + method ] = function( element, options, callback ) {
 487          if ( typeof options === "string" ) {
 488              options = { effect: options };
 489          }
 490          var hasOptions,
 491              effectName = !options ?
 492                  method :
 493                  options === true || typeof options === "number" ?
 494                      defaultEffect :
 495                      options.effect || defaultEffect;
 496          options = options || {};
 497          if ( typeof options === "number" ) {
 498              options = { duration: options };
 499          }
 500          hasOptions = !$.isEmptyObject( options );
 501          options.complete = callback;
 502          if ( options.delay ) {
 503              element.delay( options.delay );
 504          }
 505          if ( hasOptions && $.effects && ( $.effects.effect[ effectName ] || $.uiBackCompat !== false && $.effects[ effectName ] ) ) {
 506              element[ method ]( options );
 507          } else if ( effectName !== method && element[ effectName ] ) {
 508              element[ effectName ]( options.duration, options.easing, callback );
 509          } else {
 510              element.queue(function( next ) {
 511                  $( this )[ method ]();
 512                  if ( callback ) {
 513                      callback.call( element[ 0 ] );
 514                  }
 515                  next();
 516              });
 517          }
 518      };
 519  });
 520  
 521  // DEPRECATED
 522  if ( $.uiBackCompat !== false ) {
 523      $.Widget.prototype._getCreateOptions = function() {
 524          return $.metadata && $.metadata.get( this.element[0] )[ this.widgetName ];
 525      };
 526  }
 527  
 528  })( jQuery );


Generated: Fri Nov 28 14:03:12 2014 Cross-referenced by PHPXref 0.7.1