From 1c80735acb20a468300a53f85ef49b065d40af3e Mon Sep 17 00:00:00 2001 From: Zaven Muradyan Date: Sat, 23 Feb 2013 21:55:29 -0800 Subject: [PATCH] Droppable: Changed drop event to loop over a copied array instead of the droppables directly. Fixed #9116 - Droppable: Drop event can cause droppables to remain active if any droppable is created/destroyed in the event handler. --- tests/unit/droppable/droppable.html | 1 + tests/unit/droppable/droppable_events.js | 33 ++++++++++++++++++++++++ ui/jquery.ui.droppable.js | 3 ++- 3 files changed, 36 insertions(+), 1 deletion(-) diff --git a/tests/unit/droppable/droppable.html b/tests/unit/droppable/droppable.html index 7cd5eb0f540..d084464c2c6 100644 --- a/tests/unit/droppable/droppable.html +++ b/tests/unit/droppable/droppable.html @@ -42,6 +42,7 @@

Draggable
Droppable
+
Droppable
 
diff --git a/tests/unit/droppable/droppable_events.js b/tests/unit/droppable/droppable_events.js index 8f842e9425f..707eea1f4a2 100644 --- a/tests/unit/droppable/droppable_events.js +++ b/tests/unit/droppable/droppable_events.js @@ -5,6 +5,39 @@ module("droppable: events"); +test( "droppable destruction/recreation on drop event", function() { + expect( 1 ); + + var config = { + activeClass: "active", + drop: function() { + var element = $( this ), + newDroppable = $( "
" ) + .css({ width: 100, height: 100 }) + .text( "Droppable" ); + element.after( newDroppable ); + element.remove(); + newDroppable.droppable( config ); + } + }, + + draggable = $( "#draggable1" ).draggable(), + droppable1 = $( "#droppable1" ).droppable( config ), + droppable2 = $( "#droppable2" ).droppable( config ), + + droppableOffset = droppable1.offset(), + draggableOffset = draggable.offset(), + dx = droppableOffset.left - draggableOffset.left, + dy = droppableOffset.top - draggableOffset.top; + + draggable.simulate( "drag", { + dx: dx, + dy: dy + }); + + ok( !droppable2.hasClass( "active" ), "subsequent droppable no longer active" ); +}); + // this is here to make JSHint pass "unused", and we don't want to // remove the parameter for when we finally implement $.noop(); diff --git a/ui/jquery.ui.droppable.js b/ui/jquery.ui.droppable.js index 4fbfcde06cf..552b24a5850 100644 --- a/ui/jquery.ui.droppable.js +++ b/ui/jquery.ui.droppable.js @@ -278,7 +278,8 @@ $.ui.ddmanager = { drop: function(draggable, event) { var dropped = false; - $.each($.ui.ddmanager.droppables[draggable.options.scope] || [], function() { + // 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;