integration/back-office/lib/jquery-ui/ui/jquery.ui.widget.js
changeset 2 78f71aa0a477
parent 1 b95aebb070b5
child 3 54f80d24f469
child 6 547b3ddedf7f
equal deleted inserted replaced
1:b95aebb070b5 2:78f71aa0a477
     1 /*!
       
     2  * jQuery UI Widget 1.10.3
       
     3  * http://jqueryui.com
       
     4  *
       
     5  * Copyright 2013 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 		// proxiedPrototype allows the provided prototype to remain unmodified
       
    29 		// so that it can be used as a mixin for multiple widgets (#8876)
       
    30 		proxiedPrototype = {},
       
    31 		namespace = name.split( "." )[ 0 ];
       
    32 
       
    33 	name = name.split( "." )[ 1 ];
       
    34 	fullName = namespace + "-" + name;
       
    35 
       
    36 	if ( !prototype ) {
       
    37 		prototype = base;
       
    38 		base = $.Widget;
       
    39 	}
       
    40 
       
    41 	// create selector for plugin
       
    42 	$.expr[ ":" ][ fullName.toLowerCase() ] = function( elem ) {
       
    43 		return !!$.data( elem, fullName );
       
    44 	};
       
    45 
       
    46 	$[ namespace ] = $[ namespace ] || {};
       
    47 	existingConstructor = $[ namespace ][ name ];
       
    48 	constructor = $[ namespace ][ name ] = function( options, element ) {
       
    49 		// allow instantiation without "new" keyword
       
    50 		if ( !this._createWidget ) {
       
    51 			return new constructor( options, element );
       
    52 		}
       
    53 
       
    54 		// allow instantiation without initializing for simple inheritance
       
    55 		// must use "new" keyword (the code above always passes args)
       
    56 		if ( arguments.length ) {
       
    57 			this._createWidget( options, element );
       
    58 		}
       
    59 	};
       
    60 	// extend with the existing constructor to carry over any static properties
       
    61 	$.extend( constructor, existingConstructor, {
       
    62 		version: prototype.version,
       
    63 		// copy the object used to create the prototype in case we need to
       
    64 		// redefine the widget later
       
    65 		_proto: $.extend( {}, prototype ),
       
    66 		// track widgets that inherit from this widget in case this widget is
       
    67 		// redefined after a widget inherits from it
       
    68 		_childConstructors: []
       
    69 	});
       
    70 
       
    71 	basePrototype = new base();
       
    72 	// we need to make the options hash a property directly on the new instance
       
    73 	// otherwise we'll modify the options hash on the prototype that we're
       
    74 	// inheriting from
       
    75 	basePrototype.options = $.widget.extend( {}, basePrototype.options );
       
    76 	$.each( prototype, function( prop, value ) {
       
    77 		if ( !$.isFunction( value ) ) {
       
    78 			proxiedPrototype[ prop ] = value;
       
    79 			return;
       
    80 		}
       
    81 		proxiedPrototype[ prop ] = (function() {
       
    82 			var _super = function() {
       
    83 					return base.prototype[ prop ].apply( this, arguments );
       
    84 				},
       
    85 				_superApply = function( args ) {
       
    86 					return base.prototype[ prop ].apply( this, args );
       
    87 				};
       
    88 			return function() {
       
    89 				var __super = this._super,
       
    90 					__superApply = this._superApply,
       
    91 					returnValue;
       
    92 
       
    93 				this._super = _super;
       
    94 				this._superApply = _superApply;
       
    95 
       
    96 				returnValue = value.apply( this, arguments );
       
    97 
       
    98 				this._super = __super;
       
    99 				this._superApply = __superApply;
       
   100 
       
   101 				return returnValue;
       
   102 			};
       
   103 		})();
       
   104 	});
       
   105 	constructor.prototype = $.widget.extend( basePrototype, {
       
   106 		// TODO: remove support for widgetEventPrefix
       
   107 		// always use the name + a colon as the prefix, e.g., draggable:start
       
   108 		// don't prefix for widgets that aren't DOM-based
       
   109 		widgetEventPrefix: existingConstructor ? basePrototype.widgetEventPrefix : name
       
   110 	}, proxiedPrototype, {
       
   111 		constructor: constructor,
       
   112 		namespace: namespace,
       
   113 		widgetName: name,
       
   114 		widgetFullName: fullName
       
   115 	});
       
   116 
       
   117 	// If this widget is being redefined then we need to find all widgets that
       
   118 	// are inheriting from it and redefine all of them so that they inherit from
       
   119 	// the new version of this widget. We're essentially trying to replace one
       
   120 	// level in the prototype chain.
       
   121 	if ( existingConstructor ) {
       
   122 		$.each( existingConstructor._childConstructors, function( i, child ) {
       
   123 			var childPrototype = child.prototype;
       
   124 
       
   125 			// redefine the child widget using the same prototype that was
       
   126 			// originally used, but inherit from the new version of the base
       
   127 			$.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor, child._proto );
       
   128 		});
       
   129 		// remove the list of existing child constructors from the old constructor
       
   130 		// so the old child constructors can be garbage collected
       
   131 		delete existingConstructor._childConstructors;
       
   132 	} else {
       
   133 		base._childConstructors.push( constructor );
       
   134 	}
       
   135 
       
   136 	$.widget.bridge( name, constructor );
       
   137 };
       
   138 
       
   139 $.widget.extend = function( target ) {
       
   140 	var input = slice.call( arguments, 1 ),
       
   141 		inputIndex = 0,
       
   142 		inputLength = input.length,
       
   143 		key,
       
   144 		value;
       
   145 	for ( ; inputIndex < inputLength; inputIndex++ ) {
       
   146 		for ( key in input[ inputIndex ] ) {
       
   147 			value = input[ inputIndex ][ key ];
       
   148 			if ( input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) {
       
   149 				// Clone objects
       
   150 				if ( $.isPlainObject( value ) ) {
       
   151 					target[ key ] = $.isPlainObject( target[ key ] ) ?
       
   152 						$.widget.extend( {}, target[ key ], value ) :
       
   153 						// Don't extend strings, arrays, etc. with objects
       
   154 						$.widget.extend( {}, value );
       
   155 				// Copy everything else by reference
       
   156 				} else {
       
   157 					target[ key ] = value;
       
   158 				}
       
   159 			}
       
   160 		}
       
   161 	}
       
   162 	return target;
       
   163 };
       
   164 
       
   165 $.widget.bridge = function( name, object ) {
       
   166 	var fullName = object.prototype.widgetFullName || name;
       
   167 	$.fn[ name ] = function( options ) {
       
   168 		var isMethodCall = typeof options === "string",
       
   169 			args = slice.call( arguments, 1 ),
       
   170 			returnValue = this;
       
   171 
       
   172 		// allow multiple hashes to be passed on init
       
   173 		options = !isMethodCall && args.length ?
       
   174 			$.widget.extend.apply( null, [ options ].concat(args) ) :
       
   175 			options;
       
   176 
       
   177 		if ( isMethodCall ) {
       
   178 			this.each(function() {
       
   179 				var methodValue,
       
   180 					instance = $.data( this, fullName );
       
   181 				if ( !instance ) {
       
   182 					return $.error( "cannot call methods on " + name + " prior to initialization; " +
       
   183 						"attempted to call method '" + options + "'" );
       
   184 				}
       
   185 				if ( !$.isFunction( instance[options] ) || options.charAt( 0 ) === "_" ) {
       
   186 					return $.error( "no such method '" + options + "' for " + name + " widget instance" );
       
   187 				}
       
   188 				methodValue = instance[ options ].apply( instance, args );
       
   189 				if ( methodValue !== instance && methodValue !== undefined ) {
       
   190 					returnValue = methodValue && methodValue.jquery ?
       
   191 						returnValue.pushStack( methodValue.get() ) :
       
   192 						methodValue;
       
   193 					return false;
       
   194 				}
       
   195 			});
       
   196 		} else {
       
   197 			this.each(function() {
       
   198 				var instance = $.data( this, fullName );
       
   199 				if ( instance ) {
       
   200 					instance.option( options || {} )._init();
       
   201 				} else {
       
   202 					$.data( this, fullName, new object( options, this ) );
       
   203 				}
       
   204 			});
       
   205 		}
       
   206 
       
   207 		return returnValue;
       
   208 	};
       
   209 };
       
   210 
       
   211 $.Widget = function( /* options, element */ ) {};
       
   212 $.Widget._childConstructors = [];
       
   213 
       
   214 $.Widget.prototype = {
       
   215 	widgetName: "widget",
       
   216 	widgetEventPrefix: "",
       
   217 	defaultElement: "<div>",
       
   218 	options: {
       
   219 		disabled: false,
       
   220 
       
   221 		// callbacks
       
   222 		create: null
       
   223 	},
       
   224 	_createWidget: function( options, element ) {
       
   225 		element = $( element || this.defaultElement || this )[ 0 ];
       
   226 		this.element = $( element );
       
   227 		this.uuid = uuid++;
       
   228 		this.eventNamespace = "." + this.widgetName + this.uuid;
       
   229 		this.options = $.widget.extend( {},
       
   230 			this.options,
       
   231 			this._getCreateOptions(),
       
   232 			options );
       
   233 
       
   234 		this.bindings = $();
       
   235 		this.hoverable = $();
       
   236 		this.focusable = $();
       
   237 
       
   238 		if ( element !== 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 ] ) {
       
   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 })( jQuery );