Merge "Add 3D filetype for STL files"
[lhc/web/wiklou.git] / resources / lib / jquery.ui / jquery.ui.widget.js
index 66ef013..4d84afc 100644 (file)
@@ -1,48 +1,32 @@
 /*!
- * jQuery UI Widget 1.8.24
+ * jQuery UI Widget 1.9.2
+ * http://jqueryui.com
  *
- * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
- * Dual licensed under the MIT or GPL Version 2 licenses.
+ * Copyright 2012 jQuery Foundation and other contributors
+ * Released under the MIT license.
  * http://jquery.org/license
  *
- * http://docs.jquery.com/UI/Widget
+ * http://api.jqueryui.com/jQuery.widget/
  */
 (function( $, undefined ) {
 
-// jQuery 1.4+
-if ( $.cleanData ) {
-       var _cleanData = $.cleanData;
-       $.cleanData = function( elems ) {
-               for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
-                       try {
-                               $( elem ).triggerHandler( "remove" );
-                       // http://bugs.jquery.com/ticket/8235
-                       } catch( e ) {}
-               }
-               _cleanData( elems );
-       };
-} else {
-       var _remove = $.fn.remove;
-       $.fn.remove = function( selector, keepData ) {
-               return this.each(function() {
-                       if ( !keepData ) {
-                               if ( !selector || $.filter( selector, [ this ] ).length ) {
-                                       $( "*", this ).add( [ this ] ).each(function() {
-                                               try {
-                                                       $( this ).triggerHandler( "remove" );
-                                               // http://bugs.jquery.com/ticket/8235
-                                               } catch( e ) {}
-                                       });
-                               }
-                       }
-                       return _remove.call( $(this), selector, keepData );
-               });
-       };
-}
+var uuid = 0,
+       slice = Array.prototype.slice,
+       _cleanData = $.cleanData;
+$.cleanData = function( elems ) {
+       for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
+               try {
+                       $( elem ).triggerHandler( "remove" );
+               // http://bugs.jquery.com/ticket/8235
+               } catch( e ) {}
+       }
+       _cleanData( elems );
+};
 
 $.widget = function( name, base, prototype ) {
-       var namespace = name.split( "." )[ 0 ],
-               fullName;
+       var fullName, existingConstructor, constructor, basePrototype,
+               namespace = name.split( "." )[ 0 ];
+
        name = name.split( "." )[ 1 ];
        fullName = namespace + "-" + name;
 
@@ -52,81 +36,167 @@ $.widget = function( name, base, prototype ) {
        }
 
        // create selector for plugin
-       $.expr[ ":" ][ fullName ] = function( elem ) {
-               return !!$.data( elem, name );
+       $.expr.pseudos[ fullName.toLowerCase() ] = function( elem ) {
+               return !!$.data( elem, fullName );
        };
 
        $[ namespace ] = $[ namespace ] || {};
-       $[ namespace ][ name ] = function( options, element ) {
+       existingConstructor = $[ namespace ][ name ];
+       constructor = $[ namespace ][ name ] = function( options, element ) {
+               // allow instantiation without "new" keyword
+               if ( !this._createWidget ) {
+                       return new constructor( options, element );
+               }
+
                // allow instantiation without initializing for simple inheritance
+               // must use "new" keyword (the code above always passes args)
                if ( arguments.length ) {
                        this._createWidget( options, element );
                }
        };
-
-       var basePrototype = new base();
+       // extend with the existing constructor to carry over any static properties
+       $.extend( constructor, existingConstructor, {
+               version: prototype.version,
+               // copy the object used to create the prototype in case we need to
+               // redefine the widget later
+               _proto: $.extend( {}, prototype ),
+               // track widgets that inherit from this widget in case this widget is
+               // redefined after a widget inherits from it
+               _childConstructors: []
+       });
+
+       basePrototype = new base();
        // we need to make the options hash a property directly on the new instance
        // otherwise we'll modify the options hash on the prototype that we're
        // inheriting from
-//     $.each( basePrototype, function( key, val ) {
-//             if ( $.isPlainObject(val) ) {
-//                     basePrototype[ key ] = $.extend( {}, val );
-//             }
-//     });
-       basePrototype.options = $.extend( true, {}, basePrototype.options );
-       $[ namespace ][ name ].prototype = $.extend( true, basePrototype, {
+       basePrototype.options = $.widget.extend( {}, basePrototype.options );
+       $.each( prototype, function( prop, value ) {
+               if ( $.isFunction( value ) ) {
+                       prototype[ prop ] = (function() {
+                               var _super = function() {
+                                               return base.prototype[ prop ].apply( this, arguments );
+                                       },
+                                       _superApply = function( args ) {
+                                               return base.prototype[ prop ].apply( this, args );
+                                       };
+                               return function() {
+                                       var __super = this._super,
+                                               __superApply = this._superApply,
+                                               returnValue;
+
+                                       this._super = _super;
+                                       this._superApply = _superApply;
+
+                                       returnValue = value.apply( this, arguments );
+
+                                       this._super = __super;
+                                       this._superApply = __superApply;
+
+                                       return returnValue;
+                               };
+                       })();
+               }
+       });
+       constructor.prototype = $.widget.extend( basePrototype, {
+               // TODO: remove support for widgetEventPrefix
+               // always use the name + a colon as the prefix, e.g., draggable:start
+               // don't prefix for widgets that aren't DOM-based
+               widgetEventPrefix: existingConstructor ? basePrototype.widgetEventPrefix : name
+       }, prototype, {
+               constructor: constructor,
                namespace: namespace,
                widgetName: name,
-               widgetEventPrefix: $[ namespace ][ name ].prototype.widgetEventPrefix || name,
-               widgetBaseClass: fullName
-       }, prototype );
+               // TODO remove widgetBaseClass, see #8155
+               widgetBaseClass: fullName,
+               widgetFullName: fullName
+       });
+
+       // If this widget is being redefined then we need to find all widgets that
+       // are inheriting from it and redefine all of them so that they inherit from
+       // the new version of this widget. We're essentially trying to replace one
+       // level in the prototype chain.
+       if ( existingConstructor ) {
+               $.each( existingConstructor._childConstructors, function( i, child ) {
+                       var childPrototype = child.prototype;
+
+                       // redefine the child widget using the same prototype that was
+                       // originally used, but inherit from the new version of the base
+                       $.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor, child._proto );
+               });
+               // remove the list of existing child constructors from the old constructor
+               // so the old child constructors can be garbage collected
+               delete existingConstructor._childConstructors;
+       } else {
+               base._childConstructors.push( constructor );
+       }
 
-       $.widget.bridge( name, $[ namespace ][ name ] );
+       $.widget.bridge( name, constructor );
+};
+
+$.widget.extend = function( target ) {
+       var input = slice.call( arguments, 1 ),
+               inputIndex = 0,
+               inputLength = input.length,
+               key,
+               value;
+       for ( ; inputIndex < inputLength; inputIndex++ ) {
+               for ( key in input[ inputIndex ] ) {
+                       value = input[ inputIndex ][ key ];
+                       if ( input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) {
+                               // Clone objects
+                               if ( $.isPlainObject( value ) ) {
+                                       target[ key ] = $.isPlainObject( target[ key ] ) ?
+                                               $.widget.extend( {}, target[ key ], value ) :
+                                               // Don't extend strings, arrays, etc. with objects
+                                               $.widget.extend( {}, value );
+                               // Copy everything else by reference
+                               } else {
+                                       target[ key ] = value;
+                               }
+                       }
+               }
+       }
+       return target;
 };
 
 $.widget.bridge = function( name, object ) {
+       var fullName = object.prototype.widgetFullName || name;
        $.fn[ name ] = function( options ) {
                var isMethodCall = typeof options === "string",
-                       args = Array.prototype.slice.call( arguments, 1 ),
+                       args = slice.call( arguments, 1 ),
                        returnValue = this;
 
                // allow multiple hashes to be passed on init
                options = !isMethodCall && args.length ?
-                       $.extend.apply( null, [ true, options ].concat(args) ) :
+                       $.widget.extend.apply( null, [ options ].concat(args) ) :
                        options;
 
-               // prevent calls to internal methods
-               if ( isMethodCall && options.charAt( 0 ) === "_" ) {
-                       return returnValue;
-               }
-
                if ( isMethodCall ) {
                        this.each(function() {
-                               var instance = $.data( this, name ),
-                                       methodValue = instance && $.isFunction( instance[options] ) ?
-                                               instance[ options ].apply( instance, args ) :
-                                               instance;
-                               // TODO: add this back in 1.9 and use $.error() (see #5972)
-//                             if ( !instance ) {
-//                                     throw "cannot call methods on " + name + " prior to initialization; " +
-//                                             "attempted to call method '" + options + "'";
-//                             }
-//                             if ( !$.isFunction( instance[options] ) ) {
-//                                     throw "no such method '" + options + "' for " + name + " widget instance";
-//                             }
-//                             var methodValue = instance[ options ].apply( instance, args );
+                               var methodValue,
+                                       instance = $.data( this, fullName );
+                               if ( !instance ) {
+                                       return $.error( "cannot call methods on " + name + " prior to initialization; " +
+                                               "attempted to call method '" + options + "'" );
+                               }
+                               if ( !$.isFunction( instance[options] ) || options.charAt( 0 ) === "_" ) {
+                                       return $.error( "no such method '" + options + "' for " + name + " widget instance" );
+                               }
+                               methodValue = instance[ options ].apply( instance, args );
                                if ( methodValue !== instance && methodValue !== undefined ) {
-                                       returnValue = methodValue;
+                                       returnValue = methodValue && methodValue.jquery ?
+                                               returnValue.pushStack( methodValue.get() ) :
+                                               methodValue;
                                        return false;
                                }
                        });
                } else {
                        this.each(function() {
-                               var instance = $.data( this, name );
+                               var instance = $.data( this, fullName );
                                if ( instance ) {
                                        instance.option( options || {} )._init();
                                } else {
-                                       $.data( this, name, new object( options, this ) );
+                                       $.data( this, fullName, new object( options, this ) );
                                }
                        });
                }
@@ -135,74 +205,126 @@ $.widget.bridge = function( name, object ) {
        };
 };
 
-$.Widget = function( options, element ) {
-       // allow instantiation without initializing for simple inheritance
-       if ( arguments.length ) {
-               this._createWidget( options, element );
-       }
-};
+$.Widget = function( /* options, element */ ) {};
+$.Widget._childConstructors = [];
 
 $.Widget.prototype = {
        widgetName: "widget",
        widgetEventPrefix: "",
+       defaultElement: "<div>",
        options: {
-               disabled: false
+               disabled: false,
+
+               // callbacks
+               create: null
        },
        _createWidget: function( options, element ) {
-               // $.widget.bridge stores the plugin instance, but we do it anyway
-               // so that it's stored even before the _create function runs
-               $.data( element, this.widgetName, this );
+               element = $( element || this.defaultElement || this )[ 0 ];
                this.element = $( element );
-               this.options = $.extend( true, {},
+               this.uuid = uuid++;
+               this.eventNamespace = "." + this.widgetName + this.uuid;
+               this.options = $.widget.extend( {},
                        this.options,
                        this._getCreateOptions(),
                        options );
 
-               var self = this;
-               this.element.bind( "remove." + this.widgetName, function() {
-                       self.destroy();
-               });
+               this.bindings = $();
+               this.hoverable = $();
+               this.focusable = $();
+
+               if ( element !== this ) {
+                       // 1.9 BC for #7810
+                       // TODO remove dual storage
+                       $.data( element, this.widgetName, this );
+                       $.data( element, this.widgetFullName, this );
+                       this._on( true, this.element, {
+                               remove: function( event ) {
+                                       if ( event.target === element ) {
+                                               this.destroy();
+                                       }
+                               }
+                       });
+                       this.document = $( element.style ?
+                               // element within the document
+                               element.ownerDocument :
+                               // element is window or document
+                               element.document || element );
+                       this.window = $( this.document[0].defaultView || this.document[0].parentWindow );
+               }
 
                this._create();
-               this._trigger( "create" );
+               this._trigger( "create", null, this._getCreateEventData() );
                this._init();
        },
-       _getCreateOptions: function() {
-               return $.metadata && $.metadata.get( this.element[0] )[ this.widgetName ];
-       },
-       _create: function() {},
-       _init: function() {},
+       _getCreateOptions: $.noop,
+       _getCreateEventData: $.noop,
+       _create: $.noop,
+       _init: $.noop,
 
        destroy: function() {
+               this._destroy();
+               // we can probably remove the unbind calls in 2.0
+               // all event bindings should go through this._on()
                this.element
-                       .unbind( "." + this.widgetName )
-                       .removeData( this.widgetName );
+                       .unbind( this.eventNamespace )
+                       // 1.9 BC for #7810
+                       // TODO remove dual storage
+                       .removeData( this.widgetName )
+                       .removeData( this.widgetFullName )
+                       // support: jquery <1.6.3
+                       // http://bugs.jquery.com/ticket/9413
+                       .removeData( $.camelCase( this.widgetFullName ) );
                this.widget()
-                       .unbind( "." + this.widgetName )
+                       .unbind( this.eventNamespace )
                        .removeAttr( "aria-disabled" )
                        .removeClass(
-                               this.widgetBaseClass + "-disabled " +
+                               this.widgetFullName + "-disabled " +
                                "ui-state-disabled" );
+
+               // clean up events and states
+               this.bindings.unbind( this.eventNamespace );
+               this.hoverable.removeClass( "ui-state-hover" );
+               this.focusable.removeClass( "ui-state-focus" );
        },
+       _destroy: $.noop,
 
        widget: function() {
                return this.element;
        },
 
        option: function( key, value ) {
-               var options = key;
+               var options = key,
+                       parts,
+                       curOption,
+                       i;
 
                if ( arguments.length === 0 ) {
                        // don't return a reference to the internal hash
-                       return $.extend( {}, this.options );
+                       return $.widget.extend( {}, this.options );
                }
 
-               if  (typeof key === "string" ) {
-                       if ( value === undefined ) {
-                               return this.options[ key ];
-                       }
+               if ( typeof key === "string" ) {
+                       // handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } }
                        options = {};
-                       options[ key ] = value;
+                       parts = key.split( "." );
+                       key = parts.shift();
+                       if ( parts.length ) {
+                               curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] );
+                               for ( i = 0; i < parts.length - 1; i++ ) {
+                                       curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {};
+                                       curOption = curOption[ parts[ i ] ];
+                               }
+                               key = parts.pop();
+                               if ( value === undefined ) {
+                                       return curOption[ key ] === undefined ? null : curOption[ key ];
+                               }
+                               curOption[ key ] = value;
+                       } else {
+                               if ( value === undefined ) {
+                                       return this.options[ key ] === undefined ? null : this.options[ key ];
+                               }
+                               options[ key ] = value;
+                       }
                }
 
                this._setOptions( options );
@@ -210,10 +332,11 @@ $.Widget.prototype = {
                return this;
        },
        _setOptions: function( options ) {
-               var self = this;
-               $.each( options, function( key, value ) {
-                       self._setOption( key, value );
-               });
+               var key;
+
+               for ( key in options ) {
+                       this._setOption( key, options[ key ] );
+               }
 
                return this;
        },
@@ -222,10 +345,10 @@ $.Widget.prototype = {
 
                if ( key === "disabled" ) {
                        this.widget()
-                               [ value ? "addClass" : "removeClass"](
-                                       this.widgetBaseClass + "-disabled" + " " +
-                                       "ui-state-disabled" )
+                               .toggleClass( this.widgetFullName + "-disabled ui-state-disabled", !!value )
                                .attr( "aria-disabled", value );
+                       this.hoverable.removeClass( "ui-state-hover" );
+                       this.focusable.removeClass( "ui-state-focus" );
                }
 
                return this;
@@ -238,6 +361,97 @@ $.Widget.prototype = {
                return this._setOption( "disabled", true );
        },
 
+       _on: function( suppressDisabledCheck, element, handlers ) {
+               var delegateElement,
+                       instance = this;
+
+               // no suppressDisabledCheck flag, shuffle arguments
+               if ( typeof suppressDisabledCheck !== "boolean" ) {
+                       handlers = element;
+                       element = suppressDisabledCheck;
+                       suppressDisabledCheck = false;
+               }
+
+               // no element argument, shuffle and use this.element
+               if ( !handlers ) {
+                       handlers = element;
+                       element = this.element;
+                       delegateElement = this.widget();
+               } else {
+                       // accept selectors, DOM elements
+                       element = delegateElement = $( element );
+                       this.bindings = this.bindings.add( element );
+               }
+
+               $.each( handlers, function( event, handler ) {
+                       function handlerProxy() {
+                               // allow widgets to customize the disabled handling
+                               // - disabled as an array instead of boolean
+                               // - disabled class as method for disabling individual parts
+                               if ( !suppressDisabledCheck &&
+                                               ( instance.options.disabled === true ||
+                                                       $( this ).hasClass( "ui-state-disabled" ) ) ) {
+                                       return;
+                               }
+                               return ( typeof handler === "string" ? instance[ handler ] : handler )
+                                       .apply( instance, arguments );
+                       }
+
+                       // copy the guid so direct unbinding works
+                       if ( typeof handler !== "string" ) {
+                               handlerProxy.guid = handler.guid =
+                                       handler.guid || handlerProxy.guid || $.guid++;
+                       }
+
+                       var match = event.match( /^(\w+)\s*(.*)$/ ),
+                               eventName = match[1] + instance.eventNamespace,
+                               selector = match[2];
+                       if ( selector ) {
+                               delegateElement.delegate( selector, eventName, handlerProxy );
+                       } else {
+                               element.bind( eventName, handlerProxy );
+                       }
+               });
+       },
+
+       _off: function( element, eventName ) {
+               eventName = (eventName || "").split( " " ).join( this.eventNamespace + " " ) + this.eventNamespace;
+               element.unbind( eventName ).undelegate( eventName );
+       },
+
+       _delay: function( handler, delay ) {
+               function handlerProxy() {
+                       return ( typeof handler === "string" ? instance[ handler ] : handler )
+                               .apply( instance, arguments );
+               }
+               var instance = this;
+               return setTimeout( handlerProxy, delay || 0 );
+       },
+
+       _hoverable: function( element ) {
+               this.hoverable = this.hoverable.add( element );
+               this._on( element, {
+                       mouseenter: function( event ) {
+                               $( event.currentTarget ).addClass( "ui-state-hover" );
+                       },
+                       mouseleave: function( event ) {
+                               $( event.currentTarget ).removeClass( "ui-state-hover" );
+                       }
+               });
+       },
+
+       _focusable: function( element ) {
+               this.focusable = this.focusable.add( element );
+               this._on( element, {
+                       focusin: function( event ) {
+                               $( event.currentTarget ).addClass( "ui-state-focus" );
+                       },
+                       focusout: function( event ) {
+                               $( event.currentTarget ).removeClass( "ui-state-focus" );
+                       }
+               });
+       },
+
        _trigger: function( type, event, data ) {
                var prop, orig,
                        callback = this.options[ type ];
@@ -262,11 +476,53 @@ $.Widget.prototype = {
                }
 
                this.element.trigger( event, data );
-
-               return !( $.isFunction(callback) &&
-                       callback.call( this.element[0], event, data ) === false ||
+               return !( $.isFunction( callback ) &&
+                       callback.apply( this.element[0], [ event ].concat( data ) ) === false ||
                        event.isDefaultPrevented() );
        }
 };
 
+$.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) {
+       $.Widget.prototype[ "_" + method ] = function( element, options, callback ) {
+               if ( typeof options === "string" ) {
+                       options = { effect: options };
+               }
+               var hasOptions,
+                       effectName = !options ?
+                               method :
+                               options === true || typeof options === "number" ?
+                                       defaultEffect :
+                                       options.effect || defaultEffect;
+               options = options || {};
+               if ( typeof options === "number" ) {
+                       options = { duration: options };
+               }
+               hasOptions = !$.isEmptyObject( options );
+               options.complete = callback;
+               if ( options.delay ) {
+                       element.delay( options.delay );
+               }
+               if ( hasOptions && $.effects && ( $.effects.effect[ effectName ] || $.uiBackCompat !== false && $.effects[ effectName ] ) ) {
+                       element[ method ]( options );
+               } else if ( effectName !== method && element[ effectName ] ) {
+                       element[ effectName ]( options.duration, options.easing, callback );
+               } else {
+                       element.queue(function( next ) {
+                               $( this )[ method ]();
+                               if ( callback ) {
+                                       callback.call( element[ 0 ] );
+                               }
+                               next();
+                       });
+               }
+       };
+});
+
+// DEPRECATED
+if ( $.uiBackCompat !== false ) {
+       $.Widget.prototype._getCreateOptions = function() {
+               return $.metadata && $.metadata.get( this.element[0] )[ this.widgetName ];
+       };
+}
+
 })( jQuery );