From efe3b225179f8f2f3f2c05484f7757f90bc5a27b Mon Sep 17 00:00:00 2001 From: =?utf8?q?Micha=C5=82=20Go=C5=82=C4=99biowski-Owczarek?= Date: Mon, 8 Nov 2021 18:21:03 +0100 Subject: [PATCH] Sortable: Allow 0-height containers to be sortable as in 1.12.1 Note that container specific events will not fire when the dragged element is interacting with zero height containers. Fixes gh-1998 Closes gh-2008 Co-authored-by: A. Wells --- tests/unit/sortable/core.js | 53 ++++++++++++++++ ui/widgets/sortable.js | 121 +++++++++++++++++------------------- 2 files changed, 110 insertions(+), 64 deletions(-) diff --git a/tests/unit/sortable/core.js b/tests/unit/sortable/core.js index 90ec1bd76..2224f04ec 100644 --- a/tests/unit/sortable/core.js +++ b/tests/unit/sortable/core.js @@ -42,4 +42,57 @@ QUnit.test( "ui-sortable-handle applied to appropriate element", function( asser assert.equal( el.find( ".ui-sortable-handle" ).length, 0, "class name removed on destroy" ); } ); +// gh-1998 +QUnit.test( "drag & drop works with a zero-height container", function( assert ) { + var ready = assert.async(); + assert.expect( 3 ); + + var el = $( "" ) + .sortable() + .appendTo( "#qunit-fixture" ); + + function step1() { + el.find( "li" ).eq( 0 ).simulate( "drag", { + dx: 100, + dy: 3, + moves: 3 + } ); + setTimeout( step2 ); + } + + function step2() { + el.find( "li" ).eq( 2 ).simulate( "drag", { + dx: -200, + dy: -3, + moves: 3 + } ); + setTimeout( step3 ); + } + + function step3() { + assert.equal( el.find( "li" ).eq( 0 ).text(), "Item 3" ); + assert.equal( el.find( "li" ).eq( 1 ).text(), "Item 2" ); + assert.equal( el.find( "li" ).eq( 2 ).text(), "Item 1" ); + ready(); + } + + step1(); +} ); + } ); diff --git a/ui/widgets/sortable.js b/ui/widgets/sortable.js index f44b4832a..37ce4b7bb 100644 --- a/ui/widgets/sortable.js +++ b/ui/widgets/sortable.js @@ -421,79 +421,76 @@ return $.widget( "ui.sortable", $.ui.mouse, { this.helper[ 0 ].style.top = this.position.top + "px"; } - //Post events to containers - this._contactContainers( event ); - - if ( this.innermostContainer !== null ) { - - //Do scrolling - if ( o.scroll ) { - if ( this._scroll( event ) !== false ) { + //Do scrolling + if ( o.scroll ) { + if ( this._scroll( event ) !== false ) { - //Update item positions used in position checks - this._refreshItemPositions( true ); + //Update item positions used in position checks + this._refreshItemPositions( true ); - if ( $.ui.ddmanager && !o.dropBehaviour ) { - $.ui.ddmanager.prepareOffsets( this, event ); - } + if ( $.ui.ddmanager && !o.dropBehaviour ) { + $.ui.ddmanager.prepareOffsets( this, event ); } } + } - this.dragDirection = { - vertical: this._getDragVerticalDirection(), - horizontal: this._getDragHorizontalDirection() - }; - - //Rearrange - for ( i = this.items.length - 1; i >= 0; i-- ) { - - //Cache variables and intersection, continue if no intersection - item = this.items[ i ]; - itemElement = item.item[ 0 ]; - intersection = this._intersectsWithPointer( item ); - if ( !intersection ) { - continue; - } - - // Only put the placeholder inside the current Container, skip all - // items from other containers. This works because when moving - // an item from one container to another the - // currentContainer is switched before the placeholder is moved. - // - // Without this, moving items in "sub-sortables" can cause - // the placeholder to jitter between the outer and inner container. - if ( item.instance !== this.currentContainer ) { - continue; - } + this.dragDirection = { + vertical: this._getDragVerticalDirection(), + horizontal: this._getDragHorizontalDirection() + }; - // Cannot intersect with itself - // no useless actions that have been done before - // no action if the item moved is the parent of the item checked - if ( itemElement !== this.currentItem[ 0 ] && - this.placeholder[ intersection === 1 ? - "next" : "prev" ]()[ 0 ] !== itemElement && - !$.contains( this.placeholder[ 0 ], itemElement ) && - ( this.options.type === "semi-dynamic" ? - !$.contains( this.element[ 0 ], itemElement ) : - true - ) - ) { + //Rearrange + for ( i = this.items.length - 1; i >= 0; i-- ) { - this.direction = intersection === 1 ? "down" : "up"; + //Cache variables and intersection, continue if no intersection + item = this.items[ i ]; + itemElement = item.item[ 0 ]; + intersection = this._intersectsWithPointer( item ); + if ( !intersection ) { + continue; + } - if ( this.options.tolerance === "pointer" || - this._intersectsWithSides( item ) ) { - this._rearrange( event, item ); - } else { - break; - } + // Only put the placeholder inside the current Container, skip all + // items from other containers. This works because when moving + // an item from one container to another the + // currentContainer is switched before the placeholder is moved. + // + // Without this, moving items in "sub-sortables" can cause + // the placeholder to jitter between the outer and inner container. + if ( item.instance !== this.currentContainer ) { + continue; + } - this._trigger( "change", event, this._uiHash() ); + // Cannot intersect with itself + // no useless actions that have been done before + // no action if the item moved is the parent of the item checked + if ( itemElement !== this.currentItem[ 0 ] && + this.placeholder[ intersection === 1 ? + "next" : "prev" ]()[ 0 ] !== itemElement && + !$.contains( this.placeholder[ 0 ], itemElement ) && + ( this.options.type === "semi-dynamic" ? + !$.contains( this.element[ 0 ], itemElement ) : + true + ) + ) { + + this.direction = intersection === 1 ? "down" : "up"; + + if ( this.options.tolerance === "pointer" || + this._intersectsWithSides( item ) ) { + this._rearrange( event, item ); + } else { break; } + + this._trigger( "change", event, this._uiHash() ); + break; } } + //Post events to containers + this._contactContainers( event ); + //Interconnect with droppables if ( $.ui.ddmanager ) { $.ui.ddmanager.drag( this, event ); @@ -888,9 +885,7 @@ return $.widget( "ui.sortable", $.ui.mouse, { this.options.axis === "x" || this._isFloating( this.items[ 0 ].item ) : false; - if ( this.innermostContainer !== null ) { - this._refreshItemPositions( fast ); - } + this._refreshItemPositions( fast ); var i, p; @@ -1038,8 +1033,6 @@ return $.widget( "ui.sortable", $.ui.mouse, { } - this.innermostContainer = innermostContainer; - // If no intersecting containers found, return if ( !innermostContainer ) { return; -- 2.39.5