1825 lines
		
	
	
		
			51 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
		
			Vendored
		
	
	
	
			
		
		
	
	
			1825 lines
		
	
	
		
			51 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
		
			Vendored
		
	
	
	
| /*! jQuery UI - v1.11.4 - 2015-12-30
 | |
| * http://jqueryui.com
 | |
| * Includes: core.js, widget.js, position.js, tooltip.js
 | |
| * Copyright jQuery Foundation and other contributors; Licensed MIT */
 | |
| 
 | |
| (function( factory ) {
 | |
| 	if ( typeof define === "function" && define.amd ) {
 | |
| 
 | |
| 		// AMD. Register as an anonymous module.
 | |
| 		define([ "jquery" ], factory );
 | |
| 	} else {
 | |
| 
 | |
| 		// Browser globals
 | |
| 		factory( jQuery );
 | |
| 	}
 | |
| }(function( $ ) {
 | |
| /*!
 | |
|  * jQuery UI Core 1.11.4
 | |
|  * http://jqueryui.com
 | |
|  *
 | |
|  * Copyright jQuery Foundation and other contributors
 | |
|  * Released under the MIT license.
 | |
|  * http://jquery.org/license
 | |
|  *
 | |
|  * http://api.jqueryui.com/category/ui-core/
 | |
|  */
 | |
| 
 | |
| 
 | |
| // $.ui might exist from components with no dependencies, e.g., $.ui.position
 | |
| $.ui = $.ui || {};
 | |
| 
 | |
| $.extend( $.ui, {
 | |
| 	version: "1.11.4",
 | |
| 
 | |
| 	keyCode: {
 | |
| 		BACKSPACE: 8,
 | |
| 		COMMA: 188,
 | |
| 		DELETE: 46,
 | |
| 		DOWN: 40,
 | |
| 		END: 35,
 | |
| 		ENTER: 13,
 | |
| 		ESCAPE: 27,
 | |
| 		HOME: 36,
 | |
| 		LEFT: 37,
 | |
| 		PAGE_DOWN: 34,
 | |
| 		PAGE_UP: 33,
 | |
| 		PERIOD: 190,
 | |
| 		RIGHT: 39,
 | |
| 		SPACE: 32,
 | |
| 		TAB: 9,
 | |
| 		UP: 38
 | |
| 	}
 | |
| });
 | |
| 
 | |
| // plugins
 | |
| $.fn.extend({
 | |
| 	scrollParent: function( includeHidden ) {
 | |
| 		var position = this.css( "position" ),
 | |
| 			excludeStaticParent = position === "absolute",
 | |
| 			overflowRegex = includeHidden ? /(auto|scroll|hidden)/ : /(auto|scroll)/,
 | |
| 			scrollParent = this.parents().filter( function() {
 | |
| 				var parent = $( this );
 | |
| 				if ( excludeStaticParent && parent.css( "position" ) === "static" ) {
 | |
| 					return false;
 | |
| 				}
 | |
| 				return overflowRegex.test( parent.css( "overflow" ) + parent.css( "overflow-y" ) + parent.css( "overflow-x" ) );
 | |
| 			}).eq( 0 );
 | |
| 
 | |
| 		return position === "fixed" || !scrollParent.length ? $( this[ 0 ].ownerDocument || document ) : scrollParent;
 | |
| 	},
 | |
| 
 | |
| 	uniqueId: (function() {
 | |
| 		var uuid = 0;
 | |
| 
 | |
| 		return function() {
 | |
| 			return this.each(function() {
 | |
| 				if ( !this.id ) {
 | |
| 					this.id = "ui-id-" + ( ++uuid );
 | |
| 				}
 | |
| 			});
 | |
| 		};
 | |
| 	})(),
 | |
| 
 | |
| 	removeUniqueId: function() {
 | |
| 		return this.each(function() {
 | |
| 			if ( /^ui-id-\d+$/.test( this.id ) ) {
 | |
| 				$( this ).removeAttr( "id" );
 | |
| 			}
 | |
| 		});
 | |
| 	}
 | |
| });
 | |
| 
 | |
| // selectors
 | |
| function focusable( element, isTabIndexNotNaN ) {
 | |
| 	var map, mapName, img,
 | |
| 		nodeName = element.nodeName.toLowerCase();
 | |
| 	if ( "area" === nodeName ) {
 | |
| 		map = element.parentNode;
 | |
| 		mapName = map.name;
 | |
| 		if ( !element.href || !mapName || map.nodeName.toLowerCase() !== "map" ) {
 | |
| 			return false;
 | |
| 		}
 | |
| 		img = $( "img[usemap='#" + mapName + "']" )[ 0 ];
 | |
| 		return !!img && visible( img );
 | |
| 	}
 | |
| 	return ( /^(input|select|textarea|button|object)$/.test( nodeName ) ?
 | |
| 		!element.disabled :
 | |
| 		"a" === nodeName ?
 | |
| 			element.href || isTabIndexNotNaN :
 | |
| 			isTabIndexNotNaN) &&
 | |
| 		// the element and all of its ancestors must be visible
 | |
| 		visible( element );
 | |
| }
 | |
| 
 | |
| function visible( element ) {
 | |
| 	return $.expr.filters.visible( element ) &&
 | |
| 		!$( element ).parents().addBack().filter(function() {
 | |
| 			return $.css( this, "visibility" ) === "hidden";
 | |
| 		}).length;
 | |
| }
 | |
| 
 | |
| $.extend( $.expr[ ":" ], {
 | |
| 	data: $.expr.createPseudo ?
 | |
| 		$.expr.createPseudo(function( dataName ) {
 | |
| 			return function( elem ) {
 | |
| 				return !!$.data( elem, dataName );
 | |
| 			};
 | |
| 		}) :
 | |
| 		// support: jQuery <1.8
 | |
| 		function( elem, i, match ) {
 | |
| 			return !!$.data( elem, match[ 3 ] );
 | |
| 		},
 | |
| 
 | |
| 	focusable: function( element ) {
 | |
| 		return focusable( element, !isNaN( $.attr( element, "tabindex" ) ) );
 | |
| 	},
 | |
| 
 | |
| 	tabbable: function( element ) {
 | |
| 		var tabIndex = $.attr( element, "tabindex" ),
 | |
| 			isTabIndexNaN = isNaN( tabIndex );
 | |
| 		return ( isTabIndexNaN || tabIndex >= 0 ) && focusable( element, !isTabIndexNaN );
 | |
| 	}
 | |
| });
 | |
| 
 | |
| // support: jQuery <1.8
 | |
| if ( !$( "<a>" ).outerWidth( 1 ).jquery ) {
 | |
| 	$.each( [ "Width", "Height" ], function( i, name ) {
 | |
| 		var side = name === "Width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ],
 | |
| 			type = name.toLowerCase(),
 | |
| 			orig = {
 | |
| 				innerWidth: $.fn.innerWidth,
 | |
| 				innerHeight: $.fn.innerHeight,
 | |
| 				outerWidth: $.fn.outerWidth,
 | |
| 				outerHeight: $.fn.outerHeight
 | |
| 			};
 | |
| 
 | |
| 		function reduce( elem, size, border, margin ) {
 | |
| 			$.each( side, function() {
 | |
| 				size -= parseFloat( $.css( elem, "padding" + this ) ) || 0;
 | |
| 				if ( border ) {
 | |
| 					size -= parseFloat( $.css( elem, "border" + this + "Width" ) ) || 0;
 | |
| 				}
 | |
| 				if ( margin ) {
 | |
| 					size -= parseFloat( $.css( elem, "margin" + this ) ) || 0;
 | |
| 				}
 | |
| 			});
 | |
| 			return size;
 | |
| 		}
 | |
| 
 | |
| 		$.fn[ "inner" + name ] = function( size ) {
 | |
| 			if ( size === undefined ) {
 | |
| 				return orig[ "inner" + name ].call( this );
 | |
| 			}
 | |
| 
 | |
| 			return this.each(function() {
 | |
| 				$( this ).css( type, reduce( this, size ) + "px" );
 | |
| 			});
 | |
| 		};
 | |
| 
 | |
| 		$.fn[ "outer" + name] = function( size, margin ) {
 | |
| 			if ( typeof size !== "number" ) {
 | |
| 				return orig[ "outer" + name ].call( this, size );
 | |
| 			}
 | |
| 
 | |
| 			return this.each(function() {
 | |
| 				$( this).css( type, reduce( this, size, true, margin ) + "px" );
 | |
| 			});
 | |
| 		};
 | |
| 	});
 | |
| }
 | |
| 
 | |
| // support: jQuery <1.8
 | |
| if ( !$.fn.addBack ) {
 | |
| 	$.fn.addBack = function( selector ) {
 | |
| 		return this.add( selector == null ?
 | |
| 			this.prevObject : this.prevObject.filter( selector )
 | |
| 		);
 | |
| 	};
 | |
| }
 | |
| 
 | |
| // support: jQuery 1.6.1, 1.6.2 (http://bugs.jquery.com/ticket/9413)
 | |
| if ( $( "<a>" ).data( "a-b", "a" ).removeData( "a-b" ).data( "a-b" ) ) {
 | |
| 	$.fn.removeData = (function( removeData ) {
 | |
| 		return function( key ) {
 | |
| 			if ( arguments.length ) {
 | |
| 				return removeData.call( this, $.camelCase( key ) );
 | |
| 			} else {
 | |
| 				return removeData.call( this );
 | |
| 			}
 | |
| 		};
 | |
| 	})( $.fn.removeData );
 | |
| }
 | |
| 
 | |
| // deprecated
 | |
| $.ui.ie = !!/msie [\w.]+/.exec( navigator.userAgent.toLowerCase() );
 | |
| 
 | |
| $.fn.extend({
 | |
| 	focus: (function( orig ) {
 | |
| 		return function( delay, fn ) {
 | |
| 			return typeof delay === "number" ?
 | |
| 				this.each(function() {
 | |
| 					var elem = this;
 | |
| 					setTimeout(function() {
 | |
| 						$( elem ).focus();
 | |
| 						if ( fn ) {
 | |
| 							fn.call( elem );
 | |
| 						}
 | |
| 					}, delay );
 | |
| 				}) :
 | |
| 				orig.apply( this, arguments );
 | |
| 		};
 | |
| 	})( $.fn.focus ),
 | |
| 
 | |
| 	disableSelection: (function() {
 | |
| 		var eventType = "onselectstart" in document.createElement( "div" ) ?
 | |
| 			"selectstart" :
 | |
| 			"mousedown";
 | |
| 
 | |
| 		return function() {
 | |
| 			return this.bind( eventType + ".ui-disableSelection", function( event ) {
 | |
| 				event.preventDefault();
 | |
| 			});
 | |
| 		};
 | |
| 	})(),
 | |
| 
 | |
| 	enableSelection: function() {
 | |
| 		return this.unbind( ".ui-disableSelection" );
 | |
| 	},
 | |
| 
 | |
| 	zIndex: function( zIndex ) {
 | |
| 		if ( zIndex !== undefined ) {
 | |
| 			return this.css( "zIndex", zIndex );
 | |
| 		}
 | |
| 
 | |
| 		if ( this.length ) {
 | |
| 			var elem = $( this[ 0 ] ), position, value;
 | |
| 			while ( elem.length && elem[ 0 ] !== document ) {
 | |
| 				// Ignore z-index if position is set to a value where z-index is ignored by the browser
 | |
| 				// This makes behavior of this function consistent across browsers
 | |
| 				// WebKit always returns auto if the element is positioned
 | |
| 				position = elem.css( "position" );
 | |
| 				if ( position === "absolute" || position === "relative" || position === "fixed" ) {
 | |
| 					// IE returns 0 when zIndex is not specified
 | |
| 					// other browsers return a string
 | |
| 					// we ignore the case of nested elements with an explicit value of 0
 | |
| 					// <div style="z-index: -10;"><div style="z-index: 0;"></div></div>
 | |
| 					value = parseInt( elem.css( "zIndex" ), 10 );
 | |
| 					if ( !isNaN( value ) && value !== 0 ) {
 | |
| 						return value;
 | |
| 					}
 | |
| 				}
 | |
| 				elem = elem.parent();
 | |
| 			}
 | |
| 		}
 | |
| 
 | |
| 		return 0;
 | |
| 	}
 | |
| });
 | |
| 
 | |
| // $.ui.plugin is deprecated. Use $.widget() extensions instead.
 | |
| $.ui.plugin = {
 | |
| 	add: function( module, option, set ) {
 | |
| 		var i,
 | |
| 			proto = $.ui[ module ].prototype;
 | |
| 		for ( i in set ) {
 | |
| 			proto.plugins[ i ] = proto.plugins[ i ] || [];
 | |
| 			proto.plugins[ i ].push( [ option, set[ i ] ] );
 | |
| 		}
 | |
| 	},
 | |
| 	call: function( instance, name, args, allowDisconnected ) {
 | |
| 		var i,
 | |
| 			set = instance.plugins[ name ];
 | |
| 
 | |
| 		if ( !set ) {
 | |
| 			return;
 | |
| 		}
 | |
| 
 | |
| 		if ( !allowDisconnected && ( !instance.element[ 0 ].parentNode || instance.element[ 0 ].parentNode.nodeType === 11 ) ) {
 | |
| 			return;
 | |
| 		}
 | |
| 
 | |
| 		for ( i = 0; i < set.length; i++ ) {
 | |
| 			if ( instance.options[ set[ i ][ 0 ] ] ) {
 | |
| 				set[ i ][ 1 ].apply( instance.element, args );
 | |
| 			}
 | |
| 		}
 | |
| 	}
 | |
| };
 | |
| 
 | |
| 
 | |
| /*!
 | |
|  * jQuery UI Widget 1.11.4
 | |
|  * http://jqueryui.com
 | |
|  *
 | |
|  * Copyright jQuery Foundation and other contributors
 | |
|  * Released under the MIT license.
 | |
|  * http://jquery.org/license
 | |
|  *
 | |
|  * http://api.jqueryui.com/jQuery.widget/
 | |
|  */
 | |
| 
 | |
| 
 | |
| var widget_uuid = 0,
 | |
| 	widget_slice = Array.prototype.slice;
 | |
| 
 | |
| $.cleanData = (function( orig ) {
 | |
| 	return function( elems ) {
 | |
| 		var events, elem, i;
 | |
| 		for ( i = 0; (elem = elems[i]) != null; i++ ) {
 | |
| 			try {
 | |
| 
 | |
| 				// Only trigger remove when necessary to save time
 | |
| 				events = $._data( elem, "events" );
 | |
| 				if ( events && events.remove ) {
 | |
| 					$( elem ).triggerHandler( "remove" );
 | |
| 				}
 | |
| 
 | |
| 			// http://bugs.jquery.com/ticket/8235
 | |
| 			} catch ( e ) {}
 | |
| 		}
 | |
| 		orig( elems );
 | |
| 	};
 | |
| })( $.cleanData );
 | |
| 
 | |
| $.widget = function( name, base, prototype ) {
 | |
| 	var fullName, existingConstructor, constructor, basePrototype,
 | |
| 		// proxiedPrototype allows the provided prototype to remain unmodified
 | |
| 		// so that it can be used as a mixin for multiple widgets (#8876)
 | |
| 		proxiedPrototype = {},
 | |
| 		namespace = name.split( "." )[ 0 ];
 | |
| 
 | |
| 	name = name.split( "." )[ 1 ];
 | |
| 	fullName = namespace + "-" + name;
 | |
| 
 | |
| 	if ( !prototype ) {
 | |
| 		prototype = base;
 | |
| 		base = $.Widget;
 | |
| 	}
 | |
| 
 | |
| 	// create selector for plugin
 | |
| 	$.expr[ ":" ][ fullName.toLowerCase() ] = function( elem ) {
 | |
| 		return !!$.data( elem, fullName );
 | |
| 	};
 | |
| 
 | |
| 	$[ namespace ] = $[ namespace ] || {};
 | |
| 	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 );
 | |
| 		}
 | |
| 	};
 | |
| 	// 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
 | |
| 	basePrototype.options = $.widget.extend( {}, basePrototype.options );
 | |
| 	$.each( prototype, function( prop, value ) {
 | |
| 		if ( !$.isFunction( value ) ) {
 | |
| 			proxiedPrototype[ prop ] = value;
 | |
| 			return;
 | |
| 		}
 | |
| 		proxiedPrototype[ 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) : name
 | |
| 	}, proxiedPrototype, {
 | |
| 		constructor: constructor,
 | |
| 		namespace: namespace,
 | |
| 		widgetName: name,
 | |
| 		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, constructor );
 | |
| 
 | |
| 	return constructor;
 | |
| };
 | |
| 
 | |
| $.widget.extend = function( target ) {
 | |
| 	var input = widget_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 = widget_slice.call( arguments, 1 ),
 | |
| 			returnValue = this;
 | |
| 
 | |
| 		if ( isMethodCall ) {
 | |
| 			this.each(function() {
 | |
| 				var methodValue,
 | |
| 					instance = $.data( this, fullName );
 | |
| 				if ( options === "instance" ) {
 | |
| 					returnValue = instance;
 | |
| 					return false;
 | |
| 				}
 | |
| 				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 && methodValue.jquery ?
 | |
| 						returnValue.pushStack( methodValue.get() ) :
 | |
| 						methodValue;
 | |
| 					return false;
 | |
| 				}
 | |
| 			});
 | |
| 		} else {
 | |
| 
 | |
| 			// Allow multiple hashes to be passed on init
 | |
| 			if ( args.length ) {
 | |
| 				options = $.widget.extend.apply( null, [ options ].concat(args) );
 | |
| 			}
 | |
| 
 | |
| 			this.each(function() {
 | |
| 				var instance = $.data( this, fullName );
 | |
| 				if ( instance ) {
 | |
| 					instance.option( options || {} );
 | |
| 					if ( instance._init ) {
 | |
| 						instance._init();
 | |
| 					}
 | |
| 				} else {
 | |
| 					$.data( this, fullName, new object( options, this ) );
 | |
| 				}
 | |
| 			});
 | |
| 		}
 | |
| 
 | |
| 		return returnValue;
 | |
| 	};
 | |
