jquery-dragdrop-rails 2.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/.gitignore ADDED
@@ -0,0 +1,18 @@
1
+ .idea/
2
+ *.gem
3
+ *.rbc
4
+ .bundle
5
+ .config
6
+ .yardoc
7
+ Gemfile.lock
8
+ InstalledFiles
9
+ _yardoc
10
+ coverage
11
+ doc/
12
+ lib/bundler/man
13
+ pkg
14
+ rdoc
15
+ spec/reports
16
+ test/tmp
17
+ test/version_tmp
18
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in jquery-dragdrop-rails.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Aki Atoji
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,31 @@
1
+ # Jquery::Dragdrop::Rails
2
+
3
+ This is a simple integration for ThreeDubMedia's jquery.event.drag and jquery.event.drop plugins for Rails 3.x.
4
+
5
+
6
+ ## Installation
7
+
8
+ Add this line to your application's Gemfile:
9
+
10
+ gem 'jquery-dragdrop-rails'
11
+
12
+ And then execute:
13
+
14
+ $ bundle
15
+
16
+ Or install it yourself as:
17
+
18
+ $ gem install jquery-dragdrop-rails
19
+
20
+
21
+ ## Usage
22
+
23
+
24
+
25
+ ## Contributing
26
+
27
+ 1. Fork it
28
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
29
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
30
+ 4. Push to the branch (`git push origin my-new-feature`)
31
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,22 @@
1
+ # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'jquery-dragdrop-rails/version'
5
+
6
+ Gem::Specification.new do |gem|
7
+ gem.name = "jquery-dragdrop-rails"
8
+ gem.version = Jquery::Dragdrop::Rails::VERSION
9
+ gem.authors = ["Aki Atoji"]
10
+ gem.email = ["akiatoji@gmail.com"]
11
+ gem.description = %q{jQuery Drag Drop wrapper}
12
+ gem.summary = %q{Wraps ThreeDubMedia's jquery.event.drag and jquery.event.drop plugins for Rails}
13
+ gem.homepage = "http://github.dom/akiatoji/jquery-dragdrop-rails"
14
+
15
+ gem.add_dependency "railties", "~> 3.0"
16
+ gem.add_dependency "jquery-rails"
17
+
18
+ gem.files = `git ls-files`.split($/)
19
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
20
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
21
+ gem.require_paths = ["lib"]
22
+ end
@@ -0,0 +1,7 @@
1
+ module Jquery
2
+ module Dragdrop
3
+ module Rails
4
+ VERSION = "2.2.0"
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,10 @@
1
+ require "jquery-dragdrop-rails/version"
2
+
3
+ module Jquery
4
+ module Dragdrop
5
+ module Rails
6
+ class Engine < ::Rails::Engine
7
+ end
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,402 @@
1
+ /*!
2
+ * jquery.event.drag - v 2.2
3
+ * Copyright (c) 2010 Three Dub Media - http://threedubmedia.com
4
+ * Open Source MIT License - http://threedubmedia.com/code/license
5
+ */
6
+ // Created: 2008-06-04
7
+ // Updated: 2012-05-21
8
+ // REQUIRES: jquery 1.7.x
9
+
10
+ ;(function( $ ){
11
+
12
+ // add the jquery instance method
13
+ $.fn.drag = function( str, arg, opts ){
14
+ // figure out the event type
15
+ var type = typeof str == "string" ? str : "",
16
+ // figure out the event handler...
17
+ fn = $.isFunction( str ) ? str : $.isFunction( arg ) ? arg : null;
18
+ // fix the event type
19
+ if ( type.indexOf("drag") !== 0 )
20
+ type = "drag"+ type;
21
+ // were options passed
22
+ opts = ( str == fn ? arg : opts ) || {};
23
+ // trigger or bind event handler
24
+ return fn ? this.bind( type, opts, fn ) : this.trigger( type );
25
+ };
26
+
27
+ // local refs (increase compression)
28
+ var $event = $.event,
29
+ $special = $event.special,
30
+ // configure the drag special event
31
+ drag = $special.drag = {
32
+
33
+ // these are the default settings
34
+ defaults: {
35
+ which: 1, // mouse button pressed to start drag sequence
36
+ distance: 0, // distance dragged before dragstart
37
+ not: ':input', // selector to suppress dragging on target elements
38
+ handle: null, // selector to match handle target elements
39
+ relative: false, // true to use "position", false to use "offset"
40
+ drop: true, // false to suppress drop events, true or selector to allow
41
+ click: false // false to suppress click events after dragend (no proxy)
42
+ },
43
+
44
+ // the key name for stored drag data
45
+ datakey: "dragdata",
46
+
47
+ // prevent bubbling for better performance
48
+ noBubble: true,
49
+
50
+ // count bound related events
51
+ add: function( obj ){
52
+ // read the interaction data
53
+ var data = $.data( this, drag.datakey ),
54
+ // read any passed options
55
+ opts = obj.data || {};
56
+ // count another realted event
57
+ data.related += 1;
58
+ // extend data options bound with this event
59
+ // don't iterate "opts" in case it is a node
60
+ $.each( drag.defaults, function( key, def ){
61
+ if ( opts[ key ] !== undefined )
62
+ data[ key ] = opts[ key ];
63
+ });
64
+ },
65
+
66
+ // forget unbound related events
67
+ remove: function(){
68
+ $.data( this, drag.datakey ).related -= 1;
69
+ },
70
+
71
+ // configure interaction, capture settings
72
+ setup: function(){
73
+ // check for related events
74
+ if ( $.data( this, drag.datakey ) )
75
+ return;
76
+ // initialize the drag data with copied defaults
77
+ var data = $.extend({ related:0 }, drag.defaults );
78
+ // store the interaction data
79
+ $.data( this, drag.datakey, data );
80
+ // bind the mousedown event, which starts drag interactions
81
+ $event.add( this, "touchstart mousedown", drag.init, data );
82
+ // prevent image dragging in IE...
83
+ if ( this.attachEvent )
84
+ this.attachEvent("ondragstart", drag.dontstart );
85
+ },
86
+
87
+ // destroy configured interaction
88
+ teardown: function(){
89
+ var data = $.data( this, drag.datakey ) || {};
90
+ // check for related events
91
+ if ( data.related )
92
+ return;
93
+ // remove the stored data
94
+ $.removeData( this, drag.datakey );
95
+ // remove the mousedown event
96
+ $event.remove( this, "touchstart mousedown", drag.init );
97
+ // enable text selection
98
+ drag.textselect( true );
99
+ // un-prevent image dragging in IE...
100
+ if ( this.detachEvent )
101
+ this.detachEvent("ondragstart", drag.dontstart );
102
+ },
103
+
104
+ // initialize the interaction
105
+ init: function( event ){
106
+ // sorry, only one touch at a time
107
+ if ( drag.touched )
108
+ return;
109
+ // the drag/drop interaction data
110
+ var dd = event.data, results;
111
+ // check the which directive
112
+ if ( event.which != 0 && dd.which > 0 && event.which != dd.which )
113
+ return;
114
+ // check for suppressed selector
115
+ if ( $( event.target ).is( dd.not ) )
116
+ return;
117
+ // check for handle selector
118
+ if ( dd.handle && !$( event.target ).closest( dd.handle, event.currentTarget ).length )
119
+ return;
120
+
121
+ drag.touched = event.type == 'touchstart' ? this : null;
122
+ dd.propagates = 1;
123
+ dd.mousedown = this;
124
+ dd.interactions = [ drag.interaction( this, dd ) ];
125
+ dd.target = event.target;
126
+ dd.pageX = event.pageX;
127
+ dd.pageY = event.pageY;
128
+ dd.dragging = null;
129
+ // handle draginit event...
130
+ results = drag.hijack( event, "draginit", dd );
131
+ // early cancel
132
+ if ( !dd.propagates )
133
+ return;
134
+ // flatten the result set
135
+ results = drag.flatten( results );
136
+ // insert new interaction elements
137
+ if ( results && results.length ){
138
+ dd.interactions = [];
139
+ $.each( results, function(){
140
+ dd.interactions.push( drag.interaction( this, dd ) );
141
+ });
142
+ }
143
+ // remember how many interactions are propagating
144
+ dd.propagates = dd.interactions.length;
145
+ // locate and init the drop targets
146
+ if ( dd.drop !== false && $special.drop )
147
+ $special.drop.handler( event, dd );
148
+ // disable text selection
149
+ drag.textselect( false );
150
+ // bind additional events...
151
+ if ( drag.touched )
152
+ $event.add( drag.touched, "touchmove touchend", drag.handler, dd );
153
+ else
154
+ $event.add( document, "mousemove mouseup", drag.handler, dd );
155
+ // helps prevent text selection or scrolling
156
+ if ( !drag.touched || dd.live )
157
+ return false;
158
+ },
159
+
160
+ // returns an interaction object
161
+ interaction: function( elem, dd ){
162
+ var offset = $( elem )[ dd.relative ? "position" : "offset" ]() || { top:0, left:0 };
163
+ return {
164
+ drag: elem,
165
+ callback: new drag.callback(),
166
+ droppable: [],
167
+ offset: offset
168
+ };
169
+ },
170
+
171
+ // handle drag-releatd DOM events
172
+ handler: function( event ){
173
+ // read the data before hijacking anything
174
+ var dd = event.data;
175
+ // handle various events
176
+ switch ( event.type ){
177
+ // mousemove, check distance, start dragging
178
+ case !dd.dragging && 'touchmove':
179
+ event.preventDefault();
180
+ case !dd.dragging && 'mousemove':
181
+ // drag tolerance,
182
+ if ( Math.pow( event.pageX-dd.pageX, 2 ) + Math.pow( event.pageY-dd.pageY, 2 ) < Math.pow( dd.distance, 2 ) )
183
+ break; // distance tolerance not reached
184
+ event.target = dd.target; // force target from "mousedown" event (fix distance issue)
185
+ drag.hijack( event, "dragstart", dd ); // trigger "dragstart"
186
+ if ( dd.propagates ) // "dragstart" not rejected
187
+ dd.dragging = true; // activate interaction
188
+ // mousemove, dragging
189
+ case 'touchmove':
190
+ event.preventDefault();
191
+ case 'mousemove':
192
+ if ( dd.dragging ){
193
+ // trigger "drag"
194
+ drag.hijack( event, "drag", dd );
195
+ if ( dd.propagates ){
196
+ // manage drop events
197
+ if ( dd.drop !== false && $special.drop )
198
+ $special.drop.handler( event, dd ); // "dropstart", "dropend"
199
+ break; // "drag" not rejected, stop
200
+ }
201
+ event.type = "mouseup"; // helps "drop" handler behave
202
+ }
203
+ // mouseup, stop dragging
204
+ case 'touchend':
205
+ case 'mouseup':
206
+ default:
207
+ if ( drag.touched )
208
+ $event.remove( drag.touched, "touchmove touchend", drag.handler ); // remove touch events
209
+ else
210
+ $event.remove( document, "mousemove mouseup", drag.handler ); // remove page events
211
+ if ( dd.dragging ){
212
+ if ( dd.drop !== false && $special.drop )
213
+ $special.drop.handler( event, dd ); // "drop"
214
+ drag.hijack( event, "dragend", dd ); // trigger "dragend"
215
+ }
216
+ drag.textselect( true ); // enable text selection
217
+ // if suppressing click events...
218
+ if ( dd.click === false && dd.dragging )
219
+ $.data( dd.mousedown, "suppress.click", new Date().getTime() + 5 );
220
+ dd.dragging = drag.touched = false; // deactivate element
221
+ break;
222
+ }
223
+ },
224
+
225
+ // re-use event object for custom events
226
+ hijack: function( event, type, dd, x, elem ){
227
+ // not configured
228
+ if ( !dd )
229
+ return;
230
+ // remember the original event and type
231
+ var orig = { event:event.originalEvent, type:event.type },
232
+ // is the event drag related or drog related?
233
+ mode = type.indexOf("drop") ? "drag" : "drop",
234
+ // iteration vars
235
+ result, i = x || 0, ia, $elems, callback,
236
+ len = !isNaN( x ) ? x : dd.interactions.length;
237
+ // modify the event type
238
+ event.type = type;
239
+ // remove the original event
240
+ event.originalEvent = null;
241
+ // initialize the results
242
+ dd.results = [];
243
+ // handle each interacted element
244
+ do if ( ia = dd.interactions[ i ] ){
245
+ // validate the interaction
246
+ if ( type !== "dragend" && ia.cancelled )
247
+ continue;
248
+ // set the dragdrop properties on the event object
249
+ callback = drag.properties( event, dd, ia );
250
+ // prepare for more results
251
+ ia.results = [];
252
+ // handle each element
253
+ $( elem || ia[ mode ] || dd.droppable ).each(function( p, subject ){
254
+ // identify drag or drop targets individually
255
+ callback.target = subject;
256
+ // force propagtion of the custom event
257
+ event.isPropagationStopped = function(){ return false; };
258
+ // handle the event
259
+ result = subject ? $event.dispatch.call( subject, event, callback ) : null;
260
+ // stop the drag interaction for this element
261
+ if ( result === false ){
262
+ if ( mode == "drag" ){
263
+ ia.cancelled = true;
264
+ dd.propagates -= 1;
265
+ }
266
+ if ( type == "drop" ){
267
+ ia[ mode ][p] = null;
268
+ }
269
+ }
270
+ // assign any dropinit elements
271
+ else if ( type == "dropinit" )
272
+ ia.droppable.push( drag.element( result ) || subject );
273
+ // accept a returned proxy element
274
+ if ( type == "dragstart" )
275
+ ia.proxy = $( drag.element( result ) || ia.drag )[0];
276
+ // remember this result
277
+ ia.results.push( result );
278
+ // forget the event result, for recycling
279
+ delete event.result;
280
+ // break on cancelled handler
281
+ if ( type !== "dropinit" )
282
+ return result;
283
+ });
284
+ // flatten the results
285
+ dd.results[ i ] = drag.flatten( ia.results );
286
+ // accept a set of valid drop targets
287
+ if ( type == "dropinit" )
288
+ ia.droppable = drag.flatten( ia.droppable );
289
+ // locate drop targets
290
+ if ( type == "dragstart" && !ia.cancelled )
291
+ callback.update();
292
+ }
293
+ while ( ++i < len )
294
+ // restore the original event & type
295
+ event.type = orig.type;
296
+ event.originalEvent = orig.event;
297
+ // return all handler results
298
+ return drag.flatten( dd.results );
299
+ },
300
+
301
+ // extend the callback object with drag/drop properties...
302
+ properties: function( event, dd, ia ){
303
+ var obj = ia.callback;
304
+ // elements
305
+ obj.drag = ia.drag;
306
+ obj.proxy = ia.proxy || ia.drag;
307
+ // starting mouse position
308
+ obj.startX = dd.pageX;
309
+ obj.startY = dd.pageY;
310
+ // current distance dragged
311
+ obj.deltaX = event.pageX - dd.pageX;
312
+ obj.deltaY = event.pageY - dd.pageY;
313
+ // original element position
314
+ obj.originalX = ia.offset.left;
315
+ obj.originalY = ia.offset.top;
316
+ // adjusted element position
317
+ obj.offsetX = obj.originalX + obj.deltaX;
318
+ obj.offsetY = obj.originalY + obj.deltaY;
319
+ // assign the drop targets information
320
+ obj.drop = drag.flatten( ( ia.drop || [] ).slice() );
321
+ obj.available = drag.flatten( ( ia.droppable || [] ).slice() );
322
+ return obj;
323
+ },
324
+
325
+ // determine is the argument is an element or jquery instance
326
+ element: function( arg ){
327
+ if ( arg && ( arg.jquery || arg.nodeType == 1 ) )
328
+ return arg;
329
+ },
330
+
331
+ // flatten nested jquery objects and arrays into a single dimension array
332
+ flatten: function( arr ){
333
+ return $.map( arr, function( member ){
334
+ return member && member.jquery ? $.makeArray( member ) :
335
+ member && member.length ? drag.flatten( member ) : member;
336
+ });
337
+ },
338
+
339
+ // toggles text selection attributes ON (true) or OFF (false)
340
+ textselect: function( bool ){
341
+ $( document )[ bool ? "unbind" : "bind" ]("selectstart", drag.dontstart )
342
+ .css("MozUserSelect", bool ? "" : "none" );
343
+ // .attr("unselectable", bool ? "off" : "on" )
344
+ document.unselectable = bool ? "off" : "on";
345
+ },
346
+
347
+ // suppress "selectstart" and "ondragstart" events
348
+ dontstart: function(){
349
+ return false;
350
+ },
351
+
352
+ // a callback instance contructor
353
+ callback: function(){}
354
+
355
+ };
356
+
357
+ // callback methods
358
+ drag.callback.prototype = {
359
+ update: function(){
360
+ if ( $special.drop && this.available.length )
361
+ $.each( this.available, function( i ){
362
+ $special.drop.locate( this, i );
363
+ });
364
+ }
365
+ };
366
+
367
+ // patch $.event.$dispatch to allow suppressing clicks
368
+ var $dispatch = $event.dispatch;
369
+ $event.dispatch = function( event ){
370
+ if ( $.data( this, "suppress."+ event.type ) - new Date().getTime() > 0 ){
371
+ $.removeData( this, "suppress."+ event.type );
372
+ return;
373
+ }
374
+ return $dispatch.apply( this, arguments );
375
+ };
376
+
377
+ // event fix hooks for touch events...
378
+ var touchHooks =
379
+ $event.fixHooks.touchstart =
380
+ $event.fixHooks.touchmove =
381
+ $event.fixHooks.touchend =
382
+ $event.fixHooks.touchcancel = {
383
+ props: "clientX clientY pageX pageY screenX screenY".split( " " ),
384
+ filter: function( event, orig ) {
385
+ if ( orig ){
386
+ var touched = ( orig.touches && orig.touches[0] )
387
+ || ( orig.changedTouches && orig.changedTouches[0] )
388
+ || null;
389
+ // iOS webkit: touchstart, touchmove, touchend
390
+ if ( touched )
391
+ $.each( touchHooks.props, function( i, prop ){
392
+ event[ prop ] = touched[ prop ];
393
+ });
394
+ }
395
+ return event;
396
+ }
397
+ };
398
+
399
+ // share the same special event configuration with related events...
400
+ $special.draginit = $special.dragstart = $special.dragend = drag;
401
+
402
+ })( jQuery );
@@ -0,0 +1,87 @@
1
+ /*!
2
+ * jquery.event.drag.live - v 2.2
3
+ * Copyright (c) 2010 Three Dub Media - http://threedubmedia.com
4
+ * Open Source MIT License - http://threedubmedia.com/code/license
5
+ */
6
+ // Created: 2010-06-07
7
+ // Updated: 2012-05-21
8
+ // REQUIRES: jquery 1.7.x, event.drag 2.2
9
+
10
+ ;(function( $ ){
11
+
12
+ // local refs (increase compression)
13
+ var $event = $.event,
14
+ // ref the special event config
15
+ drag = $event.special.drag,
16
+ // old drag event add method
17
+ origadd = drag.add,
18
+ // old drag event teradown method
19
+ origteardown = drag.teardown;
20
+
21
+ // allow events to bubble for delegation
22
+ drag.noBubble = false;
23
+
24
+ // the namespace for internal live events
25
+ drag.livekey = "livedrag";
26
+
27
+ // new drop event add method
28
+ drag.add = function( obj ){
29
+ // call the old method
30
+ origadd.apply( this, arguments );
31
+ // read the data
32
+ var data = $.data( this, drag.datakey );
33
+ // bind the live "draginit" delegator
34
+ if ( !data.live && obj.selector ){
35
+ data.live = true;
36
+ $event.add( this, "draginit."+ drag.livekey, drag.delegate );
37
+ }
38
+ };
39
+
40
+ // new drop event teardown method
41
+ drag.teardown = function(){
42
+ // call the old method
43
+ origteardown.apply( this, arguments );
44
+ // read the data
45
+ var data = $.data( this, drag.datakey ) || {};
46
+ // bind the live "draginit" delegator
47
+ if ( data.live ){
48
+ // remove the "live" delegation
49
+ $event.remove( this, "draginit."+ drag.livekey, drag.delegate );
50
+ data.live = false;
51
+ }
52
+ };
53
+
54
+ // identify potential delegate elements
55
+ drag.delegate = function( event ){
56
+ // local refs
57
+ var elems = [], target,
58
+ // element event structure
59
+ events = $.data( this, "events" ) || {};
60
+ // query live events
61
+ $.each( events || [], function( key, arr ){
62
+ // no event type matches
63
+ if ( key.indexOf("drag") !== 0 )
64
+ return;
65
+ $.each( arr || [], function( i, obj ){
66
+ // locate the element to delegate
67
+ target = $( event.target ).closest( obj.selector, event.currentTarget )[0];
68
+ // no element found
69
+ if ( !target )
70
+ return;
71
+ // add an event handler
72
+ $event.add( target, obj.origType+'.'+drag.livekey, obj.origHandler || obj.handler, obj.data );
73
+ // remember new elements
74
+ if ( $.inArray( target, elems ) < 0 )
75
+ elems.push( target );
76
+ });
77
+ });
78
+ // if there are no elements, break
79
+ if ( !elems.length )
80
+ return false;
81
+ // return the matched results, and clenup when complete
82
+ return $( elems ).bind("dragend."+ drag.livekey, function(){
83
+ $event.remove( this, "."+ drag.livekey ); // cleanup delegation
84
+ });
85
+ };
86
+
87
+ })( jQuery );
@@ -0,0 +1,302 @@
1
+ /*!
2
+ * jquery.event.drop - v 2.2
3
+ * Copyright (c) 2010 Three Dub Media - http://threedubmedia.com
4
+ * Open Source MIT License - http://threedubmedia.com/code/license
5
+ */
6
+ // Created: 2008-06-04
7
+ // Updated: 2012-05-21
8
+ // REQUIRES: jquery 1.7.x, event.drag 2.2
9
+
10
+ ;(function($){ // secure $ jQuery alias
11
+
12
+ // Events: drop, dropstart, dropend
13
+
14
+ // add the jquery instance method
15
+ $.fn.drop = function( str, arg, opts ){
16
+ // figure out the event type
17
+ var type = typeof str == "string" ? str : "",
18
+ // figure out the event handler...
19
+ fn = $.isFunction( str ) ? str : $.isFunction( arg ) ? arg : null;
20
+ // fix the event type
21
+ if ( type.indexOf("drop") !== 0 )
22
+ type = "drop"+ type;
23
+ // were options passed
24
+ opts = ( str == fn ? arg : opts ) || {};
25
+ // trigger or bind event handler
26
+ return fn ? this.bind( type, opts, fn ) : this.trigger( type );
27
+ };
28
+
29
+ // DROP MANAGEMENT UTILITY
30
+ // returns filtered drop target elements, caches their positions
31
+ $.drop = function( opts ){
32
+ opts = opts || {};
33
+ // safely set new options...
34
+ drop.multi = opts.multi === true ? Infinity :
35
+ opts.multi === false ? 1 : !isNaN( opts.multi ) ? opts.multi : drop.multi;
36
+ drop.delay = opts.delay || drop.delay;
37
+ drop.tolerance = $.isFunction( opts.tolerance ) ? opts.tolerance :
38
+ opts.tolerance === null ? null : drop.tolerance;
39
+ drop.mode = opts.mode || drop.mode || 'intersect';
40
+ };
41
+
42
+ // local refs (increase compression)
43
+ var $event = $.event,
44
+ $special = $event.special,
45
+ // configure the drop special event
46
+ drop = $.event.special.drop = {
47
+
48
+ // these are the default settings
49
+ multi: 1, // allow multiple drop winners per dragged element
50
+ delay: 20, // async timeout delay
51
+ mode: 'overlap', // drop tolerance mode
52
+
53
+ // internal cache
54
+ targets: [],
55
+
56
+ // the key name for stored drop data
57
+ datakey: "dropdata",
58
+
59
+ // prevent bubbling for better performance
60
+ noBubble: true,
61
+
62
+ // count bound related events
63
+ add: function( obj ){
64
+ // read the interaction data
65
+ var data = $.data( this, drop.datakey );
66
+ // count another realted event
67
+ data.related += 1;
68
+ },
69
+
70
+ // forget unbound related events
71
+ remove: function(){
72
+ $.data( this, drop.datakey ).related -= 1;
73
+ },
74
+
75
+ // configure the interactions
76
+ setup: function(){
77
+ // check for related events
78
+ if ( $.data( this, drop.datakey ) )
79
+ return;
80
+ // initialize the drop element data
81
+ var data = {
82
+ related: 0,
83
+ active: [],
84
+ anyactive: 0,
85
+ winner: 0,
86
+ location: {}
87
+ };
88
+ // store the drop data on the element
89
+ $.data( this, drop.datakey, data );
90
+ // store the drop target in internal cache
91
+ drop.targets.push( this );
92
+ },
93
+
94
+ // destroy the configure interaction
95
+ teardown: function(){
96
+ var data = $.data( this, drop.datakey ) || {};
97
+ // check for related events
98
+ if ( data.related )
99
+ return;
100
+ // remove the stored data
101
+ $.removeData( this, drop.datakey );
102
+ // reference the targeted element
103
+ var element = this;
104
+ // remove from the internal cache
105
+ drop.targets = $.grep( drop.targets, function( target ){
106
+ return ( target !== element );
107
+ });
108
+ },
109
+
110
+ // shared event handler
111
+ handler: function( event, dd ){
112
+ // local vars
113
+ var results, $targets;
114
+ // make sure the right data is available
115
+ if ( !dd )
116
+ return;
117
+ // handle various events
118
+ switch ( event.type ){
119
+ // draginit, from $.event.special.drag
120
+ case 'mousedown': // DROPINIT >>
121
+ case 'touchstart': // DROPINIT >>
122
+ // collect and assign the drop targets
123
+ $targets = $( drop.targets );
124
+ if ( typeof dd.drop == "string" )
125
+ $targets = $targets.filter( dd.drop );
126
+ // reset drop data winner properties
127
+ $targets.each(function(){
128
+ var data = $.data( this, drop.datakey );
129
+ data.active = [];
130
+ data.anyactive = 0;
131
+ data.winner = 0;
132
+ });
133
+ // set available target elements
134
+ dd.droppable = $targets;
135
+ // activate drop targets for the initial element being dragged
136
+ $special.drag.hijack( event, "dropinit", dd );
137
+ break;
138
+ // drag, from $.event.special.drag
139
+ case 'mousemove': // TOLERATE >>
140
+ case 'touchmove': // TOLERATE >>
141
+ drop.event = event; // store the mousemove event
142
+ if ( !drop.timer )
143
+ // monitor drop targets
144
+ drop.tolerate( dd );
145
+ break;
146
+ // dragend, from $.event.special.drag
147
+ case 'mouseup': // DROP >> DROPEND >>
148
+ case 'touchend': // DROP >> DROPEND >>
149
+ drop.timer = clearTimeout( drop.timer ); // delete timer
150
+ if ( dd.propagates ){
151
+ $special.drag.hijack( event, "drop", dd );
152
+ $special.drag.hijack( event, "dropend", dd );
153
+ }
154
+ break;
155
+
156
+ }
157
+ },
158
+
159
+ // returns the location positions of an element
160
+ locate: function( elem, index ){
161
+ var data = $.data( elem, drop.datakey ),
162
+ $elem = $( elem ),
163
+ posi = $elem.offset() || {},
164
+ height = $elem.outerHeight(),
165
+ width = $elem.outerWidth(),
166
+ location = {
167
+ elem: elem,
168
+ width: width,
169
+ height: height,
170
+ top: posi.top,
171
+ left: posi.left,
172
+ right: posi.left + width,
173
+ bottom: posi.top + height
174
+ };
175
+ // drag elements might not have dropdata
176
+ if ( data ){
177
+ data.location = location;
178
+ data.index = index;
179
+ data.elem = elem;
180
+ }
181
+ return location;
182
+ },
183
+
184
+ // test the location positions of an element against another OR an X,Y coord
185
+ contains: function( target, test ){ // target { location } contains test [x,y] or { location }
186
+ return ( ( test[0] || test.left ) >= target.left && ( test[0] || test.right ) <= target.right
187
+ && ( test[1] || test.top ) >= target.top && ( test[1] || test.bottom ) <= target.bottom );
188
+ },
189
+
190
+ // stored tolerance modes
191
+ modes: { // fn scope: "$.event.special.drop" object
192
+ // target with mouse wins, else target with most overlap wins
193
+ 'intersect': function( event, proxy, target ){
194
+ return this.contains( target, [ event.pageX, event.pageY ] ) ? // check cursor
195
+ 1e9 : this.modes.overlap.apply( this, arguments ); // check overlap
196
+ },
197
+ // target with most overlap wins
198
+ 'overlap': function( event, proxy, target ){
199
+ // calculate the area of overlap...
200
+ return Math.max( 0, Math.min( target.bottom, proxy.bottom ) - Math.max( target.top, proxy.top ) )
201
+ * Math.max( 0, Math.min( target.right, proxy.right ) - Math.max( target.left, proxy.left ) );
202
+ },
203
+ // proxy is completely contained within target bounds
204
+ 'fit': function( event, proxy, target ){
205
+ return this.contains( target, proxy ) ? 1 : 0;
206
+ },
207
+ // center of the proxy is contained within target bounds
208
+ 'middle': function( event, proxy, target ){
209
+ return this.contains( target, [ proxy.left + proxy.width * .5, proxy.top + proxy.height * .5 ] ) ? 1 : 0;
210
+ }
211
+ },
212
+
213
+ // sort drop target cache by by winner (dsc), then index (asc)
214
+ sort: function( a, b ){
215
+ return ( b.winner - a.winner ) || ( a.index - b.index );
216
+ },
217
+
218
+ // async, recursive tolerance execution
219
+ tolerate: function( dd ){
220
+ // declare local refs
221
+ var i, drp, drg, data, arr, len, elem,
222
+ // interaction iteration variables
223
+ x = 0, ia, end = dd.interactions.length,
224
+ // determine the mouse coords
225
+ xy = [ drop.event.pageX, drop.event.pageY ],
226
+ // custom or stored tolerance fn
227
+ tolerance = drop.tolerance || drop.modes[ drop.mode ];
228
+ // go through each passed interaction...
229
+ do if ( ia = dd.interactions[x] ){
230
+ // check valid interaction
231
+ if ( !ia )
232
+ return;
233
+ // initialize or clear the drop data
234
+ ia.drop = [];
235
+ // holds the drop elements
236
+ arr = [];
237
+ len = ia.droppable.length;
238
+ // determine the proxy location, if needed
239
+ if ( tolerance )
240
+ drg = drop.locate( ia.proxy );
241
+ // reset the loop
242
+ i = 0;
243
+ // loop each stored drop target
244
+ do if ( elem = ia.droppable[i] ){
245
+ data = $.data( elem, drop.datakey );
246
+ drp = data.location;
247
+ if ( !drp ) continue;
248
+ // find a winner: tolerance function is defined, call it
249
+ data.winner = tolerance ? tolerance.call( drop, drop.event, drg, drp )
250
+ // mouse position is always the fallback
251
+ : drop.contains( drp, xy ) ? 1 : 0;
252
+ arr.push( data );
253
+ } while ( ++i < len ); // loop
254
+ // sort the drop targets
255
+ arr.sort( drop.sort );
256
+ // reset the loop
257
+ i = 0;
258
+ // loop through all of the targets again
259
+ do if ( data = arr[ i ] ){
260
+ // winners...
261
+ if ( data.winner && ia.drop.length < drop.multi ){
262
+ // new winner... dropstart
263
+ if ( !data.active[x] && !data.anyactive ){
264
+ // check to make sure that this is not prevented
265
+ if ( $special.drag.hijack( drop.event, "dropstart", dd, x, data.elem )[0] !== false ){
266
+ data.active[x] = 1;
267
+ data.anyactive += 1;
268
+ }
269
+ // if false, it is not a winner
270
+ else
271
+ data.winner = 0;
272
+ }
273
+ // if it is still a winner
274
+ if ( data.winner )
275
+ ia.drop.push( data.elem );
276
+ }
277
+ // losers...
278
+ else if ( data.active[x] && data.anyactive == 1 ){
279
+ // former winner... dropend
280
+ $special.drag.hijack( drop.event, "dropend", dd, x, data.elem );
281
+ data.active[x] = 0;
282
+ data.anyactive -= 1;
283
+ }
284
+ } while ( ++i < len ); // loop
285
+ } while ( ++x < end ) // loop
286
+ // check if the mouse is still moving or is idle
287
+ if ( drop.last && xy[0] == drop.last.pageX && xy[1] == drop.last.pageY )
288
+ delete drop.timer; // idle, don't recurse
289
+ else // recurse
290
+ drop.timer = setTimeout(function(){
291
+ drop.tolerate( dd );
292
+ }, drop.delay );
293
+ // remember event, to compare idleness
294
+ drop.last = drop.event;
295
+ }
296
+
297
+ };
298
+
299
+ // share the same special event configuration with related events...
300
+ $special.dropinit = $special.dropstart = $special.dropend = drop;
301
+
302
+ })(jQuery); // confine scope
@@ -0,0 +1,93 @@
1
+ /*!
2
+ * jquery.event.drop.live - v 2.2
3
+ * Copyright (c) 2010 Three Dub Media - http://threedubmedia.com
4
+ * Open Source MIT License - http://threedubmedia.com/code/license
5
+ */
6
+ // Created: 2010-06-07
7
+ // Updated: 2012-05-21
8
+ // REQUIRES: jquery 1.7.x, event.drag 2.2, event.drop 2.2
9
+
10
+ ;(function($){ // secure $ jQuery alias
11
+
12
+ // local refs (increase compression)
13
+ var $event = $.event,
14
+ // ref the drop special event config
15
+ drop = $event.special.drop,
16
+ // old drop event add method
17
+ origadd = drop.add,
18
+ // old drop event teradown method
19
+ origteardown = drop.teardown;
20
+
21
+ // allow events to bubble for delegation
22
+ drop.noBubble = false;
23
+
24
+ // the namespace for internal live events
25
+ drop.livekey = "livedrop";
26
+
27
+ // new drop event add method
28
+ drop.add = function( obj ){
29
+ // call the old method
30
+ origadd.apply( this, arguments );
31
+ // read the data
32
+ var data = $.data( this, drop.datakey );
33
+ // bind the live "dropinit" delegator
34
+ if ( !data.live && obj.selector ){
35
+ data.live = true;
36
+ $event.add( this, "dropinit."+ drop.livekey, drop.delegate );
37
+ }
38
+ };
39
+
40
+ // new drop event teardown method
41
+ drop.teardown = function(){
42
+ // call the old method
43
+ origteardown.apply( this, arguments );
44
+ // read the data
45
+ var data = $.data( this, drop.datakey ) || {};
46
+ // remove the live "dropinit" delegator
47
+ if ( data.live ){
48
+ // remove the "live" delegation
49
+ $event.remove( this, "dropinit", drop.delegate );
50
+ data.live = false;
51
+ }
52
+ };
53
+
54
+ // identify potential delegate elements
55
+ drop.delegate = function( event, dd ){
56
+ // local refs
57
+ var elems = [], $targets,
58
+ // element event structure
59
+ events = $.data( this, "events" ) || {};
60
+ // query live events
61
+ $.each( events || [], function( key, arr ){
62
+ // no event type matches
63
+ if ( key.indexOf("drop") !== 0 )
64
+ return;
65
+ $.each( arr, function( i, obj ){
66
+ // locate the elements to delegate
67
+ $targets = $( event.currentTarget ).find( obj.selector );
68
+ // no element found
69
+ if ( !$targets.length )
70
+ return;
71
+ // take each target...
72
+ $targets.each(function(){
73
+ // add an event handler
74
+ $event.add( this, obj.origType +'.'+ drop.livekey, obj.origHandler || obj.handler, obj.data );
75
+ // remember new elements
76
+ if ( $.inArray( this, elems ) < 0 )
77
+ elems.push( this );
78
+ });
79
+ });
80
+ });
81
+ // may not exist when artifically triggering dropinit event
82
+ if ( dd )
83
+ // clean-up after the interaction ends
84
+ $event.add( dd.drag, "dragend."+drop.livekey, function(){
85
+ $.each( elems.concat( this ), function(){
86
+ $event.remove( this, '.'+ drop.livekey );
87
+ });
88
+ });
89
+ //drop.delegates.push( elems );
90
+ return elems.length ? $( elems ) : false;
91
+ };
92
+
93
+ })( jQuery ); // confine scope
metadata ADDED
@@ -0,0 +1,90 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: jquery-dragdrop-rails
3
+ version: !ruby/object:Gem::Version
4
+ version: 2.2.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Aki Atoji
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-02-05 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: railties
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: '3.0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ version: '3.0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: jquery-rails
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ description: jQuery Drag Drop wrapper
47
+ email:
48
+ - akiatoji@gmail.com
49
+ executables: []
50
+ extensions: []
51
+ extra_rdoc_files: []
52
+ files:
53
+ - .gitignore
54
+ - Gemfile
55
+ - LICENSE.txt
56
+ - README.md
57
+ - Rakefile
58
+ - jquery-dragdrop-rails.gemspec
59
+ - lib/jquery-dragdrop-rails.rb
60
+ - lib/jquery-dragdrop-rails/version.rb
61
+ - vendor/assets/javascripts/jquery.event.drag-2.2.js
62
+ - vendor/assets/javascripts/jquery.event.drag.live-2.2.js
63
+ - vendor/assets/javascripts/jquery.event.drop-2.2.js
64
+ - vendor/assets/javascripts/jquery.event.drop.live-2.2.js
65
+ homepage: http://github.dom/akiatoji/jquery-dragdrop-rails
66
+ licenses: []
67
+ post_install_message:
68
+ rdoc_options: []
69
+ require_paths:
70
+ - lib
71
+ required_ruby_version: !ruby/object:Gem::Requirement
72
+ none: false
73
+ requirements:
74
+ - - ! '>='
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
77
+ required_rubygems_version: !ruby/object:Gem::Requirement
78
+ none: false
79
+ requirements:
80
+ - - ! '>='
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ requirements: []
84
+ rubyforge_project:
85
+ rubygems_version: 1.8.23
86
+ signing_key:
87
+ specification_version: 3
88
+ summary: Wraps ThreeDubMedia's jquery.event.drag and jquery.event.drop plugins for
89
+ Rails
90
+ test_files: []