]> source.dussan.org Git - jquery-ui.git/commitdiff
Droppable: Move droppable into widgets folder
authorAlexander Schmitz <arschmitz@gmail.com>
Wed, 15 Jul 2015 02:03:06 +0000 (22:03 -0400)
committerAlexander Schmitz <arschmitz@gmail.com>
Sat, 8 Aug 2015 04:29:38 +0000 (00:29 -0400)
Ref #13885

demos/bootstrap.js
tests/unit/draggable/core.js
tests/unit/draggable/options.js
tests/unit/droppable/common-deprecated.js
tests/unit/droppable/common.js
tests/unit/droppable/core.js
tests/unit/droppable/events.js
tests/unit/droppable/methods.js
tests/unit/droppable/options.js
ui/droppable.js [deleted file]
ui/widgets/droppable.js [new file with mode: 0644]

index a182f7f1ccc245d6a47134e9474be5c6e45b50ca..c45d5e3e0e10daea2a2e80cb3f274581a04cd2b6 100644 (file)
@@ -30,7 +30,8 @@ var widgets = [
        "button",
        "datepicker",
        "dialog",
-       "draggable"
+       "draggable",
+       "droppable"
 ];
 
 function getPath( module ) {
index d18917b4b13084c116d62f82c004a2b4a43e7ba4..e4b7a53eb976677065f0346cb0e7ab1e7cf308db 100644 (file)
@@ -2,7 +2,7 @@ define( [
        "jquery",
        "./helper",
        "ui/widgets/draggable",
-       "ui/droppable",
+       "ui/widgets/droppable",
        "ui/resizable"
 ], function( $, testHelper ) {
 
index 96db426f878db47a416e753e2766b4eb88e6d25c..9be43b384e4222a2c14ee3898b1789327aaccb36 100644 (file)
@@ -2,7 +2,7 @@ define( [
        "jquery",
        "./helper",
        "ui/widgets/draggable",
-       "ui/droppable",
+       "ui/widgets/droppable",
        "ui/sortable"
 ], function( $, testHelper ) {
 
index 9d2f6c6b66c13294add361cb9357f12875a49816..e9fdc69cc8ff19e274bc16bad15142de8072587a 100644 (file)
@@ -1,6 +1,6 @@
 define( [
        "lib/common",
-       "ui/droppable"
+       "ui/widgets/droppable"
 ], function( common ) {
 
 common.testWidget( "droppable", {
index ef8e116922c8dceafa4567c775375b0886c87939..d3bffc67b6a8e0f2e5135a820bc028406fe312b2 100644 (file)
@@ -1,6 +1,6 @@
 define( [
        "lib/common",
-       "ui/droppable"
+       "ui/widgets/droppable"
 ], function( common ) {
 
 common.testWidget( "droppable", {
index 43608353da080b3a39ca4e5ab594b4280c15da80..75951c1bc320a7e0aef7278e6884e1f7b1cd42bf 100644 (file)
@@ -1,7 +1,7 @@
 define( [
        "jquery",
        "./helper",
-       "ui/droppable"
+       "ui/widgets/droppable"
 ], function( $, testHelper ) {
 
 module("droppable: core");
index a60d9292ee37af80260c38bd5a1eb4d29b65b0a4..9c84b099f144973b69809d2e5f093449d9bb5e05 100644 (file)
@@ -1,6 +1,6 @@
 define( [
        "jquery",
-       "ui/droppable"
+       "ui/widgets/droppable"
 ], function( $ ) {
 
 module( "droppable: events" );
index 1c9bba023fa65979d365fa80fadc70e5756ae4da..10ac484996fdf8a765e703ccdb1ed5bed2f8981b 100644 (file)
@@ -1,7 +1,7 @@
 define( [
        "jquery",
        "./helper",
-       "ui/droppable"
+       "ui/widgets/droppable"
 ], function( $, testHelper ) {
 
 module("droppable: methods");
index c7c0dbdd642a6abe6d071b0dc57105a0a1b22277..2fdf483d20a5c39ebf8f772d962be3f5409b991f 100644 (file)
@@ -1,6 +1,6 @@
 define( [
        "jquery",
-       "ui/droppable"
+       "ui/widgets/droppable"
 ], function( $ ) {
 
 module( "droppable: options" );
diff --git a/ui/droppable.js b/ui/droppable.js
deleted file mode 100644 (file)
index ffa1db1..0000000
+++ /dev/null
@@ -1,459 +0,0 @@
-/*!
- * jQuery UI Droppable @VERSION
- * 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/
-
-(function( factory ) {
-       if ( typeof define === "function" && define.amd ) {
-
-               // AMD. Register as an anonymous module.
-               define([
-                       "jquery",
-                       "./version",
-                       "./widget",
-                       "./mouse",
-                       "./widgets/draggable"
-               ], factory );
-       } else {
-
-               // Browser globals
-               factory( jQuery );
-       }
-}(function( $ ) {
-
-$.widget( "ui.droppable", {
-       version: "@VERSION",
-       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 = (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 );
-                       }
-               }
-       });
-}
-
-return $.ui.droppable;
-
-}));
diff --git a/ui/widgets/droppable.js b/ui/widgets/droppable.js
new file mode 100644 (file)
index 0000000..551828b
--- /dev/null
@@ -0,0 +1,459 @@
+/*!
+ * jQuery UI Droppable @VERSION
+ * 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/
+
+(function( factory ) {
+       if ( typeof define === "function" && define.amd ) {
+
+               // AMD. Register as an anonymous module.
+               define([
+                       "jquery",
+                       "./draggable",
+                       "../mouse",
+                       "../version",
+                       "../widget"
+               ], factory );
+       } else {
+
+               // Browser globals
+               factory( jQuery );
+       }
+}(function( $ ) {
+
+$.widget( "ui.droppable", {
+       version: "@VERSION",
+       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 = (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 );
+                       }
+               }
+       });
+}
+
+return $.ui.droppable;
+
+}));