| };
 | |
| 
 | |
| $.Widget = function( /* options, element */ ) {};
 | |
| $.Widget._childConstructors = [];
 | |
| 
 | |
| $.Widget.prototype = {
 | |
| 	widgetName: "widget",
 | |
| 	widgetEventPrefix: "",
 | |
| 	defaultElement: "<div>",
 | |
| 	options: {
 | |
| 		disabled: false,
 | |
| 
 | |
| 		// callbacks
 | |
| 		create: null
 | |
| 	},
 | |
| 	_createWidget: function( options, element ) {
 | |
| 		element = $( element || this.defaultElement || this )[ 0 ];
 | |
| 		this.element = $( element );
 | |
| 		this.uuid = widget_uuid++;
 | |
| 		this.eventNamespace = "." + this.widgetName + this.uuid;
 | |
| 
 | |
| 		this.bindings = $();
 | |
| 		this.hoverable = $();
 | |
| 		this.focusable = $();
 | |
| 
 | |
| 		if ( element !== 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.options = $.widget.extend( {},
 | |
| 			this.options,
 | |
| 			this._getCreateOptions(),
 | |
| 			options );
 | |
| 
 | |
| 		this._create();
 | |
| 		this._trigger( "create", null, this._getCreateEventData() );
 | |
| 		this._init();
 | |
| 	},
 | |
| 	_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.eventNamespace )
 | |
| 			.removeData( this.widgetFullName )
 | |
| 			// support: jquery <1.6.3
 | |
| 			// http://bugs.jquery.com/ticket/9413
 | |
| 			.removeData( $.camelCase( this.widgetFullName ) );
 | |
| 		this.widget()
 | |
| 			.unbind( this.eventNamespace )
 | |
| 			.removeAttr( "aria-disabled" )
 | |
| 			.removeClass(
 | |
| 				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,
 | |
| 			parts,
 | |
| 			curOption,
 | |
| 			i;
 | |
| 
 | |
| 		if ( arguments.length === 0 ) {
 | |
| 			// don't return a reference to the internal hash
 | |
| 			return $.widget.extend( {}, this.options );
 | |
| 		}
 | |
| 
 | |
| 		if ( typeof key === "string" ) {
 | |
| 			// handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } }
 | |
| 			options = {};
 | |
| 			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 ( arguments.length === 1 ) {
 | |
| 					return curOption[ key ] === undefined ? null : curOption[ key ];
 | |
| 				}
 | |
| 				curOption[ key ] = value;
 | |
| 			} else {
 | |
| 				if ( arguments.length === 1 ) {
 | |
| 					return this.options[ key ] === undefined ? null : this.options[ key ];
 | |
| 				}
 | |
| 				options[ key ] = value;
 | |
| 			}
 | |
| 		}
 | |
| 
 | |
| 		this._setOptions( options );
 | |
| 
 | |
| 		return this;
 | |
| 	},
 | |
