diff --git a/src/gridstack.js b/src/gridstack.js index e3f0ddc..7396fe5 100644 --- a/src/gridstack.js +++ b/src/gridstack.js @@ -6,1266 +6,1266 @@ * @preserve */ (function(factory) { - if (typeof define === 'function' && define.amd) { - define(['jquery', 'lodash', 'jquery-ui/core', 'jquery-ui/widget', 'jquery-ui/mouse', 'jquery-ui/draggable', - 'jquery-ui/resizable'], factory); - } else if (typeof exports !== 'undefined') { - try { jQuery = require('jquery'); } catch (e) {} - try { _ = require('lodash'); } catch (e) {} - factory(jQuery, _); - } else { - factory(jQuery, _); - } + if (typeof define === 'function' && define.amd) { + define(['jquery', 'lodash', 'jquery-ui/core', 'jquery-ui/widget', 'jquery-ui/mouse', 'jquery-ui/draggable', + 'jquery-ui/resizable'], factory); + } else if (typeof exports !== 'undefined') { + try { jQuery = require('jquery'); } catch (e) {} + try { _ = require('lodash'); } catch (e) {} + factory(jQuery, _); + } else { + factory(jQuery, _); + } })(function($, _) { - var scope = window; - - var obsolete = function(f, oldName, newName) { - var wrapper = function() { - console.warn('gridstack.js: Function `' + oldName + '` is deprecated as of v0.2.5 and has been replaced with `' + - newName + '`. It will be **completely** removed in v1.0.'); - return f.apply(this, arguments); - }; - wrapper.prototype = f.prototype; - - return wrapper; - }; - - var obsoleteOpts = function(oldName, newName) { - console.warn('gridstack.js: Option `' + oldName + '` is deprecated as of v0.2.5 and has been replaced with `' + - newName + '`. It will be **completely** removed in v1.0.'); - }; - - var Utils = { - isIntercepted: function(a, b) { - return !(a.x + a.width <= b.x || b.x + b.width <= a.x || a.y + a.height <= b.y || b.y + b.height <= a.y); - }, - - sort: function(nodes, dir, width) { - width = width || _.chain(nodes).map(function(node) { return node.x + node.width; }).max().value(); - dir = dir != -1 ? 1 : -1; - return _.sortBy(nodes, function(n) { return dir * (n.x + n.y * width); }); - }, - - createStylesheet: function(id) { - var style = document.createElement('style'); - style.setAttribute('type', 'text/css'); - style.setAttribute('data-gs-id', id); - if (style.styleSheet) { - style.styleSheet.cssText = ''; - } else { - style.appendChild(document.createTextNode('')); - } - document.getElementsByTagName('head')[0].appendChild(style); - return style.sheet; - }, - - removeStylesheet: function(id) { - $('STYLE[data-gs-id=' + id + ']').remove(); - }, - - insertCSSRule: function(sheet, selector, rules, index) { - if (typeof sheet.insertRule === 'function') { - sheet.insertRule(selector + '{' + rules + '}', index); - } else if (typeof sheet.addRule === 'function') { - sheet.addRule(selector, rules, index); - } - }, - - toBool: function(v) { - if (typeof v == 'boolean') { - return v; - } - if (typeof v == 'string') { - v = v.toLowerCase(); - return !(v === '' || v == 'no' || v == 'false' || v == '0'); - } - return Boolean(v); - }, - - _collisionNodeCheck: function(n) { - 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); - }, - - _isAddNodeIntercepted: function(n) { - return Utils.isIntercepted({x: this.x, y: this.y, width: this.node.width, height: this.node.height}, n); - } - }; - - // jscs:disable requireCamelCaseOrUpperCaseIdentifiers - Utils.is_intercepted = obsolete(Utils.isIntercepted, 'is_intercepted', 'isIntercepted'); - - Utils.create_stylesheet = obsolete(Utils.createStylesheet, 'create_stylesheet', 'createStylesheet'); - - Utils.remove_stylesheet = obsolete(Utils.removeStylesheet, 'remove_stylesheet', 'removeStylesheet'); - - Utils.insert_css_rule = obsolete(Utils.insertCSSRule, 'insert_css_rule', 'insertCSSRule'); - // jscs:enable requireCamelCaseOrUpperCaseIdentifiers - - var idSeq = 0; - - var GridStackEngine = function(width, onchange, floatMode, height, items) { - this.width = width; - this.float = floatMode || false; - this.height = height || 0; - - this.nodes = items || []; - this.onchange = onchange || function() {}; - - this._updateCounter = 0; - this._float = this.float; - }; - - GridStackEngine.prototype.batchUpdate = function() { - this._updateCounter = 1; - this.float = true; - }; - - GridStackEngine.prototype.commit = function() { - this._updateCounter = 0; - if (this._updateCounter === 0) { - this.float = this._float; - this._packNodes(); - this._notify(); - } - }; - - GridStackEngine.prototype._fixCollisions = function(node) { - var self = this; - this._sortNodes(-1); - - var nn = node; - var hasLocked = Boolean(_.find(this.nodes, function(n) { return n.locked; })); - if (!this.float && !hasLocked) { - nn = {x: 0, y: node.y, width: this.width, height: node.height}; - } - while (true) { - var collisionNode = _.find(this.nodes, _.bind(Utils._collisionNodeCheck, {node: node, nn: nn})); - if (typeof collisionNode == 'undefined') { - return; - } - this.moveNode(collisionNode, collisionNode.x, node.y + node.height, - collisionNode.width, collisionNode.height, true); - } - }; - - GridStackEngine.prototype.isAreaEmpty = function(x, y, width, height) { - var nn = {x: x || 0, y: y || 0, width: width || 1, height: height || 1}; - var collisionNode = _.find(this.nodes, _.bind(function(n) { - return Utils.isIntercepted(n, nn); - }, this)); - return collisionNode === null; - }; - - GridStackEngine.prototype._sortNodes = function(dir) { - this.nodes = Utils.sort(this.nodes, dir, this.width); - }; - - GridStackEngine.prototype._packNodes = function() { - this._sortNodes(); - - if (this.float) { - _.each(this.nodes, _.bind(function(n, i) { - if (n._updating || typeof n._origY == 'undefined' || n.y == n._origY) { - return; - } - - var newY = n.y; - while (newY >= n._origY) { - var collisionNode = _.chain(this.nodes) - .find(_.bind(Utils._didCollide, {n: n, newY: newY})) - .value(); - - if (!collisionNode) { - n._dirty = true; - n.y = newY; - } - --newY; - } - }, this)); - } else { - _.each(this.nodes, _.bind(function(n, i) { - if (n.locked) { - return; - } - while (n.y > 0) { - var newY = n.y - 1; - var canBeMoved = i === 0; - - if (i > 0) { - var collisionNode = _.chain(this.nodes) - .take(i) - .find(_.bind(Utils._didCollide, {n: n, newY: newY})) - .value(); - canBeMoved = typeof collisionNode == 'undefined'; - } - - if (!canBeMoved) { - break; - } - n._dirty = n.y != newY; - n.y = newY; - } - }, this)); - } - }; - - GridStackEngine.prototype._prepareNode = function(node, resizing) { - node = _.defaults(node || {}, {width: 1, height: 1, x: 0, y: 0}); - - node.x = parseInt('' + node.x); - node.y = parseInt('' + node.y); - node.width = parseInt('' + node.width); - node.height = parseInt('' + node.height); - node.autoPosition = node.autoPosition || false; - node.noResize = node.noResize || false; - node.noMove = node.noMove || false; - - if (node.width > this.width) { - node.width = this.width; - } else if (node.width < 1) { - node.width = 1; - } - - if (node.height < 1) { - node.height = 1; - } - - if (node.x < 0) { - node.x = 0; - } - - if (node.x + node.width > this.width) { - if (resizing) { - node.width = this.width - node.x; - } else { - node.x = this.width - node.width; - } - } - - if (node.y < 0) { - node.y = 0; - } - - return node; - }; - - GridStackEngine.prototype._notify = function() { - if (this._updateCounter) { - return; - } - var deletedNodes = Array.prototype.slice.call(arguments, 1).concat(this.getDirtyNodes()); - deletedNodes = deletedNodes.concat(this.getDirtyNodes()); - this.onchange(deletedNodes); - }; - - GridStackEngine.prototype.cleanNodes = function() { - _.each(this.nodes, function(n) {n._dirty = false; }); - }; - - GridStackEngine.prototype.getDirtyNodes = function() { - return _.filter(this.nodes, function(n) { return n._dirty; }); - }; - - GridStackEngine.prototype.addNode = function(node) { - node = this._prepareNode(node); - - if (typeof node.maxWidth != 'undefined') { node.width = Math.min(node.width, node.maxWidth); } - if (typeof node.maxHeight != 'undefined') { node.height = Math.min(node.height, node.maxHeight); } - if (typeof node.minWidth != 'undefined') { node.width = Math.max(node.width, node.minWidth); } - if (typeof node.minHeight != 'undefined') { node.height = Math.max(node.height, node.minHeight); } - - node._id = ++idSeq; - node._dirty = true; - - if (node.autoPosition) { - this._sortNodes(); - - for (var i = 0;; ++i) { - var x = i % this.width; - var y = Math.floor(i / this.width); - if (x + node.width > this.width) { - continue; - } - if (!_.find(this.nodes, _.bind(Utils._isAddNodeIntercepted, {x: x, y: y, node: node}))) { - node.x = x; - node.y = y; - break; - } - } - } - - this.nodes.push(node); - - this._fixCollisions(node); - this._packNodes(); - this._notify(); - return node; - }; - - GridStackEngine.prototype.removeNode = function(node) { - node._id = null; - this.nodes = _.without(this.nodes, node); - this._packNodes(); - this._notify(node); - }; - - GridStackEngine.prototype.canMoveNode = function(node, x, y, width, height) { - var hasLocked = Boolean(_.find(this.nodes, function(n) { return n.locked; })); - - if (!this.height && !hasLocked) { - return true; - } - - var clonedNode; - var clone = new GridStackEngine( - this.width, - null, - this.float, - 0, - _.map(this.nodes, function(n) { - if (n == node) { - clonedNode = $.extend({}, n); - return clonedNode; - } - return $.extend({}, n); - })); - - clone.moveNode(clonedNode, x, y, width, height); - - var res = true; - - if (hasLocked) { - res &= !Boolean(_.find(clone.nodes, function(n) { - return n != clonedNode && Boolean(n.locked) && Boolean(n._dirty); - })); - } - if (this.height) { - res &= clone.getGridHeight() <= this.height; - } - - return res; - }; - - GridStackEngine.prototype.canBePlacedWithRespectToHeight = function(node) { - if (!this.height) { - return true; - } - - var clone = new GridStackEngine( - this.width, - null, - this.float, - 0, - _.map(this.nodes, function(n) { return $.extend({}, n); })); - clone.addNode(node); - return clone.getGridHeight() <= this.height; - }; - - GridStackEngine.prototype.moveNode = function(node, x, y, width, height, noPack) { - if (typeof x != 'number') { x = node.x; } - if (typeof y != 'number') { y = node.y; } - if (typeof width != 'number') { width = node.width; } - if (typeof height != 'number') { height = node.height; } - - if (typeof node.maxWidth != 'undefined') { width = Math.min(width, node.maxWidth); } - if (typeof node.maxHeight != 'undefined') { height = Math.min(height, node.maxHeight); } - if (typeof node.minWidth != 'undefined') { width = Math.max(width, node.minWidth); } - if (typeof node.minHeight != 'undefined') { height = Math.max(height, node.minHeight); } - - if (node.x == x && node.y == y && node.width == width && node.height == height) { - return node; - } - - var resizing = node.width != width; - node._dirty = true; - - node.x = x; - node.y = y; - node.width = width; - node.height = height; - - node = this._prepareNode(node, resizing); - - this._fixCollisions(node); - if (!noPack) { - this._packNodes(); - this._notify(); - } - return node; - }; - - GridStackEngine.prototype.getGridHeight = function() { - return _.reduce(this.nodes, function(memo, n) { return Math.max(memo, n.y + n.height); }, 0); - }; - - GridStackEngine.prototype.beginUpdate = function(node) { - _.each(this.nodes, function(n) { - n._origY = n.y; - }); - node._updating = true; - }; - - GridStackEngine.prototype.endUpdate = function() { - _.each(this.nodes, function(n) { - n._origY = n.y; - }); - var n = _.find(this.nodes, function(n) { return n._updating; }); - if (n) { - n._updating = false; - } - }; - - var GridStack = function(el, opts) { - var self = this; - var oneColumnMode; - - opts = opts || {}; - - this.container = $(el); - - // jscs:disable requireCamelCaseOrUpperCaseIdentifiers - if (typeof opts.handle_class !== 'undefined') { - opts.handleClass = opts.handle_class; - obsoleteOpts('handle_class', 'handleClass'); - } - if (typeof opts.item_class !== 'undefined') { - opts.itemClass = opts.item_class; - obsoleteOpts('item_class', 'itemClass'); - } - if (typeof opts.placeholder_class !== 'undefined') { - opts.placeholderClass = opts.placeholder_class; - obsoleteOpts('placeholder_class', 'placeholderClass'); - } - if (typeof opts.placeholder_text !== 'undefined') { - opts.placeholderText = opts.placeholder_text; - obsoleteOpts('placeholder_text', 'placeholderText'); - } - if (typeof opts.item_class !== 'undefined') { - opts.itemClass = opts.item_class; - obsoleteOpts('item_class', 'itemClass'); - } - if (typeof opts.cell_height !== 'undefined') { - opts.cellHeight = opts.cell_height; - obsoleteOpts('cell_height', 'cellHeight'); - } - if (typeof opts.vertical_margin !== 'undefined') { - opts.verticalMargin = opts.vertical_margin; - obsoleteOpts('vertical_margin', 'verticalMargin'); - } - if (typeof opts.min_width !== 'undefined') { - opts.minWidth = opts.min_width; - obsoleteOpts('min_width', 'minWidth'); - } - if (typeof opts.static_grid !== 'undefined') { - opts.staticGrid = opts.static_grid; - obsoleteOpts('static_grid', 'staticGrid'); - } - if (typeof opts.is_nested !== 'undefined') { - opts.isNested = opts.is_nested; - obsoleteOpts('is_nested', 'isNested'); - } - if (typeof opts.always_show_resize_handle !== 'undefined') { - opts.alwaysShowResizeHandle = opts.always_show_resize_handle; - obsoleteOpts('always_show_resize_handle', 'alwaysShowResizeHandle'); - } - // jscs:enable requireCamelCaseOrUpperCaseIdentifiers - - opts.itemClass = opts.itemClass || 'grid-stack-item'; - var isNested = this.container.closest('.' + opts.itemClass).size() > 0; - - this.opts = _.defaults(opts || {}, { - width: parseInt(this.container.attr('data-gs-width')) || 12, - height: parseInt(this.container.attr('data-gs-height')) || 0, - itemClass: 'grid-stack-item', - placeholderClass: 'grid-stack-placeholder', - placeholderText: '', - handle: '.grid-stack-item-content', - handleClass: null, - cellHeight: 60, - verticalMargin: 20, - auto: true, - minWidth: 768, - float: false, - staticGrid: false, - _class: 'grid-stack-instance-' + (Math.random() * 10000).toFixed(0), - animate: Boolean(this.container.attr('data-gs-animate')) || false, - alwaysShowResizeHandle: opts.alwaysShowResizeHandle || false, - resizable: _.defaults(opts.resizable || {}, { - autoHide: !(opts.alwaysShowResizeHandle || false), - handles: 'se' - }), - draggable: _.defaults(opts.draggable || {}, { - handle: (opts.handleClass ? '.' + opts.handleClass : (opts.handle ? opts.handle : '')) || - '.grid-stack-item-content', - scroll: false, - appendTo: 'body' - }) - }); - this.opts.isNested = isNested; - - this.cellHeight(this.opts.cellHeight, true); - this.verticalMargin(this.opts.verticalMargin, true); - - this.container.addClass(this.opts._class); - - this._setStaticClass(); - - if (isNested) { - this.container.addClass('grid-stack-nested'); - } - - this._initStyles(); - - this.grid = new GridStackEngine(this.opts.width, function(nodes) { - var maxHeight = 0; - _.each(nodes, function(n) { - if (n._id === null) { - n.el.remove(); - } else { - n.el - .attr('data-gs-x', n.x) - .attr('data-gs-y', n.y) - .attr('data-gs-width', n.width) - .attr('data-gs-height', n.height); - maxHeight = Math.max(maxHeight, n.y + n.height); - } - }); - self._updateStyles(maxHeight + 10); - }, this.opts.float, this.opts.height); - - if (this.opts.auto) { - var elements = []; - var _this = this; - this.container.children('.' + this.opts.itemClass + ':not(.' + this.opts.placeholderClass + ')') - .each(function(index, el) { - el = $(el); - elements.push({ - el: el, - i: parseInt(el.attr('data-gs-x')) + parseInt(el.attr('data-gs-y')) * _this.opts.width - }); - }); - _.chain(elements).sortBy(function(x) { return x.i; }).each(function(i) { - self._prepareElement(i.el); - }).value(); - } - - this.setAnimation(this.opts.animate); - - this.placeholder = $( - '
' + - '
' + this.opts.placeholderText + '
').hide(); - - this._updateContainerHeight(); - - this.onResizeHandler = function() { - if (self._isOneColumnMode()) { - if (oneColumnMode) { - return; - } - - oneColumnMode = true; - - self.grid._sortNodes(); - _.each(self.grid.nodes, function(node) { - self.container.append(node.el); - - if (self.opts.staticGrid) { - return; - } - if (!node.noMove) { - node.el.draggable('disable'); - } - if (!node.noResize) { - node.el.resizable('disable'); - } - }); - } else { - if (!oneColumnMode) { - return; - } - - oneColumnMode = false; - - if (self.opts.staticGrid) { - return; - } - - _.each(self.grid.nodes, function(node) { - if (!node.noMove) { - node.el.draggable('enable'); - } - if (!node.noResize) { - node.el.resizable('enable'); - } - }); - } - }; - - $(window).resize(this.onResizeHandler); - this.onResizeHandler(); - }; - - GridStack.prototype._triggerChangeEvent = function(forceTrigger) { - var elements = this.grid.getDirtyNodes(); - var hasChanges = false; - - var eventParams = []; - if (elements && elements.length) { - eventParams.push(elements); - hasChanges = true; - } - - if (hasChanges || forceTrigger === true) { - this.container.trigger('change', eventParams); - } - }; - - GridStack.prototype._initStyles = function() { - if (!this.opts.cellHeight) { //that will be handled by CSS - return ; - } - if (this._stylesId) { - $('[data-gs-id="' + this._stylesId + '"]').remove(); - } - this._stylesId = 'gridstack-style-' + (Math.random() * 100000).toFixed(); - this._styles = Utils.createStylesheet(this._stylesId); - if (this._styles != null) { - this._styles._max = 0; - } - }; - - GridStack.prototype._updateStyles = function(maxHeight) { - if (this._styles === null) { - return; - } - - var prefix = '.' + this.opts._class + ' .' + this.opts.itemClass; - var self = this; - var getHeight; - - if (typeof maxHeight == 'undefined') { - maxHeight = this._styles._max; - this._initStyles(); - this._updateContainerHeight(); - } - if (!this.opts.cellHeight) { //the rest will be handled by CSS - return ; - } - if (this._styles._max !== 0 && maxHeight <= this._styles._max) { - return ; - } - - if (!this.opts.verticalMargin || this.opts.cellHeightUnit === this.opts.verticalMarginUnit) { - getHeight = function(nbRows, nbMargins) { - return (self.opts.cellHeight * nbRows + self.opts.verticalMargin * nbMargins) + self.opts.cellHeightUnit; - }; - } else { - getHeight = function(nbRows, nbMargins) { - if (!nbRows || !nbMargins) { - return (self.opts.cellHeight * nbRows + self.opts.verticalMargin * nbMargins) + self.opts.cellHeightUnit; - } - return 'calc(' + ((self.opts.cellHeight * nbRows) + self.opts.cellHeightUnit) + ' + ' + - ((self.opts.verticalMargin * nbMargins) + self.opts.verticalMarginUnit) + ')'; - }; - } - - if (this._styles._max === 0) { - Utils.insertCSSRule(this._styles, prefix, 'min-height: ' + getHeight(1, 0) + ';', 0); - } - - if (maxHeight > this._styles._max) { - for (var i = this._styles._max; i < maxHeight; ++i) { - Utils.insertCSSRule(this._styles, - prefix + '[data-gs-height="' + (i + 1) + '"]', - 'height: ' + getHeight(i + 1, i) + ';', - i - ); - Utils.insertCSSRule(this._styles, - prefix + '[data-gs-min-height="' + (i + 1) + '"]', - 'min-height: ' + getHeight(i + 1, i) + ';', - i - ); - Utils.insertCSSRule(this._styles, - prefix + '[data-gs-max-height="' + (i + 1) + '"]', - 'max-height: ' + getHeight(i + 1, i) + ';', - i - ); - Utils.insertCSSRule(this._styles, - prefix + '[data-gs-y="' + i + '"]', - 'top: ' + getHeight(i, i) + ';', - i - ); - } - this._styles._max = maxHeight; - } - }; - - GridStack.prototype._updateContainerHeight = function() { - if (this.grid._updateCounter) { - return; - } - var height = this.grid.getGridHeight(); - this.container.attr('data-gs-current-height', height); - if (!this.opts.cellHeight) { - return ; - } - if (!this.opts.verticalMargin) { - this.container.css('height', (height * (this.opts.cellHeight)) + this.opts.cellHeightUnit); - } else if (this.opts.cellHeightUnit === this.opts.verticalMarginUnit) { - this.container.css('height', (height * (this.opts.cellHeight + this.opts.verticalMargin) - - this.opts.verticalMargin) + this.opts.cellHeightUnit); - } else { - this.container.css('height', 'calc(' + ((height * (this.opts.cellHeight)) + this.opts.cellHeightUnit) + - ' + ' + ((height * (this.opts.verticalMargin - 1)) + this.opts.verticalMarginUnit) + ')'); - } - }; - - GridStack.prototype._isOneColumnMode = function() { - return (window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth) <= - this.opts.minWidth; - }; - - GridStack.prototype._prepareElement = function(el) { - var self = this; - el = $(el); - - el.addClass(this.opts.itemClass); - var node = self.grid.addNode({ - x: el.attr('data-gs-x'), - y: el.attr('data-gs-y'), - width: el.attr('data-gs-width'), - height: el.attr('data-gs-height'), - maxWidth: el.attr('data-gs-max-width'), - minWidth: el.attr('data-gs-min-width'), - maxHeight: el.attr('data-gs-max-height'), - minHeight: el.attr('data-gs-min-height'), - autoPosition: Utils.toBool(el.attr('data-gs-auto-position')), - noResize: Utils.toBool(el.attr('data-gs-no-resize')), - noMove: Utils.toBool(el.attr('data-gs-no-move')), - locked: Utils.toBool(el.attr('data-gs-locked')), - el: el - }); - el.data('_gridstack_node', node); - - if (self.opts.staticGrid) { - return; - } - - var cellWidth; - var cellHeight; - - var dragOrResize = function(event, ui) { - var x = Math.round(ui.position.left / cellWidth); - var y = Math.floor((ui.position.top + cellHeight / 2) / cellHeight); - var width; - var height; - if (event.type != 'drag') { - width = Math.round(ui.size.width / cellWidth); - height = Math.round(ui.size.height / cellHeight); - } - - if (!self.grid.canMoveNode(node, x, y, width, height)) { - return; - } - self.grid.moveNode(node, x, y, width, height); - self._updateContainerHeight(); - }; - - var onStartMoving = function(event, ui) { - self.container.append(self.placeholder); - var o = $(this); - self.grid.cleanNodes(); - self.grid.beginUpdate(node); - cellWidth = Math.ceil(o.outerWidth() / o.attr('data-gs-width')); - var strictCellHeight = Math.ceil(o.outerHeight() / o.attr('data-gs-height')); - cellHeight = self.container.height() / parseInt(self.container.attr('data-gs-current-height')); - self.placeholder - .attr('data-gs-x', o.attr('data-gs-x')) - .attr('data-gs-y', o.attr('data-gs-y')) - .attr('data-gs-width', o.attr('data-gs-width')) - .attr('data-gs-height', o.attr('data-gs-height')) - .show(); - node.el = self.placeholder; - - el.resizable('option', 'minWidth', cellWidth * (node.minWidth || 1)); - el.resizable('option', 'minHeight', strictCellHeight * (node.minHeight || 1)); - - if (event.type == 'resizestart') { - o.find('.grid-stack-item').trigger('resizestart'); - } - }; - - var onEndMoving = function(event, ui) { - self.placeholder.detach(); - var o = $(this); - node.el = o; - self.placeholder.hide(); - o - .attr('data-gs-x', node.x) - .attr('data-gs-y', node.y) - .attr('data-gs-width', node.width) - .attr('data-gs-height', node.height) - .removeAttr('style'); - self._updateContainerHeight(); - self._triggerChangeEvent(); - - self.grid.endUpdate(); - - var nestedGrids = o.find('.grid-stack'); - if (nestedGrids.length && event.type == 'resizestop') { - nestedGrids.each(function(index, el) { - $(el).data('gridstack').onResizeHandler(); - }); - o.find('.grid-stack-item').trigger('resizestop'); - } - }; - - el - .draggable(_.extend(this.opts.draggable, { - containment: this.opts.isNested ? this.container.parent() : null, - start: onStartMoving, - stop: onEndMoving, - drag: dragOrResize - })) - .resizable(_.extend(this.opts.resizable, { - start: onStartMoving, - stop: onEndMoving, - resize: dragOrResize - })); - - if (node.noMove || this._isOneColumnMode()) { - el.draggable('disable'); - } - - if (node.noResize || this._isOneColumnMode()) { - el.resizable('disable'); - } - - el.attr('data-gs-locked', node.locked ? 'yes' : null); - }; - - GridStack.prototype.setAnimation = function(enable) { - if (enable) { - this.container.addClass('grid-stack-animate'); - } else { - this.container.removeClass('grid-stack-animate'); - } - }; - - GridStack.prototype.addWidget = function(el, x, y, width, height, autoPosition) { - el = $(el); - if (typeof x != 'undefined') { el.attr('data-gs-x', x); } - if (typeof y != 'undefined') { el.attr('data-gs-y', y); } - if (typeof width != 'undefined') { el.attr('data-gs-width', width); } - if (typeof height != 'undefined') { el.attr('data-gs-height', height); } - if (typeof autoPosition != 'undefined') { el.attr('data-gs-auto-position', autoPosition ? 'yes' : null); } - this.container.append(el); - this._prepareElement(el); - this._updateContainerHeight(); - this._triggerChangeEvent(true); - - return el; - }; - - GridStack.prototype.makeWidget = function(el) { - el = $(el); - this._prepareElement(el); - this._updateContainerHeight(); - this._triggerChangeEvent(true); - - return el; - }; - - GridStack.prototype.willItFit = function(x, y, width, height, autoPosition) { - var node = {x: x, y: y, width: width, height: height, autoPosition: autoPosition}; - return this.grid.canBePlacedWithRespectToHeight(node); - }; - - GridStack.prototype.removeWidget = function(el, detachNode) { - detachNode = typeof detachNode === 'undefined' ? true : detachNode; - el = $(el); - var node = el.data('_gridstack_node'); - this.grid.removeNode(node); - el.removeData('_gridstack_node'); - this._updateContainerHeight(); - if (detachNode) { - el.remove(); - } - this._triggerChangeEvent(true); - }; - - GridStack.prototype.removeAll = function(detachNode) { - _.each(this.grid.nodes, _.bind(function(node) { - this.removeWidget(node.el, detachNode); - }, this)); - this.grid.nodes = []; - this._updateContainerHeight(); - }; - - GridStack.prototype.destroy = function() { - $(window).off('resize', this.onResizeHandler); - this.disable(); - this.container.remove(); - Utils.removeStylesheet(this._stylesId); - if (this.grid) { - this.grid = null; - } - }; - - GridStack.prototype.resizable = function(el, val) { - var self = this; - el = $(el); - el.each(function(index, el) { - el = $(el); - var node = el.data('_gridstack_node'); - if (typeof node == 'undefined' || node === null) { - return; - } - - node.noResize = !(val || false); - if (node.noResize || self._isOneColumnMode()) { - el.resizable('disable'); - } else { - el.resizable('enable'); - } - }); - return this; - }; - - GridStack.prototype.movable = function(el, val) { - var self = this; - el = $(el); - el.each(function(index, el) { - el = $(el); - var node = el.data('_gridstack_node'); - if (typeof node == 'undefined' || node === null) { - return; - } - - node.noMove = !(val || false); - if (node.noMove || self._isOneColumnMode()) { - el.draggable('disable'); - el.removeClass('ui-draggable-handle'); - } else { - el.draggable('enable'); - el.addClass('ui-draggable-handle'); - } - }); - return this; - }; - - GridStack.prototype.disable = function() { - this.movable(this.container.children('.' + this.opts.itemClass), false); - this.resizable(this.container.children('.' + this.opts.itemClass), false); - this.container.trigger('disable'); - }; - - GridStack.prototype.enable = function() { - this.movable(this.container.children('.' + this.opts.itemClass), true); - this.resizable(this.container.children('.' + this.opts.itemClass), true); - this.container.trigger('enable'); - }; - - GridStack.prototype.locked = function(el, val) { - el = $(el); - el.each(function(index, el) { - el = $(el); - var node = el.data('_gridstack_node'); - if (typeof node == 'undefined' || node === null) { - return; - } - - node.locked = (val || false); - el.attr('data-gs-locked', node.locked ? 'yes' : null); - }); - return this; - }; - - GridStack.prototype.minHeight = function(el, val) { - el = $(el); - el.each(function(index, el) { - el = $(el); - var node = el.data('_gridstack_node'); - if (typeof node == 'undefined' || node == null) { - return; - } - - if (!isNaN(val)) { - node.minHeight = (val || false); - el.attr('data-gs-min-height', val); - } - }); - return this; - }; - - GridStack.prototype.minWidth = function(el, val) { - el = $(el); - el.each(function(index, el) { - el = $(el); - var node = el.data('_gridstack_node'); - if (typeof node == 'undefined' || node == null) { - return; - } - - if (!isNaN(val)) { - node.minWidth = (val || false); - el.attr('data-gs-min-width', val); - } - }); - return this; - }; - - GridStack.prototype._updateElement = function(el, callback) { - el = $(el).first(); - var node = el.data('_gridstack_node'); - if (typeof node == 'undefined' || node === null) { - return; - } - - var self = this; - - self.grid.cleanNodes(); - self.grid.beginUpdate(node); - - callback.call(this, el, node); - - self._updateContainerHeight(); - self._triggerChangeEvent(); - - self.grid.endUpdate(); - }; - - GridStack.prototype.resize = function(el, width, height) { - this._updateElement(el, function(el, node) { - width = (width !== null && typeof width != 'undefined') ? width : node.width; - height = (height !== null && typeof height != 'undefined') ? height : node.height; - - this.grid.moveNode(node, node.x, node.y, width, height); - }); - }; - - GridStack.prototype.move = function(el, x, y) { - this._updateElement(el, function(el, node) { - x = (x !== null && typeof x != 'undefined') ? x : node.x; - y = (y !== null && typeof y != 'undefined') ? y : node.y; - - this.grid.moveNode(node, x, y, node.width, node.height); - }); - }; - - GridStack.prototype.update = function(el, x, y, width, height) { - this._updateElement(el, function(el, node) { - x = (x !== null && typeof x != 'undefined') ? x : node.x; - y = (y !== null && typeof y != 'undefined') ? y : node.y; - width = (width !== null && typeof width != 'undefined') ? width : node.width; - height = (height !== null && typeof height != 'undefined') ? height : node.height; - - this.grid.moveNode(node, x, y, width, height); - }); - }; - - function parseHeight(val) { - var height = val; - var heightUnit = 'px'; - if (height && _.isString(height)) { - var match = height.match(/^([0-9]+)(px|em|rem)?$/); - if (!match) { - throw new Error('Invalid height'); - } - heightUnit = match[2]; - height = parseInt(match[1]); - } - return {height: height, unit: heightUnit}; - } - - GridStack.prototype.verticalMargin = function(val, noUpdate) { - if (typeof val == 'undefined') { - return this.opts.verticalMargin; - } - - var heightData = parseHeight(val); - - if (this.opts.verticalMarginUnit === heightData.unit && this.opts.height === heightData.height) { - return ; - } - this.opts.verticalMarginUnit = heightData.unit; - this.opts.verticalMargin = heightData.height; - - if (!noUpdate) { - this._updateStyles(); - } - }; - - GridStack.prototype.cellHeight = function(val, noUpdate) { - if (typeof val == 'undefined') { - if (this.opts.cellHeight) { - return this.opts.cellHeight; - } else { - var o = this.container.children('.' + this.opts.itemClass).first(); - return Math.ceil(o.outerHeight() / o.attr('data-gs-height')); - } - - } - var heightData = parseHeight(val); - - if (this.opts.cellHeightUnit === heightData.heightUnit && this.opts.height === heightData.height) { - return ; - } - this.opts.cellHeightUnit = heightData.unit; - this.opts.cellHeight = heightData.height; - - if (!noUpdate) { - this._updateStyles(); - } - - }; - - GridStack.prototype.cellWidth = function() { - var o = this.container.children('.' + this.opts.itemClass).first(); - return Math.ceil(o.outerWidth() / o.attr('data-gs-width')); - }; - - GridStack.prototype.getCellFromPixel = function(position) { - var containerPos = this.container.position(); - var relativeLeft = position.left - containerPos.left; - var relativeTop = position.top - containerPos.top; - - var columnWidth = Math.floor(this.container.width() / this.opts.width); - var rowHeight = Math.floor(this.container.height() / parseInt(this.container.attr('data-gs-current-height'))); - - return {x: Math.floor(relativeLeft / columnWidth), y: Math.floor(relativeTop / rowHeight)}; - }; - - GridStack.prototype.batchUpdate = function() { - this.grid.batchUpdate(); - }; - - GridStack.prototype.commit = function() { - this.grid.commit(); - this._updateContainerHeight(); - }; - - GridStack.prototype.isAreaEmpty = function(x, y, width, height) { - return this.grid.isAreaEmpty(x, y, width, height); - }; - - GridStack.prototype.setStatic = function(staticValue) { - this.opts.staticGrid = (staticValue === true); - this._setStaticClass(); - }; - - GridStack.prototype._setStaticClass = function() { - var staticClassName = 'grid-stack-static'; - - if (this.opts.staticGrid === true) { - this.container.addClass(staticClassName); - } else { - this.container.removeClass(staticClassName); - } - }; - - // jscs:disable requireCamelCaseOrUpperCaseIdentifiers - GridStackEngine.prototype.batch_update = obsolete(GridStackEngine.prototype.batchUpdate); - GridStackEngine.prototype._fix_collisions = obsolete(GridStackEngine.prototype._fixCollisions, - '_fix_collisions', '_fixCollisions'); - GridStackEngine.prototype.is_area_empty = obsolete(GridStackEngine.prototype.isAreaEmpty, - 'is_area_empty', 'isAreaEmpty'); - GridStackEngine.prototype._sort_nodes = obsolete(GridStackEngine.prototype._sortNodes, - '_sort_nodes', '_sortNodes'); - GridStackEngine.prototype._pack_nodes = obsolete(GridStackEngine.prototype._packNodes, - '_pack_nodes', '_packNodes'); - GridStackEngine.prototype._prepare_node = obsolete(GridStackEngine.prototype._prepareNode, - '_prepare_node', '_prepareNode'); - GridStackEngine.prototype.clean_nodes = obsolete(GridStackEngine.prototype.cleanNodes, - 'clean_nodes', 'cleanNodes'); - GridStackEngine.prototype.get_dirty_nodes = obsolete(GridStackEngine.prototype.getDirtyNodes, - 'get_dirty_nodes', 'getDirtyNodes'); - GridStackEngine.prototype.add_node = obsolete(GridStackEngine.prototype.addNode, - 'add_node', 'addNode, '); - GridStackEngine.prototype.remove_node = obsolete(GridStackEngine.prototype.removeNode, - 'remove_node', 'removeNode'); - GridStackEngine.prototype.can_move_node = obsolete(GridStackEngine.prototype.canMoveNode, - 'can_move_node', 'canMoveNode'); - GridStackEngine.prototype.move_node = obsolete(GridStackEngine.prototype.moveNode, - 'move_node', 'moveNode'); - GridStackEngine.prototype.get_grid_height = obsolete(GridStackEngine.prototype.getGridHeight, - 'get_grid_height', 'getGridHeight'); - GridStackEngine.prototype.begin_update = obsolete(GridStackEngine.prototype.beginUpdate, - 'begin_update', 'beginUpdate'); - GridStackEngine.prototype.end_update = obsolete(GridStackEngine.prototype.endUpdate, - 'end_update', 'endUpdate'); - GridStackEngine.prototype.can_be_placed_with_respect_to_height = - obsolete(GridStackEngine.prototype.canBePlacedWithRespectToHeight, - 'can_be_placed_with_respect_to_height', 'canBePlacedWithRespectToHeight'); - GridStack.prototype._trigger_change_event = obsolete(GridStack.prototype._triggerChangeEvent, - '_trigger_change_event', '_triggerChangeEvent'); - GridStack.prototype._init_styles = obsolete(GridStack.prototype._initStyles, - '_init_styles', '_initStyles'); - GridStack.prototype._update_styles = obsolete(GridStack.prototype._updateStyles, - '_update_styles', '_updateStyles'); - GridStack.prototype._update_container_height = obsolete(GridStack.prototype._updateContainerHeight, - '_update_container_height', '_updateContainerHeight'); - GridStack.prototype._is_one_column_mode = obsolete(GridStack.prototype._isOneColumnMode, - '_is_one_column_mode',' _isOneColumnMode'); - GridStack.prototype._prepare_element = obsolete(GridStack.prototype._prepareElement, - '_prepare_element', '_prepareElement'); - GridStack.prototype.set_animation = obsolete(GridStack.prototype.setAnimation, - 'set_animation', 'setAnimation'); - GridStack.prototype.add_widget = obsolete(GridStack.prototype.addWidget, - 'add_widget', 'addWidget'); - GridStack.prototype.make_widget = obsolete(GridStack.prototype.makeWidget, - 'make_widget', 'makeWidget'); - GridStack.prototype.will_it_fit = obsolete(GridStack.prototype.willItFit, - 'will_it_fit', 'willItFit'); - GridStack.prototype.remove_widget = obsolete(GridStack.prototype.removeWidget, - 'remove_widget', 'removeWidget'); - GridStack.prototype.remove_all = obsolete(GridStack.prototype.removeAll, - 'remove_all', 'removeAll'); - GridStack.prototype.min_height = obsolete(GridStack.prototype.minHeight, - 'min_height', 'minHeight'); - GridStack.prototype.min_width = obsolete(GridStack.prototype.minWidth, - 'min_width', 'minWidth'); - GridStack.prototype._update_element = obsolete(GridStack.prototype._updateElement, - '_update_element', '_updateElement'); - GridStack.prototype.cell_height = obsolete(GridStack.prototype.cellHeight, - 'cell_height', 'cellHeight'); - GridStack.prototype.cell_width = obsolete(GridStack.prototype.cellWidth, - 'cell_width', 'cellWidth'); - GridStack.prototype.get_cell_from_pixel = obsolete(GridStack.prototype.getCellFromPixel, - 'get_cell_from_pixel', 'getCellFromPixel'); - GridStack.prototype.batch_update = obsolete(GridStack.prototype.batchUpdate, - 'batch_update', 'batchUpdate'); - GridStack.prototype.is_area_empty = obsolete(GridStack.prototype.isAreaEmpty, - 'is_area_empty', 'isAreaEmpty'); - GridStack.prototype.set_static = obsolete(GridStack.prototype.setStatic, - 'set_static', 'setStatic'); - GridStack.prototype._set_static_class = obsolete(GridStack.prototype._setStaticClass, - '_set_static_class', '_setStaticClass'); - // jscs:enable requireCamelCaseOrUpperCaseIdentifiers - - scope.GridStackUI = GridStack; - - scope.GridStackUI.Utils = Utils; - - $.fn.gridstack = function(opts) { - return this.each(function() { - var o = $(this); - if (!o.data('gridstack')) { - o - .data('gridstack', new GridStack(this, opts)); - } - }); - }; - - return scope.GridStackUI; + var scope = window; + + var obsolete = function(f, oldName, newName) { + var wrapper = function() { + console.warn('gridstack.js: Function `' + oldName + '` is deprecated as of v0.2.5 and has been replaced with `' + + newName + '`. It will be **completely** removed in v1.0.'); + return f.apply(this, arguments); + }; + wrapper.prototype = f.prototype; + + return wrapper; + }; + + var obsoleteOpts = function(oldName, newName) { + console.warn('gridstack.js: Option `' + oldName + '` is deprecated as of v0.2.5 and has been replaced with `' + + newName + '`. It will be **completely** removed in v1.0.'); + }; + + var Utils = { + isIntercepted: function(a, b) { + return !(a.x + a.width <= b.x || b.x + b.width <= a.x || a.y + a.height <= b.y || b.y + b.height <= a.y); + }, + + sort: function(nodes, dir, width) { + width = width || _.chain(nodes).map(function(node) { return node.x + node.width; }).max().value(); + dir = dir != -1 ? 1 : -1; + return _.sortBy(nodes, function(n) { return dir * (n.x + n.y * width); }); + }, + + createStylesheet: function(id) { + var style = document.createElement('style'); + style.setAttribute('type', 'text/css'); + style.setAttribute('data-gs-id', id); + if (style.styleSheet) { + style.styleSheet.cssText = ''; + } else { + style.appendChild(document.createTextNode('')); + } + document.getElementsByTagName('head')[0].appendChild(style); + return style.sheet; + }, + + removeStylesheet: function(id) { + $('STYLE[data-gs-id=' + id + ']').remove(); + }, + + insertCSSRule: function(sheet, selector, rules, index) { + if (typeof sheet.insertRule === 'function') { + sheet.insertRule(selector + '{' + rules + '}', index); + } else if (typeof sheet.addRule === 'function') { + sheet.addRule(selector, rules, index); + } + }, + + toBool: function(v) { + if (typeof v == 'boolean') { + return v; + } + if (typeof v == 'string') { + v = v.toLowerCase(); + return !(v === '' || v == 'no' || v == 'false' || v == '0'); + } + return Boolean(v); + }, + + _collisionNodeCheck: function(n) { + 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); + }, + + _isAddNodeIntercepted: function(n) { + return Utils.isIntercepted({x: this.x, y: this.y, width: this.node.width, height: this.node.height}, n); + } + }; + + // jscs:disable requireCamelCaseOrUpperCaseIdentifiers + Utils.is_intercepted = obsolete(Utils.isIntercepted, 'is_intercepted', 'isIntercepted'); + + Utils.create_stylesheet = obsolete(Utils.createStylesheet, 'create_stylesheet', 'createStylesheet'); + + Utils.remove_stylesheet = obsolete(Utils.removeStylesheet, 'remove_stylesheet', 'removeStylesheet'); + + Utils.insert_css_rule = obsolete(Utils.insertCSSRule, 'insert_css_rule', 'insertCSSRule'); + // jscs:enable requireCamelCaseOrUpperCaseIdentifiers + + var idSeq = 0; + + var GridStackEngine = function(width, onchange, floatMode, height, items) { + this.width = width; + this.float = floatMode || false; + this.height = height || 0; + + this.nodes = items || []; + this.onchange = onchange || function() {}; + + this._updateCounter = 0; + this._float = this.float; + }; + + GridStackEngine.prototype.batchUpdate = function() { + this._updateCounter = 1; + this.float = true; + }; + + GridStackEngine.prototype.commit = function() { + this._updateCounter = 0; + if (this._updateCounter === 0) { + this.float = this._float; + this._packNodes(); + this._notify(); + } + }; + + GridStackEngine.prototype._fixCollisions = function(node) { + var self = this; + this._sortNodes(-1); + + var nn = node; + var hasLocked = Boolean(_.find(this.nodes, function(n) { return n.locked; })); + if (!this.float && !hasLocked) { + nn = {x: 0, y: node.y, width: this.width, height: node.height}; + } + while (true) { + var collisionNode = _.find(this.nodes, _.bind(Utils._collisionNodeCheck, {node: node, nn: nn})); + if (typeof collisionNode == 'undefined') { + return; + } + this.moveNode(collisionNode, collisionNode.x, node.y + node.height, + collisionNode.width, collisionNode.height, true); + } + }; + + GridStackEngine.prototype.isAreaEmpty = function(x, y, width, height) { + var nn = {x: x || 0, y: y || 0, width: width || 1, height: height || 1}; + var collisionNode = _.find(this.nodes, _.bind(function(n) { + return Utils.isIntercepted(n, nn); + }, this)); + return collisionNode === null; + }; + + GridStackEngine.prototype._sortNodes = function(dir) { + this.nodes = Utils.sort(this.nodes, dir, this.width); + }; + + GridStackEngine.prototype._packNodes = function() { + this._sortNodes(); + + if (this.float) { + _.each(this.nodes, _.bind(function(n, i) { + if (n._updating || typeof n._origY == 'undefined' || n.y == n._origY) { + return; + } + + var newY = n.y; + while (newY >= n._origY) { + var collisionNode = _.chain(this.nodes) + .find(_.bind(Utils._didCollide, {n: n, newY: newY})) + .value(); + + if (!collisionNode) { + n._dirty = true; + n.y = newY; + } + --newY; + } + }, this)); + } else { + _.each(this.nodes, _.bind(function(n, i) { + if (n.locked) { + return; + } + while (n.y > 0) { + var newY = n.y - 1; + var canBeMoved = i === 0; + + if (i > 0) { + var collisionNode = _.chain(this.nodes) + .take(i) + .find(_.bind(Utils._didCollide, {n: n, newY: newY})) + .value(); + canBeMoved = typeof collisionNode == 'undefined'; + } + + if (!canBeMoved) { + break; + } + n._dirty = n.y != newY; + n.y = newY; + } + }, this)); + } + }; + + GridStackEngine.prototype._prepareNode = function(node, resizing) { + node = _.defaults(node || {}, {width: 1, height: 1, x: 0, y: 0}); + + node.x = parseInt('' + node.x); + node.y = parseInt('' + node.y); + node.width = parseInt('' + node.width); + node.height = parseInt('' + node.height); + node.autoPosition = node.autoPosition || false; + node.noResize = node.noResize || false; + node.noMove = node.noMove || false; + + if (node.width > this.width) { + node.width = this.width; + } else if (node.width < 1) { + node.width = 1; + } + + if (node.height < 1) { + node.height = 1; + } + + if (node.x < 0) { + node.x = 0; + } + + if (node.x + node.width > this.width) { + if (resizing) { + node.width = this.width - node.x; + } else { + node.x = this.width - node.width; + } + } + + if (node.y < 0) { + node.y = 0; + } + + return node; + }; + + GridStackEngine.prototype._notify = function() { + if (this._updateCounter) { + return; + } + var deletedNodes = Array.prototype.slice.call(arguments, 1).concat(this.getDirtyNodes()); + deletedNodes = deletedNodes.concat(this.getDirtyNodes()); + this.onchange(deletedNodes); + }; + + GridStackEngine.prototype.cleanNodes = function() { + _.each(this.nodes, function(n) {n._dirty = false; }); + }; + + GridStackEngine.prototype.getDirtyNodes = function() { + return _.filter(this.nodes, function(n) { return n._dirty; }); + }; + + GridStackEngine.prototype.addNode = function(node) { + node = this._prepareNode(node); + + if (typeof node.maxWidth != 'undefined') { node.width = Math.min(node.width, node.maxWidth); } + if (typeof node.maxHeight != 'undefined') { node.height = Math.min(node.height, node.maxHeight); } + if (typeof node.minWidth != 'undefined') { node.width = Math.max(node.width, node.minWidth); } + if (typeof node.minHeight != 'undefined') { node.height = Math.max(node.height, node.minHeight); } + + node._id = ++idSeq; + node._dirty = true; + + if (node.autoPosition) { + this._sortNodes(); + + for (var i = 0;; ++i) { + var x = i % this.width; + var y = Math.floor(i / this.width); + if (x + node.width > this.width) { + continue; + } + if (!_.find(this.nodes, _.bind(Utils._isAddNodeIntercepted, {x: x, y: y, node: node}))) { + node.x = x; + node.y = y; + break; + } + } + } + + this.nodes.push(node); + + this._fixCollisions(node); + this._packNodes(); + this._notify(); + return node; + }; + + GridStackEngine.prototype.removeNode = function(node) { + node._id = null; + this.nodes = _.without(this.nodes, node); + this._packNodes(); + this._notify(node); + }; + + GridStackEngine.prototype.canMoveNode = function(node, x, y, width, height) { + var hasLocked = Boolean(_.find(this.nodes, function(n) { return n.locked; })); + + if (!this.height && !hasLocked) { + return true; + } + + var clonedNode; + var clone = new GridStackEngine( + this.width, + null, + this.float, + 0, + _.map(this.nodes, function(n) { + if (n == node) { + clonedNode = $.extend({}, n); + return clonedNode; + } + return $.extend({}, n); + })); + + clone.moveNode(clonedNode, x, y, width, height); + + var res = true; + + if (hasLocked) { + res &= !Boolean(_.find(clone.nodes, function(n) { + return n != clonedNode && Boolean(n.locked) && Boolean(n._dirty); + })); + } + if (this.height) { + res &= clone.getGridHeight() <= this.height; + } + + return res; + }; + + GridStackEngine.prototype.canBePlacedWithRespectToHeight = function(node) { + if (!this.height) { + return true; + } + + var clone = new GridStackEngine( + this.width, + null, + this.float, + 0, + _.map(this.nodes, function(n) { return $.extend({}, n); })); + clone.addNode(node); + return clone.getGridHeight() <= this.height; + }; + + GridStackEngine.prototype.moveNode = function(node, x, y, width, height, noPack) { + if (typeof x != 'number') { x = node.x; } + if (typeof y != 'number') { y = node.y; } + if (typeof width != 'number') { width = node.width; } + if (typeof height != 'number') { height = node.height; } + + if (typeof node.maxWidth != 'undefined') { width = Math.min(width, node.maxWidth); } + if (typeof node.maxHeight != 'undefined') { height = Math.min(height, node.maxHeight); } + if (typeof node.minWidth != 'undefined') { width = Math.max(width, node.minWidth); } + if (typeof node.minHeight != 'undefined') { height = Math.max(height, node.minHeight); } + + if (node.x == x && node.y == y && node.width == width && node.height == height) { + return node; + } + + var resizing = node.width != width; + node._dirty = true; + + node.x = x; + node.y = y; + node.width = width; + node.height = height; + + node = this._prepareNode(node, resizing); + + this._fixCollisions(node); + if (!noPack) { + this._packNodes(); + this._notify(); + } + return node; + }; + + GridStackEngine.prototype.getGridHeight = function() { + return _.reduce(this.nodes, function(memo, n) { return Math.max(memo, n.y + n.height); }, 0); + }; + + GridStackEngine.prototype.beginUpdate = function(node) { + _.each(this.nodes, function(n) { + n._origY = n.y; + }); + node._updating = true; + }; + + GridStackEngine.prototype.endUpdate = function() { + _.each(this.nodes, function(n) { + n._origY = n.y; + }); + var n = _.find(this.nodes, function(n) { return n._updating; }); + if (n) { + n._updating = false; + } + }; + + var GridStack = function(el, opts) { + var self = this; + var oneColumnMode; + + opts = opts || {}; + + this.container = $(el); + + // jscs:disable requireCamelCaseOrUpperCaseIdentifiers + if (typeof opts.handle_class !== 'undefined') { + opts.handleClass = opts.handle_class; + obsoleteOpts('handle_class', 'handleClass'); + } + if (typeof opts.item_class !== 'undefined') { + opts.itemClass = opts.item_class; + obsoleteOpts('item_class', 'itemClass'); + } + if (typeof opts.placeholder_class !== 'undefined') { + opts.placeholderClass = opts.placeholder_class; + obsoleteOpts('placeholder_class', 'placeholderClass'); + } + if (typeof opts.placeholder_text !== 'undefined') { + opts.placeholderText = opts.placeholder_text; + obsoleteOpts('placeholder_text', 'placeholderText'); + } + if (typeof opts.item_class !== 'undefined') { + opts.itemClass = opts.item_class; + obsoleteOpts('item_class', 'itemClass'); + } + if (typeof opts.cell_height !== 'undefined') { + opts.cellHeight = opts.cell_height; + obsoleteOpts('cell_height', 'cellHeight'); + } + if (typeof opts.vertical_margin !== 'undefined') { + opts.verticalMargin = opts.vertical_margin; + obsoleteOpts('vertical_margin', 'verticalMargin'); + } + if (typeof opts.min_width !== 'undefined') { + opts.minWidth = opts.min_width; + obsoleteOpts('min_width', 'minWidth'); + } + if (typeof opts.static_grid !== 'undefined') { + opts.staticGrid = opts.static_grid; + obsoleteOpts('static_grid', 'staticGrid'); + } + if (typeof opts.is_nested !== 'undefined') { + opts.isNested = opts.is_nested; + obsoleteOpts('is_nested', 'isNested'); + } + if (typeof opts.always_show_resize_handle !== 'undefined') { + opts.alwaysShowResizeHandle = opts.always_show_resize_handle; + obsoleteOpts('always_show_resize_handle', 'alwaysShowResizeHandle'); + } + // jscs:enable requireCamelCaseOrUpperCaseIdentifiers + + opts.itemClass = opts.itemClass || 'grid-stack-item'; + var isNested = this.container.closest('.' + opts.itemClass).size() > 0; + + this.opts = _.defaults(opts || {}, { + width: parseInt(this.container.attr('data-gs-width')) || 12, + height: parseInt(this.container.attr('data-gs-height')) || 0, + itemClass: 'grid-stack-item', + placeholderClass: 'grid-stack-placeholder', + placeholderText: '', + handle: '.grid-stack-item-content', + handleClass: null, + cellHeight: 60, + verticalMargin: 20, + auto: true, + minWidth: 768, + float: false, + staticGrid: false, + _class: 'grid-stack-instance-' + (Math.random() * 10000).toFixed(0), + animate: Boolean(this.container.attr('data-gs-animate')) || false, + alwaysShowResizeHandle: opts.alwaysShowResizeHandle || false, + resizable: _.defaults(opts.resizable || {}, { + autoHide: !(opts.alwaysShowResizeHandle || false), + handles: 'se' + }), + draggable: _.defaults(opts.draggable || {}, { + handle: (opts.handleClass ? '.' + opts.handleClass : (opts.handle ? opts.handle : '')) || + '.grid-stack-item-content', + scroll: false, + appendTo: 'body' + }) + }); + this.opts.isNested = isNested; + + this.cellHeight(this.opts.cellHeight, true); + this.verticalMargin(this.opts.verticalMargin, true); + + this.container.addClass(this.opts._class); + + this._setStaticClass(); + + if (isNested) { + this.container.addClass('grid-stack-nested'); + } + + this._initStyles(); + + this.grid = new GridStackEngine(this.opts.width, function(nodes) { + var maxHeight = 0; + _.each(nodes, function(n) { + if (n._id === null) { + n.el.remove(); + } else { + n.el + .attr('data-gs-x', n.x) + .attr('data-gs-y', n.y) + .attr('data-gs-width', n.width) + .attr('data-gs-height', n.height); + maxHeight = Math.max(maxHeight, n.y + n.height); + } + }); + self._updateStyles(maxHeight + 10); + }, this.opts.float, this.opts.height); + + if (this.opts.auto) { + var elements = []; + var _this = this; + this.container.children('.' + this.opts.itemClass + ':not(.' + this.opts.placeholderClass + ')') + .each(function(index, el) { + el = $(el); + elements.push({ + el: el, + i: parseInt(el.attr('data-gs-x')) + parseInt(el.attr('data-gs-y')) * _this.opts.width + }); + }); + _.chain(elements).sortBy(function(x) { return x.i; }).each(function(i) { + self._prepareElement(i.el); + }).value(); + } + + this.setAnimation(this.opts.animate); + + this.placeholder = $( + '
' + + '
' + this.opts.placeholderText + '
').hide(); + + this._updateContainerHeight(); + + this.onResizeHandler = function() { + if (self._isOneColumnMode()) { + if (oneColumnMode) { + return; + } + + oneColumnMode = true; + + self.grid._sortNodes(); + _.each(self.grid.nodes, function(node) { + self.container.append(node.el); + + if (self.opts.staticGrid) { + return; + } + if (!node.noMove) { + node.el.draggable('disable'); + } + if (!node.noResize) { + node.el.resizable('disable'); + } + }); + } else { + if (!oneColumnMode) { + return; + } + + oneColumnMode = false; + + if (self.opts.staticGrid) { + return; + } + + _.each(self.grid.nodes, function(node) { + if (!node.noMove) { + node.el.draggable('enable'); + } + if (!node.noResize) { + node.el.resizable('enable'); + } + }); + } + }; + + $(window).resize(this.onResizeHandler); + this.onResizeHandler(); + }; + + GridStack.prototype._triggerChangeEvent = function(forceTrigger) { + var elements = this.grid.getDirtyNodes(); + var hasChanges = false; + + var eventParams = []; + if (elements && elements.length) { + eventParams.push(elements); + hasChanges = true; + } + + if (hasChanges || forceTrigger === true) { + this.container.trigger('change', eventParams); + } + }; + + GridStack.prototype._initStyles = function() { + if (!this.opts.cellHeight) { //that will be handled by CSS + return ; + } + if (this._stylesId) { + $('[data-gs-id="' + this._stylesId + '"]').remove(); + } + this._stylesId = 'gridstack-style-' + (Math.random() * 100000).toFixed(); + this._styles = Utils.createStylesheet(this._stylesId); + if (this._styles != null) { + this._styles._max = 0; + } + }; + + GridStack.prototype._updateStyles = function(maxHeight) { + if (this._styles === null) { + return; + } + + var prefix = '.' + this.opts._class + ' .' + this.opts.itemClass; + var self = this; + var getHeight; + + if (typeof maxHeight == 'undefined') { + maxHeight = this._styles._max; + this._initStyles(); + this._updateContainerHeight(); + } + if (!this.opts.cellHeight) { //the rest will be handled by CSS + return ; + } + if (this._styles._max !== 0 && maxHeight <= this._styles._max) { + return ; + } + + if (!this.opts.verticalMargin || this.opts.cellHeightUnit === this.opts.verticalMarginUnit) { + getHeight = function(nbRows, nbMargins) { + return (self.opts.cellHeight * nbRows + self.opts.verticalMargin * nbMargins) + self.opts.cellHeightUnit; + }; + } else { + getHeight = function(nbRows, nbMargins) { + if (!nbRows || !nbMargins) { + return (self.opts.cellHeight * nbRows + self.opts.verticalMargin * nbMargins) + self.opts.cellHeightUnit; + } + return 'calc(' + ((self.opts.cellHeight * nbRows) + self.opts.cellHeightUnit) + ' + ' + + ((self.opts.verticalMargin * nbMargins) + self.opts.verticalMarginUnit) + ')'; + }; + } + + if (this._styles._max === 0) { + Utils.insertCSSRule(this._styles, prefix, 'min-height: ' + getHeight(1, 0) + ';', 0); + } + + if (maxHeight > this._styles._max) { + for (var i = this._styles._max; i < maxHeight; ++i) { + Utils.insertCSSRule(this._styles, + prefix + '[data-gs-height="' + (i + 1) + '"]', + 'height: ' + getHeight(i + 1, i) + ';', + i + ); + Utils.insertCSSRule(this._styles, + prefix + '[data-gs-min-height="' + (i + 1) + '"]', + 'min-height: ' + getHeight(i + 1, i) + ';', + i + ); + Utils.insertCSSRule(this._styles, + prefix + '[data-gs-max-height="' + (i + 1) + '"]', + 'max-height: ' + getHeight(i + 1, i) + ';', + i + ); + Utils.insertCSSRule(this._styles, + prefix + '[data-gs-y="' + i + '"]', + 'top: ' + getHeight(i, i) + ';', + i + ); + } + this._styles._max = maxHeight; + } + }; + + GridStack.prototype._updateContainerHeight = function() { + if (this.grid._updateCounter) { + return; + } + var height = this.grid.getGridHeight(); + this.container.attr('data-gs-current-height', height); + if (!this.opts.cellHeight) { + return ; + } + if (!this.opts.verticalMargin) { + this.container.css('height', (height * (this.opts.cellHeight)) + this.opts.cellHeightUnit); + } else if (this.opts.cellHeightUnit === this.opts.verticalMarginUnit) { + this.container.css('height', (height * (this.opts.cellHeight + this.opts.verticalMargin) - + this.opts.verticalMargin) + this.opts.cellHeightUnit); + } else { + this.container.css('height', 'calc(' + ((height * (this.opts.cellHeight)) + this.opts.cellHeightUnit) + + ' + ' + ((height * (this.opts.verticalMargin - 1)) + this.opts.verticalMarginUnit) + ')'); + } + }; + + GridStack.prototype._isOneColumnMode = function() { + return (window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth) <= + this.opts.minWidth; + }; + + GridStack.prototype._prepareElement = function(el) { + var self = this; + el = $(el); + + el.addClass(this.opts.itemClass); + var node = self.grid.addNode({ + x: el.attr('data-gs-x'), + y: el.attr('data-gs-y'), + width: el.attr('data-gs-width'), + height: el.attr('data-gs-height'), + maxWidth: el.attr('data-gs-max-width'), + minWidth: el.attr('data-gs-min-width'), + maxHeight: el.attr('data-gs-max-height'), + minHeight: el.attr('data-gs-min-height'), + autoPosition: Utils.toBool(el.attr('data-gs-auto-position')), + noResize: Utils.toBool(el.attr('data-gs-no-resize')), + noMove: Utils.toBool(el.attr('data-gs-no-move')), + locked: Utils.toBool(el.attr('data-gs-locked')), + el: el + }); + el.data('_gridstack_node', node); + + if (self.opts.staticGrid) { + return; + } + + var cellWidth; + var cellHeight; + + var dragOrResize = function(event, ui) { + var x = Math.round(ui.position.left / cellWidth); + var y = Math.floor((ui.position.top + cellHeight / 2) / cellHeight); + var width; + var height; + if (event.type != 'drag') { + width = Math.round(ui.size.width / cellWidth); + height = Math.round(ui.size.height / cellHeight); + } + + if (!self.grid.canMoveNode(node, x, y, width, height)) { + return; + } + self.grid.moveNode(node, x, y, width, height); + self._updateContainerHeight(); + }; + + var onStartMoving = function(event, ui) { + self.container.append(self.placeholder); + var o = $(this); + self.grid.cleanNodes(); + self.grid.beginUpdate(node); + cellWidth = Math.ceil(o.outerWidth() / o.attr('data-gs-width')); + var strictCellHeight = Math.ceil(o.outerHeight() / o.attr('data-gs-height')); + cellHeight = self.container.height() / parseInt(self.container.attr('data-gs-current-height')); + self.placeholder + .attr('data-gs-x', o.attr('data-gs-x')) + .attr('data-gs-y', o.attr('data-gs-y')) + .attr('data-gs-width', o.attr('data-gs-width')) + .attr('data-gs-height', o.attr('data-gs-height')) + .show(); + node.el = self.placeholder; + + el.resizable('option', 'minWidth', cellWidth * (node.minWidth || 1)); + el.resizable('option', 'minHeight', strictCellHeight * (node.minHeight || 1)); + + if (event.type == 'resizestart') { + o.find('.grid-stack-item').trigger('resizestart'); + } + }; + + var onEndMoving = function(event, ui) { + self.placeholder.detach(); + var o = $(this); + node.el = o; + self.placeholder.hide(); + o + .attr('data-gs-x', node.x) + .attr('data-gs-y', node.y) + .attr('data-gs-width', node.width) + .attr('data-gs-height', node.height) + .removeAttr('style'); + self._updateContainerHeight(); + self._triggerChangeEvent(); + + self.grid.endUpdate(); + + var nestedGrids = o.find('.grid-stack'); + if (nestedGrids.length && event.type == 'resizestop') { + nestedGrids.each(function(index, el) { + $(el).data('gridstack').onResizeHandler(); + }); + o.find('.grid-stack-item').trigger('resizestop'); + } + }; + + el + .draggable(_.extend(this.opts.draggable, { + containment: this.opts.isNested ? this.container.parent() : null, + start: onStartMoving, + stop: onEndMoving, + drag: dragOrResize + })) + .resizable(_.extend(this.opts.resizable, { + start: onStartMoving, + stop: onEndMoving, + resize: dragOrResize + })); + + if (node.noMove || this._isOneColumnMode()) { + el.draggable('disable'); + } + + if (node.noResize || this._isOneColumnMode()) { + el.resizable('disable'); + } + + el.attr('data-gs-locked', node.locked ? 'yes' : null); + }; + + GridStack.prototype.setAnimation = function(enable) { + if (enable) { + this.container.addClass('grid-stack-animate'); + } else { + this.container.removeClass('grid-stack-animate'); + } + }; + + GridStack.prototype.addWidget = function(el, x, y, width, height, autoPosition) { + el = $(el); + if (typeof x != 'undefined') { el.attr('data-gs-x', x); } + if (typeof y != 'undefined') { el.attr('data-gs-y', y); } + if (typeof width != 'undefined') { el.attr('data-gs-width', width); } + if (typeof height != 'undefined') { el.attr('data-gs-height', height); } + if (typeof autoPosition != 'undefined') { el.attr('data-gs-auto-position', autoPosition ? 'yes' : null); } + this.container.append(el); + this._prepareElement(el); + this._updateContainerHeight(); + this._triggerChangeEvent(true); + + return el; + }; + + GridStack.prototype.makeWidget = function(el) { + el = $(el); + this._prepareElement(el); + this._updateContainerHeight(); + this._triggerChangeEvent(true); + + return el; + }; + + GridStack.prototype.willItFit = function(x, y, width, height, autoPosition) { + var node = {x: x, y: y, width: width, height: height, autoPosition: autoPosition}; + return this.grid.canBePlacedWithRespectToHeight(node); + }; + + GridStack.prototype.removeWidget = function(el, detachNode) { + detachNode = typeof detachNode === 'undefined' ? true : detachNode; + el = $(el); + var node = el.data('_gridstack_node'); + this.grid.removeNode(node); + el.removeData('_gridstack_node'); + this._updateContainerHeight(); + if (detachNode) { + el.remove(); + } + this._triggerChangeEvent(true); + }; + + GridStack.prototype.removeAll = function(detachNode) { + _.each(this.grid.nodes, _.bind(function(node) { + this.removeWidget(node.el, detachNode); + }, this)); + this.grid.nodes = []; + this._updateContainerHeight(); + }; + + GridStack.prototype.destroy = function() { + $(window).off('resize', this.onResizeHandler); + this.disable(); + this.container.remove(); + Utils.removeStylesheet(this._stylesId); + if (this.grid) { + this.grid = null; + } + }; + + GridStack.prototype.resizable = function(el, val) { + var self = this; + el = $(el); + el.each(function(index, el) { + el = $(el); + var node = el.data('_gridstack_node'); + if (typeof node == 'undefined' || node === null) { + return; + } + + node.noResize = !(val || false); + if (node.noResize || self._isOneColumnMode()) { + el.resizable('disable'); + } else { + el.resizable('enable'); + } + }); + return this; + }; + + GridStack.prototype.movable = function(el, val) { + var self = this; + el = $(el); + el.each(function(index, el) { + el = $(el); + var node = el.data('_gridstack_node'); + if (typeof node == 'undefined' || node === null) { + return; + } + + node.noMove = !(val || false); + if (node.noMove || self._isOneColumnMode()) { + el.draggable('disable'); + el.removeClass('ui-draggable-handle'); + } else { + el.draggable('enable'); + el.addClass('ui-draggable-handle'); + } + }); + return this; + }; + + GridStack.prototype.disable = function() { + this.movable(this.container.children('.' + this.opts.itemClass), false); + this.resizable(this.container.children('.' + this.opts.itemClass), false); + this.container.trigger('disable'); + }; + + GridStack.prototype.enable = function() { + this.movable(this.container.children('.' + this.opts.itemClass), true); + this.resizable(this.container.children('.' + this.opts.itemClass), true); + this.container.trigger('enable'); + }; + + GridStack.prototype.locked = function(el, val) { + el = $(el); + el.each(function(index, el) { + el = $(el); + var node = el.data('_gridstack_node'); + if (typeof node == 'undefined' || node === null) { + return; + } + + node.locked = (val || false); + el.attr('data-gs-locked', node.locked ? 'yes' : null); + }); + return this; + }; + + GridStack.prototype.minHeight = function(el, val) { + el = $(el); + el.each(function(index, el) { + el = $(el); + var node = el.data('_gridstack_node'); + if (typeof node == 'undefined' || node == null) { + return; + } + + if (!isNaN(val)) { + node.minHeight = (val || false); + el.attr('data-gs-min-height', val); + } + }); + return this; + }; + + GridStack.prototype.minWidth = function(el, val) { + el = $(el); + el.each(function(index, el) { + el = $(el); + var node = el.data('_gridstack_node'); + if (typeof node == 'undefined' || node == null) { + return; + } + + if (!isNaN(val)) { + node.minWidth = (val || false); + el.attr('data-gs-min-width', val); + } + }); + return this; + }; + + GridStack.prototype._updateElement = function(el, callback) { + el = $(el).first(); + var node = el.data('_gridstack_node'); + if (typeof node == 'undefined' || node === null) { + return; + } + + var self = this; + + self.grid.cleanNodes(); + self.grid.beginUpdate(node); + + callback.call(this, el, node); + + self._updateContainerHeight(); + self._triggerChangeEvent(); + + self.grid.endUpdate(); + }; + + GridStack.prototype.resize = function(el, width, height) { + this._updateElement(el, function(el, node) { + width = (width !== null && typeof width != 'undefined') ? width : node.width; + height = (height !== null && typeof height != 'undefined') ? height : node.height; + + this.grid.moveNode(node, node.x, node.y, width, height); + }); + }; + + GridStack.prototype.move = function(el, x, y) { + this._updateElement(el, function(el, node) { + x = (x !== null && typeof x != 'undefined') ? x : node.x; + y = (y !== null && typeof y != 'undefined') ? y : node.y; + + this.grid.moveNode(node, x, y, node.width, node.height); + }); + }; + + GridStack.prototype.update = function(el, x, y, width, height) { + this._updateElement(el, function(el, node) { + x = (x !== null && typeof x != 'undefined') ? x : node.x; + y = (y !== null && typeof y != 'undefined') ? y : node.y; + width = (width !== null && typeof width != 'undefined') ? width : node.width; + height = (height !== null && typeof height != 'undefined') ? height : node.height; + + this.grid.moveNode(node, x, y, width, height); + }); + }; + + function parseHeight(val) { + var height = val; + var heightUnit = 'px'; + if (height && _.isString(height)) { + var match = height.match(/^([0-9]+)(px|em|rem)?$/); + if (!match) { + throw new Error('Invalid height'); + } + heightUnit = match[2]; + height = parseInt(match[1]); + } + return {height: height, unit: heightUnit}; + } + + GridStack.prototype.verticalMargin = function(val, noUpdate) { + if (typeof val == 'undefined') { + return this.opts.verticalMargin; + } + + var heightData = parseHeight(val); + + if (this.opts.verticalMarginUnit === heightData.unit && this.opts.height === heightData.height) { + return ; + } + this.opts.verticalMarginUnit = heightData.unit; + this.opts.verticalMargin = heightData.height; + + if (!noUpdate) { + this._updateStyles(); + } + }; + + GridStack.prototype.cellHeight = function(val, noUpdate) { + if (typeof val == 'undefined') { + if (this.opts.cellHeight) { + return this.opts.cellHeight; + } else { + var o = this.container.children('.' + this.opts.itemClass).first(); + return Math.ceil(o.outerHeight() / o.attr('data-gs-height')); + } + + } + var heightData = parseHeight(val); + + if (this.opts.cellHeightUnit === heightData.heightUnit && this.opts.height === heightData.height) { + return ; + } + this.opts.cellHeightUnit = heightData.unit; + this.opts.cellHeight = heightData.height; + + if (!noUpdate) { + this._updateStyles(); + } + + }; + + GridStack.prototype.cellWidth = function() { + var o = this.container.children('.' + this.opts.itemClass).first(); + return Math.ceil(o.outerWidth() / o.attr('data-gs-width')); + }; + + GridStack.prototype.getCellFromPixel = function(position) { + var containerPos = this.container.position(); + var relativeLeft = position.left - containerPos.left; + var relativeTop = position.top - containerPos.top; + + var columnWidth = Math.floor(this.container.width() / this.opts.width); + var rowHeight = Math.floor(this.container.height() / parseInt(this.container.attr('data-gs-current-height'))); + + return {x: Math.floor(relativeLeft / columnWidth), y: Math.floor(relativeTop / rowHeight)}; + }; + + GridStack.prototype.batchUpdate = function() { + this.grid.batchUpdate(); + }; + + GridStack.prototype.commit = function() { + this.grid.commit(); + this._updateContainerHeight(); + }; + + GridStack.prototype.isAreaEmpty = function(x, y, width, height) { + return this.grid.isAreaEmpty(x, y, width, height); + }; + + GridStack.prototype.setStatic = function(staticValue) { + this.opts.staticGrid = (staticValue === true); + this._setStaticClass(); + }; + + GridStack.prototype._setStaticClass = function() { + var staticClassName = 'grid-stack-static'; + + if (this.opts.staticGrid === true) { + this.container.addClass(staticClassName); + } else { + this.container.removeClass(staticClassName); + } + }; + + // jscs:disable requireCamelCaseOrUpperCaseIdentifiers + GridStackEngine.prototype.batch_update = obsolete(GridStackEngine.prototype.batchUpdate); + GridStackEngine.prototype._fix_collisions = obsolete(GridStackEngine.prototype._fixCollisions, + '_fix_collisions', '_fixCollisions'); + GridStackEngine.prototype.is_area_empty = obsolete(GridStackEngine.prototype.isAreaEmpty, + 'is_area_empty', 'isAreaEmpty'); + GridStackEngine.prototype._sort_nodes = obsolete(GridStackEngine.prototype._sortNodes, + '_sort_nodes', '_sortNodes'); + GridStackEngine.prototype._pack_nodes = obsolete(GridStackEngine.prototype._packNodes, + '_pack_nodes', '_packNodes'); + GridStackEngine.prototype._prepare_node = obsolete(GridStackEngine.prototype._prepareNode, + '_prepare_node', '_prepareNode'); + GridStackEngine.prototype.clean_nodes = obsolete(GridStackEngine.prototype.cleanNodes, + 'clean_nodes', 'cleanNodes'); + GridStackEngine.prototype.get_dirty_nodes = obsolete(GridStackEngine.prototype.getDirtyNodes, + 'get_dirty_nodes', 'getDirtyNodes'); + GridStackEngine.prototype.add_node = obsolete(GridStackEngine.prototype.addNode, + 'add_node', 'addNode, '); + GridStackEngine.prototype.remove_node = obsolete(GridStackEngine.prototype.removeNode, + 'remove_node', 'removeNode'); + GridStackEngine.prototype.can_move_node = obsolete(GridStackEngine.prototype.canMoveNode, + 'can_move_node', 'canMoveNode'); + GridStackEngine.prototype.move_node = obsolete(GridStackEngine.prototype.moveNode, + 'move_node', 'moveNode'); + GridStackEngine.prototype.get_grid_height = obsolete(GridStackEngine.prototype.getGridHeight, + 'get_grid_height', 'getGridHeight'); + GridStackEngine.prototype.begin_update = obsolete(GridStackEngine.prototype.beginUpdate, + 'begin_update', 'beginUpdate'); + GridStackEngine.prototype.end_update = obsolete(GridStackEngine.prototype.endUpdate, + 'end_update', 'endUpdate'); + GridStackEngine.prototype.can_be_placed_with_respect_to_height = + obsolete(GridStackEngine.prototype.canBePlacedWithRespectToHeight, + 'can_be_placed_with_respect_to_height', 'canBePlacedWithRespectToHeight'); + GridStack.prototype._trigger_change_event = obsolete(GridStack.prototype._triggerChangeEvent, + '_trigger_change_event', '_triggerChangeEvent'); + GridStack.prototype._init_styles = obsolete(GridStack.prototype._initStyles, + '_init_styles', '_initStyles'); + GridStack.prototype._update_styles = obsolete(GridStack.prototype._updateStyles, + '_update_styles', '_updateStyles'); + GridStack.prototype._update_container_height = obsolete(GridStack.prototype._updateContainerHeight, + '_update_container_height', '_updateContainerHeight'); + GridStack.prototype._is_one_column_mode = obsolete(GridStack.prototype._isOneColumnMode, + '_is_one_column_mode',' _isOneColumnMode'); + GridStack.prototype._prepare_element = obsolete(GridStack.prototype._prepareElement, + '_prepare_element', '_prepareElement'); + GridStack.prototype.set_animation = obsolete(GridStack.prototype.setAnimation, + 'set_animation', 'setAnimation'); + GridStack.prototype.add_widget = obsolete(GridStack.prototype.addWidget, + 'add_widget', 'addWidget'); + GridStack.prototype.make_widget = obsolete(GridStack.prototype.makeWidget, + 'make_widget', 'makeWidget'); + GridStack.prototype.will_it_fit = obsolete(GridStack.prototype.willItFit, + 'will_it_fit', 'willItFit'); + GridStack.prototype.remove_widget = obsolete(GridStack.prototype.removeWidget, + 'remove_widget', 'removeWidget'); + GridStack.prototype.remove_all = obsolete(GridStack.prototype.removeAll, + 'remove_all', 'removeAll'); + GridStack.prototype.min_height = obsolete(GridStack.prototype.minHeight, + 'min_height', 'minHeight'); + GridStack.prototype.min_width = obsolete(GridStack.prototype.minWidth, + 'min_width', 'minWidth'); + GridStack.prototype._update_element = obsolete(GridStack.prototype._updateElement, + '_update_element', '_updateElement'); + GridStack.prototype.cell_height = obsolete(GridStack.prototype.cellHeight, + 'cell_height', 'cellHeight'); + GridStack.prototype.cell_width = obsolete(GridStack.prototype.cellWidth, + 'cell_width', 'cellWidth'); + GridStack.prototype.get_cell_from_pixel = obsolete(GridStack.prototype.getCellFromPixel, + 'get_cell_from_pixel', 'getCellFromPixel'); + GridStack.prototype.batch_update = obsolete(GridStack.prototype.batchUpdate, + 'batch_update', 'batchUpdate'); + GridStack.prototype.is_area_empty = obsolete(GridStack.prototype.isAreaEmpty, + 'is_area_empty', 'isAreaEmpty'); + GridStack.prototype.set_static = obsolete(GridStack.prototype.setStatic, + 'set_static', 'setStatic'); + GridStack.prototype._set_static_class = obsolete(GridStack.prototype._setStaticClass, + '_set_static_class', '_setStaticClass'); + // jscs:enable requireCamelCaseOrUpperCaseIdentifiers + + scope.GridStackUI = GridStack; + + scope.GridStackUI.Utils = Utils; + + $.fn.gridstack = function(opts) { + return this.each(function() { + var o = $(this); + if (!o.data('gridstack')) { + o + .data('gridstack', new GridStack(this, opts)); + } + }); + }; + + return scope.GridStackUI; });