From: Mike Sherov Date: Sat, 16 Mar 2013 18:36:06 +0000 (-0400) Subject: Draggable: make sure snap elements are in the document before snapping. Fixes #8459... X-Git-Tag: 1.10.3~54 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=ecabe4754412b61059d429040e266ca921a754b2;p=jquery-ui.git 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.(cherry picked from commit 9d8af804ad4cebe434d420b29467c596809a7cca) --- diff --git a/tests/unit/draggable/draggable_options.js b/tests/unit/draggable/draggable_options.js index 2cb7ec22b..f4fca0b2e 100644 --- a/tests/unit/draggable/draggable_options.js +++ b/tests/unit/draggable/draggable_options.js @@ -1257,6 +1257,39 @@ test( "snap, snapMode, and snapTolerance", function() { deepEqual( element.offset(), { top: newY, left: newX }, "doesn't snap on the inner snapTolerance area when snapMode is outer" ); }); +test( "#8459: element can snap to an element that was removed during drag", function() { + expect( 1 ); + + var newX, newY, + snapTolerance = 15, + element = $( "#draggable1" ).draggable({ + snap: true, + snapMode: "both", + snapTolerance: snapTolerance, + start: function() { + element2.remove(); + } + }), + element2 = $( "#draggable2" ).draggable(); + + element.offset({ + top: 1, + left: 1 + }); + + newX = element2.offset().left - element.outerWidth() - snapTolerance + 1; + newY = element2.offset().top; + + element.simulate( "drag", { + handle: "corner", + x: newX, + y: newY, + moves: 1 + }); + + deepEqual( element.offset(), { top: newY, left: newX }, "doesn't snap to a removed element" ); +}); + test( "#8165: Snapping large rectangles to small rectangles doesn't snap properly", function() { expect( 1 ); diff --git a/ui/jquery.ui.draggable.js b/ui/jquery.ui.draggable.js index 4c8a9d5d5..605425859 100644 --- a/ui/jquery.ui.draggable.js +++ b/ui/jquery.ui.draggable.js @@ -217,9 +217,7 @@ $.widget("ui.draggable", $.ui.mouse, { _mouseStop: function(event) { //If we are using droppables, inform the manager about the drop - var element, - that = this, - elementInDom = false, + var that = this, dropped = false; if ($.ui.ddmanager && !this.options.dropBehaviour) { dropped = $.ui.ddmanager.drop(this, event); @@ -232,13 +230,7 @@ $.widget("ui.draggable", $.ui.mouse, { } //if the original element is no longer in the DOM don't bother to continue (see #8269) - element = this.element[0]; - while ( element && (element = element.parentNode) ) { - if (element === document ) { - elementInDom = true; - } - } - if ( !elementInDom && this.options.helper === "original" ) { + if ( this.options.helper === "original" && !$.contains( this.element[ 0 ].ownerDocument, this.element[ 0 ] ) ) { return false; } @@ -850,7 +842,7 @@ $.ui.plugin.add("draggable", "snap", { t = inst.snapElements[i].top; b = t + inst.snapElements[i].height; - if(x2 < l - d || x1 > r + d || y2 < t - d || y1 > b + d) { + 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 }))); }