| 	_setOptions: function( options ) {
 | |
| 		var key;
 | |
| 
 | |
| 		for ( key in options ) {
 | |
| 			this._setOption( key, options[ key ] );
 | |
| 		}
 | |
| 
 | |
| 		return this;
 | |
| 	},
 | |
| 	_setOption: function( key, value ) {
 | |
| 		this.options[ key ] = value;
 | |
| 
 | |
| 		if ( key === "disabled" ) {
 | |
| 			this.widget()
 | |
| 				.toggleClass( this.widgetFullName + "-disabled", !!value );
 | |
| 
 | |
| 			// If the widget is becoming disabled, then nothing is interactive
 | |
| 			if ( value ) {
 | |
| 				this.hoverable.removeClass( "ui-state-hover" );
 | |
| 				this.focusable.removeClass( "ui-state-focus" );
 | |
| 			}
 | |
| 		}
 | |
| 
 | |
| 		return this;
 | |
| 	},
 | |
| 
 | |
| 	enable: function() {
 | |
| 		return this._setOptions({ disabled: false });
 | |
| 	},
 | |
| 	disable: function() {
 | |
| 		return this._setOptions({ 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 {
 | |
| 			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 );
 | |
| 
 | |
| 		// Clear the stack to avoid memory leaks (#10056)
 | |
| 		this.bindings = $( this.bindings.not( element ).get() );
 | |
| 		this.focusable = $( this.focusable.not( element ).get() );
 | |
| 		this.hoverable = $( this.hoverable.not( element ).get() );
 | |
| 	},
 | |
| 
 | |
| 	_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 ];
 | |
| 
 | |
| 		data = data || {};
 | |
| 		event = $.Event( event );
 | |
| 		event.type = ( type === this.widgetEventPrefix ?
 | |
| 			type :
 | |
| 			this.widgetEventPrefix + type ).toLowerCase();
 | |
| 		// the original event may come from any element
 | |
| 		// so we need to reset the target on the new event
 | |
| 		event.target = this.element[ 0 ];
 | |
| 
 | |
| 		// copy original event properties over to the new event
 | |
| 		orig = event.originalEvent;
 | |
| 		if ( orig ) {
 | |
| 			for ( prop in orig ) {
 | |
| 				if ( !( prop in event ) ) {
 | |
| 					event[ prop ] = orig[ prop ];
 | |
| 				}
 | |
| 			}
 | |
| 		}
 | |
| 
 | |
| 		this.element.trigger( event, data );
 | |
| 		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 ] ) {
 | |
| 			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();
 | |
| 			});
 | |
| 		}
 | |
| 	};
 | |
| });
 | |
| 
 | |
| var widget = $.widget;
 | |
| 
 | |
| 
 | |
| /*!
 | |
|  * jQuery UI Position 1.11.4
 | |
|  * http://jqueryui.com
 | |
|  *
 | |
|  * Copyright jQuery Foundation and other contributors
 | |
|  * Released under the MIT license.
 | |
|  * http://jquery.org/license
 | |
|  *
 | |
|  * http://api.jqueryui.com/position/
 | |
|  */
 | |
| 
 | |
