dropzonejs-rails 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ (c) Copyright 2013 José Nahuel Cuesta Luengo
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,68 @@
1
+ # dropzonejs-rails
2
+
3
+ Integrate [Matias Meno's Dropzone](http://www.dropzonejs.com/) awesome file upload JS library right into the Asset pipeline of your Rails apps.
4
+
5
+ ## Installation and usage
6
+
7
+ First add `dropzonejs-rails` to your Gemfile and, as you already know, `bundle` it and then restart your Rails app:
8
+
9
+ ```ruby
10
+ # On your Gemfile
11
+ gem 'dropzonejs-rails'
12
+ ```
13
+
14
+ ```bash
15
+ $ bundle install
16
+ ```
17
+
18
+ After that, you need to make `dropzone.js` available on your pages. To do that, you can add it to your `application.js` file, like this:
19
+
20
+ ```javascript
21
+ //= require dropzone
22
+ ```
23
+
24
+ And **Bam!** - you're all set.
25
+
26
+
27
+ ## Issues, Requests, Comments, Poetry
28
+
29
+ Go to [this secret place](https://github.com/ncuesta/dropzonejs-rails/issues).
30
+
31
+
32
+ ## Contributing
33
+
34
+ 1. Fork,
35
+ 2. Hack,
36
+ 3. Create a Pull Request.
37
+
38
+ **DO NOT - I repeat - DO NOT bump version numbers.** Unless you **really** need to.
39
+
40
+
41
+ ### Getting the latest version of Raptor Editor
42
+
43
+ 1. Update `DropzonejsRails::DROPZONE_VERSION` to the newest version of Dropzone.
44
+ 1. Do a `rake get` - it'll download the file four you.
45
+
46
+
47
+ ## Licence (MIT)
48
+
49
+ (c) Copyright 2013 José Nahuel Cuesta Luengo
50
+
51
+ Permission is hereby granted, free of charge, to any person obtaining
52
+ a copy of this software and associated documentation files (the
53
+ "Software"), to deal in the Software without restriction, including
54
+ without limitation the rights to use, copy, modify, merge, publish,
55
+ distribute, sublicense, and/or sell copies of the Software, and to
56
+ permit persons to whom the Software is furnished to do so, subject to
57
+ the following conditions:
58
+
59
+ The above copyright notice and this permission notice shall be
60
+ included in all copies or substantial portions of the Software.
61
+
62
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
63
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
64
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
65
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
66
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
67
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
68
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Rakefile ADDED
@@ -0,0 +1,19 @@
1
+ #!/usr/bin/env rake
2
+ begin
3
+ require 'bundler/setup'
4
+ rescue LoadError
5
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
6
+ end
7
+
8
+ Bundler::GemHelper.install_tasks
9
+
10
+ require 'dropzonejs-rails'
11
+ require 'open-uri'
12
+
13
+ desc 'Get latest dropzone js build'
14
+ task :get do
15
+ source = "https://raw.github.com/enyo/dropzone/v#{DropzonejsRails::DROPZONE_VERSION}/downloads/dropzone.js"
16
+ target = DropzonejsRails::Engine.root.join('vendor/assets/javascripts/dropzone.js')
17
+
18
+ open(target, "w+") { |f| f << open(source).read }
19
+ end
@@ -0,0 +1,4 @@
1
+ require 'dropzonejs-rails/engine'
2
+
3
+ module DropzonejsRails
4
+ end
@@ -0,0 +1,6 @@
1
+ require 'rails'
2
+
3
+ module DropzonejsRails
4
+ class Engine < ::Rails::Engine
5
+ end
6
+ end
@@ -0,0 +1,4 @@
1
+ module DropzonejsRails
2
+ VERSION = '0.0.1'
3
+ DROPZONE_VERSION = '1.3.9'
4
+ end
@@ -0,0 +1,15 @@
1
+ require 'dropzonejs-rails'
2
+ require 'dropzonejs-rails/version'
3
+
4
+ module DropzonejsRails
5
+ module Generators
6
+ class InstallGenerator < Rails::Generators::Base
7
+ desc "Installs Dropzone JS files (v#{DropzonejsRails::DROPZONE_VERSION}) into the project"
8
+ source_root DropzonejsRails::Engine.root.join('vendor/assets/javascripts')
9
+
10
+ def copy_files
11
+ copy_file 'dropzone.js', 'vendor/assets/javascripts/dropzone.js'
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,944 @@
1
+ ;(function(){
2
+
3
+
4
+ /**
5
+ * hasOwnProperty.
6
+ */
7
+
8
+ var has = Object.prototype.hasOwnProperty;
9
+
10
+ /**
11
+ * Require the given path.
12
+ *
13
+ * @param {String} path
14
+ * @return {Object} exports
15
+ * @api public
16
+ */
17
+
18
+ function require(path, parent, orig) {
19
+ var resolved = require.resolve(path);
20
+
21
+ // lookup failed
22
+ if (null == resolved) {
23
+ orig = orig || path;
24
+ parent = parent || 'root';
25
+ var err = new Error('Failed to require "' + orig + '" from "' + parent + '"');
26
+ err.path = orig;
27
+ err.parent = parent;
28
+ err.require = true;
29
+ throw err;
30
+ }
31
+
32
+ var module = require.modules[resolved];
33
+
34
+ // perform real require()
35
+ // by invoking the module's
36
+ // registered function
37
+ if (!module.exports) {
38
+ module.exports = {};
39
+ module.client = module.component = true;
40
+ module.call(this, module.exports, require.relative(resolved), module);
41
+ }
42
+
43
+ return module.exports;
44
+ }
45
+
46
+ /**
47
+ * Registered modules.
48
+ */
49
+
50
+ require.modules = {};
51
+
52
+ /**
53
+ * Registered aliases.
54
+ */
55
+
56
+ require.aliases = {};
57
+
58
+ /**
59
+ * Resolve `path`.
60
+ *
61
+ * Lookup:
62
+ *
63
+ * - PATH/index.js
64
+ * - PATH.js
65
+ * - PATH
66
+ *
67
+ * @param {String} path
68
+ * @return {String} path or null
69
+ * @api private
70
+ */
71
+
72
+ require.resolve = function(path) {
73
+ if (path.charAt(0) === '/') path = path.slice(1);
74
+ var index = path + '/index.js';
75
+
76
+ var paths = [
77
+ path,
78
+ path + '.js',
79
+ path + '.json',
80
+ path + '/index.js',
81
+ path + '/index.json'
82
+ ];
83
+
84
+ for (var i = 0; i < paths.length; i++) {
85
+ var path = paths[i];
86
+ if (has.call(require.modules, path)) return path;
87
+ }
88
+
89
+ if (has.call(require.aliases, index)) {
90
+ return require.aliases[index];
91
+ }
92
+ };
93
+
94
+ /**
95
+ * Normalize `path` relative to the current path.
96
+ *
97
+ * @param {String} curr
98
+ * @param {String} path
99
+ * @return {String}
100
+ * @api private
101
+ */
102
+
103
+ require.normalize = function(curr, path) {
104
+ var segs = [];
105
+
106
+ if ('.' != path.charAt(0)) return path;
107
+
108
+ curr = curr.split('/');
109
+ path = path.split('/');
110
+
111
+ for (var i = 0; i < path.length; ++i) {
112
+ if ('..' == path[i]) {
113
+ curr.pop();
114
+ } else if ('.' != path[i] && '' != path[i]) {
115
+ segs.push(path[i]);
116
+ }
117
+ }
118
+
119
+ return curr.concat(segs).join('/');
120
+ };
121
+
122
+ /**
123
+ * Register module at `path` with callback `definition`.
124
+ *
125
+ * @param {String} path
126
+ * @param {Function} definition
127
+ * @api private
128
+ */
129
+
130
+ require.register = function(path, definition) {
131
+ require.modules[path] = definition;
132
+ };
133
+
134
+ /**
135
+ * Alias a module definition.
136
+ *
137
+ * @param {String} from
138
+ * @param {String} to
139
+ * @api private
140
+ */
141
+
142
+ require.alias = function(from, to) {
143
+ if (!has.call(require.modules, from)) {
144
+ throw new Error('Failed to alias "' + from + '", it does not exist');
145
+ }
146
+ require.aliases[to] = from;
147
+ };
148
+
149
+ /**
150
+ * Return a require function relative to the `parent` path.
151
+ *
152
+ * @param {String} parent
153
+ * @return {Function}
154
+ * @api private
155
+ */
156
+
157
+ require.relative = function(parent) {
158
+ var p = require.normalize(parent, '..');
159
+
160
+ /**
161
+ * lastIndexOf helper.
162
+ */
163
+
164
+ function lastIndexOf(arr, obj) {
165
+ var i = arr.length;
166
+ while (i--) {
167
+ if (arr[i] === obj) return i;
168
+ }
169
+ return -1;
170
+ }
171
+
172
+ /**
173
+ * The relative require() itself.
174
+ */
175
+
176
+ function localRequire(path) {
177
+ var resolved = localRequire.resolve(path);
178
+ return require(resolved, parent, path);
179
+ }
180
+
181
+ /**
182
+ * Resolve relative to the parent.
183
+ */
184
+
185
+ localRequire.resolve = function(path) {
186
+ var c = path.charAt(0);
187
+ if ('/' == c) return path.slice(1);
188
+ if ('.' == c) return require.normalize(p, path);
189
+
190
+ // resolve deps by returning
191
+ // the dep in the nearest "deps"
192
+ // directory
193
+ var segs = parent.split('/');
194
+ var i = lastIndexOf(segs, 'deps') + 1;
195
+ if (!i) i = 0;
196
+ path = segs.slice(0, i + 1).join('/') + '/deps/' + path;
197
+ return path;
198
+ };
199
+
200
+ /**
201
+ * Check if module is defined at `path`.
202
+ */
203
+
204
+ localRequire.exists = function(path) {
205
+ return has.call(require.modules, localRequire.resolve(path));
206
+ };
207
+
208
+ return localRequire;
209
+ };
210
+ require.register("component-emitter/index.js", function(exports, require, module){
211
+
212
+ /**
213
+ * Expose `Emitter`.
214
+ */
215
+
216
+ module.exports = Emitter;
217
+
218
+ /**
219
+ * Initialize a new `Emitter`.
220
+ *
221
+ * @api public
222
+ */
223
+
224
+ function Emitter(obj) {
225
+ if (obj) return mixin(obj);
226
+ };
227
+
228
+ /**
229
+ * Mixin the emitter properties.
230
+ *
231
+ * @param {Object} obj
232
+ * @return {Object}
233
+ * @api private
234
+ */
235
+
236
+ function mixin(obj) {
237
+ for (var key in Emitter.prototype) {
238
+ obj[key] = Emitter.prototype[key];
239
+ }
240
+ return obj;
241
+ }
242
+
243
+ /**
244
+ * Listen on the given `event` with `fn`.
245
+ *
246
+ * @param {String} event
247
+ * @param {Function} fn
248
+ * @return {Emitter}
249
+ * @api public
250
+ */
251
+
252
+ Emitter.prototype.on = function(event, fn){
253
+ this._callbacks = this._callbacks || {};
254
+ (this._callbacks[event] = this._callbacks[event] || [])
255
+ .push(fn);
256
+ return this;
257
+ };
258
+
259
+ /**
260
+ * Adds an `event` listener that will be invoked a single
261
+ * time then automatically removed.
262
+ *
263
+ * @param {String} event
264
+ * @param {Function} fn
265
+ * @return {Emitter}
266
+ * @api public
267
+ */
268
+
269
+ Emitter.prototype.once = function(event, fn){
270
+ var self = this;
271
+ this._callbacks = this._callbacks || {};
272
+
273
+ function on() {
274
+ self.off(event, on);
275
+ fn.apply(this, arguments);
276
+ }
277
+
278
+ fn._off = on;
279
+ this.on(event, on);
280
+ return this;
281
+ };
282
+
283
+ /**
284
+ * Remove the given callback for `event` or all
285
+ * registered callbacks.
286
+ *
287
+ * @param {String} event
288
+ * @param {Function} fn
289
+ * @return {Emitter}
290
+ * @api public
291
+ */
292
+
293
+ Emitter.prototype.off =
294
+ Emitter.prototype.removeListener =
295
+ Emitter.prototype.removeAllListeners = function(event, fn){
296
+ this._callbacks = this._callbacks || {};
297
+ var callbacks = this._callbacks[event];
298
+ if (!callbacks) return this;
299
+
300
+ // remove all handlers
301
+ if (1 == arguments.length) {
302
+ delete this._callbacks[event];
303
+ return this;
304
+ }
305
+
306
+ // remove specific handler
307
+ var i = callbacks.indexOf(fn._off || fn);
308
+ if (~i) callbacks.splice(i, 1);
309
+ return this;
310
+ };
311
+
312
+ /**
313
+ * Emit `event` with the given args.
314
+ *
315
+ * @param {String} event
316
+ * @param {Mixed} ...
317
+ * @return {Emitter}
318
+ */
319
+
320
+ Emitter.prototype.emit = function(event){
321
+ this._callbacks = this._callbacks || {};
322
+ var args = [].slice.call(arguments, 1)
323
+ , callbacks = this._callbacks[event];
324
+
325
+ if (callbacks) {
326
+ callbacks = callbacks.slice(0);
327
+ for (var i = 0, len = callbacks.length; i < len; ++i) {
328
+ callbacks[i].apply(this, args);
329
+ }
330
+ }
331
+
332
+ return this;
333
+ };
334
+
335
+ /**
336
+ * Return array of callbacks for `event`.
337
+ *
338
+ * @param {String} event
339
+ * @return {Array}
340
+ * @api public
341
+ */
342
+
343
+ Emitter.prototype.listeners = function(event){
344
+ this._callbacks = this._callbacks || {};
345
+ return this._callbacks[event] || [];
346
+ };
347
+
348
+ /**
349
+ * Check if this emitter has `event` handlers.
350
+ *
351
+ * @param {String} event
352
+ * @return {Boolean}
353
+ * @api public
354
+ */
355
+
356
+ Emitter.prototype.hasListeners = function(event){
357
+ return !! this.listeners(event).length;
358
+ };
359
+
360
+ });
361
+ require.register("dropzone/index.js", function(exports, require, module){
362
+
363
+
364
+ /**
365
+ * Exposing dropzone
366
+ */
367
+ module.exports = require("./lib/dropzone.js");
368
+
369
+ });
370
+ require.register("dropzone/lib/dropzone.js", function(exports, require, module){
371
+ // Generated by CoffeeScript 1.4.0
372
+
373
+ /*
374
+ #
375
+ # More info at [www.dropzonejs.com](http://www.dropzonejs.com)
376
+ #
377
+ # Copyright (c) 2012, Matias Meno
378
+ #
379
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
380
+ # of this software and associated documentation files (the "Software"), to deal
381
+ # in the Software without restriction, including without limitation the rights
382
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
383
+ # copies of the Software, and to permit persons to whom the Software is
384
+ # furnished to do so, subject to the following conditions:
385
+ #
386
+ # The above copyright notice and this permission notice shall be included in
387
+ # all copies or substantial portions of the Software.
388
+ #
389
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
390
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
391
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
392
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
393
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
394
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
395
+ # THE SOFTWARE.
396
+ #
397
+ */
398
+
399
+
400
+ (function() {
401
+ var Dropzone, Em, camelize, o, without,
402
+ __hasProp = {}.hasOwnProperty,
403
+ __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
404
+ __slice = [].slice;
405
+
406
+ o = typeof jQuery !== "undefined" && jQuery !== null ? jQuery : require("jquery");
407
+
408
+ Em = typeof Emitter !== "undefined" && Emitter !== null ? Emitter : require("emitter");
409
+
410
+ Dropzone = (function(_super) {
411
+
412
+ __extends(Dropzone, _super);
413
+
414
+ Dropzone.prototype.version = "1.3.9";
415
+
416
+ /*
417
+ This is a list of all available events you can register on a dropzone object.
418
+
419
+ You can register an event handler like this:
420
+
421
+ dropzone.on("dragEnter", function() { });
422
+ */
423
+
424
+
425
+ Dropzone.prototype.events = ["drop", "dragstart", "dragend", "dragenter", "dragover", "dragleave", "selectedfiles", "addedfile", "removedfile", "thumbnail", "error", "processingfile", "uploadprogress", "sending", "success", "complete", "reset"];
426
+
427
+ Dropzone.prototype.blacklistedBrowsers = [/opera.*Macintosh.*version\/12/i];
428
+
429
+ Dropzone.prototype.defaultOptions = {
430
+ url: null,
431
+ parallelUploads: 2,
432
+ maxFilesize: 256,
433
+ paramName: "file",
434
+ createImageThumbnails: true,
435
+ maxThumbnailFilesize: 2,
436
+ thumbnailWidth: 100,
437
+ thumbnailHeight: 100,
438
+ params: {},
439
+ clickable: true,
440
+ enqueueForUpload: true,
441
+ previewsContainer: null,
442
+ accept: function(file, done) {
443
+ return done();
444
+ },
445
+ fallback: function() {
446
+ this.element.addClass("browser-not-supported");
447
+ this.element.find(".message").removeClass("default");
448
+ this.element.find(".message span").html("Your browser does not support drag'n'drop file uploads.");
449
+ this.element.append("Please use the fallback form below to upload your files like in the olden days.</p>");
450
+ return this.element.append(this.getFallbackForm());
451
+ },
452
+ /*
453
+ Those functions register themselves to the events on init and handle all
454
+ the user interface specific stuff. Overwriting them won't break the upload
455
+ but can break the way it's displayed.
456
+ You can overwrite them if you don't like the default behavior. If you just
457
+ want to add an additional event handler, register it on the dropzone object
458
+ and don't overwrite those options.
459
+ */
460
+
461
+ drop: function(e) {
462
+ return this.element.removeClass("drag-hover");
463
+ },
464
+ dragstart: o.noop,
465
+ dragend: function(e) {
466
+ return this.element.removeClass("drag-hover");
467
+ },
468
+ dragenter: function(e) {
469
+ return this.element.addClass("drag-hover");
470
+ },
471
+ dragover: function(e) {
472
+ return this.element.addClass("drag-hover");
473
+ },
474
+ dragleave: function(e) {
475
+ return this.element.removeClass("drag-hover");
476
+ },
477
+ selectedfiles: function(files) {
478
+ if (this.element.is(this.previewsContainer)) {
479
+ return this.element.addClass("started");
480
+ }
481
+ },
482
+ reset: function() {
483
+ return this.element.removeClass("started");
484
+ },
485
+ addedfile: function(file) {
486
+ file.previewTemplate = o(this.options.previewTemplate);
487
+ this.previewsContainer.append(file.previewTemplate);
488
+ file.previewTemplate.find(".filename span").text(file.name);
489
+ return file.previewTemplate.find(".details").append(o("<div class=\"size\">" + (this.filesize(file.size)) + "</div>"));
490
+ },
491
+ removedfile: function(file) {
492
+ return file.previewTemplate.remove();
493
+ },
494
+ thumbnail: function(file, dataUrl) {
495
+ file.previewTemplate.removeClass("file-preview").addClass("image-preview");
496
+ return file.previewTemplate.find(".details").append(o("<img alt=\"" + file.name + "\" src=\"" + dataUrl + "\"/>"));
497
+ },
498
+ error: function(file, message) {
499
+ file.previewTemplate.addClass("error");
500
+ return file.previewTemplate.find(".error-message span").text(message);
501
+ },
502
+ processingfile: function(file) {
503
+ return file.previewTemplate.addClass("processing");
504
+ },
505
+ uploadprogress: function(file, progress) {
506
+ return file.previewTemplate.find(".progress .upload").css({
507
+ width: "" + progress + "%"
508
+ });
509
+ },
510
+ sending: o.noop,
511
+ success: function(file) {
512
+ return file.previewTemplate.addClass("success");
513
+ },
514
+ complete: o.noop,
515
+ previewTemplate: "<div class=\"preview file-preview\">\n <div class=\"details\">\n <div class=\"filename\"><span></span></div>\n </div>\n <div class=\"progress\"><span class=\"upload\"></span></div>\n <div class=\"success-mark\"><span>✔</span></div>\n <div class=\"error-mark\"><span>✘</span></div>\n <div class=\"error-message\"><span></span></div>\n</div>"
516
+ };
517
+
518
+ function Dropzone(element, options) {
519
+ var elementId, elementOptions, extend, _ref;
520
+ this.defaultOptions.previewTemplate = this.defaultOptions.previewTemplate.replace(/\n*/g, "");
521
+ this.element = o(element);
522
+ if (this.element.length !== 1) {
523
+ throw new Error("You can only instantiate dropzone on a single element.");
524
+ }
525
+ if (this.element.data("dropzone")) {
526
+ throw new Error("Dropzone already attached.");
527
+ }
528
+ this.element.data("dropzone", this);
529
+ elementId = this.element.attr("id");
530
+ elementOptions = (_ref = (elementId ? Dropzone.options[camelize(elementId)] : void 0)) != null ? _ref : {};
531
+ this.elementTagName = this.element.get(0).tagName;
532
+ extend = function() {
533
+ var key, object, objects, target, val, _i, _len;
534
+ target = arguments[0], objects = 2 <= arguments.length ? __slice.call(arguments, 1) : [];
535
+ for (_i = 0, _len = objects.length; _i < _len; _i++) {
536
+ object = objects[_i];
537
+ for (key in object) {
538
+ val = object[key];
539
+ target[key] = val;
540
+ }
541
+ }
542
+ return target;
543
+ };
544
+ this.options = extend({}, this.defaultOptions, elementOptions, options != null ? options : {});
545
+ if (this.options.url == null) {
546
+ this.options.url = this.element.attr("action");
547
+ }
548
+ if (!this.options.url) {
549
+ throw new Error("No URL provided.");
550
+ }
551
+ this.previewsContainer = this.options.previewsContainer ? o(this.options.previewsContainer) : this.element;
552
+ this.init();
553
+ }
554
+
555
+ Dropzone.prototype.init = function() {
556
+ var capableBrowser, regex, _i, _len, _ref, _ref1,
557
+ _this = this;
558
+ if (this.elementTagName === "form" && this.element.attr("enctype") !== "multipart/form-data") {
559
+ this.element.attr("enctype", "multipart/form-data");
560
+ }
561
+ if (this.element.hasClass("dropzone") && this.element.find(".message").length === 0) {
562
+ this.element.append(o("<div class=\"default message\"><span>Drop files here to upload</span></div>"));
563
+ }
564
+ capableBrowser = true;
565
+ if (window.File && window.FileReader && window.FileList && window.Blob && window.FormData) {
566
+ _ref = this.blacklistedBrowsers;
567
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
568
+ regex = _ref[_i];
569
+ if (regex.test(navigator.userAgent)) {
570
+ capableBrowser = false;
571
+ continue;
572
+ }
573
+ }
574
+ } else {
575
+ capableBrowser = false;
576
+ }
577
+ if (!capableBrowser) {
578
+ return this.options.fallback.call(this);
579
+ }
580
+ if (this.options.clickable) {
581
+ this.element.addClass("clickable");
582
+ this.hiddenFileInput = o("<input type=\"file\" multiple />");
583
+ this.element.click(function(evt) {
584
+ var target;
585
+ target = o(evt.target);
586
+ if (target.is(_this.element) || target.is(_this.element.find(".message"))) {
587
+ return _this.hiddenFileInput.click();
588
+ }
589
+ });
590
+ this.hiddenFileInput.change(function() {
591
+ var files;
592
+ files = _this.hiddenFileInput.get(0).files;
593
+ _this.emit("selectedfiles", files);
594
+ if (files.length) {
595
+ return _this.handleFiles(files);
596
+ }
597
+ });
598
+ }
599
+ this.files = [];
600
+ this.filesQueue = [];
601
+ this.filesProcessing = [];
602
+ this.URL = (_ref1 = window.URL) != null ? _ref1 : window.webkitURL;
603
+ return this.setupEventListeners();
604
+ };
605
+
606
+ Dropzone.prototype.getFallbackForm = function() {
607
+ var fields;
608
+ fields = o("<div class=\"fallback-elements\"><input type=\"file\" name=\"" + this.options.paramName + "\" multiple=\"multiple\" /><button type=\"submit\">Upload!</button></div>");
609
+ if (this.elementTagName !== "FORM") {
610
+ fields = o("<form action=\"" + this.options.url + "\" enctype=\"multipart/form-data\" method=\"post\"></form>").append(fields);
611
+ } else {
612
+ if (!this.element.attr("enctype")) {
613
+ this.element.attr("enctype", "multipart/form-data");
614
+ }
615
+ if (!this.element.attr("method")) {
616
+ this.element.attr("method", "post");
617
+ }
618
+ }
619
+ return fields;
620
+ };
621
+
622
+ Dropzone.prototype.setupEventListeners = function() {
623
+ var eventName, noPropagation, _i, _len, _ref,
624
+ _this = this;
625
+ _ref = this.events;
626
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
627
+ eventName = _ref[_i];
628
+ this.on(eventName, this.options[eventName]);
629
+ }
630
+ noPropagation = function(e) {
631
+ e.stopPropagation();
632
+ return e.preventDefault();
633
+ };
634
+ this.element.on("dragstart.dropzone", function(e) {
635
+ return _this.emit("dragstart", e);
636
+ });
637
+ this.element.on("dragenter.dropzone", function(e) {
638
+ noPropagation(e);
639
+ return _this.emit("dragenter", e);
640
+ });
641
+ this.element.on("dragover.dropzone", function(e) {
642
+ noPropagation(e);
643
+ return _this.emit("dragover", e);
644
+ });
645
+ this.element.on("dragleave.dropzone", function(e) {
646
+ return _this.emit("dragleave", e);
647
+ });
648
+ this.element.on("drop.dropzone", function(e) {
649
+ noPropagation(e);
650
+ _this.drop(e);
651
+ return _this.emit("drop", e);
652
+ });
653
+ return this.element.on("dragend.dropzone", function(e) {
654
+ return _this.emit("dragend", e);
655
+ });
656
+ };
657
+
658
+ Dropzone.prototype.removeEventListeners = function() {
659
+ return this.element.off(".dropzone");
660
+ };
661
+
662
+ Dropzone.prototype.disable = function() {
663
+ this.removeEventListeners();
664
+ this.files = [];
665
+ this.filesProcessing = [];
666
+ return this.filesQueue = [];
667
+ };
668
+
669
+ Dropzone.prototype.filesize = function(size) {
670
+ var string;
671
+ if (size >= 100000000000) {
672
+ size = size / 100000000000;
673
+ string = "TB";
674
+ } else if (size >= 100000000) {
675
+ size = size / 100000000;
676
+ string = "GB";
677
+ } else if (size >= 100000) {
678
+ size = size / 100000;
679
+ string = "MB";
680
+ } else if (size >= 100) {
681
+ size = size / 100;
682
+ string = "KB";
683
+ } else {
684
+ size = size * 10;
685
+ string = "b";
686
+ }
687
+ return "<strong>" + (Math.round(size) / 10) + "</strong> " + string;
688
+ };
689
+
690
+ Dropzone.prototype.drop = function(e) {
691
+ var files;
692
+ if (!e.originalEvent.dataTransfer) {
693
+ return;
694
+ }
695
+ files = e.originalEvent.dataTransfer.files;
696
+ this.emit("selectedfiles", files);
697
+ if (files.length) {
698
+ return this.handleFiles(files);
699
+ }
700
+ };
701
+
702
+ Dropzone.prototype.handleFiles = function(files) {
703
+ var file, _i, _len, _results;
704
+ _results = [];
705
+ for (_i = 0, _len = files.length; _i < _len; _i++) {
706
+ file = files[_i];
707
+ _results.push(this.addFile(file));
708
+ }
709
+ return _results;
710
+ };
711
+
712
+ Dropzone.prototype.accept = function(file, done) {
713
+ if (file.size > this.options.maxFilesize * 1024 * 1024) {
714
+ return done("File is too big (" + (Math.round(file.size / 1024 / 10.24) / 100) + "MB). Max filesize: " + this.options.maxFilesize + "MB");
715
+ } else {
716
+ return this.options.accept.call(this, file, done);
717
+ }
718
+ };
719
+
720
+ Dropzone.prototype.addFile = function(file) {
721
+ var _this = this;
722
+ this.files.push(file);
723
+ this.emit("addedfile", file);
724
+ if (this.options.createImageThumbnails && file.type.match(/image.*/) && file.size <= this.options.maxThumbnailFilesize * 1024 * 1024) {
725
+ this.createThumbnail(file);
726
+ }
727
+ return this.accept(file, function(error) {
728
+ if (error) {
729
+ return _this.errorProcessing(file, error);
730
+ } else {
731
+ if (_this.options.enqueueForUpload) {
732
+ _this.filesQueue.push(file);
733
+ return _this.processQueue();
734
+ }
735
+ }
736
+ });
737
+ };
738
+
739
+ Dropzone.prototype.removeFile = function(file) {
740
+ if (file.processing) {
741
+ throw new Error("Can't remove file currently processing");
742
+ }
743
+ this.files = without(this.files, file);
744
+ this.filesQueue = without(this.filesQueue, file);
745
+ this.emit("removedfile", file);
746
+ if (this.files.length === 0) {
747
+ return this.emit("reset");
748
+ }
749
+ };
750
+
751
+ Dropzone.prototype.createThumbnail = function(file) {
752
+ var fileReader,
753
+ _this = this;
754
+ fileReader = new FileReader;
755
+ fileReader.onload = function() {
756
+ var img;
757
+ img = new Image;
758
+ img.onload = function() {
759
+ var canvas, ctx, srcHeight, srcRatio, srcWidth, srcX, srcY, thumbnail, trgHeight, trgRatio, trgWidth, trgX, trgY;
760
+ canvas = document.createElement("canvas");
761
+ ctx = canvas.getContext("2d");
762
+ srcX = 0;
763
+ srcY = 0;
764
+ srcWidth = img.width;
765
+ srcHeight = img.height;
766
+ canvas.width = _this.options.thumbnailWidth;
767
+ canvas.height = _this.options.thumbnailHeight;
768
+ trgX = 0;
769
+ trgY = 0;
770
+ trgWidth = canvas.width;
771
+ trgHeight = canvas.height;
772
+ srcRatio = img.width / img.height;
773
+ trgRatio = canvas.width / canvas.height;
774
+ if (img.height < canvas.height || img.width < canvas.width) {
775
+ trgHeight = srcHeight;
776
+ trgWidth = srcWidth;
777
+ } else {
778
+ if (srcRatio > trgRatio) {
779
+ srcHeight = img.height;
780
+ srcWidth = srcHeight * trgRatio;
781
+ } else {
782
+ srcWidth = img.width;
783
+ srcHeight = srcWidth / trgRatio;
784
+ }
785
+ }
786
+ srcX = (img.width - srcWidth) / 2;
787
+ srcY = (img.height - srcHeight) / 2;
788
+ trgY = (canvas.height - trgHeight) / 2;
789
+ trgX = (canvas.width - trgWidth) / 2;
790
+ ctx.drawImage(img, srcX, srcY, srcWidth, srcHeight, trgX, trgY, trgWidth, trgHeight);
791
+ thumbnail = canvas.toDataURL("image/png");
792
+ return _this.emit("thumbnail", file, thumbnail);
793
+ };
794
+ return img.src = fileReader.result;
795
+ };
796
+ return fileReader.readAsDataURL(file);
797
+ };
798
+
799
+ Dropzone.prototype.processQueue = function() {
800
+ var i, parallelUploads, processingLength;
801
+ parallelUploads = this.options.parallelUploads;
802
+ processingLength = this.filesProcessing.length;
803
+ i = processingLength;
804
+ while (i < parallelUploads) {
805
+ if (!this.filesQueue.length) {
806
+ return;
807
+ }
808
+ this.processFile(this.filesQueue.shift());
809
+ i++;
810
+ }
811
+ };
812
+
813
+ Dropzone.prototype.processFile = function(file) {
814
+ this.filesProcessing.push(file);
815
+ file.processing = true;
816
+ this.emit("processingfile", file);
817
+ return this.uploadFile(file);
818
+ };
819
+
820
+ Dropzone.prototype.uploadFile = function(file) {
821
+ var formData, handleError, input, inputElement, inputName, key, name, progressObj, xhr, _i, _len, _ref, _ref1, _ref2,
822
+ _this = this;
823
+ xhr = new XMLHttpRequest();
824
+ xhr.open("POST", this.options.url, true);
825
+ handleError = function() {
826
+ return _this.errorProcessing(file, xhr.responseText || ("Server responded with " + xhr.status + " code."));
827
+ };
828
+ xhr.onload = function(e) {
829
+ var response;
830
+ if (xhr.status !== 200) {
831
+ return handleError();
832
+ } else {
833
+ _this.emit("uploadprogress", file, 100);
834
+ response = xhr.responseText;
835
+ if (xhr.getResponseHeader("content-type") && ~xhr.getResponseHeader("content-type").indexOf("application/json")) {
836
+ response = JSON.parse(response);
837
+ }
838
+ return _this.finished(file, response, e);
839
+ }
840
+ };
841
+ xhr.onerror = function() {
842
+ return handleError();
843
+ };
844
+ progressObj = (_ref = xhr.upload) != null ? _ref : xhr;
845
+ progressObj.onprogress = function(e) {
846
+ return _this.emit("uploadprogress", file, Math.max(0, Math.min(100, (e.loaded / e.total) * 100)));
847
+ };
848
+ xhr.setRequestHeader("Accept", "application/json");
849
+ xhr.setRequestHeader("Cache-Control", "no-cache");
850
+ xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
851
+ xhr.setRequestHeader("X-File-Name", file.name);
852
+ formData = new FormData();
853
+ if (this.options.params) {
854
+ _ref1 = this.options.params;
855
+ for (key in _ref1) {
856
+ name = _ref1[key];
857
+ formData.append(name, key);
858
+ }
859
+ }
860
+ if (this.elementTagName = "FORM") {
861
+ _ref2 = this.element.find("input, textarea, select, button");
862
+ for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
863
+ inputElement = _ref2[_i];
864
+ input = o(inputElement);
865
+ inputName = input.attr("name");
866
+ if (!input.attr("type") || input.attr("type").toLowerCase() !== "checkbox" || inputElement.checked) {
867
+ formData.append(input.attr("name"), input.val());
868
+ }
869
+ }
870
+ }
871
+ this.emit("sending", file, xhr, formData);
872
+ formData.append(this.options.paramName, file);
873
+ return xhr.send(formData);
874
+ };
875
+
876
+ Dropzone.prototype.finished = function(file, responseText, e) {
877
+ this.filesProcessing = without(this.filesProcessing, file);
878
+ file.processing = false;
879
+ this.processQueue();
880
+ this.emit("success", file, responseText, e);
881
+ this.emit("finished", file, responseText, e);
882
+ return this.emit("complete", file);
883
+ };
884
+
885
+ Dropzone.prototype.errorProcessing = function(file, message) {
886
+ this.filesProcessing = without(this.filesProcessing, file);
887
+ file.processing = false;
888
+ this.processQueue();
889
+ this.emit("error", file, message);
890
+ return this.emit("complete", file);
891
+ };
892
+
893
+ return Dropzone;
894
+
895
+ })(Em);
896
+
897
+ Dropzone.options = {};
898
+
899
+ without = function(list, rejectedItem) {
900
+ var item, _i, _len, _results;
901
+ _results = [];
902
+ for (_i = 0, _len = list.length; _i < _len; _i++) {
903
+ item = list[_i];
904
+ if (item !== rejectedItem) {
905
+ _results.push(item);
906
+ }
907
+ }
908
+ return _results;
909
+ };
910
+
911
+ camelize = function(str) {
912
+ return str.replace(/[\-_](\w)/g, function(match) {
913
+ return match[1].toUpperCase();
914
+ });
915
+ };
916
+
917
+ o.fn.dropzone = function(options) {
918
+ return this.each(function() {
919
+ return new Dropzone(this, options);
920
+ });
921
+ };
922
+
923
+ o(function() {
924
+ return o(".dropzone").dropzone();
925
+ });
926
+
927
+ if (typeof module !== "undefined" && module !== null) {
928
+ module.exports = Dropzone;
929
+ } else {
930
+ window.Dropzone = Dropzone;
931
+ }
932
+
933
+ }).call(this);
934
+
935
+ });
936
+ require.alias("component-emitter/index.js", "dropzone/deps/emitter/index.js");
937
+
938
+ if (typeof exports == "object") {
939
+ module.exports = require("dropzone");
940
+ } else if (typeof define == "function" && define.amd) {
941
+ define(require("dropzone"));
942
+ } else {
943
+ window["Dropzone"] = require("dropzone");
944
+ }})();
metadata ADDED
@@ -0,0 +1,76 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: dropzonejs-rails
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - José Nahuel Cuesta Luengo
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-02-27 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rails
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>'
20
+ - !ruby/object:Gem::Version
21
+ version: '3.1'
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.1'
30
+ description: Adds Dropzone, a great JS File upload by Matias Meno, to the Rails Asset
31
+ pipeline.
32
+ email:
33
+ - nahuelcuestaluengo@gmail.com
34
+ executables: []
35
+ extensions: []
36
+ extra_rdoc_files: []
37
+ files:
38
+ - lib/dropzonejs-rails/engine.rb
39
+ - lib/dropzonejs-rails/version.rb
40
+ - lib/dropzonejs-rails.rb
41
+ - lib/generators/dropzonejs-rails/install/install_generator.rb
42
+ - vendor/assets/javascripts/dropzone.js
43
+ - LICENSE
44
+ - Rakefile
45
+ - README.md
46
+ homepage: http://www.github.com/ncuesta/dropzonejs-rails
47
+ licenses: []
48
+ post_install_message:
49
+ rdoc_options: []
50
+ require_paths:
51
+ - lib
52
+ required_ruby_version: !ruby/object:Gem::Requirement
53
+ none: false
54
+ requirements:
55
+ - - ! '>='
56
+ - !ruby/object:Gem::Version
57
+ version: '0'
58
+ segments:
59
+ - 0
60
+ hash: 4125991172676457206
61
+ required_rubygems_version: !ruby/object:Gem::Requirement
62
+ none: false
63
+ requirements:
64
+ - - ! '>='
65
+ - !ruby/object:Gem::Version
66
+ version: '0'
67
+ segments:
68
+ - 0
69
+ hash: 4125991172676457206
70
+ requirements: []
71
+ rubyforge_project:
72
+ rubygems_version: 1.8.25
73
+ signing_key:
74
+ specification_version: 3
75
+ summary: Integrates Dropzone JS File upload into Rails Asset pipeline.
76
+ test_files: []