masonry-rails 0.1.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.
Files changed (54) hide show
  1. data/.document +5 -0
  2. data/.rspec +1 -0
  3. data/Gemfile +11 -0
  4. data/Gemfile.lock +109 -0
  5. data/LICENSE.txt +20 -0
  6. data/Masonry.mdown +51 -0
  7. data/README.md +53 -0
  8. data/Rakefile +49 -0
  9. data/VERSION +1 -0
  10. data/_config.yml +6 -0
  11. data/lib/masonry-rails.rb +7 -0
  12. data/masonry-rails.gemspec +107 -0
  13. data/minify.sh +16 -0
  14. data/spec/_layouts/default.html +75 -0
  15. data/spec/_posts/demos/2011-05-01-basic-single-column.html +206 -0
  16. data/spec/_posts/demos/2011-05-02-basic-multi-column.html +213 -0
  17. data/spec/_posts/demos/2011-05-03-images.html +57 -0
  18. data/spec/_posts/demos/2011-05-04-tumblelog.html +226 -0
  19. data/spec/_posts/demos/2011-05-05-animating-jquery.html +144 -0
  20. data/spec/_posts/demos/2011-05-06-animating-css-transitions.html +132 -0
  21. data/spec/_posts/demos/2011-05-07-animating-modernizr.html +136 -0
  22. data/spec/_posts/demos/2011-05-08-adding-items.html +89 -0
  23. data/spec/_posts/demos/2011-05-09-infinite-scroll.html +268 -0
  24. data/spec/_posts/demos/2011-05-10-gutters.html +209 -0
  25. data/spec/_posts/demos/2011-05-11-right-to-left.html +135 -0
  26. data/spec/_posts/demos/2011-05-17-centered.html +137 -0
  27. data/spec/_posts/demos/2011-07-26-fluid.html +219 -0
  28. data/spec/_posts/demos/2011-10-07-corner-stamp.html +249 -0
  29. data/spec/_posts/docs/2011-05-01-intro.mdown +149 -0
  30. data/spec/_posts/docs/2011-05-02-options.mdown +157 -0
  31. data/spec/_posts/docs/2011-05-03-methods.mdown +155 -0
  32. data/spec/_posts/docs/2011-05-04-animating.mdown +96 -0
  33. data/spec/_posts/docs/2011-05-30-help.mdown +139 -0
  34. data/spec/_posts/pages/2011-05-02-2.html +189 -0
  35. data/spec/_posts/pages/2011-05-03-3.html +174 -0
  36. data/spec/_posts/pages/2011-05-04-4.html +159 -0
  37. data/spec/_posts/pages/2011-05-05-5.html +167 -0
  38. data/spec/_posts/tests/2011-01-01-index.html +14 -0
  39. data/spec/_posts/tests/2011-05-14-lots-of-bricks.html +1438 -0
  40. data/spec/_posts/tests/2011-05-17-dual.html +247 -0
  41. data/spec/_posts/tests/2011-05-18-first-child-no-width.html +217 -0
  42. data/spec/_posts/tests/2011-05-19-empty.html +205 -0
  43. data/spec/_posts/tests/2011-08-08-destroy.html +214 -0
  44. data/spec/_posts/tests/2011-09-27-centered-few.html +50 -0
  45. data/spec/index.html +58 -0
  46. data/spec/spec_helper.rb +12 -0
  47. data/vendor/assets/javascripts/masonry/box-maker.js +38 -0
  48. data/vendor/assets/javascripts/masonry/jquery.event.drag-2.2.js +402 -0
  49. data/vendor/assets/javascripts/masonry/jquery.infinitescroll.min.js +47 -0
  50. data/vendor/assets/javascripts/masonry/jquery.masonry.js +682 -0
  51. data/vendor/assets/javascripts/masonry/jquery.masonry.min.js +10 -0
  52. data/vendor/assets/javascripts/masonry/modernizr-transitions.js +2 -0
  53. data/vendor/assets/stylesheets/masonry/style.css +616 -0
  54. metadata +199 -0
