Skip to content

Commit 3f37425

Browse files
committed
Merge commit 'a33f046fa6b05ad2e42f4b3eaf2d0921504f2b4b'
2 parents 9e8d5c3 + a33f046 commit 3f37425

File tree

9 files changed

+246
-23
lines changed

9 files changed

+246
-23
lines changed

.jscsrc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,5 +15,5 @@
1515
"requireTrailingComma": false,
1616
"disallowTrailingWhitespace": true,
1717
"requireCapitalizedComments": false,
18-
"excludeFiles": ["dist/*.js", "demo/*"]
18+
"excludeFiles": ["dist/*.js", "demo/*", "spec/*"]
1919
}

README.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ gridstack.js
33

44
[![Build Status](https://travis-ci.org/troolee/gridstack.js.svg?branch=master)](https://travis-ci.org/troolee/gridstack.js)
55
[![Coverage Status](https://coveralls.io/repos/github/troolee/gridstack.js/badge.svg?branch=master)](https://coveralls.io/github/troolee/gridstack.js?branch=master)
6+
[![Dependency Status](https://david-dm.org/troolee/gridstack.js.svg)](https://david-dm.org/troolee/gridstack.js)
7+
[![devDependency Status](https://david-dm.org/troolee/gridstack.js/dev-status.svg)](https://david-dm.org/troolee/gridstack.js#info=devDependencies)
68

79
gridstack.js is a jQuery plugin for widget layout. This is drag-and-drop multi-column grid. It allows you to build
810
draggable responsive bootstrap v3 friendly layouts. It also works great with [knockout.js](http://knockoutjs.com), [angular.js](https://angularjs.org) and touch devices.
@@ -37,6 +39,7 @@ Join gridstack.js on Slack: https://gridstackjs.troolee.com
3739
- [IE8 support](#ie8-support)
3840
- [Nested grids](#nested-grids)
3941
- [Resizing active grid](#resizing-active-grid)
42+
- [The Team](#the-team)
4043
- [Changes](#changes)
4144
- [v0.2.5-dev (Development version)](#v025-dev-development-version)
4245
- [v0.2.4 (2016-02-15)](#v024-2016-02-15)
@@ -85,6 +88,8 @@ $ bower install gridstack
8588

8689
* Using npm:
8790

91+
[![NPM version](https://img.shields.io/npm/v/gridstack.svg)](https://www.npmjs.com/package/gridstack)
92+
8893
```bash
8994
$ npm install gridstack
9095
```
@@ -436,6 +441,14 @@ Resizing on-the-fly is possible, though experimental. This may be used to make g
436441
See example: [Responsive grid demo](http://troolee.github.io/gridstack.js/demo/responsive.html)
437442

438443

444+
The Team
445+
========
446+
447+
gridstack.js is currently maintained by [Pavel Reznikov](https://github.com/troolee), [Dylan Weiss](https://github.com/radiolips)
448+
and [Kevin Dietrich](https://github.com/kdietrich). And we appreciate [all contributors](https://github.com/troolee/gridstack.js/graphs/contributors)
449+
for help.
450+
451+
439452
Changes
440453
=======
441454

dist/gridstack.js

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -87,11 +87,6 @@
8787
return n != this.node && Utils.isIntercepted(n, this.nn);
8888
},
8989

90-
_didCollideFloat: function(bn) {
91-
return this.n != bn &&
92-
Utils.isIntercepted({x: this.n.x, y: this.newY, width: this.n.width, height: this.n.height}, bn);
93-
},
94-
9590
_didCollide: function(bn) {
9691
return Utils.isIntercepted({x: this.n.x, y: this.newY, width: this.n.width, height: this.n.height}, bn);
9792
},
@@ -108,7 +103,7 @@
108103
if (!match) {
109104
throw new Error('Invalid height');
110105
}
111-
heightUnit = match[2];
106+
heightUnit = match[2] || 'px';
112107
height = parseFloat(match[1]);
113108
}
114109
return {height: height, unit: heightUnit};
@@ -182,7 +177,7 @@
182177
var collisionNode = _.find(this.nodes, _.bind(function(n) {
183178
return Utils.isIntercepted(n, nn);
184179
}, this));
185-
return collisionNode === null;
180+
return collisionNode === null || typeof collisionNode === 'undefined';
186181
};
187182

188183
GridStackEngine.prototype._sortNodes = function(dir) {
@@ -282,7 +277,7 @@
282277
if (this._updateCounter) {
283278
return;
284279
}
285-
var deletedNodes = Array.prototype.slice.call(arguments, 1).concat(this.getDirtyNodes());
280+
var deletedNodes = Array.prototype.slice.call(arguments, 0);
286281
deletedNodes = deletedNodes.concat(this.getDirtyNodes());
287282
this.onchange(deletedNodes);
288283
};
@@ -1450,6 +1445,7 @@
14501445
scope.GridStackUI = GridStack;
14511446

14521447
scope.GridStackUI.Utils = Utils;
1448+
scope.GridStackUI.Engine = GridStackEngine;
14531449

14541450
$.fn.gridstack = function(opts) {
14551451
return this.each(function() {

dist/gridstack.min.js

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/gridstack.min.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,18 @@
2424
"url": "https://github.com/troolee/gridstack.js/issues"
2525
},
2626
"homepage": "http://troolee.github.io/gridstack.js/",
27+
"dependencies": {
28+
"jquery": "^2.2.1",
29+
"jquery-ui": "^1.10.5",
30+
"lodash": "^4.5.1"
31+
},
2732
"devDependencies": {
2833
"coveralls": "^2.11.6",
2934
"grunt": "^0.4.5",
3035
"grunt-contrib-copy": "^0.8.2",
3136
"grunt-contrib-cssmin": "^0.14.0",
3237
"grunt-contrib-jshint": "^1.0.0",
33-
"grunt-contrib-uglify": "^0.10.1",
38+
"grunt-contrib-uglify": "^0.11.1",
3439
"grunt-contrib-watch": "^0.6.1",
3540
"grunt-doctoc": "^0.1.1",
3641
"grunt-jscs": "^2.7.0",

spec/gridstack-engine-spec.js

Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
1+
describe('gridstack engine', function() {
2+
'use strict';
3+
4+
var e;
5+
var w;
6+
7+
beforeEach(function() {
8+
w = window;
9+
e = w.GridStackUI.Engine;
10+
});
11+
12+
describe('test constructor', function() {
13+
var engine;
14+
15+
beforeAll(function() {
16+
engine = new GridStackUI.Engine(12);
17+
})
18+
19+
it('should be setup properly', function() {
20+
expect(engine.width).toEqual(12);
21+
expect(engine.float).toEqual(false);
22+
expect(engine.height).toEqual(0);
23+
expect(engine.nodes).toEqual([]);
24+
});
25+
});
26+
27+
describe('test _prepareNode', function() {
28+
var engine;
29+
30+
beforeAll(function() {
31+
engine = new GridStackUI.Engine(12);
32+
})
33+
34+
it('should prepare a node', function() {
35+
expect(engine._prepareNode({}, false)).toEqual(jasmine.objectContaining({x: 0, y: 0, width: 1, height: 1}));
36+
expect(engine._prepareNode({x: 10}, false)).toEqual(jasmine.objectContaining({x: 10, y: 0, width: 1, height: 1}));
37+
expect(engine._prepareNode({x: -10}, false)).toEqual(jasmine.objectContaining({x: 0, y: 0, width: 1, height: 1}));
38+
expect(engine._prepareNode({y: 10}, false)).toEqual(jasmine.objectContaining({x: 0, y: 10, width: 1, height: 1}));
39+
expect(engine._prepareNode({y: -10}, false)).toEqual(jasmine.objectContaining({x: 0, y: 0, width: 1, height: 1}));
40+
expect(engine._prepareNode({width: 3}, false)).toEqual(jasmine.objectContaining({x: 0, y: 0, width: 3, height: 1}));
41+
expect(engine._prepareNode({width: 100}, false)).toEqual(jasmine.objectContaining({x: 0, y: 0, width: 12, height: 1}));
42+
expect(engine._prepareNode({width: 0}, false)).toEqual(jasmine.objectContaining({x: 0, y: 0, width: 1, height: 1}));
43+
expect(engine._prepareNode({width: -190}, false)).toEqual(jasmine.objectContaining({x: 0, y: 0, width: 1, height: 1}));
44+
expect(engine._prepareNode({height: 3}, false)).toEqual(jasmine.objectContaining({x: 0, y: 0, width: 1, height: 3}));
45+
expect(engine._prepareNode({height: 0}, false)).toEqual(jasmine.objectContaining({x: 0, y: 0, width: 1, height: 1}));
46+
expect(engine._prepareNode({height: -10}, false)).toEqual(jasmine.objectContaining({x: 0, y: 0, width: 1, height: 1}));
47+
expect(engine._prepareNode({x: 4, width: 10}, false)).toEqual(jasmine.objectContaining({x: 2, y: 0, width: 10, height: 1}));
48+
expect(engine._prepareNode({x: 4, width: 10}, true)).toEqual(jasmine.objectContaining({x: 4, y: 0, width: 8, height: 1}));
49+
});
50+
});
51+
52+
describe('test isAreaEmpty', function() {
53+
var engine;
54+
55+
beforeAll(function() {
56+
engine = new GridStackUI.Engine(12, null, true);
57+
engine.nodes = [
58+
engine._prepareNode({x: 3, y: 2, width: 3, height: 2})
59+
];
60+
})
61+
62+
it('should be true', function() {
63+
expect(engine.isAreaEmpty(0, 0, 3, 2)).toEqual(true);
64+
expect(engine.isAreaEmpty(3, 4, 3, 2)).toEqual(true);
65+
});
66+
67+
it('should be false', function() {
68+
expect(engine.isAreaEmpty(1, 1, 3, 2)).toEqual(false);
69+
expect(engine.isAreaEmpty(2, 3, 3, 2)).toEqual(false);
70+
});
71+
});
72+
73+
describe('test cleanNodes/getDirtyNodes', function() {
74+
var engine;
75+
76+
beforeAll(function() {
77+
engine = new GridStackUI.Engine(12, null, true);
78+
engine.nodes = [
79+
engine._prepareNode({x: 0, y: 0, width: 1, height: 1, idx: 1, _dirty: true}),
80+
engine._prepareNode({x: 3, y: 2, width: 3, height: 2, idx: 2, _dirty: true}),
81+
engine._prepareNode({x: 3, y: 7, width: 3, height: 2, idx: 3})
82+
];
83+
});
84+
85+
beforeEach(function() {
86+
engine._updateCounter = 0;
87+
});
88+
89+
it('should return all dirty nodes', function() {
90+
var nodes = engine.getDirtyNodes();
91+
92+
expect(nodes.length).toEqual(2);
93+
expect(nodes[0].idx).toEqual(1);
94+
expect(nodes[1].idx).toEqual(2);
95+
});
96+
97+
it('should\'n clean nodes if _updateCounter > 0', function() {
98+
engine._updateCounter = 1;
99+
engine.cleanNodes();
100+
101+
expect(engine.getDirtyNodes().length).toBeGreaterThan(0);
102+
});
103+
104+
it('should clean all dirty nodes', function() {
105+
engine.cleanNodes();
106+
107+
expect(engine.getDirtyNodes().length).toEqual(0);
108+
});
109+
});
110+
111+
describe('test _notify', function() {
112+
var engine;
113+
var spy;
114+
115+
beforeEach(function() {
116+
spy = {
117+
callback: function () {}
118+
}
119+
spyOn(spy, 'callback');
120+
121+
engine = new GridStackUI.Engine(12, spy.callback, true);
122+
123+
engine.nodes = [
124+
engine._prepareNode({x: 0, y: 0, width: 1, height: 1, idx: 1, _dirty: true}),
125+
engine._prepareNode({x: 3, y: 2, width: 3, height: 2, idx: 2, _dirty: true}),
126+
engine._prepareNode({x: 3, y: 7, width: 3, height: 2, idx: 3})
127+
];
128+
});
129+
130+
it('should\'n be called if _updateCounter > 0', function() {
131+
engine._updateCounter = 1;
132+
engine._notify();
133+
134+
expect(spy.callback).not.toHaveBeenCalled();
135+
});
136+
137+
it('should by called with dirty nodes', function() {
138+
engine._notify();
139+
140+
expect(spy.callback).toHaveBeenCalledWith([
141+
engine.nodes[0],
142+
engine.nodes[1]
143+
]);
144+
});
145+
146+
it('should by called with extra passed dirty nodes', function() {
147+
var n1 = {idx: -1},
148+
n2 = {idx: -2};
149+
150+
engine._notify(n1, n2);
151+
152+
expect(spy.callback).toHaveBeenCalledWith([
153+
n1,
154+
n2,
155+
engine.nodes[0],
156+
engine.nodes[1]
157+
]);
158+
});
159+
});
160+
});

spec/utils-spec.js

Lines changed: 55 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,5 +39,59 @@ describe('gridstack utils', function() {
3939

4040
});
4141

42+
describe('test isIntercepted', function() {
43+
var src = {x: 3, y: 2, width: 3, height: 2};
4244

43-
});
45+
it('should intercept.', function() {
46+
expect(utils.isIntercepted(src, {x: 0, y: 0, width: 4, height: 3})).toEqual(true);
47+
expect(utils.isIntercepted(src, {x: 0, y: 0, width: 40, height: 30})).toEqual(true);
48+
expect(utils.isIntercepted(src, {x: 3, y: 2, width: 3, height: 2})).toEqual(true);
49+
expect(utils.isIntercepted(src, {x: 5, y: 3, width: 3, height: 2})).toEqual(true);
50+
});
51+
52+
it('shouldn\'t intercept.', function() {
53+
expect(utils.isIntercepted(src, {x: 0, y: 0, width: 3, height: 2})).toEqual(false);
54+
expect(utils.isIntercepted(src, {x: 0, y: 0, width: 13, height: 2})).toEqual(false);
55+
expect(utils.isIntercepted(src, {x: 1, y: 4, width: 13, height: 2})).toEqual(false);
56+
expect(utils.isIntercepted(src, {x: 0, y: 3, width: 3, height: 2})).toEqual(false);
57+
expect(utils.isIntercepted(src, {x: 6, y: 3, width: 3, height: 2})).toEqual(false);
58+
});
59+
});
60+
61+
describe('test createStylesheet/removeStylesheet', function() {
62+
63+
it('should create/remove style DOM', function() {
64+
var _id = 'test-123';
65+
66+
utils.createStylesheet(_id);
67+
68+
var style = $('STYLE[data-gs-style-id=' + _id + ']');
69+
70+
expect(style.size()).toEqual(1);
71+
expect(style.prop('tagName')).toEqual('STYLE');
72+
73+
utils.removeStylesheet(_id)
74+
75+
style = $('STYLE[data-gs-style-id=' + _id + ']');
76+
77+
expect(style.size()).toEqual(0);
78+
});
79+
80+
});
81+
82+
describe('test parseHeight', function() {
83+
84+
it('should parse height value', function() {
85+
expect(utils.parseHeight(12)).toEqual(jasmine.objectContaining({height: 12, unit: 'px'}));
86+
expect(utils.parseHeight('12px')).toEqual(jasmine.objectContaining({height: 12, unit: 'px'}));
87+
expect(utils.parseHeight('12.3px')).toEqual(jasmine.objectContaining({height: 12.3, unit: 'px'}));
88+
expect(utils.parseHeight('12.3em')).toEqual(jasmine.objectContaining({height: 12.3, unit: 'em'}));
89+
expect(utils.parseHeight('12.3rem')).toEqual(jasmine.objectContaining({height: 12.3, unit: 'rem'}));
90+
expect(utils.parseHeight('12.3vh')).toEqual(jasmine.objectContaining({height: 12.3, unit: 'vh'}));
91+
expect(utils.parseHeight('12.3vw')).toEqual(jasmine.objectContaining({height: 12.3, unit: 'vw'}));
92+
expect(utils.parseHeight('12.5')).toEqual(jasmine.objectContaining({height: 12.5, unit: 'px'}));
93+
expect(function() { utils.parseHeight('12.5 df'); }).toThrowError('Invalid height');
94+
});
95+
96+
});
97+
});

src/gridstack.js

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -87,11 +87,6 @@
8787
return n != this.node && Utils.isIntercepted(n, this.nn);
8888
},
8989

90-
_didCollideFloat: function(bn) {
91-
return this.n != bn &&
92-
Utils.isIntercepted({x: this.n.x, y: this.newY, width: this.n.width, height: this.n.height}, bn);
93-
},
94-
9590
_didCollide: function(bn) {
9691
return Utils.isIntercepted({x: this.n.x, y: this.newY, width: this.n.width, height: this.n.height}, bn);
9792
},
@@ -108,7 +103,7 @@
108103
if (!match) {
109104
throw new Error('Invalid height');
110105
}
111-
heightUnit = match[2];
106+
heightUnit = match[2] || 'px';
112107
height = parseFloat(match[1]);
113108
}
114109
return {height: height, unit: heightUnit};
@@ -182,7 +177,7 @@
182177
var collisionNode = _.find(this.nodes, _.bind(function(n) {
183178
return Utils.isIntercepted(n, nn);
184179
}, this));
185-
return collisionNode === null;
180+
return collisionNode === null || typeof collisionNode === 'undefined';
186181
};
187182

188183
GridStackEngine.prototype._sortNodes = function(dir) {
@@ -282,7 +277,7 @@
282277
if (this._updateCounter) {
283278
return;
284279
}
285-
var deletedNodes = Array.prototype.slice.call(arguments, 1).concat(this.getDirtyNodes());
280+
var deletedNodes = Array.prototype.slice.call(arguments, 0);
286281
deletedNodes = deletedNodes.concat(this.getDirtyNodes());
287282
this.onchange(deletedNodes);
288283
};

0 commit comments

Comments
 (0)