Projet

Général

Profil

Paste
Télécharger (14,7 ko) Statistiques
| Branche: | Révision:

root / drupal7 / sites / all / modules / jquery_update / replace / ui / ui / jquery.ui.widget.js @ 503b3f7b

1
/*!
2
 * jQuery UI Widget 1.10.2
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 );