pyk 0.2.6 → 0.2.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (68) hide show
  1. checksums.yaml +8 -8
  2. data/app/assets/javascripts/lib/chardinjs.min.js +2 -0
  3. data/app/assets/javascripts/lib/crossfilter.js +1383 -1
  4. data/app/assets/javascripts/lib/{d3.js → d3.v3.js} +0 -0
  5. data/app/assets/javascripts/lib/dc.js +3492 -757
  6. data/app/assets/javascripts/lib/jquery.gridster.js +2 -3621
  7. data/app/assets/javascripts/lib/markermanager.js +2 -980
  8. data/app/assets/javascripts/lib/underscore.js +1276 -0
  9. data/app/assets/javascripts/nvd3/lib/colorbrewer.js +302 -0
  10. data/app/assets/javascripts/nvd3/lib/crossfilter.js +1180 -0
  11. data/app/assets/javascripts/nvd3/lib/crossfilter.min.js +1 -0
  12. data/app/assets/javascripts/nvd3/lib/d3.v2.js +7033 -0
  13. data/app/assets/javascripts/nvd3/lib/d3.v2.min.js +4 -0
  14. data/app/assets/javascripts/nvd3/lib/d3.v3.js +8436 -0
  15. data/app/assets/javascripts/nvd3/lib/fisheye.js +86 -0
  16. data/app/assets/javascripts/nvd3/lib/hive.js +80 -0
  17. data/app/assets/javascripts/nvd3/lib/horizon.js +192 -0
  18. data/app/assets/javascripts/nvd3/lib/sankey.js +292 -0
  19. data/app/assets/javascripts/nvd3/nv.d3.js +14312 -0
  20. data/app/assets/javascripts/nvd3/nv.d3.min.js +6 -0
  21. data/app/assets/javascripts/nvd3/src/core.js +122 -0
  22. data/app/assets/javascripts/nvd3/src/interactiveLayer.js +251 -0
  23. data/app/assets/javascripts/nvd3/src/models/axis.js +405 -0
  24. data/app/assets/javascripts/nvd3/src/models/backup/bullet.js +250 -0
  25. data/app/assets/javascripts/nvd3/src/models/backup/bulletChart.js +349 -0
  26. data/app/assets/javascripts/nvd3/src/models/boilerplate.js +104 -0
  27. data/app/assets/javascripts/nvd3/src/models/bullet.js +385 -0
  28. data/app/assets/javascripts/nvd3/src/models/bulletChart.js +343 -0
  29. data/app/assets/javascripts/nvd3/src/models/cumulativeLineChart.js +782 -0
  30. data/app/assets/javascripts/nvd3/src/models/discreteBar.js +349 -0
  31. data/app/assets/javascripts/nvd3/src/models/discreteBarChart.js +333 -0
  32. data/app/assets/javascripts/nvd3/src/models/distribution.js +148 -0
  33. data/app/assets/javascripts/nvd3/src/models/historicalBar.js +331 -0
  34. data/app/assets/javascripts/nvd3/src/models/historicalBarChart.js +419 -0
  35. data/app/assets/javascripts/nvd3/src/models/indentedTree.js +337 -0
  36. data/app/assets/javascripts/nvd3/src/models/legend.js +270 -0
  37. data/app/assets/javascripts/nvd3/src/models/line.js +284 -0
  38. data/app/assets/javascripts/nvd3/src/models/lineChart.js +465 -0
  39. data/app/assets/javascripts/nvd3/src/models/linePlusBarChart.js +433 -0
  40. data/app/assets/javascripts/nvd3/src/models/linePlusBarWithFocusChart.js +658 -0
  41. data/app/assets/javascripts/nvd3/src/models/lineWithFisheye.js +200 -0
  42. data/app/assets/javascripts/nvd3/src/models/lineWithFisheyeChart.js +297 -0
  43. data/app/assets/javascripts/nvd3/src/models/lineWithFocusChart.js +574 -0
  44. data/app/assets/javascripts/nvd3/src/models/multiBar.js +461 -0
  45. data/app/assets/javascripts/nvd3/src/models/multiBarChart.js +524 -0
  46. data/app/assets/javascripts/nvd3/src/models/multiBarHorizontal.js +424 -0
  47. data/app/assets/javascripts/nvd3/src/models/multiBarHorizontalChart.js +434 -0
  48. data/app/assets/javascripts/nvd3/src/models/multiBarTimeSeries.js +384 -0
  49. data/app/assets/javascripts/nvd3/src/models/multiBarTimeSeriesChart.js +405 -0
  50. data/app/assets/javascripts/nvd3/src/models/multiChart.js +452 -0
  51. data/app/assets/javascripts/nvd3/src/models/ohlcBar.js +380 -0
  52. data/app/assets/javascripts/nvd3/src/models/parallelCoordinates.js +239 -0
  53. data/app/assets/javascripts/nvd3/src/models/pie.js +398 -0
  54. data/app/assets/javascripts/nvd3/src/models/pieChart.js +292 -0
  55. data/app/assets/javascripts/nvd3/src/models/scatter.js +674 -0
  56. data/app/assets/javascripts/nvd3/src/models/scatterChart.js +628 -0
  57. data/app/assets/javascripts/nvd3/src/models/scatterPlusLineChart.js +620 -0
  58. data/app/assets/javascripts/nvd3/src/models/sparkline.js +194 -0
  59. data/app/assets/javascripts/nvd3/src/models/sparklinePlus.js +295 -0
  60. data/app/assets/javascripts/nvd3/src/models/stackedArea.js +368 -0
  61. data/app/assets/javascripts/nvd3/src/models/stackedAreaChart.js +629 -0
  62. data/app/assets/javascripts/nvd3/src/tooltip.js +490 -0
  63. data/app/assets/javascripts/nvd3/src/utils.js +152 -0
  64. data/app/assets/javascripts/pyk.js +1 -0
  65. data/app/assets/stylesheets/lib/chardinjs.css +82 -0
  66. data/app/assets/stylesheets/nvd3/nv.d3.css +769 -0
  67. data/app/assets/stylesheets/pyk.css.scss +1 -0
  68. metadata +61 -2
