PageSourceSearch

https://www.springerpub.com/static/version1789146322/base/Magento/base/default/jquery/ui-modules/widget.js

js springerpub.com collected 2026-09-24 08:47:42 UTC 27,367 bytes, 756 lines download raw bytes

vendor: 4,424 bytes, lines 1-131
1/*!
2 * jQuery UI Widget 1.13.2
3 * http://jqueryui.com
4 *
5 * Copyright jQuery Foundation and other contributors
6 * Released under the MIT license.
7 * http://jquery.org/license
8 */
9
10//>>label: Widget
11//>>group: Core
12//>>description: Provides a factory for creating stateful widgets with a common API.
13//>>docs: http://api.jqueryui.com/jQuery.widget/
14//>>demos: http://jqueryui.com/widget/
15
16( function( factory ) {
17    "use strict";
18
19    if ( typeof define === "function" && define.amd ) {
20
21        // AMD. Register as an anonymous module.
22        define( [ "jquery", "./version" ], factory );
23    } else {
24
25        // Browser globals
26        factory( jQuery );
27    }
28} )( function( $ ) {
29    "use strict";
30
31    var widgetUuid = 0;
32    var widgetHasOwnProperty = Array.prototype.hasOwnProperty;
33    var widgetSlice = Array.prototype.slice;
34
35    $.cleanData = ( function( orig ) {
36        return function( elems ) {
37            var events, elem, i;
38            for ( i = 0; ( elem = elems[ i ] ) != null; i++ ) {
39
40                // Only trigger remove when necessary to save time
41                events = $._data( elem, "events" );
42                if ( events && events.remove ) {
43                    $( elem ).triggerHandler( "remove" );
44                }
45            }
46            orig( elems );
47        };
48    } )( $.cleanData );
49
50    $.widget = function( name, base, prototype ) {
51        var existingConstructor, constructor, basePrototype;
52
53        // ProxiedPrototype allows the provided prototype to remain unmodified
54        // so that it can be used as a mixin for multiple widgets (#8876)
55        var proxiedPrototype = {};
56
57        var namespace = name.split( "." )[ 0 ];
58        name = name.split( "." )[ 1 ];
59        var fullName = namespace + "-" + name;
60
61        if ( !prototype ) {
62            prototype = base;
63            base = $.Widget;
64        }
65
66        if ( Array.isArray( prototype ) ) {
67            prototype = $.extend.apply( null, [ {} ].concat( prototype ) );
68        }
69
70        // Create selector for plugin
71        $.expr.pseudos[ fullName.toLowerCase() ] = function( elem ) {
72            return !!$.data( elem, fullName );
73        };
74
75        $[ namespace ] = $[ namespace ] || {};
76        existingConstructor = $[ namespace ][ name ];
77        constructor = $[ namespace ][ name ] = function( options, element ) {
78
79            // Allow instantiation without "new" keyword
80            if ( !this || !this._createWidget ) {
81                return new constructor( options, element );
82            }
83
84            // Allow instantiation without initializing for simple inheritance
85            // must use "new" keyword (the code above always passes args)
86            if ( arguments.length ) {
87                this._createWidget( options, element );
88            }
89        };
90
91        // Extend with the existing constructor to carry over any static properties
92        $.extend( constructor, existingConstructor, {
93            version: prototype.version,
94
95            // Copy the object used to create the prototype in case we need to
96            // redefine the widget later
97            _proto: $.extend( {}, prototype ),
98
99            // Track widgets that inherit from this widget in case this widget is
100            // redefined after a widget inherits from it
101            _childConstructors: []
102        } );
103
104        basePrototype = new base();
105
106        // We need to make the options hash a property directly on the new instance
107        // otherwise we'll modify the options hash on the prototype that we're
108        // inheriting from
109        basePrototype.options = $.widget.extend( {}, basePrototype.options );
110        $.each( prototype, function( prop, value ) {
111            if ( typeof value !== "function" ) {
112                proxiedPrototype[ prop ] = value;
113                return;
114            }
115            proxiedPrototype[ prop ] = ( function() {
116                function _super() {
117                    return base.prototype[ prop ].apply( this, arguments );
118                }
119
120                function _superApply( args ) {
121                    return base.prototype[ prop ].apply( this, args );
122                }
123
124                return function() {
125                    var __super = this._super;
126                    var __superApply = this._superApply;
127                    var returnValue;
128
129                    this._super = _super;
130                    this._superApply = _superApply;
131
vendor: 22,518 bytes, lines 132-740
132                    returnValue = value.apply( this, arguments );
133
134                    this._super = __super;
135                    this._superApply = __superApply;
136
137                    return returnValue;
138                };
139            } )();
140        } );
141        constructor.prototype = $.widget.extend( basePrototype, {
142
143            // TODO: remove support for widgetEventPrefix
144            // always use the name + a colon as the prefix, e.g., draggable:start
145            // don't prefix for widgets that aren't DOM-based
146            widgetEventPrefix: existingConstructor ? ( basePrototype.widgetEventPrefix || name ) : name
147        }, proxiedPrototype, {
148            constructor: constructor,
149            namespace: namespace,
150            widgetName: name,
151            widgetFullName: fullName
152        } );
153
154        // If this widget is being redefined then we need to find all widgets that
155        // are inheriting from it and redefine all of them so that they inherit from
156        // the new version of this widget. We're essentially trying to replace one
157        // level in the prototype chain.
158        if ( existingConstructor ) {
159            $.each( existingConstructor._childConstructors, function( i, child ) {
160                var childPrototype = child.prototype;
161
162                // Redefine the child widget using the same prototype that was
163                // originally used, but inherit from the new version of the base
164                $.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor,
165                    child._proto );
166            } );
167
168            // Remove the list of existing child constructors from the old constructor
169            // so the old child constructors can be garbage collected
170            delete existingConstructor._childConstructors;
171        } else {
172            base._childConstructors.push( constructor );
173        }
174
175        $.widget.bridge( name, constructor );
176
177        return constructor;
178    };
179
180    $.widget.extend = function( target ) {
181        var input = widgetSlice.call( arguments, 1 );
182        var inputIndex = 0;
183        var inputLength = input.length;
184        var key;
185        var value;
186
187        for ( ; inputIndex < inputLength; inputIndex++ ) {
188            for ( key in input[ inputIndex ] ) {
189                value = input[ inputIndex ][ key ];
190                if ( widgetHasOwnProperty.call( input[ inputIndex ], key ) && value !== undefined ) {
191
192                    // Clone objects
193                    if ( $.isPlainObject( value ) ) {
194                        target[ key ] = $.isPlainObject( target[ key ] ) ?
195                            $.widget.extend( {}, target[ key ], value ) :
196
197                            // Don't extend strings, arrays, etc. with objects
198                            $.widget.extend( {}, value );
199
200                        // Copy everything else by reference
201                    } else {
202                        target[ key ] = value;
203                    }
204                }
205            }
206        }
207        return target;
208    };
209
210    $.widget.bridge = function( name, object ) {
211        var fullName = object.prototype.widgetFullName || name;
212        $.fn[ name ] = function( options ) {
213            var isMethodCall = typeof options === "string";
214            var args = widgetSlice.call( arguments, 1 );
215            var returnValue = this;
216
217            if ( isMethodCall ) {
218
219                // If this is an empty collection, we need to have the instance method
220                // return undefined instead of the jQuery instance
221                if ( !this.length && options === "instance" ) {
222                    returnValue = undefined;
223                } else {
224                    this.each( function() {
225                        var methodValue;
226                        var instance = $.data( this, fullName );
227
228                        if ( options === "instance" ) {
229                            returnValue = instance;
230                            return false;
231                        }
232
233                        if ( !instance ) {
234                            return $.error( "cannot call methods on " + name +
235                                " prior to initialization; " +
236                                "attempted to call method '" + options + "'" );
237                        }
238
239                        if ( typeof instance[ options ] !== "function" ||
240                            options.charAt( 0 ) === "_" ) {
241                            return $.error( "no such method '" + options + "' for " + name +
242                                " widget instance" );
243                        }
244
245                        methodValue = instance[ options ].apply( instance, args );
246
247                        if ( methodValue !== instance && methodValue !== undefined ) {
248                            returnValue = methodValue && methodValue.jquery ?
249                                returnValue.pushStack( methodValue.get() ) :
250                                methodValue;
251                            return false;
252                        }
253                    } );
254                }
255            } else {
256
257                // Allow multiple hashes to be passed on init
258                if ( args.length ) {
259                    options = $.widget.extend.apply( null, [ options ].concat( args ) );
260                }
261
262                this.each( function() {
263                    var instance = $.data( this, fullName );
264                    if ( instance ) {
265                        instance.option( options || {} );
266                        if ( instance._init ) {
267                            instance._init();
268                        }
269                    } else {
270                        $.data( this, fullName, new object( options, this ) );
271                    }
272                } );
273            }
274
275            return returnValue;
276        };
277    };
278
279    $.Widget = function( /* options, element */ ) {};
280    $.Widget._childConstructors = [];
281
282    $.Widget.prototype = {
283        widgetName: "widget",
284        widgetEventPrefix: "",
285        defaultElement: "<div>",
286
287        options: {
288            classes: {},
289            disabled: false,
290
291            // Callbacks
292            create: null
293        },
294
295        _createWidget: function( options, element ) {
296            element = $( element || this.defaultElement || this )[ 0 ];
297            this.element = $( element );
298            this.uuid = widgetUuid++;
299            this.eventNamespace = "." + this.widgetName + this.uuid;
300
301            this.bindings = $();
302            this.hoverable = $();
303            this.focusable = $();
304            this.classesElementLookup = {};
305
306            if ( element !== this ) {
307                $.data( element, this.widgetFullName, this );
308                this._on( true, this.element, {
309                    remove: function( event ) {
310                        if ( event.target === element ) {
311                            this.destroy();
312                        }
313                    }
314                } );
315                this.document = $( element.style ?
316
317                    // Element within the document
318                    element.ownerDocument :
319
320                    // Element is window or document
321                    element.document || element );
322                this.window = $( this.document[ 0 ].defaultView || this.document[ 0 ].parentWindow );
323            }
324
325            this.options = $.widget.extend( {},
326                this.options,
327                this._getCreateOptions(),
328                options );
329
330            this._create();
331
332            if ( this.options.disabled ) {
333                this._setOptionDisabled( this.options.disabled );
334            }
335
336            this._trigger( "create", null, this._getCreateEventData() );
337            this._init();
338        },
339
340        _getCreateOptions: function() {
341            return {};
342        },
343
344        _getCreateEventData: $.noop,
345
346        _create: $.noop,
347
348        _init: $.noop,
349
350        destroy: function() {
351            var that = this;
352
353            this._destroy();
354            $.each( this.classesElementLookup, function( key, value ) {
355                that._removeClass( value, key );
356            } );
357
358            // We can probably remove the unbind calls in 2.0
359            // all event bindings should go through this._on()
360            this.element
361                .off( this.eventNamespace )
362                .removeData( this.widgetFullName );
363            this.widget()
364                .off( this.eventNamespace )
365                .removeAttr( "aria-disabled" );
366
367            // Clean up events and states
368            this.bindings.off( this.eventNamespace );
369        },
370
371        _destroy: $.noop,
372
373        widget: function() {
374            return this.element;
375        },
376
377        option: function( key, value ) {
378            var options = key;
379            var parts;
380            var curOption;
381            var i;
382
383            if ( arguments.length === 0 ) {
384
385                // Don't return a reference to the internal hash
386                return $.widget.extend( {}, this.options );
387            }
388
389            if ( typeof key === "string" ) {
390
391                // Handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } }
392                options = {};
393                parts = key.split( "." );
394                key = parts.shift();
395                if ( parts.length ) {
396                    curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] );
397                    for ( i = 0; i < parts.length - 1; i++ ) {
398                        curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {};
399                        curOption = curOption[ parts[ i ] ];
400                    }
401                    key = parts.pop();
402                    if ( arguments.length === 1 ) {
403                        return curOption[ key ] === undefined ? null : curOption[ key ];
404                    }
405                    curOption[ key ] = value;
406                } else {
407                    if ( arguments.length === 1 ) {
408                        return this.options[ key ] === undefined ? null : this.options[ key ];
409                    }
410                    options[ key ] = value;
411                }
412            }
413
414            this._setOptions( options );
415
416            return this;
417        },
418
419        _setOptions: function( options ) {
420            var key;
421
422            for ( key in options ) {
423                this._setOption( key, options[ key ] );
424            }
425
426            return this;
427        },
428
429        _setOption: function( key, value ) {
430            if ( key === "classes" ) {
431                this._setOptionClasses( value );
432            }
433
434            this.options[ key ] = value;
435
436            if ( key === "disabled" ) {
437                this._setOptionDisabled( value );
438            }
439
440            return this;
441        },
442
443        _setOptionClasses: function( value ) {
444            var classKey, elements, currentElements;
445
446            for ( classKey in value ) {
447                currentElements = this.classesElementLookup[ classKey ];
448                if ( value[ classKey ] === this.options.classes[ classKey ] ||
449                    !currentElements ||
450                    !currentElements.length ) {
451                    continue;
452                }
453
454                // We are doing this to create a new jQuery object because the _removeClass() call
455                // on the next line is going to destroy the reference to the current elements being
456                // tracked. We need to save a copy of this collection so that we can add the new classes
457                // below.
458                elements = $( currentElements.get() );
459                this._removeClass( currentElements, classKey );
460
461                // We don't use _addClass() here, because that uses this.options.classes
462                // for generating the string of classes. We want to use the value passed in from
463                // _setOption(), this is the new value of the classes option which was passed to
464                // _setOption(). We pass this value directly to _classes().
465                elements.addClass( this._classes( {
466                    element: elements,
467                    keys: classKey,
468                    classes: value,
469                    add: true
470                } ) );
471            }
472        },
473
474        _setOptionDisabled: function( value ) {
475            this._toggleClass( this.widget(), this.widgetFullName + "-disabled", null, !!value );
476
477            // If the widget is becoming disabled, then nothing is interactive
478            if ( value ) {
479                this._removeClass( this.hoverable, null, "ui-state-hover" );
480                this._removeClass( this.focusable, null, "ui-state-focus" );
481            }
482        },
483
484        enable: function() {
485            return this._setOptions( { disabled: false } );
486        },
487
488        disable: function() {
489            return this._setOptions( { disabled: true } );
490        },
491
492        _classes: function( options ) {
493            var full = [];
494            var that = this;
495
496            options = $.extend( {
497                element: this.element,
498                classes: this.options.classes || {}
499            }, options );
500
501            function bindRemoveEvent() {
502                var nodesToBind = [];
503
504                options.element.each( function( _, element ) {
505                    var isTracked = $.map( that.classesElementLookup, function( elements ) {
506                        return elements;
507                    } )
508                        .some( function( elements ) {
509                            return elements.is( element );
510                        } );
511
512                    if ( !isTracked ) {
513                        nodesToBind.push( element );
514                    }
515                } );
516
517                that._on( $( nodesToBind ), {
518                    remove: "_untrackClassesElement"
519                } );
520            }
521
522            function processClassString( classes, checkOption ) {
523                var current, i;
524                for ( i = 0; i < classes.length; i++ ) {
525                    current = that.classesElementLookup[ classes[ i ] ] || $();
526                    if ( options.add ) {
527                        bindRemoveEvent();
528                        current = $( $.uniqueSort( current.get().concat( options.element.get() ) ) );
529                    } else {
530                        current = $( current.not( options.element ).get() );
531                    }
532                    that.classesElementLookup[ classes[ i ] ] = current;
533                    full.push( classes[ i ] );
534                    if ( checkOption && options.classes[ classes[ i ] ] ) {
535                        full.push( options.classes[ classes[ i ] ] );
536                    }
537                }
538            }
539
540            if ( options.keys ) {
541                processClassString( options.keys.match( /\S+/g ) || [], true );
542            }
543            if ( options.extra ) {
544                processClassString( options.extra.match( /\S+/g ) || [] );
545            }
546
547            return full.join( " " );
548        },
549
550        _untrackClassesElement: function( event ) {
551            var that = this;
552            $.each( that.classesElementLookup, function( key, value ) {
553                if ( $.inArray( event.target, value ) !== -1 ) {
554                    that.classesElementLookup[ key ] = $( value.not( event.target ).get() );
555                }
556            } );
557
558            this._off( $( event.target ) );
559        },
560
561        _removeClass: function( element, keys, extra ) {
562            return this._toggleClass( element, keys, extra, false );
563        },
564
565        _addClass: function( element, keys, extra ) {
566            return this._toggleClass( element, keys, extra, true );
567        },
568
569        _toggleClass: function( element, keys, extra, add ) {
570            add = ( typeof add === "boolean" ) ? add : extra;
571            var shift = ( typeof element === "string" || element === null ),
572                options = {
573                    extra: shift ? keys : extra,
574                    keys: shift ? element : keys,
575                    element: shift ? this.element : element,
576                    add: add
577                };
578            options.element.toggleClass( this._classes( options ), add );
579            return this;
580        },
581
582        _on: function( suppressDisabledCheck, element, handlers ) {
583            var delegateElement;
584            var instance = this;
585
586            // No suppressDisabledCheck flag, shuffle arguments
587            if ( typeof suppressDisabledCheck !== "boolean" ) {
588                handlers = element;
589                element = suppressDisabledCheck;
590                suppressDisabledCheck = false;
591            }
592
593            // No element argument, shuffle and use this.element
594            if ( !handlers ) {
595                handlers = element;
596                element = this.element;
597                delegateElement = this.widget();
598            } else {
599                element = delegateElement = $( element );
600                this.bindings = this.bindings.add( element );
601            }
602
603            $.each( handlers, function( event, handler ) {
604                function handlerProxy() {
605
606                    // Allow widgets to customize the disabled handling
607                    // - disabled as an array instead of boolean
608                    // - disabled class as method for disabling individual parts
609                    if ( !suppressDisabledCheck &&
610                        ( instance.options.disabled === true ||
611                            $( this ).hasClass( "ui-state-disabled" ) ) ) {
612                        return;
613                    }
614                    return ( typeof handler === "string" ? instance[ handler ] : handler )
615                        .apply( instance, arguments );
616                }
617
618                // Copy the guid so direct unbinding works
619                if ( typeof handler !== "string" ) {
620                    handlerProxy.guid = handler.guid =
621                        handler.guid || handlerProxy.guid || $.guid++;
622                }
623
624                var match = event.match( /^([\w:-]*)\s*(.*)$/ );
625                var eventName = match[ 1 ] + instance.eventNamespace;
626                var selector = match[ 2 ];
627
628                if ( selector ) {
629                    delegateElement.on( eventName, selector, handlerProxy );
630                } else {
631                    element.on( eventName, handlerProxy );
632                }
633            } );
634        },
635
636        _off: function( element, eventName ) {
637            eventName = ( eventName || "" ).split( " " ).join( this.eventNamespace + " " ) +
638                this.eventNamespace;
639            element.off( eventName );
640
641            // Clear the stack to avoid memory leaks (#10056)
642            this.bindings = $( this.bindings.not( element ).get() );
643            this.focusable = $( this.focusable.not( element ).get() );
644            this.hoverable = $( this.hoverable.not( element ).get() );
645        },
646
647        _delay: function( handler, delay ) {
648            function handlerProxy() {
649                return ( typeof handler === "string" ? instance[ handler ] : handler )
650                    .apply( instance, arguments );
651            }
652            var instance = this;
653            return setTimeout( handlerProxy, delay || 0 );
654        },
655
656        _hoverable: function( element ) {
657            this.hoverable = this.hoverable.add( element );
658            this._on( element, {
659                mouseenter: function( event ) {
660                    this._addClass( $( event.currentTarget ), null, "ui-state-hover" );
661                },
662                mouseleave: function( event ) {
663                    this._removeClass( $( event.currentTarget ), null, "ui-state-hover" );
664                }
665            } );
666        },
667
668        _focusable: function( element ) {
669            this.focusable = this.focusable.add( element );
670            this._on( element, {
671                focusin: function( event ) {
672                    this._addClass( $( event.currentTarget ), null, "ui-state-focus" );
673                },
674                focusout: function( event ) {
675                    this._removeClass( $( event.currentTarget ), null, "ui-state-focus" );
676                }
677            } );
678        },
679
680        _trigger: function( type, event, data ) {
681            var prop, orig;
682            var callback = this.options[ type ];
683
684            data = data || {};
685            event = $.Event( event );
686            event.type = ( type === this.widgetEventPrefix ?
687                type :
688                this.widgetEventPrefix + type ).toLowerCase();
689
690            // The original event may come from any element
691            // so we need to reset the target on the new event
692            event.target = this.element[ 0 ];
693
694            // Copy original event properties over to the new event
695            orig = event.originalEvent;
696            if ( orig ) {
697                for ( prop in orig ) {
698                    if ( !( prop in event ) ) {
699                        event[ prop ] = orig[ prop ];
700                    }
701                }
702            }
703
704            this.element.trigger( event, data );
705            return !( typeof callback === "function" &&
706                callback.apply( this.element[ 0 ], [ event ].concat( data ) ) === false ||
707                event.isDefaultPrevented() );
708        }
709    };
710
711    $.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) {
712        $.Widget.prototype[ "_" + method ] = function( element, options, callback ) {
713            if ( typeof options === "string" ) {
714                options = { effect: options };
715            }
716
717            var hasOptions;
718            var effectName = !options ?
719                method :
720                options === true || typeof options === "number" ?
721                    defaultEffect :
722                    options.effect || defaultEffect;
723
724            options = options || {};
725            if ( typeof options === "number" ) {
726                options = { duration: options };
727            } else if ( options === true ) {
728                options = {};
729            }
730
731            hasOptions = !$.isEmptyObject( options );
732            options.complete = callback;
733
734            if ( options.delay ) {
735                element.delay( options.delay );
736            }
737
738            if ( hasOptions && $.effects && $.effects.effect[ effectName ] ) {
739                element[ method ]( options );
740            } else if ( effectName !== method && element[ effectName ] ) {
741                element[ effectName ]( options.duration, options.easing, callback );
742            } else {
743                element.queue( function( next ) {
744                    $( this )[ method ]();
745                    if ( callback ) {
746                        callback.call( element[ 0 ] );
747                    }
748                    next();
749                } );
750            }
751        };
752    } );
753
754    return $.widget;
755
756} );

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.