Skip to content

Commit 9d8af80

Browse files
committed
Draggable: make sure snap elements are in the document before snapping. Fixes #8459 - Draggable: element can snap to an element that was removed during drag.
1 parent bd126a9 commit 9d8af80

File tree

2 files changed

+36
-11
lines changed

2 files changed

+36
-11
lines changed

tests/unit/draggable/draggable_options.js

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1257,6 +1257,39 @@ test( "snap, snapMode, and snapTolerance", function() {
12571257
deepEqual( element.offset(), { top: newY, left: newX }, "doesn't snap on the inner snapTolerance area when snapMode is outer" );
12581258
});
12591259

1260+
test( "#8459: element can snap to an element that was removed during drag", function() {
1261+
expect( 1 );
1262+
1263+
var newX, newY,
1264+
snapTolerance = 15,
1265+
element = $( "#draggable1" ).draggable({
1266+
snap: true,
1267+
snapMode: "both",
1268+
snapTolerance: snapTolerance,
1269+
start: function() {
1270+
element2.remove();
1271+
}
1272+
}),
1273+
element2 = $( "#draggable2" ).draggable();
1274+
1275+
element.offset({
1276+
top: 1,
1277+
left: 1
1278+
});
1279+
1280+
newX = element2.offset().left - element.outerWidth() - snapTolerance + 1;
1281+
newY = element2.offset().top;
1282+
1283+
element.simulate( "drag", {
1284+
handle: "corner",
1285+
x: newX,
1286+
y: newY,
1287+
moves: 1
1288+
});
1289+
1290+
deepEqual( element.offset(), { top: newY, left: newX }, "doesn't snap to a removed element" );
1291+
});
1292+
12601293
test( "#8165: Snapping large rectangles to small rectangles doesn't snap properly", function() {
12611294
expect( 1 );
12621295

ui/jquery.ui.draggable.js

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -217,9 +217,7 @@ $.widget("ui.draggable", $.ui.mouse, {
217217
_mouseStop: function(event) {
218218

219219
//If we are using droppables, inform the manager about the drop
220-
var element,
221-
that = this,
222-
elementInDom = false,
220+
var that = this,
223221
dropped = false;
224222
if ($.ui.ddmanager && !this.options.dropBehaviour) {
225223
dropped = $.ui.ddmanager.drop(this, event);
@@ -232,13 +230,7 @@ $.widget("ui.draggable", $.ui.mouse, {
232230
}
233231

234232
//if the original element is no longer in the DOM don't bother to continue (see #8269)
235-
element = this.element[0];
236-
while ( element && (element = element.parentNode) ) {
237-
if (element === document ) {
238-
elementInDom = true;
239-
}
240-
}
241-
if ( !elementInDom && this.options.helper === "original" ) {
233+
if ( this.options.helper === "original" && !$.contains( this.element[ 0 ].ownerDocument, this.element[ 0 ] ) ) {
242234
return false;
243235
}
244236

@@ -850,7 +842,7 @@ $.ui.plugin.add("draggable", "snap", {
850842
t = inst.snapElements[i].top;
851843
b = t + inst.snapElements[i].height;
852844

853-
if(x2 < l - d || x1 > r + d || y2 < t - d || y1 > b + d) {
845+
if ( x2 < l - d || x1 > r + d || y2 < t - d || y1 > b + d || !$.contains( inst.snapElements[ i ].item.ownerDocument, inst.snapElements[ i ].item ) ) {
854846
if(inst.snapElements[i].snapping) {
855847
(inst.options.snap.release && inst.options.snap.release.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })));
856848
}

0 commit comments

Comments
 (0)