data/spec/index.html ADDED
@@ -0,0 +1,58 @@
1
+ <!doctype html>
2
+ <html>
3
+ <head>
4
+ <title>Masonry Drag and Drop</title>
5
+ <style type="text/css">
6
+ .box-item {
7
+ width: 100px;
8
+ height: 100px;
9
+ float: left;
10
+ background-color: grey;
11
+ margin: 10px;
12
+ }
13
+
14
+ .handle {
15
+ background-color: black;
16
+ height: 20px;
17
+ cursor: move;
18
+ }
19
+
20
+ .drag-ghost {
21
+ opacity: 0.5;
22
+ z-index: 0;
23
+ }
24
+
25
+ .color1 { background-color: blue; z-index: 9999;}
26
+ .color2 { background-color: green;}
27
+ .bigger { height: 150px; }
28
+ .smaller { height: 75px; width: 200px; }
29
+ </style>
30
+ <script src="js/jquery-1.7.1.min.js"></script>
31
+ <script src="js/jquery.event.drag-2.2.js"></script>
32
+ <script src="jquery.masonry.js"></script>
33
+ </head>
34
+ <body>
35
+ <div id="container">
36
+ <div class="box-item"><div class="handle"></div>A</div>
37
+ <div class="box-item"><div class="handle"></div>B</div>
38
+ <div class="box-item bigger"><div class="handle"></div>C</div>
39
+ <div class="box-item"><div class="handle"></div>D</div>
40
+ <div class="box-item smaller"><div class="handle"></div>E</div>
41
+ <div class="box-item"><div class="handle"></div>F</div>
42
+ <div class="box-item"><div class="handle"></div>G</div>
43
+ <div class="box-item smaller"><div class="handle">H</div></div>
44
+ <div class="box-item"><div class="handle"></div>I</div>
45
+ <div class="box-item smaller"><div class="handle"></div>J</div>
46
+ <div class="box-item"><div class="handle"></div>K</div>
47
+ <div class="box-item bigger"><div class="handle"></div>L</div>
48
+ </div>​
49
+ <script type="text/javascript">
50
+ $("#container").masonry({
51
+ isAnimated : true,
52
+ isDraggable : true,
53
+ dragHandleSelector: '.handle',
54
+ dragClass: 'color1'
55
+ });
56
+ </script>
57
+ </body>
58
+ </html>
@@ -0,0 +1,12 @@
1
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
2
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
3
+ require 'rspec'
4
+ require 'masonry-rails'
5
+
6
+ # Requires supporting files with custom matchers and macros, etc,
7
+ # in ./support/ and its subdirectories.
8
+ Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
9
+
10
+ RSpec.configure do |config|
11
+
12
+ end
@@ -0,0 +1,38 @@
1
+ /*
2
+ * This is just a utitlity script so we can
3
+ * add random content to masonry-ed layouts
4
+ */
5
+
6
+ var boxMaker = {};
7
+
8
+ boxMaker.lorem = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus eu interdum odio. Cras lobortis mauris vitae tellus consectetur sit amet cursus ipsum vestibulum. Duis facilisis sodales tristique. Vivamus aliquet, est a rhoncus dapibus, velit tortor tempor turpis, a pharetra diam lacus a metus. Donec gravida faucibus magna, nec laoreet nibh placerat et. Cras magna lorem, faucibus vitae rhoncus ac, tincidunt vel velit. Mauris aliquam, risus vel sodales laoreet, mi nulla faucibus nunc, eu tincidunt nisi leo sed orci. Curabitur sagittis libero eu augue luctus ullamcorper. Phasellus sed tortor sed nunc elementum rutrum. Maecenas eu enim a nulla faucibus commodo iaculis tempor orci. Integer at ligula id mauris semper bibendum at eu erat. Integer vestibulum sem nec risus iaculis eu rhoncus tellus tempor. Suspendisse potenti. Sed bibendum nibh non velit blandit eu adipiscing ligula consectetur. Vivamus turpis quam, fringilla a elementum a, condimentum non purus. Pellentesque sed bibendum ante. Fusce elit mauris, pulvinar sed rutrum eget, malesuada in nisi. Etiam sagittis pretium ligula. Aliquam a metus orci, a molestie lacus. Suspendisse potenti. Mauris vel volutpat nunc. In condimentum imperdiet scelerisque. Cras aliquam tristique velit non iaculis. Aliquam pulvinar sagittis sodales. Aenean risus orci, elementum quis accumsan eget, elementum cursus tellus. Nunc vel laoreet odio. Maecenas sollicitudin, tellus vel bibendum ornare, tellus nibh hendrerit lorem, quis volutpat turpis odio ac ligula. Etiam tempus neque id libero feugiat fringilla. Nullam posuere consequat vehicula. Mauris in lorem eget sem tempor condimentum. Integer rhoncus accumsan elit eu gravida. Donec dictum ante ac nisl adipiscing vel tempor libero luctus. Praesent bibendum augue at erat semper rutrum. Fusce vel orci nulla. Vivamus condimentum, odio vel condimentum tempus, mauris ipsum gravida odio, sed viverra dolor velit sit amet magna. Donec aliquam malesuada ipsum ut suscipit. Vivamus porttitor posuere iaculis. Vestibulum lectus lorem, tincidunt at sodales et, euismod vel quam. Sed eget urna nunc. In quis felis nunc. Aliquam erat volutpat. Cras ut dui ac leo aliquet placerat faucibus in nulla. Mauris pharetra ligula et tortor ultricies eget elementum libero blandit. Praesent tincidunt, mi quis aliquam faucibus, leo risus placerat odio, ac adipiscing ante urna at tortor.'.split(".");
9
+
10
+ boxMaker.loremLen = boxMaker.lorem.length;
11
+
12
+ boxMaker.randoLoremText = function() {
13
+ var loremText = '',
14
+ sentences = Math.random() * 5;
15
+ for (var j=0; j < sentences; j++ ) {
16
+ var whichSentence = Math.floor( Math.random() * boxMaker.loremLen );
17
+ loremText += boxMaker.lorem[whichSentence] + '. ';
18
+ }
19
+ return loremText;
20
+ };
21
+
22
+ boxMaker.makeBoxes = function() {
23
+ var boxes = [],
24
+ count = Math.random()*4;
25
+
26
+ for (var i=0; i < count; i++ ) {
27
+ var box = document.createElement('div'),
28
+ text = document.createTextNode( boxMaker.randoLoremText() );
29
+
30
+ box.className = 'box col' + Math.ceil( Math.random()*3 );
31
+ box.appendChild( text );
32
+ // add box DOM node to array of new elements
33
+ boxes.push( box );
34
+ }
35
+
36
+ return boxes;
37
+ };
38
+
@@ -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, x� + y� = distance�
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 );