1 // Uses AMD or browser globals to create a jQuery plugin.
3 if (typeof define === 'function' && define.amd) {
4 // AMD. Register as an anonymous module.
5 define(['jquery'], factory);
10 } (function (jQuery) {
11 var module = { exports: { } }; // Fake component
16 * More info at [www.dropzonejs.com](http://www.dropzonejs.com)
18 * Copyright (c) 2012, Matias Meno
20 * Permission is hereby granted, free of charge, to any person obtaining a copy
21 * of this software and associated documentation files (the "Software"), to deal
22 * in the Software without restriction, including without limitation the rights
23 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
24 * copies of the Software, and to permit persons to whom the Software is
25 * furnished to do so, subject to the following conditions:
27 * The above copyright notice and this permission notice shall be included in
28 * all copies or substantial portions of the Software.
30 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
31 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
32 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
33 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
34 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
35 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
41 var Dropzone, Emitter, camelize, contentLoaded, detectVerticalSquash, drawImageIOSFix, noop, without,
43 __hasProp = {}.hasOwnProperty,
44 __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; };
48 Emitter = (function() {
51 Emitter.prototype.addEventListener = Emitter.prototype.on;
53 Emitter.prototype.on = function(event, fn) {
54 this._callbacks = this._callbacks || {};
55 if (!this._callbacks[event]) {
56 this._callbacks[event] = [];
58 this._callbacks[event].push(fn);
62 Emitter.prototype.emit = function() {
63 var args, callback, callbacks, event, _i, _len;
64 event = arguments[0], args = 2 <= arguments.length ? __slice.call(arguments, 1) : [];
65 this._callbacks = this._callbacks || {};
66 callbacks = this._callbacks[event];
68 for (_i = 0, _len = callbacks.length; _i < _len; _i++) {
69 callback = callbacks[_i];
70 callback.apply(this, args);
76 Emitter.prototype.removeListener = Emitter.prototype.off;
78 Emitter.prototype.removeAllListeners = Emitter.prototype.off;
80 Emitter.prototype.removeEventListener = Emitter.prototype.off;
82 Emitter.prototype.off = function(event, fn) {
83 var callback, callbacks, i, _i, _len;
84 if (!this._callbacks || arguments.length === 0) {
88 callbacks = this._callbacks[event];
92 if (arguments.length === 1) {
93 delete this._callbacks[event];
96 for (i = _i = 0, _len = callbacks.length; _i < _len; i = ++_i) {
97 callback = callbacks[i];
98 if (callback === fn) {
99 callbacks.splice(i, 1);
110 Dropzone = (function(_super) {
111 var extend, resolveOption;
113 __extends(Dropzone, _super);
115 Dropzone.prototype.Emitter = Emitter;
119 This is a list of all available events you can register on a dropzone object.
121 You can register an event handler like this:
123 dropzone.on("dragEnter", function() { });
126 Dropzone.prototype.events = ["drop", "dragstart", "dragend", "dragenter", "dragover", "dragleave", "addedfile", "addedfiles", "removedfile", "thumbnail", "error", "errormultiple", "processing", "processingmultiple", "uploadprogress", "totaluploadprogress", "sending", "sendingmultiple", "success", "successmultiple", "canceled", "canceledmultiple", "complete", "completemultiple", "reset", "maxfilesexceeded", "maxfilesreached", "queuecomplete"];
128 Dropzone.prototype.defaultOptions = {
131 withCredentials: false,
133 uploadMultiple: false,
136 createImageThumbnails: true,
137 maxThumbnailFilesize: 10,
139 thumbnailHeight: 120,
144 ignoreHiddenFiles: true,
146 acceptedMimeTypes: null,
147 autoProcessQueue: true,
149 addRemoveLinks: false,
150 previewsContainer: null,
151 hiddenInputContainer: "body",
153 renameFilename: null,
154 dictDefaultMessage: "Drop files here to upload",
155 dictFallbackMessage: "Your browser does not support drag'n'drop file uploads.",
156 dictFallbackText: "Please use the fallback form below to upload your files like in the olden days.",
157 dictFileTooBig: "File is too big ({{filesize}}MiB). Max filesize: {{maxFilesize}}MiB.",
158 dictInvalidFileType: "You can't upload files of this type.",
159 dictResponseError: "Server responded with {{statusCode}} code.",
160 dictCancelUpload: "Cancel upload",
161 dictCancelUploadConfirmation: "Are you sure you want to cancel this upload?",
162 dictRemoveFile: "Remove file",
163 dictRemoveFileConfirmation: null,
164 dictMaxFilesExceeded: "You can not upload any more files.",
165 accept: function(file, done) {
171 forceFallback: false,
172 fallback: function() {
173 var child, messageElement, span, _i, _len, _ref;
174 this.element.className = "" + this.element.className + " dz-browser-not-supported";
175 _ref = this.element.getElementsByTagName("div");
176 for (_i = 0, _len = _ref.length; _i < _len; _i++) {
178 if (/(^| )dz-message($| )/.test(child.className)) {
179 messageElement = child;
180 child.className = "dz-message";
184 if (!messageElement) {
185 messageElement = Dropzone.createElement("<div class=\"dz-message\"><span></span></div>");
186 this.element.appendChild(messageElement);
188 span = messageElement.getElementsByTagName("span")[0];
190 if (span.textContent != null) {
191 span.textContent = this.options.dictFallbackMessage;
192 } else if (span.innerText != null) {
193 span.innerText = this.options.dictFallbackMessage;
196 return this.element.appendChild(this.getFallbackForm());
198 resize: function(file) {
199 var info, srcRatio, trgRatio;
203 srcWidth: file.width,
204 srcHeight: file.height
206 srcRatio = file.width / file.height;
207 info.optWidth = this.options.thumbnailWidth;
208 info.optHeight = this.options.thumbnailHeight;
209 if ((info.optWidth == null) && (info.optHeight == null)) {
210 info.optWidth = info.srcWidth;
211 info.optHeight = info.srcHeight;
212 } else if (info.optWidth == null) {
213 info.optWidth = srcRatio * info.optHeight;
214 } else if (info.optHeight == null) {
215 info.optHeight = (1 / srcRatio) * info.optWidth;
217 trgRatio = info.optWidth / info.optHeight;
218 if (file.height < info.optHeight || file.width < info.optWidth) {
219 info.trgHeight = info.srcHeight;
220 info.trgWidth = info.srcWidth;
222 if (srcRatio > trgRatio) {
223 info.srcHeight = file.height;
224 info.srcWidth = info.srcHeight * trgRatio;
226 info.srcWidth = file.width;
227 info.srcHeight = info.srcWidth / trgRatio;
230 info.srcX = (file.width - info.srcWidth) / 2;
231 info.srcY = (file.height - info.srcHeight) / 2;
236 Those functions register themselves to the events on init and handle all
237 the user interface specific stuff. Overwriting them won't break the upload
238 but can break the way it's displayed.
239 You can overwrite them if you don't like the default behavior. If you just
240 want to add an additional event handler, register it on the dropzone object
241 and don't overwrite those options.
244 return this.element.classList.remove("dz-drag-hover");
247 dragend: function(e) {
248 return this.element.classList.remove("dz-drag-hover");
250 dragenter: function(e) {
251 return this.element.classList.add("dz-drag-hover");
253 dragover: function(e) {
254 return this.element.classList.add("dz-drag-hover");
256 dragleave: function(e) {
257 return this.element.classList.remove("dz-drag-hover");
261 return this.element.classList.remove("dz-started");
263 addedfile: function(file) {
264 var node, removeFileEvent, removeLink, _i, _j, _k, _len, _len1, _len2, _ref, _ref1, _ref2, _results;
265 if (this.element === this.previewsContainer) {
266 this.element.classList.add("dz-started");
268 if (this.previewsContainer) {
269 file.previewElement = Dropzone.createElement(this.options.previewTemplate.trim());
270 file.previewTemplate = file.previewElement;
271 this.previewsContainer.appendChild(file.previewElement);
272 _ref = file.previewElement.querySelectorAll("[data-dz-name]");
273 for (_i = 0, _len = _ref.length; _i < _len; _i++) {
275 node.textContent = this._renameFilename(file.name);
277 _ref1 = file.previewElement.querySelectorAll("[data-dz-size]");
278 for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) {
280 node.innerHTML = this.filesize(file.size);
282 if (this.options.addRemoveLinks) {
283 file._removeLink = Dropzone.createElement("<a class=\"dz-remove\" href=\"javascript:undefined;\" data-dz-remove>" + this.options.dictRemoveFile + "</a>");
284 file.previewElement.appendChild(file._removeLink);
286 removeFileEvent = (function(_this) {
290 if (file.status === Dropzone.UPLOADING) {
291 return Dropzone.confirm(_this.options.dictCancelUploadConfirmation, function() {
292 return _this.removeFile(file);
295 if (_this.options.dictRemoveFileConfirmation) {
296 return Dropzone.confirm(_this.options.dictRemoveFileConfirmation, function() {
297 return _this.removeFile(file);
300 return _this.removeFile(file);
305 _ref2 = file.previewElement.querySelectorAll("[data-dz-remove]");
307 for (_k = 0, _len2 = _ref2.length; _k < _len2; _k++) {
308 removeLink = _ref2[_k];
309 _results.push(removeLink.addEventListener("click", removeFileEvent));
314 removedfile: function(file) {
316 if (file.previewElement) {
317 if ((_ref = file.previewElement) != null) {
318 _ref.parentNode.removeChild(file.previewElement);
321 return this._updateMaxFilesReachedClass();
323 thumbnail: function(file, dataUrl) {
324 var thumbnailElement, _i, _len, _ref;
325 if (file.previewElement) {
326 file.previewElement.classList.remove("dz-file-preview");
327 _ref = file.previewElement.querySelectorAll("[data-dz-thumbnail]");
328 for (_i = 0, _len = _ref.length; _i < _len; _i++) {
329 thumbnailElement = _ref[_i];
330 thumbnailElement.alt = file.name;
331 thumbnailElement.src = dataUrl;
333 return setTimeout(((function(_this) {
335 return file.previewElement.classList.add("dz-image-preview");
340 error: function(file, message) {
341 var node, _i, _len, _ref, _results;
342 if (file.previewElement) {
343 file.previewElement.classList.add("dz-error");
344 if (typeof message !== "String" && message.error) {
345 message = message.error;
347 _ref = file.previewElement.querySelectorAll("[data-dz-errormessage]");
349 for (_i = 0, _len = _ref.length; _i < _len; _i++) {
351 _results.push(node.textContent = message);
357 processing: function(file) {
358 if (file.previewElement) {
359 file.previewElement.classList.add("dz-processing");
360 if (file._removeLink) {
361 return file._removeLink.textContent = this.options.dictCancelUpload;
365 processingmultiple: noop,
366 uploadprogress: function(file, progress, bytesSent) {
367 var node, _i, _len, _ref, _results;
368 if (file.previewElement) {
369 _ref = file.previewElement.querySelectorAll("[data-dz-uploadprogress]");
371 for (_i = 0, _len = _ref.length; _i < _len; _i++) {
373 if (node.nodeName === 'PROGRESS') {
374 _results.push(node.value = progress);
376 _results.push(node.style.width = "" + progress + "%");
382 totaluploadprogress: noop,
384 sendingmultiple: noop,
385 success: function(file) {
386 if (file.previewElement) {
387 return file.previewElement.classList.add("dz-success");
390 successmultiple: noop,
391 canceled: function(file) {
392 return this.emit("error", file, "Upload canceled.");
394 canceledmultiple: noop,
395 complete: function(file) {
396 if (file._removeLink) {
397 file._removeLink.textContent = this.options.dictRemoveFile;
399 if (file.previewElement) {
400 return file.previewElement.classList.add("dz-complete");
403 completemultiple: noop,
404 maxfilesexceeded: noop,
405 maxfilesreached: noop,
408 previewTemplate: "<div class=\"dz-preview dz-file-preview\">\n <div class=\"dz-image\"><img data-dz-thumbnail /></div>\n <div class=\"dz-details\">\n <div class=\"dz-size\"><span data-dz-size></span></div>\n <div class=\"dz-filename\"><span data-dz-name></span></div>\n </div>\n <div class=\"dz-progress\"><span class=\"dz-upload\" data-dz-uploadprogress></span></div>\n <div class=\"dz-error-message\"><span data-dz-errormessage></span></div>\n <div class=\"dz-success-mark\">\n <svg width=\"54px\" height=\"54px\" viewBox=\"0 0 54 54\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" xmlns:sketch=\"http://www.bohemiancoding.com/sketch/ns\">\n <title>Check</title>\n <defs></defs>\n <g id=\"Page-1\" stroke=\"none\" stroke-width=\"1\" fill=\"none\" fill-rule=\"evenodd\" sketch:type=\"MSPage\">\n <path d=\"M23.5,31.8431458 L17.5852419,25.9283877 C16.0248253,24.3679711 13.4910294,24.366835 11.9289322,25.9289322 C10.3700136,27.4878508 10.3665912,30.0234455 11.9283877,31.5852419 L20.4147581,40.0716123 C20.5133999,40.1702541 20.6159315,40.2626649 20.7218615,40.3488435 C22.2835669,41.8725651 24.794234,41.8626202 26.3461564,40.3106978 L43.3106978,23.3461564 C44.8771021,21.7797521 44.8758057,19.2483887 43.3137085,17.6862915 C41.7547899,16.1273729 39.2176035,16.1255422 37.6538436,17.6893022 L23.5,31.8431458 Z M27,53 C41.3594035,53 53,41.3594035 53,27 C53,12.6405965 41.3594035,1 27,1 C12.6405965,1 1,12.6405965 1,27 C1,41.3594035 12.6405965,53 27,53 Z\" id=\"Oval-2\" stroke-opacity=\"0.198794158\" stroke=\"#747474\" fill-opacity=\"0.816519475\" fill=\"#FFFFFF\" sketch:type=\"MSShapeGroup\"></path>\n </g>\n </svg>\n </div>\n <div class=\"dz-error-mark\">\n <svg width=\"54px\" height=\"54px\" viewBox=\"0 0 54 54\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" xmlns:sketch=\"http://www.bohemiancoding.com/sketch/ns\">\n <title>Error</title>\n <defs></defs>\n <g id=\"Page-1\" stroke=\"none\" stroke-width=\"1\" fill=\"none\" fill-rule=\"evenodd\" sketch:type=\"MSPage\">\n <g id=\"Check-+-Oval-2\" sketch:type=\"MSLayerGroup\" stroke=\"#747474\" stroke-opacity=\"0.198794158\" fill=\"#FFFFFF\" fill-opacity=\"0.816519475\">\n <path d=\"M32.6568542,29 L38.3106978,23.3461564 C39.8771021,21.7797521 39.8758057,19.2483887 38.3137085,17.6862915 C36.7547899,16.1273729 34.2176035,16.1255422 32.6538436,17.6893022 L27,23.3431458 L21.3461564,17.6893022 C19.7823965,16.1255422 17.2452101,16.1273729 15.6862915,17.6862915 C14.1241943,19.2483887 14.1228979,21.7797521 15.6893022,23.3461564 L21.3431458,29 L15.6893022,34.6538436 C14.1228979,36.2202479 14.1241943,38.7516113 15.6862915,40.3137085 C17.2452101,41.8726271 19.7823965,41.8744578 21.3461564,40.3106978 L27,34.6568542 L32.6538436,40.3106978 C34.2176035,41.8744578 36.7547899,41.8726271 38.3137085,40.3137085 C39.8758057,38.7516113 39.8771021,36.2202479 38.3106978,34.6538436 L32.6568542,29 Z M27,53 C41.3594035,53 53,41.3594035 53,27 C53,12.6405965 41.3594035,1 27,1 C12.6405965,1 1,12.6405965 1,27 C1,41.3594035 12.6405965,53 27,53 Z\" id=\"Oval-2\" sketch:type=\"MSShapeGroup\"></path>\n </g>\n </g>\n </svg>\n </div>\n</div>"
411 extend = function() {
412 var key, object, objects, target, val, _i, _len;
413 target = arguments[0], objects = 2 <= arguments.length ? __slice.call(arguments, 1) : [];
414 for (_i = 0, _len = objects.length; _i < _len; _i++) {
415 object = objects[_i];
416 for (key in object) {
424 function Dropzone(element, options) {
425 var elementOptions, fallback, _ref;
426 this.element = element;
427 this.version = Dropzone.version;
428 this.defaultOptions.previewTemplate = this.defaultOptions.previewTemplate.replace(/\n*/g, "");
429 this.clickableElements = [];
432 if (typeof this.element === "string") {
433 this.element = document.querySelector(this.element);
435 if (!(this.element && (this.element.nodeType != null))) {
436 throw new Error("Invalid dropzone element.");
438 if (this.element.dropzone) {
439 throw new Error("Dropzone already attached.");
441 Dropzone.instances.push(this);
442 this.element.dropzone = this;
443 elementOptions = (_ref = Dropzone.optionsForElement(this.element)) != null ? _ref : {};
444 this.options = extend({}, this.defaultOptions, elementOptions, options != null ? options : {});
445 if (this.options.forceFallback || !Dropzone.isBrowserSupported()) {
446 return this.options.fallback.call(this);
448 if (this.options.url == null) {
449 this.options.url = this.element.getAttribute("action");
451 if (!this.options.url) {
452 throw new Error("No URL provided.");
454 if (this.options.acceptedFiles && this.options.acceptedMimeTypes) {
455 throw new Error("You can't provide both 'acceptedFiles' and 'acceptedMimeTypes'. 'acceptedMimeTypes' is deprecated.");
457 if (this.options.acceptedMimeTypes) {
458 this.options.acceptedFiles = this.options.acceptedMimeTypes;
459 delete this.options.acceptedMimeTypes;
461 this.options.method = this.options.method.toUpperCase();
462 if ((fallback = this.getExistingFallback()) && fallback.parentNode) {
463 fallback.parentNode.removeChild(fallback);
465 if (this.options.previewsContainer !== false) {
466 if (this.options.previewsContainer) {
467 this.previewsContainer = Dropzone.getElement(this.options.previewsContainer, "previewsContainer");
469 this.previewsContainer = this.element;
472 if (this.options.clickable) {
473 if (this.options.clickable === true) {
474 this.clickableElements = [this.element];
476 this.clickableElements = Dropzone.getElements(this.options.clickable, "clickable");
482 Dropzone.prototype.getAcceptedFiles = function() {
483 var file, _i, _len, _ref, _results;
486 for (_i = 0, _len = _ref.length; _i < _len; _i++) {
495 Dropzone.prototype.getRejectedFiles = function() {
496 var file, _i, _len, _ref, _results;
499 for (_i = 0, _len = _ref.length; _i < _len; _i++) {
501 if (!file.accepted) {
508 Dropzone.prototype.getFilesWithStatus = function(status) {
509 var file, _i, _len, _ref, _results;
512 for (_i = 0, _len = _ref.length; _i < _len; _i++) {
514 if (file.status === status) {
521 Dropzone.prototype.getQueuedFiles = function() {
522 return this.getFilesWithStatus(Dropzone.QUEUED);
525 Dropzone.prototype.getUploadingFiles = function() {
526 return this.getFilesWithStatus(Dropzone.UPLOADING);
529 Dropzone.prototype.getAddedFiles = function() {
530 return this.getFilesWithStatus(Dropzone.ADDED);
533 Dropzone.prototype.getActiveFiles = function() {
534 var file, _i, _len, _ref, _results;
537 for (_i = 0, _len = _ref.length; _i < _len; _i++) {
539 if (file.status === Dropzone.UPLOADING || file.status === Dropzone.QUEUED) {
546 Dropzone.prototype.init = function() {
547 var eventName, noPropagation, setupHiddenFileInput, _i, _len, _ref, _ref1;
548 if (this.element.tagName === "form") {
549 this.element.setAttribute("enctype", "multipart/form-data");
551 if (this.element.classList.contains("dropzone") && !this.element.querySelector(".dz-message")) {
552 this.element.appendChild(Dropzone.createElement("<div class=\"dz-default dz-message\"><span>" + this.options.dictDefaultMessage + "</span></div>"));
554 if (this.clickableElements.length) {
555 setupHiddenFileInput = (function(_this) {
557 if (_this.hiddenFileInput) {
558 _this.hiddenFileInput.parentNode.removeChild(_this.hiddenFileInput);
560 _this.hiddenFileInput = document.createElement("input");
561 _this.hiddenFileInput.setAttribute("type", "file");
562 if ((_this.options.maxFiles == null) || _this.options.maxFiles > 1) {
563 _this.hiddenFileInput.setAttribute("multiple", "multiple");
565 _this.hiddenFileInput.className = "dz-hidden-input";
566 if (_this.options.acceptedFiles != null) {
567 _this.hiddenFileInput.setAttribute("accept", _this.options.acceptedFiles);
569 if (_this.options.capture != null) {
570 _this.hiddenFileInput.setAttribute("capture", _this.options.capture);
572 _this.hiddenFileInput.style.visibility = "hidden";
573 _this.hiddenFileInput.style.position = "absolute";
574 _this.hiddenFileInput.style.top = "0";
575 _this.hiddenFileInput.style.left = "0";
576 _this.hiddenFileInput.style.height = "0";
577 _this.hiddenFileInput.style.width = "0";
578 document.querySelector(_this.options.hiddenInputContainer).appendChild(_this.hiddenFileInput);
579 return _this.hiddenFileInput.addEventListener("change", function() {
580 var file, files, _i, _len;
581 files = _this.hiddenFileInput.files;
583 for (_i = 0, _len = files.length; _i < _len; _i++) {
588 _this.emit("addedfiles", files);
589 return setupHiddenFileInput();
593 setupHiddenFileInput();
595 this.URL = (_ref = window.URL) != null ? _ref : window.webkitURL;
597 for (_i = 0, _len = _ref1.length; _i < _len; _i++) {
598 eventName = _ref1[_i];
599 this.on(eventName, this.options[eventName]);
601 this.on("uploadprogress", (function(_this) {
603 return _this.updateTotalUploadProgress();
606 this.on("removedfile", (function(_this) {
608 return _this.updateTotalUploadProgress();
611 this.on("canceled", (function(_this) {
612 return function(file) {
613 return _this.emit("complete", file);
616 this.on("complete", (function(_this) {
617 return function(file) {
618 if (_this.getAddedFiles().length === 0 && _this.getUploadingFiles().length === 0 && _this.getQueuedFiles().length === 0) {
619 return setTimeout((function() {
620 return _this.emit("queuecomplete");
625 noPropagation = function(e) {
627 if (e.preventDefault) {
628 return e.preventDefault();
630 return e.returnValue = false;
635 element: this.element,
637 "dragstart": (function(_this) {
639 return _this.emit("dragstart", e);
642 "dragenter": (function(_this) {
645 return _this.emit("dragenter", e);
648 "dragover": (function(_this) {
652 efct = e.dataTransfer.effectAllowed;
654 e.dataTransfer.dropEffect = 'move' === efct || 'linkMove' === efct ? 'move' : 'copy';
656 return _this.emit("dragover", e);
659 "dragleave": (function(_this) {
661 return _this.emit("dragleave", e);
664 "drop": (function(_this) {
667 return _this.drop(e);
670 "dragend": (function(_this) {
672 return _this.emit("dragend", e);
678 this.clickableElements.forEach((function(_this) {
679 return function(clickableElement) {
680 return _this.listeners.push({
681 element: clickableElement,
683 "click": function(evt) {
684 if ((clickableElement !== _this.element) || (evt.target === _this.element || Dropzone.elementInside(evt.target, _this.element.querySelector(".dz-message")))) {
685 _this.hiddenFileInput.click();
694 return this.options.init.call(this);
697 Dropzone.prototype.destroy = function() {
700 this.removeAllFiles(true);
701 if ((_ref = this.hiddenFileInput) != null ? _ref.parentNode : void 0) {
702 this.hiddenFileInput.parentNode.removeChild(this.hiddenFileInput);
703 this.hiddenFileInput = null;
705 delete this.element.dropzone;
706 return Dropzone.instances.splice(Dropzone.instances.indexOf(this), 1);
709 Dropzone.prototype.updateTotalUploadProgress = function() {
710 var activeFiles, file, totalBytes, totalBytesSent, totalUploadProgress, _i, _len, _ref;
713 activeFiles = this.getActiveFiles();
714 if (activeFiles.length) {
715 _ref = this.getActiveFiles();
716 for (_i = 0, _len = _ref.length; _i < _len; _i++) {
718 totalBytesSent += file.upload.bytesSent;
719 totalBytes += file.upload.total;
721 totalUploadProgress = 100 * totalBytesSent / totalBytes;
723 totalUploadProgress = 100;
725 return this.emit("totaluploadprogress", totalUploadProgress, totalBytes, totalBytesSent);
728 Dropzone.prototype._getParamName = function(n) {
729 if (typeof this.options.paramName === "function") {
730 return this.options.paramName(n);
732 return "" + this.options.paramName + (this.options.uploadMultiple ? "[" + n + "]" : "");
736 Dropzone.prototype._renameFilename = function(name) {
737 if (typeof this.options.renameFilename !== "function") {
740 return this.options.renameFilename(name);
743 Dropzone.prototype.getFallbackForm = function() {
744 var existingFallback, fields, fieldsString, form;
745 if (existingFallback = this.getExistingFallback()) {
746 return existingFallback;
748 fieldsString = "<div class=\"dz-fallback\">";
749 if (this.options.dictFallbackText) {
750 fieldsString += "<p>" + this.options.dictFallbackText + "</p>";
752 fieldsString += "<input type=\"file\" name=\"" + (this._getParamName(0)) + "\" " + (this.options.uploadMultiple ? 'multiple="multiple"' : void 0) + " /><input type=\"submit\" value=\"Upload!\"></div>";
753 fields = Dropzone.createElement(fieldsString);
754 if (this.element.tagName !== "FORM") {
755 form = Dropzone.createElement("<form action=\"" + this.options.url + "\" enctype=\"multipart/form-data\" method=\"" + this.options.method + "\"></form>");
756 form.appendChild(fields);
758 this.element.setAttribute("enctype", "multipart/form-data");
759 this.element.setAttribute("method", this.options.method);
761 return form != null ? form : fields;
764 Dropzone.prototype.getExistingFallback = function() {
765 var fallback, getFallback, tagName, _i, _len, _ref;
766 getFallback = function(elements) {
768 for (_i = 0, _len = elements.length; _i < _len; _i++) {
770 if (/(^| )fallback($| )/.test(el.className)) {
775 _ref = ["div", "form"];
776 for (_i = 0, _len = _ref.length; _i < _len; _i++) {
778 if (fallback = getFallback(this.element.getElementsByTagName(tagName))) {
784 Dropzone.prototype.setupEventListeners = function() {
785 var elementListeners, event, listener, _i, _len, _ref, _results;
786 _ref = this.listeners;
788 for (_i = 0, _len = _ref.length; _i < _len; _i++) {
789 elementListeners = _ref[_i];
790 _results.push((function() {
791 var _ref1, _results1;
792 _ref1 = elementListeners.events;
794 for (event in _ref1) {
795 listener = _ref1[event];
796 _results1.push(elementListeners.element.addEventListener(event, listener, false));
804 Dropzone.prototype.removeEventListeners = function() {
805 var elementListeners, event, listener, _i, _len, _ref, _results;
806 _ref = this.listeners;
808 for (_i = 0, _len = _ref.length; _i < _len; _i++) {
809 elementListeners = _ref[_i];
810 _results.push((function() {
811 var _ref1, _results1;
812 _ref1 = elementListeners.events;
814 for (event in _ref1) {
815 listener = _ref1[event];
816 _results1.push(elementListeners.element.removeEventListener(event, listener, false));
824 Dropzone.prototype.disable = function() {
825 var file, _i, _len, _ref, _results;
826 this.clickableElements.forEach(function(element) {
827 return element.classList.remove("dz-clickable");
829 this.removeEventListeners();
832 for (_i = 0, _len = _ref.length; _i < _len; _i++) {
834 _results.push(this.cancelUpload(file));
839 Dropzone.prototype.enable = function() {
840 this.clickableElements.forEach(function(element) {
841 return element.classList.add("dz-clickable");
843 return this.setupEventListeners();
846 Dropzone.prototype.filesize = function(size) {
847 var cutoff, i, selectedSize, selectedUnit, unit, units, _i, _len;
851 units = ['TB', 'GB', 'MB', 'KB', 'b'];
852 for (i = _i = 0, _len = units.length; _i < _len; i = ++_i) {
854 cutoff = Math.pow(this.options.filesizeBase, 4 - i) / 10;
855 if (size >= cutoff) {
856 selectedSize = size / Math.pow(this.options.filesizeBase, 4 - i);
861 selectedSize = Math.round(10 * selectedSize) / 10;
863 return "<strong>" + selectedSize + "</strong> " + selectedUnit;
866 Dropzone.prototype._updateMaxFilesReachedClass = function() {
867 if ((this.options.maxFiles != null) && this.getAcceptedFiles().length >= this.options.maxFiles) {
868 if (this.getAcceptedFiles().length === this.options.maxFiles) {
869 this.emit('maxfilesreached', this.files);
871 return this.element.classList.add("dz-max-files-reached");
873 return this.element.classList.remove("dz-max-files-reached");
877 Dropzone.prototype.drop = function(e) {
879 if (!e.dataTransfer) {
882 this.emit("drop", e);
883 files = e.dataTransfer.files;
884 this.emit("addedfiles", files);
886 items = e.dataTransfer.items;
887 if (items && items.length && (items[0].webkitGetAsEntry != null)) {
888 this._addFilesFromItems(items);
890 this.handleFiles(files);
895 Dropzone.prototype.paste = function(e) {
897 if ((e != null ? (_ref = e.clipboardData) != null ? _ref.items : void 0 : void 0) == null) {
900 this.emit("paste", e);
901 items = e.clipboardData.items;
903 return this._addFilesFromItems(items);
907 Dropzone.prototype.handleFiles = function(files) {
908 var file, _i, _len, _results;
910 for (_i = 0, _len = files.length; _i < _len; _i++) {
912 _results.push(this.addFile(file));
917 Dropzone.prototype._addFilesFromItems = function(items) {
918 var entry, item, _i, _len, _results;
920 for (_i = 0, _len = items.length; _i < _len; _i++) {
922 if ((item.webkitGetAsEntry != null) && (entry = item.webkitGetAsEntry())) {
924 _results.push(this.addFile(item.getAsFile()));
925 } else if (entry.isDirectory) {
926 _results.push(this._addFilesFromDirectory(entry, entry.name));
928 _results.push(void 0);
930 } else if (item.getAsFile != null) {
931 if ((item.kind == null) || item.kind === "file") {
932 _results.push(this.addFile(item.getAsFile()));
934 _results.push(void 0);
937 _results.push(void 0);
943 Dropzone.prototype._addFilesFromDirectory = function(directory, path) {
944 var dirReader, errorHandler, readEntries;
945 dirReader = directory.createReader();
946 errorHandler = function(error) {
947 return typeof console !== "undefined" && console !== null ? typeof console.log === "function" ? console.log(error) : void 0 : void 0;
949 readEntries = (function(_this) {
951 return dirReader.readEntries(function(entries) {
953 if (entries.length > 0) {
954 for (_i = 0, _len = entries.length; _i < _len; _i++) {
957 entry.file(function(file) {
958 if (_this.options.ignoreHiddenFiles && file.name.substring(0, 1) === '.') {
961 file.fullPath = "" + path + "/" + file.name;
962 return _this.addFile(file);
964 } else if (entry.isDirectory) {
965 _this._addFilesFromDirectory(entry, "" + path + "/" + entry.name);
974 return readEntries();
977 Dropzone.prototype.accept = function(file, done) {
978 if (file.size > this.options.maxFilesize * 1024 * 1024) {
979 return done(this.options.dictFileTooBig.replace("{{filesize}}", Math.round(file.size / 1024 / 10.24) / 100).replace("{{maxFilesize}}", this.options.maxFilesize));
980 } else if (!Dropzone.isValidFile(file, this.options.acceptedFiles)) {
981 return done(this.options.dictInvalidFileType);
982 } else if ((this.options.maxFiles != null) && this.getAcceptedFiles().length >= this.options.maxFiles) {
983 done(this.options.dictMaxFilesExceeded.replace("{{maxFiles}}", this.options.maxFiles));
984 return this.emit("maxfilesexceeded", file);
986 return this.options.accept.call(this, file, done);
990 Dropzone.prototype.addFile = function(file) {
996 this.files.push(file);
997 file.status = Dropzone.ADDED;
998 this.emit("addedfile", file);
999 this._enqueueThumbnail(file);
1000 return this.accept(file, (function(_this) {
1001 return function(error) {
1003 file.accepted = false;
1004 _this._errorProcessing([file], error);
1006 file.accepted = true;
1007 if (_this.options.autoQueue) {
1008 _this.enqueueFile(file);
1011 return _this._updateMaxFilesReachedClass();
1016 Dropzone.prototype.enqueueFiles = function(files) {
1018 for (_i = 0, _len = files.length; _i < _len; _i++) {
1020 this.enqueueFile(file);
1025 Dropzone.prototype.enqueueFile = function(file) {
1026 if (file.status === Dropzone.ADDED && file.accepted === true) {
1027 file.status = Dropzone.QUEUED;
1028 if (this.options.autoProcessQueue) {
1029 return setTimeout(((function(_this) {
1031 return _this.processQueue();
1036 throw new Error("This file can't be queued because it has already been processed or was rejected.");
1040 Dropzone.prototype._thumbnailQueue = [];
1042 Dropzone.prototype._processingThumbnail = false;
1044 Dropzone.prototype._enqueueThumbnail = function(file) {
1045 if (this.options.createImageThumbnails && file.type.match(/image.*/) && file.size <= this.options.maxThumbnailFilesize * 1024 * 1024) {
1046 this._thumbnailQueue.push(file);
1047 return setTimeout(((function(_this) {
1049 return _this._processThumbnailQueue();
1055 Dropzone.prototype._processThumbnailQueue = function() {
1056 if (this._processingThumbnail || this._thumbnailQueue.length === 0) {
1059 this._processingThumbnail = true;
1060 return this.createThumbnail(this._thumbnailQueue.shift(), (function(_this) {
1062 _this._processingThumbnail = false;
1063 return _this._processThumbnailQueue();
1068 Dropzone.prototype.removeFile = function(file) {
1069 if (file.status === Dropzone.UPLOADING) {
1070 this.cancelUpload(file);
1072 this.files = without(this.files, file);
1073 this.emit("removedfile", file);
1074 if (this.files.length === 0) {
1075 return this.emit("reset");
1079 Dropzone.prototype.removeAllFiles = function(cancelIfNecessary) {
1080 var file, _i, _len, _ref;
1081 if (cancelIfNecessary == null) {
1082 cancelIfNecessary = false;
1084 _ref = this.files.slice();
1085 for (_i = 0, _len = _ref.length; _i < _len; _i++) {
1087 if (file.status !== Dropzone.UPLOADING || cancelIfNecessary) {
1088 this.removeFile(file);
1094 Dropzone.prototype.createThumbnail = function(file, callback) {
1096 fileReader = new FileReader;
1097 fileReader.onload = (function(_this) {
1099 if (file.type === "image/svg+xml") {
1100 _this.emit("thumbnail", file, fileReader.result);
1101 if (callback != null) {
1106 return _this.createThumbnailFromUrl(file, fileReader.result, callback);
1109 return fileReader.readAsDataURL(file);
1112 Dropzone.prototype.createThumbnailFromUrl = function(file, imageUrl, callback, crossOrigin) {
1114 img = document.createElement("img");
1116 img.crossOrigin = crossOrigin;
1118 img.onload = (function(_this) {
1120 var canvas, ctx, resizeInfo, thumbnail, _ref, _ref1, _ref2, _ref3;
1121 file.width = img.width;
1122 file.height = img.height;
1123 resizeInfo = _this.options.resize.call(_this, file);
1124 if (resizeInfo.trgWidth == null) {
1125 resizeInfo.trgWidth = resizeInfo.optWidth;
1127 if (resizeInfo.trgHeight == null) {
1128 resizeInfo.trgHeight = resizeInfo.optHeight;
1130 canvas = document.createElement("canvas");
1131 ctx = canvas.getContext("2d");
1132 canvas.width = resizeInfo.trgWidth;
1133 canvas.height = resizeInfo.trgHeight;
1134 drawImageIOSFix(ctx, img, (_ref = resizeInfo.srcX) != null ? _ref : 0, (_ref1 = resizeInfo.srcY) != null ? _ref1 : 0, resizeInfo.srcWidth, resizeInfo.srcHeight, (_ref2 = resizeInfo.trgX) != null ? _ref2 : 0, (_ref3 = resizeInfo.trgY) != null ? _ref3 : 0, resizeInfo.trgWidth, resizeInfo.trgHeight);
1135 thumbnail = canvas.toDataURL("image/png");
1136 _this.emit("thumbnail", file, thumbnail);
1137 if (callback != null) {
1142 if (callback != null) {
1143 img.onerror = callback;
1145 return img.src = imageUrl;
1148 Dropzone.prototype.processQueue = function() {
1149 var i, parallelUploads, processingLength, queuedFiles;
1150 parallelUploads = this.options.parallelUploads;
1151 processingLength = this.getUploadingFiles().length;
1152 i = processingLength;
1153 if (processingLength >= parallelUploads) {
1156 queuedFiles = this.getQueuedFiles();
1157 if (!(queuedFiles.length > 0)) {
1160 if (this.options.uploadMultiple) {
1161 return this.processFiles(queuedFiles.slice(0, parallelUploads - processingLength));
1163 while (i < parallelUploads) {
1164 if (!queuedFiles.length) {
1167 this.processFile(queuedFiles.shift());
1173 Dropzone.prototype.processFile = function(file) {
1174 return this.processFiles([file]);
1177 Dropzone.prototype.processFiles = function(files) {
1179 for (_i = 0, _len = files.length; _i < _len; _i++) {
1181 file.processing = true;
1182 file.status = Dropzone.UPLOADING;
1183 this.emit("processing", file);
1185 if (this.options.uploadMultiple) {
1186 this.emit("processingmultiple", files);
1188 return this.uploadFiles(files);
1191 Dropzone.prototype._getFilesWithXhr = function(xhr) {
1193 return files = (function() {
1194 var _i, _len, _ref, _results;
1197 for (_i = 0, _len = _ref.length; _i < _len; _i++) {
1199 if (file.xhr === xhr) {
1200 _results.push(file);
1207 Dropzone.prototype.cancelUpload = function(file) {
1208 var groupedFile, groupedFiles, _i, _j, _len, _len1, _ref;
1209 if (file.status === Dropzone.UPLOADING) {
1210 groupedFiles = this._getFilesWithXhr(file.xhr);
1211 for (_i = 0, _len = groupedFiles.length; _i < _len; _i++) {
1212 groupedFile = groupedFiles[_i];
1213 groupedFile.status = Dropzone.CANCELED;
1216 for (_j = 0, _len1 = groupedFiles.length; _j < _len1; _j++) {
1217 groupedFile = groupedFiles[_j];
1218 this.emit("canceled", groupedFile);
1220 if (this.options.uploadMultiple) {
1221 this.emit("canceledmultiple", groupedFiles);
1223 } else if ((_ref = file.status) === Dropzone.ADDED || _ref === Dropzone.QUEUED) {
1224 file.status = Dropzone.CANCELED;
1225 this.emit("canceled", file);
1226 if (this.options.uploadMultiple) {
1227 this.emit("canceledmultiple", [file]);
1230 if (this.options.autoProcessQueue) {
1231 return this.processQueue();
1235 resolveOption = function() {
1237 option = arguments[0], args = 2 <= arguments.length ? __slice.call(arguments, 1) : [];
1238 if (typeof option === 'function') {
1239 return option.apply(this, args);
1244 Dropzone.prototype.uploadFile = function(file) {
1245 return this.uploadFiles([file]);
1248 Dropzone.prototype.uploadFiles = function(files) {
1249 var file, formData, handleError, headerName, headerValue, headers, i, input, inputName, inputType, key, method, option, progressObj, response, updateProgress, url, value, xhr, _i, _j, _k, _l, _len, _len1, _len2, _len3, _m, _ref, _ref1, _ref2, _ref3, _ref4, _ref5;
1250 xhr = new XMLHttpRequest();
1251 for (_i = 0, _len = files.length; _i < _len; _i++) {
1255 method = resolveOption(this.options.method, files);
1256 url = resolveOption(this.options.url, files);
1257 xhr.open(method, url, true);
1258 xhr.withCredentials = !!this.options.withCredentials;
1260 handleError = (function(_this) {
1262 var _j, _len1, _results;
1264 for (_j = 0, _len1 = files.length; _j < _len1; _j++) {
1266 _results.push(_this._errorProcessing(files, response || _this.options.dictResponseError.replace("{{statusCode}}", xhr.status), xhr));
1271 updateProgress = (function(_this) {
1272 return function(e) {
1273 var allFilesFinished, progress, _j, _k, _l, _len1, _len2, _len3, _results;
1275 progress = 100 * e.loaded / e.total;
1276 for (_j = 0, _len1 = files.length; _j < _len1; _j++) {
1285 allFilesFinished = true;
1287 for (_k = 0, _len2 = files.length; _k < _len2; _k++) {
1289 if (!(file.upload.progress === 100 && file.upload.bytesSent === file.upload.total)) {
1290 allFilesFinished = false;
1292 file.upload.progress = progress;
1293 file.upload.bytesSent = file.upload.total;
1295 if (allFilesFinished) {
1300 for (_l = 0, _len3 = files.length; _l < _len3; _l++) {
1302 _results.push(_this.emit("uploadprogress", file, progress, file.upload.bytesSent));
1307 xhr.onload = (function(_this) {
1308 return function(e) {
1310 if (files[0].status === Dropzone.CANCELED) {
1313 if (xhr.readyState !== 4) {
1316 response = xhr.responseText;
1317 if (xhr.getResponseHeader("content-type") && ~xhr.getResponseHeader("content-type").indexOf("application/json")) {
1319 response = JSON.parse(response);
1322 response = "Invalid JSON response from server.";
1326 if (!((200 <= (_ref = xhr.status) && _ref < 300))) {
1327 return handleError();
1329 return _this._finished(files, response, e);
1333 xhr.onerror = (function(_this) {
1335 if (files[0].status === Dropzone.CANCELED) {
1338 return handleError();
1341 progressObj = (_ref = xhr.upload) != null ? _ref : xhr;
1342 progressObj.onprogress = updateProgress;
1344 "Accept": "application/json",
1345 "Cache-Control": "no-cache",
1346 "X-Requested-With": "XMLHttpRequest"
1348 if (this.options.headers) {
1349 extend(headers, this.options.headers);
1351 for (headerName in headers) {
1352 headerValue = headers[headerName];
1354 xhr.setRequestHeader(headerName, headerValue);
1357 formData = new FormData();
1358 if (this.options.params) {
1359 _ref1 = this.options.params;
1360 for (key in _ref1) {
1362 formData.append(key, value);
1365 for (_j = 0, _len1 = files.length; _j < _len1; _j++) {
1367 this.emit("sending", file, xhr, formData);
1369 if (this.options.uploadMultiple) {
1370 this.emit("sendingmultiple", files, xhr, formData);
1372 if (this.element.tagName === "FORM") {
1373 _ref2 = this.element.querySelectorAll("input, textarea, select, button");
1374 for (_k = 0, _len2 = _ref2.length; _k < _len2; _k++) {
1376 inputName = input.getAttribute("name");
1377 inputType = input.getAttribute("type");
1378 if (input.tagName === "SELECT" && input.hasAttribute("multiple")) {
1379 _ref3 = input.options;
1380 for (_l = 0, _len3 = _ref3.length; _l < _len3; _l++) {
1382 if (option.selected) {
1383 formData.append(inputName, option.value);
1386 } else if (!inputType || ((_ref4 = inputType.toLowerCase()) !== "checkbox" && _ref4 !== "radio") || input.checked) {
1387 formData.append(inputName, input.value);
1391 for (i = _m = 0, _ref5 = files.length - 1; 0 <= _ref5 ? _m <= _ref5 : _m >= _ref5; i = 0 <= _ref5 ? ++_m : --_m) {
1392 formData.append(this._getParamName(i), files[i], this._renameFilename(files[i].name));
1394 return this.submitRequest(xhr, formData, files);
1397 Dropzone.prototype.submitRequest = function(xhr, formData, files) {
1398 return xhr.send(formData);
1401 Dropzone.prototype._finished = function(files, responseText, e) {
1403 for (_i = 0, _len = files.length; _i < _len; _i++) {
1405 file.status = Dropzone.SUCCESS;
1406 this.emit("success", file, responseText, e);
1407 this.emit("complete", file);
1409 if (this.options.uploadMultiple) {
1410 this.emit("successmultiple", files, responseText, e);
1411 this.emit("completemultiple", files);
1413 if (this.options.autoProcessQueue) {
1414 return this.processQueue();
1418 Dropzone.prototype._errorProcessing = function(files, message, xhr) {
1420 for (_i = 0, _len = files.length; _i < _len; _i++) {
1422 file.status = Dropzone.ERROR;
1423 this.emit("error", file, message, xhr);
1424 this.emit("complete", file);
1426 if (this.options.uploadMultiple) {
1427 this.emit("errormultiple", files, message, xhr);
1428 this.emit("completemultiple", files);
1430 if (this.options.autoProcessQueue) {
1431 return this.processQueue();
1439 Dropzone.version = "4.3.0";
1441 Dropzone.options = {};
1443 Dropzone.optionsForElement = function(element) {
1444 if (element.getAttribute("id")) {
1445 return Dropzone.options[camelize(element.getAttribute("id"))];
1451 Dropzone.instances = [];
1453 Dropzone.forElement = function(element) {
1454 if (typeof element === "string") {
1455 element = document.querySelector(element);
1457 if ((element != null ? element.dropzone : void 0) == null) {
1458 throw new Error("No Dropzone found for given element. This is probably because you're trying to access it before Dropzone had the time to initialize. Use the `init` option to setup any additional observers on your Dropzone.");
1460 return element.dropzone;
1463 Dropzone.autoDiscover = true;
1465 Dropzone.discover = function() {
1466 var checkElements, dropzone, dropzones, _i, _len, _results;
1467 if (document.querySelectorAll) {
1468 dropzones = document.querySelectorAll(".dropzone");
1471 checkElements = function(elements) {
1472 var el, _i, _len, _results;
1474 for (_i = 0, _len = elements.length; _i < _len; _i++) {
1476 if (/(^| )dropzone($| )/.test(el.className)) {
1477 _results.push(dropzones.push(el));
1479 _results.push(void 0);
1484 checkElements(document.getElementsByTagName("div"));
1485 checkElements(document.getElementsByTagName("form"));
1488 for (_i = 0, _len = dropzones.length; _i < _len; _i++) {
1489 dropzone = dropzones[_i];
1490 if (Dropzone.optionsForElement(dropzone) !== false) {
1491 _results.push(new Dropzone(dropzone));
1493 _results.push(void 0);
1499 Dropzone.blacklistedBrowsers = [/opera.*Macintosh.*version\/12/i];
1501 Dropzone.isBrowserSupported = function() {
1502 var capableBrowser, regex, _i, _len, _ref;
1503 capableBrowser = true;
1504 if (window.File && window.FileReader && window.FileList && window.Blob && window.FormData && document.querySelector) {
1505 if (!("classList" in document.createElement("a"))) {
1506 capableBrowser = false;
1508 _ref = Dropzone.blacklistedBrowsers;
1509 for (_i = 0, _len = _ref.length; _i < _len; _i++) {
1511 if (regex.test(navigator.userAgent)) {
1512 capableBrowser = false;
1518 capableBrowser = false;
1520 return capableBrowser;
1523 without = function(list, rejectedItem) {
1524 var item, _i, _len, _results;
1526 for (_i = 0, _len = list.length; _i < _len; _i++) {
1528 if (item !== rejectedItem) {
1529 _results.push(item);
1535 camelize = function(str) {
1536 return str.replace(/[\-_](\w)/g, function(match) {
1537 return match.charAt(1).toUpperCase();
1541 Dropzone.createElement = function(string) {
1543 div = document.createElement("div");
1544 div.innerHTML = string;
1545 return div.childNodes[0];
1548 Dropzone.elementInside = function(element, container) {
1549 if (element === container) {
1552 while (element = element.parentNode) {
1553 if (element === container) {
1560 Dropzone.getElement = function(el, name) {
1562 if (typeof el === "string") {
1563 element = document.querySelector(el);
1564 } else if (el.nodeType != null) {
1567 if (element == null) {
1568 throw new Error("Invalid `" + name + "` option provided. Please provide a CSS selector or a plain HTML element.");
1573 Dropzone.getElements = function(els, name) {
1574 var e, el, elements, _i, _j, _len, _len1, _ref;
1575 if (els instanceof Array) {
1578 for (_i = 0, _len = els.length; _i < _len; _i++) {
1580 elements.push(this.getElement(el, name));
1586 } else if (typeof els === "string") {
1588 _ref = document.querySelectorAll(els);
1589 for (_j = 0, _len1 = _ref.length; _j < _len1; _j++) {
1593 } else if (els.nodeType != null) {
1596 if (!((elements != null) && elements.length)) {
1597 throw new Error("Invalid `" + name + "` option provided. Please provide a CSS selector, a plain HTML element or a list of those.");
1602 Dropzone.confirm = function(question, accepted, rejected) {
1603 if (window.confirm(question)) {
1605 } else if (rejected != null) {
1610 Dropzone.isValidFile = function(file, acceptedFiles) {
1611 var baseMimeType, mimeType, validType, _i, _len;
1612 if (!acceptedFiles) {
1615 acceptedFiles = acceptedFiles.split(",");
1616 mimeType = file.type;
1617 baseMimeType = mimeType.replace(/\/.*$/, "");
1618 for (_i = 0, _len = acceptedFiles.length; _i < _len; _i++) {
1619 validType = acceptedFiles[_i];
1620 validType = validType.trim();
1621 if (validType.charAt(0) === ".") {
1622 if (file.name.toLowerCase().indexOf(validType.toLowerCase(), file.name.length - validType.length) !== -1) {
1625 } else if (/\/\*$/.test(validType)) {
1626 if (baseMimeType === validType.replace(/\/.*$/, "")) {
1630 if (mimeType === validType) {
1638 if (typeof jQuery !== "undefined" && jQuery !== null) {
1639 jQuery.fn.dropzone = function(options) {
1640 return this.each(function() {
1641 return new Dropzone(this, options);
1646 if (typeof module !== "undefined" && module !== null) {
1647 module.exports = Dropzone;
1649 window.Dropzone = Dropzone;
1652 Dropzone.ADDED = "added";
1654 Dropzone.QUEUED = "queued";
1656 Dropzone.ACCEPTED = Dropzone.QUEUED;
1658 Dropzone.UPLOADING = "uploading";
1660 Dropzone.PROCESSING = Dropzone.UPLOADING;
1662 Dropzone.CANCELED = "canceled";
1664 Dropzone.ERROR = "error";
1666 Dropzone.SUCCESS = "success";
1671 Bugfix for iOS 6 and 7
1672 Source: http://stackoverflow.com/questions/11929099/html5-canvas-drawimage-ratio-bug-ios
1673 based on the work of https://github.com/stomita/ios-imagefile-megapixel
1676 detectVerticalSquash = function(img) {
1677 var alpha, canvas, ctx, data, ey, ih, iw, py, ratio, sy;
1678 iw = img.naturalWidth;
1679 ih = img.naturalHeight;
1680 canvas = document.createElement("canvas");
1683 ctx = canvas.getContext("2d");
1684 ctx.drawImage(img, 0, 0);
1685 data = ctx.getImageData(0, 0, 1, ih).data;
1690 alpha = data[(py - 1) * 4 + 3];
1696 py = (ey + sy) >> 1;
1706 drawImageIOSFix = function(ctx, img, sx, sy, sw, sh, dx, dy, dw, dh) {
1707 var vertSquashRatio;
1708 vertSquashRatio = detectVerticalSquash(img);
1709 return ctx.drawImage(img, sx, sy, sw, sh, dx, dy, dw, dh / vertSquashRatio);
1716 * Author: Diego Perini (diego.perini at gmail.com)
1717 * Summary: cross-browser wrapper for DOMContentLoaded
1723 * http://javascript.nwbox.com/ContentLoaded/
1724 * http://javascript.nwbox.com/ContentLoaded/MIT-LICENSE
1727 contentLoaded = function(win, fn) {
1728 var add, doc, done, init, poll, pre, rem, root, top;
1732 root = doc.documentElement;
1733 add = (doc.addEventListener ? "addEventListener" : "attachEvent");
1734 rem = (doc.addEventListener ? "removeEventListener" : "detachEvent");
1735 pre = (doc.addEventListener ? "" : "on");
1736 init = function(e) {
1737 if (e.type === "readystatechange" && doc.readyState !== "complete") {
1740 (e.type === "load" ? win : doc)[rem](pre + e.type, init, false);
1741 if (!done && (done = true)) {
1742 return fn.call(win, e.type || e);
1748 root.doScroll("left");
1751 setTimeout(poll, 50);
1754 return init("poll");
1756 if (doc.readyState !== "complete") {
1757 if (doc.createEventObject && root.doScroll) {
1759 top = !win.frameElement;
1765 doc[add](pre + "DOMContentLoaded", init, false);
1766 doc[add](pre + "readystatechange", init, false);
1767 return win[add](pre + "load", init, false);
1771 Dropzone._autoDiscoverFunction = function() {
1772 if (Dropzone.autoDiscover) {
1773 return Dropzone.discover();
1777 contentLoaded(window, Dropzone._autoDiscoverFunction);
1781 return module.exports;