@@ -31,6 +31,7 @@ $.widget("ui.droppable", {
3131 hoverClass : false ,
3232 scope : "default" ,
3333 tolerance : "intersect" ,
34+ andSelf : false ,
3435
3536 // callbacks
3637 activate : null ,
@@ -105,52 +106,100 @@ $.widget("ui.droppable", {
105106 }
106107 } ,
107108
109+ _triggerOver : function ( event , draggable ) {
110+ if ( this . options . hoverClass ) {
111+ this . element . addClass ( this . options . hoverClass ) ;
112+ }
113+ this . _trigger ( "over" , event , this . ui ( draggable ) ) ;
114+ } ,
115+
116+ _triggerOut : function ( event , draggable ) {
117+ if ( this . options . hoverClass ) {
118+ this . element . removeClass ( this . options . hoverClass ) ;
119+ }
120+ this . _trigger ( "out" , event , this . ui ( draggable ) ) ;
121+ } ,
122+
108123 _over : function ( event ) {
109124
110125 var draggable = $ . ui . ddmanager . current ;
111-
112- // Bail if draggable and droppable are same element
113- if ( ! draggable || ( draggable . currentItem || draggable . element ) [ 0 ] === this . element [ 0 ] ) {
114- return ;
115- }
126+ if ( ! draggable || ( ( draggable . currentItem || draggable . element ) [ 0 ] == this . element [ 0 ] && ! this . options . andSelf ) ) return ; // Bail if draggable and droppable are same element
116127
117128 if ( this . accept . call ( this . element [ 0 ] , ( draggable . currentItem || draggable . element ) ) ) {
118- if ( this . options . hoverClass ) {
119- this . element . addClass ( this . options . hoverClass ) ;
129+ if ( ! draggable . options . highest ) {
130+ this . _triggerOver ( event , draggable ) ;
131+ }
132+ else {
133+ var zStack = $ . ui . ddmanager . zStack [ draggable . options . scope ] ;
134+
135+ if ( zStack . indexOf ( this ) == - 1 ) {
136+ var lastHighest = zStack [ zStack . length - 1 ] ;
137+
138+ zStack . push ( this ) ;
139+
140+ zStack . sort ( this . _sortHighest ) ;
141+
142+ var newHighest = zStack [ zStack . length - 1 ] ;
143+
144+ if ( lastHighest !== newHighest ) {
145+ if ( lastHighest != null ) lastHighest . _triggerOut ( event , draggable ) ;
146+ if ( newHighest != null ) newHighest . _triggerOver ( event , draggable ) ;
147+ }
148+ }
120149 }
121- this . _trigger ( "over" , event , this . ui ( draggable ) ) ;
122150 }
123151
124152 } ,
125153
126154 _out : function ( event ) {
127155
128156 var draggable = $ . ui . ddmanager . current ;
129-
130- // Bail if draggable and droppable are same element
131- if ( ! draggable || ( draggable . currentItem || draggable . element ) [ 0 ] === this . element [ 0 ] ) {
132- return ;
133- }
157+ if ( ! draggable || ( ( draggable . currentItem || draggable . element ) [ 0 ] == this . element [ 0 ] && ! this . options . andSelf ) ) return ; // Bail if draggable and droppable are same element
134158
135159 if ( this . accept . call ( this . element [ 0 ] , ( draggable . currentItem || draggable . element ) ) ) {
136- if ( this . options . hoverClass ) {
137- this . element . removeClass ( this . options . hoverClass ) ;
160+ if ( ! draggable . options . highest ) {
161+ this . _triggerOut ( event , draggable ) ;
162+ }
163+ else {
164+ var zStack = $ . ui . ddmanager . zStack [ draggable . options . scope ] ;
165+
166+ var lastHighest = zStack [ zStack . length - 1 ] ;
167+
168+ zStack . splice ( zStack . indexOf ( this ) , 1 ) ;
169+
170+ zStack . sort ( this . _sortHighest ) ;
171+
172+ var newHighest = zStack [ zStack . length - 1 ] ;
173+
174+ if ( lastHighest !== newHighest ) {
175+ if ( lastHighest != null ) lastHighest . _triggerOut ( event , draggable ) ;
176+ if ( newHighest != null ) newHighest . _triggerOver ( event , draggable ) ;
177+ }
138178 }
139- this . _trigger ( "out" , event , this . ui ( draggable ) ) ;
140179 }
141180
142181 } ,
143182
144183 _drop : function ( event , custom ) {
145184
146- var draggable = custom || $ . ui . ddmanager . current ,
147- childrenIntersection = false ;
185+ var draggable = custom || $ . ui . ddmanager . current ;
148186
149- // Bail if draggable and droppable are same element
150- if ( ! draggable || ( draggable . currentItem || draggable . element ) [ 0 ] === this . element [ 0 ] ) {
151- return false ;
187+ if ( ! draggable || ( ( draggable . currentItem || draggable . element ) [ 0 ] == this . element [ 0 ] && ! this . options . andSelf ) ) return false ; // Bail if draggable and droppable are same element
188+
189+ if ( ! draggable . options . highest ) {
190+ return this . _triggerDrop ( event , draggable ) ;
152191 }
192+ else {
193+ var zStack = $ . ui . ddmanager . zStack [ draggable . options . scope ] ;
153194
195+ if ( this == zStack [ zStack . length - 1 ] ) {
196+ return this . _triggerDrop ( event , draggable ) ;
197+ }
198+ }
199+ } ,
200+
201+ _triggerDrop : function ( event , draggable ) {
202+ var childrenIntersection = false ;
154203 this . element . find ( ":data(ui-droppable)" ) . not ( ".ui-draggable-dragging" ) . each ( function ( ) {
155204 var inst = $ . data ( this , "ui-droppable" ) ;
156205 if (
@@ -180,6 +229,21 @@ $.widget("ui.droppable", {
180229
181230 } ,
182231
232+ _sortHighest : function ( a , b ) {
233+ var zIndexA = parseInt ( a . element . css ( "z-index" ) , 10 ) ;
234+ var zIndexB = parseInt ( b . element . css ( "z-index" ) , 10 ) ;
235+
236+ if ( zIndexA !== zIndexB ) {
237+ return zIndexA - zIndexB ;
238+ }
239+
240+ // If elements share a z-index, the element that is later in the DOM is on top.
241+ var indexA = a . element . index ( ) ;
242+ var indexB = b . element . index ( ) ;
243+
244+ return indexA - indexB ;
245+ } ,
246+
183247 ui : function ( c ) {
184248 return {
185249 draggable : ( c . currentItem || c . element ) ,
@@ -237,6 +301,7 @@ $.ui.intersect = function(draggable, droppable, toleranceMode) {
237301$ . ui . ddmanager = {
238302 current : null ,
239303 droppables : { "default" : [ ] } ,
304+ zStack : { 'default' : [ ] } ,
240305 prepareOffsets : function ( t , event ) {
241306
242307 var i , j ,
@@ -253,7 +318,7 @@ $.ui.ddmanager = {
253318
254319 // Filter out elements in the current dragged item
255320 for ( j = 0 ; j < list . length ; j ++ ) {
256- if ( list [ j ] === m [ i ] . element [ 0 ] ) {
321+ if ( list [ j ] === m [ i ] . element [ 0 ] && ! m [ i ] . options . andSelf ) {
257322 m [ i ] . proportions . height = 0 ;
258323 continue droppablesLoop;
259324 }
0 commit comments