Merge pull request #125 from brokenseal/master

Possible solution to memory leak #124
This commit is contained in:
Dustin Moore
2013-04-02 07:52:59 -07:00
8 changed files with 226 additions and 132 deletions
+1
View File
@@ -1,3 +1,4 @@
node_modules/ node_modules/
gh-pages/ gh-pages/
demo/ demo/
.idea
+2 -2
View File
@@ -1,6 +1,6 @@
/*! gridster.js - v0.1.0 - 2012-10-20 /*! gridster.js - v0.1.0 - 2013-02-15
* http://gridster.net/ * http://gridster.net/
* Copyright (c) 2012 ducksboard; Licensed MIT */ * Copyright (c) 2013 ducksboard; Licensed MIT */
.gridster { .gridster {
position:relative; position:relative;
+73 -42
View File
@@ -1,6 +1,6 @@
/*! gridster.js - v0.1.0 - 2012-10-20 /*! gridster.js - v0.1.0 - 2013-02-15
* http://gridster.net/ * http://gridster.net/
* Copyright (c) 2012 ducksboard; Licensed MIT */ * Copyright (c) 2013 ducksboard; Licensed MIT */
;(function($, window, document, undefined){ ;(function($, window, document, undefined){
/** /**
@@ -368,7 +368,7 @@
autoscroll: true, autoscroll: true,
ignore_dragging: ['INPUT', 'TEXTAREA', 'SELECT', 'BUTTON'], ignore_dragging: ['INPUT', 'TEXTAREA', 'SELECT', 'BUTTON'],
handle: null handle: null
// ,drag: function(e){}, // drag: function(e){},
// start : function(e, ui){}, // start : function(e, ui){},
// stop : function(e){} // stop : function(e){}
}; };
@@ -425,24 +425,26 @@
this.disabled = false; this.disabled = false;
this.events(); this.events();
$(window).bind('resize', this.on_window_resize = throttle($.proxy(this.calculate_positions, this), 200);
throttle($.proxy(this.calculate_positions, this), 200)); $(window).bind('resize', this.on_window_resize);
}; };
fn.events = function() { fn.events = function() {
this.$container.on('selectstart', $.proxy(this.on_select_start, this)); this.proxied_on_select_start = $.proxy(this.on_select_start, this);
this.$container.on('selectstart', this.proxied_on_select_start);
this.$container.on(pointer_events.start, this.options.items, $.proxy( this.proxied_drag_handler = $.proxy(this.drag_handler, this);
this.drag_handler, this)); this.$container.on(pointer_events.start, this.options.items, this.proxied_drag_handler);
this.$body.on(pointer_events.end, $.proxy(function(e) { this.proxied_pointer_events_end = $.proxy(function(e) {
this.is_dragging = false; this.is_dragging = false;
if (this.disabled) { return; } if (this.disabled) { return; }
this.$body.off(pointer_events.move); this.$body.off(pointer_events.move);
if (this.drag_start) { if (this.drag_start) {
this.on_dragstop(e); this.on_dragstop(e);
} }
}, this)); }, this);
this.$body.on(pointer_events.end, this.proxied_pointer_events_end);
}; };
fn.get_actual_pos = function($el) { fn.get_actual_pos = function($el) {
@@ -549,7 +551,7 @@
this.mouse_init_pos = this.get_mouse_pos(e); this.mouse_init_pos = this.get_mouse_pos(e);
this.offsetY = this.mouse_init_pos.top - this.el_init_pos.top; this.offsetY = this.mouse_init_pos.top - this.el_init_pos.top;
this.$body.on(pointer_events.move, function(mme){ this.on_pointer_events_move = function(mme){
var mouse_actual_pos = self.get_mouse_pos(mme); var mouse_actual_pos = self.get_mouse_pos(mme);
var diff_x = Math.abs( var diff_x = Math.abs(
mouse_actual_pos.left - self.mouse_init_pos.left); mouse_actual_pos.left - self.mouse_init_pos.left);
@@ -557,7 +559,7 @@
mouse_actual_pos.top - self.mouse_init_pos.top); mouse_actual_pos.top - self.mouse_init_pos.top);
if (!(diff_x > self.options.distance || if (!(diff_x > self.options.distance ||
diff_y > self.options.distance) diff_y > self.options.distance)
) { ) {
return false; return false;
} }
@@ -572,7 +574,9 @@
} }
return false; return false;
}); };
this.$body.on(pointer_events.move, this.on_pointer_events_move);
return false; return false;
}; };
@@ -678,6 +682,13 @@
fn.destroy = function(){ fn.destroy = function(){
this.disable(); this.disable();
this.$container.off('selectstart', this.proxied_on_select_start);
this.$container.off(pointer_events.start, this.proxied_drag_handler);
this.$body.off(pointer_events.end, this.proxied_pointer_events_end);
this.$body.off(pointer_events.move, this.on_pointer_events_move);
$(window).unbind('resize', this.on_window_resize);
$.removeData(this.$container, 'drag'); $.removeData(this.$container, 'drag');
}; };
@@ -802,8 +813,9 @@
this.$wrapper.addClass('ready'); this.$wrapper.addClass('ready');
this.draggable(); this.draggable();
$(window).bind( this.on_window_resize = throttle($.proxy(this.recalculate_faux_grid, this), 200);
'resize', throttle($.proxy(this.recalculate_faux_grid, this), 200));
$(window).bind('resize', this.on_window_resize);
}; };
@@ -1060,7 +1072,7 @@
* occupy. * occupy.
* @param {Number} size_y The number of rows that the group of cells * @param {Number} size_y The number of rows that the group of cells
* occupy. * occupy.
* @param {HTMLElement} $exclude Exclude widgets from being moved. * @param {HTMLElement} exclude Exclude widgets from being moved.
* @return {Class} Returns the instance of the Gridster Class. * @return {Class} Returns the instance of the Gridster Class.
*/ */
fn.remove_empty_cells = function(col, row, size_x, size_y, exclude) { fn.remove_empty_cells = function(col, row, size_x, size_y, exclude) {
@@ -1361,8 +1373,8 @@
* This function is executed when the player begins to be dragged. * This function is executed when the player begins to be dragged.
* *
* @method on_start_drag * @method on_start_drag
* @param {Event} The original browser event * @param {Event} event The original browser event
* @param {Object} A prepared ui object. * @param {Object} ui A prepared ui object.
*/ */
fn.on_start_drag = function(event, ui) { fn.on_start_drag = function(event, ui) {
@@ -1412,8 +1424,8 @@
* This function is executed when the player is being dragged. * This function is executed when the player is being dragged.
* *
* @method on_drag * @method on_drag
* @param {Event} The original browser event * @param {Event} event The original browser event
* @param {Object} A prepared ui object. * @param {Object} ui A prepared ui object.
*/ */
fn.on_drag = function(event, ui) { fn.on_drag = function(event, ui) {
//break if dragstop has been fired //break if dragstop has been fired
@@ -1455,8 +1467,8 @@
* This function is executed when the player stops being dragged. * This function is executed when the player stops being dragged.
* *
* @method on_stop_drag * @method on_stop_drag
* @param {Event} The original browser event * @param {Event} event The original browser event
* @param {Object} A prepared ui object. * @param {Object} ui A prepared ui object.
*/ */
fn.on_stop_drag = function(event, ui) { fn.on_stop_drag = function(event, ui) {
this.$helper.add(this.$player).add(this.$wrapper) this.$helper.add(this.$player).add(this.$wrapper)
@@ -1525,7 +1537,7 @@
*/ */
fn.on_overlapped_column_change = function(start_callback, stop_callback) { fn.on_overlapped_column_change = function(start_callback, stop_callback) {
if (!this.colliders_data.length) { if (!this.colliders_data.length) {
return; return this;
} }
var cols = this.get_targeted_columns( var cols = this.get_targeted_columns(
this.colliders_data[0].el.data.col); this.colliders_data[0].el.data.col);
@@ -1558,14 +1570,14 @@
* *
* @param {Function} start_callback Function executed when a new row begins * @param {Function} start_callback Function executed when a new row begins
* to be overlapped. The row is passed as first argument. * to be overlapped. The row is passed as first argument.
* @param {Function} stop_callback Function executed when a row stops being * @param {Function} end_callback Function executed when a row stops being
* overlapped. The row is passed as first argument. * overlapped. The row is passed as first argument.
* @method on_overlapped_row_change * @method on_overlapped_row_change
* @return {Class} Returns the instance of the Gridster Class. * @return {Class} Returns the instance of the Gridster Class.
*/ */
fn.on_overlapped_row_change = function(start_callback, end_callback) { fn.on_overlapped_row_change = function(start_callback, end_callback) {
if (!this.colliders_data.length) { if (!this.colliders_data.length) {
return; return this;
} }
var rows = this.get_targeted_rows(this.colliders_data[0].el.data.row); var rows = this.get_targeted_rows(this.colliders_data[0].el.data.row);
var last_n_rows = this.last_rows.length; var last_n_rows = this.last_rows.length;
@@ -1591,12 +1603,11 @@
/** /**
* Sets the current position of the player * Sets the current position of the player
* *
* @param {Function} start_callback Function executed when a new row begins * @param {Number} col
* to be overlapped. The row is passed as first argument. * @param {Number} row
* @param {Function} stop_callback Function executed when a row stops being * @param {Boolean} no_player
* overlapped. The row is passed as first argument.
* @method set_player * @method set_player
* @return {Class} Returns the instance of the Gridster Class. * @return {object}
*/ */
fn.set_player = function(col, row, no_player) { fn.set_player = function(col, row, no_player) {
var self = this; var self = this;
@@ -1647,9 +1658,9 @@
* a upper row and which not. * a upper row and which not.
* *
* @method widgets_contraints * @method widgets_contraints
* @param {HTMLElements} $widgets A jQuery wrapped collection of * @param {jQuery} $widgets A jQuery wrapped collection of
* HTMLElements. * HTMLElements.
* @return {Array} Returns a literal Object with two keys: `can_go_up` & * @return {object} Returns a literal Object with two keys: `can_go_up` &
* `can_not_go_up`. Each contains a set of HTMLElements. * `can_not_go_up`. Each contains a set of HTMLElements.
*/ */
fn.widgets_constraints = function($widgets) { fn.widgets_constraints = function($widgets) {
@@ -1767,7 +1778,7 @@
* each widget) in descending way. * each widget) in descending way.
* *
* @method manage_movements * @method manage_movements
* @param {HTMLElements} $widgets A jQuery collection of HTMLElements * @param {jQuery} $widgets A jQuery collection of HTMLElements
* representing the widgets you want to move. * representing the widgets you want to move.
* @param {Number} to_col The column to which we want to move the widgets. * @param {Number} to_col The column to which we want to move the widgets.
* @param {Number} to_row The row to which we want to move the widgets. * @param {Number} to_row The row to which we want to move the widgets.
@@ -2214,7 +2225,7 @@
* Get widgets overlapping with the player. * Get widgets overlapping with the player.
* *
* @method get_widgets_overlapped * @method get_widgets_overlapped
* @return {HTMLElements} Returns a jQuery collection of HTMLElements. * @return {jQuery} Returns a jQuery collection of HTMLElements.
*/ */
fn.get_widgets_overlapped = function() { fn.get_widgets_overlapped = function() {
var $w; var $w;
@@ -2247,7 +2258,7 @@
* *
* @method on_start_overlapping_column * @method on_start_overlapping_column
* @param {Number} col The collided column. * @param {Number} col The collided column.
* @return {HTMLElements} Returns a jQuery collection of HTMLElements. * @return {jQuery} Returns a jQuery collection of HTMLElements.
*/ */
fn.on_start_overlapping_column = function(col) { fn.on_start_overlapping_column = function(col) {
this.set_player(col, false); this.set_player(col, false);
@@ -2258,8 +2269,8 @@
* A callback executed when the player begins to collide with a row. * A callback executed when the player begins to collide with a row.
* *
* @method on_start_overlapping_row * @method on_start_overlapping_row
* @param {Number} col The collided row. * @param {Number} row The collided row.
* @return {HTMLElements} Returns a jQuery collection of HTMLElements. * @return {jQuery} Returns a jQuery collection of HTMLElements.
*/ */
fn.on_start_overlapping_row = function(row) { fn.on_start_overlapping_row = function(row) {
this.set_player(false, row); this.set_player(false, row);
@@ -2271,7 +2282,7 @@
* *
* @method on_stop_overlapping_column * @method on_stop_overlapping_column
* @param {Number} col The collided row. * @param {Number} col The collided row.
* @return {HTMLElements} Returns a jQuery collection of HTMLElements. * @return {jQuery} Returns a jQuery collection of HTMLElements.
*/ */
fn.on_stop_overlapping_column = function(col) { fn.on_stop_overlapping_column = function(col) {
this.set_player(col, false); this.set_player(col, false);
@@ -2289,7 +2300,7 @@
* *
* @method on_stop_overlapping_row * @method on_stop_overlapping_row
* @param {Number} row The collided row. * @param {Number} row The collided row.
* @return {HTMLElements} Returns a jQuery collection of HTMLElements. * @return {jQuery} Returns a jQuery collection of HTMLElements.
*/ */
fn.on_stop_overlapping_row = function(row) { fn.on_stop_overlapping_row = function(row) {
this.set_player(false, row); this.set_player(false, row);
@@ -2399,9 +2410,9 @@
* Move down the specified widget and all below it. * Move down the specified widget and all below it.
* *
* @method move_widget_down * @method move_widget_down
* @param {HTMLElement} $widget The jQuery object representing the widget * @param {jQuery} $widget The jQuery object representing the widget
* you want to move. * you want to move.
* @param {Number} The number of cells that the widget has to move. * @param {Number} y_units The number of cells that the widget has to move.
* @return {Class} Returns the instance of the Gridster Class. * @return {Class} Returns the instance of the Gridster Class.
*/ */
fn.move_widget_down = function($widget, y_units) { fn.move_widget_down = function($widget, y_units) {
@@ -2537,7 +2548,7 @@
* *
* @method widgets_below * @method widgets_below
* @param {HTMLElement} $el The jQuery wrapped HTMLElement. * @param {HTMLElement} $el The jQuery wrapped HTMLElement.
* @return {HTMLElements} A jQuery collection of HTMLElements. * @return {jQuery} A jQuery collection of HTMLElements.
*/ */
fn.widgets_below = function($el) { fn.widgets_below = function($el) {
var el_grid_data = $.isPlainObject($el) ? $el : $el.coords().grid; var el_grid_data = $.isPlainObject($el) ? $el : $el.coords().grid;
@@ -3217,6 +3228,26 @@
return this.generate_faux_grid(this.rows, this.cols); return this.generate_faux_grid(this.rows, this.cols);
}; };
/**
* Destroy this gridster by removing any sign of its presence, making it easy to avoid memory leaks
*
* @method destroy
* @return {undefined}
*/
fn.destroy = function(){
// remove bound callback on window resize
$(window).unbind('resize', this.on_window_resize);
if(this.drag_api){
this.drag_api.destroy();
}
// lastly, remove gridster element
// this will additionally cause any data associated to this element to be removed, including this
// very gridster instance
this.$el.remove();
};
//jQuery adapter //jQuery adapter
$.fn.gridster = function(options) { $.fn.gridster = function(options) {
+3 -3
View File
File diff suppressed because one or more lines are too long
+73 -42
View File
@@ -1,6 +1,6 @@
/*! gridster.js - v0.1.0 - 2012-10-20 /*! gridster.js - v0.1.0 - 2013-02-15
* http://gridster.net/ * http://gridster.net/
* Copyright (c) 2012 ducksboard; Licensed MIT */ * Copyright (c) 2013 ducksboard; Licensed MIT */
;(function($, window, document, undefined){ ;(function($, window, document, undefined){
/** /**
@@ -368,7 +368,7 @@
autoscroll: true, autoscroll: true,
ignore_dragging: ['INPUT', 'TEXTAREA', 'SELECT', 'BUTTON'], ignore_dragging: ['INPUT', 'TEXTAREA', 'SELECT', 'BUTTON'],
handle: null handle: null
// ,drag: function(e){}, // drag: function(e){},
// start : function(e, ui){}, // start : function(e, ui){},
// stop : function(e){} // stop : function(e){}
}; };
@@ -425,24 +425,26 @@
this.disabled = false; this.disabled = false;
this.events(); this.events();
$(window).bind('resize', this.on_window_resize = throttle($.proxy(this.calculate_positions, this), 200);
throttle($.proxy(this.calculate_positions, this), 200)); $(window).bind('resize', this.on_window_resize);
}; };
fn.events = function() { fn.events = function() {
this.$container.on('selectstart', $.proxy(this.on_select_start, this)); this.proxied_on_select_start = $.proxy(this.on_select_start, this);
this.$container.on('selectstart', this.proxied_on_select_start);
this.$container.on(pointer_events.start, this.options.items, $.proxy( this.proxied_drag_handler = $.proxy(this.drag_handler, this);
this.drag_handler, this)); this.$container.on(pointer_events.start, this.options.items, this.proxied_drag_handler);
this.$body.on(pointer_events.end, $.proxy(function(e) { this.proxied_pointer_events_end = $.proxy(function(e) {
this.is_dragging = false; this.is_dragging = false;
if (this.disabled) { return; } if (this.disabled) { return; }
this.$body.off(pointer_events.move); this.$body.off(pointer_events.move);
if (this.drag_start) { if (this.drag_start) {
this.on_dragstop(e); this.on_dragstop(e);
} }
}, this)); }, this);
this.$body.on(pointer_events.end, this.proxied_pointer_events_end);
}; };
fn.get_actual_pos = function($el) { fn.get_actual_pos = function($el) {
@@ -549,7 +551,7 @@
this.mouse_init_pos = this.get_mouse_pos(e); this.mouse_init_pos = this.get_mouse_pos(e);
this.offsetY = this.mouse_init_pos.top - this.el_init_pos.top; this.offsetY = this.mouse_init_pos.top - this.el_init_pos.top;
this.$body.on(pointer_events.move, function(mme){ this.on_pointer_events_move = function(mme){
var mouse_actual_pos = self.get_mouse_pos(mme); var mouse_actual_pos = self.get_mouse_pos(mme);
var diff_x = Math.abs( var diff_x = Math.abs(
mouse_actual_pos.left - self.mouse_init_pos.left); mouse_actual_pos.left - self.mouse_init_pos.left);
@@ -557,7 +559,7 @@
mouse_actual_pos.top - self.mouse_init_pos.top); mouse_actual_pos.top - self.mouse_init_pos.top);
if (!(diff_x > self.options.distance || if (!(diff_x > self.options.distance ||
diff_y > self.options.distance) diff_y > self.options.distance)
) { ) {
return false; return false;
} }
@@ -572,7 +574,9 @@
} }
return false; return false;
}); };
this.$body.on(pointer_events.move, this.on_pointer_events_move);
return false; return false;
}; };
@@ -678,6 +682,13 @@
fn.destroy = function(){ fn.destroy = function(){
this.disable(); this.disable();
this.$container.off('selectstart', this.proxied_on_select_start);
this.$container.off(pointer_events.start, this.proxied_drag_handler);
this.$body.off(pointer_events.end, this.proxied_pointer_events_end);
this.$body.off(pointer_events.move, this.on_pointer_events_move);
$(window).unbind('resize', this.on_window_resize);
$.removeData(this.$container, 'drag'); $.removeData(this.$container, 'drag');
}; };
@@ -802,8 +813,9 @@
this.$wrapper.addClass('ready'); this.$wrapper.addClass('ready');
this.draggable(); this.draggable();
$(window).bind( this.on_window_resize = throttle($.proxy(this.recalculate_faux_grid, this), 200);
'resize', throttle($.proxy(this.recalculate_faux_grid, this), 200));
$(window).bind('resize', this.on_window_resize);
}; };
@@ -1060,7 +1072,7 @@
* occupy. * occupy.
* @param {Number} size_y The number of rows that the group of cells * @param {Number} size_y The number of rows that the group of cells
* occupy. * occupy.
* @param {HTMLElement} $exclude Exclude widgets from being moved. * @param {HTMLElement} exclude Exclude widgets from being moved.
* @return {Class} Returns the instance of the Gridster Class. * @return {Class} Returns the instance of the Gridster Class.
*/ */
fn.remove_empty_cells = function(col, row, size_x, size_y, exclude) { fn.remove_empty_cells = function(col, row, size_x, size_y, exclude) {
@@ -1361,8 +1373,8 @@
* This function is executed when the player begins to be dragged. * This function is executed when the player begins to be dragged.
* *
* @method on_start_drag * @method on_start_drag
* @param {Event} The original browser event * @param {Event} event The original browser event
* @param {Object} A prepared ui object. * @param {Object} ui A prepared ui object.
*/ */
fn.on_start_drag = function(event, ui) { fn.on_start_drag = function(event, ui) {
@@ -1412,8 +1424,8 @@
* This function is executed when the player is being dragged. * This function is executed when the player is being dragged.
* *
* @method on_drag * @method on_drag
* @param {Event} The original browser event * @param {Event} event The original browser event
* @param {Object} A prepared ui object. * @param {Object} ui A prepared ui object.
*/ */
fn.on_drag = function(event, ui) { fn.on_drag = function(event, ui) {
//break if dragstop has been fired //break if dragstop has been fired
@@ -1455,8 +1467,8 @@
* This function is executed when the player stops being dragged. * This function is executed when the player stops being dragged.
* *
* @method on_stop_drag * @method on_stop_drag
* @param {Event} The original browser event * @param {Event} event The original browser event
* @param {Object} A prepared ui object. * @param {Object} ui A prepared ui object.
*/ */
fn.on_stop_drag = function(event, ui) { fn.on_stop_drag = function(event, ui) {
this.$helper.add(this.$player).add(this.$wrapper) this.$helper.add(this.$player).add(this.$wrapper)
@@ -1525,7 +1537,7 @@
*/ */
fn.on_overlapped_column_change = function(start_callback, stop_callback) { fn.on_overlapped_column_change = function(start_callback, stop_callback) {
if (!this.colliders_data.length) { if (!this.colliders_data.length) {
return; return this;
} }
var cols = this.get_targeted_columns( var cols = this.get_targeted_columns(
this.colliders_data[0].el.data.col); this.colliders_data[0].el.data.col);
@@ -1558,14 +1570,14 @@
* *
* @param {Function} start_callback Function executed when a new row begins * @param {Function} start_callback Function executed when a new row begins
* to be overlapped. The row is passed as first argument. * to be overlapped. The row is passed as first argument.
* @param {Function} stop_callback Function executed when a row stops being * @param {Function} end_callback Function executed when a row stops being
* overlapped. The row is passed as first argument. * overlapped. The row is passed as first argument.
* @method on_overlapped_row_change * @method on_overlapped_row_change
* @return {Class} Returns the instance of the Gridster Class. * @return {Class} Returns the instance of the Gridster Class.
*/ */
fn.on_overlapped_row_change = function(start_callback, end_callback) { fn.on_overlapped_row_change = function(start_callback, end_callback) {
if (!this.colliders_data.length) { if (!this.colliders_data.length) {
return; return this;
} }
var rows = this.get_targeted_rows(this.colliders_data[0].el.data.row); var rows = this.get_targeted_rows(this.colliders_data[0].el.data.row);
var last_n_rows = this.last_rows.length; var last_n_rows = this.last_rows.length;
@@ -1591,12 +1603,11 @@
/** /**
* Sets the current position of the player * Sets the current position of the player
* *
* @param {Function} start_callback Function executed when a new row begins * @param {Number} col
* to be overlapped. The row is passed as first argument. * @param {Number} row
* @param {Function} stop_callback Function executed when a row stops being * @param {Boolean} no_player
* overlapped. The row is passed as first argument.
* @method set_player * @method set_player
* @return {Class} Returns the instance of the Gridster Class. * @return {object}
*/ */
fn.set_player = function(col, row, no_player) { fn.set_player = function(col, row, no_player) {
var self = this; var self = this;
@@ -1647,9 +1658,9 @@
* a upper row and which not. * a upper row and which not.
* *
* @method widgets_contraints * @method widgets_contraints
* @param {HTMLElements} $widgets A jQuery wrapped collection of * @param {jQuery} $widgets A jQuery wrapped collection of
* HTMLElements. * HTMLElements.
* @return {Array} Returns a literal Object with two keys: `can_go_up` & * @return {object} Returns a literal Object with two keys: `can_go_up` &
* `can_not_go_up`. Each contains a set of HTMLElements. * `can_not_go_up`. Each contains a set of HTMLElements.
*/ */
fn.widgets_constraints = function($widgets) { fn.widgets_constraints = function($widgets) {
@@ -1767,7 +1778,7 @@
* each widget) in descending way. * each widget) in descending way.
* *
* @method manage_movements * @method manage_movements
* @param {HTMLElements} $widgets A jQuery collection of HTMLElements * @param {jQuery} $widgets A jQuery collection of HTMLElements
* representing the widgets you want to move. * representing the widgets you want to move.
* @param {Number} to_col The column to which we want to move the widgets. * @param {Number} to_col The column to which we want to move the widgets.
* @param {Number} to_row The row to which we want to move the widgets. * @param {Number} to_row The row to which we want to move the widgets.
@@ -2214,7 +2225,7 @@
* Get widgets overlapping with the player. * Get widgets overlapping with the player.
* *
* @method get_widgets_overlapped * @method get_widgets_overlapped
* @return {HTMLElements} Returns a jQuery collection of HTMLElements. * @return {jQuery} Returns a jQuery collection of HTMLElements.
*/ */
fn.get_widgets_overlapped = function() { fn.get_widgets_overlapped = function() {
var $w; var $w;
@@ -2247,7 +2258,7 @@
* *
* @method on_start_overlapping_column * @method on_start_overlapping_column
* @param {Number} col The collided column. * @param {Number} col The collided column.
* @return {HTMLElements} Returns a jQuery collection of HTMLElements. * @return {jQuery} Returns a jQuery collection of HTMLElements.
*/ */
fn.on_start_overlapping_column = function(col) { fn.on_start_overlapping_column = function(col) {
this.set_player(col, false); this.set_player(col, false);
@@ -2258,8 +2269,8 @@
* A callback executed when the player begins to collide with a row. * A callback executed when the player begins to collide with a row.
* *
* @method on_start_overlapping_row * @method on_start_overlapping_row
* @param {Number} col The collided row. * @param {Number} row The collided row.
* @return {HTMLElements} Returns a jQuery collection of HTMLElements. * @return {jQuery} Returns a jQuery collection of HTMLElements.
*/ */
fn.on_start_overlapping_row = function(row) { fn.on_start_overlapping_row = function(row) {
this.set_player(false, row); this.set_player(false, row);
@@ -2271,7 +2282,7 @@
* *
* @method on_stop_overlapping_column * @method on_stop_overlapping_column
* @param {Number} col The collided row. * @param {Number} col The collided row.
* @return {HTMLElements} Returns a jQuery collection of HTMLElements. * @return {jQuery} Returns a jQuery collection of HTMLElements.
*/ */
fn.on_stop_overlapping_column = function(col) { fn.on_stop_overlapping_column = function(col) {
this.set_player(col, false); this.set_player(col, false);
@@ -2289,7 +2300,7 @@
* *
* @method on_stop_overlapping_row * @method on_stop_overlapping_row
* @param {Number} row The collided row. * @param {Number} row The collided row.
* @return {HTMLElements} Returns a jQuery collection of HTMLElements. * @return {jQuery} Returns a jQuery collection of HTMLElements.
*/ */
fn.on_stop_overlapping_row = function(row) { fn.on_stop_overlapping_row = function(row) {
this.set_player(false, row); this.set_player(false, row);
@@ -2399,9 +2410,9 @@
* Move down the specified widget and all below it. * Move down the specified widget and all below it.
* *
* @method move_widget_down * @method move_widget_down
* @param {HTMLElement} $widget The jQuery object representing the widget * @param {jQuery} $widget The jQuery object representing the widget
* you want to move. * you want to move.
* @param {Number} The number of cells that the widget has to move. * @param {Number} y_units The number of cells that the widget has to move.
* @return {Class} Returns the instance of the Gridster Class. * @return {Class} Returns the instance of the Gridster Class.
*/ */
fn.move_widget_down = function($widget, y_units) { fn.move_widget_down = function($widget, y_units) {
@@ -2537,7 +2548,7 @@
* *
* @method widgets_below * @method widgets_below
* @param {HTMLElement} $el The jQuery wrapped HTMLElement. * @param {HTMLElement} $el The jQuery wrapped HTMLElement.
* @return {HTMLElements} A jQuery collection of HTMLElements. * @return {jQuery} A jQuery collection of HTMLElements.
*/ */
fn.widgets_below = function($el) { fn.widgets_below = function($el) {
var el_grid_data = $.isPlainObject($el) ? $el : $el.coords().grid; var el_grid_data = $.isPlainObject($el) ? $el : $el.coords().grid;
@@ -3217,6 +3228,26 @@
return this.generate_faux_grid(this.rows, this.cols); return this.generate_faux_grid(this.rows, this.cols);
}; };
/**
* Destroy this gridster by removing any sign of its presence, making it easy to avoid memory leaks
*
* @method destroy
* @return {undefined}
*/
fn.destroy = function(){
// remove bound callback on window resize
$(window).unbind('resize', this.on_window_resize);
if(this.drag_api){
this.drag_api.destroy();
}
// lastly, remove gridster element
// this will additionally cause any data associated to this element to be removed, including this
// very gridster instance
this.$el.remove();
};
//jQuery adapter //jQuery adapter
$.fn.gridster = function(options) { $.fn.gridster = function(options) {
File diff suppressed because one or more lines are too long
+22 -11
View File
@@ -16,7 +16,7 @@
autoscroll: true, autoscroll: true,
ignore_dragging: ['INPUT', 'TEXTAREA', 'SELECT', 'BUTTON'], ignore_dragging: ['INPUT', 'TEXTAREA', 'SELECT', 'BUTTON'],
handle: null handle: null
// ,drag: function(e){}, // drag: function(e){},
// start : function(e, ui){}, // start : function(e, ui){},
// stop : function(e){} // stop : function(e){}
}; };
@@ -73,24 +73,26 @@
this.disabled = false; this.disabled = false;
this.events(); this.events();
$(window).bind('resize', this.on_window_resize = throttle($.proxy(this.calculate_positions, this), 200);
throttle($.proxy(this.calculate_positions, this), 200)); $(window).bind('resize', this.on_window_resize);
}; };
fn.events = function() { fn.events = function() {
this.$container.on('selectstart', $.proxy(this.on_select_start, this)); this.proxied_on_select_start = $.proxy(this.on_select_start, this);
this.$container.on('selectstart', this.proxied_on_select_start);
this.$container.on(pointer_events.start, this.options.items, $.proxy( this.proxied_drag_handler = $.proxy(this.drag_handler, this);
this.drag_handler, this)); this.$container.on(pointer_events.start, this.options.items, this.proxied_drag_handler);
this.$body.on(pointer_events.end, $.proxy(function(e) { this.proxied_pointer_events_end = $.proxy(function(e) {
this.is_dragging = false; this.is_dragging = false;
if (this.disabled) { return; } if (this.disabled) { return; }
this.$body.off(pointer_events.move); this.$body.off(pointer_events.move);
if (this.drag_start) { if (this.drag_start) {
this.on_dragstop(e); this.on_dragstop(e);
} }
}, this)); }, this);
this.$body.on(pointer_events.end, this.proxied_pointer_events_end);
}; };
fn.get_actual_pos = function($el) { fn.get_actual_pos = function($el) {
@@ -197,7 +199,7 @@
this.mouse_init_pos = this.get_mouse_pos(e); this.mouse_init_pos = this.get_mouse_pos(e);
this.offsetY = this.mouse_init_pos.top - this.el_init_pos.top; this.offsetY = this.mouse_init_pos.top - this.el_init_pos.top;
this.$body.on(pointer_events.move, function(mme){ this.on_pointer_events_move = function(mme){
var mouse_actual_pos = self.get_mouse_pos(mme); var mouse_actual_pos = self.get_mouse_pos(mme);
var diff_x = Math.abs( var diff_x = Math.abs(
mouse_actual_pos.left - self.mouse_init_pos.left); mouse_actual_pos.left - self.mouse_init_pos.left);
@@ -205,7 +207,7 @@
mouse_actual_pos.top - self.mouse_init_pos.top); mouse_actual_pos.top - self.mouse_init_pos.top);
if (!(diff_x > self.options.distance || if (!(diff_x > self.options.distance ||
diff_y > self.options.distance) diff_y > self.options.distance)
) { ) {
return false; return false;
} }
@@ -220,7 +222,9 @@
} }
return false; return false;
}); };
this.$body.on(pointer_events.move, this.on_pointer_events_move);
return false; return false;
}; };
@@ -326,6 +330,13 @@
fn.destroy = function(){ fn.destroy = function(){
this.disable(); this.disable();
this.$container.off('selectstart', this.proxied_on_select_start);
this.$container.off(pointer_events.start, this.proxied_drag_handler);
this.$body.off(pointer_events.end, this.proxied_pointer_events_end);
this.$body.off(pointer_events.move, this.on_pointer_events_move);
$(window).unbind('resize', this.on_window_resize);
$.removeData(this.$container, 'drag'); $.removeData(this.$container, 'drag');
}; };
+49 -29
View File
@@ -106,8 +106,9 @@
this.$wrapper.addClass('ready'); this.$wrapper.addClass('ready');
this.draggable(); this.draggable();
$(window).bind( this.on_window_resize = throttle($.proxy(this.recalculate_faux_grid, this), 200);
'resize', throttle($.proxy(this.recalculate_faux_grid, this), 200));
$(window).bind('resize', this.on_window_resize);
}; };
@@ -364,7 +365,7 @@
* occupy. * occupy.
* @param {Number} size_y The number of rows that the group of cells * @param {Number} size_y The number of rows that the group of cells
* occupy. * occupy.
* @param {HTMLElement} $exclude Exclude widgets from being moved. * @param {HTMLElement} exclude Exclude widgets from being moved.
* @return {Class} Returns the instance of the Gridster Class. * @return {Class} Returns the instance of the Gridster Class.
*/ */
fn.remove_empty_cells = function(col, row, size_x, size_y, exclude) { fn.remove_empty_cells = function(col, row, size_x, size_y, exclude) {
@@ -665,8 +666,8 @@
* This function is executed when the player begins to be dragged. * This function is executed when the player begins to be dragged.
* *
* @method on_start_drag * @method on_start_drag
* @param {Event} The original browser event * @param {Event} event The original browser event
* @param {Object} A prepared ui object. * @param {Object} ui A prepared ui object.
*/ */
fn.on_start_drag = function(event, ui) { fn.on_start_drag = function(event, ui) {
@@ -716,8 +717,8 @@
* This function is executed when the player is being dragged. * This function is executed when the player is being dragged.
* *
* @method on_drag * @method on_drag
* @param {Event} The original browser event * @param {Event} event The original browser event
* @param {Object} A prepared ui object. * @param {Object} ui A prepared ui object.
*/ */
fn.on_drag = function(event, ui) { fn.on_drag = function(event, ui) {
//break if dragstop has been fired //break if dragstop has been fired
@@ -759,8 +760,8 @@
* This function is executed when the player stops being dragged. * This function is executed when the player stops being dragged.
* *
* @method on_stop_drag * @method on_stop_drag
* @param {Event} The original browser event * @param {Event} event The original browser event
* @param {Object} A prepared ui object. * @param {Object} ui A prepared ui object.
*/ */
fn.on_stop_drag = function(event, ui) { fn.on_stop_drag = function(event, ui) {
this.$helper.add(this.$player).add(this.$wrapper) this.$helper.add(this.$player).add(this.$wrapper)
@@ -829,7 +830,7 @@
*/ */
fn.on_overlapped_column_change = function(start_callback, stop_callback) { fn.on_overlapped_column_change = function(start_callback, stop_callback) {
if (!this.colliders_data.length) { if (!this.colliders_data.length) {
return; return this;
} }
var cols = this.get_targeted_columns( var cols = this.get_targeted_columns(
this.colliders_data[0].el.data.col); this.colliders_data[0].el.data.col);
@@ -862,14 +863,14 @@
* *
* @param {Function} start_callback Function executed when a new row begins * @param {Function} start_callback Function executed when a new row begins
* to be overlapped. The row is passed as first argument. * to be overlapped. The row is passed as first argument.
* @param {Function} stop_callback Function executed when a row stops being * @param {Function} end_callback Function executed when a row stops being
* overlapped. The row is passed as first argument. * overlapped. The row is passed as first argument.
* @method on_overlapped_row_change * @method on_overlapped_row_change
* @return {Class} Returns the instance of the Gridster Class. * @return {Class} Returns the instance of the Gridster Class.
*/ */
fn.on_overlapped_row_change = function(start_callback, end_callback) { fn.on_overlapped_row_change = function(start_callback, end_callback) {
if (!this.colliders_data.length) { if (!this.colliders_data.length) {
return; return this;
} }
var rows = this.get_targeted_rows(this.colliders_data[0].el.data.row); var rows = this.get_targeted_rows(this.colliders_data[0].el.data.row);
var last_n_rows = this.last_rows.length; var last_n_rows = this.last_rows.length;
@@ -895,12 +896,11 @@
/** /**
* Sets the current position of the player * Sets the current position of the player
* *
* @param {Function} start_callback Function executed when a new row begins * @param {Number} col
* to be overlapped. The row is passed as first argument. * @param {Number} row
* @param {Function} stop_callback Function executed when a row stops being * @param {Boolean} no_player
* overlapped. The row is passed as first argument.
* @method set_player * @method set_player
* @return {Class} Returns the instance of the Gridster Class. * @return {object}
*/ */
fn.set_player = function(col, row, no_player) { fn.set_player = function(col, row, no_player) {
var self = this; var self = this;
@@ -951,9 +951,9 @@
* a upper row and which not. * a upper row and which not.
* *
* @method widgets_contraints * @method widgets_contraints
* @param {HTMLElements} $widgets A jQuery wrapped collection of * @param {jQuery} $widgets A jQuery wrapped collection of
* HTMLElements. * HTMLElements.
* @return {Array} Returns a literal Object with two keys: `can_go_up` & * @return {object} Returns a literal Object with two keys: `can_go_up` &
* `can_not_go_up`. Each contains a set of HTMLElements. * `can_not_go_up`. Each contains a set of HTMLElements.
*/ */
fn.widgets_constraints = function($widgets) { fn.widgets_constraints = function($widgets) {
@@ -1071,7 +1071,7 @@
* each widget) in descending way. * each widget) in descending way.
* *
* @method manage_movements * @method manage_movements
* @param {HTMLElements} $widgets A jQuery collection of HTMLElements * @param {jQuery} $widgets A jQuery collection of HTMLElements
* representing the widgets you want to move. * representing the widgets you want to move.
* @param {Number} to_col The column to which we want to move the widgets. * @param {Number} to_col The column to which we want to move the widgets.
* @param {Number} to_row The row to which we want to move the widgets. * @param {Number} to_row The row to which we want to move the widgets.
@@ -1518,7 +1518,7 @@
* Get widgets overlapping with the player. * Get widgets overlapping with the player.
* *
* @method get_widgets_overlapped * @method get_widgets_overlapped
* @return {HTMLElements} Returns a jQuery collection of HTMLElements. * @return {jQuery} Returns a jQuery collection of HTMLElements.
*/ */
fn.get_widgets_overlapped = function() { fn.get_widgets_overlapped = function() {
var $w; var $w;
@@ -1551,7 +1551,7 @@
* *
* @method on_start_overlapping_column * @method on_start_overlapping_column
* @param {Number} col The collided column. * @param {Number} col The collided column.
* @return {HTMLElements} Returns a jQuery collection of HTMLElements. * @return {jQuery} Returns a jQuery collection of HTMLElements.
*/ */
fn.on_start_overlapping_column = function(col) { fn.on_start_overlapping_column = function(col) {
this.set_player(col, false); this.set_player(col, false);
@@ -1562,8 +1562,8 @@
* A callback executed when the player begins to collide with a row. * A callback executed when the player begins to collide with a row.
* *
* @method on_start_overlapping_row * @method on_start_overlapping_row
* @param {Number} col The collided row. * @param {Number} row The collided row.
* @return {HTMLElements} Returns a jQuery collection of HTMLElements. * @return {jQuery} Returns a jQuery collection of HTMLElements.
*/ */
fn.on_start_overlapping_row = function(row) { fn.on_start_overlapping_row = function(row) {
this.set_player(false, row); this.set_player(false, row);
@@ -1575,7 +1575,7 @@
* *
* @method on_stop_overlapping_column * @method on_stop_overlapping_column
* @param {Number} col The collided row. * @param {Number} col The collided row.
* @return {HTMLElements} Returns a jQuery collection of HTMLElements. * @return {jQuery} Returns a jQuery collection of HTMLElements.
*/ */
fn.on_stop_overlapping_column = function(col) { fn.on_stop_overlapping_column = function(col) {
this.set_player(col, false); this.set_player(col, false);
@@ -1593,7 +1593,7 @@
* *
* @method on_stop_overlapping_row * @method on_stop_overlapping_row
* @param {Number} row The collided row. * @param {Number} row The collided row.
* @return {HTMLElements} Returns a jQuery collection of HTMLElements. * @return {jQuery} Returns a jQuery collection of HTMLElements.
*/ */
fn.on_stop_overlapping_row = function(row) { fn.on_stop_overlapping_row = function(row) {
this.set_player(false, row); this.set_player(false, row);
@@ -1703,9 +1703,9 @@
* Move down the specified widget and all below it. * Move down the specified widget and all below it.
* *
* @method move_widget_down * @method move_widget_down
* @param {HTMLElement} $widget The jQuery object representing the widget * @param {jQuery} $widget The jQuery object representing the widget
* you want to move. * you want to move.
* @param {Number} The number of cells that the widget has to move. * @param {Number} y_units The number of cells that the widget has to move.
* @return {Class} Returns the instance of the Gridster Class. * @return {Class} Returns the instance of the Gridster Class.
*/ */
fn.move_widget_down = function($widget, y_units) { fn.move_widget_down = function($widget, y_units) {
@@ -1841,7 +1841,7 @@
* *
* @method widgets_below * @method widgets_below
* @param {HTMLElement} $el The jQuery wrapped HTMLElement. * @param {HTMLElement} $el The jQuery wrapped HTMLElement.
* @return {HTMLElements} A jQuery collection of HTMLElements. * @return {jQuery} A jQuery collection of HTMLElements.
*/ */
fn.widgets_below = function($el) { fn.widgets_below = function($el) {
var el_grid_data = $.isPlainObject($el) ? $el : $el.coords().grid; var el_grid_data = $.isPlainObject($el) ? $el : $el.coords().grid;
@@ -2521,6 +2521,26 @@
return this.generate_faux_grid(this.rows, this.cols); return this.generate_faux_grid(this.rows, this.cols);
}; };
/**
* Destroy this gridster by removing any sign of its presence, making it easy to avoid memory leaks
*
* @method destroy
* @return {undefined}
*/
fn.destroy = function(){
// remove bound callback on window resize
$(window).unbind('resize', this.on_window_resize);
if(this.drag_api){
this.drag_api.destroy();
}
// lastly, remove gridster element
// this will additionally cause any data associated to this element to be removed, including this
// very gridster instance
this.$el.remove();
};
//jQuery adapter //jQuery adapter
$.fn.gridster = function(options) { $.fn.gridster = function(options) {