puffer 0.0.32 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (117) hide show
  1. data/.gitignore +7 -0
  2. data/Gemfile +1 -26
  3. data/Gemfile.lock +66 -64
  4. data/README.md +34 -23
  5. data/Rakefile +1 -11
  6. data/VERSION +1 -1
  7. data/app/assets/javascripts/puffer/application.js +6 -1
  8. data/app/assets/javascripts/puffer/associations.js +18 -0
  9. data/app/assets/javascripts/puffer/puffer.js +7 -0
  10. data/app/assets/javascripts/puffer/right-calendar-src.js +19 -3
  11. data/app/assets/javascripts/puffer/right-dnd-src.js +591 -0
  12. data/app/assets/javascripts/puffer/right-in-edit-src.js +373 -0
  13. data/app/assets/javascripts/puffer/right-keys-src.js +87 -0
  14. data/app/assets/javascripts/puffer/{paginator.js → right-paginator-src.js} +0 -0
  15. data/app/assets/javascripts/puffer/right-slider-src.js +29 -32
  16. data/app/assets/javascripts/puffer/right-sortable-src.js +430 -0
  17. data/app/assets/javascripts/puffer/right-src.js +358 -99
  18. data/app/assets/stylesheets/puffer/puffer.css +29 -4
  19. data/app/components/base/form.html.erb +8 -14
  20. data/app/components/base_component.rb +1 -1
  21. data/app/components/boolean/form.html.erb +5 -3
  22. data/app/components/boolean/index.html.erb +6 -2
  23. data/app/components/boolean_component.rb +2 -2
  24. data/app/components/date_time/filter.html.erb +9 -0
  25. data/app/components/date_time/form.html.erb +8 -4
  26. data/app/components/date_time_component.rb +21 -5
  27. data/app/components/file/form.html.erb +8 -4
  28. data/app/components/hidden/form.html.erb +3 -1
  29. data/app/components/nested_attributes_many/form.html.erb +47 -0
  30. data/app/components/nested_attributes_many_component.rb +7 -0
  31. data/app/components/nested_attributes_one/form.html.erb +48 -0
  32. data/app/components/nested_attributes_one_component.rb +7 -0
  33. data/app/components/password/form.html.erb +8 -4
  34. data/app/components/password_component.rb +1 -1
  35. data/app/components/references_many/index.html.erb +1 -1
  36. data/app/components/references_one/choose.html.erb +1 -1
  37. data/app/components/references_one/form.html.erb +10 -9
  38. data/app/components/references_one_component.rb +0 -1
  39. data/app/components/render_component.rb +13 -0
  40. data/app/components/select/filter.html.erb +4 -2
  41. data/app/components/select/form.html.erb +8 -4
  42. data/app/components/text/form.html.erb +8 -4
  43. data/app/controllers/admin/sessions_controller.rb +1 -21
  44. data/app/controllers/puffer/base.rb +10 -3
  45. data/app/controllers/puffer/dashboard_base.rb +7 -1
  46. data/app/controllers/puffer/{sessions_base.rb → sessions/base.rb} +10 -7
  47. data/app/controllers/puffer/sessions/clearance.rb +29 -0
  48. data/app/controllers/puffer/{sessions_devise_base.rb → sessions/devise.rb} +1 -1
  49. data/app/controllers/puffer/sessions/simple.rb +28 -0
  50. data/app/controllers/puffer/tree_base.rb +1 -1
  51. data/app/models/puffer_user.rb +3 -0
  52. data/app/views/layouts/puffer.html.erb +3 -3
  53. data/app/views/puffer/base/_edit.html.erb +15 -0
  54. data/app/views/puffer/base/_index.html.erb +26 -0
  55. data/app/views/puffer/base/_show.html.erb +13 -0
  56. data/app/views/puffer/base/_table.html.erb +1 -1
  57. data/app/views/puffer/base/edit.html.erb +1 -15
  58. data/app/views/puffer/base/edit.js.erb +1 -0
  59. data/app/views/puffer/base/index.html.erb +1 -20
  60. data/app/views/puffer/base/index.js.erb +1 -0
  61. data/app/views/puffer/base/new.html.erb +1 -1
  62. data/app/views/puffer/base/show.html.erb +1 -22
  63. data/app/views/puffer/base/show.js.erb +1 -0
  64. data/app/views/puffer/base/update.js.erb +1 -0
  65. data/app/views/puffer/sessions/base/new.html.erb +11 -0
  66. data/app/views/puffer/tree_base/_record.html.erb +1 -1
  67. data/lib/puffer/component.rb +14 -47
  68. data/lib/puffer/controller/auth.rb +13 -9
  69. data/lib/puffer/controller/config.rb +18 -0
  70. data/lib/puffer/controller/mutate.rb +8 -8
  71. data/lib/puffer/engine.rb +5 -0
  72. data/lib/puffer/field.rb +5 -11
  73. data/lib/puffer/filters.rb +86 -56
  74. data/lib/puffer/helpers/component_helper.rb +24 -0
  75. data/lib/puffer/helpers/puffer_helper.rb +65 -0
  76. data/lib/puffer/helpers/puffer_tree_helper.rb +19 -0
  77. data/lib/puffer/orm_adapter/active_record.rb +40 -11
  78. data/lib/puffer/orm_adapter/base.rb +9 -0
  79. data/lib/puffer/orm_adapter/mongoid.rb +32 -9
  80. data/lib/puffer/resource/node.rb +2 -2
  81. data/lib/puffer/resource/routing.rb +30 -16
  82. data/lib/puffer/resource.rb +20 -20
  83. data/lib/puffer/version.rb +3 -0
  84. data/lib/puffer.rb +26 -5
  85. data/puffer.gemspec +34 -296
  86. data/spec/app/components/base_component_spec.rb +1 -1
  87. data/spec/app/components/boolean_component_spec.rb +2 -0
  88. data/spec/app/components/date_time_component_spec.rb +1 -0
  89. data/spec/app/components/file_component_spec.rb +1 -0
  90. data/spec/app/components/hidden_component_spec.rb +1 -0
  91. data/spec/app/components/password_component_spec.rb +2 -0
  92. data/spec/app/components/select_component_spec.rb +1 -0
  93. data/spec/app/components/string_component_spec.rb +1 -0
  94. data/spec/app/components/text_component_spec.rb +1 -0
  95. data/spec/dummy/app/controllers/admin/news_controller.rb +2 -0
  96. data/spec/dummy/app/controllers/admin/profiles_controller.rb +1 -1
  97. data/spec/dummy/app/controllers/admin/users_controller.rb +2 -0
  98. data/spec/dummy/app/controllers/orms/active_record_orm_primals_controller.rb +8 -0
  99. data/spec/dummy/app/helpers/news_helper.rb +7 -0
  100. data/spec/dummy/app/models/active_record_orm/has_many_reference.rb +5 -0
  101. data/spec/dummy/app/models/active_record_orm/has_one_reference.rb +5 -0
  102. data/spec/dummy/app/models/active_record_orm/primal.rb +4 -0
  103. data/spec/dummy/config/environments/development.rb +1 -1
  104. data/spec/dummy/db/migrate/20111120144025_create_active_record_orm_has_one_references.rb +10 -0
  105. data/spec/dummy/db/migrate/20111122203304_create_active_record_orm_has_many_references.rb +10 -0
  106. data/spec/dummy/db/schema.rb +15 -1
  107. data/spec/helpers/puffer_helper_spec.rb +1 -1
  108. data/spec/lib/fields_spec.rb +0 -9
  109. data/spec/lib/filters_spec.rb +4 -8
  110. data/spec/lib/orm_adapter/base_shared.rb +22 -0
  111. data/spec/spec_helper.rb +1 -1
  112. metadata +89 -60
  113. data/app/components/string/form.html.erb +0 -5
  114. data/app/helpers/puffer_helper.rb +0 -51
  115. data/app/helpers/puffer_tree_helper.rb +0 -15
  116. data/app/views/puffer/sessions_base/new.html.erb +0 -11
  117. data/lib/puffer/extensions/form.rb +0 -16
