www

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README

jquery.ui.widget.js (6011B)


      1 /*!
      2  * jQuery UI Widget 1.8
      3  *
      4  * Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about)
      5  * Dual licensed under the MIT (MIT-LICENSE.txt)
      6  * and GPL (GPL-LICENSE.txt) licenses.
      7  *
      8  * http://docs.jquery.com/UI/Widget
      9  */
     10 (function( $ ) {
     11 
     12 var _remove = $.fn.remove;
     13 
     14 $.fn.remove = function( selector, keepData ) {
     15 	return this.each(function() {
     16 		if ( !keepData ) {
     17 			if ( !selector || $.filter( selector, [ this ] ).length ) {
     18 				$( "*", this ).add( this ).each(function() {
     19 					$( this ).triggerHandler( "remove" );
     20 				});
     21 			}
     22 		}
     23 		return _remove.call( $(this), selector, keepData );
     24 	});
     25 };
     26 
     27 $.widget = function( name, base, prototype ) {
     28 	var namespace = name.split( "." )[ 0 ],
     29 		fullName;
     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 ] = function( elem ) {
     40 		return !!$.data( elem, name );
     41 	};
     42 
     43 	$[ namespace ] = $[ namespace ] || {};
     44 	$[ namespace ][ name ] = function( options, element ) {
     45 		// allow instantiation without initializing for simple inheritance
     46 		if ( arguments.length ) {
     47 			this._createWidget( options, element );
     48 		}
     49 	};
     50 
     51 	var basePrototype = new base();
     52 	// we need to make the options hash a property directly on the new instance
     53 	// otherwise we'll modify the options hash on the prototype that we're
     54 	// inheriting from
     55 //	$.each( basePrototype, function( key, val ) {
     56 //		if ( $.isPlainObject(val) ) {
     57 //			basePrototype[ key ] = $.extend( {}, val );
     58 //		}
     59 //	});
     60 	basePrototype.options = $.extend( {}, basePrototype.options );
     61 	$[ namespace ][ name ].prototype = $.extend( true, basePrototype, {
     62 		namespace: namespace,
     63 		widgetName: name,
     64 		widgetEventPrefix: $[ namespace ][ name ].prototype.widgetEventPrefix || name,
     65 		widgetBaseClass: fullName
     66 	}, prototype );
     67 
     68 	$.widget.bridge( name, $[ namespace ][ name ] );
     69 };
     70 
     71 $.widget.bridge = function( name, object ) {
     72 	$.fn[ name ] = function( options ) {
     73 		var isMethodCall = typeof options === "string",
     74 			args = Array.prototype.slice.call( arguments, 1 ),
     75 			returnValue = this;
     76 
     77 		// allow multiple hashes to be passed on init
     78 		options = !isMethodCall && args.length ?
     79 			$.extend.apply( null, [ true, options ].concat(args) ) :
     80 			options;
     81 
     82 		// prevent calls to internal methods
     83 		if ( isMethodCall && options.substring( 0, 1 ) === "_" ) {
     84 			return returnValue;
     85 		}
     86 
     87 		if ( isMethodCall ) {
     88 			this.each(function() {
     89 				var instance = $.data( this, name ),
     90 					methodValue = instance && $.isFunction( instance[options] ) ?
     91 						instance[ options ].apply( instance, args ) :
     92 						instance;
     93 				if ( methodValue !== instance && methodValue !== undefined ) {
     94 					returnValue = methodValue;
     95 					return false;
     96 				}
     97 			});
     98 		} else {
     99 			this.each(function() {
    100 				var instance = $.data( this, name );
    101 				if ( instance ) {
    102 					if ( options ) {
    103 						instance.option( options );
    104 					}
    105 					instance._init();
    106 				} else {
    107 					$.data( this, name, new object( options, this ) );
    108 				}
    109 			});
    110 		}
    111 
    112 		return returnValue;
    113 	};
    114 };
    115 
    116 $.Widget = function( options, element ) {
    117 	// allow instantiation without initializing for simple inheritance
    118 	if ( arguments.length ) {
    119 		this._createWidget( options, element );
    120 	}
    121 };
    122 
    123 $.Widget.prototype = {
    124 	widgetName: "widget",
    125 	widgetEventPrefix: "",
    126 	options: {
    127 		disabled: false
    128 	},
    129 	_createWidget: function( options, element ) {
    130 		// $.widget.bridge stores the plugin instance, but we do it anyway
    131 		// so that it's stored even before the _create function runs
    132 		this.element = $( element ).data( this.widgetName, this );
    133 		this.options = $.extend( true, {},
    134 			this.options,
    135 			$.metadata && $.metadata.get( element )[ this.widgetName ],
    136 			options );
    137 
    138 		var self = this;
    139 		this.element.bind( "remove." + this.widgetName, function() {
    140 			self.destroy();
    141 		});
    142 
    143 		this._create();
    144 		this._init();
    145 	},
    146 	_create: function() {},
    147 	_init: function() {},
    148 
    149 	destroy: function() {
    150 		this.element
    151 			.unbind( "." + this.widgetName )
    152 			.removeData( this.widgetName );
    153 		this.widget()
    154 			.unbind( "." + this.widgetName )
    155 			.removeAttr( "aria-disabled" )
    156 			.removeClass(
    157 				this.widgetBaseClass + "-disabled " +
    158 				this.namespace + "-state-disabled" );
    159 	},
    160 
    161 	widget: function() {
    162 		return this.element;
    163 	},
    164 
    165 	option: function( key, value ) {
    166 		var options = key,
    167 			self = this;
    168 
    169 		if ( arguments.length === 0 ) {
    170 			// don't return a reference to the internal hash
    171 			return $.extend( {}, self.options );
    172 		}
    173 
    174 		if  (typeof key === "string" ) {
    175 			if ( value === undefined ) {
    176 				return this.options[ key ];
    177 			}
    178 			options = {};
    179 			options[ key ] = value;
    180 		}
    181 
    182 		$.each( options, function( key, value ) {
    183 			self._setOption( key, value );
    184 		});
    185 
    186 		return self;
    187 	},
    188 	_setOption: function( key, value ) {
    189 		this.options[ key ] = value;
    190 
    191 		if ( key === "disabled" ) {
    192 			this.widget()
    193 				[ value ? "addClass" : "removeClass"](
    194 					this.widgetBaseClass + "-disabled" + " " +
    195 					this.namespace + "-state-disabled" )
    196 				.attr( "aria-disabled", value );
    197 		}
    198 
    199 		return this;
    200 	},
    201 
    202 	enable: function() {
    203 		return this._setOption( "disabled", false );
    204 	},
    205 	disable: function() {
    206 		return this._setOption( "disabled", true );
    207 	},
    208 
    209 	_trigger: function( type, event, data ) {
    210 		var callback = this.options[ type ];
    211 
    212 		event = $.Event( event );
    213 		event.type = ( type === this.widgetEventPrefix ?
    214 			type :
    215 			this.widgetEventPrefix + type ).toLowerCase();
    216 		data = data || {};
    217 
    218 		// copy original event properties over to the new event
    219 		// this would happen if we could call $.event.fix instead of $.Event
    220 		// but we don't have a way to force an event to be fixed multiple times
    221 		if ( event.originalEvent ) {
    222 			for ( var i = $.event.props.length, prop; i; ) {
    223 				prop = $.event.props[ --i ];
    224 				event[ prop ] = event.originalEvent[ prop ];
    225 			}
    226 		}
    227 
    228 		this.element.trigger( event, data );
    229 
    230 		return !( $.isFunction(callback) &&
    231 			callback.call( this.element[0], event, data ) === false ||
    232 			event.isDefaultPrevented() );
    233 	}
    234 };
    235 
    236 })( jQuery );