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