@@ -0,0 +1,591 @@
1
+ /**
2
+ * Drag'n'Drop module v2.2.2
3
+ * http://rightjs.org/plugins/drag-n-drop
4
+ *
5
+ * Copyright (C) 2009-2011 Nikolay Nemshilov
6
+ */
7
+ (function(window, document, RightJS) {
8
+ /**
9
+ * The DND module initialization script
10
+ *
11
+ * Copyright (C) 2010 Nikolay Nemshilov
12
+ */
13
+ var R = RightJS,
14
+ $ = RightJS.$,
15
+ $w = RightJS.$w,
16
+ Class = RightJS.Class,
17
+ isHash = RightJS.isHash,
18
+ isArray = RightJS.isArray,
19
+ Element = RightJS.Element,
20
+ Observer = RightJS.Observer;
21
+
22
+
23
+
24
+ /**
25
+ * Draggable unit
26
+ *
27
+ * Copyright (C) 2009-2011 Nikolay Nemshilov
28
+ */
29
+ var Draggable = new Class(Observer, {
30
+ extend: {
31
+ version: '2.2.2',
32
+
33
+ EVENTS: $w('before start drag stop drop'),
34
+
35
+ Options: {
36
+ handle: null, // a handle element that will start the drag
37
+
38
+ snap: 0, // a number in pixels or [x,y]
39
+ axis: null, // null or 'x' or 'y' or 'vertical' or 'horizontal'
40
+ range: null, // {x: [min, max], y:[min, max]} or reference to another element
41
+
42
+ dragClass: 'dragging', // the in-process class name
43
+
44
+ clone: false, // if should keep a clone in place
45
+ revert: false, // marker if the object should be moved back on finish
46
+ revertDuration: 'normal', // the moving back fx duration
47
+
48
+ scroll: true, // if it should automatically scroll
49
+ scrollSensitivity: 32, // the scrolling area size in pixels
50
+
51
+ zIndex: 10000000, // the element's z-index
52
+ moveOut: false, // marker if the draggable should be moved out of it's context (for overflown elements)
53
+
54
+ relName: 'draggable' // the audodiscovery feature key
55
+ },
56
+
57
+ // referenece to the currently active draggable
58
+ current: null,
59
+
60
+ // scans the document for auto-processed draggables with the rel="draggable" attribute
61
+ rescan: function(scope) {
62
+ var key = this.Options.relName, ref = this === Draggable ? 'draggable' : 'droppable';
63
+
64
+ ($(scope)||$(document)).find('*[rel^="'+key+'"]').each(function(element) {
65
+ if (!element[ref]) {
66
+ new this(element, new Function('return '+element.get('data-'+key))() || {});
67
+ }
68
+ }, this);
69
+ }
70
+ },
71
+
72
+ /**
73
+ * Basic controller
74
+ *
75
+ * @param mixed element reference
76
+ * @param Object options
77
+ */
78
+ initialize: function(element, options) {
79
+ this.element = $(element);
80
+ this.$super(options);
81
+
82
+ this._dragStart = R(this.dragStart).bind(this);
83
+ this.handle.onMousedown(this._dragStart);
84
+
85
+ this.element.draggable = this;
86
+ },
87
+
88
+ /**
89
+ * detaches the mouse observers out of the draggable element
90
+ *
91
+ * @return this
92
+ */
93
+ destroy: function() {
94
+ this.handle.stopObserving('mousedown', this._dragStart);
95
+ delete(this.element.draggable);
96
+
97
+ return this;
98
+ },
99
+
100
+ // additional options processing
101
+ setOptions: function(options) {
102
+ this.$super(options);
103
+
104
+ // checking the handle
105
+ this.handle = this.options.handle ? $(this.options.handle) : this.element;
106
+
107
+ // checking the spappings
108
+ if (isArray(this.options.snap)) {
109
+ this.snapX = this.options.snap[0];
110
+ this.snapY = this.options.snap[1];
111
+ } else {
112
+ this.snapX = this.snapY = this.options.snap;
113
+ }
114
+
115
+ return this;
116
+ },
117
+
118
+ /**
119
+ * Moves the element back to the original position
120
+ *
121
+ * @return this
122
+ */
123
+ revert: function() {
124
+ var position = this.clone.position();
125
+ var end_style = {
126
+ top: (position.y + this.ryDiff) + 'px',
127
+ left: (position.x + this.rxDiff) + 'px'
128
+ };
129
+
130
+ if (this.options.revertDuration && this.element.morph) {
131
+ this.element.morph(end_style, {
132
+ duration: this.options.revertDuration,
133
+ onFinish: R(this.swapBack).bind(this)
134
+ });
135
+ } else {
136
+ this.element.setStyle(end_style);
137
+ this.swapBack();
138
+ }
139
+
140
+ return this;
141
+ },
142
+
143
+ // protected
144
+
145
+ // handles the event start
146
+ dragStart: function(event) {
147
+ if (this._drag) { return false; } else { this._drag = true; }
148
+
149
+ this.fire('before', this, event.stop());
150
+
151
+ // calculating the positions diff
152
+ var position = this.element.position();
153
+
154
+ this.xDiff = event.pageX - position.x;
155
+ this.yDiff = event.pageY - position.y;
156
+
157
+ // grabbing the relative position diffs for nested spaces
158
+ this.rxDiff = this.ryDiff = 0;
159
+ this.element.parents().reverse().each(function(parent) {
160
+ if (parent.getStyle('position') !== 'static') {
161
+ parent = parent.position();
162
+
163
+ this.rxDiff = - parent.x;
164
+ this.ryDiff = - parent.y;
165
+ }
166
+ }, this);
167
+
168
+ // preserving the element sizes
169
+ var size = {
170
+ x: this.element.getStyle('width'),
171
+ y: this.element.getStyle('height')
172
+ };
173
+
174
+ if (size.x == 'auto') { size.x = this.element._.offsetWidth + 'px'; }
175
+ if (size.y == 'auto') { size.y = this.element._.offsetHeight + 'px'; }
176
+
177
+ // building a clone element if necessary
178
+ if (this.options.clone || this.options.revert) {
179
+ this.clone = new Element(this.element._.cloneNode(true)).setStyle({
180
+ visibility: this.options.clone ? 'visible' : 'hidden'
181
+ }).insertTo(this.element, 'before');
182
+ }
183
+
184
+ // reinserting the element to the body so it was over all the other elements
185
+ this.element.setStyle({
186
+ position: 'absolute',
187
+ zIndex: Draggable.Options.zIndex++,
188
+ top: (position.y + this.ryDiff) + 'px',
189
+ left: (position.x + this.rxDiff) + 'px',
190
+ width: size.x,
191
+ height: size.y
192
+ }).addClass(this.options.dragClass);
193
+
194
+ if (this.options.moveOut) {
195
+ this.element.insertTo(document.body);
196
+ }
197
+
198
+ // caching the window scrolls
199
+ this.winScrolls = $(window).scrolls();
200
+ this.winSizes = $(window).size();
201
+
202
+ Draggable.current = this.calcConstraints().fire('start', this, event);
203
+
204
+ this.style = this.element._.style;
205
+ },
206
+
207
+ // catches the mouse move event
208
+ dragProcess: function(event) {
209
+ var page_x = event.pageX, page_y = event.pageY, x = page_x - this.xDiff, y = page_y - this.yDiff;
210
+
211
+ // checking the range
212
+ if (this.ranged) {
213
+ if (this.minX > x) { x = this.minX; }
214
+ if (this.maxX < x) { x = this.maxX; }
215
+ if (this.minY > y) { y = this.minY; }
216
+ if (this.maxY < y) { y = this.maxY; }
217
+ }
218
+
219
+ // checking the scrolls
220
+ if (this.options.scroll) {
221
+ var scrolls = {x: this.winScrolls.x, y: this.winScrolls.y},
222
+ sensitivity = this.options.scrollSensitivity;
223
+
224
+ if ((page_y - scrolls.y) < sensitivity) {
225
+ scrolls.y = page_y - sensitivity;
226
+ } else if ((scrolls.y + this.winSizes.y - page_y) < sensitivity){
227
+ scrolls.y = page_y - this.winSizes.y + sensitivity;
228
+ }
229
+
230
+ if ((page_x - scrolls.x) < sensitivity) {
231
+ scrolls.x = page_x - sensitivity;
232
+ } else if ((scrolls.x + this.winSizes.x - page_x) < sensitivity){
233
+ scrolls.x = page_x - this.winSizes.x + sensitivity;
234
+ }
235
+
236
+ if (scrolls.y < 0) { scrolls.y = 0; }
237
+ if (scrolls.x < 0) { scrolls.x = 0; }
238
+
239
+ if (scrolls.y < this.winScrolls.y || scrolls.y > this.winScrolls.y ||
240
+ scrolls.x < this.winScrolls.x || scrolls.x > this.winScrolls.x) {
241
+
242
+ $(window).scrollTo(this.winScrolls = scrolls);
243
+ }
244
+ }
245
+
246
+ // checking the snaps
247
+ if (this.snapX) { x = x - x % this.snapX; }
248
+ if (this.snapY) { y = y - y % this.snapY; }
249
+
250
+ // checking the constraints
251
+ if (!this.axisY) { this.style.left = (x + this.rxDiff) + 'px'; }
252
+ if (!this.axisX) { this.style.top = (y + this.ryDiff) + 'px'; }
253
+
254
+ this.fire('drag', this, event);
255
+ },
256
+
257
+ // handles the event stop
258
+ dragStop: function(event) {
259
+ this.element.removeClass(this.options.dragClass);
260
+
261
+ // notifying the droppables for the drop
262
+ Droppable.checkDrop(event, this);
263
+
264
+ if (this.options.revert) {
265
+ this.revert();
266
+ } else {
267
+ this._drag = false;
268
+ }
269
+
270
+ Draggable.current = null;
271
+
272
+ this.fire('stop', this, event);
273
+ },
274
+
275
+ // swaps the clone element to the actual element back
276
+ swapBack: function() {
277
+ if (this.clone) {
278
+ this.clone.replace(
279
+ this.element.setStyle({
280
+ width: this.clone.getStyle('width'),
281
+ height: this.clone.getStyle('height'),
282
+ position: this.clone.getStyle('position'),
283
+ zIndex: this.clone.getStyle('zIndex') || ''
284
+ })
285
+ );
286
+ }
287
+ this._drag = false;
288
+ },
289
+
290
+ // calculates the constraints
291
+ calcConstraints: function() {
292
+ var axis = this.options.axis;
293
+ this.axisX = R(['x', 'horizontal']).include(axis);
294
+ this.axisY = R(['y', 'vertical']).include(axis);
295
+
296
+ this.ranged = false;
297
+ var range = this.options.range;
298
+ if (range) {
299
+ this.ranged = true;
300
+
301
+ // if the range is defined by another element
302
+ var element = $(range);
303
+ if (element instanceof Element) {
304
+ var dims = element.dimensions();
305
+
306
+ range = {
307
+ x: [dims.left, dims.left + dims.width],
308
+ y: [dims.top, dims.top + dims.height]
309
+ };
310
+ }
311
+
312
+ if (isHash(range)) {
313
+ var size = this.element.size();
314
+
315
+ if (range.x) {
316
+ this.minX = range.x[0];
317
+ this.maxX = range.x[1] - size.x;
318
+ }
319
+ if (range.y) {
320
+ this.minY = range.y[0];
321
+ this.maxY = range.y[1] - size.y;
322
+ }
323
+ }
324
+ }
325
+
326
+ return this;
327
+ }
328
+ });
329
+
330
+ /**
331
+ * Droppable unit
332
+ *
333
+ * Copyright (C) 2009-2010 Nikolay Nemshilov
334
+ */
335
+ var Droppable = new Class(Observer, {
336
+ extend: {
337
+ EVENTS: $w('drop hover leave'),
338
+
339
+ Options: {
340
+ accept: '*',
341
+ containment: null, // the list of elements (or ids) that should to be accepted
342
+
343
+ overlap: null, // 'x', 'y', 'horizontal', 'vertical', 'both' makes it respond only if the draggable overlaps the droppable
344
+ overlapSize: 0.5, // the overlapping level 0 for nothing 1 for the whole thing
345
+
346
+ allowClass: 'droppable-allow',
347
+ denyClass: 'droppable-deny',
348
+
349
+ relName: 'droppable' // automatically discovered feature key
350
+ },
351
+
352
+ // See the Draggable rescan method, case we're kinda hijacking it in here
353
+ rescan: Draggable.rescan,
354
+
355
+ /**
356
+ * Checks for hoverting draggable
357
+ *
358
+ * @param Event mouse event
359
+ * @param Draggable draggable
360
+ */
361
+ checkHover: function(event, draggable) {
362
+ for (var i=0, length = this.active.length; i < length; i++) {
363
+ this.active[i].checkHover(event, draggable);
364
+ }
365
+ },
366
+
367
+ /**
368
+ * Checks for a drop
369
+ *
370
+ * @param Event mouse event
371
+ * @param Draggable draggable
372
+ */
373
+ checkDrop: function(event, draggable) {
374
+ for (var i=0, length = this.active.length; i < length; i++) {
375
+ this.active[i].checkDrop(event, draggable);
376
+ }
377
+ },
378
+
379
+ active: []
380
+ },
381
+
382
+ /**
383
+ * Basic cosntructor
384
+ *
385
+ * @param mixed the draggable element reference
386
+ * @param Object options
387
+ */
388
+ initialize: function(element, options) {
389
+ this.element = $(element);
390
+ this.$super(options);
391
+
392
+ Droppable.active.push(this.element._droppable = this);
393
+ },
394
+
395
+ /**
396
+ * Detaches the attached events
397
+ *
398
+ * @return self
399
+ */
400
+ destroy: function() {
401
+ Droppable.active = Droppable.active.without(this);
402
+ delete(this.element.droppable);
403
+ return this;
404
+ },
405
+
406
+ /**
407
+ * checks the event for hovering
408
+ *
409
+ * @param Event mouse event
410
+ * @param Draggable the draggable object
411
+ */
412
+ checkHover: function(event, draggable) {
413
+ if (this.hoveredBy(event, draggable)) {
414
+ if (!this._hovered) {
415
+ this._hovered = true;
416
+ this.element.addClass(this.options[this.allows(draggable) ? 'allowClass' : 'denyClass']);
417
+ this.fire('hover', draggable, this, event);
418
+ }
419
+ } else if (this._hovered) {
420
+ this._hovered = false;
421
+ this.reset().fire('leave', draggable, this, event);
422
+ }
423
+ },
424
+
425
+ /**
426
+ * Checks if it should process the drop from draggable
427
+ *
428
+ * @param Event mouse event
429
+ * @param Draggable draggable
430
+ */
431
+ checkDrop: function(event, draggable) {
432
+ this.reset();
433
+ if (this.hoveredBy(event, draggable) && this.allows(draggable)) {
434
+ draggable.fire('drop', this, draggable, event);
435
+ this.fire('drop', draggable, this, event);
436
+ }
437
+ },
438
+
439
+ /**
440
+ * resets the element state
441
+ *
442
+ * @return self
443
+ */
444
+ reset: function() {
445
+ this.element.removeClass(this.options.allowClass).removeClass(this.options.denyClass);
446
+ return this;
447
+ },
448
+
449
+ // protected
450
+
451
+ // checks if the element is hovered by the event
452
+ hoveredBy: function(event, draggable) {
453
+ var dims = this.element.dimensions(),
454
+ t_top = dims.top,
455
+ t_left = dims.left,
456
+ t_right = dims.left + dims.width,
457
+ t_bottom = dims.top + dims.height,
458
+ event_x = event.pageX,
459
+ event_y = event.pageY;
460
+
461
+ // checking the overlapping
462
+ if (this.options.overlap) {
463
+ var drag_dims = draggable.element.dimensions(),
464
+ level = this.options.overlapSize,
465
+ top = drag_dims.top,
466
+ left = drag_dims.left,
467
+ right = drag_dims.left + drag_dims.width,
468
+ bottom = drag_dims.top + drag_dims.height;
469
+
470
+
471
+ switch (this.options.overlap) {
472
+ // horizontal overlapping only check
473
+ case 'x':
474
+ case 'horizontal':
475
+ return (
476
+ (top > t_top && top < t_bottom) ||
477
+ (bottom > t_top && bottom < t_bottom)
478
+ ) && (
479
+ (left > t_left && left < (t_right - dims.width * level)) ||
480
+ (right < t_right && right > (t_left + dims.width * level))
481
+ );
482
+
483
+ // vertical overlapping only check
484
+ case 'y':
485
+ case 'vertical':
486
+ return (
487
+ (left > t_left && left < t_right) ||
488
+ (right > t_left && right < t_right)
489
+ ) && (
490
+ (top > t_top && top < (t_bottom - dims.height * level)) ||
491
+ (bottom < t_bottom && bottom > (t_top + dims.height * level))
492
+ );
493
+
494
+ // both overlaps check
495
+ default:
496
+ return (
497
+ (left > t_left && left < (t_right - dims.width * level)) ||
498
+ (right < t_right && right > (t_left + dims.width * level))
499
+ ) && (
500
+ (top > t_top && top < (t_bottom - dims.height * level)) ||
501
+ (bottom < t_bottom && bottom > (t_top + dims.height * level))
502
+ );
503
+ }
504
+
505
+ } else {
506
+ // simple check agains the event position
507
+ return event_x > t_left && event_x < t_right && event_y > t_top && event_y < t_bottom;
508
+ }
509
+ },
510
+
511
+ // checks if the object accepts the draggable
512
+ allows: function(draggable) {
513
+ if (this.options.containment && !this._scanned) {
514
+ this.options.containment = R(this.options.containment).map($);
515
+ this._scanned = true;
516
+ }
517
+
518
+ // checking the invitations list
519
+ var welcomed = this.options.containment ? this.options.containment.includes(draggable.element) : true;
520
+
521
+ return welcomed && (this.options.accept == '*' ? true : draggable.element.match(this.options.accept));
522
+ }
523
+
524
+ });
525
+
526
+ /**
527
+ * The document events hooker
528
+ *
529
+ * Copyright (C) 2009-2011 Nikolay Nemshilov
530
+ */
531
+ $(document).on({
532
+ // parocesses the automatically discovered elements
533
+ ready: function() {
534
+ Draggable.rescan();
535
+ Droppable.rescan();
536
+ },
537
+
538
+ // watch the draggables moving arond
539
+ mousemove: function(event) {
540
+ if (Draggable.current !== null) {
541
+ Draggable.current.dragProcess(event);
542
+ Droppable.checkHover(event, Draggable.current);
543
+ }
544
+ },
545
+
546
+ // releases the current draggable on mouse up
547
+ mouseup: function(event) {
548
+ if (Draggable.current !== null) {
549
+ Draggable.current.dragStop(event);
550
+ }
551
+ }
552
+ });
553
+
554
+ /**
555
+ * Element level hooks for drag'n'drops
556
+ *
557
+ * Copyright (C) 2009-2010 Nikolay Nemshilov
558
+ */
559
+ Element.include({
560
+
561
+ makeDraggable: function(options) {
562
+ new Draggable(this, options);
563
+ return this;
564
+ },
565
+
566
+ undoDraggable: function() {
567
+ if ('draggable' in this) {
568
+ this.draggable.destroy();
569
+ }
570
+
571
+ return this;
572
+ },
573
+
574
+ makeDroppable: function(options) {
575
+ new Droppable(this, options);
576
+ return this;
577
+ },
578
+
579
+ undoDroppable: function() {
580
+ if ('droppable' in this) {
581
+ this.droppable.destroy();
582
+ }
583
+
584
+ return this;
585
+ }
586
+
587
+ });
588
+
589
+ window.Draggable = RightJS.Draggable = Draggable;
590
+ window.Droppable = RightJS.Droppable = Droppable;
591
+ })(window, document, RightJS);