pyk 0.2.6 → 0.2.7

Sign up to get free protection for your applications and to get access to all the features.
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)