|
@@ -0,0 +1,3109 @@
|
|
|
|
+/*! jQuery UI - v1.12.1 - 2016-12-08
|
|
|
|
+* http://jqueryui.com
|
|
|
|
+* Includes: widget.js, data.js, scroll-parent.js, widgets/draggable.js, widgets/droppable.js, widgets/selectable.js, widgets/mouse.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( $ ) {
|
|
|
|
+
|
|
|
|
+$.ui = $.ui || {};
|
|
|
|
+
|
|
|
|
+var version = $.ui.version = "1.12.1";
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+/*!
|
|
|
|
+ * jQuery UI Widget 1.12.1
|
|
|
|
+ * http://jqueryui.com
|
|
|
|
+ *
|
|
|
|
+ * Copyright jQuery Foundation and other contributors
|
|
|
|
+ * Released under the MIT license.
|
|
|
|
+ * http://jquery.org/license
|
|
|
|
+ */
|
|
|
|
+
|
|
|
|
+//>>label: Widget
|
|
|
|
+//>>group: Core
|
|
|
|
+//>>description: Provides a factory for creating stateful widgets with a common API.
|
|
|
|
+//>>docs: http://api.jqueryui.com/jQuery.widget/
|
|
|
|
+//>>demos: http://jqueryui.com/widget/
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+var widgetUuid = 0;
|
|
|
|
+var widgetSlice = 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 existingConstructor, constructor, basePrototype;
|
|
|
|
+
|
|
|
|
+ // ProxiedPrototype allows the provided prototype to remain unmodified
|
|
|
|
+ // so that it can be used as a mixin for multiple widgets (#8876)
|
|
|
|
+ var proxiedPrototype = {};
|
|
|
|
+
|
|
|
|
+ var namespace = name.split( "." )[ 0 ];
|
|
|
|
+ name = name.split( "." )[ 1 ];
|
|
|
|
+ var fullName = namespace + "-" + name;
|
|
|
|
+
|
|
|
|
+ if ( !prototype ) {
|
|
|
|
+ prototype = base;
|
|
|
|
+ base = $.Widget;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if ( $.isArray( prototype ) ) {
|
|
|
|
+ prototype = $.extend.apply( null, [ {} ].concat( prototype ) );
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 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() {
|
|
|
|
+ function _super() {
|
|
|
|
+ return base.prototype[ prop ].apply( this, arguments );
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ function _superApply( args ) {
|
|
|
|
+ return base.prototype[ prop ].apply( this, args );
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return function() {
|
|
|
|
+ var __super = this._super;
|
|
|
|
+ var __superApply = this._superApply;
|
|
|
|
+ var 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 = widgetSlice.call( arguments, 1 );
|
|
|
|
+ var inputIndex = 0;
|
|
|
|
+ var inputLength = input.length;
|
|
|
|
+ var key;
|
|
|
|
+ var 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";
|
|
|
|
+ var args = widgetSlice.call( arguments, 1 );
|
|
|
|
+ var returnValue = this;
|
|
|
|
+
|
|
|
|
+ if ( isMethodCall ) {
|
|
|
|
+
|
|
|
|
+ // If this is an empty collection, we need to have the instance method
|
|
|
|
+ // return undefined instead of the jQuery instance
|
|
|
|
+ if ( !this.length && options === "instance" ) {
|
|
|
|
+ returnValue = undefined;
|
|
|
|
+ } else {
|
|
|
|
+ this.each( function() {
|
|
|
|
+ var methodValue;
|
|
|
|
+ var 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: {
|
|
|
|
+ classes: {},
|
|
|
|
+ disabled: false,
|
|
|
|
+
|
|
|
|
+ // Callbacks
|
|
|
|
+ create: null
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ _createWidget: function( options, element ) {
|
|
|
|
+ element = $( element || this.defaultElement || this )[ 0 ];
|
|
|
|
+ this.element = $( element );
|
|
|
|
+ this.uuid = widgetUuid++;
|
|
|
|
+ this.eventNamespace = "." + this.widgetName + this.uuid;
|
|
|
|
+
|
|
|
|
+ this.bindings = $();
|
|
|
|
+ this.hoverable = $();
|
|
|
|
+ this.focusable = $();
|
|
|
|
+ this.classesElementLookup = {};
|
|
|
|
+
|
|
|
|
+ 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();
|
|
|
|
+
|
|
|
|
+ if ( this.options.disabled ) {
|
|
|
|
+ this._setOptionDisabled( this.options.disabled );
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ this._trigger( "create", null, this._getCreateEventData() );
|
|
|
|
+ this._init();
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ _getCreateOptions: function() {
|
|
|
|
+ return {};
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ _getCreateEventData: $.noop,
|
|
|
|
+
|
|
|
|
+ _create: $.noop,
|
|
|
|
+
|
|
|
|
+ _init: $.noop,
|
|
|
|
+
|
|
|
|
+ destroy: function() {
|
|
|
|
+ var that = this;
|
|
|
|
+
|
|
|
|
+ this._destroy();
|
|
|
|
+ $.each( this.classesElementLookup, function( key, value ) {
|
|
|
|
+ that._removeClass( value, key );
|
|
|
|
+ } );
|
|
|
|
+
|
|
|
|
+ // We can probably remove the unbind calls in 2.0
|
|
|
|
+ // all event bindings should go through this._on()
|
|
|
|
+ this.element
|
|
|
|
+ .off( this.eventNamespace )
|
|
|
|
+ .removeData( this.widgetFullName );
|
|
|
|
+ this.widget()
|
|
|
|
+ .off( this.eventNamespace )
|
|
|
|
+ .removeAttr( "aria-disabled" );
|
|
|
|
+
|
|
|
|
+ // Clean up events and states
|
|
|
|
+ this.bindings.off( this.eventNamespace );
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ _destroy: $.noop,
|
|
|
|
+
|
|
|
|
+ widget: function() {
|
|
|
|
+ return this.element;
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ option: function( key, value ) {
|
|
|
|
+ var options = key;
|
|
|
|
+ var parts;
|
|
|
|
+ var curOption;
|
|
|
|
+ var 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 ) {
|
|
|
|
+ if ( key === "classes" ) {
|
|
|
|
+ this._setOptionClasses( value );
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ this.options[ key ] = value;
|
|
|
|
+
|
|
|
|
+ if ( key === "disabled" ) {
|
|
|
|
+ this._setOptionDisabled( value );
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return this;
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ _setOptionClasses: function( value ) {
|
|
|
|
+ var classKey, elements, currentElements;
|
|
|
|
+
|
|
|
|
+ for ( classKey in value ) {
|
|
|
|
+ currentElements = this.classesElementLookup[ classKey ];
|
|
|
|
+ if ( value[ classKey ] === this.options.classes[ classKey ] ||
|
|
|
|
+ !currentElements ||
|
|
|
|
+ !currentElements.length ) {
|
|
|
|
+ continue;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // We are doing this to create a new jQuery object because the _removeClass() call
|
|
|
|
+ // on the next line is going to destroy the reference to the current elements being
|
|
|
|
+ // tracked. We need to save a copy of this collection so that we can add the new classes
|
|
|
|
+ // below.
|
|
|
|
+ elements = $( currentElements.get() );
|
|
|
|
+ this._removeClass( currentElements, classKey );
|
|
|
|
+
|
|
|
|
+ // We don't use _addClass() here, because that uses this.options.classes
|
|
|
|
+ // for generating the string of classes. We want to use the value passed in from
|
|
|
|
+ // _setOption(), this is the new value of the classes option which was passed to
|
|
|
|
+ // _setOption(). We pass this value directly to _classes().
|
|
|
|
+ elements.addClass( this._classes( {
|
|
|
|
+ element: elements,
|
|
|
|
+ keys: classKey,
|
|
|
|
+ classes: value,
|
|
|
|
+ add: true
|
|
|
|
+ } ) );
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ _setOptionDisabled: function( value ) {
|
|
|
|
+ this._toggleClass( this.widget(), this.widgetFullName + "-disabled", null, !!value );
|
|
|
|
+
|
|
|
|
+ // If the widget is becoming disabled, then nothing is interactive
|
|
|
|
+ if ( value ) {
|
|
|
|
+ this._removeClass( this.hoverable, null, "ui-state-hover" );
|
|
|
|
+ this._removeClass( this.focusable, null, "ui-state-focus" );
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ enable: function() {
|
|
|
|
+ return this._setOptions( { disabled: false } );
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ disable: function() {
|
|
|
|
+ return this._setOptions( { disabled: true } );
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ _classes: function( options ) {
|
|
|
|
+ var full = [];
|
|
|
|
+ var that = this;
|
|
|
|
+
|
|
|
|
+ options = $.extend( {
|
|
|
|
+ element: this.element,
|
|
|
|
+ classes: this.options.classes || {}
|
|
|
|
+ }, options );
|
|
|
|
+
|
|
|
|
+ function processClassString( classes, checkOption ) {
|
|
|
|
+ var current, i;
|
|
|
|
+ for ( i = 0; i < classes.length; i++ ) {
|
|
|
|
+ current = that.classesElementLookup[ classes[ i ] ] || $();
|
|
|
|
+ if ( options.add ) {
|
|
|
|
+ current = $( $.unique( current.get().concat( options.element.get() ) ) );
|
|
|
|
+ } else {
|
|
|
|
+ current = $( current.not( options.element ).get() );
|
|
|
|
+ }
|
|
|
|
+ that.classesElementLookup[ classes[ i ] ] = current;
|
|
|
|
+ full.push( classes[ i ] );
|
|
|
|
+ if ( checkOption && options.classes[ classes[ i ] ] ) {
|
|
|
|
+ full.push( options.classes[ classes[ i ] ] );
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ this._on( options.element, {
|
|
|
|
+ "remove": "_untrackClassesElement"
|
|
|
|
+ } );
|
|
|
|
+
|
|
|
|
+ if ( options.keys ) {
|
|
|
|
+ processClassString( options.keys.match( /\S+/g ) || [], true );
|
|
|
|
+ }
|
|
|
|
+ if ( options.extra ) {
|
|
|
|
+ processClassString( options.extra.match( /\S+/g ) || [] );
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return full.join( " " );
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ _untrackClassesElement: function( event ) {
|
|
|
|
+ var that = this;
|
|
|
|
+ $.each( that.classesElementLookup, function( key, value ) {
|
|
|
|
+ if ( $.inArray( event.target, value ) !== -1 ) {
|
|
|
|
+ that.classesElementLookup[ key ] = $( value.not( event.target ).get() );
|
|
|
|
+ }
|
|
|
|
+ } );
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ _removeClass: function( element, keys, extra ) {
|
|
|
|
+ return this._toggleClass( element, keys, extra, false );
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ _addClass: function( element, keys, extra ) {
|
|
|
|
+ return this._toggleClass( element, keys, extra, true );
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ _toggleClass: function( element, keys, extra, add ) {
|
|
|
|
+ add = ( typeof add === "boolean" ) ? add : extra;
|
|
|
|
+ var shift = ( typeof element === "string" || element === null ),
|
|
|
|
+ options = {
|
|
|
|
+ extra: shift ? keys : extra,
|
|
|
|
+ keys: shift ? element : keys,
|
|
|
|
+ element: shift ? this.element : element,
|
|
|
|
+ add: add
|
|
|
|
+ };
|
|
|
|
+ options.element.toggleClass( this._classes( options ), add );
|
|
|
|
+ return this;
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ _on: function( suppressDisabledCheck, element, handlers ) {
|
|
|
|
+ var delegateElement;
|
|
|
|
+ var 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*(.*)$/ );
|
|
|
|
+ var eventName = match[ 1 ] + instance.eventNamespace;
|
|
|
|
+ var selector = match[ 2 ];
|
|
|
|
+
|
|
|
|
+ if ( selector ) {
|
|
|
|
+ delegateElement.on( eventName, selector, handlerProxy );
|
|
|
|
+ } else {
|
|
|
|
+ element.on( eventName, handlerProxy );
|
|
|
|
+ }
|
|
|
|
+ } );
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ _off: function( element, eventName ) {
|
|
|
|
+ eventName = ( eventName || "" ).split( " " ).join( this.eventNamespace + " " ) +
|
|
|
|
+ this.eventNamespace;
|
|
|
|
+ element.off( eventName ).off( 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 ) {
|
|
|
|
+ this._addClass( $( event.currentTarget ), null, "ui-state-hover" );
|
|
|
|
+ },
|
|
|
|
+ mouseleave: function( event ) {
|
|
|
|
+ this._removeClass( $( event.currentTarget ), null, "ui-state-hover" );
|
|
|
|
+ }
|
|
|
|
+ } );
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ _focusable: function( element ) {
|
|
|
|
+ this.focusable = this.focusable.add( element );
|
|
|
|
+ this._on( element, {
|
|
|
|
+ focusin: function( event ) {
|
|
|
|
+ this._addClass( $( event.currentTarget ), null, "ui-state-focus" );
|
|
|
|
+ },
|
|
|
|
+ focusout: function( event ) {
|
|
|
|
+ this._removeClass( $( event.currentTarget ), null, "ui-state-focus" );
|
|
|
|
+ }
|
|
|
|
+ } );
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ _trigger: function( type, event, data ) {
|
|
|
|
+ var prop, orig;
|
|
|
|
+ var 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;
|
|
|
|
+ var 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 :data 1.12.1
|
|
|
|
+ * http://jqueryui.com
|
|
|
|
+ *
|
|
|
|
+ * Copyright jQuery Foundation and other contributors
|
|
|
|
+ * Released under the MIT license.
|
|
|
|
+ * http://jquery.org/license
|
|
|
|
+ */
|
|
|
|
+
|
|
|
|
+//>>label: :data Selector
|
|
|
|
+//>>group: Core
|
|
|
|
+//>>description: Selects elements which have data stored under the specified key.
|
|
|
|
+//>>docs: http://api.jqueryui.com/data-selector/
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+var data = $.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 ] );
|
|
|
|
+ }
|
|
|
|
+} );
|
|
|
|
+
|
|
|
|
+/*!
|
|
|
|
+ * jQuery UI Scroll Parent 1.12.1
|
|
|
|
+ * http://jqueryui.com
|
|
|
|
+ *
|
|
|
|
+ * Copyright jQuery Foundation and other contributors
|
|
|
|
+ * Released under the MIT license.
|
|
|
|
+ * http://jquery.org/license
|
|
|
|
+ */
|
|
|
|
+
|
|
|
|
+//>>label: scrollParent
|
|
|
|
+//>>group: Core
|
|
|
|
+//>>description: Get the closest ancestor element that is scrollable.
|
|
|
|
+//>>docs: http://api.jqueryui.com/scrollParent/
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+var scrollParent = $.fn.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;
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+// This file is deprecated
|
|
|
|
+var ie = $.ui.ie = !!/msie [\w.]+/.exec( navigator.userAgent.toLowerCase() );
|
|
|
|
+
|
|
|
|
+/*!
|
|
|
|
+ * jQuery UI Mouse 1.12.1
|
|
|
|
+ * http://jqueryui.com
|
|
|
|
+ *
|
|
|
|
+ * Copyright jQuery Foundation and other contributors
|
|
|
|
+ * Released under the MIT license.
|
|
|
|
+ * http://jquery.org/license
|
|
|
|
+ */
|
|
|
|
+
|
|
|
|
+//>>label: Mouse
|
|
|
|
+//>>group: Widgets
|
|
|
|
+//>>description: Abstracts mouse-based interactions to assist in creating certain widgets.
|
|
|
|
+//>>docs: http://api.jqueryui.com/mouse/
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+var mouseHandled = false;
|
|
|
|
+$( document ).on( "mouseup", function() {
|
|
|
|
+ mouseHandled = false;
|
|
|
|
+} );
|
|
|
|
+
|
|
|
|
+var widgetsMouse = $.widget( "ui.mouse", {
|
|
|
|
+ version: "1.12.1",
|
|
|
|
+ options: {
|
|
|
|
+ cancel: "input, textarea, button, select, option",
|
|
|
|
+ distance: 1,
|
|
|
|
+ delay: 0
|
|
|
|
+ },
|
|
|
|
+ _mouseInit: function() {
|
|
|
|
+ var that = this;
|
|
|
|
+
|
|
|
|
+ this.element
|
|
|
|
+ .on( "mousedown." + this.widgetName, function( event ) {
|
|
|
|
+ return that._mouseDown( event );
|
|
|
|
+ } )
|
|
|
|
+ .on( "click." + this.widgetName, function( event ) {
|
|
|
|
+ if ( true === $.data( event.target, that.widgetName + ".preventClickEvent" ) ) {
|
|
|
|
+ $.removeData( event.target, that.widgetName + ".preventClickEvent" );
|
|
|
|
+ event.stopImmediatePropagation();
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+ } );
|
|
|
|
+
|
|
|
|
+ this.started = false;
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ // TODO: make sure destroying one instance of mouse doesn't mess with
|
|
|
|
+ // other instances of mouse
|
|
|
|
+ _mouseDestroy: function() {
|
|
|
|
+ this.element.off( "." + this.widgetName );
|
|
|
|
+ if ( this._mouseMoveDelegate ) {
|
|
|
|
+ this.document
|
|
|
|
+ .off( "mousemove." + this.widgetName, this._mouseMoveDelegate )
|
|
|
|
+ .off( "mouseup." + this.widgetName, this._mouseUpDelegate );
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ _mouseDown: function( event ) {
|
|
|
|
+
|
|
|
|
+ // don't let more than one widget handle mouseStart
|
|
|
|
+ if ( mouseHandled ) {
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ this._mouseMoved = false;
|
|
|
|
+
|
|
|
|
+ // We may have missed mouseup (out of window)
|
|
|
|
+ ( this._mouseStarted && this._mouseUp( event ) );
|
|
|
|
+
|
|
|
|
+ this._mouseDownEvent = event;
|
|
|
|
+
|
|
|
|
+ var that = this,
|
|
|
|
+ btnIsLeft = ( event.which === 1 ),
|
|
|
|
+
|
|
|
|
+ // event.target.nodeName works around a bug in IE 8 with
|
|
|
|
+ // disabled inputs (#7620)
|
|
|
|
+ elIsCancel = ( typeof this.options.cancel === "string" && event.target.nodeName ?
|
|
|
|
+ $( event.target ).closest( this.options.cancel ).length : false );
|
|
|
|
+ if ( !btnIsLeft || elIsCancel || !this._mouseCapture( event ) ) {
|
|
|
|
+ return true;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ this.mouseDelayMet = !this.options.delay;
|
|
|
|
+ if ( !this.mouseDelayMet ) {
|
|
|
|
+ this._mouseDelayTimer = setTimeout( function() {
|
|
|
|
+ that.mouseDelayMet = true;
|
|
|
|
+ }, this.options.delay );
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if ( this._mouseDistanceMet( event ) && this._mouseDelayMet( event ) ) {
|
|
|
|
+ this._mouseStarted = ( this._mouseStart( event ) !== false );
|
|
|
|
+ if ( !this._mouseStarted ) {
|
|
|
|
+ event.preventDefault();
|
|
|
|
+ return true;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // Click event may never have fired (Gecko & Opera)
|
|
|
|
+ if ( true === $.data( event.target, this.widgetName + ".preventClickEvent" ) ) {
|
|
|
|
+ $.removeData( event.target, this.widgetName + ".preventClickEvent" );
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // These delegates are required to keep context
|
|
|
|
+ this._mouseMoveDelegate = function( event ) {
|
|
|
|
+ return that._mouseMove( event );
|
|
|
|
+ };
|
|
|
|
+ this._mouseUpDelegate = function( event ) {
|
|
|
|
+ return that._mouseUp( event );
|
|
|
|
+ };
|
|
|
|
+
|
|
|
|
+ this.document
|
|
|
|
+ .on( "mousemove." + this.widgetName, this._mouseMoveDelegate )
|
|
|
|
+ .on( "mouseup." + this.widgetName, this._mouseUpDelegate );
|
|
|
|
+
|
|
|
|
+ event.preventDefault();
|
|
|
|
+
|
|
|
|
+ mouseHandled = true;
|
|
|
|
+ return true;
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ _mouseMove: function( event ) {
|
|
|
|
+
|
|
|
|
+ // Only check for mouseups outside the document if you've moved inside the document
|
|
|
|
+ // at least once. This prevents the firing of mouseup in the case of IE<9, which will
|
|
|
|
+ // fire a mousemove event if content is placed under the cursor. See #7778
|
|
|
|
+ // Support: IE <9
|
|
|
|
+ if ( this._mouseMoved ) {
|
|
|
|
+
|
|
|
|
+ // IE mouseup check - mouseup happened when mouse was out of window
|
|
|
|
+ if ( $.ui.ie && ( !document.documentMode || document.documentMode < 9 ) &&
|
|
|
|
+ !event.button ) {
|
|
|
|
+ return this._mouseUp( event );
|
|
|
|
+
|
|
|
|
+ // Iframe mouseup check - mouseup occurred in another document
|
|
|
|
+ } else if ( !event.which ) {
|
|
|
|
+
|
|
|
|
+ // Support: Safari <=8 - 9
|
|
|
|
+ // Safari sets which to 0 if you press any of the following keys
|
|
|
|
+ // during a drag (#14461)
|
|
|
|
+ if ( event.originalEvent.altKey || event.originalEvent.ctrlKey ||
|
|
|
|
+ event.originalEvent.metaKey || event.originalEvent.shiftKey ) {
|
|
|
|
+ this.ignoreMissingWhich = true;
|
|
|
|
+ } else if ( !this.ignoreMissingWhich ) {
|
|
|
|
+ return this._mouseUp( event );
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if ( event.which || event.button ) {
|
|
|
|
+ this._mouseMoved = true;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if ( this._mouseStarted ) {
|
|
|
|
+ this._mouseDrag( event );
|
|
|
|
+ return event.preventDefault();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if ( this._mouseDistanceMet( event ) && this._mouseDelayMet( event ) ) {
|
|
|
|
+ this._mouseStarted =
|
|
|
|
+ ( this._mouseStart( this._mouseDownEvent, event ) !== false );
|
|
|
|
+ ( this._mouseStarted ? this._mouseDrag( event ) : this._mouseUp( event ) );
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return !this._mouseStarted;
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ _mouseUp: function( event ) {
|
|
|
|
+ this.document
|
|
|
|
+ .off( "mousemove." + this.widgetName, this._mouseMoveDelegate )
|
|
|
|
+ .off( "mouseup." + this.widgetName, this._mouseUpDelegate );
|
|
|
|
+
|
|
|
|
+ if ( this._mouseStarted ) {
|
|
|
|
+ this._mouseStarted = false;
|
|
|
|
+
|
|
|
|
+ if ( event.target === this._mouseDownEvent.target ) {
|
|
|
|
+ $.data( event.target, this.widgetName + ".preventClickEvent", true );
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ this._mouseStop( event );
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if ( this._mouseDelayTimer ) {
|
|
|
|
+ clearTimeout( this._mouseDelayTimer );
|
|
|
|
+ delete this._mouseDelayTimer;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ this.ignoreMissingWhich = false;
|
|
|
|
+ mouseHandled = false;
|
|
|
|
+ event.preventDefault();
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ _mouseDistanceMet: function( event ) {
|
|
|
|
+ return ( Math.max(
|
|
|
|
+ Math.abs( this._mouseDownEvent.pageX - event.pageX ),
|
|
|
|
+ Math.abs( this._mouseDownEvent.pageY - event.pageY )
|
|
|
|
+ ) >= this.options.distance
|
|
|
|
+ );
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ _mouseDelayMet: function( /* event */ ) {
|
|
|
|
+ return this.mouseDelayMet;
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ // These are placeholder methods, to be overriden by extending plugin
|
|
|
|
+ _mouseStart: function( /* event */ ) {},
|
|
|
|
+ _mouseDrag: function( /* event */ ) {},
|
|
|
|
+ _mouseStop: function( /* event */ ) {},
|
|
|
|
+ _mouseCapture: function( /* event */ ) { return true; }
|
|
|
|
+} );
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+// $.ui.plugin is deprecated. Use $.widget() extensions instead.
|
|
|
|
+var plugin = $.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 );
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+var safeActiveElement = $.ui.safeActiveElement = function( document ) {
|
|
|
|
+ var activeElement;
|
|
|
|
+
|
|
|
|
+ // Support: IE 9 only
|
|
|
|
+ // IE9 throws an "Unspecified error" accessing document.activeElement from an <iframe>
|
|
|
|
+ try {
|
|
|
|
+ activeElement = document.activeElement;
|
|
|
|
+ } catch ( error ) {
|
|
|
|
+ activeElement = document.body;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // Support: IE 9 - 11 only
|
|
|
|
+ // IE may return null instead of an element
|
|
|
|
+ // Interestingly, this only seems to occur when NOT in an iframe
|
|
|
|
+ if ( !activeElement ) {
|
|
|
|
+ activeElement = document.body;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // Support: IE 11 only
|
|
|
|
+ // IE11 returns a seemingly empty object in some cases when accessing
|
|
|
|
+ // document.activeElement from an <iframe>
|
|
|
|
+ if ( !activeElement.nodeName ) {
|
|
|
|
+ activeElement = document.body;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return activeElement;
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+var safeBlur = $.ui.safeBlur = function( element ) {
|
|
|
|
+
|
|
|
|
+ // Support: IE9 - 10 only
|
|
|
|
+ // If the <body> is blurred, IE will switch windows, see #9420
|
|
|
|
+ if ( element && element.nodeName.toLowerCase() !== "body" ) {
|
|
|
|
+ $( element ).trigger( "blur" );
|
|
|
|
+ }
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+/*!
|
|
|
|
+ * jQuery UI Draggable 1.12.1
|
|
|
|
+ * http://jqueryui.com
|
|
|
|
+ *
|
|
|
|
+ * Copyright jQuery Foundation and other contributors
|
|
|
|
+ * Released under the MIT license.
|
|
|
|
+ * http://jquery.org/license
|
|
|
|
+ */
|
|
|
|
+
|
|
|
|
+//>>label: Draggable
|
|
|
|
+//>>group: Interactions
|
|
|
|
+//>>description: Enables dragging functionality for any element.
|
|
|
|
+//>>docs: http://api.jqueryui.com/draggable/
|
|
|
|
+//>>demos: http://jqueryui.com/draggable/
|
|
|
|
+//>>css.structure: ../../themes/base/draggable.css
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+$.widget( "ui.draggable", $.ui.mouse, {
|
|
|
|
+ version: "1.12.1",
|
|
|
|
+ widgetEventPrefix: "drag",
|
|
|
|
+ options: {
|
|
|
|
+ addClasses: true,
|
|
|
|
+ appendTo: "parent",
|
|
|
|
+ axis: false,
|
|
|
|
+ connectToSortable: false,
|
|
|
|
+ containment: false,
|
|
|
|
+ cursor: "auto",
|
|
|
|
+ cursorAt: false,
|
|
|
|
+ grid: false,
|
|
|
|
+ handle: false,
|
|
|
|
+ helper: "original",
|
|
|
|
+ iframeFix: false,
|
|
|
|
+ opacity: false,
|
|
|
|
+ refreshPositions: false,
|
|
|
|
+ revert: false,
|
|
|
|
+ revertDuration: 500,
|
|
|
|
+ scope: "default",
|
|
|
|
+ scroll: true,
|
|
|
|
+ scrollSensitivity: 20,
|
|
|
|
+ scrollSpeed: 20,
|
|
|
|
+ snap: false,
|
|
|
|
+ snapMode: "both",
|
|
|
|
+ snapTolerance: 20,
|
|
|
|
+ stack: false,
|
|
|
|
+ zIndex: false,
|
|
|
|
+
|
|
|
|
+ // Callbacks
|
|
|
|
+ drag: null,
|
|
|
|
+ start: null,
|
|
|
|
+ stop: null
|
|
|
|
+ },
|
|
|
|
+ _create: function() {
|
|
|
|
+
|
|
|
|
+ if ( this.options.helper === "original" ) {
|
|
|
|
+ this._setPositionRelative();
|
|
|
|
+ }
|
|
|
|
+ if ( this.options.addClasses ) {
|
|
|
|
+ this._addClass( "ui-draggable" );
|
|
|
|
+ }
|
|
|
|
+ this._setHandleClassName();
|
|
|
|
+
|
|
|
|
+ this._mouseInit();
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ _setOption: function( key, value ) {
|
|
|
|
+ this._super( key, value );
|
|
|
|
+ if ( key === "handle" ) {
|
|
|
|
+ this._removeHandleClassName();
|
|
|
|
+ this._setHandleClassName();
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ _destroy: function() {
|
|
|
|
+ if ( ( this.helper || this.element ).is( ".ui-draggable-dragging" ) ) {
|
|
|
|
+ this.destroyOnClear = true;
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+ this._removeHandleClassName();
|
|
|
|
+ this._mouseDestroy();
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ _mouseCapture: function( event ) {
|
|
|
|
+ var o = this.options;
|
|
|
|
+
|
|
|
|
+ // Among others, prevent a drag on a resizable-handle
|
|
|
|
+ if ( this.helper || o.disabled ||
|
|
|
|
+ $( event.target ).closest( ".ui-resizable-handle" ).length > 0 ) {
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ //Quit if we're not on a valid handle
|
|
|
|
+ this.handle = this._getHandle( event );
|
|
|
|
+ if ( !this.handle ) {
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ this._blurActiveElement( event );
|
|
|
|
+
|
|
|
|
+ this._blockFrames( o.iframeFix === true ? "iframe" : o.iframeFix );
|
|
|
|
+
|
|
|
|
+ return true;
|
|
|
|
+
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ _blockFrames: function( selector ) {
|
|
|
|
+ this.iframeBlocks = this.document.find( selector ).map( function() {
|
|
|
|
+ var iframe = $( this );
|
|
|
|
+
|
|
|
|
+ return $( "<div>" )
|
|
|
|
+ .css( "position", "absolute" )
|
|
|
|
+ .appendTo( iframe.parent() )
|
|
|
|
+ .outerWidth( iframe.outerWidth() )
|
|
|
|
+ .outerHeight( iframe.outerHeight() )
|
|
|
|
+ .offset( iframe.offset() )[ 0 ];
|
|
|
|
+ } );
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ _unblockFrames: function() {
|
|
|
|
+ if ( this.iframeBlocks ) {
|
|
|
|
+ this.iframeBlocks.remove();
|
|
|
|
+ delete this.iframeBlocks;
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ _blurActiveElement: function( event ) {
|
|
|
|
+ var activeElement = $.ui.safeActiveElement( this.document[ 0 ] ),
|
|
|
|
+ target = $( event.target );
|
|
|
|
+
|
|
|
|
+ // Don't blur if the event occurred on an element that is within
|
|
|
|
+ // the currently focused element
|
|
|
|
+ // See #10527, #12472
|
|
|
|
+ if ( target.closest( activeElement ).length ) {
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // Blur any element that currently has focus, see #4261
|
|
|
|
+ $.ui.safeBlur( activeElement );
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ _mouseStart: function( event ) {
|
|
|
|
+
|
|
|
|
+ var o = this.options;
|
|
|
|
+
|
|
|
|
+ //Create and append the visible helper
|
|
|
|
+ this.helper = this._createHelper( event );
|
|
|
|
+
|
|
|
|
+ this._addClass( this.helper, "ui-draggable-dragging" );
|
|
|
|
+
|
|
|
|
+ //Cache the helper size
|
|
|
|
+ this._cacheHelperProportions();
|
|
|
|
+
|
|
|
|
+ //If ddmanager is used for droppables, set the global draggable
|
|
|
|
+ if ( $.ui.ddmanager ) {
|
|
|
|
+ $.ui.ddmanager.current = this;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /*
|
|
|
|
+ * - Position generation -
|
|
|
|
+ * This block generates everything position related - it's the core of draggables.
|
|
|
|
+ */
|
|
|
|
+
|
|
|
|
+ //Cache the margins of the original element
|
|
|
|
+ this._cacheMargins();
|
|
|
|
+
|
|
|
|
+ //Store the helper's css position
|
|
|
|
+ this.cssPosition = this.helper.css( "position" );
|
|
|
|
+ this.scrollParent = this.helper.scrollParent( true );
|
|
|
|
+ this.offsetParent = this.helper.offsetParent();
|
|
|
|
+ this.hasFixedAncestor = this.helper.parents().filter( function() {
|
|
|
|
+ return $( this ).css( "position" ) === "fixed";
|
|
|
|
+ } ).length > 0;
|
|
|
|
+
|
|
|
|
+ //The element's absolute position on the page minus margins
|
|
|
|
+ this.positionAbs = this.element.offset();
|
|
|
|
+ this._refreshOffsets( event );
|
|
|
|
+
|
|
|
|
+ //Generate the original position
|
|
|
|
+ this.originalPosition = this.position = this._generatePosition( event, false );
|
|
|
|
+ this.originalPageX = event.pageX;
|
|
|
|
+ this.originalPageY = event.pageY;
|
|
|
|
+
|
|
|
|
+ //Adjust the mouse offset relative to the helper if "cursorAt" is supplied
|
|
|
|
+ ( o.cursorAt && this._adjustOffsetFromHelper( o.cursorAt ) );
|
|
|
|
+
|
|
|
|
+ //Set a containment if given in the options
|
|
|
|
+ this._setContainment();
|
|
|
|
+
|
|
|
|
+ //Trigger event + callbacks
|
|
|
|
+ if ( this._trigger( "start", event ) === false ) {
|
|
|
|
+ this._clear();
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ //Recache the helper size
|
|
|
|
+ this._cacheHelperProportions();
|
|
|
|
+
|
|
|
|
+ //Prepare the droppable offsets
|
|
|
|
+ if ( $.ui.ddmanager && !o.dropBehaviour ) {
|
|
|
|
+ $.ui.ddmanager.prepareOffsets( this, event );
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // Execute the drag once - this causes the helper not to be visible before getting its
|
|
|
|
+ // correct position
|
|
|
|
+ this._mouseDrag( event, true );
|
|
|
|
+
|
|
|
|
+ // If the ddmanager is used for droppables, inform the manager that dragging has started
|
|
|
|
+ // (see #5003)
|
|
|
|
+ if ( $.ui.ddmanager ) {
|
|
|
|
+ $.ui.ddmanager.dragStart( this, event );
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return true;
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ _refreshOffsets: function( event ) {
|
|
|
|
+ this.offset = {
|
|
|
|
+ top: this.positionAbs.top - this.margins.top,
|
|
|
|
+ left: this.positionAbs.left - this.margins.left,
|
|
|
|
+ scroll: false,
|
|
|
|
+ parent: this._getParentOffset(),
|
|
|
|
+ relative: this._getRelativeOffset()
|
|
|
|
+ };
|
|
|
|
+
|
|
|
|
+ this.offset.click = {
|
|
|
|
+ left: event.pageX - this.offset.left,
|
|
|
|
+ top: event.pageY - this.offset.top
|
|
|
|
+ };
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ _mouseDrag: function( event, noPropagation ) {
|
|
|
|
+
|
|
|
|
+ // reset any necessary cached properties (see #5009)
|
|
|
|
+ if ( this.hasFixedAncestor ) {
|
|
|
|
+ this.offset.parent = this._getParentOffset();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ //Compute the helpers position
|
|
|
|
+ this.position = this._generatePosition( event, true );
|
|
|
|
+ this.positionAbs = this._convertPositionTo( "absolute" );
|
|
|
|
+
|
|
|
|
+ //Call plugins and callbacks and use the resulting position if something is returned
|
|
|
|
+ if ( !noPropagation ) {
|
|
|
|
+ var ui = this._uiHash();
|
|
|
|
+ if ( this._trigger( "drag", event, ui ) === false ) {
|
|
|
|
+ this._mouseUp( new $.Event( "mouseup", event ) );
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+ this.position = ui.position;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ this.helper[ 0 ].style.left = this.position.left + "px";
|
|
|
|
+ this.helper[ 0 ].style.top = this.position.top + "px";
|
|
|
|
+
|
|
|
|
+ if ( $.ui.ddmanager ) {
|
|
|
|
+ $.ui.ddmanager.drag( this, event );
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return false;
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ _mouseStop: function( event ) {
|
|
|
|
+
|
|
|
|
+ //If we are using droppables, inform the manager about the drop
|
|
|
|
+ var that = this,
|
|
|
|
+ dropped = false;
|
|
|
|
+ if ( $.ui.ddmanager && !this.options.dropBehaviour ) {
|
|
|
|
+ dropped = $.ui.ddmanager.drop( this, event );
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ //if a drop comes from outside (a sortable)
|
|
|
|
+ if ( this.dropped ) {
|
|
|
|
+ dropped = this.dropped;
|
|
|
|
+ this.dropped = false;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if ( ( this.options.revert === "invalid" && !dropped ) ||
|
|
|
|
+ ( this.options.revert === "valid" && dropped ) ||
|
|
|
|
+ this.options.revert === true || ( $.isFunction( this.options.revert ) &&
|
|
|
|
+ this.options.revert.call( this.element, dropped ) )
|
|
|
|
+ ) {
|
|
|
|
+ $( this.helper ).animate(
|
|
|
|
+ this.originalPosition,
|
|
|
|
+ parseInt( this.options.revertDuration, 10 ),
|
|
|
|
+ function() {
|
|
|
|
+ if ( that._trigger( "stop", event ) !== false ) {
|
|
|
|
+ that._clear();
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ );
|
|
|
|
+ } else {
|
|
|
|
+ if ( this._trigger( "stop", event ) !== false ) {
|
|
|
|
+ this._clear();
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return false;
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ _mouseUp: function( event ) {
|
|
|
|
+ this._unblockFrames();
|
|
|
|
+
|
|
|
|
+ // If the ddmanager is used for droppables, inform the manager that dragging has stopped
|
|
|
|
+ // (see #5003)
|
|
|
|
+ if ( $.ui.ddmanager ) {
|
|
|
|
+ $.ui.ddmanager.dragStop( this, event );
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // Only need to focus if the event occurred on the draggable itself, see #10527
|
|
|
|
+ if ( this.handleElement.is( event.target ) ) {
|
|
|
|
+
|
|
|
|
+ // The interaction is over; whether or not the click resulted in a drag,
|
|
|
|
+ // focus the element
|
|
|
|
+ this.element.trigger( "focus" );
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return $.ui.mouse.prototype._mouseUp.call( this, event );
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ cancel: function() {
|
|
|
|
+
|
|
|
|
+ if ( this.helper.is( ".ui-draggable-dragging" ) ) {
|
|
|
|
+ this._mouseUp( new $.Event( "mouseup", { target: this.element[ 0 ] } ) );
|
|
|
|
+ } else {
|
|
|
|
+ this._clear();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return this;
|
|
|
|
+
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ _getHandle: function( event ) {
|
|
|
|
+ return this.options.handle ?
|
|
|
|
+ !!$( event.target ).closest( this.element.find( this.options.handle ) ).length :
|
|
|
|
+ true;
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ _setHandleClassName: function() {
|
|
|
|
+ this.handleElement = this.options.handle ?
|
|
|
|
+ this.element.find( this.options.handle ) : this.element;
|
|
|
|
+ this._addClass( this.handleElement, "ui-draggable-handle" );
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ _removeHandleClassName: function() {
|
|
|
|
+ this._removeClass( this.handleElement, "ui-draggable-handle" );
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ _createHelper: function( event ) {
|
|
|
|
+
|
|
|
|
+ var o = this.options,
|
|
|
|
+ helperIsFunction = $.isFunction( o.helper ),
|
|
|
|
+ helper = helperIsFunction ?
|
|
|
|
+ $( o.helper.apply( this.element[ 0 ], [ event ] ) ) :
|
|
|
|
+ ( o.helper === "clone" ?
|
|
|
|
+ this.element.clone().removeAttr( "id" ) :
|
|
|
|
+ this.element );
|
|
|
|
+
|
|
|
|
+ if ( !helper.parents( "body" ).length ) {
|
|
|
|
+ helper.appendTo( ( o.appendTo === "parent" ?
|
|
|
|
+ this.element[ 0 ].parentNode :
|
|
|
|
+ o.appendTo ) );
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // Http://bugs.jqueryui.com/ticket/9446
|
|
|
|
+ // a helper function can return the original element
|
|
|
|
+ // which wouldn't have been set to relative in _create
|
|
|
|
+ if ( helperIsFunction && helper[ 0 ] === this.element[ 0 ] ) {
|
|
|
|
+ this._setPositionRelative();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if ( helper[ 0 ] !== this.element[ 0 ] &&
|
|
|
|
+ !( /(fixed|absolute)/ ).test( helper.css( "position" ) ) ) {
|
|
|
|
+ helper.css( "position", "absolute" );
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return helper;
|
|
|
|
+
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ _setPositionRelative: function() {
|
|
|
|
+ if ( !( /^(?:r|a|f)/ ).test( this.element.css( "position" ) ) ) {
|
|
|
|
+ this.element[ 0 ].style.position = "relative";
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ _adjustOffsetFromHelper: function( obj ) {
|
|
|
|
+ if ( typeof obj === "string" ) {
|
|
|
|
+ obj = obj.split( " " );
|
|
|
|
+ }
|
|
|
|
+ if ( $.isArray( obj ) ) {
|
|
|
|
+ obj = { left: +obj[ 0 ], top: +obj[ 1 ] || 0 };
|
|
|
|
+ }
|
|
|
|
+ if ( "left" in obj ) {
|
|
|
|
+ this.offset.click.left = obj.left + this.margins.left;
|
|
|
|
+ }
|
|
|
|
+ if ( "right" in obj ) {
|
|
|
|
+ this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
|
|
|
|
+ }
|
|
|
|
+ if ( "top" in obj ) {
|
|
|
|
+ this.offset.click.top = obj.top + this.margins.top;
|
|
|
|
+ }
|
|
|
|
+ if ( "bottom" in obj ) {
|
|
|
|
+ this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ _isRootNode: function( element ) {
|
|
|
|
+ return ( /(html|body)/i ).test( element.tagName ) || element === this.document[ 0 ];
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ _getParentOffset: function() {
|
|
|
|
+
|
|
|
|
+ //Get the offsetParent and cache its position
|
|
|
|
+ var po = this.offsetParent.offset(),
|
|
|
|
+ document = this.document[ 0 ];
|
|
|
|
+
|
|
|
|
+ // This is a special case where we need to modify a offset calculated on start, since the
|
|
|
|
+ // following happened:
|
|
|
|
+ // 1. The position of the helper is absolute, so it's position is calculated based on the
|
|
|
|
+ // next positioned parent
|
|
|
|
+ // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't
|
|
|
|
+ // the document, which means that the scroll is included in the initial calculation of the
|
|
|
|
+ // offset of the parent, and never recalculated upon drag
|
|
|
|
+ if ( this.cssPosition === "absolute" && this.scrollParent[ 0 ] !== document &&
|
|
|
|
+ $.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) {
|
|
|
|
+ po.left += this.scrollParent.scrollLeft();
|
|
|
|
+ po.top += this.scrollParent.scrollTop();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if ( this._isRootNode( this.offsetParent[ 0 ] ) ) {
|
|
|
|
+ po = { top: 0, left: 0 };
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return {
|
|
|
|
+ top: po.top + ( parseInt( this.offsetParent.css( "borderTopWidth" ), 10 ) || 0 ),
|
|
|
|
+ left: po.left + ( parseInt( this.offsetParent.css( "borderLeftWidth" ), 10 ) || 0 )
|
|
|
|
+ };
|
|
|
|
+
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ _getRelativeOffset: function() {
|
|
|
|
+ if ( this.cssPosition !== "relative" ) {
|
|
|
|
+ return { top: 0, left: 0 };
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ var p = this.element.position(),
|
|
|
|
+ scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] );
|
|
|
|
+
|
|
|
|
+ return {
|
|
|
|
+ top: p.top - ( parseInt( this.helper.css( "top" ), 10 ) || 0 ) +
|
|
|
|
+ ( !scrollIsRootNode ? this.scrollParent.scrollTop() : 0 ),
|
|
|
|
+ left: p.left - ( parseInt( this.helper.css( "left" ), 10 ) || 0 ) +
|
|
|
|
+ ( !scrollIsRootNode ? this.scrollParent.scrollLeft() : 0 )
|
|
|
|
+ };
|
|
|
|
+
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ _cacheMargins: function() {
|
|
|
|
+ this.margins = {
|
|
|
|
+ left: ( parseInt( this.element.css( "marginLeft" ), 10 ) || 0 ),
|
|
|
|
+ top: ( parseInt( this.element.css( "marginTop" ), 10 ) || 0 ),
|
|
|
|
+ right: ( parseInt( this.element.css( "marginRight" ), 10 ) || 0 ),
|
|
|
|
+ bottom: ( parseInt( this.element.css( "marginBottom" ), 10 ) || 0 )
|
|
|
|
+ };
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ _cacheHelperProportions: function() {
|
|
|
|
+ this.helperProportions = {
|
|
|
|
+ width: this.helper.outerWidth(),
|
|
|
|
+ height: this.helper.outerHeight()
|
|
|
|
+ };
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ _setContainment: function() {
|
|
|
|
+
|
|
|
|
+ var isUserScrollable, c, ce,
|
|
|
|
+ o = this.options,
|
|
|
|
+ document = this.document[ 0 ];
|
|
|
|
+
|
|
|
|
+ this.relativeContainer = null;
|
|
|
|
+
|
|
|
|
+ if ( !o.containment ) {
|
|
|
|
+ this.containment = null;
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if ( o.containment === "window" ) {
|
|
|
|
+ this.containment = [
|
|
|
|
+ $( window ).scrollLeft() - this.offset.relative.left - this.offset.parent.left,
|
|
|
|
+ $( window ).scrollTop() - this.offset.relative.top - this.offset.parent.top,
|
|
|
|
+ $( window ).scrollLeft() + $( window ).width() -
|
|
|
|
+ this.helperProportions.width - this.margins.left,
|
|
|
|
+ $( window ).scrollTop() +
|
|
|
|
+ ( $( window ).height() || document.body.parentNode.scrollHeight ) -
|
|
|
|
+ this.helperProportions.height - this.margins.top
|
|
|
|
+ ];
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if ( o.containment === "document" ) {
|
|
|
|
+ this.containment = [
|
|
|
|
+ 0,
|
|
|
|
+ 0,
|
|
|
|
+ $( document ).width() - this.helperProportions.width - this.margins.left,
|
|
|
|
+ ( $( document ).height() || document.body.parentNode.scrollHeight ) -
|
|
|
|
+ this.helperProportions.height - this.margins.top
|
|
|
|
+ ];
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if ( o.containment.constructor === Array ) {
|
|
|
|
+ this.containment = o.containment;
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if ( o.containment === "parent" ) {
|
|
|
|
+ o.containment = this.helper[ 0 ].parentNode;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ c = $( o.containment );
|
|
|
|
+ ce = c[ 0 ];
|
|
|
|
+
|
|
|
|
+ if ( !ce ) {
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ isUserScrollable = /(scroll|auto)/.test( c.css( "overflow" ) );
|
|
|
|
+
|
|
|
|
+ this.containment = [
|
|
|
|
+ ( parseInt( c.css( "borderLeftWidth" ), 10 ) || 0 ) +
|
|
|
|
+ ( parseInt( c.css( "paddingLeft" ), 10 ) || 0 ),
|
|
|
|
+ ( parseInt( c.css( "borderTopWidth" ), 10 ) || 0 ) +
|
|
|
|
+ ( parseInt( c.css( "paddingTop" ), 10 ) || 0 ),
|
|
|
|
+ ( isUserScrollable ? Math.max( ce.scrollWidth, ce.offsetWidth ) : ce.offsetWidth ) -
|
|
|
|
+ ( parseInt( c.css( "borderRightWidth" ), 10 ) || 0 ) -
|
|
|
|
+ ( parseInt( c.css( "paddingRight" ), 10 ) || 0 ) -
|
|
|
|
+ this.helperProportions.width -
|
|
|
|
+ this.margins.left -
|
|
|
|
+ this.margins.right,
|
|
|
|
+ ( isUserScrollable ? Math.max( ce.scrollHeight, ce.offsetHeight ) : ce.offsetHeight ) -
|
|
|
|
+ ( parseInt( c.css( "borderBottomWidth" ), 10 ) || 0 ) -
|
|
|
|
+ ( parseInt( c.css( "paddingBottom" ), 10 ) || 0 ) -
|
|
|
|
+ this.helperProportions.height -
|
|
|
|
+ this.margins.top -
|
|
|
|
+ this.margins.bottom
|
|
|
|
+ ];
|
|
|
|
+ this.relativeContainer = c;
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ _convertPositionTo: function( d, pos ) {
|
|
|
|
+
|
|
|
|
+ if ( !pos ) {
|
|
|
|
+ pos = this.position;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ var mod = d === "absolute" ? 1 : -1,
|
|
|
|
+ scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] );
|
|
|
|
+
|
|
|
|
+ return {
|
|
|
|
+ top: (
|
|
|
|
+
|
|
|
|
+ // The absolute mouse position
|
|
|
|
+ pos.top +
|
|
|
|
+
|
|
|
|
+ // Only for relative positioned nodes: Relative offset from element to offset parent
|
|
|
|
+ this.offset.relative.top * mod +
|
|
|
|
+
|
|
|
|
+ // The offsetParent's offset without borders (offset + border)
|
|
|
|
+ this.offset.parent.top * mod -
|
|
|
|
+ ( ( this.cssPosition === "fixed" ?
|
|
|
|
+ -this.offset.scroll.top :
|
|
|
|
+ ( scrollIsRootNode ? 0 : this.offset.scroll.top ) ) * mod )
|
|
|
|
+ ),
|
|
|
|
+ left: (
|
|
|
|
+
|
|
|
|
+ // The absolute mouse position
|
|
|
|
+ pos.left +
|
|
|
|
+
|
|
|
|
+ // Only for relative positioned nodes: Relative offset from element to offset parent
|
|
|
|
+ this.offset.relative.left * mod +
|
|
|
|
+
|
|
|
|
+ // The offsetParent's offset without borders (offset + border)
|
|
|
|
+ this.offset.parent.left * mod -
|
|
|
|
+ ( ( this.cssPosition === "fixed" ?
|
|
|
|
+ -this.offset.scroll.left :
|
|
|
|
+ ( scrollIsRootNode ? 0 : this.offset.scroll.left ) ) * mod )
|
|
|
|
+ )
|
|
|
|
+ };
|
|
|
|
+
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ _generatePosition: function( event, constrainPosition ) {
|
|
|
|
+
|
|
|
|
+ var containment, co, top, left,
|
|
|
|
+ o = this.options,
|
|
|
|
+ scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] ),
|
|
|
|
+ pageX = event.pageX,
|
|
|
|
+ pageY = event.pageY;
|
|
|
|
+
|
|
|
|
+ // Cache the scroll
|
|
|
|
+ if ( !scrollIsRootNode || !this.offset.scroll ) {
|
|
|
|
+ this.offset.scroll = {
|
|
|
|
+ top: this.scrollParent.scrollTop(),
|
|
|
|
+ left: this.scrollParent.scrollLeft()
|
|
|
|
+ };
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /*
|
|
|
|
+ * - Position constraining -
|
|
|
|
+ * Constrain the position to a mix of grid, containment.
|
|
|
|
+ */
|
|
|
|
+
|
|
|
|
+ // If we are not dragging yet, we won't check for options
|
|
|
|
+ if ( constrainPosition ) {
|
|
|
|
+ if ( this.containment ) {
|
|
|
|
+ if ( this.relativeContainer ) {
|
|
|
|
+ co = this.relativeContainer.offset();
|
|
|
|
+ containment = [
|
|
|
|
+ this.containment[ 0 ] + co.left,
|
|
|
|
+ this.containment[ 1 ] + co.top,
|
|
|
|
+ this.containment[ 2 ] + co.left,
|
|
|
|
+ this.containment[ 3 ] + co.top
|
|
|
|
+ ];
|
|
|
|
+ } else {
|
|
|
|
+ containment = this.containment;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if ( event.pageX - this.offset.click.left < containment[ 0 ] ) {
|
|
|
|
+ pageX = containment[ 0 ] + this.offset.click.left;
|
|
|
|
+ }
|
|
|
|
+ if ( event.pageY - this.offset.click.top < containment[ 1 ] ) {
|
|
|
|
+ pageY = containment[ 1 ] + this.offset.click.top;
|
|
|
|
+ }
|
|
|
|
+ if ( event.pageX - this.offset.click.left > containment[ 2 ] ) {
|
|
|
|
+ pageX = containment[ 2 ] + this.offset.click.left;
|
|
|
|
+ }
|
|
|
|
+ if ( event.pageY - this.offset.click.top > containment[ 3 ] ) {
|
|
|
|
+ pageY = containment[ 3 ] + this.offset.click.top;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if ( o.grid ) {
|
|
|
|
+
|
|
|
|
+ //Check for grid elements set to 0 to prevent divide by 0 error causing invalid
|
|
|
|
+ // argument errors in IE (see ticket #6950)
|
|
|
|
+ top = o.grid[ 1 ] ? this.originalPageY + Math.round( ( pageY -
|
|
|
|
+ this.originalPageY ) / o.grid[ 1 ] ) * o.grid[ 1 ] : this.originalPageY;
|
|
|
|
+ pageY = containment ? ( ( top - this.offset.click.top >= containment[ 1 ] ||
|
|
|
|
+ top - this.offset.click.top > containment[ 3 ] ) ?
|
|
|
|
+ top :
|
|
|
|
+ ( ( top - this.offset.click.top >= containment[ 1 ] ) ?
|
|
|
|
+ top - o.grid[ 1 ] : top + o.grid[ 1 ] ) ) : top;
|
|
|
|
+
|
|
|
|
+ left = o.grid[ 0 ] ? this.originalPageX +
|
|
|
|
+ Math.round( ( pageX - this.originalPageX ) / o.grid[ 0 ] ) * o.grid[ 0 ] :
|
|
|
|
+ this.originalPageX;
|
|
|
|
+ pageX = containment ? ( ( left - this.offset.click.left >= containment[ 0 ] ||
|
|
|
|
+ left - this.offset.click.left > containment[ 2 ] ) ?
|
|
|
|
+ left :
|
|
|
|
+ ( ( left - this.offset.click.left >= containment[ 0 ] ) ?
|
|
|
|
+ left - o.grid[ 0 ] : left + o.grid[ 0 ] ) ) : left;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if ( o.axis === "y" ) {
|
|
|
|
+ pageX = this.originalPageX;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if ( o.axis === "x" ) {
|
|
|
|
+ pageY = this.originalPageY;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return {
|
|
|
|
+ top: (
|
|
|
|
+
|
|
|
|
+ // The absolute mouse position
|
|
|
|
+ pageY -
|
|
|
|
+
|
|
|
|
+ // Click offset (relative to the element)
|
|
|
|
+ this.offset.click.top -
|
|
|
|
+
|
|
|
|
+ // Only for relative positioned nodes: Relative offset from element to offset parent
|
|
|
|
+ this.offset.relative.top -
|
|
|
|
+
|
|
|
|
+ // The offsetParent's offset without borders (offset + border)
|
|
|
|
+ this.offset.parent.top +
|
|
|
|
+ ( this.cssPosition === "fixed" ?
|
|
|
|
+ -this.offset.scroll.top :
|
|
|
|
+ ( scrollIsRootNode ? 0 : this.offset.scroll.top ) )
|
|
|
|
+ ),
|
|
|
|
+ left: (
|
|
|
|
+
|
|
|
|
+ // The absolute mouse position
|
|
|
|
+ pageX -
|
|
|
|
+
|
|
|
|
+ // Click offset (relative to the element)
|
|
|
|
+ this.offset.click.left -
|
|
|
|
+
|
|
|
|
+ // Only for relative positioned nodes: Relative offset from element to offset parent
|
|
|
|
+ this.offset.relative.left -
|
|
|
|
+
|
|
|
|
+ // The offsetParent's offset without borders (offset + border)
|
|
|
|
+ this.offset.parent.left +
|
|
|
|
+ ( this.cssPosition === "fixed" ?
|
|
|
|
+ -this.offset.scroll.left :
|
|
|
|
+ ( scrollIsRootNode ? 0 : this.offset.scroll.left ) )
|
|
|
|
+ )
|
|
|
|
+ };
|
|
|
|
+
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ _clear: function() {
|
|
|
|
+ this._removeClass( this.helper, "ui-draggable-dragging" );
|
|
|
|
+ if ( this.helper[ 0 ] !== this.element[ 0 ] && !this.cancelHelperRemoval ) {
|
|
|
|
+ this.helper.remove();
|
|
|
|
+ }
|
|
|
|
+ this.helper = null;
|
|
|
|
+ this.cancelHelperRemoval = false;
|
|
|
|
+ if ( this.destroyOnClear ) {
|
|
|
|
+ this.destroy();
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ // From now on bulk stuff - mainly helpers
|
|
|
|
+
|
|
|
|
+ _trigger: function( type, event, ui ) {
|
|
|
|
+ ui = ui || this._uiHash();
|
|
|
|
+ $.ui.plugin.call( this, type, [ event, ui, this ], true );
|
|
|
|
+
|
|
|
|
+ // Absolute position and offset (see #6884 ) have to be recalculated after plugins
|
|
|
|
+ if ( /^(drag|start|stop)/.test( type ) ) {
|
|
|
|
+ this.positionAbs = this._convertPositionTo( "absolute" );
|
|
|
|
+ ui.offset = this.positionAbs;
|
|
|
|
+ }
|
|
|
|
+ return $.Widget.prototype._trigger.call( this, type, event, ui );
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ plugins: {},
|
|
|
|
+
|
|
|
|
+ _uiHash: function() {
|
|
|
|
+ return {
|
|
|
|
+ helper: this.helper,
|
|
|
|
+ position: this.position,
|
|
|
|
+ originalPosition: this.originalPosition,
|
|
|
|
+ offset: this.positionAbs
|
|
|
|
+ };
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+} );
|
|
|
|
+
|
|
|
|
+$.ui.plugin.add( "draggable", "connectToSortable", {
|
|
|
|
+ start: function( event, ui, draggable ) {
|
|
|
|
+ var uiSortable = $.extend( {}, ui, {
|
|
|
|
+ item: draggable.element
|
|
|
|
+ } );
|
|
|
|
+
|
|
|
|
+ draggable.sortables = [];
|
|
|
|
+ $( draggable.options.connectToSortable ).each( function() {
|
|
|
|
+ var sortable = $( this ).sortable( "instance" );
|
|
|
|
+
|
|
|
|
+ if ( sortable && !sortable.options.disabled ) {
|
|
|
|
+ draggable.sortables.push( sortable );
|
|
|
|
+
|
|
|
|
+ // RefreshPositions is called at drag start to refresh the containerCache
|
|
|
|
+ // which is used in drag. This ensures it's initialized and synchronized
|
|
|
|
+ // with any changes that might have happened on the page since initialization.
|
|
|
|
+ sortable.refreshPositions();
|
|
|
|
+ sortable._trigger( "activate", event, uiSortable );
|
|
|
|
+ }
|
|
|
|
+ } );
|
|
|
|
+ },
|
|
|
|
+ stop: function( event, ui, draggable ) {
|
|
|
|
+ var uiSortable = $.extend( {}, ui, {
|
|
|
|
+ item: draggable.element
|
|
|
|
+ } );
|
|
|
|
+
|
|
|
|
+ draggable.cancelHelperRemoval = false;
|
|
|
|
+
|
|
|
|
+ $.each( draggable.sortables, function() {
|
|
|
|
+ var sortable = this;
|
|
|
|
+
|
|
|
|
+ if ( sortable.isOver ) {
|
|
|
|
+ sortable.isOver = 0;
|
|
|
|
+
|
|
|
|
+ // Allow this sortable to handle removing the helper
|
|
|
|
+ draggable.cancelHelperRemoval = true;
|
|
|
|
+ sortable.cancelHelperRemoval = false;
|
|
|
|
+
|
|
|
|
+ // Use _storedCSS To restore properties in the sortable,
|
|
|
|
+ // as this also handles revert (#9675) since the draggable
|
|
|
|
+ // may have modified them in unexpected ways (#8809)
|
|
|
|
+ sortable._storedCSS = {
|
|
|
|
+ position: sortable.placeholder.css( "position" ),
|
|
|
|
+ top: sortable.placeholder.css( "top" ),
|
|
|
|
+ left: sortable.placeholder.css( "left" )
|
|
|
|
+ };
|
|
|
|
+
|
|
|
|
+ sortable._mouseStop( event );
|
|
|
|
+
|
|
|
|
+ // Once drag has ended, the sortable should return to using
|
|
|
|
+ // its original helper, not the shared helper from draggable
|
|
|
|
+ sortable.options.helper = sortable.options._helper;
|
|
|
|
+ } else {
|
|
|
|
+
|
|
|
|
+ // Prevent this Sortable from removing the helper.
|
|
|
|
+ // However, don't set the draggable to remove the helper
|
|
|
|
+ // either as another connected Sortable may yet handle the removal.
|
|
|
|
+ sortable.cancelHelperRemoval = true;
|
|
|
|
+
|
|
|
|
+ sortable._trigger( "deactivate", event, uiSortable );
|
|
|
|
+ }
|
|
|
|
+ } );
|
|
|
|
+ },
|
|
|
|
+ drag: function( event, ui, draggable ) {
|
|
|
|
+ $.each( draggable.sortables, function() {
|
|
|
|
+ var innermostIntersecting = false,
|
|
|
|
+ sortable = this;
|
|
|
|
+
|
|
|
|
+ // Copy over variables that sortable's _intersectsWith uses
|
|
|
|
+ sortable.positionAbs = draggable.positionAbs;
|
|
|
|
+ sortable.helperProportions = draggable.helperProportions;
|
|
|
|
+ sortable.offset.click = draggable.offset.click;
|
|
|
|
+
|
|
|
|
+ if ( sortable._intersectsWith( sortable.containerCache ) ) {
|
|
|
|
+ innermostIntersecting = true;
|
|
|
|
+
|
|
|
|
+ $.each( draggable.sortables, function() {
|
|
|
|
+
|
|
|
|
+ // Copy over variables that sortable's _intersectsWith uses
|
|
|
|
+ this.positionAbs = draggable.positionAbs;
|
|
|
|
+ this.helperProportions = draggable.helperProportions;
|
|
|
|
+ this.offset.click = draggable.offset.click;
|
|
|
|
+
|
|
|
|
+ if ( this !== sortable &&
|
|
|
|
+ this._intersectsWith( this.containerCache ) &&
|
|
|
|
+ $.contains( sortable.element[ 0 ], this.element[ 0 ] ) ) {
|
|
|
|
+ innermostIntersecting = false;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return innermostIntersecting;
|
|
|
|
+ } );
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if ( innermostIntersecting ) {
|
|
|
|
+
|
|
|
|
+ // If it intersects, we use a little isOver variable and set it once,
|
|
|
|
+ // so that the move-in stuff gets fired only once.
|
|
|
|
+ if ( !sortable.isOver ) {
|
|
|
|
+ sortable.isOver = 1;
|
|
|
|
+
|
|
|
|
+ // Store draggable's parent in case we need to reappend to it later.
|
|
|
|
+ draggable._parent = ui.helper.parent();
|
|
|
|
+
|
|
|
|
+ sortable.currentItem = ui.helper
|
|
|
|
+ .appendTo( sortable.element )
|
|
|
|
+ .data( "ui-sortable-item", true );
|
|
|
|
+
|
|
|
|
+ // Store helper option to later restore it
|
|
|
|
+ sortable.options._helper = sortable.options.helper;
|
|
|
|
+
|
|
|
|
+ sortable.options.helper = function() {
|
|
|
|
+ return ui.helper[ 0 ];
|
|
|
|
+ };
|
|
|
|
+
|
|
|
|
+ // Fire the start events of the sortable with our passed browser event,
|
|
|
|
+ // and our own helper (so it doesn't create a new one)
|
|
|
|
+ event.target = sortable.currentItem[ 0 ];
|
|
|
|
+ sortable._mouseCapture( event, true );
|
|
|
|
+ sortable._mouseStart( event, true, true );
|
|
|
|
+
|
|
|
|
+ // Because the browser event is way off the new appended portlet,
|
|
|
|
+ // modify necessary variables to reflect the changes
|
|
|
|
+ sortable.offset.click.top = draggable.offset.click.top;
|
|
|
|
+ sortable.offset.click.left = draggable.offset.click.left;
|
|
|
|
+ sortable.offset.parent.left -= draggable.offset.parent.left -
|
|
|
|
+ sortable.offset.parent.left;
|
|
|
|
+ sortable.offset.parent.top -= draggable.offset.parent.top -
|
|
|
|
+ sortable.offset.parent.top;
|
|
|
|
+
|
|
|
|
+ draggable._trigger( "toSortable", event );
|
|
|
|
+
|
|
|
|
+ // Inform draggable that the helper is in a valid drop zone,
|
|
|
|
+ // used solely in the revert option to handle "valid/invalid".
|
|
|
|
+ draggable.dropped = sortable.element;
|
|
|
|
+
|
|
|
|
+ // Need to refreshPositions of all sortables in the case that
|
|
|
|
+ // adding to one sortable changes the location of the other sortables (#9675)
|
|
|
|
+ $.each( draggable.sortables, function() {
|
|
|
|
+ this.refreshPositions();
|
|
|
|
+ } );
|
|
|
|
+
|
|
|
|
+ // Hack so receive/update callbacks work (mostly)
|
|
|
|
+ draggable.currentItem = draggable.element;
|
|
|
|
+ sortable.fromOutside = draggable;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if ( sortable.currentItem ) {
|
|
|
|
+ sortable._mouseDrag( event );
|
|
|
|
+
|
|
|
|
+ // Copy the sortable's position because the draggable's can potentially reflect
|
|
|
|
+ // a relative position, while sortable is always absolute, which the dragged
|
|
|
|
+ // element has now become. (#8809)
|
|
|
|
+ ui.position = sortable.position;
|
|
|
|
+ }
|
|
|
|
+ } else {
|
|
|
|
+
|
|
|
|
+ // If it doesn't intersect with the sortable, and it intersected before,
|
|
|
|
+ // we fake the drag stop of the sortable, but make sure it doesn't remove
|
|
|
|
+ // the helper by using cancelHelperRemoval.
|
|
|
|
+ if ( sortable.isOver ) {
|
|
|
|
+
|
|
|
|
+ sortable.isOver = 0;
|
|
|
|
+ sortable.cancelHelperRemoval = true;
|
|
|
|
+
|
|
|
|
+ // Calling sortable's mouseStop would trigger a revert,
|
|
|
|
+ // so revert must be temporarily false until after mouseStop is called.
|
|
|
|
+ sortable.options._revert = sortable.options.revert;
|
|
|
|
+ sortable.options.revert = false;
|
|
|
|
+
|
|
|
|
+ sortable._trigger( "out", event, sortable._uiHash( sortable ) );
|
|
|
|
+ sortable._mouseStop( event, true );
|
|
|
|
+
|
|
|
|
+ // Restore sortable behaviors that were modfied
|
|
|
|
+ // when the draggable entered the sortable area (#9481)
|
|
|
|
+ sortable.options.revert = sortable.options._revert;
|
|
|
|
+ sortable.options.helper = sortable.options._helper;
|
|
|
|
+
|
|
|
|
+ if ( sortable.placeholder ) {
|
|
|
|
+ sortable.placeholder.remove();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // Restore and recalculate the draggable's offset considering the sortable
|
|
|
|
+ // may have modified them in unexpected ways. (#8809, #10669)
|
|
|
|
+ ui.helper.appendTo( draggable._parent );
|
|
|
|
+ draggable._refreshOffsets( event );
|
|
|
|
+ ui.position = draggable._generatePosition( event, true );
|
|
|
|
+
|
|
|
|
+ draggable._trigger( "fromSortable", event );
|
|
|
|
+
|
|
|
|
+ // Inform draggable that the helper is no longer in a valid drop zone
|
|
|
|
+ draggable.dropped = false;
|
|
|
|
+
|
|
|
|
+ // Need to refreshPositions of all sortables just in case removing
|
|
|
|
+ // from one sortable changes the location of other sortables (#9675)
|
|
|
|
+ $.each( draggable.sortables, function() {
|
|
|
|
+ this.refreshPositions();
|
|
|
|
+ } );
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ } );
|
|
|
|
+ }
|
|
|
|
+} );
|
|
|
|
+
|
|
|
|
+$.ui.plugin.add( "draggable", "cursor", {
|
|
|
|
+ start: function( event, ui, instance ) {
|
|
|
|
+ var t = $( "body" ),
|
|
|
|
+ o = instance.options;
|
|
|
|
+
|
|
|
|
+ if ( t.css( "cursor" ) ) {
|
|
|
|
+ o._cursor = t.css( "cursor" );
|
|
|
|
+ }
|
|
|
|
+ t.css( "cursor", o.cursor );
|
|
|
|
+ },
|
|
|
|
+ stop: function( event, ui, instance ) {
|
|
|
|
+ var o = instance.options;
|
|
|
|
+ if ( o._cursor ) {
|
|
|
|
+ $( "body" ).css( "cursor", o._cursor );
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+} );
|
|
|
|
+
|
|
|
|
+$.ui.plugin.add( "draggable", "opacity", {
|
|
|
|
+ start: function( event, ui, instance ) {
|
|
|
|
+ var t = $( ui.helper ),
|
|
|
|
+ o = instance.options;
|
|
|
|
+ if ( t.css( "opacity" ) ) {
|
|
|
|
+ o._opacity = t.css( "opacity" );
|
|
|
|
+ }
|
|
|
|
+ t.css( "opacity", o.opacity );
|
|
|
|
+ },
|
|
|
|
+ stop: function( event, ui, instance ) {
|
|
|
|
+ var o = instance.options;
|
|
|
|
+ if ( o._opacity ) {
|
|
|
|
+ $( ui.helper ).css( "opacity", o._opacity );
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+} );
|
|
|
|
+
|
|
|
|
+$.ui.plugin.add( "draggable", "scroll", {
|
|
|
|
+ start: function( event, ui, i ) {
|
|
|
|
+ if ( !i.scrollParentNotHidden ) {
|
|
|
|
+ i.scrollParentNotHidden = i.helper.scrollParent( false );
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if ( i.scrollParentNotHidden[ 0 ] !== i.document[ 0 ] &&
|
|
|
|
+ i.scrollParentNotHidden[ 0 ].tagName !== "HTML" ) {
|
|
|
|
+ i.overflowOffset = i.scrollParentNotHidden.offset();
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+ drag: function( event, ui, i ) {
|
|
|
|
+
|
|
|
|
+ var o = i.options,
|
|
|
|
+ scrolled = false,
|
|
|
|
+ scrollParent = i.scrollParentNotHidden[ 0 ],
|
|
|
|
+ document = i.document[ 0 ];
|
|
|
|
+
|
|
|
|
+ if ( scrollParent !== document && scrollParent.tagName !== "HTML" ) {
|
|
|
|
+ if ( !o.axis || o.axis !== "x" ) {
|
|
|
|
+ if ( ( i.overflowOffset.top + scrollParent.offsetHeight ) - event.pageY <
|
|
|
|
+ o.scrollSensitivity ) {
|
|
|
|
+ scrollParent.scrollTop = scrolled = scrollParent.scrollTop + o.scrollSpeed;
|
|
|
|
+ } else if ( event.pageY - i.overflowOffset.top < o.scrollSensitivity ) {
|
|
|
|
+ scrollParent.scrollTop = scrolled = scrollParent.scrollTop - o.scrollSpeed;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if ( !o.axis || o.axis !== "y" ) {
|
|
|
|
+ if ( ( i.overflowOffset.left + scrollParent.offsetWidth ) - event.pageX <
|
|
|
|
+ o.scrollSensitivity ) {
|
|
|
|
+ scrollParent.scrollLeft = scrolled = scrollParent.scrollLeft + o.scrollSpeed;
|
|
|
|
+ } else if ( event.pageX - i.overflowOffset.left < o.scrollSensitivity ) {
|
|
|
|
+ scrollParent.scrollLeft = scrolled = scrollParent.scrollLeft - o.scrollSpeed;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ } else {
|
|
|
|
+
|
|
|
|
+ if ( !o.axis || o.axis !== "x" ) {
|
|
|
|
+ if ( event.pageY - $( document ).scrollTop() < o.scrollSensitivity ) {
|
|
|
|
+ scrolled = $( document ).scrollTop( $( document ).scrollTop() - o.scrollSpeed );
|
|
|
|
+ } else if ( $( window ).height() - ( event.pageY - $( document ).scrollTop() ) <
|
|
|
|
+ o.scrollSensitivity ) {
|
|
|
|
+ scrolled = $( document ).scrollTop( $( document ).scrollTop() + o.scrollSpeed );
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if ( !o.axis || o.axis !== "y" ) {
|
|
|
|
+ if ( event.pageX - $( document ).scrollLeft() < o.scrollSensitivity ) {
|
|
|
|
+ scrolled = $( document ).scrollLeft(
|
|
|
|
+ $( document ).scrollLeft() - o.scrollSpeed
|
|
|
|
+ );
|
|
|
|
+ } else if ( $( window ).width() - ( event.pageX - $( document ).scrollLeft() ) <
|
|
|
|
+ o.scrollSensitivity ) {
|
|
|
|
+ scrolled = $( document ).scrollLeft(
|
|
|
|
+ $( document ).scrollLeft() + o.scrollSpeed
|
|
|
|
+ );
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if ( scrolled !== false && $.ui.ddmanager && !o.dropBehaviour ) {
|
|
|
|
+ $.ui.ddmanager.prepareOffsets( i, event );
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+} );
|
|
|
|
+
|
|
|
|
+$.ui.plugin.add( "draggable", "snap", {
|
|
|
|
+ start: function( event, ui, i ) {
|
|
|
|
+
|
|
|
|
+ var o = i.options;
|
|
|
|
+
|
|
|
|
+ i.snapElements = [];
|
|
|
|
+
|
|
|
|
+ $( o.snap.constructor !== String ? ( o.snap.items || ":data(ui-draggable)" ) : o.snap )
|
|
|
|
+ .each( function() {
|
|
|
|
+ var $t = $( this ),
|
|
|
|
+ $o = $t.offset();
|
|
|
|
+ if ( this !== i.element[ 0 ] ) {
|
|
|
|
+ i.snapElements.push( {
|
|
|
|
+ item: this,
|
|
|
|
+ width: $t.outerWidth(), height: $t.outerHeight(),
|
|
|
|
+ top: $o.top, left: $o.left
|
|
|
|
+ } );
|
|
|
|
+ }
|
|
|
|
+ } );
|
|
|
|
+
|
|
|
|
+ },
|
|
|
|
+ drag: function( event, ui, inst ) {
|
|
|
|
+
|
|
|
|
+ var ts, bs, ls, rs, l, r, t, b, i, first,
|
|
|
|
+ o = inst.options,
|
|
|
|
+ d = o.snapTolerance,
|
|
|
|
+ x1 = ui.offset.left, x2 = x1 + inst.helperProportions.width,
|
|
|
|
+ y1 = ui.offset.top, y2 = y1 + inst.helperProportions.height;
|
|
|
|
+
|
|
|
|
+ for ( i = inst.snapElements.length - 1; i >= 0; i-- ) {
|
|
|
|
+
|
|
|
|
+ l = inst.snapElements[ i ].left - inst.margins.left;
|
|
|
|
+ r = l + inst.snapElements[ i ].width;
|
|
|
|
+ t = inst.snapElements[ i ].top - inst.margins.top;
|
|
|
|
+ b = t + inst.snapElements[ i ].height;
|
|
|
|
+
|
|
|
|
+ if ( x2 < l - d || x1 > r + d || y2 < t - d || y1 > b + d ||
|
|
|
|
+ !$.contains( inst.snapElements[ i ].item.ownerDocument,
|
|
|
|
+ inst.snapElements[ i ].item ) ) {
|
|
|
|
+ if ( inst.snapElements[ i ].snapping ) {
|
|
|
|
+ ( inst.options.snap.release &&
|
|
|
|
+ inst.options.snap.release.call(
|
|
|
|
+ inst.element,
|
|
|
|
+ event,
|
|
|
|
+ $.extend( inst._uiHash(), { snapItem: inst.snapElements[ i ].item } )
|
|
|
|
+ ) );
|
|
|
|
+ }
|
|
|
|
+ inst.snapElements[ i ].snapping = false;
|
|
|
|
+ continue;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if ( o.snapMode !== "inner" ) {
|
|
|
|
+ ts = Math.abs( t - y2 ) <= d;
|
|
|
|
+ bs = Math.abs( b - y1 ) <= d;
|
|
|
|
+ ls = Math.abs( l - x2 ) <= d;
|
|
|
|
+ rs = Math.abs( r - x1 ) <= d;
|
|
|
|
+ if ( ts ) {
|
|
|
|
+ ui.position.top = inst._convertPositionTo( "relative", {
|
|
|
|
+ top: t - inst.helperProportions.height,
|
|
|
|
+ left: 0
|
|
|
|
+ } ).top;
|
|
|
|
+ }
|
|
|
|
+ if ( bs ) {
|
|
|
|
+ ui.position.top = inst._convertPositionTo( "relative", {
|
|
|
|
+ top: b,
|
|
|
|
+ left: 0
|
|
|
|
+ } ).top;
|
|
|
|
+ }
|
|
|
|
+ if ( ls ) {
|
|
|
|
+ ui.position.left = inst._convertPositionTo( "relative", {
|
|
|
|
+ top: 0,
|
|
|
|
+ left: l - inst.helperProportions.width
|
|
|
|
+ } ).left;
|
|
|
|
+ }
|
|
|
|
+ if ( rs ) {
|
|
|
|
+ ui.position.left = inst._convertPositionTo( "relative", {
|
|
|
|
+ top: 0,
|
|
|
|
+ left: r
|
|
|
|
+ } ).left;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ first = ( ts || bs || ls || rs );
|
|
|
|
+
|
|
|
|
+ if ( o.snapMode !== "outer" ) {
|
|
|
|
+ ts = Math.abs( t - y1 ) <= d;
|
|
|
|
+ bs = Math.abs( b - y2 ) <= d;
|
|
|
|
+ ls = Math.abs( l - x1 ) <= d;
|
|
|
|
+ rs = Math.abs( r - x2 ) <= d;
|
|
|
|
+ if ( ts ) {
|
|
|
|
+ ui.position.top = inst._convertPositionTo( "relative", {
|
|
|
|
+ top: t,
|
|
|
|
+ left: 0
|
|
|
|
+ } ).top;
|
|
|
|
+ }
|
|
|
|
+ if ( bs ) {
|
|
|
|
+ ui.position.top = inst._convertPositionTo( "relative", {
|
|
|
|
+ top: b - inst.helperProportions.height,
|
|
|
|
+ left: 0
|
|
|
|
+ } ).top;
|
|
|
|
+ }
|
|
|
|
+ if ( ls ) {
|
|
|
|
+ ui.position.left = inst._convertPositionTo( "relative", {
|
|
|
|
+ top: 0,
|
|
|
|
+ left: l
|
|
|
|
+ } ).left;
|
|
|
|
+ }
|
|
|
|
+ if ( rs ) {
|
|
|
|
+ ui.position.left = inst._convertPositionTo( "relative", {
|
|
|
|
+ top: 0,
|
|
|
|
+ left: r - inst.helperProportions.width
|
|
|
|
+ } ).left;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if ( !inst.snapElements[ i ].snapping && ( ts || bs || ls || rs || first ) ) {
|
|
|
|
+ ( inst.options.snap.snap &&
|
|
|
|
+ inst.options.snap.snap.call(
|
|
|
|
+ inst.element,
|
|
|
|
+ event,
|
|
|
|
+ $.extend( inst._uiHash(), {
|
|
|
|
+ snapItem: inst.snapElements[ i ].item
|
|
|
|
+ } ) ) );
|
|
|
|
+ }
|
|
|
|
+ inst.snapElements[ i ].snapping = ( ts || bs || ls || rs || first );
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+} );
|
|
|
|
+
|
|
|
|
+$.ui.plugin.add( "draggable", "stack", {
|
|
|
|
+ start: function( event, ui, instance ) {
|
|
|
|
+ var min,
|
|
|
|
+ o = instance.options,
|
|
|
|
+ group = $.makeArray( $( o.stack ) ).sort( function( a, b ) {
|
|
|
|
+ return ( parseInt( $( a ).css( "zIndex" ), 10 ) || 0 ) -
|
|
|
|
+ ( parseInt( $( b ).css( "zIndex" ), 10 ) || 0 );
|
|
|
|
+ } );
|
|
|
|
+
|
|
|
|
+ if ( !group.length ) { return; }
|
|
|
|
+
|
|
|
|
+ min = parseInt( $( group[ 0 ] ).css( "zIndex" ), 10 ) || 0;
|
|
|
|
+ $( group ).each( function( i ) {
|
|
|
|
+ $( this ).css( "zIndex", min + i );
|
|
|
|
+ } );
|
|
|
|
+ this.css( "zIndex", ( min + group.length ) );
|
|
|
|
+ }
|
|
|
|
+} );
|
|
|
|
+
|
|
|
|
+$.ui.plugin.add( "draggable", "zIndex", {
|
|
|
|
+ start: function( event, ui, instance ) {
|
|
|
|
+ var t = $( ui.helper ),
|
|
|
|
+ o = instance.options;
|
|
|
|
+
|
|
|
|
+ if ( t.css( "zIndex" ) ) {
|
|
|
|
+ o._zIndex = t.css( "zIndex" );
|
|
|
|
+ }
|
|
|
|
+ t.css( "zIndex", o.zIndex );
|
|
|
|
+ },
|
|
|
|
+ stop: function( event, ui, instance ) {
|
|
|
|
+ var o = instance.options;
|
|
|
|
+
|
|
|
|
+ if ( o._zIndex ) {
|
|
|
|
+ $( ui.helper ).css( "zIndex", o._zIndex );
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+} );
|
|
|
|
+
|
|
|
|
+var widgetsDraggable = $.ui.draggable;
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+/*!
|
|
|
|
+ * jQuery UI Droppable 1.12.1
|
|
|
|
+ * http://jqueryui.com
|
|
|
|
+ *
|
|
|
|
+ * Copyright jQuery Foundation and other contributors
|
|
|
|
+ * Released under the MIT license.
|
|
|
|
+ * http://jquery.org/license
|
|
|
|
+ */
|
|
|
|
+
|
|
|
|
+//>>label: Droppable
|
|
|
|
+//>>group: Interactions
|
|
|
|
+//>>description: Enables drop targets for draggable elements.
|
|
|
|
+//>>docs: http://api.jqueryui.com/droppable/
|
|
|
|
+//>>demos: http://jqueryui.com/droppable/
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+$.widget( "ui.droppable", {
|
|
|
|
+ version: "1.12.1",
|
|
|
|
+ widgetEventPrefix: "drop",
|
|
|
|
+ options: {
|
|
|
|
+ accept: "*",
|
|
|
|
+ addClasses: true,
|
|
|
|
+ greedy: false,
|
|
|
|
+ scope: "default",
|
|
|
|
+ tolerance: "intersect",
|
|
|
|
+
|
|
|
|
+ // Callbacks
|
|
|
|
+ activate: null,
|
|
|
|
+ deactivate: null,
|
|
|
|
+ drop: null,
|
|
|
|
+ out: null,
|
|
|
|
+ over: null
|
|
|
|
+ },
|
|
|
|
+ _create: function() {
|
|
|
|
+
|
|
|
|
+ var proportions,
|
|
|
|
+ o = this.options,
|
|
|
|
+ accept = o.accept;
|
|
|
|
+
|
|
|
|
+ this.isover = false;
|
|
|
|
+ this.isout = true;
|
|
|
|
+
|
|
|
|
+ this.accept = $.isFunction( accept ) ? accept : function( d ) {
|
|
|
|
+ return d.is( accept );
|
|
|
|
+ };
|
|
|
|
+
|
|
|
|
+ this.proportions = function( /* valueToWrite */ ) {
|
|
|
|
+ if ( arguments.length ) {
|
|
|
|
+
|
|
|
|
+ // Store the droppable's proportions
|
|
|
|
+ proportions = arguments[ 0 ];
|
|
|
|
+ } else {
|
|
|
|
+
|
|
|
|
+ // Retrieve or derive the droppable's proportions
|
|
|
|
+ return proportions ?
|
|
|
|
+ proportions :
|
|
|
|
+ proportions = {
|
|
|
|
+ width: this.element[ 0 ].offsetWidth,
|
|
|
|
+ height: this.element[ 0 ].offsetHeight
|
|
|
|
+ };
|
|
|
|
+ }
|
|
|
|
+ };
|
|
|
|
+
|
|
|
|
+ this._addToManager( o.scope );
|
|
|
|
+
|
|
|
|
+ o.addClasses && this._addClass( "ui-droppable" );
|
|
|
|
+
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ _addToManager: function( scope ) {
|
|
|
|
+
|
|
|
|
+ // Add the reference and positions to the manager
|
|
|
|
+ $.ui.ddmanager.droppables[ scope ] = $.ui.ddmanager.droppables[ scope ] || [];
|
|
|
|
+ $.ui.ddmanager.droppables[ scope ].push( this );
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ _splice: function( drop ) {
|
|
|
|
+ var i = 0;
|
|
|
|
+ for ( ; i < drop.length; i++ ) {
|
|
|
|
+ if ( drop[ i ] === this ) {
|
|
|
|
+ drop.splice( i, 1 );
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ _destroy: function() {
|
|
|
|
+ var drop = $.ui.ddmanager.droppables[ this.options.scope ];
|
|
|
|
+
|
|
|
|
+ this._splice( drop );
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ _setOption: function( key, value ) {
|
|
|
|
+
|
|
|
|
+ if ( key === "accept" ) {
|
|
|
|
+ this.accept = $.isFunction( value ) ? value : function( d ) {
|
|
|
|
+ return d.is( value );
|
|
|
|
+ };
|
|
|
|
+ } else if ( key === "scope" ) {
|
|
|
|
+ var drop = $.ui.ddmanager.droppables[ this.options.scope ];
|
|
|
|
+
|
|
|
|
+ this._splice( drop );
|
|
|
|
+ this._addToManager( value );
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ this._super( key, value );
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ _activate: function( event ) {
|
|
|
|
+ var draggable = $.ui.ddmanager.current;
|
|
|
|
+
|
|
|
|
+ this._addActiveClass();
|
|
|
|
+ if ( draggable ) {
|
|
|
|
+ this._trigger( "activate", event, this.ui( draggable ) );
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ _deactivate: function( event ) {
|
|
|
|
+ var draggable = $.ui.ddmanager.current;
|
|
|
|
+
|
|
|
|
+ this._removeActiveClass();
|
|
|
|
+ if ( draggable ) {
|
|
|
|
+ this._trigger( "deactivate", event, this.ui( draggable ) );
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ _over: function( event ) {
|
|
|
|
+
|
|
|
|
+ var draggable = $.ui.ddmanager.current;
|
|
|
|
+
|
|
|
|
+ // Bail if draggable and droppable are same element
|
|
|
|
+ if ( !draggable || ( draggable.currentItem ||
|
|
|
|
+ draggable.element )[ 0 ] === this.element[ 0 ] ) {
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem ||
|
|
|
|
+ draggable.element ) ) ) {
|
|
|
|
+ this._addHoverClass();
|
|
|
|
+ this._trigger( "over", event, this.ui( draggable ) );
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ _out: function( event ) {
|
|
|
|
+
|
|
|
|
+ var draggable = $.ui.ddmanager.current;
|
|
|
|
+
|
|
|
|
+ // Bail if draggable and droppable are same element
|
|
|
|
+ if ( !draggable || ( draggable.currentItem ||
|
|
|
|
+ draggable.element )[ 0 ] === this.element[ 0 ] ) {
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem ||
|
|
|
|
+ draggable.element ) ) ) {
|
|
|
|
+ this._removeHoverClass();
|
|
|
|
+ this._trigger( "out", event, this.ui( draggable ) );
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ _drop: function( event, custom ) {
|
|
|
|
+
|
|
|
|
+ var draggable = custom || $.ui.ddmanager.current,
|
|
|
|
+ childrenIntersection = false;
|
|
|
|
+
|
|
|
|
+ // Bail if draggable and droppable are same element
|
|
|
|
+ if ( !draggable || ( draggable.currentItem ||
|
|
|
|
+ draggable.element )[ 0 ] === this.element[ 0 ] ) {
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ this.element
|
|
|
|
+ .find( ":data(ui-droppable)" )
|
|
|
|
+ .not( ".ui-draggable-dragging" )
|
|
|
|
+ .each( function() {
|
|
|
|
+ var inst = $( this ).droppable( "instance" );
|
|
|
|
+ if (
|
|
|
|
+ inst.options.greedy &&
|
|
|
|
+ !inst.options.disabled &&
|
|
|
|
+ inst.options.scope === draggable.options.scope &&
|
|
|
|
+ inst.accept.call(
|
|
|
|
+ inst.element[ 0 ], ( draggable.currentItem || draggable.element )
|
|
|
|
+ ) &&
|
|
|
|
+ intersect(
|
|
|
|
+ draggable,
|
|
|
|
+ $.extend( inst, { offset: inst.element.offset() } ),
|
|
|
|
+ inst.options.tolerance, event
|
|
|
|
+ )
|
|
|
|
+ ) {
|
|
|
|
+ childrenIntersection = true;
|
|
|
|
+ return false; }
|
|
|
|
+ } );
|
|
|
|
+ if ( childrenIntersection ) {
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if ( this.accept.call( this.element[ 0 ],
|
|
|
|
+ ( draggable.currentItem || draggable.element ) ) ) {
|
|
|
|
+ this._removeActiveClass();
|
|
|
|
+ this._removeHoverClass();
|
|
|
|
+
|
|
|
|
+ this._trigger( "drop", event, this.ui( draggable ) );
|
|
|
|
+ return this.element;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return false;
|
|
|
|
+
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ ui: function( c ) {
|
|
|
|
+ return {
|
|
|
|
+ draggable: ( c.currentItem || c.element ),
|
|
|
|
+ helper: c.helper,
|
|
|
|
+ position: c.position,
|
|
|
|
+ offset: c.positionAbs
|
|
|
|
+ };
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ // Extension points just to make backcompat sane and avoid duplicating logic
|
|
|
|
+ // TODO: Remove in 1.13 along with call to it below
|
|
|
|
+ _addHoverClass: function() {
|
|
|
|
+ this._addClass( "ui-droppable-hover" );
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ _removeHoverClass: function() {
|
|
|
|
+ this._removeClass( "ui-droppable-hover" );
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ _addActiveClass: function() {
|
|
|
|
+ this._addClass( "ui-droppable-active" );
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ _removeActiveClass: function() {
|
|
|
|
+ this._removeClass( "ui-droppable-active" );
|
|
|
|
+ }
|
|
|
|
+} );
|
|
|
|
+
|
|
|
|
+var intersect = $.ui.intersect = ( function() {
|
|
|
|
+ function isOverAxis( x, reference, size ) {
|
|
|
|
+ return ( x >= reference ) && ( x < ( reference + size ) );
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return function( draggable, droppable, toleranceMode, event ) {
|
|
|
|
+
|
|
|
|
+ if ( !droppable.offset ) {
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ var x1 = ( draggable.positionAbs ||
|
|
|
|
+ draggable.position.absolute ).left + draggable.margins.left,
|
|
|
|
+ y1 = ( draggable.positionAbs ||
|
|
|
|
+ draggable.position.absolute ).top + draggable.margins.top,
|
|
|
|
+ x2 = x1 + draggable.helperProportions.width,
|
|
|
|
+ y2 = y1 + draggable.helperProportions.height,
|
|
|
|
+ l = droppable.offset.left,
|
|
|
|
+ t = droppable.offset.top,
|
|
|
|
+ r = l + droppable.proportions().width,
|
|
|
|
+ b = t + droppable.proportions().height;
|
|
|
|
+
|
|
|
|
+ switch ( toleranceMode ) {
|
|
|
|
+ case "fit":
|
|
|
|
+ return ( l <= x1 && x2 <= r && t <= y1 && y2 <= b );
|
|
|
|
+ case "intersect":
|
|
|
|
+ return ( l < x1 + ( draggable.helperProportions.width / 2 ) && // Right Half
|
|
|
|
+ x2 - ( draggable.helperProportions.width / 2 ) < r && // Left Half
|
|
|
|
+ t < y1 + ( draggable.helperProportions.height / 2 ) && // Bottom Half
|
|
|
|
+ y2 - ( draggable.helperProportions.height / 2 ) < b ); // Top Half
|
|
|
|
+ case "pointer":
|
|
|
|
+ return isOverAxis( event.pageY, t, droppable.proportions().height ) &&
|
|
|
|
+ isOverAxis( event.pageX, l, droppable.proportions().width );
|
|
|
|
+ case "touch":
|
|
|
|
+ return (
|
|
|
|
+ ( y1 >= t && y1 <= b ) || // Top edge touching
|
|
|
|
+ ( y2 >= t && y2 <= b ) || // Bottom edge touching
|
|
|
|
+ ( y1 < t && y2 > b ) // Surrounded vertically
|
|
|
|
+ ) && (
|
|
|
|
+ ( x1 >= l && x1 <= r ) || // Left edge touching
|
|
|
|
+ ( x2 >= l && x2 <= r ) || // Right edge touching
|
|
|
|
+ ( x1 < l && x2 > r ) // Surrounded horizontally
|
|
|
|
+ );
|
|
|
|
+ default:
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+ };
|
|
|
|
+} )();
|
|
|
|
+
|
|
|
|
+/*
|
|
|
|
+ This manager tracks offsets of draggables and droppables
|
|
|
|
+*/
|
|
|
|
+$.ui.ddmanager = {
|
|
|
|
+ current: null,
|
|
|
|
+ droppables: { "default": [] },
|
|
|
|
+ prepareOffsets: function( t, event ) {
|
|
|
|
+
|
|
|
|
+ var i, j,
|
|
|
|
+ m = $.ui.ddmanager.droppables[ t.options.scope ] || [],
|
|
|
|
+ type = event ? event.type : null, // workaround for #2317
|
|
|
|
+ list = ( t.currentItem || t.element ).find( ":data(ui-droppable)" ).addBack();
|
|
|
|
+
|
|
|
|
+ droppablesLoop: for ( i = 0; i < m.length; i++ ) {
|
|
|
|
+
|
|
|
|
+ // No disabled and non-accepted
|
|
|
|
+ if ( m[ i ].options.disabled || ( t && !m[ i ].accept.call( m[ i ].element[ 0 ],
|
|
|
|
+ ( t.currentItem || t.element ) ) ) ) {
|
|
|
|
+ continue;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // Filter out elements in the current dragged item
|
|
|
|
+ for ( j = 0; j < list.length; j++ ) {
|
|
|
|
+ if ( list[ j ] === m[ i ].element[ 0 ] ) {
|
|
|
|
+ m[ i ].proportions().height = 0;
|
|
|
|
+ continue droppablesLoop;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ m[ i ].visible = m[ i ].element.css( "display" ) !== "none";
|
|
|
|
+ if ( !m[ i ].visible ) {
|
|
|
|
+ continue;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // Activate the droppable if used directly from draggables
|
|
|
|
+ if ( type === "mousedown" ) {
|
|
|
|
+ m[ i ]._activate.call( m[ i ], event );
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ m[ i ].offset = m[ i ].element.offset();
|
|
|
|
+ m[ i ].proportions( {
|
|
|
|
+ width: m[ i ].element[ 0 ].offsetWidth,
|
|
|
|
+ height: m[ i ].element[ 0 ].offsetHeight
|
|
|
|
+ } );
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ },
|
|
|
|
+ drop: function( draggable, event ) {
|
|
|
|
+
|
|
|
|
+ var dropped = false;
|
|
|
|
+
|
|
|
|
+ // Create a copy of the droppables in case the list changes during the drop (#9116)
|
|
|
|
+ $.each( ( $.ui.ddmanager.droppables[ draggable.options.scope ] || [] ).slice(), function() {
|
|
|
|
+
|
|
|
|
+ if ( !this.options ) {
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+ if ( !this.options.disabled && this.visible &&
|
|
|
|
+ intersect( draggable, this, this.options.tolerance, event ) ) {
|
|
|
|
+ dropped = this._drop.call( this, event ) || dropped;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if ( !this.options.disabled && this.visible && this.accept.call( this.element[ 0 ],
|
|
|
|
+ ( draggable.currentItem || draggable.element ) ) ) {
|
|
|
|
+ this.isout = true;
|
|
|
|
+ this.isover = false;
|
|
|
|
+ this._deactivate.call( this, event );
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ } );
|
|
|
|
+ return dropped;
|
|
|
|
+
|
|
|
|
+ },
|
|
|
|
+ dragStart: function( draggable, event ) {
|
|
|
|
+
|
|
|
|
+ // Listen for scrolling so that if the dragging causes scrolling the position of the
|
|
|
|
+ // droppables can be recalculated (see #5003)
|
|
|
|
+ draggable.element.parentsUntil( "body" ).on( "scroll.droppable", function() {
|
|
|
|
+ if ( !draggable.options.refreshPositions ) {
|
|
|
|
+ $.ui.ddmanager.prepareOffsets( draggable, event );
|
|
|
|
+ }
|
|
|
|
+ } );
|
|
|
|
+ },
|
|
|
|
+ drag: function( draggable, event ) {
|
|
|
|
+
|
|
|
|
+ // If you have a highly dynamic page, you might try this option. It renders positions
|
|
|
|
+ // every time you move the mouse.
|
|
|
|
+ if ( draggable.options.refreshPositions ) {
|
|
|
|
+ $.ui.ddmanager.prepareOffsets( draggable, event );
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // Run through all droppables and check their positions based on specific tolerance options
|
|
|
|
+ $.each( $.ui.ddmanager.droppables[ draggable.options.scope ] || [], function() {
|
|
|
|
+
|
|
|
|
+ if ( this.options.disabled || this.greedyChild || !this.visible ) {
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ var parentInstance, scope, parent,
|
|
|
|
+ intersects = intersect( draggable, this, this.options.tolerance, event ),
|
|
|
|
+ c = !intersects && this.isover ?
|
|
|
|
+ "isout" :
|
|
|
|
+ ( intersects && !this.isover ? "isover" : null );
|
|
|
|
+ if ( !c ) {
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if ( this.options.greedy ) {
|
|
|
|
+
|
|
|
|
+ // find droppable parents with same scope
|
|
|
|
+ scope = this.options.scope;
|
|
|
|
+ parent = this.element.parents( ":data(ui-droppable)" ).filter( function() {
|
|
|
|
+ return $( this ).droppable( "instance" ).options.scope === scope;
|
|
|
|
+ } );
|
|
|
|
+
|
|
|
|
+ if ( parent.length ) {
|
|
|
|
+ parentInstance = $( parent[ 0 ] ).droppable( "instance" );
|
|
|
|
+ parentInstance.greedyChild = ( c === "isover" );
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // We just moved into a greedy child
|
|
|
|
+ if ( parentInstance && c === "isover" ) {
|
|
|
|
+ parentInstance.isover = false;
|
|
|
|
+ parentInstance.isout = true;
|
|
|
|
+ parentInstance._out.call( parentInstance, event );
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ this[ c ] = true;
|
|
|
|
+ this[ c === "isout" ? "isover" : "isout" ] = false;
|
|
|
|
+ this[ c === "isover" ? "_over" : "_out" ].call( this, event );
|
|
|
|
+
|
|
|
|
+ // We just moved out of a greedy child
|
|
|
|
+ if ( parentInstance && c === "isout" ) {
|
|
|
|
+ parentInstance.isout = false;
|
|
|
|
+ parentInstance.isover = true;
|
|
|
|
+ parentInstance._over.call( parentInstance, event );
|
|
|
|
+ }
|
|
|
|
+ } );
|
|
|
|
+
|
|
|
|
+ },
|
|
|
|
+ dragStop: function( draggable, event ) {
|
|
|
|
+ draggable.element.parentsUntil( "body" ).off( "scroll.droppable" );
|
|
|
|
+
|
|
|
|
+ // Call prepareOffsets one final time since IE does not fire return scroll events when
|
|
|
|
+ // overflow was caused by drag (see #5003)
|
|
|
|
+ if ( !draggable.options.refreshPositions ) {
|
|
|
|
+ $.ui.ddmanager.prepareOffsets( draggable, event );
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
+// DEPRECATED
|
|
|
|
+// TODO: switch return back to widget declaration at top of file when this is removed
|
|
|
|
+if ( $.uiBackCompat !== false ) {
|
|
|
|
+
|
|
|
|
+ // Backcompat for activeClass and hoverClass options
|
|
|
|
+ $.widget( "ui.droppable", $.ui.droppable, {
|
|
|
|
+ options: {
|
|
|
|
+ hoverClass: false,
|
|
|
|
+ activeClass: false
|
|
|
|
+ },
|
|
|
|
+ _addActiveClass: function() {
|
|
|
|
+ this._super();
|
|
|
|
+ if ( this.options.activeClass ) {
|
|
|
|
+ this.element.addClass( this.options.activeClass );
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+ _removeActiveClass: function() {
|
|
|
|
+ this._super();
|
|
|
|
+ if ( this.options.activeClass ) {
|
|
|
|
+ this.element.removeClass( this.options.activeClass );
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+ _addHoverClass: function() {
|
|
|
|
+ this._super();
|
|
|
|
+ if ( this.options.hoverClass ) {
|
|
|
|
+ this.element.addClass( this.options.hoverClass );
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+ _removeHoverClass: function() {
|
|
|
|
+ this._super();
|
|
|
|
+ if ( this.options.hoverClass ) {
|
|
|
|
+ this.element.removeClass( this.options.hoverClass );
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ } );
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+var widgetsDroppable = $.ui.droppable;
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+/*!
|
|
|
|
+ * jQuery UI Selectable 1.12.1
|
|
|
|
+ * http://jqueryui.com
|
|
|
|
+ *
|
|
|
|
+ * Copyright jQuery Foundation and other contributors
|
|
|
|
+ * Released under the MIT license.
|
|
|
|
+ * http://jquery.org/license
|
|
|
|
+ */
|
|
|
|
+
|
|
|
|
+//>>label: Selectable
|
|
|
|
+//>>group: Interactions
|
|
|
|
+//>>description: Allows groups of elements to be selected with the mouse.
|
|
|
|
+//>>docs: http://api.jqueryui.com/selectable/
|
|
|
|
+//>>demos: http://jqueryui.com/selectable/
|
|
|
|
+//>>css.structure: ../../themes/base/selectable.css
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+var widgetsSelectable = $.widget( "ui.selectable", $.ui.mouse, {
|
|
|
|
+ version: "1.12.1",
|
|
|
|
+ options: {
|
|
|
|
+ appendTo: "body",
|
|
|
|
+ autoRefresh: true,
|
|
|
|
+ distance: 0,
|
|
|
|
+ filter: "*",
|
|
|
|
+ tolerance: "touch",
|
|
|
|
+
|
|
|
|
+ // Callbacks
|
|
|
|
+ selected: null,
|
|
|
|
+ selecting: null,
|
|
|
|
+ start: null,
|
|
|
|
+ stop: null,
|
|
|
|
+ unselected: null,
|
|
|
|
+ unselecting: null
|
|
|
|
+ },
|
|
|
|
+ _create: function() {
|
|
|
|
+ var that = this;
|
|
|
|
+
|
|
|
|
+ this._addClass( "ui-selectable" );
|
|
|
|
+
|
|
|
|
+ this.dragged = false;
|
|
|
|
+
|
|
|
|
+ // Cache selectee children based on filter
|
|
|
|
+ this.refresh = function() {
|
|
|
|
+ that.elementPos = $( that.element[ 0 ] ).offset();
|
|
|
|
+ that.selectees = $( that.options.filter, that.element[ 0 ] );
|
|
|
|
+ that._addClass( that.selectees, "ui-selectee" );
|
|
|
|
+ that.selectees.each( function() {
|
|
|
|
+ var $this = $( this ),
|
|
|
|
+ selecteeOffset = $this.offset(),
|
|
|
|
+ pos = {
|
|
|
|
+ left: selecteeOffset.left - that.elementPos.left,
|
|
|
|
+ top: selecteeOffset.top - that.elementPos.top
|
|
|
|
+ };
|
|
|
|
+ $.data( this, "selectable-item", {
|
|
|
|
+ element: this,
|
|
|
|
+ $element: $this,
|
|
|
|
+ left: pos.left,
|
|
|
|
+ top: pos.top,
|
|
|
|
+ right: pos.left + $this.outerWidth(),
|
|
|
|
+ bottom: pos.top + $this.outerHeight(),
|
|
|
|
+ startselected: false,
|
|
|
|
+ selected: $this.hasClass( "ui-selected" ),
|
|
|
|
+ selecting: $this.hasClass( "ui-selecting" ),
|
|
|
|
+ unselecting: $this.hasClass( "ui-unselecting" )
|
|
|
|
+ } );
|
|
|
|
+ } );
|
|
|
|
+ };
|
|
|
|
+ this.refresh();
|
|
|
|
+
|
|
|
|
+ this._mouseInit();
|
|
|
|
+
|
|
|
|
+ this.helper = $( "<div>" );
|
|
|
|
+ this._addClass( this.helper, "ui-selectable-helper" );
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ _destroy: function() {
|
|
|
|
+ this.selectees.removeData( "selectable-item" );
|
|
|
|
+ this._mouseDestroy();
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ _mouseStart: function( event ) {
|
|
|
|
+ var that = this,
|
|
|
|
+ options = this.options;
|
|
|
|
+
|
|
|
|
+ this.opos = [ event.pageX, event.pageY ];
|
|
|
|
+ this.elementPos = $( this.element[ 0 ] ).offset();
|
|
|
|
+
|
|
|
|
+ if ( this.options.disabled ) {
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ this.selectees = $( options.filter, this.element[ 0 ] );
|
|
|
|
+
|
|
|
|
+ this._trigger( "start", event );
|
|
|
|
+
|
|
|
|
+ $( options.appendTo ).append( this.helper );
|
|
|
|
+
|
|
|
|
+ // position helper (lasso)
|
|
|
|
+ this.helper.css( {
|
|
|
|
+ "left": event.pageX,
|
|
|
|
+ "top": event.pageY,
|
|
|
|
+ "width": 0,
|
|
|
|
+ "height": 0
|
|
|
|
+ } );
|
|
|
|
+
|
|
|
|
+ if ( options.autoRefresh ) {
|
|
|
|
+ this.refresh();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ this.selectees.filter( ".ui-selected" ).each( function() {
|
|
|
|
+ var selectee = $.data( this, "selectable-item" );
|
|
|
|
+ selectee.startselected = true;
|
|
|
|
+ if ( !event.metaKey && !event.ctrlKey ) {
|
|
|
|
+ that._removeClass( selectee.$element, "ui-selected" );
|
|
|
|
+ selectee.selected = false;
|
|
|
|
+ that._addClass( selectee.$element, "ui-unselecting" );
|
|
|
|
+ selectee.unselecting = true;
|
|
|
|
+
|
|
|
|
+ // selectable UNSELECTING callback
|
|
|
|
+ that._trigger( "unselecting", event, {
|
|
|
|
+ unselecting: selectee.element
|
|
|
|
+ } );
|
|
|
|
+ }
|
|
|
|
+ } );
|
|
|
|
+
|
|
|
|
+ $( event.target ).parents().addBack().each( function() {
|
|
|
|
+ var doSelect,
|
|
|
|
+ selectee = $.data( this, "selectable-item" );
|
|
|
|
+ if ( selectee ) {
|
|
|
|
+ doSelect = ( !event.metaKey && !event.ctrlKey ) ||
|
|
|
|
+ !selectee.$element.hasClass( "ui-selected" );
|
|
|
|
+ that._removeClass( selectee.$element, doSelect ? "ui-unselecting" : "ui-selected" )
|
|
|
|
+ ._addClass( selectee.$element, doSelect ? "ui-selecting" : "ui-unselecting" );
|
|
|
|
+ selectee.unselecting = !doSelect;
|
|
|
|
+ selectee.selecting = doSelect;
|
|
|
|
+ selectee.selected = doSelect;
|
|
|
|
+
|
|
|
|
+ // selectable (UN)SELECTING callback
|
|
|
|
+ if ( doSelect ) {
|
|
|
|
+ that._trigger( "selecting", event, {
|
|
|
|
+ selecting: selectee.element
|
|
|
|
+ } );
|
|
|
|
+ } else {
|
|
|
|
+ that._trigger( "unselecting", event, {
|
|
|
|
+ unselecting: selectee.element
|
|
|
|
+ } );
|
|
|
|
+ }
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+ } );
|
|
|
|
+
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ _mouseDrag: function( event ) {
|
|
|
|
+
|
|
|
|
+ this.dragged = true;
|
|
|
|
+
|
|
|
|
+ if ( this.options.disabled ) {
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ var tmp,
|
|
|
|
+ that = this,
|
|
|
|
+ options = this.options,
|
|
|
|
+ x1 = this.opos[ 0 ],
|
|
|
|
+ y1 = this.opos[ 1 ],
|
|
|
|
+ x2 = event.pageX,
|
|
|
|
+ y2 = event.pageY;
|
|
|
|
+
|
|
|
|
+ if ( x1 > x2 ) { tmp = x2; x2 = x1; x1 = tmp; }
|
|
|
|
+ if ( y1 > y2 ) { tmp = y2; y2 = y1; y1 = tmp; }
|
|
|
|
+ this.helper.css( { left: x1, top: y1, width: x2 - x1, height: y2 - y1 } );
|
|
|
|
+
|
|
|
|
+ this.selectees.each( function() {
|
|
|
|
+ var selectee = $.data( this, "selectable-item" ),
|
|
|
|
+ hit = false,
|
|
|
|
+ offset = {};
|
|
|
|
+
|
|
|
|
+ //prevent helper from being selected if appendTo: selectable
|
|
|
|
+ if ( !selectee || selectee.element === that.element[ 0 ] ) {
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ offset.left = selectee.left + that.elementPos.left;
|
|
|
|
+ offset.right = selectee.right + that.elementPos.left;
|
|
|
|
+ offset.top = selectee.top + that.elementPos.top;
|
|
|
|
+ offset.bottom = selectee.bottom + that.elementPos.top;
|
|
|
|
+
|
|
|
|
+ if ( options.tolerance === "touch" ) {
|
|
|
|
+ hit = ( !( offset.left > x2 || offset.right < x1 || offset.top > y2 ||
|
|
|
|
+ offset.bottom < y1 ) );
|
|
|
|
+ } else if ( options.tolerance === "fit" ) {
|
|
|
|
+ hit = ( offset.left > x1 && offset.right < x2 && offset.top > y1 &&
|
|
|
|
+ offset.bottom < y2 );
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if ( hit ) {
|
|
|
|
+
|
|
|
|
+ // SELECT
|
|
|
|
+ if ( selectee.selected ) {
|
|
|
|
+ that._removeClass( selectee.$element, "ui-selected" );
|
|
|
|
+ selectee.selected = false;
|
|
|
|
+ }
|
|
|
|
+ if ( selectee.unselecting ) {
|
|
|
|
+ that._removeClass( selectee.$element, "ui-unselecting" );
|
|
|
|
+ selectee.unselecting = false;
|
|
|
|
+ }
|
|
|
|
+ if ( !selectee.selecting ) {
|
|
|
|
+ that._addClass( selectee.$element, "ui-selecting" );
|
|
|
|
+ selectee.selecting = true;
|
|
|
|
+
|
|
|
|
+ // selectable SELECTING callback
|
|
|
|
+ that._trigger( "selecting", event, {
|
|
|
|
+ selecting: selectee.element
|
|
|
|
+ } );
|
|
|
|
+ }
|
|
|
|
+ } else {
|
|
|
|
+
|
|
|
|
+ // UNSELECT
|
|
|
|
+ if ( selectee.selecting ) {
|
|
|
|
+ if ( ( event.metaKey || event.ctrlKey ) && selectee.startselected ) {
|
|
|
|
+ that._removeClass( selectee.$element, "ui-selecting" );
|
|
|
|
+ selectee.selecting = false;
|
|
|
|
+ that._addClass( selectee.$element, "ui-selected" );
|
|
|
|
+ selectee.selected = true;
|
|
|
|
+ } else {
|
|
|
|
+ that._removeClass( selectee.$element, "ui-selecting" );
|
|
|
|
+ selectee.selecting = false;
|
|
|
|
+ if ( selectee.startselected ) {
|
|
|
|
+ that._addClass( selectee.$element, "ui-unselecting" );
|
|
|
|
+ selectee.unselecting = true;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // selectable UNSELECTING callback
|
|
|
|
+ that._trigger( "unselecting", event, {
|
|
|
|
+ unselecting: selectee.element
|
|
|
|
+ } );
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ if ( selectee.selected ) {
|
|
|
|
+ if ( !event.metaKey && !event.ctrlKey && !selectee.startselected ) {
|
|
|
|
+ that._removeClass( selectee.$element, "ui-selected" );
|
|
|
|
+ selectee.selected = false;
|
|
|
|
+
|
|
|
|
+ that._addClass( selectee.$element, "ui-unselecting" );
|
|
|
|
+ selectee.unselecting = true;
|
|
|
|
+
|
|
|
|
+ // selectable UNSELECTING callback
|
|
|
|
+ that._trigger( "unselecting", event, {
|
|
|
|
+ unselecting: selectee.element
|
|
|
|
+ } );
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ } );
|
|
|
|
+
|
|
|
|
+ return false;
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ _mouseStop: function( event ) {
|
|
|
|
+ var that = this;
|
|
|
|
+
|
|
|
|
+ this.dragged = false;
|
|
|
|
+
|
|
|
|
+ $( ".ui-unselecting", this.element[ 0 ] ).each( function() {
|
|
|
|
+ var selectee = $.data( this, "selectable-item" );
|
|
|
|
+ that._removeClass( selectee.$element, "ui-unselecting" );
|
|
|
|
+ selectee.unselecting = false;
|
|
|
|
+ selectee.startselected = false;
|
|
|
|
+ that._trigger( "unselected", event, {
|
|
|
|
+ unselected: selectee.element
|
|
|
|
+ } );
|
|
|
|
+ } );
|
|
|
|
+ $( ".ui-selecting", this.element[ 0 ] ).each( function() {
|
|
|
|
+ var selectee = $.data( this, "selectable-item" );
|
|
|
|
+ that._removeClass( selectee.$element, "ui-selecting" )
|
|
|
|
+ ._addClass( selectee.$element, "ui-selected" );
|
|
|
|
+ selectee.selecting = false;
|
|
|
|
+ selectee.selected = true;
|
|
|
|
+ selectee.startselected = true;
|
|
|
|
+ that._trigger( "selected", event, {
|
|
|
|
+ selected: selectee.element
|
|
|
|
+ } );
|
|
|
|
+ } );
|
|
|
|
+ this._trigger( "stop", event );
|
|
|
|
+
|
|
|
|
+ this.helper.remove();
|
|
|
|
+
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+} );
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+}));
|