Skip to content

Commit c7ec583

Browse files
authored
Merge pull request #1696 from adumesny/master
collision: fix for single grid drag out/in
2 parents 8159e0d + 82e85b2 commit c7ec583

File tree

7 files changed

+15
-61
lines changed

7 files changed

+15
-61
lines changed

doc/CHANGES.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,17 +55,18 @@ Change log
5555

5656
- fix [#1693](https://github.com/gridstack/gridstack.js/issues/1693) `load` after `init()` broken in 4.x
5757
- fix [#1687](https://github.com/gridstack/gridstack.js/issues/1687) drag between 2 grids with `row / maxRow` broken in 4.x
58+
- fix [#1676](https://github.com/gridstack/gridstack.js/issues/1676) drag edge case in/out single grid without acceptWidgets fix broken in 4.x
5859

5960
## 4.0.2 (2021-3-27)
6061

6162
- fix [#1679](https://github.com/gridstack/gridstack.js/issues/1679) `Resizable: {handles:'w/sw'}` broken in 4.x
6263
- fix [#1658](https://github.com/gridstack/gridstack.js/issues/1658) `enableMove(T/F)` not working correctly
63-
- fix `helper: myFunction` now working for H5 case for `dragInOptions` & `setupDragIn()`
64+
- fix `helper: myFunction` now working for H5 case for `dragInOptions` & `setupDragIn()` broken in 3.x
6465
- fix prevent `addGrid()` from creating nested div grid if container already is a '.grid-stack' div
6566

6667
## 4.0.1 (2021-3-20)
6768

68-
- fix [#1669](https://github.com/gridstack/gridstack.js/issues/1669) JQ resize broken
69+
- fix [#1669](https://github.com/gridstack/gridstack.js/issues/1669) JQ resize broken in 4.x
6970
- fix [#1661](https://github.com/gridstack/gridstack.js/issues/1661) serialization of nested grid
7071

7172
## 4.0.0 (2021-3-19)

spec/e2e/html/141_1534_swap.html

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,13 @@ <h1>Swap collision demo</h1>
3737
let size = 1;
3838
let layout = 0;
3939

40-
let grid = GridStack.init({float: false, cellHeight: 70, maxRow: 0, resizable: {handles: 'sw,w,e,se'}});
40+
let opt = {
41+
float: false,
42+
cellHeight: 70,
43+
maxRow: 0,
44+
resizable: {handles: 'sw,w,e,se'}
45+
};
46+
let grid = GridStack.init(opt);
4147
addEvents(grid);
4248

4349
let items = [[ // load 0

src/gridstack-dd.ts

Lines changed: 2 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -76,15 +76,6 @@ export abstract class GridStackDD extends GridStackDDI {
7676
GridStack.prototype._setupAcceptWidget = function(): GridStack {
7777
if (this.opts.staticGrid) return this;
7878

79-
// if we don't accept external widgets (default) we still need to accept dragging within our
80-
// list of items (else we get a no-drop icon on windows)
81-
if (!this.opts.acceptWidgets) {
82-
GridStackDD.get().droppable(this.el, {
83-
accept: (el: GridItemHTMLElement) => el.gridstackNode && el.gridstackNode.grid === this
84-
})
85-
return this;
86-
}
87-
8879
// vars shared across all methods
8980
let gridPos: MousePosition;
9081
let cellHeight: number, cellWidth: number;
@@ -128,6 +119,7 @@ GridStack.prototype._setupAcceptWidget = function(): GridStack {
128119
let node: GridStackNode = el.gridstackNode;
129120
// set accept drop to true on ourself (which we ignore) so we don't get "can't drop" icon in HTML5 mode while moving
130121
if (node && node.grid === this) return true;
122+
if (!this.opts.acceptWidgets) return false;
131123
// check for accept method or class matching
132124
let canAccept = true;
133125
if (typeof this.opts.acceptWidgets === 'function') {
@@ -199,9 +191,6 @@ GridStack.prototype._setupAcceptWidget = function(): GridStack {
199191
node._temporaryRemoved = true; // so we can insert it
200192
}
201193

202-
// we're entering this grid (even if we left another)
203-
delete node._isCursorOutside;
204-
205194
GridStackDD.get().on(el, 'drag', onDrag);
206195
// make sure this is called at least once when going fast #1578
207196
onDrag(event as DragEvent, el, helper);
@@ -477,7 +466,6 @@ GridStack.prototype._onStartMoving = function(el: GridItemHTMLElement, event: Ev
477466
node._prevYPix = ui.position.top;
478467
node._moving = (event.type === 'dragstart'); // 'dropover' are not initially moving so they can go exactly where they enter (will push stuff out of the way)
479468
delete node._lastTried;
480-
delete node._isCursorOutside;
481469

482470
if (event.type === 'dropover' && node._temporaryRemoved) {
483471
// TEST console.log('engine.addNode x=' + node.x);
@@ -504,7 +492,6 @@ GridStack.prototype._leave = function(node: GridStackNode, el: GridItemHTMLEleme
504492
if (!node) return;
505493

506494
if (dropoutEvent) {
507-
node._isCursorOutside = true;
508495
GridStackDD.get().off(el, 'drag'); // no need to track while being outside
509496
}
510497

@@ -535,7 +522,7 @@ GridStack.prototype._dragOrResize = function(el: GridItemHTMLElement, event: Eve
535522
let resizing: boolean;
536523

537524
if (event.type === 'drag') {
538-
if (node._isCursorOutside) return; // handled by dropover
525+
if (node._temporaryRemoved) return; // handled by dropover
539526
let distance = ui.position.top - node._prevYPix;
540527
node._prevYPix = ui.position.top;
541528
Utils.updateScrollPosition(el, ui.position, distance);
@@ -545,19 +532,6 @@ GridStack.prototype._dragOrResize = function(el: GridItemHTMLElement, event: Eve
545532
let top = ui.position.top + (ui.position.top > node._lastUiPosition.top ? -this.opts.marginBottom : this.opts.marginTop);
546533
p.x = Math.round(left / cellWidth);
547534
p.y = Math.round(top / cellHeight);
548-
549-
// if inTrash or outside of the bounds (but not external which is handled by 'dropout' event), temporarily remove it from us
550-
if (node._isAboutToRemove || (!node._isExternal && this.engine.isOutside(p.x, p.y, node))) {
551-
this._leave(node, event.target);
552-
} else {
553-
if (node._temporaryRemoved) {
554-
node.el = this.placeholder;
555-
this.engine.addNode(node);
556-
this.el.appendChild(this.placeholder);
557-
// TEST console.log('drag placeholder');
558-
delete node._temporaryRemoved;
559-
}
560-
}
561535
if (node.x === p.x && node.y === p.y) return; // skip same
562536
// DON'T skip one we tried as we might have failed because of coverage <50% before
563537
// if (node._lastTried && node._lastTried.x === x && node._lastTried.y === y) return;

src/gridstack-ddi.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,8 @@ export class GridStackDDI {
2424
}
2525

2626
/** removes any drag&drop present (called during destroy) */
27-
public remove(_el: GridItemHTMLElement): GridStackDDI {
27+
/* eslint-disable-next-line @typescript-eslint/no-unused-vars */
28+
public remove(el: GridItemHTMLElement): GridStackDDI {
2829
return this; // no-op for static grids
2930
}
3031
}

src/gridstack-engine.ts

Lines changed: 0 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -565,32 +565,6 @@ export class GridStackEngine {
565565
return clone.getRow() <= this.maxRow;
566566
}
567567

568-
/** return true if the passed in node (x,y) is being dragged outside of the grid, and not added to bottom */
569-
public isOutside(x: number, y: number, node: GridStackNode): boolean {
570-
if (node._isCursorOutside) return false; // dragging out is handled by 'dropout' event instead
571-
// simple outside boundaries
572-
if (x < 0 || x >= this.column || y < 0) return true;
573-
if (this.maxRow) return (y >= this.maxRow);
574-
else if (this.float) return false; // infinite grow with no maxRow
575-
576-
// see if dragging PAST bottom (row+1)
577-
let row = this.getRow();
578-
if (y < row || y === 0) return false;
579-
if (y > row) return true;
580-
// else check to see if we can add that item to the bottom... (y == row)
581-
if (!node._temporaryRemoved) {
582-
let clone = new GridStackEngine({
583-
column: this.column,
584-
float: this.float,
585-
nodes: this.nodes.filter(n => n !== node).map(n => {return {...n}})
586-
});
587-
let nn = {...node, x, y};
588-
clone.addNode(nn);
589-
return nn.y === node.y && nn.x === node.x; // didn't actually move, so last row was a drag out and not a new place...
590-
}
591-
return node._temporaryRemoved; // if still outside so we don't flicker back & forth
592-
}
593-
594568
/** true if x,y or w,h are different after clamping to min/max */
595569
public changedPosConstrain(node: GridStackNode, p: GridStackPosition): boolean {
596570
// make sure w,h are set

src/gridstack.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -760,7 +760,7 @@ export class GridStack {
760760
public getCellFromPixel(position: MousePosition, useDocRelative = false): CellPosition {
761761
let box = this.el.getBoundingClientRect();
762762
// console.log(`getBoundingClientRect left: ${box.left} top: ${box.top} w: ${box.w} h: ${box.h}`)
763-
let containerPos;
763+
let containerPos: {top: number, left: number};
764764
if (useDocRelative) {
765765
containerPos = {top: box.top + document.documentElement.scrollTop, left: box.left};
766766
// console.log(`getCellFromPixel scrollTop: ${document.documentElement.scrollTop}`)

src/types.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -326,8 +326,6 @@ export interface GridStackNode extends GridStackWidget {
326326
_dirty?: boolean;
327327
/** @internal */
328328
_updating?: boolean;
329-
/** @internal true if the cursor is outside of the grid, as we get dropout/dropover vs shape being outside */
330-
_isCursorOutside?: boolean;
331329
/** @internal true when over trash/another grid so we don't bother removing drag CSS style that would animate back to old position */
332330
_isAboutToRemove?: boolean;
333331
/** @internal true if item came from outside of the grid -> actual item need to be moved over */

0 commit comments

Comments
 (0)