Skip to content

Commit 6f12ba4

Browse files
authored
Merge pull request #2861 from adumesny/master
loading same layout with overlapping widget
2 parents 034a670 + 328a205 commit 6f12ba4

File tree

5 files changed

+74
-13
lines changed

5 files changed

+74
-13
lines changed

spec/e2e/html/2492_load_twice.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ <h1>load twice bug</h1>
2424
];
2525
let count = 0;
2626
items.forEach(n => n.id = String(count++)); // TEST loading with ids
27-
let grid = GridStack.init({cellHeight: 70, margin: 5}).load(items)
27+
let grid = GridStack.init({cellHeight: 70, margin: 5, children: items})
2828
items.forEach(n => n.content += '*')
2929
grid.load(items);
3030
</script>

spec/gridstack-spec.ts

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import { GridItemHTMLElement, GridStack, GridStackNode, GridStackWidget } from '../src/gridstack';
22
import { Utils } from '../src/utils';
3-
import '../dist/gridstack.css';
43

54
describe('gridstack >', function() {
65
'use strict';
@@ -73,10 +72,6 @@ describe('gridstack >', function() {
7372
grids = GridStack.initAll(undefined, 'grid-stack');
7473
expect(grids.length).toBe(1);
7574
});
76-
it('initAll use wrong selector >', function() {
77-
grids = GridStack.initAll(undefined, 'BAD_SELECTOR_TEST');
78-
expect(grids.length).toBe(0);
79-
});
8075
});
8176