@@ -1,3621 +1,2 @@
1
- /*
2
- * jquery.coords
3
- * https://github.com/ducksboard/gridster.js
4
- *
5
- * Copyright (c) 2012 ducksboard
6
- * Licensed under the MIT licenses.
7
- */
8
-
9
- ;(function($, window, document, undefined){
10
- /**
11
- * Creates objects with coordinates (x1, y1, x2, y2, cx, cy, width, height)
12
- * to simulate DOM elements on the screen.
13
- * Coords is used by Gridster to create a faux grid with any DOM element can
14
- * collide.
15
- *
16
- * @class Coords
17
- * @param {HTMLElement|Object} obj The jQuery HTMLElement or a object with: left,
18
- * top, width and height properties.
19
- * @return {Object} Coords instance.
20
- * @constructor
21
- */
22
- function Coords(obj) {
23
- if (obj[0] && $.isPlainObject(obj[0])) {
24
- this.data = obj[0];
25
- }else {
26
- this.el = obj;
27
- }
28
-
29
- this.isCoords = true;
30
- this.coords = {};
31
- this.init();
32
- return this;
33
- }
34
-
35
-
36
- var fn = Coords.prototype;
37
-
38
-
39
- fn.init = function(){
40
- this.set();
41
- this.original_coords = this.get();
42
- };
43
-
44
-
45
- fn.set = function(update, not_update_offsets) {
46
- var el = this.el;
47
-
48
- if (el && !update) {
49
- this.data = el.offset();
50
- this.data.width = el.width();
51
- this.data.height = el.height();
52
- }
53
-
54
- if (el && update && !not_update_offsets) {
55
- var offset = el.offset();
56
- this.data.top = offset.top;
57
- this.data.left = offset.left;
58
- }
59
-
60
- var d = this.data;
61
-
62
- this.coords.x1 = d.left;
63
- this.coords.y1 = d.top;
64
- this.coords.x2 = d.left + d.width;
65
- this.coords.y2 = d.top + d.height;
66
- this.coords.cx = d.left + (d.width / 2);
67
- this.coords.cy = d.top + (d.height / 2);
68
- this.coords.width = d.width;
69
- this.coords.height = d.height;
70
- this.coords.el = el || false ;
71
-
72
- return this;
73
- };
74
-
75
-
76
- fn.update = function(data){
77
- if (!data && !this.el) {
78
- return this;
79
- }
80
-
81
- if (data) {
82
- var new_data = $.extend({}, this.data, data);
83
- this.data = new_data;
84
- return this.set(true, true);
85
- }
86
-
87
- this.set(true);
88
- return this;
89
- };
90
-
91
-
92
- fn.get = function(){
93
- return this.coords;
94
- };
95
-
96
-
97
- //jQuery adapter
98
- $.fn.coords = function() {
99
- if (this.data('coords') ) {
100
- return this.data('coords');
101
- }
102
-
103
- var ins = new Coords(this, arguments[0]);
104
- this.data('coords', ins);
105
- return ins;
106
- };
107
-
108
- }(jQuery, window, document));
109
-
110
- /*
111
- * jquery.collision
112
- * https://github.com/ducksboard/gridster.js
113
- *
114
- * Copyright (c) 2012 ducksboard
115
- * Licensed under the MIT licenses.
116
- */
117
-
118
- ;(function($, window, document, undefined){
119
-
120
- var defaults = {
121
- colliders_context: document.body
122
- // ,on_overlap: function(collider_data){},
123
- // on_overlap_start : function(collider_data){},
124
- // on_overlap_stop : function(collider_data){}
125
- };
126
-
127
-
128
- /**
129
- * Detects collisions between a DOM element against other DOM elements or
130
- * Coords objects.
131
- *
132
- * @class Collision
133
- * @uses Coords
134
- * @param {HTMLElement} el The jQuery wrapped HTMLElement.
135
- * @param {HTMLElement|Array} colliders Can be a jQuery collection
136
- * of HTMLElements or an Array of Coords instances.
137
- * @param {Object} [options] An Object with all options you want to
138
- * overwrite:
139
- * @param {Function} [options.on_overlap_start] Executes a function the first
140
- * time each `collider ` is overlapped.
141
- * @param {Function} [options.on_overlap_stop] Executes a function when a
142
- * `collider` is no longer collided.
143
- * @param {Function} [options.on_overlap] Executes a function when the
144
- * mouse is moved during the collision.
145
- * @return {Object} Collision instance.
146
- * @constructor
147
- */
148
- function Collision(el, colliders, options) {
149
- this.options = $.extend(defaults, options);
150
- this.$element = el;
151
- this.last_colliders = [];
152
- this.last_colliders_coords = [];
153
- if (typeof colliders === 'string' || colliders instanceof jQuery) {
154
- this.$colliders = $(colliders,
155
- this.options.colliders_context).not(this.$element);
156
- }else{
157
- this.colliders = $(colliders);
158
- }
159
-
160
- this.init();
161
- }
162
-
163
-
164
- var fn = Collision.prototype;
165
-
166
-
167
- fn.init = function() {
168
- this.find_collisions();
169
- };
170
-
171
-
172
- fn.overlaps = function(a, b) {
173
- var x = false;
174
- var y = false;
175
-
176
- if ((b.x1 >= a.x1 && b.x1 <= a.x2) ||
177
- (b.x2 >= a.x1 && b.x2 <= a.x2) ||
178
- (a.x1 >= b.x1 && a.x2 <= b.x2)
179
- ) { x = true; }
180
-
181
- if ((b.y1 >= a.y1 && b.y1 <= a.y2) ||
182
- (b.y2 >= a.y1 && b.y2 <= a.y2) ||
183
- (a.y1 >= b.y1 && a.y2 <= b.y2)
184
- ) { y = true; }
185
-
186
- return (x && y);
187
- };
188
-
189
-
190
- fn.detect_overlapping_region = function(a, b){
191
- var regionX = '';
192
- var regionY = '';
193
-
194
- if (a.y1 > b.cy && a.y1 < b.y2) { regionX = 'N'; }
195
- if (a.y2 > b.y1 && a.y2 < b.cy) { regionX = 'S'; }
196
- if (a.x1 > b.cx && a.x1 < b.x2) { regionY = 'W'; }
197
- if (a.x2 > b.x1 && a.x2 < b.cx) { regionY = 'E'; }
198
-
199
- return (regionX + regionY) || 'C';
200
- };
201
-
202
-
203
- fn.calculate_overlapped_area_coords = function(a, b){
204
- var x1 = Math.max(a.x1, b.x1);
205
- var y1 = Math.max(a.y1, b.y1);
206
- var x2 = Math.min(a.x2, b.x2);
207
- var y2 = Math.min(a.y2, b.y2);
208
-
209
- return $({
210
- left: x1,
211
- top: y1,
212
- width : (x2 - x1),
213
- height: (y2 - y1)
214
- }).coords().get();
215
- };
216
-
217
-
218
- fn.calculate_overlapped_area = function(coords){
219
- return (coords.width * coords.height);
220
- };
221
-
222
-
223
- fn.manage_colliders_start_stop = function(new_colliders_coords, start_callback, stop_callback){
224
- var last = this.last_colliders_coords;
225
-
226
- for (var i = 0, il = last.length; i < il; i++) {
227
- if ($.inArray(last[i], new_colliders_coords) === -1) {
228
- start_callback.call(this, last[i]);
229
- }
230
- }
231
-
232
- for (var j = 0, jl = new_colliders_coords.length; j < jl; j++) {
233
- if ($.inArray(new_colliders_coords[j], last) === -1) {
234
- stop_callback.call(this, new_colliders_coords[j]);
235
- }
236
-
237
- }
238
- };
239
-
240
-
241
- fn.find_collisions = function(player_data_coords){
242
- var self = this;
243
- var colliders_coords = [];
244
- var colliders_data = [];
245
- var $colliders = (this.colliders || this.$colliders);
246
- var count = $colliders.length;
247
- var player_coords = self.$element.coords()
248
- .update(player_data_coords || false).get();
249
-
250
- while(count--){
251
- var $collider = self.$colliders ?
252
- $($colliders[count]) : $colliders[count];
253
- var $collider_coords_ins = ($collider.isCoords) ?
254
- $collider : $collider.coords();
255
- var collider_coords = $collider_coords_ins.get();
256
- var overlaps = self.overlaps(player_coords, collider_coords);
257
-
258
- if (!overlaps) {
259
- continue;
260
- }
261
-
262
- var region = self.detect_overlapping_region(
263
- player_coords, collider_coords);
264
-
265
- //todo: make this an option
266
- if (region === 'C'){
267
- var area_coords = self.calculate_overlapped_area_coords(
268
- player_coords, collider_coords);
269
- var area = self.calculate_overlapped_area(area_coords);
270
- var collider_data = {
271
- area: area,
272
- area_coords : area_coords,
273
- region: region,
274
- coords: collider_coords,
275
- player_coords: player_coords,
276
- el: $collider
277
- };
278
-
279
- if (self.options.on_overlap) {
280
- self.options.on_overlap.call(this, collider_data);
281
- }
282
- colliders_coords.push($collider_coords_ins);
283
- colliders_data.push(collider_data);
284
- }
285
- }
286
-
287
- if (self.options.on_overlap_stop || self.options.on_overlap_start) {
288
- this.manage_colliders_start_stop(colliders_coords,
289
- self.options.on_overlap_start, self.options.on_overlap_stop);
290
- }
291
-
292
- this.last_colliders_coords = colliders_coords;
293
-
294
- return colliders_data;
295
- };
296
-
297
-
298
- fn.get_closest_colliders = function(player_data_coords){
299
- var colliders = this.find_collisions(player_data_coords);
300
-
301
- colliders.sort(function(a, b) {
302
- /* if colliders are being overlapped by the "C" (center) region,
303
- * we have to set a lower index in the array to which they are placed
304
- * above in the grid. */
305
- if (a.region === 'C' && b.region === 'C') {
306
- if (a.coords.y1 < b.coords.y1 || a.coords.x1 < b.coords.x1) {
307
- return - 1;
308
- }else{
309
- return 1;
310
- }
311
- }
312
-
313
- if (a.area < b.area) {
314
- return 1;
315
- }
316
-
317
- return 1;
318
- });
319
- return colliders;
320
- };
321
-
322
-
323
- //jQuery adapter
324
- $.fn.collision = function(collider, options) {
325
- return new Collision( this, collider, options );
326
- };
327
-
328
-
329
- }(jQuery, window, document));
330
-
331
- ;(function(window, undefined) {
332
- /* Debounce and throttle functions taken from underscore.js */
333
- window.debounce = function(func, wait, immediate) {
334
- var timeout;
335
- return function() {
336
- var context = this, args = arguments;
337
- var later = function() {
338
- timeout = null;
339
- if (!immediate) func.apply(context, args);
340
- };
341
- if (immediate && !timeout) func.apply(context, args);
342
- clearTimeout(timeout);
343
- timeout = setTimeout(later, wait);
344
- };
345
- };
346
-
347
-
348
- window.throttle = function(func, wait) {
349
- var context, args, timeout, throttling, more, result;
350
- var whenDone = debounce(
351
- function(){ more = throttling = false; }, wait);
352
- return function() {
353
- context = this; args = arguments;
354
- var later = function() {
355
- timeout = null;
356
- if (more) func.apply(context, args);
357
- whenDone();
358
- };
359
- if (!timeout) timeout = setTimeout(later, wait);
360
- if (throttling) {
361
- more = true;
362
- } else {
363
- result = func.apply(context, args);
364
- }
365
- whenDone();
366
- throttling = true;
367
- return result;
368
- };
369
- };
370
-
371
- })(window);
372
-
373
- /*
374
- * jquery.draggable
375
- * https://github.com/ducksboard/gridster.js
376
- *
377
- * Copyright (c) 2012 ducksboard
378
- * Licensed under the MIT licenses.
379
- */
380
-
381
- ;(function($, window, document, undefined){
382
-
383
- var defaults = {
384
- items: '.gs_w',
385
- distance: 1,
386
- limit: true,
387
- offset_left: 0,
388
- autoscroll: true,
389
- ignore_dragging: ['INPUT', 'TEXTAREA', 'SELECT', 'BUTTON'],
390
- handle: null
391
- // drag: function(e){},
392
- // start : function(e, ui){},
393
- // stop : function(e){}
394
- };
395
-
396
- var $window = $(window);
397
- var isTouch = !!('ontouchstart' in window);
398
- var pointer_events = {
399
- start: isTouch ? 'touchstart' : 'mousedown.draggable',
400
- move: isTouch ? 'touchmove' : 'mousemove.draggable',
401
- end: isTouch ? 'touchend' : 'mouseup.draggable'
402
- };
403
-
404
- /**
405
- * Basic drag implementation for DOM elements inside a container.
406
- * Provide start/stop/drag callbacks.
407
- *
408
- * @class Draggable
409
- * @param {HTMLElement} el The HTMLelement that contains all the widgets
410
- * to be dragged.
411
- * @param {Object} [options] An Object with all options you want to
412
- * overwrite:
413
- * @param {HTMLElement|String} [options.items] Define who will
414
- * be the draggable items. Can be a CSS Selector String or a
415
- * collection of HTMLElements.
416
- * @param {Number} [options.distance] Distance in pixels after mousedown
417
- * the mouse must move before dragging should start.
418
- * @param {Boolean} [options.limit] Constrains dragging to the width of
419
- * the container
420
- * @param {offset_left} [options.offset_left] Offset added to the item
421
- * that is being dragged.
422
- * @param {Number} [options.drag] Executes a callback when the mouse is
423
- * moved during the dragging.
424
- * @param {Number} [options.start] Executes a callback when the drag
425
- * starts.
426
- * @param {Number} [options.stop] Executes a callback when the drag stops.
427
- * @return {Object} Returns `el`.
428
- * @constructor
429
- */
430
- function Draggable(el, options) {
431
- this.options = $.extend({}, defaults, options);
432
- this.$body = $(document.body);
433
- this.$container = $(el);
434
- this.$dragitems = $(this.options.items, this.$container);
435
- this.is_dragging = false;
436
- this.player_min_left = 0 + this.options.offset_left;
437
- this.init();
438
- }
439
-
440
- var fn = Draggable.prototype;
441
-
442
- fn.init = function() {
443
- this.calculate_positions();
444
- this.$container.css('position', 'relative');
445
- this.disabled = false;
446
- this.events();
447
-
448
- this.on_window_resize = throttle($.proxy(this.calculate_positions, this), 200);
449
- $(window).bind('resize', this.on_window_resize);
450
- };
451
-
452
- fn.events = function() {
453
- this.proxied_on_select_start = $.proxy(this.on_select_start, this);
454
- this.$container.on('selectstart', this.proxied_on_select_start);
455
-
456
- this.proxied_drag_handler = $.proxy(this.drag_handler, this);
457
- this.$container.on(pointer_events.start, this.options.items, this.proxied_drag_handler);
458
-
459
- this.proxied_pointer_events_end = $.proxy(function(e) {
460
- this.is_dragging = false;
461
- if (this.disabled) { return; }
462
- this.$body.off(pointer_events.move);
463
- if (this.drag_start) {
464
- this.on_dragstop(e);
465
- }
466
- }, this);
467
- this.$body.on(pointer_events.end, this.proxied_pointer_events_end);
468
- };
469
-
470
- fn.get_actual_pos = function($el) {
471
- var pos = $el.position();
472
- return pos;
473
- };
474
-
475
-
476
- fn.get_mouse_pos = function(e) {
477
- if (isTouch) {
478
- var oe = e.originalEvent;
479
- e = oe.touches.length ? oe.touches[0] : oe.changedTouches[0];
480
- }
481
-
482
- return {
483
- left: e.clientX,
484
- top: e.clientY
485
- };
486
- };
487
-
488
-
489
- fn.get_offset = function(e) {
490
- e.preventDefault();
491
- var mouse_actual_pos = this.get_mouse_pos(e);
492
- var diff_x = Math.round(
493
- mouse_actual_pos.left - this.mouse_init_pos.left);
494
- var diff_y = Math.round(mouse_actual_pos.top - this.mouse_init_pos.top);
495
-
496
- var left = Math.round(this.el_init_offset.left + diff_x - this.baseX);
497
- var top = Math.round(
498
- this.el_init_offset.top + diff_y - this.baseY + this.scrollOffset);
499
-
500
- if (this.options.limit) {
501
- if (left > this.player_max_left) {
502
- left = this.player_max_left;
503
- }else if(left < this.player_min_left) {
504
- left = this.player_min_left;
505
- }
506
- }
507
-
508
- return {
509
- left: left,
510
- top: top,
511
- mouse_left: mouse_actual_pos.left,
512
- mouse_top: mouse_actual_pos.top
513
- };
514
- };
515
-
516
-
517
- fn.manage_scroll = function(offset) {
518
- /* scroll document */
519
- var nextScrollTop;
520
- var scrollTop = $window.scrollTop();
521
- var min_window_y = scrollTop;
522
- var max_window_y = min_window_y + this.window_height;
523
-
524
- var mouse_down_zone = max_window_y - 50;
525
- var mouse_up_zone = min_window_y + 50;
526
-
527
- var abs_mouse_left = offset.mouse_left;
528
- var abs_mouse_top = min_window_y + offset.mouse_top;
529
-
530
- var max_player_y = (this.doc_height - this.window_height +
531
- this.player_height);
532
-
533
- if (abs_mouse_top >= mouse_down_zone) {
534
- nextScrollTop = scrollTop + 30;
535
- if (nextScrollTop < max_player_y) {
536
- $window.scrollTop(nextScrollTop);
537
- this.scrollOffset = this.scrollOffset + 30;
538
- }
539
- }
540
-
541
- if (abs_mouse_top <= mouse_up_zone) {
542
- nextScrollTop = scrollTop - 30;
543
- if (nextScrollTop > 0) {
544
- $window.scrollTop(nextScrollTop);
545
- this.scrollOffset = this.scrollOffset - 30;
546
- }
547
- }
548
- };
549
-
550
-
551
- fn.calculate_positions = function(e) {
552
- this.window_height = $window.height();
553
- };
554
-
555
-
556
- fn.drag_handler = function(e) {
557
- var node = e.target.nodeName;
558
- if (this.disabled || e.which !== 1 && !isTouch) {
559
- return;
560
- }
561
-
562
- if (this.ignore_drag(e)) {
563
- return;
564
- }
565
-
566
- var self = this;
567
- var first = true;
568
- this.$player = $(e.currentTarget);
569
-
570
- this.el_init_pos = this.get_actual_pos(this.$player);
571
- this.mouse_init_pos = this.get_mouse_pos(e);
572
- this.offsetY = this.mouse_init_pos.top - this.el_init_pos.top;
573
-
574
- this.on_pointer_events_move = function(mme){
575
- var mouse_actual_pos = self.get_mouse_pos(mme);
576
- var diff_x = Math.abs(
577
- mouse_actual_pos.left - self.mouse_init_pos.left);
578
- var diff_y = Math.abs(
579
- mouse_actual_pos.top - self.mouse_init_pos.top);
580
- if (!(diff_x > self.options.distance ||
581
- diff_y > self.options.distance)
582
- ) {
583
- return false;
584
- }
585
-
586
- if (first) {
587
- first = false;
588
- self.on_dragstart.call(self, mme);
589
- return false;
590
- }
591
-
592
- if (self.is_dragging === true) {
593
- self.on_dragmove.call(self, mme);
594
- }
595
-
596
- return false;
597
- };
598
-
599
- this.$body.on(pointer_events.move, this.on_pointer_events_move);
600
-
601
- return false;
602
- };
603
-
604
-
605
- fn.on_dragstart = function(e) {
606
- e.preventDefault();
607
- this.drag_start = true;
608
- this.is_dragging = true;
609
- var offset = this.$container.offset();
610
- this.baseX = Math.round(offset.left);
611
- this.baseY = Math.round(offset.top);
612
- this.doc_height = $(document).height();
613
-
614
- if (this.options.helper === 'clone') {
615
- this.$helper = this.$player.clone()
616
- .appendTo(this.$container).addClass('helper');
617
- this.helper = true;
618
- }else{
619
- this.helper = false;
620
- }
621
- this.scrollOffset = 0;
622
- this.el_init_offset = this.$player.offset();
623
- this.player_width = this.$player.width();
624
- this.player_height = this.$player.height();
625
- this.player_max_left = (this.$container.width() - this.player_width +
626
- this.options.offset_left);
627
-
628
- if (this.options.start) {
629
- this.options.start.call(this.$player, e, {
630
- helper: this.helper ? this.$helper : this.$player
631
- });
632
- }
633
- return false;
634
- };
635
-
636
-
637
- fn.on_dragmove = function(e) {
638
- var offset = this.get_offset(e);
639
-
640
- this.options.autoscroll && this.manage_scroll(offset);
641
-
642
- (this.helper ? this.$helper : this.$player).css({
643
- 'position': 'absolute',
644
- 'left' : offset.left,
645
- 'top' : offset.top
646
- });
647
-
648
- var ui = {
649
- 'position': {
650
- 'left': offset.left,
651
- 'top': offset.top
652
- }
653
- };
654
-
655
- if (this.options.drag) {
656
- this.options.drag.call(this.$player, e, ui);
657
- }
658
- return false;
659
- };
660
-
661
-
662
- fn.on_dragstop = function(e) {
663
- var offset = this.get_offset(e);
664
- this.drag_start = false;
665
-
666
- var ui = {
667
- 'position': {
668
- 'left': offset.left,
669
- 'top': offset.top
670
- }
671
- };
672
-
673
- if (this.options.stop) {
674
- this.options.stop.call(this.$player, e, ui);
675
- }
676
-
677
- if (this.helper) {
678
- this.$helper.remove();
679
- }
680
-
681
- return false;
682
- };
683
-
684
- fn.on_select_start = function(e) {
685
- if (this.disabled) { return; }
686
-
687
- if (this.ignore_drag(e)) {
688
- return;
689
- }
690
-
691
- return false;
692
- };
693
-
694
- fn.enable = function() {
695
- this.disabled = false;
696
- };
697
-
698
- fn.disable = function() {
699
- this.disabled = true;
700
- };
701
-
702
-
703
- fn.destroy = function(){
704
- this.disable();
705
-
706
- this.$container.off('selectstart', this.proxied_on_select_start);
707
- this.$container.off(pointer_events.start, this.proxied_drag_handler);
708
- this.$body.off(pointer_events.end, this.proxied_pointer_events_end);
709
- this.$body.off(pointer_events.move, this.on_pointer_events_move);
710
- $(window).unbind('resize', this.on_window_resize);
711
-
712
- $.removeData(this.$container, 'drag');
713
- };
714
-
715
- fn.ignore_drag = function(event) {
716
- if (this.options.handle) {
717
- return !$(event.target).is(this.options.handle);
718
- }
719
-
720
- return $.inArray(event.target.nodeName, this.options.ignore_dragging) >= 0;
721
- };
722
-
723
- //jQuery adapter
724
- $.fn.dragg = function ( options ) {
725
- return this.each(function () {
726
- if (!$.data(this, 'drag')) {
727
- $.data(this, 'drag', new Draggable( this, options ));
728
- }
729
- });
730
- };
731
-
732
-
733
- }(jQuery, window, document));
734
-
735
- /*
736
- * jquery.gridster
737
- * https://github.com/ducksboard/gridster.js
738
- *
739
- * Copyright (c) 2012 ducksboard
740
- * Licensed under the MIT licenses.
741
- */
742
- ;(function($, window, document, undefined) {
743
-
744
- //ToDo Max_cols and Max_size_x conflict.. need to unify
745
- var defaults = {
746
- namespace: '',
747
- widget_selector: 'li',
748
- static_class: 'static',
749
- widget_margins: [10, 10],
750
- widget_base_dimensions: [400, 225],
751
- extra_rows: 0,
752
- extra_cols: 0,
753
- min_cols: 1,
754
- max_cols: 60,
755
- min_rows: 15,
756
- max_rows: 15,
757
- max_size_x: 6,
758
- autogenerate_stylesheet: true,
759
- avoid_overlapped_widgets: true,
760
- shift_larger_widgets_down: true,
761
- serialize_params: function($w, wgd) {
762
- return {
763
- col: wgd.col,
764
- row: wgd.row,
765
- size_x: wgd.size_x,
766
- size_y: wgd.size_y
767
- };
768
- },
769
- collision: {},
770
- draggable: {
771
- distance: 4,
772
- items: ".gs_w:not(.static)"
773
- }
774
- };
775
-
776
-
777
- /**
778
- * @class Gridster
779
- * @uses Draggable
780
- * @uses Collision
781
- * @param {HTMLElement} el The HTMLelement that contains all the widgets.
782
- * @param {Object} [options] An Object with all options you want to
783
- * overwrite:
784
- * @param {HTMLElement|String} [options.widget_selector] Define who will
785
- * be the draggable widgets. Can be a CSS Selector String or a
786
- * collection of HTMLElements
787
- * @param {Array} [options.widget_margins] Margin between widgets.
788
- * The first index for the horizontal margin (left, right) and
789
- * the second for the vertical margin (top, bottom).
790
- * @param {Array} [options.widget_base_dimensions] Base widget dimensions
791
- * in pixels. The first index for the width and the second for the
792
- * height.
793
- * @param {Number} [options.extra_cols] Add more columns in addition to
794
- * those that have been calculated.
795
- * @param {Number} [options.extra_rows] Add more rows in addition to
796
- * those that have been calculated.
797
- * @param {Number} [options.min_cols] The minimum required columns.
798
- * @param {Number} [options.min_rows] The minimum required rows.
799
- * @param {Number} [options.max_size_x] The maximum number of columns
800
- * that a widget can span.
801
- * @param {Boolean} [options.autogenerate_stylesheet] If true, all the
802
- * CSS required to position all widgets in their respective columns
803
- * and rows will be generated automatically and injected to the
804
- * `<head>` of the document. You can set this to false, and write
805
- * your own CSS targeting rows and cols via data-attributes like so:
806
- * `[data-col="1"] { left: 10px; }`
807
- * @param {Boolean} [options.avoid_overlapped_widgets] Avoid that widgets loaded
808
- * from the DOM can be overlapped. It is helpful if the positions were
809
- * bad stored in the database or if there was any conflict.
810
- * @param {Function} [options.serialize_params] Return the data you want
811
- * for each widget in the serialization. Two arguments are passed:
812
- * `$w`: the jQuery wrapped HTMLElement, and `wgd`: the grid
813
- * coords object (`col`, `row`, `size_x`, `size_y`).
814
- * @param {Object} [options.collision] An Object with all options for
815
- * Collision class you want to overwrite. See Collision docs for
816
- * more info.
817
- * @param {Object} [options.draggable] An Object with all options for
818
- * Draggable class you want to overwrite. See Draggable docs for more
819
- * info.
820
- *
821
- * @constructor
822
- */
823
- function Gridster(el, options) {
824
- this.options = $.extend(true, defaults, options);
825
- this.$el = $(el);
826
- this.$wrapper = this.$el.parent();
827
- this.$widgets = this.$el.children(this.options.widget_selector).addClass('gs_w');
828
- this.widgets = [];
829
- this.$changed = $([]);
830
- this.w_queue = {};
831
- this.wrapper_width = this.$wrapper.width();
832
- this.min_widget_width = (this.options.widget_margins[0] * 2) +
833
- this.options.widget_base_dimensions[0];
834
- this.min_widget_height = (this.options.widget_margins[1] * 2) +
835
- this.options.widget_base_dimensions[1];
836
- this.init();
837
- }
838
-
839
- Gridster.generated_stylesheets = [];
840
-
841
- var fn = Gridster.prototype;
842
-
843
- fn.init = function() {
844
- this.generate_grid_and_stylesheet();
845
- this.get_widgets_from_DOM();
846
- this.set_dom_grid_height();
847
- this.$wrapper.addClass('ready');
848
- this.draggable();
849
-
850
- $(window).bind(
851
- 'resize', throttle($.proxy(this.recalculate_faux_grid, this), 200));
852
- };
853
-
854
-
855
- /**
856
- * Disables dragging.
857
- *
858
- * @method disable
859
- * @return {Class} Returns the instance of the Gridster Class.
860
- */
861
- fn.disable = function() {
862
- this.$wrapper.find('.player-revert').removeClass('player-revert');
863
- this.drag_api.disable();
864
- return this;
865
- };
866
-
867
-
868
- /**
869
- * Enables dragging.
870
- *
871
- * @method enable
872
- * @return {Class} Returns the instance of the Gridster Class.
873
- */
874
- fn.enable = function() {
875
- this.drag_api.enable();
876
- return this;
877
- };
878
-
879
-
880
- /**
881
- * Add a new widget to the grid.
882
- *
883
- * @method add_widget
884
- * @param {String|HTMLElement} html The string representing the HTML of the widget
885
- * or the HTMLElement.
886
- * @param {Number} [size_x] The nº of rows the widget occupies horizontally.
887
- * @param {Number} [size_y] The nº of columns the widget occupies vertically.
888
- * @param {Number} [col] The column the widget should start in.
889
- * @param {Number} [row] The row the widget should start in.
890
- * @return {HTMLElement} Returns the jQuery wrapped HTMLElement representing.
891
- * the widget that was just created.
892
- */
893
- fn.add_widget = function(html, size_x, size_y, col, row) {
894
- var pos;
895
- size_x || (size_x = 1);
896
- size_y || (size_y = 1);
897
-
898
- if (!col & !row) {
899
- pos = this.next_position(size_x, size_y);
900
- }else{
901
- pos = {
902
- col: col,
903
- row: row
904
- };
905
-
906
- this.empty_cells(col, row, size_x, size_y);
907
- }
908
-
909
- var $w = $(html).attr({
910
- 'data-col': pos.col,
911
- 'data-row': pos.row,
912
- 'data-sizex' : size_x,
913
- 'data-sizey' : size_y
914
- }).addClass('gs_w').appendTo(this.$el).hide();
915
-
916
- this.$widgets = this.$widgets.add($w);
917
- this.$changed = this.$changed.add($w);
918
-
919
- this.register_widget($w);
920
-
921
- this.add_faux_rows(pos.size_y);
922
- //this.add_faux_cols(pos.size_x);
923
-
924
- this.set_dom_grid_height();
925
-
926
- return $w.fadeIn();
927
- };
928
-
929
-
930
-
931
- /**
932
- * Change the size of a widget.
933
- *
934
- * @method resize_widget
935
- * @param {HTMLElement} $widget The jQuery wrapped HTMLElement
936
- * representing the widget.
937
- * @param {Number} size_x The number of columns that will occupy the widget.
938
- * @param {Number} size_y The number of rows that will occupy the widget.
939
- * @return {HTMLElement} Returns $widget.
940
- */
941
- fn.resize_widget = function($widget, size_x, size_y) {
942
- var wgd = $widget.coords().grid;
943
- size_x || (size_x = wgd.size_x);
944
- size_y || (size_y = wgd.size_y);
945
-
946
- if (size_x > this.cols) {
947
- size_x = this.cols;
948
- }
949
-
950
- var old_cells_occupied = this.get_cells_occupied(wgd);
951
- var old_size_x = wgd.size_x;
952
- var old_size_y = wgd.size_y;
953
- var old_col = wgd.col;
954
- var new_col = old_col;
955
- var wider = size_x > old_size_x;
956
- var taller = size_y > old_size_y;
957
-
958
- if (old_col + size_x - 1 > this.cols) {
959
- var diff = old_col + (size_x - 1) - this.cols;
960
- var c = old_col - diff;
961
- new_col = Math.max(1, c);
962
- }
963
-
964
- var new_grid_data = {
965
- col: new_col,
966
- row: wgd.row,
967
- size_x: size_x,
968
- size_y: size_y
969
- };
970
-
971
- var new_cells_occupied = this.get_cells_occupied(new_grid_data);
972
-
973
- var empty_cols = [];
974
- $.each(old_cells_occupied.cols, function(i, col) {
975
- if ($.inArray(col, new_cells_occupied.cols) === -1) {
976
- empty_cols.push(col);
977
- }
978
- });
979
-
980
- var occupied_cols = [];
981
- $.each(new_cells_occupied.cols, function(i, col) {
982
- if ($.inArray(col, old_cells_occupied.cols) === -1) {
983
- occupied_cols.push(col);
984
- }
985
- });
986
-
987
- var empty_rows = [];
988
- $.each(old_cells_occupied.rows, function(i, row) {
989
- if ($.inArray(row, new_cells_occupied.rows) === -1) {
990
- empty_rows.push(row);
991
- }
992
- });
993
-
994
- var occupied_rows = [];
995
- $.each(new_cells_occupied.rows, function(i, row) {
996
- if ($.inArray(row, old_cells_occupied.rows) === -1) {
997
- occupied_rows.push(row);
998
- }
999
- });
1000
-
1001
- this.remove_from_gridmap(wgd);
1002
-
1003
- if (occupied_cols.length) {
1004
- var cols_to_empty = [
1005
- new_col, wgd.row, size_x, Math.min(old_size_y, size_y), $widget
1006
- ];
1007
- this.empty_cells.apply(this, cols_to_empty);
1008
- }
1009
-
1010
- if (occupied_rows.length) {
1011
- var rows_to_empty = [new_col, wgd.row, size_x, size_y, $widget];
1012
- this.empty_cells.apply(this, rows_to_empty);
1013
- }
1014
-
1015
- wgd.col = new_col;
1016
- wgd.size_x = size_x;
1017
- wgd.size_y = size_y;
1018
- this.add_to_gridmap(new_grid_data, $widget);
1019
-
1020
- //update coords instance attributes
1021
- $widget.data('coords').update({
1022
- width: (size_x * this.options.widget_base_dimensions[0] +
1023
- ((size_x - 1) * this.options.widget_margins[0]) * 2),
1024
- height: (size_y * this.options.widget_base_dimensions[1] +
1025
- ((size_y - 1) * this.options.widget_margins[1]) * 2)
1026
- });
1027
-
1028
- if (size_y > old_size_y) {
1029
- this.add_faux_rows(size_y - old_size_y);
1030
- }
1031
-
1032
- if (size_x > old_size_x) {
1033
- this.add_faux_cols(size_x - old_size_x);
1034
- }
1035
-
1036
- $widget.attr({
1037
- 'data-col': new_col,
1038
- 'data-sizex': size_x,
1039
- 'data-sizey': size_y
1040
- });
1041
-
1042
- if (empty_cols.length) {
1043
- var cols_to_remove_holes = [
1044
- empty_cols[0], wgd.row,
1045
- empty_cols.length,
1046
- Math.min(old_size_y, size_y),
1047
- $widget
1048
- ];
1049
-
1050
- this.remove_empty_cells.apply(this, cols_to_remove_holes);
1051
- }
1052
-
1053
- if (empty_rows.length) {
1054
- var rows_to_remove_holes = [
1055
- new_col, wgd.row, size_x, size_y, $widget
1056
- ];
1057
- this.remove_empty_cells.apply(this, rows_to_remove_holes);
1058
- }
1059
-
1060
- return $widget;
1061
- };
1062
-
1063
- /**
1064
- * Move down widgets in cells represented by the arguments col, row, size_x,
1065
- * size_y
1066
- *
1067
- * @method empty_cells
1068
- * @param {Number} col The column where the group of cells begin.
1069
- * @param {Number} row The row where the group of cells begin.
1070
- * @param {Number} size_x The number of columns that the group of cells
1071
- * occupy.
1072
- * @param {Number} size_y The number of rows that the group of cells
1073
- * occupy.
1074
- * @param {HTMLElement} $exclude Exclude widgets from being moved.
1075
- * @return {Class} Returns the instance of the Gridster Class.
1076
- */
1077
- fn.empty_cells = function(col, row, size_x, size_y, $exclude) {
1078
- var $nexts = this.widgets_below({
1079
- col: col,
1080
- row: row - size_y,
1081
- size_x: size_x,
1082
- size_y: size_y
1083
- });
1084
-
1085
- $nexts.not($exclude).each($.proxy(function(i, w) {
1086
- var wgd = $(w).coords().grid;
1087
- if (!(wgd.row <= (row + size_y - 1))) { return; }
1088
- var diff = (row + size_y) - wgd.row;
1089
- this.move_widget_down($(w), diff);
1090
- }, this));
1091
-
1092
- this.set_dom_grid_height();
1093
-
1094
- return this;
1095
- };
1096
-
1097
-
1098
- /**
1099
- * Move up widgets below cells represented by the arguments col, row, size_x,
1100
- * size_y.
1101
- *
1102
- * @method remove_empty_cells
1103
- * @param {Number} col The column where the group of cells begin.
1104
- * @param {Number} row The row where the group of cells begin.
1105
- * @param {Number} size_x The number of columns that the group of cells
1106
- * occupy.
1107
- * @param {Number} size_y The number of rows that the group of cells
1108
- * occupy.
1109
- * @param {HTMLElement} $exclude Exclude widgets from being moved.
1110
- * @return {Class} Returns the instance of the Gridster Class.
1111
- */
1112
- fn.remove_empty_cells = function(col, row, size_x, size_y, exclude) {
1113
- var $nexts = this.widgets_below({
1114
- col: col,
1115
- row: row,
1116
- size_x: size_x,
1117
- size_y: size_y
1118
- });
1119
-
1120
- /*
1121
- $nexts.not(exclude).each($.proxy(function(i, widget) {
1122
- console.log("from_remove")
1123
- this.move_widget_up( $(widget), size_y );
1124
- }, this));
1125
- */
1126
-
1127
- this.set_dom_grid_height();
1128
-
1129
- return this;
1130
- };
1131
-
1132
-
1133
- /**
1134
- * Get the most left column below to add a new widget.
1135
- *
1136
- * @method next_position
1137
- * @param {Number} size_x The nº of rows the widget occupies horizontally.
1138
- * @param {Number} size_y The nº of columns the widget occupies vertically.
1139
- * @return {Object} Returns a grid coords object representing the future
1140
- * widget coords.
1141
- */
1142
- fn.next_position = function(size_x, size_y) {
1143
- size_x || (size_x = 1);
1144
- size_y || (size_y = 1);
1145
- var ga = this.gridmap;
1146
- var cols_l = ga.length;
1147
- var valid_pos = [];
1148
- var rows_l;
1149
-
1150
- for (var c = 1; c < cols_l; c++) {
1151
- rows_l = ga[c].length;
1152
- for (var r = 1; r <= rows_l; r++) {
1153
- var can_move_to = this.can_move_to({
1154
- size_x: size_x,
1155
- size_y: size_y
1156
- }, c, r);
1157
-
1158
- if (can_move_to) {
1159
- valid_pos.push({
1160
- col: c,
1161
- row: r,
1162
- size_y: size_y,
1163
- size_x: size_x
1164
- });
1165
- }
1166
- }
1167
- }
1168
-
1169
- if (valid_pos.length) {
1170
- return this.sort_by_row_and_col_asc(valid_pos)[0];
1171
- }
1172
- return false;
1173
- };
1174
-
1175
- fn.remove_by_grid = function(col, row){
1176
- var $w = this.is_widget(col, row);
1177
- if($w){
1178
- this.remove_widget($w);
1179
- }
1180
- }
1181
-
1182
-
1183
- /**
1184
- * Remove a widget from the grid.
1185
- *
1186
- * @method remove_widget
1187
- * @param {HTMLElement} el The jQuery wrapped HTMLElement you want to remove.
1188
- * @param {Boolean|Function} silent If true, widgets below the removed one
1189
- * will not move up. If a Function is passed it will be used as callback.
1190
- * @param {Function} callback Function executed when the widget is removed.
1191
- * @return {Class} Returns the instance of the Gridster Class.
1192
- */
1193
- fn.remove_widget = function(el, silent, callback) {
1194
- var $el = el instanceof jQuery ? el : $(el);
1195
- var wgd = $el.coords().grid;
1196
-
1197
- // if silent is a function assume it's a callback
1198
- if ($.isFunction(silent)) {
1199
- callback = silent;
1200
- silent = false;
1201
- }
1202
-
1203
- this.cells_occupied_by_placeholder = {};
1204
- this.$widgets = this.$widgets.not($el);
1205
-
1206
- var $nexts = this.widgets_below($el);
1207
-
1208
- this.remove_from_gridmap(wgd);
1209
-
1210
- $el.fadeOut($.proxy(function() {
1211
- $el.remove();
1212
-
1213
- if (!silent) {
1214
- $nexts.each($.proxy(function(i, widget) {
1215
- this.move_widget_up( $(widget), wgd.size_y );
1216
- }, this));
1217
- }
1218
-
1219
- this.set_dom_grid_height();
1220
-
1221
- if (callback) {
1222
- callback.call(this, el);
1223
- }
1224
- }, this));
1225
- };
1226
-
1227
-
1228
- /**
1229
- * Remove all widgets from the grid.
1230
- *
1231
- * @method remove_all_widgets
1232
- * @param {Function} callback Function executed for each widget removed.
1233
- * @return {Class} Returns the instance of the Gridster Class.
1234
- */
1235
- fn.remove_all_widgets = function(callback) {
1236
- this.$widgets.each($.proxy(function(i, el){
1237
- this.remove_widget(el, true, callback);
1238
- }, this));
1239
-
1240
- return this;
1241
- };
1242
-
1243
-
1244
- /**
1245
- * Returns a serialized array of the widgets in the grid.
1246
- *
1247
- * @method serialize
1248
- * @param {HTMLElement} [$widgets] The collection of jQuery wrapped
1249
- * HTMLElements you want to serialize. If no argument is passed all widgets
1250
- * will be serialized.
1251
- * @return {Array} Returns an Array of Objects with the data specified in
1252
- * the serialize_params option.
1253
- */
1254
- fn.serialize = function($widgets) {
1255
- $widgets || ($widgets = this.$widgets);
1256
- var result = [];
1257
- $widgets.each($.proxy(function(i, widget) {
1258
- if(typeof($(widget).coords().grid) != "undefined"){
1259
- result.push(this.options.serialize_params(
1260
- $(widget), $(widget).coords().grid ) );
1261
- }
1262
- }, this));
1263
-
1264
- return result;
1265
- };
1266
-
1267
- /**
1268
- * Returns a serialized array of the widgets that have changed their
1269
- * position.
1270
- *
1271
- * @method serialize_changed
1272
- * @return {Array} Returns an Array of Objects with the data specified in
1273
- * the serialize_params option.
1274
- */
1275
- fn.serialize_changed = function() {
1276
- return this.serialize(this.$changed);
1277
- };
1278
-
1279
-
1280
- /**
1281
- * Creates the grid coords object representing the widget a add it to the
1282
- * mapped array of positions.
1283
- *
1284
- * @method register_widget
1285
- * @return {Array} Returns the instance of the Gridster class.
1286
- */
1287
- fn.register_widget = function($el) {
1288
-
1289
- var wgd = {
1290
- 'col': parseInt($el.attr('data-col'), 10),
1291
- 'row': parseInt($el.attr('data-row'), 10),
1292
- 'size_x': parseInt($el.attr('data-sizex'), 10),
1293
- 'size_y': parseInt($el.attr('data-sizey'), 10),
1294
- 'el': $el
1295
- };
1296
-
1297
- if (this.options.avoid_overlapped_widgets &&
1298
- !this.can_move_to(
1299
- {size_x: wgd.size_x, size_y: wgd.size_y}, wgd.col, wgd.row)
1300
- ) {
1301
- /*if(!$el.hasClass('.disp_ad')){
1302
- $el.remove();
1303
- return false;
1304
- }*/
1305
- wgd = this.next_position(wgd.size_x, wgd.size_y);
1306
- wgd.el = $el;
1307
- $el.attr({
1308
- 'data-col': wgd.col,
1309
- 'data-row': wgd.row,
1310
- 'data-sizex': wgd.size_x,
1311
- 'data-sizey': wgd.size_y
1312
- });
1313
- }
1314
-
1315
- // attach Coord object to player data-coord attribute
1316
- $el.data('coords', $el.coords());
1317
-
1318
- // Extend Coord object with grid position info
1319
- $el.data('coords').grid = wgd;
1320
-
1321
- this.add_to_gridmap(wgd, $el);
1322
-
1323
- return this;
1324
- };
1325
-
1326
-
1327
- /**
1328
- * Update in the mapped array of positions the value of cells represented by
1329
- * the grid coords object passed in the `grid_data` param.
1330
- *
1331
- * @param {Object} grid_data The grid coords object representing the cells
1332
- * to update in the mapped array.
1333
- * @param {HTMLElement|Boolean} value Pass `false` or the jQuery wrapped
1334
- * HTMLElement, depends if you want to delete an existing position or add
1335
- * a new one.
1336
- * @method update_widget_position
1337
- * @return {Class} Returns the instance of the Gridster Class.
1338
- */
1339
- fn.update_widget_position = function(grid_data, value) {
1340
- this.for_each_cell_occupied(grid_data, function(col, row) {
1341
- if (!this.gridmap[col]) { return this; }
1342
- this.gridmap[col][row] = value;
1343
- });
1344
- return this;
1345
- };
1346
-
1347
-
1348
- /**
1349
- * Remove a widget from the mapped array of positions.
1350
- *
1351
- * @method remove_from_gridmap
1352
- * @param {Object} grid_data The grid coords object representing the cells
1353
- * to update in the mapped array.
1354
- * @return {Class} Returns the instance of the Gridster Class.
1355
- */
1356
- fn.remove_from_gridmap = function(grid_data) {
1357
- return this.update_widget_position(grid_data, false);
1358
- };
1359
-
1360
-
1361
- /**
1362
- * Add a widget to the mapped array of positions.
1363
- *
1364
- * @method add_to_gridmap
1365
- * @param {Object} grid_data The grid coords object representing the cells
1366
- * to update in the mapped array.
1367
- * @param {HTMLElement|Boolean} value The value to set in the specified
1368
- * position .
1369
- * @return {Class} Returns the instance of the Gridster Class.
1370
- */
1371
- fn.add_to_gridmap = function(grid_data, value) {
1372
- this.update_widget_position(grid_data, value || grid_data.el);
1373
- /*if (grid_data.el) {
1374
- var $widgets = this.widgets_below(grid_data.el);
1375
- $widgets.each($.proxy(function(i, widget) {
1376
- console.log("from_add_to_gridmap");
1377
- this.move_widget_up( $(widget));
1378
- }, this));
1379
- } */
1380
- };
1381
-
1382
-
1383
- /**
1384
- * Make widgets draggable.
1385
- *
1386
- * @uses Draggable
1387
- * @method draggable
1388
- * @return {Class} Returns the instance of the Gridster Class.
1389
- */
1390
- fn.draggable = function() {
1391
- var self = this;
1392
- var draggable_options = $.extend(true, {}, this.options.draggable, {
1393
- offset_left: this.options.widget_margins[0],
1394
- start: function(event, ui) {
1395
- self.$widgets.filter('.player-revert')
1396
- .removeClass('player-revert');
1397
-
1398
- self.$player = $(this);
1399
- self.$helper = self.options.draggable.helper === 'clone' ?
1400
- $(ui.helper) : self.$player;
1401
- self.helper = !self.$helper.is(self.$player);
1402
-
1403
- self.on_start_drag.call(self, event, ui);
1404
- self.$el.trigger('gridster:dragstart');
1405
- },
1406
- stop: function(event, ui) {
1407
- self.on_stop_drag.call(self, event, ui);
1408
- self.$el.trigger('gridster:dragstop');
1409
- },
1410
- drag: throttle(function(event, ui) {
1411
- self.on_drag.call(self, event, ui);
1412
- self.$el.trigger('gridster:drag');
1413
- }, 60)
1414
- });
1415
-
1416
- this.drag_api = this.$el.dragg(draggable_options).data('drag');
1417
- return this;
1418
- };
1419
-
1420
-
1421
- /**
1422
- * This function is executed when the player begins to be dragged.
1423
- *
1424
- * @method on_start_drag
1425
- * @param {Event} The original browser event
1426
- * @param {Object} A prepared ui object.
1427
- */
1428
- fn.on_start_drag = function(event, ui) {
1429
-
1430
- this.$helper.add(this.$player).add(this.$wrapper).addClass('dragging');
1431
-
1432
- this.$player.addClass('player');
1433
- this.player_grid_data = this.$player.coords().grid;
1434
- this.placeholder_grid_data = $.extend({}, this.player_grid_data);
1435
-
1436
- //set new grid height along the dragging period
1437
- this.$el.css('height', this.$el.height() +
1438
- (this.player_grid_data.size_y * this.min_widget_height));
1439
-
1440
- var colliders = this.faux_grid;
1441
- var coords = this.$player.data('coords').coords;
1442
-
1443
- this.cells_occupied_by_player = this.get_cells_occupied(
1444
- this.player_grid_data);
1445
- this.cells_occupied_by_placeholder = this.get_cells_occupied(
1446
- this.placeholder_grid_data);
1447
-
1448
- this.last_cols = [];
1449
- this.last_rows = [];
1450
-
1451
-
1452
- // see jquery.collision.js
1453
- this.collision_api = this.$helper.collision(
1454
- colliders, this.options.collision);
1455
-
1456
- this.$preview_holder = $('<li />', {
1457
- 'class': 'preview-holder',
1458
- 'data-row': this.$player.attr('data-row'),
1459
- 'data-col': this.$player.attr('data-col'),
1460
- css: {
1461
- width: coords.width,
1462
- height: coords.height
1463
- }
1464
- }).appendTo(this.$el);
1465
-
1466
- if (this.options.draggable.start) {
1467
- this.options.draggable.start.call(this, event, ui);
1468
- }
1469
- };
1470
-
1471
-
1472
- /**
1473
- * This function is executed when the player is being dragged.
1474
- *
1475
- * @method on_drag
1476
- * @param {Event} The original browser event
1477
- * @param {Object} A prepared ui object.
1478
- */
1479
- fn.on_drag = function(event, ui) {
1480
- //break if dragstop has been fired
1481
- if (this.$player === null) {
1482
- return false;
1483
- }
1484
-
1485
- var abs_offset = {
1486
- left: ui.position.left + this.baseX,
1487
- top: ui.position.top + this.baseY
1488
- };
1489
-
1490
- this.colliders_data = this.collision_api.get_closest_colliders(
1491
- abs_offset);
1492
-
1493
- this.on_overlapped_column_change(
1494
- this.on_start_overlapping_column,
1495
- this.on_stop_overlapping_column
1496
- );
1497
-
1498
- this.on_overlapped_row_change(
1499
- this.on_start_overlapping_row,
1500
- this.on_stop_overlapping_row
1501
- );
1502
-
1503
- if (this.helper && this.$player) {
1504
- this.$player.css({
1505
- 'left': ui.position.left,
1506
- 'top': ui.position.top
1507
- });
1508
- }
1509
-
1510
- if (this.options.draggable.drag) {
1511
- this.options.draggable.drag.call(this, event, ui);
1512
- }
1513
- };
1514
-
1515
- /**
1516
- * This function is executed when the player stops being dragged.
1517
- *
1518
- * @method on_stop_drag
1519
- * @param {Event} The original browser event
1520
- * @param {Object} A prepared ui object.
1521
- */
1522
- fn.on_stop_drag = function(event, ui) {
1523
- this.$helper.add(this.$player).add(this.$wrapper)
1524
- .removeClass('dragging');
1525
-
1526
- ui.position.left = ui.position.left + this.baseX;
1527
- ui.position.top = ui.position.top + this.baseY;
1528
- this.colliders_data = this.collision_api.get_closest_colliders(ui.position);
1529
-
1530
- this.on_overlapped_column_change(
1531
- this.on_start_overlapping_column,
1532
- this.on_stop_overlapping_column
1533
- );
1534
-
1535
- this.on_overlapped_row_change(
1536
- this.on_start_overlapping_row,
1537
- this.on_stop_overlapping_row
1538
- );
1539
-
1540
- this.$player.addClass('player-revert').removeClass('player')
1541
- .attr({
1542
- 'data-col': this.placeholder_grid_data.col,
1543
- 'data-row': this.placeholder_grid_data.row
1544
- }).css({
1545
- 'left': '',
1546
- 'top': ''
1547
- });
1548
-
1549
- this.$changed = this.$changed.add(this.$player);
1550
-
1551
- this.cells_occupied_by_player = this.get_cells_occupied(
1552
- this.placeholder_grid_data);
1553
- this.set_cells_player_occupies(
1554
- this.placeholder_grid_data.col, this.placeholder_grid_data.row);
1555
-
1556
- this.$player.coords().grid.row = this.placeholder_grid_data.row;
1557
- this.$player.coords().grid.col = this.placeholder_grid_data.col;
1558
-
1559
- if (this.options.draggable.stop) {
1560
- this.options.draggable.stop.call(this, event, ui);
1561
- }
1562
-
1563
- this.$preview_holder.remove();
1564
-
1565
- this.$player = null;
1566
- this.$helper = null;
1567
- this.placeholder_grid_data = {};
1568
- this.player_grid_data = {};
1569
- this.cells_occupied_by_placeholder = {};
1570
- this.cells_occupied_by_player = {};
1571
- this.w_queue = {};
1572
-
1573
- this.set_dom_grid_height();
1574
- };
1575
-
1576
-
1577
- /**
1578
- * Executes the callbacks passed as arguments when a column begins to be
1579
- * overlapped or stops being overlapped.
1580
- *
1581
- * @param {Function} start_callback Function executed when a new column
1582
- * begins to be overlapped. The column is passed as first argument.
1583
- * @param {Function} stop_callback Function executed when a column stops
1584
- * being overlapped. The column is passed as first argument.
1585
- * @method on_overlapped_column_change
1586
- * @return {Class} Returns the instance of the Gridster Class.
1587
- */
1588
- fn.on_overlapped_column_change = function(start_callback, stop_callback) {
1589
- if (!this.colliders_data.length) {
1590
- return;
1591
- }
1592
- var cols = this.get_targeted_columns(
1593
- this.colliders_data[0].el.data.col);
1594
-
1595
- var last_n_cols = this.last_cols.length;
1596
- var n_cols = cols.length;
1597
- var i;
1598
-
1599
- for (i = 0; i < n_cols; i++) {
1600
- if ($.inArray(cols[i], this.last_cols) === -1) {
1601
- (start_callback || $.noop).call(this, cols[i]);
1602
- }
1603
- }
1604
-
1605
- for (i = 0; i< last_n_cols; i++) {
1606
- if ($.inArray(this.last_cols[i], cols) === -1) {
1607
- (stop_callback || $.noop).call(this, this.last_cols[i]);
1608
- }
1609
- }
1610
-
1611
- this.last_cols = cols;
1612
-
1613
- return this;
1614
- };
1615
-
1616
-
1617
- /**
1618
- * Executes the callbacks passed as arguments when a row starts to be
1619
- * overlapped or stops being overlapped.
1620
- *
1621
- * @param {Function} start_callback Function executed when a new row begins
1622
- * to be overlapped. The row is passed as first argument.
1623
- * @param {Function} stop_callback Function executed when a row stops being
1624
- * overlapped. The row is passed as first argument.
1625
- * @method on_overlapped_row_change
1626
- * @return {Class} Returns the instance of the Gridster Class.
1627
- */
1628
- fn.on_overlapped_row_change = function(start_callback, end_callback) {
1629
- if (!this.colliders_data.length) {
1630
- return;
1631
- }
1632
- var rows = this.get_targeted_rows(this.colliders_data[0].el.data.row);
1633
- var last_n_rows = this.last_rows.length;
1634
- var n_rows = rows.length;
1635
- var i;
1636
-
1637
- for (i = 0; i < n_rows; i++) {
1638
- if ($.inArray(rows[i], this.last_rows) === -1) {
1639
- (start_callback || $.noop).call(this, rows[i]);
1640
- }
1641
- }
1642
-
1643
- for (i = 0; i < last_n_rows; i++) {
1644
- if ($.inArray(this.last_rows[i], rows) === -1) {
1645
- (end_callback || $.noop).call(this, this.last_rows[i]);
1646
- }
1647
- }
1648
-
1649
- this.last_rows = rows;
1650
- };
1651
-
1652
-
1653
- /**
1654
- * Sets the current position of the player
1655
- *
1656
- * @param {Function} start_callback Function executed when a new row begins
1657
- * to be overlapped. The row is passed as first argument.
1658
- * @param {Function} stop_callback Function executed when a row stops being
1659
- * overlapped. The row is passed as first argument.
1660
- * @method set_player
1661
- * @return {Class} Returns the instance of the Gridster Class.
1662
- */
1663
- fn.set_player = function(col, row, no_player) {
1664
- var self = this;
1665
- var swap = false;
1666
- if (!no_player) {
1667
- this.empty_cells_player_occupies();
1668
- }
1669
- var cell = !no_player ? self.colliders_data[0].el.data : {col: col};
1670
- var to_col = cell.col;
1671
- var to_row = cell.row || row;
1672
-
1673
- this.player_grid_data = {
1674
- col: to_col,
1675
- row: to_row,
1676
- size_y : this.player_grid_data.size_y,
1677
- size_x : this.player_grid_data.size_x
1678
- };
1679
-
1680
- this.cells_occupied_by_player = this.get_cells_occupied(
1681
- this.player_grid_data);
1682
-
1683
- //Added placeholder for more advanced movement.
1684
- this.cells_occupied_by_placeholder = this.get_cells_occupied(
1685
- this.placeholder_grid_data);
1686
-
1687
- var $overlapped_widgets = this.get_widgets_overlapped(
1688
- this.player_grid_data);
1689
-
1690
- var player_size_y = this.player_grid_data.size_y;
1691
- var player_size_x = this.player_grid_data.size_x;
1692
- var placeholder_cells = this.cells_occupied_by_placeholder;
1693
- var $gr = this;
1694
-
1695
-
1696
- //Queue Swaps
1697
- $overlapped_widgets.each($.proxy(function(i, w){
1698
- var $w = $(w);
1699
- var wgd = $w.coords().grid;
1700
-
1701
- // Ensure all values are in integer format
1702
- wgd.col = parseInt(wgd.col);
1703
- wgd.row = parseInt(wgd.row);
1704
- wgd.size_x = parseInt(wgd.size_x);
1705
- wgd.size_y = parseInt(wgd.size_y);
1706
- player_size_x = parseInt(player_size_x);
1707
- player_size_y = parseInt(player_size_y);
1708
-
1709
- var outside_col = placeholder_cells.cols[0]+player_size_x-1;
1710
- var outside_row = placeholder_cells.rows[0]+player_size_y-1;
1711
- if ($w.hasClass($gr.options.static_class)){
1712
- //next iteration
1713
- return true;
1714
- }
1715
- if(wgd.size_x <= player_size_x && wgd.size_y <= player_size_y){
1716
- if(!$gr.is_swap_occupied(placeholder_cells.cols[0], wgd.row, wgd.size_x, wgd.size_y) && !$gr.is_player_in(placeholder_cells.cols[0], wgd.row) && !$gr.is_in_queue(placeholder_cells.cols[0], wgd.row, $w)){
1717
- swap = $gr.queue_widget(placeholder_cells.cols[0], wgd.row, $w);
1718
- }
1719
- else if(!$gr.is_swap_occupied(outside_col, wgd.row, wgd.size_x, wgd.size_y) && !$gr.is_player_in(outside_col, wgd.row) && !$gr.is_in_queue(outside_col, wgd.row, $w)){
1720
- swap = $gr.queue_widget(outside_col, wgd.row, $w);
1721
- }
1722
- else if(!$gr.is_swap_occupied(wgd.col, placeholder_cells.rows[0], wgd.size_x, wgd.size_y) && !$gr.is_player_in(wgd.col, placeholder_cells.rows[0]) && !$gr.is_in_queue(wgd.col, placeholder_cells.rows[0], $w)){
1723
- swap = $gr.queue_widget(wgd.col, placeholder_cells.rows[0], $w);
1724
- }
1725
- else if(!$gr.is_swap_occupied(wgd.col, outside_row, wgd.size_x, wgd.size_y) && !$gr.is_player_in(wgd.col, outside_row) && !$gr.is_in_queue(wgd.col, outside_row, $w)){
1726
- swap = $gr.queue_widget(wgd.col, outside_row, $w);
1727
- }
1728
- else if(!$gr.is_swap_occupied(placeholder_cells.cols[0],placeholder_cells.rows[0], wgd.size_x, wgd.size_y) && !$gr.is_player_in(placeholder_cells.cols[0],placeholder_cells.rows[0]) && !$gr.is_in_queue(placeholder_cells.cols[0],placeholder_cells.rows[0], $w)){
1729
- swap = $gr.queue_widget(placeholder_cells.cols[0], placeholder_cells.rows[0], $w);
1730
- } else {
1731
- //in one last attempt we check for any other empty spaces
1732
- for (var c = 0; c < player_size_x; c++){
1733
- for (var r = 0; r < player_size_y; r++){
1734
- var colc = placeholder_cells.cols[0]+c;
1735
- var rowc = placeholder_cells.rows[0]+r;
1736
- if (!$gr.is_swap_occupied(colc,rowc, wgd.size_x, wgd.size_y) && !$gr.is_player_in(colc,rowc) && !$gr.is_in_queue(colc, rowc, $w)){
1737
- swap = $gr.queue_widget(colc, rowc, $w);
1738
- c = player_size_x;
1739
- break;
1740
- }
1741
- }
1742
- }
1743
-
1744
- }
1745
- } else if ($gr.options.shift_larger_widgets_down && !swap) {
1746
- $overlapped_widgets.each($.proxy(function(i, w){
1747
- var $w = $(w);
1748
- var wgd = $w.coords().grid;
1749
-
1750
- if($gr.can_go_down($w)){
1751
- $gr.move_widget_down($w, $gr.player_grid_data.size_y);
1752
- $gr.set_placeholder(to_col, to_row);
1753
- }
1754
- }));
1755
- }
1756
-
1757
- $gr.clean_up_changed();
1758
- }));
1759
-
1760
-
1761
- /* To show queued items in console
1762
- for(var key in this.w_queue){
1763
- console.log("key " +key);
1764
- console.log(this.w_queue[key]);
1765
- }
1766
- */
1767
-
1768
- //Move queued widgets
1769
- if(swap && this.can_placeholder_be_set(to_col, to_row, player_size_x, player_size_y)){
1770
- for(var key in this.w_queue){
1771
- var col = parseInt(key.split("_")[0]);
1772
- var row = parseInt(key.split("_")[1]);
1773
- if (this.w_queue[key] != "full"){
1774
- this.new_move_widget_to(this.w_queue[key], col, row);
1775
- }
1776
- }
1777
- this.set_placeholder(to_col, to_row);
1778
- }
1779
-
1780
- /* if there is not widgets overlapping in the new player position,
1781
- * update the new placeholder position. */
1782
- if (!$overlapped_widgets.length) {
1783
- var pp = this.can_go_player_up(this.player_grid_data);
1784
- if (pp !== false) {
1785
- to_row = pp;
1786
- }
1787
- if(this.can_placeholder_be_set(to_col, to_row, player_size_x, player_size_y)){
1788
- this.set_placeholder(to_col, to_row);
1789
- }
1790
- }
1791
-
1792
- this.w_queue = {};
1793
-
1794
- return {
1795
- col: to_col,
1796
- row: to_row
1797
- };
1798
- };
1799
-
1800
-
1801
- fn.is_swap_occupied = function(col, row, w_size_x, w_size_y) {
1802
- var occupied = false;
1803
- for (var c = 0; c < w_size_x; c++){
1804
- for (var r = 0; r < w_size_y; r++){
1805
- var colc = col + c;
1806
- var rowc = row + r;
1807
- var key = colc+"_"+rowc;
1808
- if(this.is_occupied(colc,rowc)){
1809
- occupied = true;
1810
- } else if(key in this.w_queue){
1811
- if(this.w_queue[key] == "full"){
1812
- occupied = true;
1813
- continue;
1814
- }
1815
- $tw = this.w_queue[key];
1816
- tgd = $tw.coords().grid;
1817
- //remove queued items if no longer under player.
1818
- if(!this.is_widget_under_player(tgd.col,tgd.row)){
1819
- delete this.w_queue[key];
1820
- }
1821
- }
1822
- if(rowc > parseInt(this.options.max_rows)){
1823
- occupied = true;
1824
- }
1825
- if(colc > parseInt(this.options.max_cols)){
1826
- occupied = true;
1827
- }
1828
- if (this.is_player_in(colc,rowc)){
1829
- occupied = true;
1830
- }
1831
- }
1832
- }
1833
-
1834
- return occupied;
1835
- }
1836
-
1837
- fn.can_placeholder_be_set = function(col, row, player_size_x, player_size_y){
1838
- var can_set = true;
1839
- for (var c = 0; c < player_size_x; c++){
1840
- for (var r = 0; r < player_size_y; r++){
1841
- var colc = col + c;
1842
- var rowc = row + r;
1843
- var key = colc+"_"+rowc;
1844
- var $tw = this.is_widget(colc, rowc);
1845
- //if this space is occupied and not queued for move.
1846
- if(rowc > parseInt(this.options.max_rows)){
1847
- can_set = false;
1848
- }
1849
- if(colc > parseInt(this.options.max_cols)){
1850
- can_set = false;
1851
- }
1852
- if(this.is_occupied(colc,rowc) && !this.is_widget_queued_and_can_move($tw)){
1853
- can_set = false;
1854
- }
1855
- }
1856
- }
1857
- return can_set;
1858
- }
1859
-
1860
- fn.queue_widget = function(col, row, $widget){
1861
- var $w = $widget
1862
- var wgd = $w.coords().grid;
1863
- var primary_key = col+"_"+row;
1864
- if (primary_key in this.w_queue){
1865
- return false;
1866
- }
1867
-
1868
- this.w_queue[primary_key] = $w;
1869
-
1870
- for (var c = 0; c < wgd.size_x; c++){
1871
- for (var r = 0; r < wgd.size_y; r++){
1872
- var colc = col + c;
1873
- var rowc = row + r;
1874
- var key = colc+"_"+rowc;
1875
- if (key == primary_key){
1876
- continue;
1877
- }
1878
- this.w_queue[key] = "full";
1879
- }
1880
- }
1881
-
1882
- return true;
1883
- }
1884
-
1885
- fn.is_widget_queued_and_can_move = function($widget){
1886
- var queued = false;
1887
- if ($widget === false){
1888
- return false;
1889
- }
1890
-
1891
- for(var key in this.w_queue){
1892
- if(this.w_queue[key] == "full"){
1893
- continue;
1894
- }
1895
- if(this.w_queue[key].attr("data-col") == $widget.attr("data-col") && this.w_queue[key].attr("data-row") == $widget.attr("data-row")){
1896
- queued = true;
1897
- //test whole space
1898
- var $w = this.w_queue[key];
1899
- var dcol = parseInt(key.split("_")[0]);
1900
- var drow = parseInt(key.split("_")[1]);
1901
- var wgd = $w.coords().grid;
1902
-
1903
- for (var c = 0; c < wgd.size_x; c++){
1904
- for (var r = 0; r < wgd.size_y; r++){
1905
- var colc = dcol + c;
1906
- var rowc = drow + r;
1907
- if (this.is_player_in(colc,rowc)){
1908
- queued = false;
1909
- }
1910
-
1911
- }
1912
- }
1913
-
1914
- }
1915
- }
1916
-
1917
- return queued
1918
- }
1919
-
1920
- fn.is_in_queue = function(col,row, $widget){
1921
- var queued = false;
1922
- var key = col+"_"+row;
1923
-
1924
- if ((key in this.w_queue)){
1925
- if (this.w_queue[key] == "full"){
1926
- queued = true;
1927
- } else {
1928
- $tw = this.w_queue[key];
1929
- tgd = $tw.coords().grid;
1930
- if(!this.is_widget_under_player(tgd.col,tgd.row)){
1931
- delete this.w_queue[key]
1932
- queued = false;
1933
- } else if(this.w_queue[key].attr("data-col") == $widget.attr("data-col") && this.w_queue[key].attr("data-row") == $widget.attr("data-row")) {
1934
- delete this.w_queue[key]
1935
- queued = false;
1936
- } else {
1937
- queued = true;
1938
- }
1939
- }
1940
- }
1941
-
1942
- return queued;
1943
- }
1944
-
1945
-
1946
- /**
1947
- * See which of the widgets in the $widgets param collection can go to
1948
- * a upper row and which not.
1949
- *
1950
- * @method widgets_contraints
1951
- * @param {HTMLElements} $widgets A jQuery wrapped collection of
1952
- * HTMLElements.
1953
- * @return {Array} Returns a literal Object with two keys: `can_go_up` &
1954
- * `can_not_go_up`. Each contains a set of HTMLElements.
1955
- */
1956
- fn.widgets_constraints = function($widgets) {
1957
- var $widgets_can_go_up = $([]);
1958
- var $widgets_can_not_go_up;
1959
- var wgd_can_go_up = [];
1960
- var wgd_can_not_go_up = [];
1961
-
1962
- $widgets.each($.proxy(function(i, w) {
1963
- var $w = $(w);
1964
- var wgd = $w.coords().grid;
1965
- if (this.can_go_widget_up(wgd)) {
1966
- $widgets_can_go_up = $widgets_can_go_up.add($w);
1967
- wgd_can_go_up.push(wgd);
1968
- }else{
1969
- wgd_can_not_go_up.push(wgd);
1970
- }
1971
- }, this));
1972
-
1973
- $widgets_can_not_go_up = $widgets.not($widgets_can_go_up);
1974
-
1975
- return {
1976
- can_go_up: this.sort_by_row_asc(wgd_can_go_up),
1977
- can_not_go_up: this.sort_by_row_desc(wgd_can_not_go_up)
1978
- };
1979
- };
1980
-
1981
-
1982
- /**
1983
- * Sorts an Array of grid coords objects (representing the grid coords of
1984
- * each widget) in ascending way.
1985
- *
1986
- * @method sort_by_row_asc
1987
- * @param {Array} widgets Array of grid coords objects
1988
- * @return {Array} Returns the array sorted.
1989
- */
1990
- fn.sort_by_row_asc = function(widgets) {
1991
- widgets = widgets.sort(function(a, b) {
1992
- if (!a.row) {
1993
- a = $(a).coords().grid;
1994
- b = $(b).coords().grid;
1995
- }
1996
-
1997
- if (a.row > b.row) {
1998
- return 1;
1999
- }
2000
- return -1;
2001
- });
2002
-
2003
- return widgets;
2004
- };
2005
-
2006
-
2007
- /**
2008
- * Sorts an Array of grid coords objects (representing the grid coords of
2009
- * each widget) placing first the empty cells upper left.
2010
- *
2011
- * @method sort_by_row_and_col_asc
2012
- * @param {Array} widgets Array of grid coords objects
2013
- * @return {Array} Returns the array sorted.
2014
- */
2015
- fn.sort_by_row_and_col_asc = function(widgets) {
2016
- widgets = widgets.sort(function(a, b) {
2017
- if (a.row > b.row || a.row === b.row && a.col > b.col) {
2018
- return 1;
2019
- }
2020
- return -1;
2021
- });
2022
-
2023
- return widgets;
2024
- };
2025
-
2026
-
2027
- /**
2028
- * Sorts an Array of grid coords objects by column (representing the grid
2029
- * coords of each widget) in ascending way.
2030
- *
2031
- * @method sort_by_col_asc
2032
- * @param {Array} widgets Array of grid coords objects
2033
- * @return {Array} Returns the array sorted.
2034
- */
2035
- fn.sort_by_col_asc = function(widgets) {
2036
- widgets = widgets.sort(function(a, b) {
2037
- if (a.col > b.col) {
2038
- return 1;
2039
- }
2040
- return -1;
2041
- });
2042
-
2043
- return widgets;
2044
- };
2045
-
2046
-
2047
- /**
2048
- * Sorts an Array of grid coords objects (representing the grid coords of
2049
- * each widget) in descending way.
2050
- *
2051
- * @method sort_by_row_desc
2052
- * @param {Array} widgets Array of grid coords objects
2053
- * @return {Array} Returns the array sorted.
2054
- */
2055
- fn.sort_by_row_desc = function(widgets) {
2056
- widgets = widgets.sort(function(a, b) {
2057
- if (a.row + a.size_y < b.row + b.size_y) {
2058
- return 1;
2059
- }
2060
- return -1;
2061
- });
2062
- return widgets;
2063
- };
2064
-
2065
-
2066
- /**
2067
- * Sorts an Array of grid coords objects (representing the grid coords of
2068
- * each widget) in descending way.
2069
-
2070
- * Depreciated.
2071
- *
2072
- * @method manage_movements
2073
- * @param {HTMLElements} $widgets A jQuery collection of HTMLElements
2074
- * representing the widgets you want to move.
2075
- * @param {Number} to_col The column to which we want to move the widgets.
2076
- * @param {Number} to_row The row to which we want to move the widgets.
2077
- * @return {Class} Returns the instance of the Gridster Class.
2078
- */
2079
- fn.manage_movements = function($widgets, to_col, to_row) {
2080
- $.each($widgets, $.proxy(function(i, w) {
2081
- var wgd = w;
2082
- var $w = wgd.el;
2083
-
2084
- var can_go_widget_up = this.can_go_widget_up(wgd);
2085
-
2086
- if (can_go_widget_up) {
2087
- //target CAN go up
2088
- //so move widget up
2089
- this.move_widget_to($w, can_go_widget_up);
2090
- this.set_placeholder(to_col, can_go_widget_up + wgd.size_y);
2091
-
2092
- } else {
2093
- //target can't go up
2094
- var can_go_player_up = this.can_go_player_up(
2095
- this.player_grid_data);
2096
-
2097
- if (!can_go_player_up) {
2098
- // target can't go up
2099
- // player cant't go up
2100
- // so we need to move widget down to a position that dont
2101
- // overlaps player
2102
- var y = (to_row + this.player_grid_data.size_y) - wgd.row;
2103
- if (this.can_go_down($w)){
2104
- console.log("In Move Down!")
2105
- this.move_widget_down($w, y);
2106
- this.set_placeholder(to_col, to_row);
2107
- }
2108
- }
2109
- }
2110
- }, this));
2111
-
2112
- return this;
2113
- };
2114
-
2115
- /**
2116
- * Determines if there is a widget in the row and col given. Or if the
2117
- * HTMLElement passed as first argument is the player.
2118
- *
2119
- * @method is_player
2120
- * @param {Number|HTMLElement} col_or_el A jQuery wrapped collection of
2121
- * HTMLElements.
2122
- * @param {Number} [row] The column to which we want to move the widgets.
2123
- * @return {Boolean} Returns true or false.
2124
- */
2125
- fn.is_player = function(col_or_el, row) {
2126
- if (row && !this.gridmap[col_or_el]) { return false; }
2127
- var $w = row ? this.gridmap[col_or_el][row] : col_or_el;
2128
- return $w && ($w.is(this.$player) || $w.is(this.$helper));
2129
- };
2130
-
2131
-
2132
- /**
2133
- * Determines if the widget that is being dragged is currently over the row
2134
- * and col given.
2135
- *
2136
- * @method is_player_in
2137
- * @param {Number} col The column to check.
2138
- * @param {Number} row The row to check.
2139
- * @return {Boolean} Returns true or false.
2140
- */
2141
- fn.is_player_in = function(col, row) {
2142
- var c = this.cells_occupied_by_player || {};
2143
- return $.inArray(col, c.cols) >= 0 && $.inArray(row, c.rows) >= 0;
2144
- };
2145
-
2146
-
2147
- /**
2148
- * Determines if the placeholder is currently over the row and col given.
2149
- *
2150
- * @method is_placeholder_in
2151
- * @param {Number} col The column to check.
2152
- * @param {Number} row The row to check.
2153
- * @return {Boolean} Returns true or false.
2154
- */
2155
- fn.is_placeholder_in = function(col, row) {
2156
- var c = this.cells_occupied_by_placeholder || {};
2157
- return this.is_placeholder_in_col(col) && $.inArray(row, c.rows) >= 0;
2158
- };
2159
-
2160
-
2161
- /**
2162
- * Determines if the placeholder is currently over the column given.
2163
- *
2164
- * @method is_placeholder_in_col
2165
- * @param {Number} col The column to check.
2166
- * @return {Boolean} Returns true or false.
2167
- */
2168
- fn.is_placeholder_in_col = function(col) {
2169
- var c = this.cells_occupied_by_placeholder || [];
2170
- return $.inArray(col, c.cols) >= 0;
2171
- };
2172
-
2173
-
2174
- /**
2175
- * Determines if the cell represented by col and row params is empty.
2176
- *
2177
- * @method is_empty
2178
- * @param {Number} col The column to check.
2179
- * @param {Number} row The row to check.
2180
- * @return {Boolean} Returns true or false.
2181
- */
2182
- fn.is_empty = function(col, row) {
2183
- if (typeof this.gridmap[col] !== 'undefined' &&
2184
- typeof this.gridmap[col][row] !== 'undefined' &&
2185
- this.gridmap[col][row] === false
2186
- ) {
2187
- return true;
2188
- }
2189
- return false;
2190
- };
2191
-
2192
-
2193
- /**
2194
- * Determines if the cell represented by col and row params is occupied.
2195
- *
2196
- * @method is_occupied
2197
- * @param {Number} col The column to check.
2198
- * @param {Number} row The row to check.
2199
- * @return {Boolean} Returns true or false.
2200
- */
2201
- fn.is_occupied = function(col, row) {
2202
- if (!this.gridmap[col]) {
2203
- return false;
2204
- }
2205
-
2206
- if (this.gridmap[col][row]) {
2207
- return true;
2208
- }
2209
- return false;
2210
- };
2211
-
2212
-
2213
- /**
2214
- * Determines if there is a widget in the cell represented by col/row params.
2215
- *
2216
- * @method is_widget
2217
- * @param {Number} col The column to check.
2218
- * @param {Number} row The row to check.
2219
- * @return {Boolean|HTMLElement} Returns false if there is no widget,
2220
- * else returns the jQuery HTMLElement
2221
- */
2222
- fn.is_widget = function(col, row) {
2223
- var cell = this.gridmap[col];
2224
- if (!cell) {
2225
- return false;
2226
- }
2227
-
2228
- cell = cell[row];
2229
-
2230
- if (cell) {
2231
- return cell;
2232
- }
2233
-
2234
- return false;
2235
- };
2236
-
2237
- /**
2238
- * Determines if widget is supposed to be static.
2239
- * @method is_static
2240
- * @param {Number} col The column to check.
2241
- * @param {Number} row The row to check.
2242
- * @return {Boolean} Returns true if widget exists and has static class,
2243
- * else returns false
2244
- */
2245
-
2246
- fn.is_static = function(col, row) {
2247
- var cell = this.gridmap[col];
2248
- if (!cell) {
2249
- return false;
2250
- }
2251
-
2252
- cell = cell[row];
2253
-
2254
- if (cell) {
2255
- if(cell.hasClass(this.options.static_class)){
2256
- return true;
2257
- }
2258
- }
2259
-
2260
- return false;
2261
- };
2262
-
2263
-
2264
- /**
2265
- * Determines if there is a widget in the cell represented by col/row
2266
- * params and if this is under the widget that is being dragged.
2267
- *
2268
- * @method is_widget_under_player
2269
- * @param {Number} col The column to check.
2270
- * @param {Number} row The row to check.
2271
- * @return {Boolean} Returns true or false.
2272
- */
2273
- fn.is_widget_under_player = function(col, row) {
2274
- if (this.is_widget(col, row)) {
2275
- return this.is_player_in(col, row);
2276
- }
2277
- return false;
2278
- };
2279
-
2280
-
2281
- /**
2282
- * Get widgets overlapping with the player or with the object passed
2283
- * representing the grid cells.
2284
- *
2285
- * @method get_widgets_under_player
2286
- * @return {HTMLElement} Returns a jQuery collection of HTMLElements
2287
- */
2288
- fn.get_widgets_under_player = function(cells) {
2289
- cells || (cells = this.cells_occupied_by_player || {cols: [], rows: []});
2290
- var $widgets = $([]);
2291
-
2292
- $.each(cells.cols, $.proxy(function(i, col) {
2293
- $.each(cells.rows, $.proxy(function(i, row) {
2294
- if(this.is_widget(col, row)) {
2295
- $widgets = $widgets.add(this.gridmap[col][row]);
2296
- }
2297
- }, this));
2298
- }, this));
2299
-
2300
- return $widgets;
2301
- };
2302
-
2303
-
2304
- /**
2305
- * Put placeholder at the row and column specified.
2306
- *
2307
- * @method set_placeholder
2308
- * @param {Number} col The column to which we want to move the
2309
- * placeholder.
2310
- * @param {Number} row The row to which we want to move the
2311
- * placeholder.
2312
- * @return {Class} Returns the instance of the Gridster Class.
2313
- */
2314
- fn.set_placeholder = function(col, row) {
2315
- var phgd = $.extend({}, this.placeholder_grid_data);
2316
- var $nexts = this.widgets_below({
2317
- col: phgd.col,
2318
- row: phgd.row,
2319
- size_y: phgd.size_y,
2320
- size_x: phgd.size_x
2321
- });
2322
-
2323
- // Prevents widgets go out of the grid
2324
- var right_col = (col + parseInt(phgd.size_x) - 1);
2325
- if (right_col > this.cols) {
2326
- col = col - (right_col - col);
2327
- }
2328
-
2329
- var moved_down = this.placeholder_grid_data.row < row;
2330
- var changed_column = this.placeholder_grid_data.col !== col;
2331
-
2332
- this.placeholder_grid_data.col = col;
2333
- this.placeholder_grid_data.row = row;
2334
-
2335
- this.cells_occupied_by_placeholder = this.get_cells_occupied(
2336
- this.placeholder_grid_data);
2337
-
2338
- this.$preview_holder.attr({
2339
- 'data-row' : row,
2340
- 'data-col' : col
2341
- });
2342
-
2343
- if (moved_down || changed_column) {
2344
- $nexts.each($.proxy(function(i, widget) {
2345
- //Make sure widget is at it's topmost position
2346
- $w = $(widget);
2347
- wgd = $w.coords().grid;
2348
-
2349
- var can_go_widget_up = this.can_go_widget_up(wgd);
2350
-
2351
- if (can_go_widget_up) {
2352
- this.move_widget_to($w, can_go_widget_up);
2353
- }
2354
-
2355
- }, this));
2356
- }
2357
-
2358
-
2359
- var $widgets_under_ph = this.get_widgets_under_player(this.cells_occupied_by_placeholder);
2360
- if ($widgets_under_ph.length) {
2361
- $widgets_under_ph.each($.proxy(function(i, widget) {
2362
- var $w = $(widget);
2363
- this.move_widget_down(
2364
- $w, row + phgd.size_y - $w.data('coords').grid.row);
2365
- }, this));
2366
- }
2367
-
2368
- };
2369
-
2370
-
2371
- /**
2372
- * Determines whether the player can move to a position above.
2373
- *
2374
- * @method can_go_player_up
2375
- * @param {Object} widget_grid_data The actual grid coords object of the
2376
- * player.
2377
- * @return {Number|Boolean} If the player can be moved to an upper row
2378
- * returns the row number, else returns false.
2379
- */
2380
- fn.can_go_player_up = function(widget_grid_data) {
2381
- var p_bottom_row = widget_grid_data.row + widget_grid_data.size_y - 1;
2382
- var result = true;
2383
- var upper_rows = [];
2384
- var min_row = 10000;
2385
- var $widgets_under_player = this.get_widgets_under_player();
2386
-
2387
- /* generate an array with columns as index and array with upper rows
2388
- * empty as value */
2389
- this.for_each_column_occupied(widget_grid_data, function(tcol) {
2390
- var grid_col = this.gridmap[tcol];
2391
- var r = p_bottom_row + 1;
2392
- upper_rows[tcol] = [];
2393
-
2394
- while (--r > 0) {
2395
- if (this.is_empty(tcol, r) || this.is_player(tcol, r) ||
2396
- this.is_widget(tcol, r) &&
2397
- grid_col[r].is($widgets_under_player)
2398
- ) {
2399
- upper_rows[tcol].push(r);
2400
- min_row = r < min_row ? r : min_row;
2401
- }else{
2402
- break;
2403
- }
2404
- }
2405
-
2406
- if (upper_rows[tcol].length === 0) {
2407
- result = false;
2408
- return true; //break
2409
- }
2410
-
2411
- upper_rows[tcol].sort();
2412
- });
2413
-
2414
- if (!result) { return false; }
2415
-
2416
- return this.get_valid_rows(widget_grid_data, upper_rows, min_row);
2417
- };
2418
-
2419
-
2420
- /**
2421
- * Determines whether a widget can move to a position above.
2422
- *
2423
- * @method can_go_widget_up
2424
- * @param {Object} widget_grid_data The actual grid coords object of the
2425
- * widget we want to check.
2426
- * @return {Number|Boolean} If the widget can be moved to an upper row
2427
- * returns the row number, else returns false.
2428
- */
2429
- fn.can_go_widget_up = function(widget_grid_data) {
2430
- var p_bottom_row = widget_grid_data.row + widget_grid_data.size_y - 1;
2431
- var result = true;
2432
- var upper_rows = [];
2433
- var min_row = 10000;
2434
-
2435
- /* generate an array with columns as index and array with topmost rows
2436
- * empty as value */
2437
- this.for_each_column_occupied(widget_grid_data, function(tcol) {
2438
- var grid_col = this.gridmap[tcol];
2439
- upper_rows[tcol] = [];
2440
-
2441
- var r = p_bottom_row + 1;
2442
- // iterate over each row
2443
- while (--r > 0) {
2444
- if (this.is_widget(tcol, r) && !this.is_player_in(tcol, r)) {
2445
- if (!grid_col[r].is(widget_grid_data.el)) {
2446
- break;
2447
- }
2448
- }
2449
-
2450
- if (!this.is_player(tcol, r) &&
2451
- !this.is_placeholder_in(tcol, r) &&
2452
- !this.is_player_in(tcol, r)) {
2453
- upper_rows[tcol].push(r);
2454
- }
2455
-
2456
- if (r < min_row) {
2457
- min_row = r;
2458
- }
2459
- }
2460
-
2461
- if (upper_rows[tcol].length === 0) {
2462
- result = false;
2463
- return true; //break
2464
- }
2465
-
2466
- upper_rows[tcol].sort();
2467
- });
2468
-
2469
- if (!result) { return false; }
2470
-
2471
- return this.get_valid_rows(widget_grid_data, upper_rows, min_row);
2472
- };
2473
-
2474
-
2475
- /**
2476
- * Search a valid row for the widget represented by `widget_grid_data' in
2477
- * the `upper_rows` array. Iteration starts from row specified in `min_row`.
2478
- *
2479
- * @method get_valid_rows
2480
- * @param {Object} widget_grid_data The actual grid coords object of the
2481
- * player.
2482
- * @param {Array} upper_rows An array with columns as index and arrays
2483
- * of valid rows as values.
2484
- * @param {Number} min_row The upper row from which the iteration will start.
2485
- * @return {Number|Boolean} Returns the upper row valid from the `upper_rows`
2486
- * for the widget in question.
2487
- */
2488
- fn.get_valid_rows = function(widget_grid_data, upper_rows, min_row) {
2489
- var p_top_row = widget_grid_data.row;
2490
- var p_bottom_row = widget_grid_data.row + widget_grid_data.size_y - 1;
2491
- var size_y = widget_grid_data.size_y;
2492
- var r = min_row - 1;
2493
- var valid_rows = [];
2494
-
2495
- while (++r <= p_bottom_row ) {
2496
- var common = true;
2497
- $.each(upper_rows, function(col, rows) {
2498
- if ($.isArray(rows) && $.inArray(r, rows) === -1) {
2499
- common = false;
2500
- }
2501
- });
2502
-
2503
- if (common === true) {
2504
- valid_rows.push(r);
2505
- if (valid_rows.length === size_y) {
2506
- break;
2507
- }
2508
- }
2509
- }
2510
-
2511
- var new_row = false;
2512
- if (size_y === 1) {
2513
- if (valid_rows[0] !== p_top_row) {
2514
- new_row = valid_rows[0] || false;
2515
- }
2516
- }else{
2517
- if (valid_rows[0] !== p_top_row) {
2518
- new_row = this.get_consecutive_numbers_index(
2519
- valid_rows, size_y);
2520
- }
2521
- }
2522
-
2523
- return new_row;
2524
- };
2525
-
2526
-
2527
- fn.get_consecutive_numbers_index = function(arr, size_y) {
2528
- var max = arr.length;
2529
- var result = [];
2530
- var first = true;
2531
- var prev = -1; // or null?
2532
-
2533
- for (var i=0; i < max; i++) {
2534
- if (first || arr[i] === prev + 1) {
2535
- result.push(i);
2536
- if (result.length === size_y) {
2537
- break;
2538
- }
2539
- first = false;
2540
- }else{
2541
- result = [];
2542
- first = true;
2543
- }
2544
-
2545
- prev = arr[i];
2546
- }
2547
-
2548
- return result.length >= size_y ? arr[result[0]] : false;
2549
- };
2550
-
2551
-
2552
- /**
2553
- * Get widgets overlapping with the player.
2554
- *
2555
- * @method get_widgets_overlapped
2556
- * @return {HTMLElements} Returns a jQuery collection of HTMLElements.
2557
- */
2558
- fn.get_widgets_overlapped = function() {
2559
- var $w;
2560
- var $widgets = $([]);
2561
- var used = [];
2562
- var rows_from_bottom = this.cells_occupied_by_player.rows.slice(0);
2563
- rows_from_bottom.reverse();
2564
-
2565
- $.each(this.cells_occupied_by_player.cols, $.proxy(function(i, col) {
2566
- $.each(rows_from_bottom, $.proxy(function(i, row) {
2567
- // if there is a widget in the player position
2568
- if (!this.gridmap[col]) { return true; } //next iteration
2569
- var $w = this.gridmap[col][row];
2570
- if (this.is_occupied(col, row) && !this.is_player($w) &&
2571
- $.inArray($w, used) === -1
2572
- ) {
2573
- $widgets = $widgets.add($w);
2574
- used.push($w);
2575
- }
2576
-
2577
- }, this));
2578
- }, this));
2579
-
2580
- return $widgets;
2581
- };
2582
-
2583
-
2584
- /**
2585
- * This callback is executed when the player begins to collide with a column.
2586
- *
2587
- * @method on_start_overlapping_column
2588
- * @param {Number} col The collided column.
2589
- * @return {HTMLElements} Returns a jQuery collection of HTMLElements.
2590
- */
2591
- fn.on_start_overlapping_column = function(col) {
2592
- this.set_player(col, false);
2593
- };
2594
-
2595
-
2596
- /**
2597
- * A callback executed when the player begins to collide with a row.
2598
- *
2599
- * @method on_start_overlapping_row
2600
- * @param {Number} col The collided row.
2601
- * @return {HTMLElements} Returns a jQuery collection of HTMLElements.
2602
- */
2603
- fn.on_start_overlapping_row = function(row) {
2604
- this.set_player(false, row);
2605
- };
2606
-
2607
-
2608
- /**
2609
- * A callback executed when the the player ends to collide with a column.
2610
- *
2611
- * @method on_stop_overlapping_column
2612
- * @param {Number} col The collided row.
2613
- * @return {HTMLElements} Returns a jQuery collection of HTMLElements.
2614
- */
2615
- fn.on_stop_overlapping_column = function(col) {
2616
- //this.set_player(col, false);
2617
- var self = this;
2618
- if(this.options.shift_larger_widgets_down){
2619
- this.for_each_widget_below(col, this.cells_occupied_by_player.rows[0],
2620
- function(tcol, trow) {
2621
- self.move_widget_up(this, self.player_grid_data.size_y);
2622
- });
2623
- }
2624
- };
2625
-
2626
-
2627
- /**
2628
- * This callback is executed when the player ends to collide with a row.
2629
- *
2630
- * @method on_stop_overlapping_row
2631
- * @param {Number} row The collided row.
2632
- * @return {HTMLElements} Returns a jQuery collection of HTMLElements.
2633
- */
2634
- fn.on_stop_overlapping_row = function(row) {
2635
- //this.set_player(false, row);
2636
- var self = this;
2637
- var cols = this.cells_occupied_by_player.cols;
2638
- if(this.options.shift_larger_widgets_down){
2639
- for (var c = 0, cl = cols.length; c < cl; c++) {
2640
- this.for_each_widget_below(cols[c], row, function(tcol, trow) {
2641
- console.log("from_on_stop_overlapping_row");
2642
- self.move_widget_up(this, self.player_grid_data.size_y);
2643
- });
2644
- }
2645
- }
2646
- };
2647
-
2648
- //Not yet part of api - DM.
2649
- fn.new_move_widget_to = function($widget, col, row){
2650
- var self = this;
2651
- var widget_grid_data = $widget.coords().grid;
2652
-
2653
- this.remove_from_gridmap(widget_grid_data);
2654
- widget_grid_data.row = row;
2655
- widget_grid_data.col = col;
2656
-
2657
- this.add_to_gridmap(widget_grid_data);
2658
- $widget.attr('data-row', row);
2659
- $widget.attr('data-col', col);
2660
- this.update_widget_position(widget_grid_data, $widget);
2661
- this.$changed = this.$changed.add($widget);
2662
-
2663
- return this;
2664
- }
2665
-
2666
-
2667
- /**
2668
- * Move a widget to a specific row. The cell or cells must be empty.
2669
- * If the widget has widgets below, all of these widgets will be moved also
2670
- * if they can.
2671
- *
2672
- * @method move_widget_to
2673
- * @param {HTMLElement} $widget The jQuery wrapped HTMLElement of the
2674
- * widget is going to be moved.
2675
- * @return {Class} Returns the instance of the Gridster Class.
2676
- */
2677
- fn.move_widget_to = function($widget, row) {
2678
- var self = this;
2679
- var widget_grid_data = $widget.coords().grid;
2680
- var diff = row - widget_grid_data.row;
2681
- var $next_widgets = this.widgets_below($widget);
2682
-
2683
- var can_move_to_new_cell = this.can_move_to(
2684
- widget_grid_data, widget_grid_data.col, row, $widget);
2685
-
2686
- if (can_move_to_new_cell === false) {
2687
- return false;
2688
- }
2689
-
2690
- this.remove_from_gridmap(widget_grid_data);
2691
- widget_grid_data.row = row;
2692
- this.add_to_gridmap(widget_grid_data);
2693
- $widget.attr('data-row', row);
2694
- this.$changed = this.$changed.add($widget);
2695
-
2696
-
2697
- $next_widgets.each(function(i, widget) {
2698
- var $w = $(widget);
2699
- var wgd = $w.coords().grid;
2700
- var can_go_up = self.can_go_widget_up(wgd);
2701
- if (can_go_up && can_go_up !== wgd.row) {
2702
- self.move_widget_to($w, can_go_up);
2703
- }
2704
- });
2705
-
2706
- return this;
2707
- };
2708
-
2709
-
2710
- /**
2711
- * Move up the specified widget and all below it.
2712
- *
2713
- * @method move_widget_up
2714
- * @param {HTMLElement} $widget The widget you want to move.
2715
- * @param {Number} [y_units] The number of cells that the widget has to move.
2716
- * @return {Class} Returns the instance of the Gridster Class.
2717
- */
2718
- fn.move_widget_up = function($widget, y_units) {
2719
- var el_grid_data = $widget.coords().grid;
2720
- var actual_row = el_grid_data.row;
2721
- var moved = [];
2722
- var can_go_up = true;
2723
- y_units || (y_units = 1);
2724
-
2725
- if (!this.can_go_up($widget)) { return false; } //break;
2726
-
2727
- this.for_each_column_occupied(el_grid_data, function(col) {
2728
- // can_go_up
2729
- if ($.inArray($widget, moved) === -1) {
2730
- var widget_grid_data = $widget.coords().grid;
2731
- var next_row = actual_row - y_units;
2732
- next_row = this.can_go_up_to_row(
2733
- widget_grid_data, col, next_row);
2734
-
2735
- if (!next_row) {
2736
- return true;
2737
- }
2738
-
2739
- var $next_widgets = this.widgets_below($widget);
2740
-
2741
- this.remove_from_gridmap(widget_grid_data);
2742
- widget_grid_data.row = next_row;
2743
- this.add_to_gridmap(widget_grid_data);
2744
- $widget.attr('data-row', widget_grid_data.row);
2745
- this.$changed = this.$changed.add($widget);
2746
-
2747
- moved.push($widget);
2748
-
2749
- /* $next_widgets.each($.proxy(function(i, widget) {
2750
- console.log("from_within_move_widget_up");
2751
- this.move_widget_up($(widget), y_units);
2752
- }, this)); */
2753
- }
2754
- });
2755
-
2756
- };
2757
-
2758
-
2759
- /**
2760
- * Move down the specified widget and all below it.
2761
- *
2762
- * @method move_widget_down
2763
- * @param {HTMLElement} $widget The jQuery object representing the widget
2764
- * you want to move.
2765
- * @param {Number} The number of cells that the widget has to move.
2766
- * @return {Class} Returns the instance of the Gridster Class.
2767
- */
2768
- fn.move_widget_down = function($widget, y_units) {
2769
- var el_grid_data = $widget.coords().grid;
2770
- var actual_row = el_grid_data.row;
2771
- var moved = [];
2772
- var y_diff = y_units;
2773
-
2774
- if (!$widget) { return false; }
2775
-
2776
- if ($.inArray($widget, moved) === -1) {
2777
-
2778
- var widget_grid_data = $widget.coords().grid;
2779
- var next_row = actual_row + y_units;
2780
- var $next_widgets = this.widgets_below($widget);
2781
-
2782
- this.remove_from_gridmap(widget_grid_data);
2783
-
2784
- $next_widgets.each($.proxy(function(i, widget) {
2785
- var $w = $(widget);
2786
- var wd = $w.coords().grid;
2787
- var tmp_y = this.displacement_diff(
2788
- wd, widget_grid_data, y_diff);
2789
-
2790
- if (tmp_y > 0) {
2791
- this.move_widget_down($w, tmp_y);
2792
- }
2793
- }, this));
2794
-
2795
- widget_grid_data.row = next_row;
2796
- this.update_widget_position(widget_grid_data, $widget);
2797
- $widget.attr('data-row', widget_grid_data.row);
2798
- this.$changed = this.$changed.add($widget);
2799
-
2800
- moved.push($widget);
2801
- }
2802
- };
2803
-
2804
-
2805
- /**
2806
- * Check if the widget can move to the specified row, else returns the
2807
- * upper row possible.
2808
- *
2809
- * @method can_go_up_to_row
2810
- * @param {Number} widget_grid_data The current grid coords object of the
2811
- * widget.
2812
- * @param {Number} col The target column.
2813
- * @param {Number} row The target row.
2814
- * @return {Boolean|Number} Returns the row number if the widget can move
2815
- * to the target position, else returns false.
2816
- */
2817
- fn.can_go_up_to_row = function(widget_grid_data, col, row) {
2818
- var ga = this.gridmap;
2819
- var result = true;
2820
- var urc = []; // upper_rows_in_columns
2821
- var actual_row = widget_grid_data.row;
2822
- var r;
2823
-
2824
- /* generate an array with columns as index and array with
2825
- * upper rows empty in the column */
2826
- this.for_each_column_occupied(widget_grid_data, function(tcol) {
2827
- var grid_col = ga[tcol];
2828
- urc[tcol] = [];
2829
-
2830
- r = actual_row;
2831
- while (r--) {
2832
- if (this.is_empty(tcol, r) &&
2833
- !this.is_placeholder_in(tcol, r)
2834
- ) {
2835
- urc[tcol].push(r);
2836
- }else{
2837
- break;
2838
- }
2839
- }
2840
-
2841
- if (!urc[tcol].length) {
2842
- result = false;
2843
- return true;
2844
- }
2845
-
2846
- });
2847
-
2848
- if (!result) { return false; }
2849
-
2850
- /* get common rows starting from upper position in all the columns
2851
- * that widget occupies */
2852
- r = row;
2853
- for (r = 1; r < actual_row; r++) {
2854
- var common = true;
2855
-
2856
- for (var uc = 0, ucl = urc.length; uc < ucl; uc++) {
2857
- if (urc[uc] && $.inArray(r, urc[uc]) === -1) {
2858
- common = false;
2859
- }
2860
- }
2861
-
2862
- if (common === true) {
2863
- result = r;
2864
- break;
2865
- }
2866
- }
2867
-
2868
- return result;
2869
- };
2870
-
2871
-
2872
- fn.displacement_diff = function(widget_grid_data, parent_bgd, y_units) {
2873
- var actual_row = widget_grid_data.row;
2874
- var diffs = [];
2875
- var parent_max_y = parent_bgd.row + parent_bgd.size_y;
2876
-
2877
- this.for_each_column_occupied(widget_grid_data, function(col) {
2878
- var temp_y_units = 0;
2879
-
2880
- for (var r = parent_max_y; r < actual_row; r++) {
2881
- if (this.is_empty(col, r)) {
2882
- temp_y_units = temp_y_units + 1;
2883
- }
2884
- }
2885
-
2886
- diffs.push(temp_y_units);
2887
- });
2888
-
2889
- var max_diff = Math.max.apply(Math, diffs);
2890
- y_units = (y_units - max_diff);
2891
-
2892
- return y_units > 0 ? y_units : 0;
2893
- };
2894
-
2895
-
2896
- /**
2897
- * Get widgets below a widget.
2898
- *
2899
- * @method widgets_below
2900
- * @param {HTMLElement} $el The jQuery wrapped HTMLElement.
2901
- * @return {HTMLElements} A jQuery collection of HTMLElements.
2902
- */
2903
- fn.widgets_below = function($el) {
2904
- var el_grid_data = $.isPlainObject($el) ? $el : $el.coords().grid;
2905
- var self = this;
2906
- var ga = this.gridmap;
2907
- var next_row = el_grid_data.row + el_grid_data.size_y - 1;
2908
- var $nexts = $([]);
2909
-
2910
- this.for_each_column_occupied(el_grid_data, function(col) {
2911
- self.for_each_widget_below(col, next_row, function(tcol, trow) {
2912
- if (!self.is_player(this) && $.inArray(this, $nexts) === -1) {
2913
- $nexts = $nexts.add(this);
2914
- return true; // break
2915
- }
2916
- });
2917
- });
2918
-
2919
- return this.sort_by_row_asc($nexts);
2920
- };
2921
-
2922
-
2923
- /**
2924
- * Update the array of mapped positions with the new player position.
2925
- *
2926
- * @method set_cells_player_occupies
2927
- * @param {Number} col The new player col.
2928
- * @param {Number} col The new player row.
2929
- * @return {Class} Returns the instance of the Gridster Class.
2930
- */
2931
- fn.set_cells_player_occupies = function(col, row) {
2932
- this.remove_from_gridmap(this.placeholder_grid_data);
2933
- this.placeholder_grid_data.col = col;
2934
- this.placeholder_grid_data.row = row;
2935
- this.add_to_gridmap(this.placeholder_grid_data, this.$player);
2936
- return this;
2937
- };
2938
-
2939
-
2940
- /**
2941
- * Remove from the array of mapped positions the reference to the player.
2942
- *
2943
- * @method empty_cells_player_occupies
2944
- * @return {Class} Returns the instance of the Gridster Class.
2945
- */
2946
- fn.empty_cells_player_occupies = function() {
2947
- this.remove_from_gridmap(this.placeholder_grid_data);
2948
- return this;
2949
- };
2950
-
2951
- fn.can_go_down = function($el) {
2952
- var can_go_down = true;
2953
- var $gr = this;
2954
-
2955
- if ($el.hasClass(this.options.static_class)){
2956
- can_go_down = false;
2957
- }
2958
-
2959
- this.widgets_below($el).each(function(){
2960
- if ($(this).hasClass($gr.options.static_class)){
2961
- can_go_down = false;
2962
- }
2963
- })
2964
-
2965
- return can_go_down;
2966
- }
2967
-
2968
-
2969
- fn.can_go_up = function($el) {
2970
- var el_grid_data = $el.coords().grid;
2971
- var initial_row = el_grid_data.row;
2972
- var prev_row = initial_row - 1;
2973
- var ga = this.gridmap;
2974
- var upper_rows_by_column = [];
2975
-
2976
- var result = true;
2977
- if (initial_row === 1) { return false; }
2978
-
2979
- this.for_each_column_occupied(el_grid_data, function(col) {
2980
- var $w = this.is_widget(col, prev_row);
2981
-
2982
- if (this.is_occupied(col, prev_row) ||
2983
- this.is_player(col, prev_row) ||
2984
- this.is_placeholder_in(col, prev_row) ||
2985
- this.is_player_in(col, prev_row)
2986
- ) {
2987
- result = false;
2988
- return true; //break
2989
- }
2990
- });
2991
-
2992
- return result;
2993
- };
2994
-
2995
-
2996
-
2997
- /**
2998
- * Check if it's possible to move a widget to a specific col/row. It takes
2999
- * into account the dimensions (`size_y` and `size_x` attrs. of the grid
3000
- * coords object) the widget occupies.
3001
- *
3002
- * @method can_move_to
3003
- * @param {Object} widget_grid_data The grid coords object that represents
3004
- * the widget.
3005
- * @param {Object} col The col to check.
3006
- * @param {Object} row The row to check.
3007
- * @param {Number} [max_row] The max row allowed.
3008
- * @return {Boolean} Returns true if all cells are empty, else return false.
3009
- */
3010
- fn.can_move_to = function(widget_grid_data, col, row, max_row) {
3011
- var ga = this.gridmap;
3012
- var $w = widget_grid_data.el;
3013
- var future_wd = {
3014
- size_y: widget_grid_data.size_y,
3015
- size_x: widget_grid_data.size_x,
3016
- col: col,
3017
- row: row
3018
- };
3019
- var result = true;
3020
-
3021
- //Prevents widgets go out of the grid
3022
- var right_col = col + widget_grid_data.size_x - 1;
3023
- if (right_col > this.cols) {
3024
- return false;
3025
- }
3026
-
3027
- if (max_row && max_row < row + widget_grid_data.size_y - 1) {
3028
- return false;
3029
- }
3030
-
3031
- this.for_each_cell_occupied(future_wd, function(tcol, trow) {
3032
- var $tw = this.is_widget(tcol, trow);
3033
- if ($tw && (!widget_grid_data.el || $tw.is($w))) {
3034
- result = false;
3035
- }
3036
- });
3037
-
3038
- return result;
3039
- };
3040
-
3041
-
3042
- /**
3043
- * Given the leftmost column returns all columns that are overlapping
3044
- * with the player.
3045
- *
3046
- * @method get_targeted_columns
3047
- * @param {Number} [from_col] The leftmost column.
3048
- * @return {Array} Returns an array with column numbers.
3049
- */
3050
- fn.get_targeted_columns = function(from_col) {
3051
- var max = (from_col || this.player_grid_data.col) +
3052
- (this.player_grid_data.size_x - 1);
3053
- var cols = [];
3054
- for (var col = from_col; col <= max; col++) {
3055
- cols.push(col);
3056
- }
3057
- return cols;
3058
- };
3059
-
3060
-
3061
- /**
3062
- * Given the upper row returns all rows that are overlapping with the player.
3063
- *
3064
- * @method get_targeted_rows
3065
- * @param {Number} [from_row] The upper row.
3066
- * @return {Array} Returns an array with row numbers.
3067
- */
3068
- fn.get_targeted_rows = function(from_row) {
3069
- var max = (from_row || this.player_grid_data.row) +
3070
- (this.player_grid_data.size_y - 1);
3071
- var rows = [];
3072
- for (var row = from_row; row <= max; row++) {
3073
- rows.push(row);
3074
- }
3075
- return rows;
3076
- };
3077
-
3078
- /**
3079
- * Get all columns and rows that a widget occupies.
3080
- *
3081
- * @method get_cells_occupied
3082
- * @param {Object} el_grid_data The grid coords object of the widget.
3083
- * @return {Object} Returns an object like `{ cols: [], rows: []}`.
3084
- */
3085
- fn.get_cells_occupied = function(el_grid_data) {
3086
- var cells = { cols: [], rows: []};
3087
- var i;
3088
- if (arguments[1] instanceof jQuery) {
3089
- el_grid_data = arguments[1].coords().grid;
3090
- }
3091
-
3092
- for (i = 0; i < el_grid_data.size_x; i++) {
3093
- var col = el_grid_data.col + i;
3094
- cells.cols.push(col);
3095
- }
3096
-
3097
- for (i = 0; i < el_grid_data.size_y; i++) {
3098
- var row = el_grid_data.row + i;
3099
- cells.rows.push(row);
3100
- }
3101
-
3102
- return cells;
3103
- };
3104
-
3105
-
3106
- /**
3107
- * Iterate over the cells occupied by a widget executing a function for
3108
- * each one.
3109
- *
3110
- * @method for_each_cell_occupied
3111
- * @param {Object} el_grid_data The grid coords object that represents the
3112
- * widget.
3113
- * @param {Function} callback The function to execute on each column
3114
- * iteration. Column and row are passed as arguments.
3115
- * @return {Class} Returns the instance of the Gridster Class.
3116
- */
3117
- fn.for_each_cell_occupied = function(grid_data, callback) {
3118
- this.for_each_column_occupied(grid_data, function(col) {
3119
- this.for_each_row_occupied(grid_data, function(row) {
3120
- callback.call(this, col, row);
3121
- });
3122
- });
3123
- return this;
3124
- };
3125
-
3126
-
3127
- /**
3128
- * Iterate over the columns occupied by a widget executing a function for
3129
- * each one.
3130
- *
3131
- * @method for_each_column_occupied
3132
- * @param {Object} el_grid_data The grid coords object that represents
3133
- * the widget.
3134
- * @param {Function} callback The function to execute on each column
3135
- * iteration. The column number is passed as first argument.
3136
- * @return {Class} Returns the instance of the Gridster Class.
3137
- */
3138
- fn.for_each_column_occupied = function(el_grid_data, callback) {
3139
- for (var i = 0; i < el_grid_data.size_x; i++) {
3140
- var col = el_grid_data.col + i;
3141
- callback.call(this, col, el_grid_data);
3142
- }
3143
- };
3144
-
3145
-
3146
- /**
3147
- * Iterate over the rows occupied by a widget executing a function for
3148
- * each one.
3149
- *
3150
- * @method for_each_row_occupied
3151
- * @param {Object} el_grid_data The grid coords object that represents
3152
- * the widget.
3153
- * @param {Function} callback The function to execute on each column
3154
- * iteration. The row number is passed as first argument.
3155
- * @return {Class} Returns the instance of the Gridster Class.
3156
- */
3157
- fn.for_each_row_occupied = function(el_grid_data, callback) {
3158
- for (var i = 0; i < el_grid_data.size_y; i++) {
3159
- var row = el_grid_data.row + i;
3160
- callback.call(this, row, el_grid_data);
3161
- }
3162
- };
3163
-
3164
- fn.clean_up_changed = function(){
3165
- $gr = this;
3166
- $gr.$changed.each(function(){
3167
- if($gr.options.shift_larger_widgets_down){
3168
- $gr.move_widget_up($(this));
3169
- }
3170
- });
3171
- }
3172
-
3173
-
3174
-
3175
- fn._traversing_widgets = function(type, direction, col, row, callback) {
3176
- var ga = this.gridmap;
3177
- if (!ga[col]) { return; }
3178
-
3179
- var cr, max;
3180
- var action = type + '/' + direction;
3181
- if (arguments[2] instanceof jQuery) {
3182
- var el_grid_data = arguments[2].coords().grid;
3183
- col = el_grid_data.col;
3184
- row = el_grid_data.row;
3185
- callback = arguments[3];
3186
- }
3187
- var matched = [];
3188
- var trow = row;
3189
-
3190
-
3191
- var methods = {
3192
- 'for_each/above': function() {
3193
- while (trow--) {
3194
- if (trow > 0 && this.is_widget(col, trow) &&
3195
- $.inArray(ga[col][trow], matched) === -1
3196
- ) {
3197
- cr = callback.call(ga[col][trow], col, trow);
3198
- matched.push(ga[col][trow]);
3199
- if (cr) { break; }
3200
- }
3201
- }
3202
- },
3203
- 'for_each/below': function() {
3204
- for (trow = row + 1, max = ga[col].length; trow < max; trow++) {
3205
- if (this.is_widget(col, trow) &&
3206
- $.inArray(ga[col][trow], matched) === -1
3207
- ) {
3208
- cr = callback.call(ga[col][trow], col, trow);
3209
- matched.push(ga[col][trow]);
3210
- //break was causing problems, leaving for testing.
3211
- //if (cr) { break; }
3212
- }
3213
- }
3214
- }
3215
- };
3216
-
3217
- if (methods[action]) {
3218
- methods[action].call(this);
3219
- }
3220
- };
3221
-
3222
-
3223
- /**
3224
- * Iterate over each widget above the column and row specified.
3225
- *
3226
- * @method for_each_widget_above
3227
- * @param {Number} col The column to start iterating.
3228
- * @param {Number} row The row to start iterating.
3229
- * @param {Function} callback The function to execute on each widget
3230
- * iteration. The value of `this` inside the function is the jQuery
3231
- * wrapped HTMLElement.
3232
- * @return {Class} Returns the instance of the Gridster Class.
3233
- */
3234
- fn.for_each_widget_above = function(col, row, callback) {
3235
- this._traversing_widgets('for_each', 'above', col, row, callback);
3236
- return this;
3237
- };
3238
-
3239
-
3240
- /**
3241
- * Iterate over each widget below the column and row specified.
3242
- *
3243
- * @method for_each_widget_below
3244
- * @param {Number} col The column to start iterating.
3245
- * @param {Number} row The row to start iterating.
3246
- * @param {Function} callback The function to execute on each widget
3247
- * iteration. The value of `this` inside the function is the jQuery wrapped
3248
- * HTMLElement.
3249
- * @return {Class} Returns the instance of the Gridster Class.
3250
- */
3251
- fn.for_each_widget_below = function(col, row, callback) {
3252
- this._traversing_widgets('for_each', 'below', col, row, callback);
3253
- return this;
3254
- };
3255
-
3256
-
3257
- /**
3258
- * Returns the highest occupied cell in the grid.
3259
- *
3260
- * @method get_highest_occupied_cell
3261
- * @return {Object} Returns an object with `col` and `row` numbers.
3262
- */
3263
- fn.get_highest_occupied_cell = function() {
3264
- var r;
3265
- var gm = this.gridmap;
3266
- var rows = [];
3267
- var row_in_col = [];
3268
- for (var c = gm.length - 1; c >= 1; c--) {
3269
- for (r = gm[c].length - 1; r >= 1; r--) {
3270
- if (this.is_widget(c, r)) {
3271
- rows.push(r);
3272
- row_in_col[r] = c;
3273
- break;
3274
- }
3275
- }
3276
- }
3277
-
3278
- var highest_row = Math.max.apply(Math, rows);
3279
-
3280
- this.highest_occupied_cell = {
3281
- col: row_in_col[highest_row],
3282
- row: highest_row
3283
- };
3284
-
3285
- return this.highest_occupied_cell;
3286
- };
3287
-
3288
-
3289
- fn.get_widgets_from = function(col, row) {
3290
- var ga = this.gridmap;
3291
- var $widgets = $();
3292
-
3293
- if (col) {
3294
- $widgets = $widgets.add(
3295
- this.$widgets.filter(function() {
3296
- var tcol = $(this).attr('data-col');
3297
- return (tcol === col || tcol > col);
3298
- })
3299
- );
3300
- }
3301
-
3302
- if (row) {
3303
- $widgets = $widgets.add(
3304
- this.$widgets.filter(function() {
3305
- var trow = $(this).attr('data-row');
3306
- return (trow === row || trow > row);
3307
- })
3308
- );
3309
- }
3310
-
3311
- return $widgets;
3312
- };
3313
-
3314
-
3315
- /**
3316
- * Set the current height of the parent grid.
3317
- *
3318
- * @method set_dom_grid_height
3319
- * @return {Object} Returns the instance of the Gridster class.
3320
- */
3321
- fn.set_dom_grid_height = function() {
3322
- var r = this.get_highest_occupied_cell().row;
3323
- this.$el.css('height', r * this.min_widget_height);
3324
- return this;
3325
- };
3326
-
3327
-
3328
- /**
3329
- * It generates the neccessary styles to position the widgets.
3330
- *
3331
- * @method generate_stylesheet
3332
- * @param {Number} rows Number of columns.
3333
- * @param {Number} cols Number of rows.
3334
- * @return {Object} Returns the instance of the Gridster class.
3335
- */
3336
- fn.generate_stylesheet = function(opts) {
3337
- var styles = '';
3338
- var max_size_x = this.options.max_size_x;
3339
- var max_rows = 0;
3340
- var max_cols = 0;
3341
- var i;
3342
- var rules;
3343
-
3344
- opts || (opts = {});
3345
- opts.cols || (opts.cols = this.cols);
3346
- opts.rows || (opts.rows = this.rows);
3347
- opts.namespace || (opts.namespace = this.options.namespace);
3348
- opts.widget_base_dimensions ||
3349
- (opts.widget_base_dimensions = this.options.widget_base_dimensions);
3350
- opts.widget_margins ||
3351
- (opts.widget_margins = this.options.widget_margins);
3352
- opts.min_widget_width = (opts.widget_margins[0] * 2) +
3353
- opts.widget_base_dimensions[0];
3354
- opts.min_widget_height = (opts.widget_margins[1] * 2) +
3355
- opts.widget_base_dimensions[1];
3356
-
3357
- // don't duplicate stylesheets for the same configuration
3358
- var serialized_opts = $.param(opts);
3359
- if ($.inArray(serialized_opts, Gridster.generated_stylesheets) >= 0) {
3360
- return false;
3361
- }
3362
-
3363
- Gridster.generated_stylesheets.push(serialized_opts);
3364
-
3365
- /* generate CSS styles for cols */
3366
- for (i = opts.cols; i >= 0; i--) {
3367
- styles += (opts.namespace + ' [data-col="'+ (i + 1) + '"] { left:' +
3368
- ((i * opts.widget_base_dimensions[0]) +
3369
- (i * opts.widget_margins[0]) +
3370
- ((i + 1) * opts.widget_margins[0])) + 'px;} ');
3371
- }
3372
-
3373
- /* generate CSS styles for rows */
3374
- for (i = opts.rows; i >= 0; i--) {
3375
- styles += (opts.namespace + ' [data-row="' + (i + 1) + '"] { top:' +
3376
- ((i * opts.widget_base_dimensions[1]) +
3377
- (i * opts.widget_margins[1]) +
3378
- ((i + 1) * opts.widget_margins[1]) ) + 'px;} ');
3379
- }
3380
-
3381
- for (var y = 1; y <= opts.rows; y++) {
3382
- styles += (opts.namespace + ' [data-sizey="' + y + '"] { height:' +
3383
- (y * opts.widget_base_dimensions[1] +
3384
- (y - 1) * (opts.widget_margins[1] * 2)) + 'px;}');
3385
- }
3386
-
3387
- for (var x = 1; x <= max_size_x; x++) {
3388
- styles += (opts.namespace + ' [data-sizex="' + x + '"] { width:' +
3389
- (x * opts.widget_base_dimensions[0] +
3390
- (x - 1) * (opts.widget_margins[0] * 2)) + 'px;}');
3391
- }
3392
-
3393
- return this.add_style_tag(styles);
3394
- };
3395
-
3396
-
3397
- /**
3398
- * Injects the given CSS as string to the head of the document.
3399
- *
3400
- * @method add_style_tag
3401
- * @param {String} css The styles to apply.
3402
- * @return {Object} Returns the instance of the Gridster class.
3403
- */
3404
- fn.add_style_tag = function(css) {
3405
- var d = document;
3406
- var tag = d.createElement('style');
3407
-
3408
- d.getElementsByTagName('head')[0].appendChild(tag);
3409
- tag.setAttribute('type', 'text/css');
3410
-
3411
- if (tag.styleSheet) {
3412
- tag.styleSheet.cssText = css;
3413
- }else{
3414
- tag.appendChild(document.createTextNode(css));
3415
- }
3416
- return this;
3417
- };
3418
-
3419
-
3420
- /**
3421
- * Generates a faux grid to collide with it when a widget is dragged and
3422
- * detect row or column that we want to go.
3423
- *
3424
- * @method generate_faux_grid
3425
- * @param {Number} rows Number of columns.
3426
- * @param {Number} cols Number of rows.
3427
- * @return {Object} Returns the instance of the Gridster class.
3428
- */
3429
- fn.generate_faux_grid = function(rows, cols) {
3430
- this.faux_grid = [];
3431
- this.gridmap = [];
3432
- var col;
3433
- var row;
3434
- for (col = cols; col > 0; col--) {
3435
- this.gridmap[col] = [];
3436
- for (row = rows; row > 0; row--) {
3437
- this.add_faux_cell(row, col);
3438
- }
3439
- }
3440
- return this;
3441
- };
3442
-
3443
-
3444
- /**
3445
- * Add cell to the faux grid.
3446
- *
3447
- * @method add_faux_cell
3448
- * @param {Number} row The row for the new faux cell.
3449
- * @param {Number} col The col for the new faux cell.
3450
- * @return {Object} Returns the instance of the Gridster class.
3451
- */
3452
- fn.add_faux_cell = function(row, col) {
3453
- var coords = $({
3454
- left: this.baseX + ((col - 1) * this.min_widget_width),
3455
- top: this.baseY + (row -1) * this.min_widget_height,
3456
- width: this.min_widget_width,
3457
- height: this.min_widget_height,
3458
- col: col,
3459
- row: row,
3460
- original_col: col,
3461
- original_row: row
3462
- }).coords();
3463
-
3464
- if (!$.isArray(this.gridmap[col])) {
3465
- this.gridmap[col] = [];
3466
- }
3467
-
3468
- this.gridmap[col][row] = false;
3469
- this.faux_grid.push(coords);
3470
-
3471
- return this;
3472
- };
3473
-
3474
-
3475
- /**
3476
- * Add rows to the faux grid.
3477
- *
3478
- * @method add_faux_rows
3479
- * @param {Number} rows The number of rows you want to add to the faux grid.
3480
- * @return {Object} Returns the instance of the Gridster class.
3481
- */
3482
- fn.add_faux_rows = function(rows) {
3483
- var actual_rows = this.rows;
3484
- var max_rows = actual_rows + (rows || 1);
3485
-
3486
- for (var r = max_rows; r > actual_rows; r--) {
3487
- for (var c = this.cols; c >= 1; c--) {
3488
- this.add_faux_cell(r, c);
3489
- }
3490
- }
3491
-
3492
- this.rows = max_rows;
3493
-
3494
- if (this.options.autogenerate_stylesheet) {
3495
- this.generate_stylesheet();
3496
- }
3497
-
3498
- return this;
3499
- };
3500
-
3501
- /**
3502
- * Add cols to the faux grid.
3503
- *
3504
- * @method add_faux_cols
3505
- * @param {Number} cols The number of cols you want to add to the faux grid.
3506
- * @return {Object} Returns the instance of the Gridster class.
3507
- */
3508
- fn.add_faux_cols = function(cols) {
3509
- var actual_cols = this.cols;
3510
- var max_cols = actual_cols + (cols || 1);
3511
-
3512
- for (var c = actual_cols; c < max_cols; c++) {
3513
- for (var r = this.rows; r >= 1; r--) {
3514
- this.add_faux_cell(r, c);
3515
- }
3516
- }
3517
-
3518
- this.cols = max_cols;
3519
-
3520
- if (this.options.autogenerate_stylesheet) {
3521
- this.generate_stylesheet();
3522
- }
3523
-
3524
- return this;
3525
- };
3526
-
3527
-
3528
- /**
3529
- * Recalculates the offsets for the faux grid. You need to use it when
3530
- * the browser is resized.
3531
- *
3532
- * @method recalculate_faux_grid
3533
- * @return {Object} Returns the instance of the Gridster class.
3534
- */
3535
- fn.recalculate_faux_grid = function() {
3536
- var aw = this.$wrapper.width();
3537
- this.baseX = ($(window).width() - aw) / 2;
3538
- this.baseY = this.$wrapper.offset().top;
3539
-
3540
- $.each(this.faux_grid, $.proxy(function(i, coords) {
3541
- this.faux_grid[i] = coords.update({
3542
- left: this.baseX + (coords.data.col -1) * this.min_widget_width,
3543
- top: this.baseY + (coords.data.row -1) * this.min_widget_height
3544
- });
3545
-
3546
- }, this));
3547
-
3548
- return this;
3549
- };
3550
-
3551
-
3552
- /**
3553
- * Get all widgets in the DOM and register them.
3554
- *
3555
- * @method get_widgets_from_DOM
3556
- * @return {Object} Returns the instance of the Gridster class.
3557
- */
3558
- fn.get_widgets_from_DOM = function() {
3559
- this.$widgets.each($.proxy(function(i, widget) {
3560
- this.register_widget($(widget));
3561
- }, this));
3562
- return this;
3563
- };
3564
-
3565
-
3566
- /**
3567
- * Calculate columns and rows to be set based on the configuration
3568
- * parameters, grid dimensions, etc ...
3569
- *
3570
- * @method generate_grid_and_stylesheet
3571
- * @return {Object} Returns the instance of the Gridster class.
3572
- */
3573
- fn.generate_grid_and_stylesheet = function() {
3574
- var aw = this.$wrapper.width();
3575
- var ah = this.$wrapper.height();
3576
-
3577
- var cols = Math.floor(aw / this.min_widget_width) +
3578
- this.options.extra_cols;
3579
-
3580
- var actual_cols = this.$widgets.map(function() {
3581
- return $(this).attr('data-col');
3582
- });
3583
- actual_cols = Array.prototype.slice.call(actual_cols, 0);
3584
- //needed to pass tests with phantomjs
3585
- actual_cols.length || (actual_cols = [0]);
3586
-
3587
- var min_cols = Math.max.apply(Math, actual_cols);
3588
-
3589
- // get all rows that could be occupied by the current widgets
3590
- var max_rows = this.options.extra_rows;
3591
- this.$widgets.each(function(i, w) {
3592
- max_rows += (+$(w).attr('data-sizey'));
3593
- });
3594
-
3595
- this.cols = Math.max(min_cols, cols, this.options.min_cols);
3596
- //this.rows = Math.max(max_rows, this.options.min_rows);
3597
- this.rows = this.options.max_rows;
3598
-
3599
- this.baseX = ($(window).width() - aw) / 2;
3600
- this.baseY = this.$wrapper.offset().top;
3601
-
3602
- if (this.options.autogenerate_stylesheet) {
3603
- this.generate_stylesheet();
3604
- }
3605
-
3606
- return this.generate_faux_grid(this.rows, this.cols);
3607
- };
3608
-
3609
-
3610
- //jQuery adapter
3611
- $.fn.gridster = function(options) {
3612
- return this.each(function() {
3613
- if (!$(this).data('gridster')) {
3614
- $(this).data('gridster', new Gridster( this, options ));
3615
- }
3616
- });
3617
- };
3618
-
3619
- $.Gridster = fn;
3620
-
3621
- }(jQuery, window, document));
1
+ /** https://github.com/ducksboard/gridster.js */
2
+ (function(e,t,n,r){function i(t){if(t[0]&&e.isPlainObject(t[0])){this.data=t[0]}else{this.el=t}this.isCoords=true;this.coords={};this.init();return this}var s=i.prototype;s.init=function(){this.set();this.original_coords=this.get()};s.set=function(e,t){var n=this.el;if(n&&!e){this.data=n.offset();this.data.width=n.width();this.data.height=n.height()}if(n&&e&&!t){var r=n.offset();this.data.top=r.top;this.data.left=r.left}var i=this.data;this.coords.x1=i.left;this.coords.y1=i.top;this.coords.x2=i.left+i.width;this.coords.y2=i.top+i.height;this.coords.cx=i.left+i.width/2;this.coords.cy=i.top+i.height/2;this.coords.width=i.width;this.coords.height=i.height;this.coords.el=n||false;return this};s.update=function(t){if(!t&&!this.el){return this}if(t){var n=e.extend({},this.data,t);this.data=n;return this.set(true,true)}this.set(true);return this};s.get=function(){return this.coords};e.fn.coords=function(){if(this.data("coords")){return this.data("coords")}var e=new i(this,arguments[0]);this.data("coords",e);return e}})(jQuery,window,document);(function(e,t,n,r){function s(t,n,r){this.options=e.extend(i,r);this.$element=t;this.last_colliders=[];this.last_colliders_coords=[];if(typeof n==="string"||n instanceof jQuery){this.$colliders=e(n,this.options.colliders_context).not(this.$element)}else{this.colliders=e(n)}this.init()}var i={colliders_context:n.body};var o=s.prototype;o.init=function(){this.find_collisions()};o.overlaps=function(e,t){var n=false;var r=false;if(t.x1>=e.x1&&t.x1<=e.x2||t.x2>=e.x1&&t.x2<=e.x2||e.x1>=t.x1&&e.x2<=t.x2){n=true}if(t.y1>=e.y1&&t.y1<=e.y2||t.y2>=e.y1&&t.y2<=e.y2||e.y1>=t.y1&&e.y2<=t.y2){r=true}return n&&r};o.detect_overlapping_region=function(e,t){var n="";var r="";if(e.y1>t.cy&&e.y1<t.y2){n="N"}if(e.y2>t.y1&&e.y2<t.cy){n="S"}if(e.x1>t.cx&&e.x1<t.x2){r="W"}if(e.x2>t.x1&&e.x2<t.cx){r="E"}return n+r||"C"};o.calculate_overlapped_area_coords=function(t,n){var r=Math.max(t.x1,n.x1);var i=Math.max(t.y1,n.y1);var s=Math.min(t.x2,n.x2);var o=Math.min(t.y2,n.y2);return e({left:r,top:i,width:s-r,height:o-i}).coords().get()};o.calculate_overlapped_area=function(e){return e.width*e.height};o.manage_colliders_start_stop=function(t,n,r){var i=this.last_colliders_coords;for(var s=0,o=i.length;s<o;s++){if(e.inArray(i[s],t)===-1){n.call(this,i[s])}}for(var u=0,a=t.length;u<a;u++){if(e.inArray(t[u],i)===-1){r.call(this,t[u])}}};o.find_collisions=function(t){var n=this;var r=[];var i=[];var s=this.colliders||this.$colliders;var o=s.length;var u=n.$element.coords().update(t||false).get();while(o--){var a=n.$colliders?e(s[o]):s[o];var f=a.isCoords?a:a.coords();var l=f.get();var c=n.overlaps(u,l);if(!c){continue}var h=n.detect_overlapping_region(u,l);if(h==="C"){var p=n.calculate_overlapped_area_coords(u,l);var d=n.calculate_overlapped_area(p);var v={area:d,area_coords:p,region:h,coords:l,player_coords:u,el:a};if(n.options.on_overlap){n.options.on_overlap.call(this,v)}r.push(f);i.push(v)}}if(n.options.on_overlap_stop||n.options.on_overlap_start){this.manage_colliders_start_stop(r,n.options.on_overlap_start,n.options.on_overlap_stop)}this.last_colliders_coords=r;return i};o.get_closest_colliders=function(e){var t=this.find_collisions(e);t.sort(function(e,t){if(e.region==="C"&&t.region==="C"){if(e.coords.y1<t.coords.y1||e.coords.x1<t.coords.x1){return-1}else{return 1}}if(e.area<t.area){return 1}return 1});return t};e.fn.collision=function(e,t){return new s(this,e,t)}})(jQuery,window,document);(function(e,t){e.debounce=function(e,t,n){var r;return function(){var i=this,s=arguments;var o=function(){r=null;if(!n)e.apply(i,s)};if(n&&!r)e.apply(i,s);clearTimeout(r);r=setTimeout(o,t)}};e.throttle=function(e,t){var n,r,i,s,o,u;var a=debounce(function(){o=s=false},t);return function(){n=this;r=arguments;var f=function(){i=null;if(o)e.apply(n,r);a()};if(!i)i=setTimeout(f,t);if(s){o=true}else{u=e.apply(n,r)}a();s=true;return u}}})(window);(function(e,t,n,r){function a(t,r){this.options=e.extend({},i,r);this.$body=e(n.body);this.$container=e(t);this.$dragitems=e(this.options.items,this.$container);this.is_dragging=false;this.player_min_left=0+this.options.offset_left;this.init()}var i={items:".gs_w",distance:1,limit:true,offset_left:0,autoscroll:true,ignore_dragging:["INPUT","TEXTAREA","SELECT","BUTTON"],handle:null};var s=e(t);var o=!!("ontouchstart"in t);var u={start:o?"touchstart":"mousedown.draggable",move:o?"touchmove":"mousemove.draggable",end:o?"touchend":"mouseup.draggable"};var f=a.prototype;f.init=function(){this.calculate_positions();this.$container.css("position","relative");this.disabled=false;this.events();this.on_window_resize=throttle(e.proxy(this.calculate_positions,this),200);e(t).bind("resize",this.on_window_resize)};f.events=function(){this.proxied_on_select_start=e.proxy(this.on_select_start,this);this.$container.on("selectstart",this.proxied_on_select_start);this.proxied_drag_handler=e.proxy(this.drag_handler,this);this.$container.on(u.start,this.options.items,this.proxied_drag_handler);this.proxied_pointer_events_end=e.proxy(function(e){this.is_dragging=false;if(this.disabled){return}this.$body.off(u.move);if(this.drag_start){this.on_dragstop(e)}},this);this.$body.on(u.end,this.proxied_pointer_events_end)};f.get_actual_pos=function(e){var t=e.position();return t};f.get_mouse_pos=function(e){if(o){var t=e.originalEvent;e=t.touches.length?t.touches[0]:t.changedTouches[0]}return{left:e.clientX,top:e.clientY}};f.get_offset=function(e){e.preventDefault();var t=this.get_mouse_pos(e);var n=Math.round(t.left-this.mouse_init_pos.left);var r=Math.round(t.top-this.mouse_init_pos.top);var i=Math.round(this.el_init_offset.left+n-this.baseX);var s=Math.round(this.el_init_offset.top+r-this.baseY+this.scrollOffset);if(this.options.limit){if(i>this.player_max_left){i=this.player_max_left}else if(i<this.player_min_left){i=this.player_min_left}}return{left:i,top:s,mouse_left:t.left,mouse_top:t.top}};f.manage_scroll=function(e){var t;var n=s.scrollTop();var r=n;var i=r+this.window_height;var o=i-50;var u=r+50;var a=e.mouse_left;var f=r+e.mouse_top;var l=this.doc_height-this.window_height+this.player_height;if(f>=o){t=n+30;if(t<l){s.scrollTop(t);this.scrollOffset=this.scrollOffset+30}}if(f<=u){t=n-30;if(t>0){s.scrollTop(t);this.scrollOffset=this.scrollOffset-30}}};f.calculate_positions=function(e){this.window_height=s.height()};f.drag_handler=function(t){var n=t.target.nodeName;if(this.disabled||t.which!==1&&!o){return}if(this.ignore_drag(t)){return}var r=this;var i=true;this.$player=e(t.currentTarget);this.el_init_pos=this.get_actual_pos(this.$player);this.mouse_init_pos=this.get_mouse_pos(t);this.offsetY=this.mouse_init_pos.top-this.el_init_pos.top;this.on_pointer_events_move=function(e){var t=r.get_mouse_pos(e);var n=Math.abs(t.left-r.mouse_init_pos.left);var s=Math.abs(t.top-r.mouse_init_pos.top);if(!(n>r.options.distance||s>r.options.distance)){return false}if(i){i=false;r.on_dragstart.call(r,e);return false}if(r.is_dragging===true){r.on_dragmove.call(r,e)}return false};this.$body.on(u.move,this.on_pointer_events_move);return false};f.on_dragstart=function(t){t.preventDefault();this.drag_start=true;this.is_dragging=true;var r=this.$container.offset();this.baseX=Math.round(r.left);this.baseY=Math.round(r.top);this.doc_height=e(n).height();if(this.options.helper==="clone"){this.$helper=this.$player.clone().appendTo(this.$container).addClass("helper");this.helper=true}else{this.helper=false}this.scrollOffset=0;this.el_init_offset=this.$player.offset();this.player_width=this.$player.width();this.player_height=this.$player.height();this.player_max_left=this.$container.width()-this.player_width+this.options.offset_left;if(this.options.start){this.options.start.call(this.$player,t,{helper:this.helper?this.$helper:this.$player})}return false};f.on_dragmove=function(e){var t=this.get_offset(e);this.options.autoscroll&&this.manage_scroll(t);(this.helper?this.$helper:this.$player).css({position:"absolute",left:t.left,top:t.top});var n={position:{left:t.left,top:t.top}};if(this.options.drag){this.options.drag.call(this.$player,e,n)}return false};f.on_dragstop=function(e){var t=this.get_offset(e);this.drag_start=false;var n={position:{left:t.left,top:t.top}};if(this.options.stop){this.options.stop.call(this.$player,e,n)}if(this.helper){this.$helper.remove()}return false};f.on_select_start=function(e){if(this.disabled){return}if(this.ignore_drag(e)){return}return false};f.enable=function(){this.disabled=false};f.disable=function(){this.disabled=true};f.destroy=function(){this.disable();this.$container.off("selectstart",this.proxied_on_select_start);this.$container.off(u.start,this.proxied_drag_handler);this.$body.off(u.end,this.proxied_pointer_events_end);this.$body.off(u.move,this.on_pointer_events_move);e(t).unbind("resize",this.on_window_resize);e.removeData(this.$container,"drag")};f.ignore_drag=function(t){if(this.options.handle){return!e(t.target).is(this.options.handle)}return e.inArray(t.target.nodeName,this.options.ignore_dragging)>=0};e.fn.dragg=function(t){return this.each(function(){if(!e.data(this,"drag")){e.data(this,"drag",new a(this,t))}})}})(jQuery,window,document);(function(e,t,n,r){function s(t,n){this.options=e.extend(true,i,n);this.$el=e(t);this.$wrapper=this.$el.parent();this.$widgets=this.$el.children(this.options.widget_selector).addClass("gs_w");this.widgets=[];this.$changed=e([]);this.w_queue={};this.wrapper_width=this.$wrapper.width();this.min_widget_width=this.options.widget_margins[0]*2+this.options.widget_base_dimensions[0];this.min_widget_height=this.options.widget_margins[1]*2+this.options.widget_base_dimensions[1];this.init()}var i={namespace:"",widget_selector:"li",static_class:"static",widget_margins:[10,10],widget_base_dimensions:[400,225],extra_rows:0,extra_cols:0,min_cols:1,max_cols:60,min_rows:15,max_rows:15,max_size_x:6,autogenerate_stylesheet:true,avoid_overlapped_widgets:true,shift_larger_widgets_down:true,serialize_params:function(e,t){return{col:t.col,row:t.row,size_x:t.size_x,size_y:t.size_y}},collision:{},draggable:{distance:4,items:".gs_w:not(.static)"}};s.generated_stylesheets=[];var o=s.prototype;o.init=function(){this.generate_grid_and_stylesheet();this.get_widgets_from_DOM();this.set_dom_grid_height();this.$wrapper.addClass("ready");this.draggable();e(t).bind("resize",throttle(e.proxy(this.recalculate_faux_grid,this),200))};o.disable=function(){this.$wrapper.find(".player-revert").removeClass("player-revert");this.drag_api.disable();return this};o.enable=function(){this.drag_api.enable();return this};o.add_widget=function(t,n,r,i,s){var o;n||(n=1);r||(r=1);if(!i&!s){o=this.next_position(n,r)}else{o={col:i,row:s};this.empty_cells(i,s,n,r)}var u=e(t).attr({"data-col":o.col,"data-row":o.row,"data-sizex":n,"data-sizey":r}).addClass("gs_w").appendTo(this.$el).hide();this.$widgets=this.$widgets.add(u);this.$changed=this.$changed.add(u);this.register_widget(u);this.add_faux_rows(o.size_y);this.set_dom_grid_height();return u.fadeIn()};o.resize_widget=function(t,n,r){var i=t.coords().grid;n||(n=i.size_x);r||(r=i.size_y);if(n>this.cols){n=this.cols}var s=this.get_cells_occupied(i);var o=i.size_x;var u=i.size_y;var a=i.col;var f=a;var l=n>o;var c=r>u;if(a+n-1>this.cols){var h=a+(n-1)-this.cols;var p=a-h;f=Math.max(1,p)}var d={col:f,row:i.row,size_x:n,size_y:r};var v=this.get_cells_occupied(d);var m=[];e.each(s.cols,function(t,n){if(e.inArray(n,v.cols)===-1){m.push(n)}});var g=[];e.each(v.cols,function(t,n){if(e.inArray(n,s.cols)===-1){g.push(n)}});var y=[];e.each(s.rows,function(t,n){if(e.inArray(n,v.rows)===-1){y.push(n)}});var b=[];e.each(v.rows,function(t,n){if(e.inArray(n,s.rows)===-1){b.push(n)}});this.remove_from_gridmap(i);if(g.length){var w=[f,i.row,n,Math.min(u,r),t];this.empty_cells.apply(this,w)}if(b.length){var E=[f,i.row,n,r,t];this.empty_cells.apply(this,E)}i.col=f;i.size_x=n;i.size_y=r;this.add_to_gridmap(d,t);t.data("coords").update({width:n*this.options.widget_base_dimensions[0]+(n-1)*this.options.widget_margins[0]*2,height:r*this.options.widget_base_dimensions[1]+(r-1)*this.options.widget_margins[1]*2});if(r>u){this.add_faux_rows(r-u)}if(n>o){this.add_faux_cols(n-o)}t.attr({"data-col":f,"data-sizex":n,"data-sizey":r});if(m.length){var S=[m[0],i.row,m.length,Math.min(u,r),t];this.remove_empty_cells.apply(this,S)}if(y.length){var x=[f,i.row,n,r,t];this.remove_empty_cells.apply(this,x)}return t};o.empty_cells=function(t,n,r,i,s){var o=this.widgets_below({col:t,row:n-i,size_x:r,size_y:i});o.not(s).each(e.proxy(function(t,r){var s=e(r).coords().grid;if(!(s.row<=n+i-1)){return}var o=n+i-s.row;this.move_widget_down(e(r),o)},this));this.set_dom_grid_height();return this};o.remove_empty_cells=function(e,t,n,r,i){var s=this.widgets_below({col:e,row:t,size_x:n,size_y:r});this.set_dom_grid_height();return this};o.next_position=function(e,t){e||(e=1);t||(t=1);var n=this.gridmap;var r=n.length;var i=[];var s;for(var o=1;o<r;o++){s=n[o].length;for(var u=1;u<=s;u++){var a=this.can_move_to({size_x:e,size_y:t},o,u);if(a){i.push({col:o,row:u,size_y:t,size_x:e})}}}if(i.length){return this.sort_by_row_and_col_asc(i)[0]}return false};o.remove_by_grid=function(e,t){var n=this.is_widget(e,t);if(n){this.remove_widget(n)}};o.remove_widget=function(t,n,r){var i=t instanceof jQuery?t:e(t);var s=i.coords().grid;if(e.isFunction(n)){r=n;n=false}this.cells_occupied_by_placeholder={};this.$widgets=this.$widgets.not(i);var o=this.widgets_below(i);this.remove_from_gridmap(s);i.fadeOut(e.proxy(function(){i.remove();if(!n){o.each(e.proxy(function(t,n){this.move_widget_up(e(n),s.size_y)},this))}this.set_dom_grid_height();if(r){r.call(this,t)}},this))};o.remove_all_widgets=function(t){this.$widgets.each(e.proxy(function(e,n){this.remove_widget(n,true,t)},this));return this};o.serialize=function(t){t||(t=this.$widgets);var n=[];t.each(e.proxy(function(t,r){if(typeof e(r).coords().grid!="undefined"){n.push(this.options.serialize_params(e(r),e(r).coords().grid))}},this));return n};o.serialize_changed=function(){return this.serialize(this.$changed)};o.register_widget=function(e){var t={col:parseInt(e.attr("data-col"),10),row:parseInt(e.attr("data-row"),10),size_x:parseInt(e.attr("data-sizex"),10),size_y:parseInt(e.attr("data-sizey"),10),el:e};if(this.options.avoid_overlapped_widgets&&!this.can_move_to({size_x:t.size_x,size_y:t.size_y},t.col,t.row)){t=this.next_position(t.size_x,t.size_y);t.el=e;e.attr({"data-col":t.col,"data-row":t.row,"data-sizex":t.size_x,"data-sizey":t.size_y})}e.data("coords",e.coords());e.data("coords").grid=t;this.add_to_gridmap(t,e);return this};o.update_widget_position=function(e,t){this.for_each_cell_occupied(e,function(e,n){if(!this.gridmap[e]){return this}this.gridmap[e][n]=t});return this};o.remove_from_gridmap=function(e){return this.update_widget_position(e,false)};o.add_to_gridmap=function(e,t){this.update_widget_position(e,t||e.el)};o.draggable=function(){var t=this;var n=e.extend(true,{},this.options.draggable,{offset_left:this.options.widget_margins[0],start:function(n,r){t.$widgets.filter(".player-revert").removeClass("player-revert");t.$player=e(this);t.$helper=t.options.draggable.helper==="clone"?e(r.helper):t.$player;t.helper=!t.$helper.is(t.$player);t.on_start_drag.call(t,n,r);t.$el.trigger("gridster:dragstart")},stop:function(e,n){t.on_stop_drag.call(t,e,n);t.$el.trigger("gridster:dragstop")},drag:throttle(function(e,n){t.on_drag.call(t,e,n);t.$el.trigger("gridster:drag")},60)});this.drag_api=this.$el.dragg(n).data("drag");return this};o.on_start_drag=function(t,n){this.$helper.add(this.$player).add(this.$wrapper).addClass("dragging");this.$player.addClass("player");this.player_grid_data=this.$player.coords().grid;this.placeholder_grid_data=e.extend({},this.player_grid_data);this.$el.css("height",this.$el.height()+this.player_grid_data.size_y*this.min_widget_height);var r=this.faux_grid;var i=this.$player.data("coords").coords;this.cells_occupied_by_player=this.get_cells_occupied(this.player_grid_data);this.cells_occupied_by_placeholder=this.get_cells_occupied(this.placeholder_grid_data);this.last_cols=[];this.last_rows=[];this.collision_api=this.$helper.collision(r,this.options.collision);this.$preview_holder=e("<li />",{"class":"preview-holder","data-row":this.$player.attr("data-row"),"data-col":this.$player.attr("data-col"),css:{width:i.width,height:i.height}}).appendTo(this.$el);if(this.options.draggable.start){this.options.draggable.start.call(this,t,n)}};o.on_drag=function(e,t){if(this.$player===null){return false}var n={left:t.position.left+this.baseX,top:t.position.top+this.baseY};this.colliders_data=this.collision_api.get_closest_colliders(n);this.on_overlapped_column_change(this.on_start_overlapping_column,this.on_stop_overlapping_column);this.on_overlapped_row_change(this.on_start_overlapping_row,this.on_stop_overlapping_row);if(this.helper&&this.$player){this.$player.css({left:t.position.left,top:t.position.top})}if(this.options.draggable.drag){this.options.draggable.drag.call(this,e,t)}};o.on_stop_drag=function(e,t){this.$helper.add(this.$player).add(this.$wrapper).removeClass("dragging");t.position.left=t.position.left+this.baseX;t.position.top=t.position.top+this.baseY;this.colliders_data=this.collision_api.get_closest_colliders(t.position);this.on_overlapped_column_change(this.on_start_overlapping_column,this.on_stop_overlapping_column);this.on_overlapped_row_change(this.on_start_overlapping_row,this.on_stop_overlapping_row);this.$player.addClass("player-revert").removeClass("player").attr({"data-col":this.placeholder_grid_data.col,"data-row":this.placeholder_grid_data.row}).css({left:"",top:""});this.$changed=this.$changed.add(this.$player);this.cells_occupied_by_player=this.get_cells_occupied(this.placeholder_grid_data);this.set_cells_player_occupies(this.placeholder_grid_data.col,this.placeholder_grid_data.row);this.$player.coords().grid.row=this.placeholder_grid_data.row;this.$player.coords().grid.col=this.placeholder_grid_data.col;if(this.options.draggable.stop){this.options.draggable.stop.call(this,e,t)}this.$preview_holder.remove();this.$player=null;this.$helper=null;this.placeholder_grid_data={};this.player_grid_data={};this.cells_occupied_by_placeholder={};this.cells_occupied_by_player={};this.w_queue={};this.set_dom_grid_height()};o.on_overlapped_column_change=function(t,n){if(!this.colliders_data.length){return}var r=this.get_targeted_columns(this.colliders_data[0].el.data.col);var i=this.last_cols.length;var s=r.length;var o;for(o=0;o<s;o++){if(e.inArray(r[o],this.last_cols)===-1){(t||e.noop).call(this,r[o])}}for(o=0;o<i;o++){if(e.inArray(this.last_cols[o],r)===-1){(n||e.noop).call(this,this.last_cols[o])}}this.last_cols=r;return this};o.on_overlapped_row_change=function(t,n){if(!this.colliders_data.length){return}var r=this.get_targeted_rows(this.colliders_data[0].el.data.row);var i=this.last_rows.length;var s=r.length;var o;for(o=0;o<s;o++){if(e.inArray(r[o],this.last_rows)===-1){(t||e.noop).call(this,r[o])}}for(o=0;o<i;o++){if(e.inArray(this.last_rows[o],r)===-1){(n||e.noop).call(this,this.last_rows[o])}}this.last_rows=r};o.set_player=function(t,n,r){var i=this;var s=false;if(!r){this.empty_cells_player_occupies()}var o=!r?i.colliders_data[0].el.data:{col:t};var u=o.col;var a=o.row||n;this.player_grid_data={col:u,row:a,size_y:this.player_grid_data.size_y,size_x:this.player_grid_data.size_x};this.cells_occupied_by_player=this.get_cells_occupied(this.player_grid_data);this.cells_occupied_by_placeholder=this.get_cells_occupied(this.placeholder_grid_data);var f=this.get_widgets_overlapped(this.player_grid_data);var l=this.player_grid_data.size_y;var c=this.player_grid_data.size_x;var h=this.cells_occupied_by_placeholder;var p=this;f.each(e.proxy(function(t,n){var r=e(n);var i=r.coords().grid;i.col=parseInt(i.col);i.row=parseInt(i.row);i.size_x=parseInt(i.size_x);i.size_y=parseInt(i.size_y);c=parseInt(c);l=parseInt(l);var o=h.cols[0]+c-1;var d=h.rows[0]+l-1;if(r.hasClass(p.options.static_class)){return true}if(i.size_x<=c&&i.size_y<=l){if(!p.is_swap_occupied(h.cols[0],i.row,i.size_x,i.size_y)&&!p.is_player_in(h.cols[0],i.row)&&!p.is_in_queue(h.cols[0],i.row,r)){s=p.queue_widget(h.cols[0],i.row,r)}else if(!p.is_swap_occupied(o,i.row,i.size_x,i.size_y)&&!p.is_player_in(o,i.row)&&!p.is_in_queue(o,i.row,r)){s=p.queue_widget(o,i.row,r)}else if(!p.is_swap_occupied(i.col,h.rows[0],i.size_x,i.size_y)&&!p.is_player_in(i.col,h.rows[0])&&!p.is_in_queue(i.col,h.rows[0],r)){s=p.queue_widget(i.col,h.rows[0],r)}else if(!p.is_swap_occupied(i.col,d,i.size_x,i.size_y)&&!p.is_player_in(i.col,d)&&!p.is_in_queue(i.col,d,r)){s=p.queue_widget(i.col,d,r)}else if(!p.is_swap_occupied(h.cols[0],h.rows[0],i.size_x,i.size_y)&&!p.is_player_in(h.cols[0],h.rows[0])&&!p.is_in_queue(h.cols[0],h.rows[0],r)){s=p.queue_widget(h.cols[0],h.rows[0],r)}else{for(var v=0;v<c;v++){for(var m=0;m<l;m++){var g=h.cols[0]+v;var y=h.rows[0]+m;if(!p.is_swap_occupied(g,y,i.size_x,i.size_y)&&!p.is_player_in(g,y)&&!p.is_in_queue(g,y,r)){s=p.queue_widget(g,y,r);v=c;break}}}}}else if(p.options.shift_larger_widgets_down&&!s){f.each(e.proxy(function(t,n){var r=e(n);var i=r.coords().grid;if(p.can_go_down(r)){p.move_widget_down(r,p.player_grid_data.size_y);p.set_placeholder(u,a)}}))}p.clean_up_changed()}));if(s&&this.can_placeholder_be_set(u,a,c,l)){for(var d in this.w_queue){var t=parseInt(d.split("_")[0]);var n=parseInt(d.split("_")[1]);if(this.w_queue[d]!="full"){this.new_move_widget_to(this.w_queue[d],t,n)}}this.set_placeholder(u,a)}if(!f.length){var v=this.can_go_player_up(this.player_grid_data);if(v!==false){a=v}if(this.can_placeholder_be_set(u,a,c,l)){this.set_placeholder(u,a)}}this.w_queue={};return{col:u,row:a}};o.is_swap_occupied=function(e,t,n,r){var i=false;for(var s=0;s<n;s++){for(var o=0;o<r;o++){var u=e+s;var a=t+o;var f=u+"_"+a;if(this.is_occupied(u,a)){i=true}else if(f in this.w_queue){if(this.w_queue[f]=="full"){i=true;continue}$tw=this.w_queue[f];tgd=$tw.coords().grid;if(!this.is_widget_under_player(tgd.col,tgd.row)){delete this.w_queue[f]}}if(a>parseInt(this.options.max_rows)){i=true}if(u>parseInt(this.options.max_cols)){i=true}if(this.is_player_in(u,a)){i=true}}}return i};o.can_placeholder_be_set=function(e,t,n,r){var i=true;for(var s=0;s<n;s++){for(var o=0;o<r;o++){var u=e+s;var a=t+o;var f=u+"_"+a;var l=this.is_widget(u,a);if(a>parseInt(this.options.max_rows)){i=false}if(u>parseInt(this.options.max_cols)){i=false}if(this.is_occupied(u,a)&&!this.is_widget_queued_and_can_move(l)){i=false}}}return i};o.queue_widget=function(e,t,n){var r=n;var i=r.coords().grid;var s=e+"_"+t;if(s in this.w_queue){return false}this.w_queue[s]=r;for(var o=0;o<i.size_x;o++){for(var u=0;u<i.size_y;u++){var a=e+o;var f=t+u;var l=a+"_"+f;if(l==s){continue}this.w_queue[l]="full"}}return true};o.is_widget_queued_and_can_move=function(e){var t=false;if(e===false){return false}for(var n in this.w_queue){if(this.w_queue[n]=="full"){continue}if(this.w_queue[n].attr("data-col")==e.attr("data-col")&&this.w_queue[n].attr("data-row")==e.attr("data-row")){t=true;var r=this.w_queue[n];var i=parseInt(n.split("_")[0]);var s=parseInt(n.split("_")[1]);var o=r.coords().grid;for(var u=0;u<o.size_x;u++){for(var a=0;a<o.size_y;a++){var f=i+u;var l=s+a;if(this.is_player_in(f,l)){t=false}}}}}return t};o.is_in_queue=function(e,t,n){var r=false;var i=e+"_"+t;if(i in this.w_queue){if(this.w_queue[i]=="full"){r=true}else{$tw=this.w_queue[i];tgd=$tw.coords().grid;if(!this.is_widget_under_player(tgd.col,tgd.row)){delete this.w_queue[i];r=false}else if(this.w_queue[i].attr("data-col")==n.attr("data-col")&&this.w_queue[i].attr("data-row")==n.attr("data-row")){delete this.w_queue[i];r=false}else{r=true}}}return r};o.widgets_constraints=function(t){var n=e([]);var r;var i=[];var s=[];t.each(e.proxy(function(t,r){var o=e(r);var u=o.coords().grid;if(this.can_go_widget_up(u)){n=n.add(o);i.push(u)}else{s.push(u)}},this));r=t.not(n);return{can_go_up:this.sort_by_row_asc(i),can_not_go_up:this.sort_by_row_desc(s)}};o.sort_by_row_asc=function(t){t=t.sort(function(t,n){if(!t.row){t=e(t).coords().grid;n=e(n).coords().grid}if(t.row>n.row){return 1}return-1});return t};o.sort_by_row_and_col_asc=function(e){e=e.sort(function(e,t){if(e.row>t.row||e.row===t.row&&e.col>t.col){return 1}return-1});return e};o.sort_by_col_asc=function(e){e=e.sort(function(e,t){if(e.col>t.col){return 1}return-1});return e};o.sort_by_row_desc=function(e){e=e.sort(function(e,t){if(e.row+e.size_y<t.row+t.size_y){return 1}return-1});return e};o.manage_movements=function(t,n,r){e.each(t,e.proxy(function(e,t){var i=t;var s=i.el;var o=this.can_go_widget_up(i);if(o){this.move_widget_to(s,o);this.set_placeholder(n,o+i.size_y)}else{var u=this.can_go_player_up(this.player_grid_data);if(!u){var a=r+this.player_grid_data.size_y-i.row;if(this.can_go_down(s)){console.log("In Move Down!");this.move_widget_down(s,a);this.set_placeholder(n,r)}}}},this));return this};o.is_player=function(e,t){if(t&&!this.gridmap[e]){return false}var n=t?this.gridmap[e][t]:e;return n&&(n.is(this.$player)||n.is(this.$helper))};o.is_player_in=function(t,n){var r=this.cells_occupied_by_player||{};return e.inArray(t,r.cols)>=0&&e.inArray(n,r.rows)>=0};o.is_placeholder_in=function(t,n){var r=this.cells_occupied_by_placeholder||{};return this.is_placeholder_in_col(t)&&e.inArray(n,r.rows)>=0};o.is_placeholder_in_col=function(t){var n=this.cells_occupied_by_placeholder||[];return e.inArray(t,n.cols)>=0};o.is_empty=function(e,t){if(typeof this.gridmap[e]!=="undefined"&&typeof this.gridmap[e][t]!=="undefined"&&this.gridmap[e][t]===false){return true}return false};o.is_occupied=function(e,t){if(!this.gridmap[e]){return false}if(this.gridmap[e][t]){return true}return false};o.is_widget=function(e,t){var n=this.gridmap[e];if(!n){return false}n=n[t];if(n){return n}return false};o.is_static=function(e,t){var n=this.gridmap[e];if(!n){return false}n=n[t];if(n){if(n.hasClass(this.options.static_class)){return true}}return false};o.is_widget_under_player=function(e,t){if(this.is_widget(e,t)){return this.is_player_in(e,t)}return false};o.get_widgets_under_player=function(t){t||(t=this.cells_occupied_by_player||{cols:[],rows:[]});var n=e([]);e.each(t.cols,e.proxy(function(r,i){e.each(t.rows,e.proxy(function(e,t){if(this.is_widget(i,t)){n=n.add(this.gridmap[i][t])}},this))},this));return n};o.set_placeholder=function(t,n){var r=e.extend({},this.placeholder_grid_data);var i=this.widgets_below({col:r.col,row:r.row,size_y:r.size_y,size_x:r.size_x});var s=t+parseInt(r.size_x)-1;if(s>this.cols){t=t-(s-t)}var o=this.placeholder_grid_data.row<n;var u=this.placeholder_grid_data.col!==t;this.placeholder_grid_data.col=t;this.placeholder_grid_data.row=n;this.cells_occupied_by_placeholder=this.get_cells_occupied(this.placeholder_grid_data);this.$preview_holder.attr({"data-row":n,"data-col":t});if(o||u){i.each(e.proxy(function(t,n){$w=e(n);wgd=$w.coords().grid;var r=this.can_go_widget_up(wgd);if(r){this.move_widget_to($w,r)}},this))}var a=this.get_widgets_under_player(this.cells_occupied_by_placeholder);if(a.length){a.each(e.proxy(function(t,i){var s=e(i);this.move_widget_down(s,n+r.size_y-s.data("coords").grid.row)},this))}};o.can_go_player_up=function(e){var t=e.row+e.size_y-1;var n=true;var r=[];var i=1e4;var s=this.get_widgets_under_player();this.for_each_column_occupied(e,function(e){var o=this.gridmap[e];var u=t+1;r[e]=[];while(--u>0){if(this.is_empty(e,u)||this.is_player(e,u)||this.is_widget(e,u)&&o[u].is(s)){r[e].push(u);i=u<i?u:i}else{break}}if(r[e].length===0){n=false;return true}r[e].sort()});if(!n){return false}return this.get_valid_rows(e,r,i)};o.can_go_widget_up=function(e){var t=e.row+e.size_y-1;var n=true;var r=[];var i=1e4;this.for_each_column_occupied(e,function(s){var o=this.gridmap[s];r[s]=[];var u=t+1;while(--u>0){if(this.is_widget(s,u)&&!this.is_player_in(s,u)){if(!o[u].is(e.el)){break}}if(!this.is_player(s,u)&&!this.is_placeholder_in(s,u)&&!this.is_player_in(s,u)){r[s].push(u)}if(u<i){i=u}}if(r[s].length===0){n=false;return true}r[s].sort()});if(!n){return false}return this.get_valid_rows(e,r,i)};o.get_valid_rows=function(t,n,r){var i=t.row;var s=t.row+t.size_y-1;var o=t.size_y;var u=r-1;var a=[];while(++u<=s){var f=true;e.each(n,function(t,n){if(e.isArray(n)&&e.inArray(u,n)===-1){f=false}});if(f===true){a.push(u);if(a.length===o){break}}}var l=false;if(o===1){if(a[0]!==i){l=a[0]||false}}else{if(a[0]!==i){l=this.get_consecutive_numbers_index(a,o)}}return l};o.get_consecutive_numbers_index=function(e,t){var n=e.length;var r=[];var i=true;var s=-1;for(var o=0;o<n;o++){if(i||e[o]===s+1){r.push(o);if(r.length===t){break}i=false}else{r=[];i=true}s=e[o]}return r.length>=t?e[r[0]]:false};o.get_widgets_overlapped=function(){var t;var n=e([]);var r=[];var i=this.cells_occupied_by_player.rows.slice(0);i.reverse();e.each(this.cells_occupied_by_player.cols,e.proxy(function(t,s){e.each(i,e.proxy(function(t,i){if(!this.gridmap[s]){return true}var o=this.gridmap[s][i];if(this.is_occupied(s,i)&&!this.is_player(o)&&e.inArray(o,r)===-1){n=n.add(o);r.push(o)}},this))},this));return n};o.on_start_overlapping_column=function(e){this.set_player(e,false)};o.on_start_overlapping_row=function(e){this.set_player(false,e)};o.on_stop_overlapping_column=function(e){var t=this;if(this.options.shift_larger_widgets_down){this.for_each_widget_below(e,this.cells_occupied_by_player.rows[0],function(e,n){t.move_widget_up(this,t.player_grid_data.size_y)})}};o.on_stop_overlapping_row=function(e){var t=this;var n=this.cells_occupied_by_player.cols;if(this.options.shift_larger_widgets_down){for(var r=0,i=n.length;r<i;r++){this.for_each_widget_below(n[r],e,function(e,n){console.log("from_on_stop_overlapping_row");t.move_widget_up(this,t.player_grid_data.size_y)})}}};o.new_move_widget_to=function(e,t,n){var r=this;var i=e.coords().grid;this.remove_from_gridmap(i);i.row=n;i.col=t;this.add_to_gridmap(i);e.attr("data-row",n);e.attr("data-col",t);this.update_widget_position(i,e);this.$changed=this.$changed.add(e);return this};o.move_widget_to=function(t,n){var r=this;var i=t.coords().grid;var s=n-i.row;var o=this.widgets_below(t);var u=this.can_move_to(i,i.col,n,t);if(u===false){return false}this.remove_from_gridmap(i);i.row=n;this.add_to_gridmap(i);t.attr("data-row",n);this.$changed=this.$changed.add(t);o.each(function(t,n){var i=e(n);var s=i.coords().grid;var o=r.can_go_widget_up(s);if(o&&o!==s.row){r.move_widget_to(i,o)}});return this};o.move_widget_up=function(t,n){var r=t.coords().grid;var i=r.row;var s=[];var o=true;n||(n=1);if(!this.can_go_up(t)){return false}this.for_each_column_occupied(r,function(r){if(e.inArray(t,s)===-1){var o=t.coords().grid;var u=i-n;u=this.can_go_up_to_row(o,r,u);if(!u){return true}var a=this.widgets_below(t);this.remove_from_gridmap(o);o.row=u;this.add_to_gridmap(o);t.attr("data-row",o.row);this.$changed=this.$changed.add(t);s.push(t)}})};o.move_widget_down=function(t,n){var r=t.coords().grid;var i=r.row;var s=[];var o=n;if(!t){return false}if(e.inArray(t,s)===-1){var u=t.coords().grid;var a=i+n;var f=this.widgets_below(t);this.remove_from_gridmap(u);f.each(e.proxy(function(t,n){var r=e(n);var i=r.coords().grid;var s=this.displacement_diff(i,u,o);if(s>0){this.move_widget_down(r,s)}},this));u.row=a;this.update_widget_position(u,t);t.attr("data-row",u.row);this.$changed=this.$changed.add(t);s.push(t)}};o.can_go_up_to_row=function(t,n,r){var i=this.gridmap;var s=true;var o=[];var u=t.row;var a;this.for_each_column_occupied(t,function(e){var t=i[e];o[e]=[];a=u;while(a--){if(this.is_empty(e,a)&&!this.is_placeholder_in(e,a)){o[e].push(a)}else{break}}if(!o[e].length){s=false;return true}});if(!s){return false}a=r;for(a=1;a<u;a++){var f=true;for(var l=0,c=o.length;l<c;l++){if(o[l]&&e.inArray(a,o[l])===-1){f=false}}if(f===true){s=a;break}}return s};o.displacement_diff=function(e,t,n){var r=e.row;var i=[];var s=t.row+t.size_y;this.for_each_column_occupied(e,function(e){var t=0;for(var n=s;n<r;n++){if(this.is_empty(e,n)){t=t+1}}i.push(t)});var o=Math.max.apply(Math,i);n=n-o;return n>0?n:0};o.widgets_below=function(t){var n=e.isPlainObject(t)?t:t.coords().grid;var r=this;var i=this.gridmap;var s=n.row+n.size_y-1;var o=e([]);this.for_each_column_occupied(n,function(t){r.for_each_widget_below(t,s,function(t,n){if(!r.is_player(this)&&e.inArray(this,o)===-1){o=o.add(this);return true}})});return this.sort_by_row_asc(o)};o.set_cells_player_occupies=function(e,t){this.remove_from_gridmap(this.placeholder_grid_data);this.placeholder_grid_data.col=e;this.placeholder_grid_data.row=t;this.add_to_gridmap(this.placeholder_grid_data,this.$player);return this};o.empty_cells_player_occupies=function(){this.remove_from_gridmap(this.placeholder_grid_data);return this};o.can_go_down=function(t){var n=true;var r=this;if(t.hasClass(this.options.static_class)){n=false}this.widgets_below(t).each(function(){if(e(this).hasClass(r.options.static_class)){n=false}});return n};o.can_go_up=function(e){var t=e.coords().grid;var n=t.row;var r=n-1;var i=this.gridmap;var s=[];var o=true;if(n===1){return false}this.for_each_column_occupied(t,function(e){var t=this.is_widget(e,r);if(this.is_occupied(e,r)||this.is_player(e,r)||this.is_placeholder_in(e,r)||this.is_player_in(e,r)){o=false;return true}});return o};o.can_move_to=function(e,t,n,r){var i=this.gridmap;var s=e.el;var o={size_y:e.size_y,size_x:e.size_x,col:t,row:n};var u=true;var a=t+e.size_x-1;if(a>this.cols){return false}if(r&&r<n+e.size_y-1){return false}this.for_each_cell_occupied(o,function(t,n){var r=this.is_widget(t,n);if(r&&(!e.el||r.is(s))){u=false}});return u};o.get_targeted_columns=function(e){var t=(e||this.player_grid_data.col)+(this.player_grid_data.size_x-1);var n=[];for(var r=e;r<=t;r++){n.push(r)}return n};o.get_targeted_rows=function(e){var t=(e||this.player_grid_data.row)+(this.player_grid_data.size_y-1);var n=[];for(var r=e;r<=t;r++){n.push(r)}return n};o.get_cells_occupied=function(e){var t={cols:[],rows:[]};var n;if(arguments[1]instanceof jQuery){e=arguments[1].coords().grid}for(n=0;n<e.size_x;n++){var r=e.col+n;t.cols.push(r)}for(n=0;n<e.size_y;n++){var i=e.row+n;t.rows.push(i)}return t};o.for_each_cell_occupied=function(e,t){this.for_each_column_occupied(e,function(n){this.for_each_row_occupied(e,function(e){t.call(this,n,e)})});return this};o.for_each_column_occupied=function(e,t){for(var n=0;n<e.size_x;n++){var r=e.col+n;t.call(this,r,e)}};o.for_each_row_occupied=function(e,t){for(var n=0;n<e.size_y;n++){var r=e.row+n;t.call(this,r,e)}};o.clean_up_changed=function(){$gr=this;$gr.$changed.each(function(){if($gr.options.shift_larger_widgets_down){$gr.move_widget_up(e(this))}})};o._traversing_widgets=function(t,n,r,i,s){var o=this.gridmap;if(!o[r]){return}var u,a;var f=t+"/"+n;if(arguments[2]instanceof jQuery){var l=arguments[2].coords().grid;r=l.col;i=l.row;s=arguments[3]}var c=[];var h=i;var p={"for_each/above":function(){while(h--){if(h>0&&this.is_widget(r,h)&&e.inArray(o[r][h],c)===-1){u=s.call(o[r][h],r,h);c.push(o[r][h]);if(u){break}}}},"for_each/below":function(){for(h=i+1,a=o[r].length;h<a;h++){if(this.is_widget(r,h)&&e.inArray(o[r][h],c)===-1){u=s.call(o[r][h],r,h);c.push(o[r][h])}}}};if(p[f]){p[f].call(this)}};o.for_each_widget_above=function(e,t,n){this._traversing_widgets("for_each","above",e,t,n);return this};o.for_each_widget_below=function(e,t,n){this._traversing_widgets("for_each","below",e,t,n);return this};o.get_highest_occupied_cell=function(){var e;var t=this.gridmap;var n=[];var r=[];for(var i=t.length-1;i>=1;i--){for(e=t[i].length-1;e>=1;e--){if(this.is_widget(i,e)){n.push(e);r[e]=i;break}}}var s=Math.max.apply(Math,n);this.highest_occupied_cell={col:r[s],row:s};return this.highest_occupied_cell};o.get_widgets_from=function(t,n){var r=this.gridmap;var i=e();if(t){i=i.add(this.$widgets.filter(function(){var n=e(this).attr("data-col");return n===t||n>t}))}if(n){i=i.add(this.$widgets.filter(function(){var t=e(this).attr("data-row");return t===n||t>n}))}return i};o.set_dom_grid_height=function(){var e=this.get_highest_occupied_cell().row;this.$el.css("height",e*this.min_widget_height);return this};o.generate_stylesheet=function(t){var n="";var r=this.options.max_size_x;var i=0;var o=0;var u;var a;t||(t={});t.cols||(t.cols=this.cols);t.rows||(t.rows=this.rows);t.namespace||(t.namespace=this.options.namespace);t.widget_base_dimensions||(t.widget_base_dimensions=this.options.widget_base_dimensions);t.widget_margins||(t.widget_margins=this.options.widget_margins);t.min_widget_width=t.widget_margins[0]*2+t.widget_base_dimensions[0];t.min_widget_height=t.widget_margins[1]*2+t.widget_base_dimensions[1];var f=e.param(t);if(e.inArray(f,s.generated_stylesheets)>=0){return false}s.generated_stylesheets.push(f);for(u=t.cols;u>=0;u--){n+=t.namespace+' [data-col="'+(u+1)+'"] { left:'+(u*t.widget_base_dimensions[0]+u*t.widget_margins[0]+(u+1)*t.widget_margins[0])+"px;} "}for(u=t.rows;u>=0;u--){n+=t.namespace+' [data-row="'+(u+1)+'"] { top:'+(u*t.widget_base_dimensions[1]+u*t.widget_margins[1]+(u+1)*t.widget_margins[1])+"px;} "}for(var l=1;l<=t.rows;l++){n+=t.namespace+' [data-sizey="'+l+'"] { height:'+(l*t.widget_base_dimensions[1]+(l-1)*t.widget_margins[1]*2)+"px;}"}for(var c=1;c<=r;c++){n+=t.namespace+' [data-sizex="'+c+'"] { width:'+(c*t.widget_base_dimensions[0]+(c-1)*t.widget_margins[0]*2)+"px;}"}return this.add_style_tag(n)};o.add_style_tag=function(e){var t=n;var r=t.createElement("style");t.getElementsByTagName("head")[0].appendChild(r);r.setAttribute("type","text/css");if(r.styleSheet){r.styleSheet.cssText=e}else{r.appendChild(n.createTextNode(e))}return this};o.generate_faux_grid=function(e,t){this.faux_grid=[];this.gridmap=[];var n;var r;for(n=t;n>0;n--){this.gridmap[n]=[];for(r=e;r>0;r--){this.add_faux_cell(r,n)}}return this};o.add_faux_cell=function(t,n){var r=e({left:this.baseX+(n-1)*this.min_widget_width,top:this.baseY+(t-1)*this.min_widget_height,width:this.min_widget_width,height:this.min_widget_height,col:n,row:t,original_col:n,original_row:t}).coords();if(!e.isArray(this.gridmap[n])){this.gridmap[n]=[]}this.gridmap[n][t]=false;this.faux_grid.push(r);return this};o.add_faux_rows=function(e){var t=this.rows;var n=t+(e||1);for(var r=n;r>t;r--){for(var i=this.cols;i>=1;i--){this.add_faux_cell(r,i)}}this.rows=n;if(this.options.autogenerate_stylesheet){this.generate_stylesheet()}return this};o.add_faux_cols=function(e){var t=this.cols;var n=t+(e||1);for(var r=t;r<n;r++){for(var i=this.rows;i>=1;i--){this.add_faux_cell(i,r)}}this.cols=n;if(this.options.autogenerate_stylesheet){this.generate_stylesheet()}return this};o.recalculate_faux_grid=function(){var n=this.$wrapper.width();this.baseX=(e(t).width()-n)/2;this.baseY=this.$wrapper.offset().top;e.each(this.faux_grid,e.proxy(function(e,t){this.faux_grid[e]=t.update({left:this.baseX+(t.data.col-1)*this.min_widget_width,top:this.baseY+(t.data.row-1)*this.min_widget_height})},this));return this};o.get_widgets_from_DOM=function(){this.$widgets.each(e.proxy(function(t,n){this.register_widget(e(n))},this));return this};o.generate_grid_and_stylesheet=function(){var n=this.$wrapper.width();var r=this.$wrapper.height();var i=Math.floor(n/this.min_widget_width)+this.options.extra_cols;var s=this.$widgets.map(function(){return e(this).attr("data-col")});s=Array.prototype.slice.call(s,0);s.length||(s=[0]);var o=Math.max.apply(Math,s);var u=this.options.extra_rows;this.$widgets.each(function(t,n){u+=+e(n).attr("data-sizey")});this.cols=Math.max(o,i,this.options.min_cols);this.rows=this.options.max_rows;this.baseX=(e(t).width()-n)/2;this.baseY=this.$wrapper.offset().top;if(this.options.autogenerate_stylesheet){this.generate_stylesheet()}return this.generate_faux_grid(this.rows,this.cols)};e.fn.gridster=function(t){return this.each(function(){if(!e(this).data("gridster")){e(this).data("gridster",new s(this,t))}})};e.Gridster=o})(jQuery,window,document)