| (function() {
 | |
| 
 | |
| $.ui = $.ui || {};
 | |
| 
 | |
| var cachedScrollbarWidth, supportsOffsetFractions,
 | |
| 	max = Math.max,
 | |
| 	abs = Math.abs,
 | |
| 	round = Math.round,
 | |
| 	rhorizontal = /left|center|right/,
 | |
| 	rvertical = /top|center|bottom/,
 | |
| 	roffset = /[\+\-]\d+(\.[\d]+)?%?/,
 | |
| 	rposition = /^\w+/,
 | |
| 	rpercent = /%$/,
 | |
| 	_position = $.fn.position;
 | |
| 
 | |
| function getOffsets( offsets, width, height ) {
 | |
| 	return [
 | |
| 		parseFloat( offsets[ 0 ] ) * ( rpercent.test( offsets[ 0 ] ) ? width / 100 : 1 ),
 | |
| 		parseFloat( offsets[ 1 ] ) * ( rpercent.test( offsets[ 1 ] ) ? height / 100 : 1 )
 | |
| 	];
 | |
| }
 | |
| 
 | |
| function parseCss( element, property ) {
 | |
| 	return parseInt( $.css( element, property ), 10 ) || 0;
 | |
| }
 | |
| 
 | |
| function getDimensions( elem ) {
 | |
| 	var raw = elem[0];
 | |
| 	if ( raw.nodeType === 9 ) {
 | |
| 		return {
 | |
| 			width: elem.width(),
 | |
| 			height: elem.height(),
 | |
| 			offset: { top: 0, left: 0 }
 | |
| 		};
 | |
| 	}
 | |
| 	if ( $.isWindow( raw ) ) {
 | |
| 		return {
 | |
| 			width: elem.width(),
 | |
| 			height: elem.height(),
 | |
| 			offset: { top: elem.scrollTop(), left: elem.scrollLeft() }
 | |
| 		};
 | |
| 	}
 | |
| 	if ( raw.preventDefault ) {
 | |
| 		return {
 | |
| 			width: 0,
 | |
| 			height: 0,
 | |
| 			offset: { top: raw.pageY, left: raw.pageX }
 | |
| 		};
 | |
| 	}
 | |
| 	return {
 | |
| 		width: elem.outerWidth(),
 | |
| 		height: elem.outerHeight(),
 | |
| 		offset: elem.offset()
 | |
| 	};
 | |
| }
 | |
| 
 | |
| $.position = {
 | |
| 	scrollbarWidth: function() {
 | |
| 		if ( cachedScrollbarWidth !== undefined ) {
 | |
| 			return cachedScrollbarWidth;
 | |
| 		}
 | |
| 		var w1, w2,
 | |
| 			div = $( "<div style='display:block;position:absolute;width:50px;height:50px;overflow:hidden;'><div style='height:100px;width:auto;'></div></div>" ),
 | |
| 			innerDiv = div.children()[0];
 | |
| 
 | |
| 		$( "body" ).append( div );
 | |
| 		w1 = innerDiv.offsetWidth;
 | |
| 		div.css( "overflow", "scroll" );
 | |
| 
 | |
| 		w2 = innerDiv.offsetWidth;
 | |
| 
 | |
| 		if ( w1 === w2 ) {
 | |
| 			w2 = div[0].clientWidth;
 | |
| 		}
 | |
| 
 | |
| 		div.remove();
 | |
| 
 | |
| 		return (cachedScrollbarWidth = w1 - w2);
 | |
| 	},
 | |
| 	getScrollInfo: function( within ) {
 | |
| 		var overflowX = within.isWindow || within.isDocument ? "" :
 | |
| 				within.element.css( "overflow-x" ),
 | |
| 			overflowY = within.isWindow || within.isDocument ? "" :
 | |
| 				within.element.css( "overflow-y" ),
 | |
| 			hasOverflowX = overflowX === "scroll" ||
 | |
| 				( overflowX === "auto" && within.width < within.element[0].scrollWidth ),
 | |
| 			hasOverflowY = overflowY === "scroll" ||
 | |
| 				( overflowY === "auto" && within.height < within.element[0].scrollHeight );
 | |
| 		return {
 | |
| 			width: hasOverflowY ? $.position.scrollbarWidth() : 0,
 | |
| 			height: hasOverflowX ? $.position.scrollbarWidth() : 0
 | |
| 		};
 | |
| 	},
 | |
| 	getWithinInfo: function( element ) {
 | |
| 		var withinElement = $( element || window ),
 | |
| 			isWindow = $.isWindow( withinElement[0] ),
 | |
| 			isDocument = !!withinElement[ 0 ] && withinElement[ 0 ].nodeType === 9;
 | |
| 		return {
 | |
| 			element: withinElement,
 | |
| 			isWindow: isWindow,
 | |
| 			isDocument: isDocument,
 | |
| 			offset: withinElement.offset() || { left: 0, top: 0 },
 | |
| 			scrollLeft: withinElement.scrollLeft(),
 | |
| 			scrollTop: withinElement.scrollTop(),
 | |
| 
 | |
| 			// support: jQuery 1.6.x
 | |
| 			// jQuery 1.6 doesn't support .outerWidth/Height() on documents or windows
 | |
| 			width: isWindow || isDocument ? withinElement.width() : withinElement.outerWidth(),
 | |
| 			height: isWindow || isDocument ? withinElement.height() : withinElement.outerHeight()
 | |
| 		};
 | |
| 	}
 | |
| };
 | |
| 
 | |
| $.fn.position = function( options ) {
 | |
| 	if ( !options || !options.of ) {
 | |
| 		return _position.apply( this, arguments );
 | |
| 	}
 | |
| 
 | |
| 	// make a copy, we don't want to modify arguments
 | |
| 	options = $.extend( {}, options );
 | |
| 
 | |
| 	var atOffset, targetWidth, targetHeight, targetOffset, basePosition, dimensions,
 | |
| 		target = $( options.of ),
 | |
| 		within = $.position.getWithinInfo( options.within ),
 | |
| 		scrollInfo = $.position.getScrollInfo( within ),
 | |
| 		collision = ( options.collision || "flip" ).split( " " ),
 | |
| 		offsets = {};
 | |
| 
 | |
| 	dimensions = getDimensions( target );
 | |
| 	if ( target[0].preventDefault ) {
 | |
| 		// force left top to allow flipping
 | |
| 		options.at = "left top";
 | |
| 	}
 | |
| 	targetWidth = dimensions.width;
 | |
| 	targetHeight = dimensions.height;
 | |
| 	targetOffset = dimensions.offset;
 | |
| 	// clone to reuse original targetOffset later
 | |
| 	basePosition = $.extend( {}, targetOffset );
 | |
| 
 | |
| 	// force my and at to have valid horizontal and vertical positions
 | |
| 	// if a value is missing or invalid, it will be converted to center
 | |
| 	$.each( [ "my", "at" ], function() {
 | |
| 		var pos = ( options[ this ] || "" ).split( " " ),
 | |
| 			horizontalOffset,
 | |
| 			verticalOffset;
 | |
| 
 | |
| 		if ( pos.length === 1) {
 | |
| 			pos = rhorizontal.test( pos[ 0 ] ) ?
 | |
| 				pos.concat( [ "center" ] ) :
 | |
| 				rvertical.test( pos[ 0 ] ) ?
 | |
| 					[ "center" ].concat( pos ) :
 | |
| 					[ "center", "center" ];
 | |
| 		}
 | |
| 		pos[ 0 ] = rhorizontal.test( pos[ 0 ] ) ? pos[ 0 ] : "center";
 | |
| 		pos[ 1 ] = rvertical.test( pos[ 1 ] ) ? pos[ 1 ] : "center";
 | |
| 
 | |
| 		// calculate offsets
 | |
| 		horizontalOffset = roffset.exec( pos[ 0 ] );
 | |
| 		verticalOffset = roffset.exec( pos[ 1 ] );
 | |
| 		offsets[ this ] = [
 | |
| 			horizontalOffset ? horizontalOffset[ 0 ] : 0,
 | |
| 			verticalOffset ? verticalOffset[ 0 ] : 0
 | |
| 		];
 | |
| 
 | |
| 		// reduce to just the positions without the offsets
 | |
| 		options[ this ] = [
 | |
| 			rposition.exec( pos[ 0 ] )[ 0 ],
 | |
| 			rposition.exec( pos[ 1 ] )[ 0 ]
 | |
| 		];
 | |
| 	});
 | |
| 
 | |
| 	// normalize collision option
 | |
| 	if ( collision.length === 1 ) {
 | |
| 		collision[ 1 ] = collision[ 0 ];
 | |
| 	}
 | |
| 
 | |
| 	if ( options.at[ 0 ] === "right" ) {
 | |
| 		basePosition.left += targetWidth;
 | |
| 	} else if ( options.at[ 0 ] === "center" ) {
 | |
| 		basePosition.left += targetWidth / 2;
 | |
| 	}
 | |
| 
 | |
| 	if ( options.at[ 1 ] === "bottom" ) {
 | |
| 		basePosition.top += targetHeight;
 | |
| 	} else if ( options.at[ 1 ] === "center" ) {
 | |
| 		basePosition.top += targetHeight / 2;
 | |
| 	}
 | |
| 
 | |
| 	atOffset = getOffsets( offsets.at, targetWidth, targetHeight );
 | |
| 	basePosition.left += atOffset[ 0 ];
 | |
| 	basePosition.top += atOffset[ 1 ];
 | |
| 
 | |
| 	return this.each(function() {
 | |
| 		var collisionPosition, using,
 | |
| 			elem = $( this ),
 | |
| 			elemWidth = elem.outerWidth(),
 | |
| 			elemHeight = elem.outerHeight(),
 | |
| 			marginLeft = parseCss( this, "marginLeft" ),
 | |
| 			marginTop = parseCss( this, "marginTop" ),
 | |
| 			collisionWidth = elemWidth + marginLeft + parseCss( this, "marginRight" ) + scrollInfo.width,
 | |
| 			collisionHeight = elemHeight + marginTop + parseCss( this, "marginBottom" ) + scrollInfo.height,
 | |
| 			position = $.extend( {}, basePosition ),
 | |
| 			myOffset = getOffsets( offsets.my, elem.outerWidth(), elem.outerHeight() );
 | |
| 
 | |
| 		if ( options.my[ 0 ] === "right" ) {
 | |
| 			position.left -= elemWidth;
 | |
| 		} else if ( options.my[ 0 ] === "center" ) {
 | |
| 			position.left -= elemWidth / 2;
 | |
| 		}
 | |
| 
 | |
| 		if ( options.my[ 1 ] === "bottom" ) {
 | |
| 			position.top -= elemHeight;
 | |
| 		} else if ( options.my[ 1 ] === "center" ) {
 | |
| 			position.top -= elemHeight / 2;
 | |
| 		}
 | |
| 
 | |
| 		position.left += myOffset[ 0 ];
 | |
| 		position.top += myOffset[ 1 ];
 | |
| 
 | |
| 		// if the browser doesn't support fractions, then round for consistent results
 | |
| 		if ( !supportsOffsetFractions ) {
 | |
| 			position.left = round( position.left );
 | |
| 			position.top = round( position.top );
 | |
| 		}
 | |
| 
 | |
| 		collisionPosition = {
 | |
| 			marginLeft: marginLeft,
 | |
| 			marginTop: marginTop
 | |
| 		};
 | |
| 
 | |
| 		$.each( [ "left", "top" ], function( i, dir ) {
 | |
| 			if ( $.ui.position[ collision[ i ] ] ) {
 | |
| 				$.ui.position[ collision[ i ] ][ dir ]( position, {
 | |
| 					targetWidth: targetWidth,
 | |
| 					targetHeight: targetHeight,
 | |
| 					elemWidth: elemWidth,
 | |
| 					elemHeight: elemHeight,
 | |
| 					collisionPosition: collisionPosition,
 | |
| 					collisionWidth: collisionWidth,
 | |
| 					collisionHeight: collisionHeight,
 | |
| 					offset: [ atOffset[ 0 ] + myOffset[ 0 ], atOffset [ 1 ] + myOffset[ 1 ] ],
 | |
| 					my: options.my,
 | |
| 					at: options.at,
 | |
| 					within: within,
 | |
| 					elem: elem
 | |
| 				});
 | |
| 			}
 | |
| 		});
 | |
| 
 | |
| 		if ( options.using ) {
 | |
| 			// adds feedback as second argument to using callback, if present
 | |
| 			using = function( props ) {
 | |
| 				var left = targetOffset.left - position.left,
 | |
| 					right = left + targetWidth - elemWidth,
 | |
| 					top = targetOffset.top - position.top,
 | |
| 					bottom = top + targetHeight - elemHeight,
 | |
| 					feedback = {
 | |
| 						target: {
 | |
| 							element: target,
 | |
| 							left: targetOffset.left,
 | |
| 							top: targetOffset.top,
 | |
| 							width: targetWidth,
 | |
| 							height: targetHeight
 | |
| 						},
 | |
| 						element: {
 | |
| 							element: elem,
 | |
| 							left: position.left,
 | |
| 							top: position.top,
 | |
| 							width: elemWidth,
 | |
| 							height: elemHeight
 | |
| 						},
 | |
| 						horizontal: right < 0 ? "left" : left > 0 ? "right" : "center",
 | |
| 						vertical: bottom < 0 ? "top" : top > 0 ? "bottom" : "middle"
 | |
| 					};
 | |
| 				if ( targetWidth < elemWidth && abs( left + right ) < targetWidth ) {
 | |
| 					feedback.horizontal = "center";
 | |
| 				}
 | |
| 				if ( targetHeight < elemHeight && abs( top + bottom ) < targetHeight ) {
 | |
| 					feedback.vertical = "middle";
 | |
| 				}
 | |
| 				if ( max( abs( left ), abs( right ) ) > max( abs( top ), abs( bottom ) ) ) {
 | |
| 					feedback.important = "horizontal";
 | |
| 				} else {
 | |
| 					feedback.important = "vertical";
 | |
| 				}
 | |
| 				options.using.call( this, props, feedback );
 | |
| 			};
 | |
| 		}
 | |
| 
 | |
| 		elem.offset( $.extend( position, { using: using } ) );
 | |
| 	});
 | |
| };
 | |
| 
 | |
| $.ui.position = {
 | |
| 	fit: {
 | |
| 		left: function( position, data ) {
 | |
| 			var within = data.within,
 | |
| 				withinOffset = within.isWindow ? within.scrollLeft : within.offset.left,
 | |
| 				outerWidth = within.width,
 | |
| 				collisionPosLeft = position.left - data.collisionPosition.marginLeft,
 | |
| 				overLeft = withinOffset - collisionPosLeft,
 | |
| 				overRight = collisionPosLeft + data.collisionWidth - outerWidth - withinOffset,
 | |
| 				newOverRight;
 | |
| 
 | |
| 			// element is wider than within
 | |
| 			if ( data.collisionWidth > outerWidth ) {
 | |
| 				// element is initially over the left side of within
 | |
| 				if ( overLeft > 0 && overRight <= 0 ) {
 | |
| 					newOverRight = position.left + overLeft + data.collisionWidth - outerWidth - withinOffset;
 | |
| 					position.left += overLeft - newOverRight;
 | |
| 				// element is initially over right side of within
 | |
| 				} else if ( overRight > 0 && overLeft <= 0 ) {
 | |
| 					position.left = withinOffset;
 | |
| 				// element is initially over both left and right sides of within
 | |
| 				} else {
 | |
| 					if ( overLeft > overRight ) {
 | |
| 						position.left = withinOffset + outerWidth - data.collisionWidth;
 | |
| 					} else {
 | |
| 						position.left = withinOffset;
 | |
| 					}
 | |
| 				}
 | |
| 			// too far left -> align with left edge
 | |
| 			} else if ( overLeft > 0 ) {
 | |
| 				position.left += overLeft;
 | |
| 			// too far right -> align with right edge
 | |
| 			} else if ( overRight > 0 ) {
 | |
| 				position.left -= overRight;
 | |
| 			// adjust based on position and margin
 | |
| 			} else {
 | |
| 				position.left = max( position.left - collisionPosLeft, position.left );
 | |
| 			}
 | |
| 		},
 | |
| 		top: function( position, data ) {
 | |
| 			var within = data.within,
 | |
| 				withinOffset = within.isWindow ? within.scrollTop : within.offset.top,
 | |
| 				outerHeight = data.within.height,
 | |
| 				collisionPosTop = position.top - data.collisionPosition.marginTop,
 | |
| 				overTop = withinOffset - collisionPosTop,
 | |
| 				overBottom = collisionPosTop + data.collisionHeight - outerHeight - withinOffset,
 | |
| 				newOverBottom;
 | |
| 
 | |
| 			// element is taller than within
 | |
| 			if ( data.collisionHeight > outerHeight ) {
 | |
| 				// element is initially over the top of within
 | |
| 				if ( overTop > 0 && overBottom <= 0 ) {
 | |
| 					newOverBottom = position.top + overTop + data.collisionHeight - outerHeight - withinOffset;
 | |
| 					position.top += overTop - newOverBottom;
 | |
| 				// element is initially over bottom of within
 | |
| 				} else if ( overBottom > 0 && overTop <= 0 ) {
 | |
| 					position.top = withinOffset;
 | |
| 				// element is initially over both top and bottom of within
 | |
| 				} else {
 | |
| 					if ( overTop > overBottom ) {
 | |
| 						position.top = withinOffset + outerHeight - data.collisionHeight;
 | |
| 					} else {
 | |
| 						position.top = withinOffset;
 | |
| 					}
 | |
| 				}
 | |
| 			// too far up -> align with top
 | |
| 			} else if ( overTop > 0 ) {
 | |
| 				position.top += overTop;
 | |
| 			// too far down -> align with bottom edge
 | |
| 			} else if ( overBottom > 0 ) {
 | |
| 				position.top -= overBottom;
 | |
| 			// adjust based on position and margin
 | |
| 			} else {
 | |
| 				position.top = max( position.top - collisionPosTop, position.top );
 | |
| 			}
 | |
| 		}
 | |
| 	},
 | |
| 	flip: {
 | |
| 		left: function( position, data ) {
 | |
| 			var within = data.within,
 | |
| 				withinOffset = within.offset.left + within.scrollLeft,
 | |
| 				outerWidth = within.width,
 | |
| 				offsetLeft = within.isWindow ? within.scrollLeft : within.offset.left,
 | |
| 				collisionPosLeft = position.left - data.collisionPosition.marginLeft,
 | |
| 				overLeft = collisionPosLeft - offsetLeft,
 | |
| 				overRight = collisionPosLeft + data.collisionWidth - outerWidth - offsetLeft,
 | |
| 				myOffset = data.my[ 0 ] === "left" ?
 | |
| 					-data.elemWidth :
 | |
| 					data.my[ 0 ] === "right" ?
 | |
| 						data.elemWidth :
 | |
| 						0,
 | |
| 				atOffset = data.at[ 0 ] === "left" ?
 | |
| 					data.targetWidth :
 | |
| 					data.at[ 0 ] === "right" ?
 | |
| 						-data.targetWidth :
 | |
| 						0,
 | |
| 				offset = -2 * data.offset[ 0 ],
 | |
| 				newOverRight,
 | |
| 				newOverLeft;
 | |
| 
 | |
| 			if ( overLeft < 0 ) {
 | |
| 				newOverRight = position.left + myOffset + atOffset + offset + data.collisionWidth - outerWidth - withinOffset;
 | |
| 				if ( newOverRight < 0 || newOverRight < abs( overLeft ) ) {
 | |
| 					position.left += myOffset + atOffset + offset;
 | |
| 				}
 | |
| 			} else if ( overRight > 0 ) {
 | |
| 				newOverLeft = position.left - data.collisionPosition.marginLeft + myOffset + atOffset + offset - offsetLeft;
 | |
| 				if ( newOverLeft > 0 || abs( newOverLeft ) < overRight ) {
 | |
| 					position.left += myOffset + atOffset + offset;
 | |
| 				}
 | |
| 			}
 | |
| 		},
 | |
| 		top: function( position, data ) {
 | |
| 			var within = data.within,
 | |
| 				withinOffset = within.offset.top + within.scrollTop,
 | |
| 				outerHeight = within.height,
 | |
| 				offsetTop = within.isWindow ? within.scrollTop : within.offset.top,
 | |
| 				collisionPosTop = position.top - data.collisionPosition.marginTop,
 | |
| 				overTop = collisionPosTop - offsetTop,
 | |
| 				overBottom = collisionPosTop + data.collisionHeight - outerHeight - offsetTop,
 | |
| 				top = data.my[ 1 ] === "top",
 | |
| 				myOffset = top ?
 | |
| 					-data.elemHeight :
 | |
| 					data.my[ 1 ] === "bottom" ?
 | |
| 						data.elemHeight :
 | |
| 						0,
 | |
| 				atOffset = data.at[ 1 ] === "top" ?
 | |
| 					data.targetHeight :
 | |
| 					data.at[ 1 ] === "bottom" ?
 | |
| 						-data.targetHeight :
 | |
| 						0,
 | |
| 				offset = -2 * data.offset[ 1 ],
 | |
| 				newOverTop,
 | |
| 				newOverBottom;
 | |
| 			if ( overTop < 0 ) {
 | |
| 				newOverBottom = position.top + myOffset + atOffset + offset + data.collisionHeight - outerHeight - withinOffset;
 | |
| 				if ( newOverBottom < 0 || newOverBottom < abs( overTop ) ) {
 | |
| 					position.top += myOffset + atOffset + offset;
 | |
| 				}
 | |
| 			} else if ( overBottom > 0 ) {
 | |
| 				newOverTop = position.top - data.collisionPosition.marginTop + myOffset + atOffset + offset - offsetTop;
 | |
| 				if ( newOverTop > 0 || abs( newOverTop ) < overBottom ) {
 | |
| 					position.top += myOffset + atOffset + offset;
 | |
| 				}
 | |
| 			}
 | |
| 		}
 | |
| 	},
 | |
| 	flipfit: {
 | |
| 		left: function() {
 | |
| 			$.ui.position.flip.left.apply( this, arguments );
 | |
| 			$.ui.position.fit.left.apply( this, arguments );
 | |
| 		},
 | |
| 		top: function() {
 | |
| 			$.ui.position.flip.top.apply( this, arguments );
 | |
| 			$.ui.position.fit.top.apply( this, arguments );
 | |
| 		}
 | |
| 	}
 | |
| };
 | |
| 
 | |
| // fraction support test
 | |
| (function() {
 | |
| 	var testElement, testElementParent, testElementStyle, offsetLeft, i,
 | |
| 		body = document.getElementsByTagName( "body" )[ 0 ],
 | |
| 		div = document.createElement( "div" );
 | |
| 
 | |
| 	//Create a "fake body" for testing based on method used in jQuery.support
 | |
| 	testElement = document.createElement( body ? "div" : "body" );
 | |
| 	testElementStyle = {
 | |
| 		visibility: "hidden",
 | |
| 		width: 0,
 | |
| 		height: 0,
 | |
| 		border: 0,
 | |
| 		margin: 0,
 | |
| 		background: "none"
 | |
| 	};
 | |
| 	if ( body ) {
 | |
| 		$.extend( testElementStyle, {
 | |
| 			position: "absolute",
 | |
| 			left: "-1000px",
 | |
| 			top: "-1000px"
 | |
| 		});
 | |
| 	}
 | |
| 	for ( i in testElementStyle ) {
 | |
| 		testElement.style[ i ] = testElementStyle[ i ];
 | |
| 	}
 | |
| 	testElement.appendChild( div );
 | |
| 	testElementParent = body || document.documentElement;
 | |
| 	testElementParent.insertBefore( testElement, testElementParent.firstChild );
 | |
| 
 | |
| 	div.style.cssText = "position: absolute; left: 10.7432222px;";
 | |
| 
 | |
| 	offsetLeft = $( div ).offset().left;
 | |
| 	supportsOffsetFractions = offsetLeft > 10 && offsetLeft < 11;
 | |
| 
 | |
| 	testElement.innerHTML = "";
 | |
| 	testElementParent.removeChild( testElement );
 | |
| })();
 | |
| 
 | |
| })();
 | |