8277
describe('grid.setAnimation >', function() {
@@ -766,7 +761,7 @@ describe('gridstack >', function() {
766761
grid = GridStack.init(options);
767762
let items = Utils.getElements('.grid-stack-item');
768763
items.forEach(oldEl => {
769-
let el = grid.addWidget(oldEl);
764+
let el = grid.makeWidget(oldEl);
770765
expect(parseInt(oldEl.getAttribute('gs-x'), 10)).toBe(parseInt(el.getAttribute('gs-x'), 10));
771766
expect(parseInt(oldEl.getAttribute('gs-y'), 10)).toBe(parseInt(el.getAttribute('gs-y'), 10));
772767
})
@@ -780,7 +775,7 @@ describe('gridstack >', function() {
780775
let items = Utils.getElements('.grid-stack-item');
781776
items.forEach(oldEl => {
782777
let el = oldEl.cloneNode(true) as HTMLElement;
783-
el = grid.addWidget(el);
778+
el = grid.makeWidget(el);
784779
expect(parseInt(el.getAttribute('gs-y'), 10)).not.toBe(parseInt(oldEl.getAttribute('gs-y'), 10));
785780
});
786781
});

spec/regression-spec.ts

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
import { GridItemHTMLElement, GridStack, GridStackWidget } from '../src/gridstack';
2+
3+
describe('regression >', function() {
4+
'use strict';
5+
6+
let grid: GridStack;
7+
let findEl = function(id: string): GridItemHTMLElement {
8+
return grid.engine.nodes.find(n => n.id === id)!.el!;
9+
};
10+
11+
// empty grid
12+
let gridstackEmptyHTML =
13+
'<div style="width: 800px; height: 600px" id="gs-cont">' +
14+
' <div class="grid-stack"></div>' +
15+
'</div>';
16+
17+
describe('2492 load() twice >', function() {
18+
beforeEach(function() {
19+
document.body.insertAdjacentHTML('afterbegin', gridstackEmptyHTML);
20+
});
21+
afterEach(function() {
22+
document.body.removeChild(document.getElementById('gs-cont'));
23+
});
24+
it('', function() {
25+
let items: GridStackWidget[] = [
26+
{x: 0, y: 0, w:2, content: '0 wide'},
27+
{x: 1, y: 0, content: '1 over'},
28+
{x: 2, y: 1, content: '2 float'},
29+
];
30+
let count = 0;
31+
items.forEach(n => n.id = String(count++));
32+
grid = GridStack.init({cellHeight: 70, margin: 5}).load(items);
33+
34+
let el0 = findEl('0');
35+
let el1 = findEl('1');
36+
let el2 = findEl('2');
37+
38+
expect(parseInt(el0.getAttribute('gs-x'), 10)).toBe(0);
39+
expect(parseInt(el0.getAttribute('gs-y'), 10)).toBe(0);
40+
expect(el0.children[0].innerHTML).toBe(items[0].content!);
41+
expect(parseInt(el1.getAttribute('gs-x'), 10)).toBe(1);
42+
expect(parseInt(el1.getAttribute('gs-y'), 10)).toBe(1);
43+
expect(parseInt(el2.getAttribute('gs-x'), 10)).toBe(2);
44+
expect(parseInt(el2.getAttribute('gs-y'), 10)).toBe(0);
45+
46+
// loading with changed content should be same positions
47+
items.forEach(n => n.content += '*')
48+
grid.load(items);
49+
expect(parseInt(el0.getAttribute('gs-x'), 10)).toBe(0);
50+
expect(parseInt(el0.getAttribute('gs-y'), 10)).toBe(0);
51+
expect(el0.children[0].innerHTML).toBe(items[0].content!);
52+
expect(parseInt(el1.getAttribute('gs-x'), 10)).toBe(1);
53+
expect(parseInt(el1.getAttribute('gs-y'), 10)).toBe(1);
54+
expect(parseInt(el2.getAttribute('gs-x'), 10)).toBe(2);
55+
expect(parseInt(el2.getAttribute('gs-y'), 10)).toBe(0);
56+
});
57+
});
58+
});

src/gridstack-engine.ts

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -112,8 +112,12 @@ export class GridStackEngine {
112112
if (collide.locked || this._loading || node._moving && !node._skipDown && nn.y > node.y && !this.float &&
113113
// can take space we had, or before where we're going
114114
(!this.collide(collide, {...collide, y: node.y}, node) || !this.collide(collide, {...collide, y: nn.y - collide.h}, node))) {
115+
115116
node._skipDown = (node._skipDown || nn.y > node.y);
116-
moved = this.moveNode(node, {...nn, y: collide.y + collide.h, ...newOpt});
117+
const newNN = {...nn, y: collide.y + collide.h, ...newOpt};
118+
// pretent we moved to where we are now so we can continue any collision checks #2492
119+
moved = this._loading && Utils.samePos(node, newNN) ? true : this.moveNode(node, newNN);
120+
117121
if ((collide.locked || this._loading) && moved) {
118122
Utils.copyPos(nn, node); // moving after lock become our new desired location
119123
} else if (!collide.locked && moved && opt.pack) {
@@ -127,7 +131,9 @@ export class GridStackEngine {
127131
// move collide down *after* where we will be, ignoring where we are now (don't collide with us)
128132
moved = this.moveNode(collide, {...collide, y: nn.y + nn.h, skip: node, ...newOpt});
129133
}
130-
if (!moved) { return didMove; } // break inf loop if we couldn't move after all (ex: maxRow, fixed)
134+
135+
if (!moved) return didMove; // break inf loop if we couldn't move after all (ex: maxRow, fixed)
136+
131137
collide = undefined;
132138
}
133139
return didMove;
@@ -720,7 +726,7 @@ export class GridStackEngine {
720726
}
721727

722728
// now move (to the original ask vs the collision version which might differ) and repack things
723-
if (needToMove) {
729+
if (needToMove && !Utils.samePos(node, nn)) {
724730
node._dirty = true;
725731
Utils.copyPos(node, nn);
726732
}

src/gridstack.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -744,12 +744,13 @@ export class GridStack {
744744

745745
// add back to current list BUT force a collision check if it 'appears' we didn't change to make sure we don't overlap others now
746746
this.engine.nodes.push(item);
747-
if (Utils.samePos(item, w)) {
747+
if (Utils.samePos(item, w) && this.engine.nodes.length > 1) {
748748
this.moveNode(item, { ...w, forceCollide: true });
749-
Utils.copyPos(w, item);
749+
Utils.copyPos(w, item); // use possily updated values before update() is called next (no-op since already moved)
750750
}
751751

752752
this.update(item.el, w);
753+
753754
if (w.subGridOpts?.children) { // update any sub grid as well
754755
const sub = item.el.querySelector('.grid-stack') as GridHTMLElement;
755756
if (sub && sub.gridstack) {
@@ -1312,6 +1313,7 @@ export class GridStack {
13121313
if (w.content !== undefined) {
13131314
const itemContent = el.querySelector('.grid-stack-item-content') as HTMLElement;
13141315
if (itemContent && itemContent.textContent !== w.content) {
1316+
n.content = w.content;
13151317
GridStack.renderCB(itemContent, w);
13161318
// restore any sub-grid back
13171319
if (n.subGrid?.el) {

0 commit comments

Comments
 (0)