Merge commit 'a33f046fa6b05ad2e42f4b3eaf2d0921504f2b4b'

This commit is contained in:
Dylan Weiss 2016-02-23 05:34:55 -05:00
commit 3f374257f2
9 changed files with 246 additions and 23 deletions

View file

@ -15,5 +15,5 @@
"requireTrailingComma": false,
"disallowTrailingWhitespace": true,
"requireCapitalizedComments": false,
"excludeFiles": ["dist/*.js", "demo/*"]
"excludeFiles": ["dist/*.js", "demo/*", "spec/*"]
}

View file

@ -3,6 +3,8 @@ gridstack.js
[![Build Status](https://travis-ci.org/troolee/gridstack.js.svg?branch=master)](https://travis-ci.org/troolee/gridstack.js)
[![Coverage Status](https://coveralls.io/repos/github/troolee/gridstack.js/badge.svg?branch=master)](https://coveralls.io/github/troolee/gridstack.js?branch=master)
[![Dependency Status](https://david-dm.org/troolee/gridstack.js.svg)](https://david-dm.org/troolee/gridstack.js)
[![devDependency Status](https://david-dm.org/troolee/gridstack.js/dev-status.svg)](https://david-dm.org/troolee/gridstack.js#info=devDependencies)
gridstack.js is a jQuery plugin for widget layout. This is drag-and-drop multi-column grid. It allows you to build
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
- [IE8 support](#ie8-support)
- [Nested grids](#nested-grids)
- [Resizing active grid](#resizing-active-grid)
- [The Team](#the-team)
- [Changes](#changes)
- [v0.2.5-dev (Development version)](#v025-dev-development-version)
- [v0.2.4 (2016-02-15)](#v024-2016-02-15)
@ -85,6 +88,8 @@ $ bower install gridstack
* Using npm:
[![NPM version](https://img.shields.io/npm/v/gridstack.svg)](https://www.npmjs.com/package/gridstack)
```bash
$ npm install gridstack
```
@ -436,6 +441,14 @@ Resizing on-the-fly is possible, though experimental. This may be used to make g
See example: [Responsive grid demo](http://troolee.github.io/gridstack.js/demo/responsive.html)
The Team
========
gridstack.js is currently maintained by [Pavel Reznikov](https://github.com/troolee), [Dylan Weiss](https://github.com/radiolips)
and [Kevin Dietrich](https://github.com/kdietrich). And we appreciate [all contributors](https://github.com/troolee/gridstack.js/graphs/contributors)
for help.
Changes
=======

12
dist/gridstack.js vendored
View file

@ -87,11 +87,6 @@
return n != this.node && Utils.isIntercepted(n, this.nn);
},
_didCollideFloat: function(bn) {
return this.n != bn &&
Utils.isIntercepted({x: this.n.x, y: this.newY, width: this.n.width, height: this.n.height}, bn);
},
_didCollide: function(bn) {
return Utils.isIntercepted({x: this.n.x, y: this.newY, width: this.n.width, height: this.n.height}, bn);
},
@ -108,7 +103,7 @@
if (!match) {
throw new Error('Invalid height');
}
heightUnit = match[2];
heightUnit = match[2] || 'px';
height = parseFloat(match[1]);
}
return {height: height, unit: heightUnit};
@ -182,7 +177,7 @@
var collisionNode = _.find(this.nodes, _.bind(function(n) {
return Utils.isIntercepted(n, nn);
}, this));
return collisionNode === null;
return collisionNode === null || typeof collisionNode === 'undefined';
};
GridStackEngine.prototype._sortNodes = function(dir) {
@ -282,7 +277,7 @@
if (this._updateCounter) {
return;
}
var deletedNodes = Array.prototype.slice.call(arguments, 1).concat(this.getDirtyNodes());
var deletedNodes = Array.prototype.slice.call(arguments, 0);
deletedNodes = deletedNodes.concat(this.getDirtyNodes());
this.onchange(deletedNodes);
};
@ -1450,6 +1445,7 @@
scope.GridStackUI = GridStack;
scope.GridStackUI.Utils = Utils;
scope.GridStackUI.Engine = GridStackEngine;
$.fn.gridstack = function(opts) {
return this.each(function() {

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -24,13 +24,18 @@
"url": "https://github.com/troolee/gridstack.js/issues"
},
"homepage": "http://troolee.github.io/gridstack.js/",
"dependencies": {
"jquery": "^2.2.1",
"jquery-ui": "^1.10.5",
"lodash": "^4.5.1"
},
"devDependencies": {
"coveralls": "^2.11.6",
"grunt": "^0.4.5",
"grunt-contrib-copy": "^0.8.2",
"grunt-contrib-cssmin": "^0.14.0",
"grunt-contrib-jshint": "^1.0.0",
"grunt-contrib-uglify": "^0.10.1",
"grunt-contrib-uglify": "^0.11.1",
"grunt-contrib-watch": "^0.6.1",
"grunt-doctoc": "^0.1.1",
"grunt-jscs": "^2.7.0",

View file

@ -0,0 +1,160 @@
describe('gridstack engine', function() {
'use strict';
var e;
var w;
beforeEach(function() {
w = window;
e = w.GridStackUI.Engine;
});
describe('test constructor', function() {
var engine;
beforeAll(function() {
engine = new GridStackUI.Engine(12);
})
it('should be setup properly', function() {
expect(engine.width).toEqual(12);
expect(engine.float).toEqual(false);
expect(engine.height).toEqual(0);
expect(engine.nodes).toEqual([]);
});
});
describe('test _prepareNode', function() {
var engine;
beforeAll(function() {
engine = new GridStackUI.Engine(12);
})
it('should prepare a node', function() {
expect(engine._prepareNode({}, false)).toEqual(jasmine.objectContaining({x: 0, y: 0, width: 1, height: 1}));
expect(engine._prepareNode({x: 10}, false)).toEqual(jasmine.objectContaining({x: 10, y: 0, width: 1, height: 1}));
expect(engine._prepareNode({x: -10}, false)).toEqual(jasmine.objectContaining({x: 0, y: 0, width: 1, height: 1}));
expect(engine._prepareNode({y: 10}, false)).toEqual(jasmine.objectContaining({x: 0, y: 10, width: 1, height: 1}));
expect(engine._prepareNode({y: -10}, false)).toEqual(jasmine.objectContaining({x: 0, y: 0, width: 1, height: 1}));
expect(engine._prepareNode({width: 3}, false)).toEqual(jasmine.objectContaining({x: 0, y: 0, width: 3, height: 1}));
expect(engine._prepareNode({width: 100}, false)).toEqual(jasmine.objectContaining({x: 0, y: 0, width: 12, height: 1}));
expect(engine._prepareNode({width: 0}, false)).toEqual(jasmine.objectContaining({x: 0, y: 0, width: 1, height: 1}));
expect(engine._prepareNode({width: -190}, false)).toEqual(jasmine.objectContaining({x: 0, y: 0, width: 1, height: 1}));
expect(engine._prepareNode({height: 3}, false)).toEqual(jasmine.objectContaining({x: 0, y: 0, width: 1, height: 3}));
expect(engine._prepareNode({height: 0}, false)).toEqual(jasmine.objectContaining({x: 0, y: 0, width: 1, height: 1}));
expect(engine._prepareNode({height: -10}, false)).toEqual(jasmine.objectContaining({x: 0, y: 0, width: 1, height: 1}));
expect(engine._prepareNode({x: 4, width: 10}, false)).toEqual(jasmine.objectContaining({x: 2, y: 0, width: 10, height: 1}));
expect(engine._prepareNode({x: 4, width: 10}, true)).toEqual(jasmine.objectContaining({x: 4, y: 0, width: 8, height: 1}));
});
});
describe('test isAreaEmpty', function() {
var engine;
beforeAll(function() {
engine = new GridStackUI.Engine(12, null, true);
engine.nodes = [
engine._prepareNode({x: 3, y: 2, width: 3, height: 2})
];
})
it('should be true', function() {
expect(engine.isAreaEmpty(0, 0, 3, 2)).toEqual(true);
expect(engine.isAreaEmpty(3, 4, 3, 2)).toEqual(true);
});
it('should be false', function() {
expect(engine.isAreaEmpty(1, 1, 3, 2)).toEqual(false);
expect(engine.isAreaEmpty(2, 3, 3, 2)).toEqual(false);
});
});
describe('test cleanNodes/getDirtyNodes', function() {
var engine;
beforeAll(function() {
engine = new GridStackUI.Engine(12, null, true);
engine.nodes = [
engine._prepareNode({x: 0, y: 0, width: 1, height: 1, idx: 1, _dirty: true}),
engine._prepareNode({x: 3, y: 2, width: 3, height: 2, idx: 2, _dirty: true}),
engine._prepareNode({x: 3, y: 7, width: 3, height: 2, idx: 3})
];
});
beforeEach(function() {
engine._updateCounter = 0;
});
it('should return all dirty nodes', function() {
var nodes = engine.getDirtyNodes();
expect(nodes.length).toEqual(2);
expect(nodes[0].idx).toEqual(1);
expect(nodes[1].idx).toEqual(2);
});
it('should\'n clean nodes if _updateCounter > 0', function() {
engine._updateCounter = 1;
engine.cleanNodes();
expect(engine.getDirtyNodes().length).toBeGreaterThan(0);
});
it('should clean all dirty nodes', function() {
engine.cleanNodes();
expect(engine.getDirtyNodes().length).toEqual(0);
});
});
describe('test _notify', function() {
var engine;
var spy;
beforeEach(function() {
spy = {
callback: function () {}
}
spyOn(spy, 'callback');
engine = new GridStackUI.Engine(12, spy.callback, true);
engine.nodes = [
engine._prepareNode({x: 0, y: 0, width: 1, height: 1, idx: 1, _dirty: true}),
engine._prepareNode({x: 3, y: 2, width: 3, height: 2, idx: 2, _dirty: true}),
engine._prepareNode({x: 3, y: 7, width: 3, height: 2, idx: 3})
];
});
it('should\'n be called if _updateCounter > 0', function() {
engine._updateCounter = 1;
engine._notify();
expect(spy.callback).not.toHaveBeenCalled();
});
it('should by called with dirty nodes', function() {
engine._notify();
expect(spy.callback).toHaveBeenCalledWith([
engine.nodes[0],
engine.nodes[1]
]);
});
it('should by called with extra passed dirty nodes', function() {
var n1 = {idx: -1},
n2 = {idx: -2};
engine._notify(n1, n2);
expect(spy.callback).toHaveBeenCalledWith([
n1,
n2,
engine.nodes[0],
engine.nodes[1]
]);
});
});
});

View file

@ -39,5 +39,59 @@ describe('gridstack utils', function() {
});
describe('test isIntercepted', function() {
var src = {x: 3, y: 2, width: 3, height: 2};
});
it('should intercept.', function() {
expect(utils.isIntercepted(src, {x: 0, y: 0, width: 4, height: 3})).toEqual(true);
expect(utils.isIntercepted(src, {x: 0, y: 0, width: 40, height: 30})).toEqual(true);
expect(utils.isIntercepted(src, {x: 3, y: 2, width: 3, height: 2})).toEqual(true);
expect(utils.isIntercepted(src, {x: 5, y: 3, width: 3, height: 2})).toEqual(true);
});
it('shouldn\'t intercept.', function() {
expect(utils.isIntercepted(src, {x: 0, y: 0, width: 3, height: 2})).toEqual(false);
expect(utils.isIntercepted(src, {x: 0, y: 0, width: 13, height: 2})).toEqual(false);
expect(utils.isIntercepted(src, {x: 1, y: 4, width: 13, height: 2})).toEqual(false);
expect(utils.isIntercepted(src, {x: 0, y: 3, width: 3, height: 2})).toEqual(false);
expect(utils.isIntercepted(src, {x: 6, y: 3, width: 3, height: 2})).toEqual(false);
});
});
describe('test createStylesheet/removeStylesheet', function() {
it('should create/remove style DOM', function() {
var _id = 'test-123';
utils.createStylesheet(_id);
var style = $('STYLE[data-gs-style-id=' + _id + ']');
expect(style.size()).toEqual(1);
expect(style.prop('tagName')).toEqual('STYLE');
utils.removeStylesheet(_id)
style = $('STYLE[data-gs-style-id=' + _id + ']');
expect(style.size()).toEqual(0);
});
});
describe('test parseHeight', function() {
it('should parse height value', function() {
expect(utils.parseHeight(12)).toEqual(jasmine.objectContaining({height: 12, unit: 'px'}));
expect(utils.parseHeight('12px')).toEqual(jasmine.objectContaining({height: 12, unit: 'px'}));
expect(utils.parseHeight('12.3px')).toEqual(jasmine.objectContaining({height: 12.3, unit: 'px'}));
expect(utils.parseHeight('12.3em')).toEqual(jasmine.objectContaining({height: 12.3, unit: 'em'}));
expect(utils.parseHeight('12.3rem')).toEqual(jasmine.objectContaining({height: 12.3, unit: 'rem'}));
expect(utils.parseHeight('12.3vh')).toEqual(jasmine.objectContaining({height: 12.3, unit: 'vh'}));
expect(utils.parseHeight('12.3vw')).toEqual(jasmine.objectContaining({height: 12.3, unit: 'vw'}));
expect(utils.parseHeight('12.5')).toEqual(jasmine.objectContaining({height: 12.5, unit: 'px'}));
expect(function() { utils.parseHeight('12.5 df'); }).toThrowError('Invalid height');
});
});
});

View file

@ -87,11 +87,6 @@
return n != this.node && Utils.isIntercepted(n, this.nn);
},
_didCollideFloat: function(bn) {
return this.n != bn &&
Utils.isIntercepted({x: this.n.x, y: this.newY, width: this.n.width, height: this.n.height}, bn);
},
_didCollide: function(bn) {
return Utils.isIntercepted({x: this.n.x, y: this.newY, width: this.n.width, height: this.n.height}, bn);
},
@ -108,7 +103,7 @@
if (!match) {
throw new Error('Invalid height');
}
heightUnit = match[2];
heightUnit = match[2] || 'px';
height = parseFloat(match[1]);
}
return {height: height, unit: heightUnit};
@ -182,7 +177,7 @@
var collisionNode = _.find(this.nodes, _.bind(function(n) {
return Utils.isIntercepted(n, nn);
}, this));
return collisionNode === null;
return collisionNode === null || typeof collisionNode === 'undefined';
};
GridStackEngine.prototype._sortNodes = function(dir) {
@ -282,7 +277,7 @@
if (this._updateCounter) {
return;
}
var deletedNodes = Array.prototype.slice.call(arguments, 1).concat(this.getDirtyNodes());
var deletedNodes = Array.prototype.slice.call(arguments, 0);
deletedNodes = deletedNodes.concat(this.getDirtyNodes());
this.onchange(deletedNodes);
};