| 
 | |
| var position = $.ui.position;
 | |
| 
 | |
| 
 | |
| /*!
 | |
|  * jQuery UI Tooltip 1.11.4
 | |
|  * http://jqueryui.com
 | |
|  *
 | |
|  * Copyright jQuery Foundation and other contributors
 | |
|  * Released under the MIT license.
 | |
|  * http://jquery.org/license
 | |
|  *
 | |
|  * http://api.jqueryui.com/tooltip/
 | |
|  */
 | |
| 
 | |
| 
 | |
| var tooltip = $.widget( "ui.tooltip", {
 | |
| 	version: "1.11.4",
 | |
| 	options: {
 | |
| 		content: function() {
 | |
| 			// support: IE<9, Opera in jQuery <1.7
 | |
| 			// .text() can't accept undefined, so coerce to a string
 | |
| 			var title = $( this ).attr( "title" ) || "";
 | |
| 			// Escape title, since we're going from an attribute to raw HTML
 | |
| 			return $( "<a>" ).text( title ).html();
 | |
| 		},
 | |
| 		hide: true,
 | |
| 		// Disabled elements have inconsistent behavior across browsers (#8661)
 | |
| 		items: "[title]:not([disabled])",
 | |
| 		position: {
 | |
| 			my: "left top+15",
 | |
| 			at: "left bottom",
 | |
| 			collision: "flipfit flip"
 | |
| 		},
 | |
| 		show: true,
 | |
| 		tooltipClass: null,
 | |
| 		track: false,
 | |
| 
 | |
| 		// callbacks
 | |
| 		close: null,
 | |
| 		open: null
 | |
| 	},
 | |
| 
 | |
| 	_addDescribedBy: function( elem, id ) {
 | |
| 		var describedby = (elem.attr( "aria-describedby" ) || "").split( /\s+/ );
 | |
| 		describedby.push( id );
 | |
| 		elem
 | |
| 			.data( "ui-tooltip-id", id )
 | |
| 			.attr( "aria-describedby", $.trim( describedby.join( " " ) ) );
 | |
| 	},
 | |
| 
 | |
| 	_removeDescribedBy: function( elem ) {
 | |
| 		var id = elem.data( "ui-tooltip-id" ),
 | |
| 			describedby = (elem.attr( "aria-describedby" ) || "").split( /\s+/ ),
 | |
| 			index = $.inArray( id, describedby );
 | |
| 
 | |
| 		if ( index !== -1 ) {
 | |
| 			describedby.splice( index, 1 );
 | |
| 		}
 | |
| 
 | |
| 		elem.removeData( "ui-tooltip-id" );
 | |
| 		describedby = $.trim( describedby.join( " " ) );
 | |
| 		if ( describedby ) {
 | |
| 			elem.attr( "aria-describedby", describedby );
 | |
| 		} else {
 | |
| 			elem.removeAttr( "aria-describedby" );
 | |
| 		}
 | |
| 	},
 | |
| 
 | |
| 	_create: function() {
 | |
| 		this._on({
 | |
| 			mouseover: "open",
 | |
| 			focusin: "open"
 | |
| 		});
 | |
| 
 | |
| 		// IDs of generated tooltips, needed for destroy
 | |
| 		this.tooltips = {};
 | |
| 
 | |
| 		// IDs of parent tooltips where we removed the title attribute
 | |
| 		this.parents = {};
 | |
| 
 | |
| 		if ( this.options.disabled ) {
 | |
| 			this._disable();
 | |
| 		}
 | |
| 
 | |
| 		// Append the aria-live region so tooltips announce correctly
 | |
| 		this.liveRegion = $( "<div>" )
 | |
| 			.attr({
 | |
| 				role: "log",
 | |
| 				"aria-live": "assertive",
 | |
| 				"aria-relevant": "additions"
 | |
| 			})
 | |
| 			.addClass( "ui-helper-hidden-accessible" )
 | |
| 			.appendTo( this.document[ 0 ].body );
 | |
| 	},
 | |
| 
 | |
| 	_setOption: function( key, value ) {
 | |
| 		var that = this;
 | |
| 
 | |
| 		if ( key === "disabled" ) {
 | |
| 			this[ value ? "_disable" : "_enable" ]();
 | |
| 			this.options[ key ] = value;
 | |
| 			// disable element style changes
 | |
| 			return;
 | |
| 		}
 | |
| 
 | |
| 		this._super( key, value );
 | |
| 
 | |
| 		if ( key === "content" ) {
 | |
| 			$.each( this.tooltips, function( id, tooltipData ) {
 | |
| 				that._updateContent( tooltipData.element );
 | |
| 			});
 | |
| 		}
 | |
| 	},
 | |
| 
 | |
| 	_disable: function() {
 | |
| 		var that = this;
 | |
| 
 | |
| 		// close open tooltips
 | |
| 		$.each( this.tooltips, function( id, tooltipData ) {
 | |
| 			var event = $.Event( "blur" );
 | |
| 			event.target = event.currentTarget = tooltipData.element[ 0 ];
 | |
| 			that.close( event, true );
 | |
| 		});
 | |
| 
 | |
| 		// remove title attributes to prevent native tooltips
 | |
| 		this.element.find( this.options.items ).addBack().each(function() {
 | |
| 			var element = $( this );
 | |
| 			if ( element.is( "[title]" ) ) {
 | |
| 				element
 | |
| 					.data( "ui-tooltip-title", element.attr( "title" ) )
 | |
| 					.removeAttr( "title" );
 | |
| 			}
 | |
| 		});
 | |
| 	},
 | |
| 
 | |
| 	_enable: function() {
 | |
| 		// restore title attributes
 | |
| 		this.element.find( this.options.items ).addBack().each(function() {
 | |
| 			var element = $( this );
 | |
| 			if ( element.data( "ui-tooltip-title" ) ) {
 | |
| 				element.attr( "title", element.data( "ui-tooltip-title" ) );
 | |
| 			}
 | |
| 		});
 | |
| 	},
 | |
| 
 | |
| 	open: function( event ) {
 | |
| 		var that = this,
 | |
| 			target = $( event ? event.target : this.element )
 | |
| 				// we need closest here due to mouseover bubbling,
 | |
| 				// but always pointing at the same event target
 | |
| 				.closest( this.options.items );
 | |
| 
 | |
| 		// No element to show a tooltip for or the tooltip is already open
 | |
| 		if ( !target.length || target.data( "ui-tooltip-id" ) ) {
 | |
| 			return;
 | |
| 		}
 | |
| 
 | |
| 		if ( target.attr( "title" ) ) {
 | |
| 			target.data( "ui-tooltip-title", target.attr( "title" ) );
 | |
| 		}
 | |
| 
 | |
| 		target.data( "ui-tooltip-open", true );
 | |
| 
 | |
| 		// kill parent tooltips, custom or native, for hover
 | |
| 		if ( event && event.type === "mouseover" ) {
 | |
| 			target.parents().each(function() {
 | |
| 				var parent = $( this ),
 | |
| 					blurEvent;
 | |
| 				if ( parent.data( "ui-tooltip-open" ) ) {
 | |
| 					blurEvent = $.Event( "blur" );
 | |
| 					blurEvent.target = blurEvent.currentTarget = this;
 | |
| 					that.close( blurEvent, true );
 | |
| 				}
 | |
| 				if ( parent.attr( "title" ) ) {
 | |
| 					parent.uniqueId();
 | |
| 					that.parents[ this.id ] = {
 | |
| 						element: this,
 | |
| 						title: parent.attr( "title" )
 | |
| 					};
 | |
| 					parent.attr( "title", "" );
 | |
| 				}
 | |
| 			});
 | |
| 		}
 | |
| 
 | |
| 		this._registerCloseHandlers( event, target );
 | |
| 		this._updateContent( target, event );
 | |
| 	},
 | |
| 
 | |
| 	_updateContent: function( target, event ) {
 | |
| 		var content,
 | |
| 			contentOption = this.options.content,
 | |
| 			that = this,
 | |
| 			eventType = event ? event.type : null;
 | |
| 
 | |
| 		if ( typeof contentOption === "string" ) {
 | |
| 			return this._open( event, target, contentOption );
 | |
| 		}
 | |
| 
 | |
| 		content = contentOption.call( target[0], function( response ) {
 | |
| 
 | |
| 			// IE may instantly serve a cached response for ajax requests
 | |
| 			// delay this call to _open so the other call to _open runs first
 | |
| 			that._delay(function() {
 | |
| 
 | |
| 				// Ignore async response if tooltip was closed already
 | |
| 				if ( !target.data( "ui-tooltip-open" ) ) {
 | |
| 					return;
 | |
| 				}
 | |
| 
 | |
| 				// jQuery creates a special event for focusin when it doesn't
 | |
| 				// exist natively. To improve performance, the native event
 | |
| 				// object is reused and the type is changed. Therefore, we can't
 | |
| 				// rely on the type being correct after the event finished
 | |
| 				// bubbling, so we set it back to the previous value. (#8740)
 | |
| 				if ( event ) {
 | |
| 					event.type = eventType;
 | |
| 				}
 | |
| 				this._open( event, target, response );
 | |
| 			});
 | |
| 		});
 | |
| 		if ( content ) {
 | |
| 			this._open( event, target, content );
 | |
| 		}
 | |
| 	},
 | |
| 
 | |
| 	_open: function( event, target, content ) {
 | |
| 		var tooltipData, tooltip, delayedShow, a11yContent,
 | |
| 			positionOption = $.extend( {}, this.options.position );
 | |
| 
 | |
| 		if ( !content ) {
 | |
| 			return;
 | |
| 		}
 | |
| 
 | |
| 		// Content can be updated multiple times. If the tooltip already
 | |
| 		// exists, then just update the content and bail.
 | |
| 		tooltipData = this._find( target );
 | |
| 		if ( tooltipData ) {
 | |
| 			tooltipData.tooltip.find( ".ui-tooltip-content" ).html( content );
 | |
| 			return;
 | |
| 		}
 | |
| 
 | |
| 		// if we have a title, clear it to prevent the native tooltip
 | |
| 		// we have to check first to avoid defining a title if none exists
 | |
| 		// (we don't want to cause an element to start matching [title])
 | |
| 		//
 | |
| 		// We use removeAttr only for key events, to allow IE to export the correct
 | |
| 		// accessible attributes. For mouse events, set to empty string to avoid
 | |
| 		// native tooltip showing up (happens only when removing inside mouseover).
 | |
| 		if ( target.is( "[title]" ) ) {
 | |
| 			if ( event && event.type === "mouseover" ) {
 | |
| 				target.attr( "title", "" );
 | |
| 			} else {
 | |
| 				target.removeAttr( "title" );
 | |
| 			}
 | |
| 		}
 | |
| 
 | |
| 		tooltipData = this._tooltip( target );
 | |
| 		tooltip = tooltipData.tooltip;
 | |
| 		this._addDescribedBy( target, tooltip.attr( "id" ) );
 | |
| 		tooltip.find( ".ui-tooltip-content" ).html( content );
 | |
| 
 | |
| 		// Support: Voiceover on OS X, JAWS on IE <= 9
 | |
| 		// JAWS announces deletions even when aria-relevant="additions"
 | |
| 		// Voiceover will sometimes re-read the entire log region's contents from the beginning
 | |
| 		this.liveRegion.children().hide();
 | |
| 		if ( content.clone ) {
 | |
| 			a11yContent = content.clone();
 | |
| 			a11yContent.removeAttr( "id" ).find( "[id]" ).removeAttr( "id" );
 | |
| 		} else {
 | |
| 			a11yContent = content;
 | |
| 		}
 | |
| 		$( "<div>" ).html( a11yContent ).appendTo( this.liveRegion );
 | |
| 
 | |
| 		function position( event ) {
 | |
| 			positionOption.of = event;
 | |
| 			if ( tooltip.is( ":hidden" ) ) {
 | |
| 				return;
 | |
| 			}
 | |
| 			tooltip.position( positionOption );
 | |
| 		}
 | |
| 		if ( this.options.track && event && /^mouse/.test( event.type ) ) {
 | |
| 			this._on( this.document, {
 | |
| 				mousemove: position
 | |
| 			});
 | |
| 			// trigger once to override element-relative positioning
 | |
| 			position( event );
 | |
| 		} else {
 | |
| 			tooltip.position( $.extend({
 | |
| 				of: target
 | |
| 			}, this.options.position ) );
 | |
| 		}
 | |
| 
 | |
| 		tooltip.hide();
 | |
| 
 | |
| 		this._show( tooltip, this.options.show );
 | |
| 		// Handle tracking tooltips that are shown with a delay (#8644). As soon
 | |
| 		// as the tooltip is visible, position the tooltip using the most recent
 | |
| 		// event.
 | |
| 		if ( this.options.show && this.options.show.delay ) {
 | |
| 			delayedShow = this.delayedShow = setInterval(function() {
 | |
| 				if ( tooltip.is( ":visible" ) ) {
 | |
| 					position( positionOption.of );
 | |
| 					clearInterval( delayedShow );
 | |
| 				}
 | |
| 			}, $.fx.interval );
 | |
| 		}
 | |
| 
 | |
| 		this._trigger( "open", event, { tooltip: tooltip } );
 | |
| 	},
 | |
| 
 | |
| 	_registerCloseHandlers: function( event, target ) {
 | |
| 		var events = {
 | |
| 			keyup: function( event ) {
 | |
| 				if ( event.keyCode === $.ui.keyCode.ESCAPE ) {
 | |
| 					var fakeEvent = $.Event(event);
 | |
| 					fakeEvent.currentTarget = target[0];
 | |
| 					this.close( fakeEvent, true );
 | |
| 				}
 | |
| 			}
 | |
| 		};
 | |
| 
 | |
| 		// Only bind remove handler for delegated targets. Non-delegated
 | |
| 		// tooltips will handle this in destroy.
 | |
| 		if ( target[ 0 ] !== this.element[ 0 ] ) {
 | |
| 			events.remove = function() {
 | |
| 				this._removeTooltip( this._find( target ).tooltip );
 | |
| 			};
 | |
| 		}
 | |
| 
 | |
| 		if ( !event || event.type === "mouseover" ) {
 | |
| 			events.mouseleave = "close";
 | |
| 		}
 | |
| 		if ( !event || event.type === "focusin" ) {
 | |
| 			events.focusout = "close";
 | |
| 		}
 | |
| 		this._on( true, target, events );
 | |
| 	},
 | |
| 
 | |
| 	close: function( event ) {
 | |
| 		var tooltip,
 | |
| 			that = this,
 | |
| 			target = $( event ? event.currentTarget : this.element ),
 | |
| 			tooltipData = this._find( target );
 | |
| 
 | |
| 		// The tooltip may already be closed
 | |
| 		if ( !tooltipData ) {
 | |
| 
 | |
| 			// We set ui-tooltip-open immediately upon open (in open()), but only set the
 | |
| 			// additional data once there's actually content to show (in _open()). So even if the
 | |
| 			// tooltip doesn't have full data, we always remove ui-tooltip-open in case we're in
 | |
| 			// the period between open() and _open().
 | |
| 			target.removeData( "ui-tooltip-open" );
 | |
| 			return;
 | |
| 		}
 | |
| 
 | |
| 		tooltip = tooltipData.tooltip;
 | |
| 
 | |
| 		// disabling closes the tooltip, so we need to track when we're closing
 | |
| 		// to avoid an infinite loop in case the tooltip becomes disabled on close
 | |
| 		if ( tooltipData.closing ) {
 | |
| 			return;
 | |
| 		}
 | |
| 
 | |
| 		// Clear the interval for delayed tracking tooltips
 | |
| 		clearInterval( this.delayedShow );
 | |
| 
 | |
| 		// only set title if we had one before (see comment in _open())
 | |
| 		// If the title attribute has changed since open(), don't restore
 | |
| 		if ( target.data( "ui-tooltip-title" ) && !target.attr( "title" ) ) {
 | |
| 			target.attr( "title", target.data( "ui-tooltip-title" ) );
 | |
| 		}
 | |
| 
 | |
| 		this._removeDescribedBy( target );
 | |
| 
 | |
| 		tooltipData.hiding = true;
 | |
| 		tooltip.stop( true );
 | |
| 		this._hide( tooltip, this.options.hide, function() {
 | |
| 			that._removeTooltip( $( this ) );
 | |
| 		});
 | |
| 
 | |
| 		target.removeData( "ui-tooltip-open" );
 | |
| 		this._off( target, "mouseleave focusout keyup" );
 | |
| 
 | |
| 		// Remove 'remove' binding only on delegated targets
 | |
| 		if ( target[ 0 ] !== this.element[ 0 ] ) {
 | |
| 			this._off( target, "remove" );
 | |
| 		}
 | |
| 		this._off( this.document, "mousemove" );
 | |
| 
 | |
| 		if ( event && event.type === "mouseleave" ) {
 | |
| 			$.each( this.parents, function( id, parent ) {
 | |
| 				$( parent.element ).attr( "title", parent.title );
 | |
| 				delete that.parents[ id ];
 | |
| 			});
 | |
| 		}
 | |
| 
 | |
| 		tooltipData.closing = true;
 | |
| 		this._trigger( "close", event, { tooltip: tooltip } );
 | |
| 		if ( !tooltipData.hiding ) {
 | |
| 			tooltipData.closing = false;
 | |
| 		}
 | |
| 	},
 | |
| 
 | |
| 	_tooltip: function( element ) {
 | |
| 		var tooltip = $( "<div>" )
 | |
| 				.attr( "role", "tooltip" )
 | |
| 				.addClass( "ui-tooltip ui-widget ui-corner-all ui-widget-content " +
 | |
| 					( this.options.tooltipClass || "" ) ),
 | |
| 			id = tooltip.uniqueId().attr( "id" );
 | |
| 
 | |
| 		$( "<div>" )
 | |
| 			.addClass( "ui-tooltip-content" )
 | |
| 			.appendTo( tooltip );
 | |
| 
 | |
| 		tooltip.appendTo( this.document[0].body );
 | |
| 
 | |
| 		return this.tooltips[ id ] = {
 | |
| 			element: element,
 | |
| 			tooltip: tooltip
 | |
| 		};
 | |
| 	},
 | |
| 
 | |
| 	_find: function( target ) {
 | |
| 		var id = target.data( "ui-tooltip-id" );
 | |
| 		return id ? this.tooltips[ id ] : null;
 | |
| 	},
 | |
| 
 | |
| 	_removeTooltip: function( tooltip ) {
 | |
| 		tooltip.remove();
 | |
| 		delete this.tooltips[ tooltip.attr( "id" ) ];
 | |
| 	},
 | |
| 
 | |
| 	_destroy: function() {
 | |
| 		var that = this;
 | |
| 
 | |
| 		// close open tooltips
 | |
| 		$.each( this.tooltips, function( id, tooltipData ) {
 | |
| 			// Delegate to close method to handle common cleanup
 | |
| 			var event = $.Event( "blur" ),
 | |
| 				element = tooltipData.element;
 | |
| 			event.target = event.currentTarget = element[ 0 ];
 | |
| 			that.close( event, true );
 | |
| 
 | |
| 			// Remove immediately; destroying an open tooltip doesn't use the
 | |
| 			// hide animation
 | |
| 			$( "#" + id ).remove();
 | |
| 
 | |
| 			// Restore the title
 | |
| 			if ( element.data( "ui-tooltip-title" ) ) {
 | |
| 				// If the title attribute has changed since open(), don't restore
 | |
| 				if ( !element.attr( "title" ) ) {
 | |
| 					element.attr( "title", element.data( "ui-tooltip-title" ) );
 | |
| 				}
 | |
| 				element.removeData( "ui-tooltip-title" );
 | |
| 			}
 | |
| 		});
 | |
| 		this.liveRegion.remove();
 | |
| 	}
 | |
| });
 | |
| 
 | |
| 
 | |
| 
 | |
| })); | 
