Date picker and bylines for platforms`
[bus.git] / busui / js / jquery.ui.widget.js
blob:a/busui/js/jquery.ui.widget.js -> blob:b/busui/js/jquery.ui.widget.js
  /*!
  * jQuery UI Widget @VERSION
  *
  * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
  * Dual licensed under the MIT or GPL Version 2 licenses.
  * http://jquery.org/license
  *
  * http://docs.jquery.com/UI/Widget
  */
  (function( $, undefined ) {
   
  var slice = Array.prototype.slice;
   
  var _cleanData = $.cleanData;
  $.cleanData = function( elems ) {
  for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
  $( elem ).triggerHandler( "remove" );
  }
  _cleanData( elems );
  };
   
  $.widget = function( name, base, prototype ) {
  var namespace = name.split( "." )[ 0 ],
  fullName;
  name = name.split( "." )[ 1 ];
  fullName = namespace + "-" + name;
   
  if ( !prototype ) {
  prototype = base;
  base = $.Widget;
  }
   
  // create selector for plugin
  $.expr[ ":" ][ fullName ] = function( elem ) {
  return !!$.data( elem, name );
  };
   
  $[ namespace ] = $[ namespace ] || {};
  $[ namespace ][ name ] = $[ namespace ][ name ] || function( options, element ) {
  // allow instantiation without "new" keyword
  if ( !this._createWidget ) {
  return new $[ namespace ][ name ]( options, element );
  }
   
  // allow instantiation without initializing for simple inheritance
  // must use "new" keyword (the code above always passes args)
  if ( arguments.length ) {
  this._createWidget( options, element );
  }
  };
   
  var basePrototype = new base();
  // we need to make the options hash a property directly on the new instance
  // otherwise we'll modify the options hash on the prototype that we're
  // inheriting from
  basePrototype.options = $.extend( true, {}, basePrototype.options );
  $[ namespace ][ name ].prototype = $.extend( true, basePrototype, {
  namespace: namespace,
  widgetName: name,
  widgetEventPrefix: name,
  widgetBaseClass: fullName,
  base: base.prototype
  }, prototype );
   
  $.widget.bridge( name, $[ namespace ][ name ] );
  };
   
  $.widget.bridge = function( name, object ) {
  $.fn[ name ] = function( options ) {
  var isMethodCall = typeof options === "string",
  args = slice.call( arguments, 1 ),
  returnValue = this;
   
  // allow multiple hashes to be passed on init
  options = !isMethodCall && args.length ?
  $.extend.apply( null, [ true, options ].concat(args) ) :
  options;
   
  // prevent calls to internal methods
  if ( isMethodCall && options.charAt( 0 ) === "_" ) {
  return returnValue;
  }
   
  if ( isMethodCall ) {
  this.each(function() {
  var instance = $.data( this, name );
  if ( !instance ) {
  return $.error( "cannot call methods on " + name + " prior to initialization; " +
  "attempted to call method '" + options + "'" );
  }
  if ( !$.isFunction( instance[options] ) ) {
  return $.error( "no such method '" + options + "' for " + name + " widget instance" );
  }
  var methodValue = instance[ options ].apply( instance, args );
  if ( methodValue !== instance && methodValue !== undefined ) {
  returnValue = methodValue;
  return false;
  }
  });
  } else {
  this.each(function() {
  var instance = $.data( this, name );
  if ( instance ) {
  instance.option( options || {} )._init();
  } else {
  object( options, this );
  }
  });
  }
   
  return returnValue;
  };
  };
   
  $.Widget = function( options, element ) {
  // allow instantiation without "new" keyword
  if ( !this._createWidget ) {
  return new $[ namespace ][ name ]( options, element );
  }
   
  // allow instantiation without initializing for simple inheritance
  // must use "new" keyword (the code above always passes args)
  if ( arguments.length ) {
  this._createWidget( options, element );
  }
  };
   
  $.Widget.prototype = {
  widgetName: "widget",
  widgetEventPrefix: "",
  defaultElement: "<div>",
  options: {
  disabled: false
  },
  _createWidget: function( options, element ) {
  element = $( element || this.defaultElement || this )[ 0 ];
  this.element = $( element );
  this.options = $.extend( true, {},
  this.options,
  this._getCreateOptions(),
  options );
   
  this.bindings = $();
  this.hoverable = $();
  this.focusable = $();
   
  if ( element !== this ) {
  $.data( element, this.widgetName, this );
  this._bind({ remove: "destroy" });
  }
   
  this._create();
  this._trigger( "create" );
  this._init();
  },
  _getCreateOptions: function() {
  return $.metadata && $.metadata.get( this.element[0] )[ this.widgetName ];
  },
  _create: $.noop,
  _init: $.noop,
   
  _super: function( method ) {
  return this.base[ method ].apply( this, slice.call( arguments, 1 ) );
  },
  _superApply: function( method, args ) {
  return this.base[ method ].apply( this, args );
  },
   
  destroy: function() {
  this._destroy();
  // we can probably remove the unbind calls in 2.0
  // all event bindings should go through this._bind()
  this.element
  .unbind( "." + this.widgetName )
  .removeData( this.widgetName );
  this.widget()
  .unbind( "." + this.widgetName )
  .removeAttr( "aria-disabled" )
  .removeClass(
  this.widgetBaseClass + "-disabled " +
  "ui-state-disabled" );
   
  // clean up events and states
  this.bindings.unbind( "." + this.widgetName );
  this.hoverable.removeClass( "ui-state-hover" );
  this.focusable.removeClass( "ui-state-focus" );
  },
  _destroy: $.noop,
   
  widget: function() {
  return this.element;
  },
   
  option: function( key, value ) {
  var options = key;
   
  if ( arguments.length === 0 ) {
  // don't return a reference to the internal hash
  return $.extend( {}, this.options );
  }
   
  if (typeof key === "string" ) {
  if ( value === undefined ) {
  return this.options[ key ];
  }
  options = {};
  options[ key ] = value;
  }
   
  this._setOptions( options );
   
  return this;
  },
  _setOptions: function( options ) {
  var self = this;
  $.each( options, function( key, value ) {
  self._setOption( key, value );
  });
   
  return this;
  },
  _setOption: function( key, value ) {
  this.options[ key ] = value;
   
  if ( key === "disabled" ) {
  this.widget()
  .toggleClass( this.widgetBaseClass + "-disabled ui-state-disabled", !!value )
  .attr( "aria-disabled", value );
  this.hoverable.removeClass( "ui-state-hover" );
  this.focusable.removeClass( "ui-state-focus" );
  }
   
  return this;
  },
   
  enable: function() {
  return this._setOption( "disabled", false );
  },
  disable: function() {
  return this._setOption( "disabled", true );
  },
   
  _bind: function( element, handlers ) {
  // no element argument, shuffle and use this.element
  if ( !handlers ) {
  handlers = element;
  element = this.element;
  } else {
  this.bindings = this.bindings.add( element );
  }
  var instance = this;
  $.each( handlers, function( event, handler ) {
  element.bind( event + "." + instance.widgetName, function() {
  // allow widgets to customize the disabled handling
  // - disabled as an array instead of boolean
  // - disabled class as method for disabling individual parts
  if ( instance.options.disabled === true ||
  $( this ).hasClass( "ui-state-disabled" ) ) {
  return;
  }
  return ( typeof handler === "string" ? instance[ handler ] : handler )
  .apply( instance, arguments );
  });
  });
  },
   
  _hoverable: function( element ) {
  this.hoverable = this.hoverable.add( element );
  this._bind( element, {
  mouseenter: function( event ) {
  $( event.currentTarget ).addClass( "ui-state-hover" );
  },
  mouseleave: function( event ) {
  $( event.currentTarget ).removeClass( "ui-state-hover" );
  }
  });
  },
   
  _focusable: function( element ) {
  this.focusable = this.focusable.add( element );
  this._bind( element, {
  focusin: function( event ) {
  $( event.currentTarget ).addClass( "ui-state-focus" );
  },
  focusout: function( event ) {
  $( event.currentTarget ).removeClass( "ui-state-focus" );
  }
  });
  },
   
  _trigger: function( type, event, data ) {
  var callback = this.options[ type ],
  args;
   
  event = $.Event( event );
  event.type = ( type === this.widgetEventPrefix ?
  type :
  this.widgetEventPrefix + type ).toLowerCase();
  data = data || {};
   
  // copy original event properties over to the new event
  // this would happen if we could call $.event.fix instead of $.Event
  // but we don't have a way to force an event to be fixed multiple times
  if ( event.originalEvent ) {
  for ( var i = $.event.props.length, prop; i; ) {
  prop = $.event.props[ --i ];
  event[ prop ] = event.originalEvent[ prop ];
  }
  }
   
  this.element.trigger( event, data );
   
  args = $.isArray( data ) ?
  [ event ].concat( data ) :
  [ event, data ];
   
  return !( $.isFunction( callback ) &&
  callback.apply( this.element[0], args ) === false ||
  event.isDefaultPrevented() );
  }
  };
   
  })( jQuery );