Changeset 106613 in spip-zone
- Timestamp:
- Oct 9, 2017, 8:11:27 AM (3 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
_plugins_/uploadhtml5/trunk/lib/dropzone/dropzone.js
r105979 r106613 1 "use strict"; 2 3 var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); 4 5 function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } 6 7 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } 8 9 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 1 10 2 11 /* … … 26 35 */ 27 36 28 (function() { 29 var Dropzone, Emitter, ExifRestore, camelize, contentLoaded, detectVerticalSquash, drawImageIOSFix, noop, without, 30 slice = [].slice, 31 extend1 = 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; }, 32 hasProp = {}.hasOwnProperty; 33 34 noop = function() {};35 36 Emitter = (function() { 37 function Emitter() {}38 39 Emitter.prototype.addEventListener = Emitter.prototype.on; 40 41 Emitter.prototype.on = function(event, fn) {37 // The Emitter class provides the ability to call `.on()` on Dropzone to listen 38 // to events. 39 // It is strongly based on component's emitter class, and I removed the 40 // functionality because of the dependency hell with different frameworks. 41 var Emitter = function () { 42 function Emitter() { 43 _classCallCheck(this, Emitter); 44 } 45 46 _createClass(Emitter, [{ 47 key: "on", 48 49 // Add an event listener for given event 50 value: function on(event, fn) { 42 51 this._callbacks = this._callbacks || {}; 52 // Create namespace for this event 43 53 if (!this._callbacks[event]) { 44 54 this._callbacks[event] = []; … … 46 56 this._callbacks[event].push(fn); 47 57 return this; 48 }; 49 50 Emitter.prototype.emit = function() { 51 var args, callback, callbacks, event, j, len; 52 event = arguments[0], args = 2 <= arguments.length ? slice.call(arguments, 1) : []; 58 } 59 }, { 60 key: "emit", 61 value: function emit(event) { 53 62 this._callbacks = this._callbacks || {}; 54 callbacks = this._callbacks[event]; 63 var callbacks = this._callbacks[event]; 64 55 65 if (callbacks) { 56 for (j = 0, len = callbacks.length; j < len; j++) { 57 callback = callbacks[j]; 66 for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { 67 args[_key - 1] = arguments[_key]; 68 } 69 70 for (var _iterator = callbacks, _isArray = true, _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) { 71 var _ref; 72 73 if (_isArray) { 74 if (_i >= _iterator.length) break; 75 _ref = _iterator[_i++]; 76 } else { 77 _i = _iterator.next(); 78 if (_i.done) break; 79 _ref = _i.value; 80 } 81 82 var callback = _ref; 83 58 84 callback.apply(this, args); 59 85 } 60 86 } 87 61 88 return this; 62 }; 63 64 Emitter.prototype.removeListener = Emitter.prototype.off; 65 66 Emitter.prototype.removeAllListeners = Emitter.prototype.off; 67 68 Emitter.prototype.removeEventListener = Emitter.prototype.off; 69 70 Emitter.prototype.off = function(event, fn) { 71 var callback, callbacks, i, j, len; 89 } 90 91 // Remove event listener for given event. If fn is not provided, all event 92 // listeners for that event will be removed. If neither is provided, all 93 // event listeners will be removed. 94 95 }, { 96 key: "off", 97 value: function off(event, fn) { 72 98 if (!this._callbacks || arguments.length === 0) { 73 99 this._callbacks = {}; 74 100 return this; 75 101 } 76 callbacks = this._callbacks[event]; 102 103 // specific event 104 var callbacks = this._callbacks[event]; 77 105 if (!callbacks) { 78 106 return this; 79 107 } 108 109 // remove all handlers 80 110 if (arguments.length === 1) { 81 111 delete this._callbacks[event]; 82 112 return this; 83 113 } 84 for (i = j = 0, len = callbacks.length; j < len; i = ++j) { 85 callback = callbacks[i]; 114 115 // remove specific handler 116 for (var i = 0; i < callbacks.length; i++) { 117 var callback = callbacks[i]; 86 118 if (callback === fn) { 87 119 callbacks.splice(i, 1); … … 89 121 } 90 122 } 123 91 124 return this; 92 } ;93 94 return Emitter; 95 96 })();97 98 Dropzone = (function(superClass) {99 var extend, resolveOption;100 101 extend1(Dropzone, superClass);102 103 Dropzone.prototype.Emitter = Emitter;104 105 106 /*107 This is a list of all available events you can register on a dropzone object. 108 109 You can register an event handler like this:110 125 } 126 }]); 127 128 return Emitter; 129 }(); 130 131 var Dropzone = function (_Emitter) { 132 _inherits(Dropzone, _Emitter); 133 134 _createClass(Dropzone, null, [{ 135 key: "initClass", 136 value: function initClass() { 137 138 // Exposing the emitter class, mainly for tests 139 this.prototype.Emitter = Emitter; 140 141 /* 142 This is a list of all available events you can register on a dropzone object. 143 You can register an event handler like this: 111 144 dropzone.on("dragEnter", function() { }); 112 */ 113 114 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"]; 115 116 Dropzone.prototype.defaultOptions = { 117 url: null, 118 method: "post", 119 withCredentials: false, 120 timeout: 30000, 121 parallelUploads: 2, 122 uploadMultiple: false, 123 maxFilesize: 256, 124 paramName: "file", 125 createImageThumbnails: true, 126 maxThumbnailFilesize: 10, 127 thumbnailWidth: 120, 128 thumbnailHeight: 120, 129 thumbnailMethod: 'crop', 130 resizeWidth: null, 131 resizeHeight: null, 132 resizeMimeType: null, 133 resizeQuality: 0.8, 134 resizeMethod: 'contain', 135 filesizeBase: 1000, 136 maxFiles: null, 137 params: {}, 138 headers: null, 139 clickable: true, 140 ignoreHiddenFiles: true, 141 acceptedFiles: null, 142 acceptedMimeTypes: null, 143 autoProcessQueue: true, 144 autoQueue: true, 145 addRemoveLinks: false, 146 previewsContainer: null, 147 hiddenInputContainer: "body", 148 capture: null, 149 renameFilename: null, 150 renameFile: null, 151 forceFallback: false, 152 dictDefaultMessage: "Drop files here to upload", 153 dictFallbackMessage: "Your browser does not support drag'n'drop file uploads.", 154 dictFallbackText: "Please use the fallback form below to upload your files like in the olden days.", 155 dictFileTooBig: "File is too big ({{filesize}}MiB). Max filesize: {{maxFilesize}}MiB.", 156 dictInvalidFileType: "You can't upload files of this type.", 157 dictResponseError: "Server responded with {{statusCode}} code.", 158 dictCancelUpload: "Cancel upload", 159 dictCancelUploadConfirmation: "Are you sure you want to cancel this upload?", 160 dictRemoveFile: "Remove file", 161 dictRemoveFileConfirmation: null, 162 dictMaxFilesExceeded: "You can not upload any more files.", 163 dictFileSizeUnits: { 164 tb: "TB", 165 gb: "GB", 166 mb: "MB", 167 kb: "KB", 168 b: "b" 169 }, 170 init: function() { 171 return noop; 172 }, 173 accept: function(file, done) { 174 return done(); 175 }, 176 fallback: function() { 177 var child, j, len, messageElement, ref, span; 178 this.element.className = this.element.className + " dz-browser-not-supported"; 179 ref = this.element.getElementsByTagName("div"); 180 for (j = 0, len = ref.length; j < len; j++) { 181 child = ref[j]; 182 if (/(^| )dz-message($| )/.test(child.className)) { 183 messageElement = child; 184 child.className = "dz-message"; 185 continue; 186 } 187 } 188 if (!messageElement) { 189 messageElement = Dropzone.createElement("<div class=\"dz-message\"><span></span></div>"); 190 this.element.appendChild(messageElement); 191 } 192 span = messageElement.getElementsByTagName("span")[0]; 193 if (span) { 194 if (span.textContent != null) { 195 span.textContent = this.options.dictFallbackMessage; 196 } else if (span.innerText != null) { 197 span.innerText = this.options.dictFallbackMessage; 198 } 199 } 200 return this.element.appendChild(this.getFallbackForm()); 201 }, 202 resize: function(file, width, height, resizeMethod) { 203 var info, srcRatio, trgRatio; 204 info = { 205 srcX: 0, 206 srcY: 0, 207 srcWidth: file.width, 208 srcHeight: file.height 209 }; 210 srcRatio = file.width / file.height; 211 if ((width == null) && (height == null)) { 212 width = info.srcWidth; 213 height = info.srcHeight; 214 } else if (width == null) { 215 width = height * srcRatio; 216 } else if (height == null) { 217 height = width / srcRatio; 218 } 219 width = Math.min(width, info.srcWidth); 220 height = Math.min(height, info.srcHeight); 221 trgRatio = width / height; 222 if (info.srcWidth > width || info.srcHeight > height) { 223 if (resizeMethod === 'crop') { 224 if (srcRatio > trgRatio) { 225 info.srcHeight = file.height; 226 info.srcWidth = info.srcHeight * trgRatio; 145 */ 146 this.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"]; 147 148 this.prototype.defaultOptions = { 149 /** 150 * Has to be specified on elements other than form (or when the form 151 * doesn't have an `action` attribute). You can also 152 * provide a function that will be called with `files` and 153 * must return the url (since `v3.12.0`) 154 */ 155 url: null, 156 157 /** 158 * Can be changed to `"put"` if necessary. You can also provide a function 159 * that will be called with `files` and must return the method (since `v3.12.0`). 160 */ 161 method: "post", 162 163 /** 164 * Will be set on the XHRequest. 165 */ 166 withCredentials: false, 167 168 /** 169 * The timeout for the XHR requests in milliseconds (since `v4.4.0`). 170 */ 171 timeout: 30000, 172 173 /** 174 * How many file uploads to process in parallel (See the 175 * Enqueuing file uploads* documentation section for more info) 176 */ 177 parallelUploads: 2, 178 179 /** 180 * Whether to send multiple files in one request. If 181 * this it set to true, then the fallback file input element will 182 * have the `multiple` attribute as well. This option will 183 * also trigger additional events (like `processingmultiple`). See the events 184 * documentation section for more information. 185 */ 186 uploadMultiple: false, 187 188 /** 189 * Whether you want files to be uploaded in chunks to your server. This can't be 190 * used in combination with `uploadMultiple`. 191 * 192 * See [chunksUploaded](#config-chunksUploaded) for the callback to finalise an upload. 193 */ 194 chunking: false, 195 196 /** 197 * If `chunking` is enabled, this defines whether **every** file should be chunked, 198 * even if the file size is below chunkSize. This means, that the additional chunk 199 * form data will be submitted and the `chunksUploaded` callback will be invoked. 200 */ 201 forceChunking: false, 202 203 /** 204 * If `chunking` is `true`, then this defines the chunk size in bytes. 205 */ 206 chunkSize: 2000000, 207 208 /** 209 * If `true`, the individual chunks of a file are being uploaded simultaneously. 210 */ 211 parallelChunkUploads: false, 212 213 /** 214 * Whether a chunk should be retried if it fails. 215 */ 216 retryChunks: false, 217 218 /** 219 * If `retryChunks` is true, how many times should it be retried. 220 */ 221 retryChunksLimit: 3, 222 223 /** 224 * If not `null` defines how many files this Dropzone handles. If it exceeds, 225 * the event `maxfilesexceeded` will be called. The dropzone element gets the 226 * class `dz-max-files-reached` accordingly so you can provide visual feedback. 227 */ 228 maxFilesize: 256, 229 230 /** 231 * The name of the file param that gets transferred. 232 * **NOTE**: If you have the option `uploadMultiple` set to `true`, then 233 * Dropzone will append `[]` to the name. 234 */ 235 paramName: "file", 236 237 /** 238 * Whether thumbnails for images should be generated 239 */ 240 createImageThumbnails: true, 241 242 /** 243 * In MB. When the filename exceeds this limit, the thumbnail will not be generated. 244 */ 245 maxThumbnailFilesize: 10, 246 247 /** 248 * If `null`, the ratio of the image will be used to calculate it. 249 */ 250 thumbnailWidth: 120, 251 252 /** 253 * The same as `thumbnailWidth`. If both are null, images will not be resized. 254 */ 255 thumbnailHeight: 120, 256 257 /** 258 * How the images should be scaled down in case both, `thumbnailWidth` and `thumbnailHeight` are provided. 259 * Can be either `contain` or `crop`. 260 */ 261 thumbnailMethod: 'crop', 262 263 /** 264 * If set, images will be resized to these dimensions before being **uploaded**. 265 * If only one, `resizeWidth` **or** `resizeHeight` is provided, the original aspect 266 * ratio of the file will be preserved. 267 * 268 * The `options.transformFile` function uses these options, so if the `transformFile` function 269 * is overridden, these options don't do anything. 270 */ 271 resizeWidth: null, 272 273 /** 274 * See `resizeWidth`. 275 */ 276 resizeHeight: null, 277 278 /** 279 * The mime type of the resized image (before it gets uploaded to the server). 280 * If `null` the original mime type will be used. To force jpeg, for example, use `image/jpeg`. 281 * See `resizeWidth` for more information. 282 */ 283 resizeMimeType: null, 284 285 /** 286 * The quality of the resized images. See `resizeWidth`. 287 */ 288 resizeQuality: 0.8, 289 290 /** 291 * How the images should be scaled down in case both, `resizeWidth` and `resizeHeight` are provided. 292 * Can be either `contain` or `crop`. 293 */ 294 resizeMethod: 'contain', 295 296 /** 297 * The base that is used to calculate the filesize. You can change this to 298 * 1024 if you would rather display kibibytes, mebibytes, etc... 299 * 1024 is technically incorrect, because `1024 bytes` are `1 kibibyte` not `1 kilobyte`. 300 * You can change this to `1024` if you don't care about validity. 301 */ 302 filesizeBase: 1000, 303 304 /** 305 * Can be used to limit the maximum number of files that will be handled by this Dropzone 306 */ 307 maxFiles: null, 308 309 /** 310 * An optional object to send additional headers to the server. Eg: 311 * `{ "My-Awesome-Header": "header value" }` 312 */ 313 headers: null, 314 315 /** 316 * If `true`, the dropzone element itself will be clickable, if `false` 317 * nothing will be clickable. 318 * 319 * You can also pass an HTML element, a CSS selector (for multiple elements) 320 * or an array of those. In that case, all of those elements will trigger an 321 * upload when clicked. 322 */ 323 clickable: true, 324 325 /** 326 * Whether hidden files in directories should be ignored. 327 */ 328 ignoreHiddenFiles: true, 329 330 /** 331 * The default implementation of `accept` checks the file's mime type or 332 * extension against this list. This is a comma separated list of mime 333 * types or file extensions. 334 * 335 * Eg.: `image/*,application/pdf,.psd` 336 * 337 * If the Dropzone is `clickable` this option will also be used as 338 * [`accept`](https://developer.mozilla.org/en-US/docs/HTML/Element/input#attr-accept) 339 * parameter on the hidden file input as well. 340 */ 341 acceptedFiles: null, 342 343 /** 344 * **Deprecated!** 345 * Use acceptedFiles instead. 346 */ 347 acceptedMimeTypes: null, 348 349 /** 350 * If false, files will be added to the queue but the queue will not be 351 * processed automatically. 352 * This can be useful if you need some additional user input before sending 353 * files (or if you want want all files sent at once). 354 * If you're ready to send the file simply call `myDropzone.processQueue()`. 355 * 356 * See the [enqueuing file uploads](#enqueuing-file-uploads) documentation 357 * section for more information. 358 */ 359 autoProcessQueue: true, 360 361 /** 362 * If false, files added to the dropzone will not be queued by default. 363 * You'll have to call `enqueueFile(file)` manually. 364 */ 365 autoQueue: true, 366 367 /** 368 * If `true`, this will add a link to every file preview to remove or cancel (if 369 * already uploading) the file. The `dictCancelUpload`, `dictCancelUploadConfirmation` 370 * and `dictRemoveFile` options are used for the wording. 371 */ 372 addRemoveLinks: false, 373 374 /** 375 * Defines where to display the file previews – if `null` the 376 * Dropzone element itself is used. Can be a plain `HTMLElement` or a CSS 377 * selector. The element should have the `dropzone-previews` class so 378 * the previews are displayed properly. 379 */ 380 previewsContainer: null, 381 382 /** 383 * This is the element the hidden input field (which is used when clicking on the 384 * dropzone to trigger file selection) will be appended to. This might 385 * be important in case you use frameworks to switch the content of your page. 386 */ 387 hiddenInputContainer: "body", 388 389 /** 390 * If null, no capture type will be specified 391 * If camera, mobile devices will skip the file selection and choose camera 392 * If microphone, mobile devices will skip the file selection and choose the microphone 393 * If camcorder, mobile devices will skip the file selection and choose the camera in video mode 394 * On apple devices multiple must be set to false. AcceptedFiles may need to 395 * be set to an appropriate mime type (e.g. "image/*", "audio/*", or "video/*"). 396 */ 397 capture: null, 398 399 /** 400 * **Deprecated**. Use `renameFile` instead. 401 */ 402 renameFilename: null, 403 404 /** 405 * A function that is invoked before the file is uploaded to the server and renames the file. 406 * This function gets the `File` as argument and can use the `file.name`. The actual name of the 407 * file that gets used during the upload can be accessed through `file.upload.filename`. 408 */ 409 renameFile: null, 410 411 /** 412 * If `true` the fallback will be forced. This is very useful to test your server 413 * implementations first and make sure that everything works as 414 * expected without dropzone if you experience problems, and to test 415 * how your fallbacks will look. 416 */ 417 forceFallback: false, 418 419 /** 420 * The text used before any files are dropped. 421 */ 422 dictDefaultMessage: "Drop files here to upload", 423 424 /** 425 * The text that replaces the default message text it the browser is not supported. 426 */ 427 dictFallbackMessage: "Your browser does not support drag'n'drop file uploads.", 428 429 /** 430 * The text that will be added before the fallback form. 431 * If you provide a fallback element yourself, or if this option is `null` this will 432 * be ignored. 433 */ 434 dictFallbackText: "Please use the fallback form below to upload your files like in the olden days.", 435 436 /** 437 * If the filesize is too big. 438 * `{{filesize}}` and `{{maxFilesize}}` will be replaced with the respective configuration values. 439 */ 440 dictFileTooBig: "File is too big ({{filesize}}MiB). Max filesize: {{maxFilesize}}MiB.", 441 442 /** 443 * If the file doesn't match the file type. 444 */ 445 dictInvalidFileType: "You can't upload files of this type.", 446 447 /** 448 * If the server response was invalid. 449 * `{{statusCode}}` will be replaced with the servers status code. 450 */ 451 dictResponseError: "Server responded with {{statusCode}} code.", 452 453 /** 454 * If `addRemoveLinks` is true, the text to be used for the cancel upload link. 455 */ 456 dictCancelUpload: "Cancel upload", 457 458 /** 459 * If `addRemoveLinks` is true, the text to be used for confirmation when cancelling upload. 460 */ 461 dictCancelUploadConfirmation: "Are you sure you want to cancel this upload?", 462 463 /** 464 * If `addRemoveLinks` is true, the text to be used to remove a file. 465 */ 466 dictRemoveFile: "Remove file", 467 468 /** 469 * If this is not null, then the user will be prompted before removing a file. 470 */ 471 dictRemoveFileConfirmation: null, 472 473 /** 474 * Displayed if `maxFiles` is st and exceeded. 475 * The string `{{maxFiles}}` will be replaced by the configuration value. 476 */ 477 dictMaxFilesExceeded: "You can not upload any more files.", 478 479 /** 480 * Allows you to translate the different units. Starting with `tb` for terabytes and going down to 481 * `b` for bytes. 482 */ 483 dictFileSizeUnits: { tb: "TB", gb: "GB", mb: "MB", kb: "KB", b: "b" }, 484 485 /** 486 * Called when dropzone initialized 487 * You can add event listeners here 488 */ 489 init: function init() {}, 490 491 492 /** 493 * Can be an **object** of additional parameters to transfer to the server, **or** a `Function` 494 * that gets invoked with the `files`, `xhr` and, if it's a chunked upload, `chunk` arguments. In case 495 * of a function, this needs to return a map. 496 * 497 * The default implementation does nothing for normal uploads, but adds relevant information for 498 * chunked uploads. 499 * 500 * This is the same as adding hidden input fields in the form element. 501 */ 502 params: function params(files, xhr, chunk) { 503 if (chunk) { 504 return { 505 dzuuid: chunk.file.upload.uuid, 506 dzchunkindex: chunk.index, 507 dztotalfilesize: chunk.file.size, 508 dzchunksize: this.options.chunkSize, 509 dztotalchunkcount: chunk.file.upload.totalChunkCount, 510 dzchunkbyteoffset: chunk.index * this.options.chunkSize 511 }; 512 } 513 }, 514 515 516 /** 517 * A function that gets a [file](https://developer.mozilla.org/en-US/docs/DOM/File) 518 * and a `done` function as parameters. 519 * 520 * If the done function is invoked without arguments, the file is "accepted" and will 521 * be processed. If you pass an error message, the file is rejected, and the error 522 * message will be displayed. 523 * This function will not be called if the file is too big or doesn't match the mime types. 524 */ 525 accept: function accept(file, done) { 526 return done(); 527 }, 528 529 530 /** 531 * The callback that will be invoked when all chunks have been uploaded for a file. 532 * It gets the file for which the chunks have been uploaded as the first parameter, 533 * and the `done` function as second. `done()` needs to be invoked when everything 534 * needed to finish the upload process is done. 535 */ 536 chunksUploaded: function chunksUploaded(file, done) { 537 done(); 538 }, 539 540 /** 541 * Gets called when the browser is not supported. 542 * The default implementation shows the fallback input field and adds 543 * a text. 544 */ 545 fallback: function fallback() { 546 // This code should pass in IE7... :( 547 var messageElement = void 0; 548 this.element.className = this.element.className + " dz-browser-not-supported"; 549 550 for (var _iterator2 = this.element.getElementsByTagName("div"), _isArray2 = true, _i2 = 0, _iterator2 = _isArray2 ? _iterator2 : _iterator2[Symbol.iterator]();;) { 551 var _ref2; 552 553 if (_isArray2) { 554 if (_i2 >= _iterator2.length) break; 555 _ref2 = _iterator2[_i2++]; 227 556 } else { 228 info.srcWidth = file.width; 229 info.srcHeight = info.srcWidth / trgRatio; 557 _i2 = _iterator2.next(); 558 if (_i2.done) break; 559 _ref2 = _i2.value; 230 560 } 231 } else if (resizeMethod === 'contain') { 232 if (srcRatio > trgRatio) { 233 height = width / srcRatio; 561 562 var child = _ref2; 563 564 if (/(^| )dz-message($| )/.test(child.className)) { 565 messageElement = child; 566 child.className = "dz-message"; // Removes the 'dz-default' class 567 break; 568 } 569 } 570 if (!messageElement) { 571 messageElement = Dropzone.createElement("<div class=\"dz-message\"><span></span></div>"); 572 this.element.appendChild(messageElement); 573 } 574 575 var span = messageElement.getElementsByTagName("span")[0]; 576 if (span) { 577 if (span.textContent != null) { 578 span.textContent = this.options.dictFallbackMessage; 579 } else if (span.innerText != null) { 580 span.innerText = this.options.dictFallbackMessage; 581 } 582 } 583 584 return this.element.appendChild(this.getFallbackForm()); 585 }, 586 587 588 /** 589 * Gets called to calculate the thumbnail dimensions. 590 * 591 * It gets `file`, `width` and `height` (both may be `null`) as parameters and must return an object containing: 592 * 593 * - `srcWidth` & `srcHeight` (required) 594 * - `trgWidth` & `trgHeight` (required) 595 * - `srcX` & `srcY` (optional, default `0`) 596 * - `trgX` & `trgY` (optional, default `0`) 597 * 598 * Those values are going to be used by `ctx.drawImage()`. 599 */ 600 resize: function resize(file, width, height, resizeMethod) { 601 var info = { 602 srcX: 0, 603 srcY: 0, 604 srcWidth: file.width, 605 srcHeight: file.height 606 }; 607 608 var srcRatio = file.width / file.height; 609 610 // Automatically calculate dimensions if not specified 611 if (width == null && height == null) { 612 width = info.srcWidth; 613 height = info.srcHeight; 614 } else if (width == null) { 615 width = height * srcRatio; 616 } else if (height == null) { 617 height = width / srcRatio; 618 } 619 620 // Make sure images aren't upscaled 621 width = Math.min(width, info.srcWidth); 622 height = Math.min(height, info.srcHeight); 623 624 var trgRatio = width / height; 625 626 if (info.srcWidth > width || info.srcHeight > height) { 627 // Image is bigger and needs rescaling 628 if (resizeMethod === 'crop') { 629 if (srcRatio > trgRatio) { 630 info.srcHeight = file.height; 631 info.srcWidth = info.srcHeight * trgRatio; 632 } else { 633 info.srcWidth = file.width; 634 info.srcHeight = info.srcWidth / trgRatio; 635 } 636 } else if (resizeMethod === 'contain') { 637 // Method 'contain' 638 if (srcRatio > trgRatio) { 639 height = width / srcRatio; 640 } else { 641 width = height * srcRatio; 642 } 234 643 } else { 235 width = height * srcRatio;644 throw new Error("Unknown resizeMethod '" + resizeMethod + "'"); 236 645 } 646 } 647 648 info.srcX = (file.width - info.srcWidth) / 2; 649 info.srcY = (file.height - info.srcHeight) / 2; 650 651 info.trgWidth = width; 652 info.trgHeight = height; 653 654 return info; 655 }, 656 657 658 /** 659 * Can be used to transform the file (for example, resize an image if necessary). 660 * 661 * The default implementation uses `resizeWidth` and `resizeHeight` (if provided) and resizes 662 * images according to those dimensions. 663 * 664 * Gets the `file` as the first parameter, and a `done()` function as the second, that needs 665 * to be invoked with the file when the transformation is done. 666 */ 667 transformFile: function transformFile(file, done) { 668 if ((this.options.resizeWidth || this.options.resizeHeight) && file.type.match(/image.*/)) { 669 return this.resizeImage(file, this.options.resizeWidth, this.options.resizeHeight, this.options.resizeMethod, done); 237 670 } else { 238 throw new Error("Unknown resizeMethod '" + resizeMethod + "'"); 239 } 240 } 241 info.srcX = (file.width - info.srcWidth) / 2; 242 info.srcY = (file.height - info.srcHeight) / 2; 243 info.trgWidth = width; 244 info.trgHeight = height; 245 return info; 246 }, 247 transformFile: function(file, done) { 248 if ((this.options.resizeWidth || this.options.resizeHeight) && file.type.match(/image.*/)) { 249 return this.resizeImage(file, this.options.resizeWidth, this.options.resizeHeight, this.options.resizeMethod, done); 250 } else { 251 return done(file); 252 } 253 }, 254 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>", 255 256 /* 257 Those functions register themselves to the events on init and handle all 258 the user interface specific stuff. Overwriting them won't break the upload 259 but can break the way it's displayed. 260 You can overwrite them if you don't like the default behavior. If you just 261 want to add an additional event handler, register it on the dropzone object 262 and don't overwrite those options. 263 */ 264 drop: function(e) { 265 return this.element.classList.remove("dz-drag-hover"); 266 }, 267 dragstart: noop, 268 dragend: function(e) { 269 return this.element.classList.remove("dz-drag-hover"); 270 }, 271 dragenter: function(e) { 272 return this.element.classList.add("dz-drag-hover"); 273 }, 274 dragover: function(e) { 275 return this.element.classList.add("dz-drag-hover"); 276 }, 277 dragleave: function(e) { 278 return this.element.classList.remove("dz-drag-hover"); 279 }, 280 paste: noop, 281 reset: function() { 282 return this.element.classList.remove("dz-started"); 283 }, 284 addedfile: function(file) { 285 var j, k, l, len, len1, len2, node, ref, ref1, ref2, removeFileEvent, removeLink, results; 286 if (this.element === this.previewsContainer) { 287 this.element.classList.add("dz-started"); 288 } 289 if (this.previewsContainer) { 290 file.previewElement = Dropzone.createElement(this.options.previewTemplate.trim()); 291 file.previewTemplate = file.previewElement; 292 this.previewsContainer.appendChild(file.previewElement); 293 ref = file.previewElement.querySelectorAll("[data-dz-name]"); 294 for (j = 0, len = ref.length; j < len; j++) { 295 node = ref[j]; 296 node.textContent = file.name; 297 } 298 ref1 = file.previewElement.querySelectorAll("[data-dz-size]"); 299 for (k = 0, len1 = ref1.length; k < len1; k++) { 300 node = ref1[k]; 301 node.innerHTML = this.filesize(file.size); 302 } 303 if (this.options.addRemoveLinks) { 304 file._removeLink = Dropzone.createElement("<a class=\"dz-remove\" href=\"javascript:undefined;\" data-dz-remove>" + this.options.dictRemoveFile + "</a>"); 305 file.previewElement.appendChild(file._removeLink); 306 } 307 removeFileEvent = (function(_this) { 308 return function(e) { 671 return done(file); 672 } 673 }, 674 675 676 /** 677 * A string that contains the template used for each dropped 678 * file. Change it to fulfill your needs but make sure to properly 679 * provide all elements. 680 * 681 * If you want to use an actual HTML element instead of providing a String 682 * as a config option, you could create a div with the id `tpl`, 683 * put the template inside it and provide the element like this: 684 * 685 * document 686 * .querySelector('#tpl') 687 * .innerHTML 688 * 689 */ 690 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>", 691 692 // END OPTIONS 693 // (Required by the dropzone documentation parser) 694 695 696 /* 697 Those functions register themselves to the events on init and handle all 698 the user interface specific stuff. Overwriting them won't break the upload 699 but can break the way it's displayed. 700 You can overwrite them if you don't like the default behavior. If you just 701 want to add an additional event handler, register it on the dropzone object 702 and don't overwrite those options. 703 */ 704 705 // Those are self explanatory and simply concern the DragnDrop. 706 drop: function drop(e) { 707 return this.element.classList.remove("dz-drag-hover"); 708 }, 709 dragstart: function dragstart(e) {}, 710 dragend: function dragend(e) { 711 return this.element.classList.remove("dz-drag-hover"); 712 }, 713 dragenter: function dragenter(e) { 714 return this.element.classList.add("dz-drag-hover"); 715 }, 716 dragover: function dragover(e) { 717 return this.element.classList.add("dz-drag-hover"); 718 }, 719 dragleave: function dragleave(e) { 720 return this.element.classList.remove("dz-drag-hover"); 721 }, 722 paste: function paste(e) {}, 723 724 725 // Called whenever there are no files left in the dropzone anymore, and the 726 // dropzone should be displayed as if in the initial state. 727 reset: function reset() { 728 return this.element.classList.remove("dz-started"); 729 }, 730 731 732 // Called when a file is added to the queue 733 // Receives `file` 734 addedfile: function addedfile(file) { 735 var _this2 = this; 736 737 if (this.element === this.previewsContainer) { 738 this.element.classList.add("dz-started"); 739 } 740 741 if (this.previewsContainer) { 742 file.previewElement = Dropzone.createElement(this.options.previewTemplate.trim()); 743 file.previewTemplate = file.previewElement; // Backwards compatibility 744 745 this.previewsContainer.appendChild(file.previewElement); 746 for (var _iterator3 = file.previewElement.querySelectorAll("[data-dz-name]"), _isArray3 = true, _i3 = 0, _iterator3 = _isArray3 ? _iterator3 : _iterator3[Symbol.iterator]();;) { 747 var _ref3; 748 749 if (_isArray3) { 750 if (_i3 >= _iterator3.length) break; 751 _ref3 = _iterator3[_i3++]; 752 } else { 753 _i3 = _iterator3.next(); 754 if (_i3.done) break; 755 _ref3 = _i3.value; 756 } 757 758 var node = _ref3; 759 760 node.textContent = file.name; 761 } 762 for (var _iterator4 = file.previewElement.querySelectorAll("[data-dz-size]"), _isArray4 = true, _i4 = 0, _iterator4 = _isArray4 ? _iterator4 : _iterator4[Symbol.iterator]();;) { 763 if (_isArray4) { 764 if (_i4 >= _iterator4.length) break; 765 node = _iterator4[_i4++]; 766 } else { 767 _i4 = _iterator4.next(); 768 if (_i4.done) break; 769 node = _i4.value; 770 } 771 772 node.innerHTML = this.filesize(file.size); 773 } 774 775 if (this.options.addRemoveLinks) { 776 file._removeLink = Dropzone.createElement("<a class=\"dz-remove\" href=\"javascript:undefined;\" data-dz-remove>" + this.options.dictRemoveFile + "</a>"); 777 file.previewElement.appendChild(file._removeLink); 778 } 779 780 var removeFileEvent = function removeFileEvent(e) { 309 781 e.preventDefault(); 310 782 e.stopPropagation(); 311 783 if (file.status === Dropzone.UPLOADING) { 312 return Dropzone.confirm(_this .options.dictCancelUploadConfirmation, function() {313 return _this .removeFile(file);784 return Dropzone.confirm(_this2.options.dictCancelUploadConfirmation, function () { 785 return _this2.removeFile(file); 314 786 }); 315 787 } else { 316 if (_this .options.dictRemoveFileConfirmation) {317 return Dropzone.confirm(_this .options.dictRemoveFileConfirmation, function() {318 return _this .removeFile(file);788 if (_this2.options.dictRemoveFileConfirmation) { 789 return Dropzone.confirm(_this2.options.dictRemoveFileConfirmation, function () { 790 return _this2.removeFile(file); 319 791 }); 320 792 } else { 321 return _this .removeFile(file);793 return _this2.removeFile(file); 322 794 } 323 795 } 324 796 }; 325 })(this); 326 ref2 = file.previewElement.querySelectorAll("[data-dz-remove]"); 327 results = []; 328 for (l = 0, len2 = ref2.length; l < len2; l++) { 329 removeLink = ref2[l]; 330 results.push(removeLink.addEventListener("click", removeFileEvent)); 331 } 332 return results; 333 } 334 }, 335 removedfile: function(file) { 336 var ref; 337 if (file.previewElement) { 338 if ((ref = file.previewElement) != null) { 339 ref.parentNode.removeChild(file.previewElement); 340 } 341 } 342 return this._updateMaxFilesReachedClass(); 343 }, 344 thumbnail: function(file, dataUrl) { 345 var j, len, ref, thumbnailElement; 346 if (file.previewElement) { 347 file.previewElement.classList.remove("dz-file-preview"); 348 ref = file.previewElement.querySelectorAll("[data-dz-thumbnail]"); 349 for (j = 0, len = ref.length; j < len; j++) { 350 thumbnailElement = ref[j]; 351 thumbnailElement.alt = file.name; 352 thumbnailElement.src = dataUrl; 353 } 354 return setTimeout(((function(_this) { 355 return function() { 797 798 for (var _iterator5 = file.previewElement.querySelectorAll("[data-dz-remove]"), _isArray5 = true, _i5 = 0, _iterator5 = _isArray5 ? _iterator5 : _iterator5[Symbol.iterator]();;) { 799 var _ref4; 800 801 if (_isArray5) { 802 if (_i5 >= _iterator5.length) break; 803 _ref4 = _iterator5[_i5++]; 804 } else { 805 _i5 = _iterator5.next(); 806 if (_i5.done) break; 807 _ref4 = _i5.value; 808 } 809 810 var removeLink = _ref4; 811 812 removeLink.addEventListener("click", removeFileEvent); 813 } 814 } 815 }, 816 817 818 // Called whenever a file is removed. 819 removedfile: function removedfile(file) { 820 if (file.previewElement != null && file.previewElement.parentNode != null) { 821 file.previewElement.parentNode.removeChild(file.previewElement); 822 } 823 return this._updateMaxFilesReachedClass(); 824 }, 825 826 827 // Called when a thumbnail has been generated 828 // Receives `file` and `dataUrl` 829 thumbnail: function thumbnail(file, dataUrl) { 830 if (file.previewElement) { 831 file.previewElement.classList.remove("dz-file-preview"); 832 for (var _iterator6 = file.previewElement.querySelectorAll("[data-dz-thumbnail]"), _isArray6 = true, _i6 = 0, _iterator6 = _isArray6 ? _iterator6 : _iterator6[Symbol.iterator]();;) { 833 var _ref5; 834 835 if (_isArray6) { 836 if (_i6 >= _iterator6.length) break; 837 _ref5 = _iterator6[_i6++]; 838 } else { 839 _i6 = _iterator6.next(); 840 if (_i6.done) break; 841 _ref5 = _i6.value; 842 } 843 844 var thumbnailElement = _ref5; 845 846 thumbnailElement.alt = file.name; 847 thumbnailElement.src = dataUrl; 848 } 849 850 return setTimeout(function () { 356 851 return file.previewElement.classList.add("dz-image-preview"); 357 }; 358 })(this)), 1); 359 } 360 }, 361 error: function(file, message) { 362 var j, len, node, ref, results; 363 if (file.previewElement) { 364 file.previewElement.classList.add("dz-error"); 365 if (typeof message !== "String" && message.error) { 366 message = message.error; 367 } 368 ref = file.previewElement.querySelectorAll("[data-dz-errormessage]"); 369 results = []; 370 for (j = 0, len = ref.length; j < len; j++) { 371 node = ref[j]; 372 results.push(node.textContent = message); 373 } 374 return results; 375 } 376 }, 377 errormultiple: noop, 378 processing: function(file) { 379 if (file.previewElement) { 380 file.previewElement.classList.add("dz-processing"); 852 }, 1); 853 } 854 }, 855 856 857 // Called whenever an error occurs 858 // Receives `file` and `message` 859 error: function error(file, message) { 860 if (file.previewElement) { 861 file.previewElement.classList.add("dz-error"); 862 if (typeof message !== "String" && message.error) { 863 message = message.error; 864 } 865 for (var _iterator7 = file.previewElement.querySelectorAll("[data-dz-errormessage]"), _isArray7 = true, _i7 = 0, _iterator7 = _isArray7 ? _iterator7 : _iterator7[Symbol.iterator]();;) { 866 var _ref6; 867 868 if (_isArray7) { 869 if (_i7 >= _iterator7.length) break; 870 _ref6 = _iterator7[_i7++]; 871 } else { 872 _i7 = _iterator7.next(); 873 if (_i7.done) break; 874 _ref6 = _i7.value; 875 } 876 877 var node = _ref6; 878 879 node.textContent = message; 880 } 881 } 882 }, 883 errormultiple: function errormultiple() {}, 884 885 886 // Called when a file gets processed. Since there is a cue, not all added 887 // files are processed immediately. 888 // Receives `file` 889 processing: function processing(file) { 890 if (file.previewElement) { 891 file.previewElement.classList.add("dz-processing"); 892 if (file._removeLink) { 893 return file._removeLink.textContent = this.options.dictCancelUpload; 894 } 895 } 896 }, 897 processingmultiple: function processingmultiple() {}, 898 899 900 // Called whenever the upload progress gets updated. 901 // Receives `file`, `progress` (percentage 0-100) and `bytesSent`. 902 // To get the total number of bytes of the file, use `file.size` 903 uploadprogress: function uploadprogress(file, progress, bytesSent) { 904 if (file.previewElement) { 905 for (var _iterator8 = file.previewElement.querySelectorAll("[data-dz-uploadprogress]"), _isArray8 = true, _i8 = 0, _iterator8 = _isArray8 ? _iterator8 : _iterator8[Symbol.iterator]();;) { 906 var _ref7; 907 908 if (_isArray8) { 909 if (_i8 >= _iterator8.length) break; 910 _ref7 = _iterator8[_i8++]; 911 } else { 912 _i8 = _iterator8.next(); 913 if (_i8.done) break; 914 _ref7 = _i8.value; 915 } 916 917 var node = _ref7; 918 919 node.nodeName === 'PROGRESS' ? node.value = progress : node.style.width = progress + "%"; 920 } 921 } 922 }, 923 924 925 // Called whenever the total upload progress gets updated. 926 // Called with totalUploadProgress (0-100), totalBytes and totalBytesSent 927 totaluploadprogress: function totaluploadprogress() {}, 928 929 930 // Called just before the file is sent. Gets the `xhr` object as second 931 // parameter, so you can modify it (for example to add a CSRF token) and a 932 // `formData` object to add additional information. 933 sending: function sending() {}, 934 sendingmultiple: function sendingmultiple() {}, 935 936 937 // When the complete upload is finished and successful 938 // Receives `file` 939 success: function success(file) { 940 if (file.previewElement) { 941 return file.previewElement.classList.add("dz-success"); 942 } 943 }, 944 successmultiple: function successmultiple() {}, 945 946 947 // When the upload is canceled. 948 canceled: function canceled(file) { 949 return this.emit("error", file, "Upload canceled."); 950 }, 951 canceledmultiple: function canceledmultiple() {}, 952 953 954 // When the upload is finished, either with success or an error. 955 // Receives `file` 956 complete: function complete(file) { 381 957 if (file._removeLink) { 382 return file._removeLink.textContent = this.options.dictCancelUpload; 383 } 384 } 385 }, 386 processingmultiple: noop, 387 uploadprogress: function(file, progress, bytesSent) { 388 var j, len, node, ref, results; 389 if (file.previewElement) { 390 ref = file.previewElement.querySelectorAll("[data-dz-uploadprogress]"); 391 results = []; 392 for (j = 0, len = ref.length; j < len; j++) { 393 node = ref[j]; 394 if (node.nodeName === 'PROGRESS') { 395 results.push(node.value = progress); 396 } else { 397 results.push(node.style.width = progress + "%"); 398 } 399 } 400 return results; 401 } 402 }, 403 totaluploadprogress: noop, 404 sending: noop, 405 sendingmultiple: noop, 406 success: function(file) { 407 if (file.previewElement) { 408 return file.previewElement.classList.add("dz-success"); 409 } 410 }, 411 successmultiple: noop, 412 canceled: function(file) { 413 return this.emit("error", file, "Upload canceled."); 414 }, 415 canceledmultiple: noop, 416 complete: function(file) { 417 if (file._removeLink) { 418 file._removeLink.textContent = this.options.dictRemoveFile; 419 } 420 if (file.previewElement) { 421 return file.previewElement.classList.add("dz-complete"); 422 } 423 }, 424 completemultiple: noop, 425 maxfilesexceeded: noop, 426 maxfilesreached: noop, 427 queuecomplete: noop, 428 addedfiles: noop 429 }; 430 431 extend = function() { 432 var j, key, len, object, objects, target, val; 433 target = arguments[0], objects = 2 <= arguments.length ? slice.call(arguments, 1) : []; 434 for (j = 0, len = objects.length; j < len; j++) { 435 object = objects[j]; 436 for (key in object) { 437 val = object[key]; 958 file._removeLink.textContent = this.options.dictRemoveFile; 959 } 960 if (file.previewElement) { 961 return file.previewElement.classList.add("dz-complete"); 962 } 963 }, 964 completemultiple: function completemultiple() {}, 965 maxfilesexceeded: function maxfilesexceeded() {}, 966 maxfilesreached: function maxfilesreached() {}, 967 queuecomplete: function queuecomplete() {}, 968 addedfiles: function addedfiles() {} 969 }; 970 971 this.prototype._thumbnailQueue = []; 972 this.prototype._processingThumbnail = false; 973 } 974 975 // global utility 976 977 }, { 978 key: "extend", 979 value: function extend(target) { 980 for (var _len2 = arguments.length, objects = Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) { 981 objects[_key2 - 1] = arguments[_key2]; 982 } 983 984 for (var _iterator9 = objects, _isArray9 = true, _i9 = 0, _iterator9 = _isArray9 ? _iterator9 : _iterator9[Symbol.iterator]();;) { 985 var _ref8; 986 987 if (_isArray9) { 988 if (_i9 >= _iterator9.length) break; 989 _ref8 = _iterator9[_i9++]; 990 } else { 991 _i9 = _iterator9.next(); 992 if (_i9.done) break; 993 _ref8 = _i9.value; 994 } 995 996 var object = _ref8; 997 998 for (var key in object) { 999 var val = object[key]; 438 1000 target[key] = val; 439 1001 } 440 1002 } 441 1003 return target; 442 }; 443 444 function Dropzone(element1, options) { 445 var elementOptions, fallback, ref; 446 this.element = element1; 447 this.version = Dropzone.version; 448 this.defaultOptions.previewTemplate = this.defaultOptions.previewTemplate.replace(/\n*/g, ""); 449 this.clickableElements = []; 450 this.listeners = []; 451 this.files = []; 452 if (typeof this.element === "string") { 453 this.element = document.querySelector(this.element); 454 } 455 if (!(this.element && (this.element.nodeType != null))) { 456 throw new Error("Invalid dropzone element."); 457 } 458 if (this.element.dropzone) { 459 throw new Error("Dropzone already attached."); 460 } 461 Dropzone.instances.push(this); 462 this.element.dropzone = this; 463 elementOptions = (ref = Dropzone.optionsForElement(this.element)) != null ? ref : {}; 464 this.options = extend({}, this.defaultOptions, elementOptions, options != null ? options : {}); 465 if (this.options.forceFallback || !Dropzone.isBrowserSupported()) { 466 return this.options.fallback.call(this); 467 } 468 if (this.options.url == null) { 469 this.options.url = this.element.getAttribute("action"); 470 } 471 if (!this.options.url) { 472 throw new Error("No URL provided."); 473 } 474 if (this.options.acceptedFiles && this.options.acceptedMimeTypes) { 475 throw new Error("You can't provide both 'acceptedFiles' and 'acceptedMimeTypes'. 'acceptedMimeTypes' is deprecated."); 476 } 477 if (this.options.acceptedMimeTypes) { 478 this.options.acceptedFiles = this.options.acceptedMimeTypes; 479 delete this.options.acceptedMimeTypes; 480 } 481 if (this.options.renameFilename != null) { 482 this.options.renameFile = (function(_this) { 483 return function(file) { 484 return _this.options.renameFilename.call(_this, file.name, file); 485 }; 486 })(this); 487 } 488 this.options.method = this.options.method.toUpperCase(); 489 if ((fallback = this.getExistingFallback()) && fallback.parentNode) { 490 fallback.parentNode.removeChild(fallback); 491 } 492 if (this.options.previewsContainer !== false) { 493 if (this.options.previewsContainer) { 494 this.previewsContainer = Dropzone.getElement(this.options.previewsContainer, "previewsContainer"); 495 } else { 496 this.previewsContainer = this.element; 497 } 498 } 499 if (this.options.clickable) { 500 if (this.options.clickable === true) { 501 this.clickableElements = [this.element]; 502 } else { 503 this.clickableElements = Dropzone.getElements(this.options.clickable, "clickable"); 504 } 505 } 506 this.init(); 507 } 508 509 Dropzone.prototype.getAcceptedFiles = function() { 510 var file, j, len, ref, results; 511 ref = this.files; 512 results = []; 513 for (j = 0, len = ref.length; j < len; j++) { 514 file = ref[j]; 515 if (file.accepted) { 516 results.push(file); 517 } 518 } 519 return results; 520 }; 521 522 Dropzone.prototype.getRejectedFiles = function() { 523 var file, j, len, ref, results; 524 ref = this.files; 525 results = []; 526 for (j = 0, len = ref.length; j < len; j++) { 527 file = ref[j]; 528 if (!file.accepted) { 529 results.push(file); 530 } 531 } 532 return results; 533 }; 534 535 Dropzone.prototype.getFilesWithStatus = function(status) { 536 var file, j, len, ref, results; 537 ref = this.files; 538 results = []; 539 for (j = 0, len = ref.length; j < len; j++) { 540 file = ref[j]; 541 if (file.status === status) { 542 results.push(file); 543 } 544 } 545 return results; 546 }; 547 548 Dropzone.prototype.getQueuedFiles = function() { 1004 } 1005 }]); 1006 1007 function Dropzone(el, options) { 1008 _classCallCheck(this, Dropzone); 1009 1010 var _this = _possibleConstructorReturn(this, (Dropzone.__proto__ || Object.getPrototypeOf(Dropzone)).call(this)); 1011 1012 var fallback = void 0, 1013 left = void 0; 1014 _this.element = el; 1015 // For backwards compatibility since the version was in the prototype previously 1016 _this.version = Dropzone.version; 1017 1018 _this.defaultOptions.previewTemplate = _this.defaultOptions.previewTemplate.replace(/\n*/g, ""); 1019 1020 _this.clickableElements = []; 1021 _this.listeners = []; 1022 _this.files = []; // All files 1023 1024 if (typeof _this.element === "string") { 1025 _this.element = document.querySelector(_this.element); 1026 } 1027 1028 // Not checking if instance of HTMLElement or Element since IE9 is extremely weird. 1029 if (!_this.element || _this.element.nodeType == null) { 1030 throw new Error("Invalid dropzone element."); 1031 } 1032 1033 if (_this.element.dropzone) { 1034 throw new Error("Dropzone already attached."); 1035 } 1036 1037 // Now add this dropzone to the instances. 1038 Dropzone.instances.push(_this); 1039 1040 // Put the dropzone inside the element itself. 1041 _this.element.dropzone = _this; 1042 1043 var elementOptions = (left = Dropzone.optionsForElement(_this.element)) != null ? left : {}; 1044 1045 _this.options = Dropzone.extend({}, _this.defaultOptions, elementOptions, options != null ? options : {}); 1046 1047 // If the browser failed, just call the fallback and leave 1048 if (_this.options.forceFallback || !Dropzone.isBrowserSupported()) { 1049 var _ret; 1050 1051 return _ret = _this.options.fallback.call(_this), _possibleConstructorReturn(_this, _ret); 1052 } 1053 1054 // @options.url = @element.getAttribute "action" unless @options.url? 1055 if (_this.options.url == null) { 1056 _this.options.url = _this.element.getAttribute("action"); 1057 } 1058 1059 if (!_this.options.url) { 1060 throw new Error("No URL provided."); 1061 } 1062 1063 if (_this.options.acceptedFiles && _this.options.acceptedMimeTypes) { 1064 throw new Error("You can't provide both 'acceptedFiles' and 'acceptedMimeTypes'. 'acceptedMimeTypes' is deprecated."); 1065 } 1066 1067 if (_this.options.uploadMultiple && _this.options.chunking) { 1068 throw new Error('You cannot set both: uploadMultiple and chunking.'); 1069 } 1070 1071 // Backwards compatibility 1072 if (_this.options.acceptedMimeTypes) { 1073 _this.options.acceptedFiles = _this.options.acceptedMimeTypes; 1074 delete _this.options.acceptedMimeTypes; 1075 } 1076 1077 // Backwards compatibility 1078 if (_this.options.renameFilename != null) { 1079 _this.options.renameFile = function (file) { 1080 return _this.options.renameFilename.call(_this, file.name, file); 1081 }; 1082 } 1083 1084 _this.options.method = _this.options.method.toUpperCase(); 1085 1086 if ((fallback = _this.getExistingFallback()) && fallback.parentNode) { 1087 // Remove the fallback 1088 fallback.parentNode.removeChild(fallback); 1089 } 1090 1091 // Display previews in the previewsContainer element or the Dropzone element unless explicitly set to false 1092 if (_this.options.previewsContainer !== false) { 1093 if (_this.options.previewsContainer) { 1094 _this.previewsContainer = Dropzone.getElement(_this.options.previewsContainer, "previewsContainer"); 1095 } else { 1096 _this.previewsContainer = _this.element; 1097 } 1098 } 1099 1100 if (_this.options.clickable) { 1101 if (_this.options.clickable === true) { 1102 _this.clickableElements = [_this.element]; 1103 } else { 1104 _this.clickableElements = Dropzone.getElements(_this.options.clickable, "clickable"); 1105 } 1106 } 1107 1108 _this.init(); 1109 return _this; 1110 } 1111 1112 // Returns all files that have been accepted 1113 1114 1115 _createClass(Dropzone, [{ 1116 key: "getAcceptedFiles", 1117 value: function getAcceptedFiles() { 1118 return this.files.filter(function (file) { 1119 return file.accepted; 1120 }).map(function (file) { 1121 return file; 1122 }); 1123 } 1124 1125 // Returns all files that have been rejected 1126 // Not sure when that's going to be useful, but added for completeness. 1127 1128 }, { 1129 key: "getRejectedFiles", 1130 value: function getRejectedFiles() { 1131 return this.files.filter(function (file) { 1132 return !file.accepted; 1133 }).map(function (file) { 1134 return file; 1135 }); 1136 } 1137 }, { 1138 key: "getFilesWithStatus", 1139 value: function getFilesWithStatus(status) { 1140 return this.files.filter(function (file) { 1141 return file.status === status; 1142 }).map(function (file) { 1143 return file; 1144 }); 1145 } 1146 1147 // Returns all files that are in the queue 1148 1149 }, { 1150 key: "getQueuedFiles", 1151 value: function getQueuedFiles() { 549 1152 return this.getFilesWithStatus(Dropzone.QUEUED); 550 }; 551 552 Dropzone.prototype.getUploadingFiles = function() { 1153 } 1154 }, { 1155 key: "getUploadingFiles", 1156 value: function getUploadingFiles() { 553 1157 return this.getFilesWithStatus(Dropzone.UPLOADING); 554 }; 555 556 Dropzone.prototype.getAddedFiles = function() { 1158 } 1159 }, { 1160 key: "getAddedFiles", 1161 value: function getAddedFiles() { 557 1162 return this.getFilesWithStatus(Dropzone.ADDED); 558 }; 559 560 Dropzone.prototype.getActiveFiles = function() { 561 var file, j, len, ref, results; 562 ref = this.files; 563 results = []; 564 for (j = 0, len = ref.length; j < len; j++) { 565 file = ref[j]; 566 if (file.status === Dropzone.UPLOADING || file.status === Dropzone.QUEUED) { 567 results.push(file); 568 } 569 } 570 return results; 571 }; 572 573 Dropzone.prototype.init = function() { 574 var eventName, j, len, noPropagation, ref, ref1, setupHiddenFileInput; 1163 } 1164 1165 // Files that are either queued or uploading 1166 1167 }, { 1168 key: "getActiveFiles", 1169 value: function getActiveFiles() { 1170 return this.files.filter(function (file) { 1171 return file.status === Dropzone.UPLOADING || file.status === Dropzone.QUEUED; 1172 }).map(function (file) { 1173 return file; 1174 }); 1175 } 1176 1177 // The function that gets called when Dropzone is initialized. You 1178 // can (and should) setup event listeners inside this function. 1179 1180 }, { 1181 key: "init", 1182 value: function init() { 1183 var _this3 = this; 1184 1185 // In case it isn't set already 575 1186 if (this.element.tagName === "form") { 576 1187 this.element.setAttribute("enctype", "multipart/form-data"); 577 1188 } 1189 578 1190 if (this.element.classList.contains("dropzone") && !this.element.querySelector(".dz-message")) { 579 1191 this.element.appendChild(Dropzone.createElement("<div class=\"dz-default dz-message\"><span>" + this.options.dictDefaultMessage + "</span></div>")); 580 1192 } 1193 581 1194 if (this.clickableElements.length) { 582 setupHiddenFileInput = (function(_this) { 583 return function() { 584 if (_this.hiddenFileInput) { 585 _this.hiddenFileInput.parentNode.removeChild(_this.hiddenFileInput); 1195 var setupHiddenFileInput = function setupHiddenFileInput() { 1196 if (_this3.hiddenFileInput) { 1197 _this3.hiddenFileInput.parentNode.removeChild(_this3.hiddenFileInput); 1198 } 1199 _this3.hiddenFileInput = document.createElement("input"); 1200 _this3.hiddenFileInput.setAttribute("type", "file"); 1201 if (_this3.options.maxFiles === null || _this3.options.maxFiles > 1) { 1202 _this3.hiddenFileInput.setAttribute("multiple", "multiple"); 1203 } 1204 _this3.hiddenFileInput.className = "dz-hidden-input"; 1205 1206 if (_this3.options.acceptedFiles !== null) { 1207 _this3.hiddenFileInput.setAttribute("accept", _this3.options.acceptedFiles); 1208 } 1209 if (_this3.options.capture !== null) { 1210 _this3.hiddenFileInput.setAttribute("capture", _this3.options.capture); 1211 } 1212 1213 // Not setting `display="none"` because some browsers don't accept clicks 1214 // on elements that aren't displayed. 1215 _this3.hiddenFileInput.style.visibility = "hidden"; 1216 _this3.hiddenFileInput.style.position = "absolute"; 1217 _this3.hiddenFileInput.style.top = "0"; 1218 _this3.hiddenFileInput.style.left = "0"; 1219 _this3.hiddenFileInput.style.height = "0"; 1220 _this3.hiddenFileInput.style.width = "0"; 1221 document.querySelector(_this3.options.hiddenInputContainer).appendChild(_this3.hiddenFileInput); 1222 return _this3.hiddenFileInput.addEventListener("change", function () { 1223 var files = _this3.hiddenFileInput.files; 1224 1225 if (files.length) { 1226 for (var _iterator10 = files, _isArray10 = true, _i10 = 0, _iterator10 = _isArray10 ? _iterator10 : _iterator10[Symbol.iterator]();;) { 1227 var _ref9; 1228 1229 if (_isArray10) { 1230 if (_i10 >= _iterator10.length) break; 1231 _ref9 = _iterator10[_i10++]; 1232 } else { 1233 _i10 = _iterator10.next(); 1234 if (_i10.done) break; 1235 _ref9 = _i10.value; 1236 } 1237 1238 var file = _ref9; 1239 1240 _this3.addFile(file); 1241 } 586 1242 } 587 _this.hiddenFileInput = document.createElement("input"); 588 _this.hiddenFileInput.setAttribute("type", "file"); 589 if ((_this.options.maxFiles == null) || _this.options.maxFiles > 1) { 590 _this.hiddenFileInput.setAttribute("multiple", "multiple"); 591 } 592 _this.hiddenFileInput.className = "dz-hidden-input"; 593 if (_this.options.acceptedFiles != null) { 594 _this.hiddenFileInput.setAttribute("accept", _this.options.acceptedFiles); 595 } 596 if (_this.options.capture != null) { 597 _this.hiddenFileInput.setAttribute("capture", _this.options.capture); 598 } 599 _this.hiddenFileInput.style.visibility = "hidden"; 600 _this.hiddenFileInput.style.position = "absolute"; 601 _this.hiddenFileInput.style.top = "0"; 602 _this.hiddenFileInput.style.left = "0"; 603 _this.hiddenFileInput.style.height = "0"; 604 _this.hiddenFileInput.style.width = "0"; 605 document.querySelector(_this.options.hiddenInputContainer).appendChild(_this.hiddenFileInput); 606 return _this.hiddenFileInput.addEventListener("change", function() { 607 var file, files, j, len; 608 files = _this.hiddenFileInput.files; 609 if (files.length) { 610 for (j = 0, len = files.length; j < len; j++) { 611 file = files[j]; 612 _this.addFile(file); 613 } 614 } 615 _this.emit("addedfiles", files); 616 return setupHiddenFileInput(); 617 }); 618 }; 619 })(this); 1243 _this3.emit("addedfiles", files); 1244 return setupHiddenFileInput(); 1245 }); 1246 }; 620 1247 setupHiddenFileInput(); 621 1248 } 622 this.URL = (ref = window.URL) != null ? ref : window.webkitURL; 623 ref1 = this.events; 624 for (j = 0, len = ref1.length; j < len; j++) { 625 eventName = ref1[j]; 1249 1250 this.URL = window.URL !== null ? window.URL : window.webkitURL; 1251 1252 // Setup all event listeners on the Dropzone object itself. 1253 // They're not in @setupEventListeners() because they shouldn't be removed 1254 // again when the dropzone gets disabled. 1255 for (var _iterator11 = this.events, _isArray11 = true, _i11 = 0, _iterator11 = _isArray11 ? _iterator11 : _iterator11[Symbol.iterator]();;) { 1256 var _ref10; 1257 1258 if (_isArray11) { 1259 if (_i11 >= _iterator11.length) break; 1260 _ref10 = _iterator11[_i11++]; 1261 } else { 1262 _i11 = _iterator11.next(); 1263 if (_i11.done) break; 1264 _ref10 = _i11.value; 1265 } 1266 1267 var eventName = _ref10; 1268 626 1269 this.on(eventName, this.options[eventName]); 627 1270 } 628 this.on("uploadprogress", (function(_this) { 629 return function() { 630 return _this.updateTotalUploadProgress(); 631 }; 632 })(this)); 633 this.on("removedfile", (function(_this) { 634 return function() { 635 return _this.updateTotalUploadProgress(); 636 }; 637 })(this)); 638 this.on("canceled", (function(_this) { 639 return function(file) { 640 return _this.emit("complete", file); 641 }; 642 })(this)); 643 this.on("complete", (function(_this) { 644 return function(file) { 645 if (_this.getAddedFiles().length === 0 && _this.getUploadingFiles().length === 0 && _this.getQueuedFiles().length === 0) { 646 return setTimeout((function() { 647 return _this.emit("queuecomplete"); 648 }), 0); 649 } 650 }; 651 })(this)); 652 noPropagation = function(e) { 1271 1272 this.on("uploadprogress", function () { 1273 return _this3.updateTotalUploadProgress(); 1274 }); 1275 1276 this.on("removedfile", function () { 1277 return _this3.updateTotalUploadProgress(); 1278 }); 1279 1280 this.on("canceled", function (file) { 1281 return _this3.emit("complete", file); 1282 }); 1283 1284 // Emit a `queuecomplete` event if all files finished uploading. 1285 this.on("complete", function (file) { 1286 if (_this3.getAddedFiles().length === 0 && _this3.getUploadingFiles().length === 0 && _this3.getQueuedFiles().length === 0) { 1287 // This needs to be deferred so that `queuecomplete` really triggers after `complete` 1288 return setTimeout(function () { 1289 return _this3.emit("queuecomplete"); 1290 }, 0); 1291 } 1292 }); 1293 1294 var noPropagation = function noPropagation(e) { 653 1295 e.stopPropagation(); 654 1296 if (e.preventDefault) { … … 658 1300 } 659 1301 }; 660 this.listeners = [ 661 { 662 element: this.element, 1302 1303 // Create the listeners 1304 this.listeners = [{ 1305 element: this.element, 1306 events: { 1307 "dragstart": function dragstart(e) { 1308 return _this3.emit("dragstart", e); 1309 }, 1310 "dragenter": function dragenter(e) { 1311 noPropagation(e); 1312 return _this3.emit("dragenter", e); 1313 }, 1314 "dragover": function dragover(e) { 1315 // Makes it possible to drag files from chrome's download bar 1316 // http://stackoverflow.com/questions/19526430/drag-and-drop-file-uploads-from-chrome-downloads-bar 1317 // Try is required to prevent bug in Internet Explorer 11 (SCRIPT65535 exception) 1318 var efct = void 0; 1319 try { 1320 efct = e.dataTransfer.effectAllowed; 1321 } catch (error) {} 1322 e.dataTransfer.dropEffect = 'move' === efct || 'linkMove' === efct ? 'move' : 'copy'; 1323 1324 noPropagation(e); 1325 return _this3.emit("dragover", e); 1326 }, 1327 "dragleave": function dragleave(e) { 1328 return _this3.emit("dragleave", e); 1329 }, 1330 "drop": function drop(e) { 1331 noPropagation(e); 1332 return _this3.drop(e); 1333 }, 1334 "dragend": function dragend(e) { 1335 return _this3.emit("dragend", e); 1336 } 1337 1338 // This is disabled right now, because the browsers don't implement it properly. 1339 // "paste": (e) => 1340 // noPropagation e 1341 // @paste e 1342 } }]; 1343 1344 this.clickableElements.forEach(function (clickableElement) { 1345 return _this3.listeners.push({ 1346 element: clickableElement, 663 1347 events: { 664 "dragstart": (function(_this) { 665 return function(e) { 666 return _this.emit("dragstart", e); 667 }; 668 })(this), 669 "dragenter": (function(_this) { 670 return function(e) { 671 noPropagation(e); 672 return _this.emit("dragenter", e); 673 }; 674 })(this), 675 "dragover": (function(_this) { 676 return function(e) { 677 var efct; 678 try { 679 efct = e.dataTransfer.effectAllowed; 680 } catch (undefined) {} 681 e.dataTransfer.dropEffect = 'move' === efct || 'linkMove' === efct ? 'move' : 'copy'; 682 noPropagation(e); 683 return _this.emit("dragover", e); 684 }; 685 })(this), 686 "dragleave": (function(_this) { 687 return function(e) { 688 return _this.emit("dragleave", e); 689 }; 690 })(this), 691 "drop": (function(_this) { 692 return function(e) { 693 noPropagation(e); 694 return _this.drop(e); 695 }; 696 })(this), 697 "dragend": (function(_this) { 698 return function(e) { 699 return _this.emit("dragend", e); 700 }; 701 })(this) 702 } 703 } 704 ]; 705 this.clickableElements.forEach((function(_this) { 706 return function(clickableElement) { 707 return _this.listeners.push({ 708 element: clickableElement, 709 events: { 710 "click": function(evt) { 711 if ((clickableElement !== _this.element) || (evt.target === _this.element || Dropzone.elementInside(evt.target, _this.element.querySelector(".dz-message")))) { 712 _this.hiddenFileInput.click(); 713 } 714 return true; 1348 "click": function click(evt) { 1349 // Only the actual dropzone or the message element should trigger file selection 1350 if (clickableElement !== _this3.element || evt.target === _this3.element || Dropzone.elementInside(evt.target, _this3.element.querySelector(".dz-message"))) { 1351 _this3.hiddenFileInput.click(); // Forward the click 715 1352 } 1353 return true; 716 1354 } 717 }); 718 }; 719 })(this)); 1355 } 1356 }); 1357 }); 1358 720 1359 this.enable(); 1360 721 1361 return this.options.init.call(this); 722 }; 723 724 Dropzone.prototype.destroy = function() { 725 var ref; 1362 } 1363 1364 // Not fully tested yet 1365 1366 }, { 1367 key: "destroy", 1368 value: function destroy() { 726 1369 this.disable(); 727 1370 this.removeAllFiles(true); 728 if ( (ref = this.hiddenFileInput) != null ? ref.parentNode : void 0) {1371 if (this.hiddenFileInput != null ? this.hiddenFileInput.parentNode : undefined) { 729 1372 this.hiddenFileInput.parentNode.removeChild(this.hiddenFileInput); 730 1373 this.hiddenFileInput = null; … … 732 1375 delete this.element.dropzone; 733 1376 return Dropzone.instances.splice(Dropzone.instances.indexOf(this), 1); 734 }; 735 736 Dropzone.prototype.updateTotalUploadProgress = function() { 737 var activeFiles, file, j, len, ref, totalBytes, totalBytesSent, totalUploadProgress; 738 totalBytesSent = 0; 739 totalBytes = 0; 740 activeFiles = this.getActiveFiles(); 1377 } 1378 }, { 1379 key: "updateTotalUploadProgress", 1380 value: function updateTotalUploadProgress() { 1381 var totalUploadProgress = void 0; 1382 var totalBytesSent = 0; 1383 var totalBytes = 0; 1384 1385 var activeFiles = this.getActiveFiles(); 1386 741 1387 if (activeFiles.length) { 742 ref = this.getActiveFiles(); 743 for (j = 0, len = ref.length; j < len; j++) { 744 file = ref[j]; 1388 for (var _iterator12 = this.getActiveFiles(), _isArray12 = true, _i12 = 0, _iterator12 = _isArray12 ? _iterator12 : _iterator12[Symbol.iterator]();;) { 1389 var _ref11; 1390 1391 if (_isArray12) { 1392 if (_i12 >= _iterator12.length) break; 1393 _ref11 = _iterator12[_i12++]; 1394 } else { 1395 _i12 = _iterator12.next(); 1396 if (_i12.done) break; 1397 _ref11 = _i12.value; 1398 } 1399 1400 var file = _ref11; 1401 745 1402 totalBytesSent += file.upload.bytesSent; 746 1403 totalBytes += file.upload.total; … … 750 1407 totalUploadProgress = 100; 751 1408 } 1409 752 1410 return this.emit("totaluploadprogress", totalUploadProgress, totalBytes, totalBytesSent); 753 }; 754 755 Dropzone.prototype._getParamName = function(n) { 1411 } 1412 1413 // @options.paramName can be a function taking one parameter rather than a string. 1414 // A parameter name for a file is obtained simply by calling this with an index number. 1415 1416 }, { 1417 key: "_getParamName", 1418 value: function _getParamName(n) { 756 1419 if (typeof this.options.paramName === "function") { 757 1420 return this.options.paramName(n); … … 759 1422 return "" + this.options.paramName + (this.options.uploadMultiple ? "[" + n + "]" : ""); 760 1423 } 761 }; 762 763 Dropzone.prototype._renameFile = function(file) { 1424 } 1425 1426 // If @options.renameFile is a function, 1427 // the function will be used to rename the file.name before appending it to the formData 1428 1429 }, { 1430 key: "_renameFile", 1431 value: function _renameFile(file) { 764 1432 if (typeof this.options.renameFile !== "function") { 765 1433 return file.name; 766 1434 } 767 1435 return this.options.renameFile(file); 768 }; 769 770 Dropzone.prototype.getFallbackForm = function() { 771 var existingFallback, fields, fieldsString, form; 1436 } 1437 1438 // Returns a form that can be used as fallback if the browser does not support DragnDrop 1439 // 1440 // If the dropzone is already a form, only the input field and button are returned. Otherwise a complete form element is provided. 1441 // This code has to pass in IE7 :( 1442 1443 }, { 1444 key: "getFallbackForm", 1445 value: function getFallbackForm() { 1446 var existingFallback = void 0, 1447 form = void 0; 772 1448 if (existingFallback = this.getExistingFallback()) { 773 1449 return existingFallback; 774 1450 } 775 fieldsString = "<div class=\"dz-fallback\">"; 1451 1452 var fieldsString = "<div class=\"dz-fallback\">"; 776 1453 if (this.options.dictFallbackText) { 777 1454 fieldsString += "<p>" + this.options.dictFallbackText + "</p>"; 778 1455 } 779 fieldsString += "<input type=\"file\" name=\"" + (this._getParamName(0)) + "\" " + (this.options.uploadMultiple ? 'multiple="multiple"' : void 0) + " /><input type=\"submit\" value=\"Upload!\"></div>"; 780 fields = Dropzone.createElement(fieldsString); 1456 fieldsString += "<input type=\"file\" name=\"" + this._getParamName(0) + "\" " + (this.options.uploadMultiple ? 'multiple="multiple"' : undefined) + " /><input type=\"submit\" value=\"Upload!\"></div>"; 1457 1458 var fields = Dropzone.createElement(fieldsString); 781 1459 if (this.element.tagName !== "FORM") { 782 1460 form = Dropzone.createElement("<form action=\"" + this.options.url + "\" enctype=\"multipart/form-data\" method=\"" + this.options.method + "\"></form>"); 783 1461 form.appendChild(fields); 784 1462 } else { 1463 // Make sure that the enctype and method attributes are set properly 785 1464 this.element.setAttribute("enctype", "multipart/form-data"); 786 1465 this.element.setAttribute("method", this.options.method); 787 1466 } 788 1467 return form != null ? form : fields; 789 }; 790 791 Dropzone.prototype.getExistingFallback = function() { 792 var fallback, getFallback, j, len, ref, tagName; 793 getFallback = function(elements) { 794 var el, j, len; 795 for (j = 0, len = elements.length; j < len; j++) { 796 el = elements[j]; 1468 } 1469 1470 // Returns the fallback elements if they exist already 1471 // 1472 // This code has to pass in IE7 :( 1473 1474 }, { 1475 key: "getExistingFallback", 1476 value: function getExistingFallback() { 1477 var getFallback = function getFallback(elements) { 1478 for (var _iterator13 = elements, _isArray13 = true, _i13 = 0, _iterator13 = _isArray13 ? _iterator13 : _iterator13[Symbol.iterator]();;) { 1479 var _ref12; 1480 1481 if (_isArray13) { 1482 if (_i13 >= _iterator13.length) break; 1483 _ref12 = _iterator13[_i13++]; 1484 } else { 1485 _i13 = _iterator13.next(); 1486 if (_i13.done) break; 1487 _ref12 = _i13.value; 1488 } 1489 1490 var el = _ref12; 1491 797 1492 if (/(^| )fallback($| )/.test(el.className)) { 798 1493 return el; … … 800 1495 } 801 1496 }; 802 ref = ["div", "form"]; 803 for (j = 0, len = ref.length; j < len; j++) { 804 tagName = ref[j]; 1497 1498 var _arr = ["div", "form"]; 1499 for (var _i14 = 0; _i14 < _arr.length; _i14++) { 1500 var tagName = _arr[_i14]; 1501 var fallback; 805 1502 if (fallback = getFallback(this.element.getElementsByTagName(tagName))) { 806 1503 return fallback; 807 1504 } 808 1505 } 809 }; 810 811 Dropzone.prototype.setupEventListeners = function() { 812 var elementListeners, event, j, len, listener, ref, results; 813 ref = this.listeners; 814 results = []; 815 for (j = 0, len = ref.length; j < len; j++) { 816 elementListeners = ref[j]; 817 results.push((function() { 818 var ref1, results1; 819 ref1 = elementListeners.events; 820 results1 = []; 821 for (event in ref1) { 822 listener = ref1[event]; 823 results1.push(elementListeners.element.addEventListener(event, listener, false)); 824 } 825 return results1; 826 })()); 827 } 828 return results; 829 }; 830 831 Dropzone.prototype.removeEventListeners = function() { 832 var elementListeners, event, j, len, listener, ref, results; 833 ref = this.listeners; 834 results = []; 835 for (j = 0, len = ref.length; j < len; j++) { 836 elementListeners = ref[j]; 837 results.push((function() { 838 var ref1, results1; 839 ref1 = elementListeners.events; 840 results1 = []; 841 for (event in ref1) { 842 listener = ref1[event]; 843 results1.push(elementListeners.element.removeEventListener(event, listener, false)); 844 } 845 return results1; 846 })()); 847 } 848 return results; 849 }; 850 851 Dropzone.prototype.disable = function() { 852 var file, j, len, ref, results; 853 this.clickableElements.forEach(function(element) { 1506 } 1507 1508 // Activates all listeners stored in @listeners 1509 1510 }, { 1511 key: "setupEventListeners", 1512 value: function setupEventListeners() { 1513 return this.listeners.map(function (elementListeners) { 1514 return function () { 1515 var result = []; 1516 for (var event in elementListeners.events) { 1517 var listener = elementListeners.events[event]; 1518 result.push(elementListeners.element.addEventListener(event, listener, false)); 1519 } 1520 return result; 1521 }(); 1522 }); 1523 } 1524 1525 // Deactivates all listeners stored in @listeners 1526 1527 }, { 1528 key: "removeEventListeners", 1529 value: function removeEventListeners() { 1530 return this.listeners.map(function (elementListeners) { 1531 return function () { 1532 var result = []; 1533 for (var event in elementListeners.events) { 1534 var listener = elementListeners.events[event]; 1535 result.push(elementListeners.element.removeEventListener(event, listener, false)); 1536 } 1537 return result; 1538 }(); 1539 }); 1540 } 1541 1542 // Removes all event listeners and cancels all files in the queue or being processed. 1543 1544 }, { 1545 key: "disable", 1546 value: function disable() { 1547 var _this4 = this; 1548 1549 this.clickableElements.forEach(function (element) { 854 1550 return element.classList.remove("dz-clickable"); 855 1551 }); 856 1552 this.removeEventListeners(); 857 ref = this.files; 858 results = []; 859 for (j = 0, len = ref.length; j < len; j++) { 860 file = ref[j]; 861 results.push(this.cancelUpload(file)); 862 } 863 return results; 864 }; 865 866 Dropzone.prototype.enable = function() { 867 this.clickableElements.forEach(function(element) { 1553 1554 return this.files.map(function (file) { 1555 return _this4.cancelUpload(file); 1556 }); 1557 } 1558 }, { 1559 key: "enable", 1560 value: function enable() { 1561 this.clickableElements.forEach(function (element) { 868 1562 return element.classList.add("dz-clickable"); 869 1563 }); 870 1564 return this.setupEventListeners(); 871 }; 872 873 Dropzone.prototype.filesize = function(size) { 874 var cutoff, i, j, len, selectedSize, selectedUnit, unit, units; 875 selectedSize = 0; 876 selectedUnit = "b"; 1565 } 1566 1567 // Returns a nicely formatted filesize 1568 1569 }, { 1570 key: "filesize", 1571 value: function filesize(size) { 1572 var selectedSize = 0; 1573 var selectedUnit = "b"; 1574 877 1575 if (size > 0) { 878 units = ['tb', 'gb', 'mb', 'kb', 'b']; 879 for (i = j = 0, len = units.length; j < len; i = ++j) { 880 unit = units[i]; 881 cutoff = Math.pow(this.options.filesizeBase, 4 - i) / 10; 1576 var units = ['tb', 'gb', 'mb', 'kb', 'b']; 1577 1578 for (var i = 0; i < units.length; i++) { 1579 var unit = units[i]; 1580 var cutoff = Math.pow(this.options.filesizeBase, 4 - i) / 10; 1581 882 1582 if (size >= cutoff) { 883 1583 selectedSize = size / Math.pow(this.options.filesizeBase, 4 - i); … … 886 1586 } 887 1587 } 888 selectedSize = Math.round(10 * selectedSize) / 10; 889 } 1588 1589 selectedSize = Math.round(10 * selectedSize) / 10; // Cutting of digits 1590 } 1591 890 1592 return "<strong>" + selectedSize + "</strong> " + this.options.dictFileSizeUnits[selectedUnit]; 891 }; 892 893 Dropzone.prototype._updateMaxFilesReachedClass = function() { 894 if ((this.options.maxFiles != null) && this.getAcceptedFiles().length >= this.options.maxFiles) { 1593 } 1594 1595 // Adds or removes the `dz-max-files-reached` class from the form. 1596 1597 }, { 1598 key: "_updateMaxFilesReachedClass", 1599 value: function _updateMaxFilesReachedClass() { 1600 if (this.options.maxFiles != null && this.getAcceptedFiles().length >= this.options.maxFiles) { 895 1601 if (this.getAcceptedFiles().length === this.options.maxFiles) { 896 1602 this.emit('maxfilesreached', this.files); … … 900 1606 return this.element.classList.remove("dz-max-files-reached"); 901 1607 } 902 } ;903 904 Dropzone.prototype.drop = function(e) {905 var files, items;1608 } 1609 }, { 1610 key: "drop", 1611 value: function drop(e) { 906 1612 if (!e.dataTransfer) { 907 1613 return; 908 1614 } 909 1615 this.emit("drop", e); 910 files = e.dataTransfer.files; 1616 1617 var files = e.dataTransfer.files; 1618 911 1619 this.emit("addedfiles", files); 1620 1621 // Even if it's a folder, files.length will contain the folders. 912 1622 if (files.length) { 913 items = e.dataTransfer.items; 914 if (items && items.length && (items[0].webkitGetAsEntry != null)) { 1623 var items = e.dataTransfer.items; 1624 1625 if (items && items.length && items[0].webkitGetAsEntry != null) { 1626 // The browser supports dropping of folders, so handle items instead of files 915 1627 this._addFilesFromItems(items); 916 1628 } else { … … 918 1630 } 919 1631 } 920 }; 921 922 Dropzone.prototype.paste = function(e) { 923 var items, ref; 924 if ((e != null ? (ref = e.clipboardData) != null ? ref.items : void 0 : void 0) == null) { 1632 } 1633 }, { 1634 key: "paste", 1635 value: function paste(e) { 1636 if (__guard__(e != null ? e.clipboardData : undefined, function (x) { 1637 return x.items; 1638 }) == null) { 925 1639 return; 926 1640 } 1641 927 1642 this.emit("paste", e); 928 items = e.clipboardData.items; 1643 var items = e.clipboardData.items; 1644 1645 929 1646 if (items.length) { 930 1647 return this._addFilesFromItems(items); 931 1648 } 932 }; 933 934 Dropzone.prototype.handleFiles = function(files) { 935 var file, j, len, results; 936 results = []; 937 for (j = 0, len = files.length; j < len; j++) { 938 file = files[j]; 939 results.push(this.addFile(file)); 940 } 941 return results; 942 }; 943 944 Dropzone.prototype._addFilesFromItems = function(items) { 945 var entry, item, j, len, results; 946 results = []; 947 for (j = 0, len = items.length; j < len; j++) { 948 item = items[j]; 949 if ((item.webkitGetAsEntry != null) && (entry = item.webkitGetAsEntry())) { 950 if (entry.isFile) { 951 results.push(this.addFile(item.getAsFile())); 952 } else if (entry.isDirectory) { 953 results.push(this._addFilesFromDirectory(entry, entry.name)); 1649 } 1650 }, { 1651 key: "handleFiles", 1652 value: function handleFiles(files) { 1653 var _this5 = this; 1654 1655 return files.map(function (file) { 1656 return _this5.addFile(file); 1657 }); 1658 } 1659 1660 // When a folder is dropped (or files are pasted), items must be handled 1661 // instead of files. 1662 1663 }, { 1664 key: "_addFilesFromItems", 1665 value: function _addFilesFromItems(items) { 1666 var _this6 = this; 1667 1668 return function () { 1669 var result = []; 1670 for (var _iterator14 = items, _isArray14 = true, _i15 = 0, _iterator14 = _isArray14 ? _iterator14 : _iterator14[Symbol.iterator]();;) { 1671 var _ref13; 1672 1673 if (_isArray14) { 1674 if (_i15 >= _iterator14.length) break; 1675 _ref13 = _iterator14[_i15++]; 954 1676 } else { 955 results.push(void 0); 956 } 957 } else if (item.getAsFile != null) { 958 if ((item.kind == null) || item.kind === "file") { 959 results.push(this.addFile(item.getAsFile())); 1677 _i15 = _iterator14.next(); 1678 if (_i15.done) break; 1679 _ref13 = _i15.value; 1680 } 1681 1682 var item = _ref13; 1683 1684 var entry; 1685 if (item.webkitGetAsEntry != null && (entry = item.webkitGetAsEntry())) { 1686 if (entry.isFile) { 1687 result.push(_this6.addFile(item.getAsFile())); 1688 } else if (entry.isDirectory) { 1689 // Append all files from that directory to files 1690 result.push(_this6._addFilesFromDirectory(entry, entry.name)); 1691 } else { 1692 result.push(undefined); 1693 } 1694 } else if (item.getAsFile != null) { 1695 if (item.kind == null || item.kind === "file") { 1696 result.push(_this6.addFile(item.getAsFile())); 1697 } else { 1698 result.push(undefined); 1699 } 960 1700 } else { 961 results.push(void 0); 962 } 963 } else { 964 results.push(void 0); 965 } 966 } 967 return results; 968 }; 969 970 Dropzone.prototype._addFilesFromDirectory = function(directory, path) { 971 var dirReader, errorHandler, readEntries; 972 dirReader = directory.createReader(); 973 errorHandler = function(error) { 974 return typeof console !== "undefined" && console !== null ? typeof console.log === "function" ? console.log(error) : void 0 : void 0; 1701 result.push(undefined); 1702 } 1703 } 1704 return result; 1705 }(); 1706 } 1707 1708 // Goes through the directory, and adds each file it finds recursively 1709 1710 }, { 1711 key: "_addFilesFromDirectory", 1712 value: function _addFilesFromDirectory(directory, path) { 1713 var _this7 = this; 1714 1715 var dirReader = directory.createReader(); 1716 1717 var errorHandler = function errorHandler(error) { 1718 return __guardMethod__(console, 'log', function (o) { 1719 return o.log(error); 1720 }); 975 1721 }; 976 readEntries = (function(_this) { 977 return function() { 978 return dirReader.readEntries(function(entries) { 979 var entry, j, len; 980 if (entries.length > 0) { 981 for (j = 0, len = entries.length; j < len; j++) { 982 entry = entries[j]; 983 if (entry.isFile) { 984 entry.file(function(file) { 985 if (_this.options.ignoreHiddenFiles && file.name.substring(0, 1) === '.') { 986 return; 987 } 988 file.fullPath = path + "/" + file.name; 989 return _this.addFile(file); 990 }); 991 } else if (entry.isDirectory) { 992 _this._addFilesFromDirectory(entry, path + "/" + entry.name); 993 } 1722 1723 var readEntries = function readEntries() { 1724 return dirReader.readEntries(function (entries) { 1725 if (entries.length > 0) { 1726 for (var _iterator15 = entries, _isArray15 = true, _i16 = 0, _iterator15 = _isArray15 ? _iterator15 : _iterator15[Symbol.iterator]();;) { 1727 var _ref14; 1728 1729 if (_isArray15) { 1730 if (_i16 >= _iterator15.length) break; 1731 _ref14 = _iterator15[_i16++]; 1732 } else { 1733 _i16 = _iterator15.next(); 1734 if (_i16.done) break; 1735 _ref14 = _i16.value; 994 1736 } 995 readEntries(); 1737 1738 var entry = _ref14; 1739 1740 if (entry.isFile) { 1741 entry.file(function (file) { 1742 if (_this7.options.ignoreHiddenFiles && file.name.substring(0, 1) === '.') { 1743 return; 1744 } 1745 file.fullPath = path + "/" + file.name; 1746 return _this7.addFile(file); 1747 }); 1748 } else if (entry.isDirectory) { 1749 _this7._addFilesFromDirectory(entry, path + "/" + entry.name); 1750 } 996 1751 } 997 return null; 998 }, errorHandler); 999 }; 1000 })(this); 1752 1753 // Recursively call readEntries() again, since browser only handle 1754 // the first 100 entries. 1755 // See: https://developer.mozilla.org/en-US/docs/Web/API/DirectoryReader#readEntries 1756 readEntries(); 1757 } 1758 return null; 1759 }, errorHandler); 1760 }; 1761 1001 1762 return readEntries(); 1002 }; 1003 1004 Dropzone.prototype.accept = function(file, done) { 1763 } 1764 1765 // If `done()` is called without argument the file is accepted 1766 // If you call it with an error message, the file is rejected 1767 // (This allows for asynchronous validation) 1768 // 1769 // This function checks the filesize, and if the file.type passes the 1770 // `acceptedFiles` check. 1771 1772 }, { 1773 key: "accept", 1774 value: function accept(file, done) { 1005 1775 if (file.size > this.options.maxFilesize * 1024 * 1024) { 1006 1776 return done(this.options.dictFileTooBig.replace("{{filesize}}", Math.round(file.size / 1024 / 10.24) / 100).replace("{{maxFilesize}}", this.options.maxFilesize)); 1007 1777 } else if (!Dropzone.isValidFile(file, this.options.acceptedFiles)) { 1008 1778 return done(this.options.dictInvalidFileType); 1009 } else if ( (this.options.maxFiles != null)&& this.getAcceptedFiles().length >= this.options.maxFiles) {1779 } else if (this.options.maxFiles != null && this.getAcceptedFiles().length >= this.options.maxFiles) { 1010 1780 done(this.options.dictMaxFilesExceeded.replace("{{maxFiles}}", this.options.maxFiles)); 1011 1781 return this.emit("maxfilesexceeded", file); … … 1013 1783 return this.options.accept.call(this, file, done); 1014 1784 } 1015 }; 1016 1017 Dropzone.prototype.addFile = function(file) { 1785 } 1786 }, { 1787 key: "addFile", 1788 value: function addFile(file) { 1789 var _this8 = this; 1790 1018 1791 file.upload = { 1792 uuid: Dropzone.uuidv4(), 1019 1793 progress: 0, 1794 // Setting the total upload size to file.size for the beginning 1795 // It's actual different than the size to be transmitted. 1020 1796 total: file.size, 1021 1797 bytesSent: 0, 1022 filename: this._renameFile(file) 1798 filename: this._renameFile(file), 1799 chunked: this.options.chunking && (this.options.forceChunking || file.size > this.options.chunkSize), 1800 totalChunkCount: Math.ceil(file.size / this.options.chunkSize) 1023 1801 }; 1024 1802 this.files.push(file); 1803 1025 1804 file.status = Dropzone.ADDED; 1805 1026 1806 this.emit("addedfile", file); 1807 1027 1808 this._enqueueThumbnail(file); 1028 return this.accept(file, (function(_this) { 1029 return function(error) { 1030 if (error) { 1031 file.accepted = false; 1032 _this._errorProcessing([file], error); 1033 } else { 1034 file.accepted = true; 1035 if (_this.options.autoQueue) { 1036 _this.enqueueFile(file); 1037 } 1038 } 1039 return _this._updateMaxFilesReachedClass(); 1040 }; 1041 })(this)); 1042 }; 1043 1044 Dropzone.prototype.enqueueFiles = function(files) { 1045 var file, j, len; 1046 for (j = 0, len = files.length; j < len; j++) { 1047 file = files[j]; 1809 1810 return this.accept(file, function (error) { 1811 if (error) { 1812 file.accepted = false; 1813 _this8._errorProcessing([file], error); // Will set the file.status 1814 } else { 1815 file.accepted = true; 1816 if (_this8.options.autoQueue) { 1817 _this8.enqueueFile(file); 1818 } // Will set .accepted = true 1819 } 1820 return _this8._updateMaxFilesReachedClass(); 1821 }); 1822 } 1823 1824 // Wrapper for enqueueFile 1825 1826 }, { 1827 key: "enqueueFiles", 1828 value: function enqueueFiles(files) { 1829 for (var _iterator16 = files, _isArray16 = true, _i17 = 0, _iterator16 = _isArray16 ? _iterator16 : _iterator16[Symbol.iterator]();;) { 1830 var _ref15; 1831 1832 if (_isArray16) { 1833 if (_i17 >= _iterator16.length) break; 1834 _ref15 = _iterator16[_i17++]; 1835 } else { 1836 _i17 = _iterator16.next(); 1837 if (_i17.done) break; 1838 _ref15 = _i17.value; 1839 } 1840 1841 var file = _ref15; 1842 1048 1843 this.enqueueFile(file); 1049 1844 } 1050 1845 return null; 1051 }; 1052 1053 Dropzone.prototype.enqueueFile = function(file) { 1846 } 1847 }, { 1848 key: "enqueueFile", 1849 value: function enqueueFile(file) { 1850 var _this9 = this; 1851 1054 1852 if (file.status === Dropzone.ADDED && file.accepted === true) { 1055 1853 file.status = Dropzone.QUEUED; 1056 1854 if (this.options.autoProcessQueue) { 1057 return setTimeout(((function(_this) { 1058 return function() { 1059 return _this.processQueue(); 1060 }; 1061 })(this)), 0); 1855 return setTimeout(function () { 1856 return _this9.processQueue(); 1857 }, 0); // Deferring the call 1062 1858 } 1063 1859 } else { 1064 1860 throw new Error("This file can't be queued because it has already been processed or was rejected."); 1065 1861 } 1066 }; 1067 1068 Dropzone.prototype._thumbnailQueue = []; 1069 1070 Dropzone.prototype._processingThumbnail = false; 1071 1072 Dropzone.prototype._enqueueThumbnail = function(file) { 1862 } 1863 }, { 1864 key: "_enqueueThumbnail", 1865 value: function _enqueueThumbnail(file) { 1866 var _this10 = this; 1867 1073 1868 if (this.options.createImageThumbnails && file.type.match(/image.*/) && file.size <= this.options.maxThumbnailFilesize * 1024 * 1024) { 1074 1869 this._thumbnailQueue.push(file); 1075 return setTimeout( ((function(_this) {1076 return function() {1077 return _this._processThumbnailQueue();1078 };1079 })(this)), 0);1080 }1081 };1082 1083 Dropzone.prototype._processThumbnailQueue = function() {1084 var file; 1870 return setTimeout(function () { 1871 return _this10._processThumbnailQueue(); 1872 }, 0); // Deferring the call 1873 } 1874 } 1875 }, { 1876 key: "_processThumbnailQueue", 1877 value: function _processThumbnailQueue() { 1878 var _this11 = this; 1879 1085 1880 if (this._processingThumbnail || this._thumbnailQueue.length === 0) { 1086 1881 return; 1087 1882 } 1883 1088 1884 this._processingThumbnail = true; 1089 file = this._thumbnailQueue.shift(); 1090 return this.createThumbnail(file, this.options.thumbnailWidth, this.options.thumbnailHeight, this.options.thumbnailMethod, true, (function(_this) { 1091 return function(dataUrl) { 1092 _this.emit("thumbnail", file, dataUrl); 1093 _this._processingThumbnail = false; 1094 return _this._processThumbnailQueue(); 1095 }; 1096 })(this)); 1097 }; 1098 1099 Dropzone.prototype.removeFile = function(file) { 1885 var file = this._thumbnailQueue.shift(); 1886 return this.createThumbnail(file, this.options.thumbnailWidth, this.options.thumbnailHeight, this.options.thumbnailMethod, true, function (dataUrl) { 1887 _this11.emit("thumbnail", file, dataUrl); 1888 _this11._processingThumbnail = false; 1889 return _this11._processThumbnailQueue(); 1890 }); 1891 } 1892 1893 // Can be called by the user to remove a file 1894 1895 }, { 1896 key: "removeFile", 1897 value: function removeFile(file) { 1100 1898 if (file.status === Dropzone.UPLOADING) { 1101 1899 this.cancelUpload(file); 1102 1900 } 1103 1901 this.files = without(this.files, file); 1902 1104 1903 this.emit("removedfile", file); 1105 1904 if (this.files.length === 0) { 1106 1905 return this.emit("reset"); 1107 1906 } 1108 }; 1109 1110 Dropzone.prototype.removeAllFiles = function(cancelIfNecessary) { 1111 var file, j, len, ref; 1907 } 1908 1909 // Removes all files that aren't currently processed from the list 1910 1911 }, { 1912 key: "removeAllFiles", 1913 value: function removeAllFiles(cancelIfNecessary) { 1914 // Create a copy of files since removeFile() changes the @files array. 1112 1915 if (cancelIfNecessary == null) { 1113 1916 cancelIfNecessary = false; 1114 1917 } 1115 ref = this.files.slice(); 1116 for (j = 0, len = ref.length; j < len; j++) { 1117 file = ref[j]; 1918 for (var _iterator17 = this.files.slice(), _isArray17 = true, _i18 = 0, _iterator17 = _isArray17 ? _iterator17 : _iterator17[Symbol.iterator]();;) { 1919 var _ref16; 1920 1921 if (_isArray17) { 1922 if (_i18 >= _iterator17.length) break; 1923 _ref16 = _iterator17[_i18++]; 1924 } else { 1925 _i18 = _iterator17.next(); 1926 if (_i18.done) break; 1927 _ref16 = _i18.value; 1928 } 1929 1930 var file = _ref16; 1931 1118 1932 if (file.status !== Dropzone.UPLOADING || cancelIfNecessary) { 1119 1933 this.removeFile(file); … … 1121 1935 } 1122 1936 return null; 1123 }; 1124 1125 Dropzone.prototype.resizeImage = function(file, width, height, resizeMethod, callback) { 1126 return this.createThumbnail(file, width, height, resizeMethod, false, (function(_this) { 1127 return function(dataUrl, canvas) { 1128 var resizeMimeType, resizedDataURL; 1129 if (canvas === null) { 1130 return callback(file); 1131 } else { 1132 resizeMimeType = _this.options.resizeMimeType; 1133 if (resizeMimeType == null) { 1134 resizeMimeType = file.type; 1135 } 1136 resizedDataURL = canvas.toDataURL(resizeMimeType, _this.options.resizeQuality); 1137 if (resizeMimeType === 'image/jpeg' || resizeMimeType === 'image/jpg') { 1138 resizedDataURL = ExifRestore.restore(file.dataURL, resizedDataURL); 1139 } 1140 return callback(Dropzone.dataURItoBlob(resizedDataURL)); 1141 } 1142 }; 1143 })(this)); 1144 }; 1145 1146 Dropzone.prototype.createThumbnail = function(file, width, height, resizeMethod, fixOrientation, callback) { 1147 var fileReader; 1148 fileReader = new FileReader; 1149 fileReader.onload = (function(_this) { 1150 return function() { 1151 file.dataURL = fileReader.result; 1152 if (file.type === "image/svg+xml") { 1153 if (callback != null) { 1154 callback(fileReader.result); 1155 } 1156 return; 1157 } 1158 return _this.createThumbnailFromUrl(file, width, height, resizeMethod, fixOrientation, callback); 1159 }; 1160 })(this); 1937 } 1938 1939 // Resizes an image before it gets sent to the server. This function is the default behavior of 1940 // `options.transformFile` if `resizeWidth` or `resizeHeight` are set. The callback is invoked with 1941 // the resized blob. 1942 1943 }, { 1944 key: "resizeImage", 1945 value: function resizeImage(file, width, height, resizeMethod, callback) { 1946 var _this12 = this; 1947 1948 return this.createThumbnail(file, width, height, resizeMethod, false, function (dataUrl, canvas) { 1949 if (canvas === null) { 1950 // The image has not been resized 1951 return callback(file); 1952 } else { 1953 var resizeMimeType = _this12.options.resizeMimeType; 1954 1955 if (resizeMimeType == null) { 1956 resizeMimeType = file.type; 1957 } 1958 var resizedDataURL = canvas.toDataURL(resizeMimeType, _this12.options.resizeQuality); 1959 if (resizeMimeType === 'image/jpeg' || resizeMimeType === 'image/jpg') { 1960 // Now add the original EXIF information 1961 resizedDataURL = ExifRestore.restore(file.dataURL, resizedDataURL); 1962 } 1963 return callback(Dropzone.dataURItoBlob(resizedDataURL)); 1964 } 1965 }); 1966 } 1967 }, { 1968 key: "createThumbnail", 1969 value: function createThumbnail(file, width, height, resizeMethod, fixOrientation, callback) { 1970 var _this13 = this; 1971 1972 var fileReader = new FileReader(); 1973 1974 fileReader.onload = function () { 1975 1976 file.dataURL = fileReader.result; 1977 1978 // Don't bother creating a thumbnail for SVG images since they're vector 1979 if (file.type === "image/svg+xml") { 1980 if (callback != null) { 1981 callback(fileReader.result); 1982 } 1983 return; 1984 } 1985 1986 return _this13.createThumbnailFromUrl(file, width, height, resizeMethod, fixOrientation, callback); 1987 }; 1988 1161 1989 return fileReader.readAsDataURL(file); 1162 }; 1163 1164 Dropzone.prototype.createThumbnailFromUrl = function(file, width, height, resizeMethod, fixOrientation, callback, crossOrigin) { 1165 var img; 1166 img = document.createElement("img"); 1990 } 1991 }, { 1992 key: "createThumbnailFromUrl", 1993 value: function createThumbnailFromUrl(file, width, height, resizeMethod, fixOrientation, callback, crossOrigin) { 1994 var _this14 = this; 1995 1996 // Not using `new Image` here because of a bug in latest Chrome versions. 1997 // See https://github.com/enyo/dropzone/pull/226 1998 var img = document.createElement("img"); 1999 1167 2000 if (crossOrigin) { 1168 2001 img.crossOrigin = crossOrigin; 1169 2002 } 1170 img.onload = (function(_this) { 1171 return function() { 1172 var loadExif; 1173 loadExif = function(callback) { 1174 return callback(1); 2003 2004 img.onload = function () { 2005 var loadExif = function loadExif(callback) { 2006 return callback(1); 2007 }; 2008 if (typeof EXIF !== 'undefined' && EXIF !== null && fixOrientation) { 2009 loadExif = function loadExif(callback) { 2010 return EXIF.getData(img, function () { 2011 return callback(EXIF.getTag(this, 'Orientation')); 2012 }); 1175 2013 }; 1176 if ((typeof EXIF !== "undefined" && EXIF !== null) && fixOrientation) { 1177 loadExif = function(callback) { 1178 return EXIF.getData(img, function() { 1179 return callback(EXIF.getTag(this, 'Orientation')); 1180 }); 1181 }; 1182 } 1183 return loadExif(function(orientation) { 1184 var canvas, ctx, ref, ref1, ref2, ref3, resizeInfo, thumbnail; 1185 file.width = img.width; 1186 file.height = img.height; 1187 resizeInfo = _this.options.resize.call(_this, file, width, height, resizeMethod); 1188 canvas = document.createElement("canvas"); 1189 ctx = canvas.getContext("2d"); 1190 canvas.width = resizeInfo.trgWidth; 1191 canvas.height = resizeInfo.trgHeight; 1192 if (orientation > 4) { 1193 canvas.width = resizeInfo.trgHeight; 1194 canvas.height = resizeInfo.trgWidth; 1195 } 1196 switch (orientation) { 1197 case 2: 1198 ctx.translate(canvas.width, 0); 1199 ctx.scale(-1, 1); 1200 break; 1201 case 3: 1202 ctx.translate(canvas.width, canvas.height); 1203 ctx.rotate(Math.PI); 1204 break; 1205 case 4: 1206 ctx.translate(0, canvas.height); 1207 ctx.scale(1, -1); 1208 break; 1209 case 5: 1210 ctx.rotate(0.5 * Math.PI); 1211 ctx.scale(1, -1); 1212 break; 1213 case 6: 1214 ctx.rotate(0.5 * Math.PI); 1215 ctx.translate(0, -canvas.height); 1216 break; 1217 case 7: 1218 ctx.rotate(0.5 * Math.PI); 1219 ctx.translate(canvas.width, -canvas.height); 1220 ctx.scale(-1, 1); 1221 break; 1222 case 8: 1223 ctx.rotate(-0.5 * Math.PI); 1224 ctx.translate(-canvas.width, 0); 1225 } 1226 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); 1227 thumbnail = canvas.toDataURL("image/png"); 1228 if (callback != null) { 1229 return callback(thumbnail, canvas); 1230 } 1231 }); 1232 }; 1233 })(this); 2014 } 2015 2016 return loadExif(function (orientation) { 2017 file.width = img.width; 2018 file.height = img.height; 2019 2020 var resizeInfo = _this14.options.resize.call(_this14, file, width, height, resizeMethod); 2021 2022 var canvas = document.createElement("canvas"); 2023 var ctx = canvas.getContext("2d"); 2024 2025 canvas.width = resizeInfo.trgWidth; 2026 canvas.height = resizeInfo.trgHeight; 2027 2028 if (orientation > 4) { 2029 canvas.width = resizeInfo.trgHeight; 2030 canvas.height = resizeInfo.trgWidth; 2031 } 2032 2033 switch (orientation) { 2034 case 2: 2035 // horizontal flip 2036 ctx.translate(canvas.width, 0); 2037 ctx.scale(-1, 1); 2038 break; 2039 case 3: 2040 // 180° rotate left 2041 ctx.translate(canvas.width, canvas.height); 2042 ctx.rotate(Math.PI); 2043 break; 2044 case 4: 2045 // vertical flip 2046 ctx.translate(0, canvas.height); 2047 ctx.scale(1, -1); 2048 break; 2049 case 5: 2050 // vertical flip + 90 rotate right 2051 ctx.rotate(0.5 * Math.PI); 2052 ctx.scale(1, -1); 2053 break; 2054 case 6: 2055 // 90° rotate right 2056 ctx.rotate(0.5 * Math.PI); 2057 ctx.translate(0, -canvas.height); 2058 break; 2059 case 7: 2060 // horizontal flip + 90 rotate right 2061 ctx.rotate(0.5 * Math.PI); 2062 ctx.translate(canvas.width, -canvas.height); 2063 ctx.scale(-1, 1); 2064 break; 2065 case 8: 2066 // 90° rotate left 2067 ctx.rotate(-0.5 * Math.PI); 2068 ctx.translate(-canvas.width, 0); 2069 break; 2070 } 2071 2072 // This is a bugfix for iOS' scaling bug. 2073 drawImageIOSFix(ctx, img, resizeInfo.srcX != null ? resizeInfo.srcX : 0, resizeInfo.srcY != null ? resizeInfo.srcY : 0, resizeInfo.srcWidth, resizeInfo.srcHeight, resizeInfo.trgX != null ? resizeInfo.trgX : 0, resizeInfo.trgY != null ? resizeInfo.trgY : 0, resizeInfo.trgWidth, resizeInfo.trgHeight); 2074 2075 var thumbnail = canvas.toDataURL("image/png"); 2076 2077 if (callback != null) { 2078 return callback(thumbnail, canvas); 2079 } 2080 }); 2081 }; 2082 1234 2083 if (callback != null) { 1235 2084 img.onerror = callback; 1236 2085 } 2086 1237 2087 return img.src = file.dataURL; 1238 }; 1239 1240 Dropzone.prototype.processQueue = function() { 1241 var i, parallelUploads, processingLength, queuedFiles; 1242 parallelUploads = this.options.parallelUploads; 1243 processingLength = this.getUploadingFiles().length; 1244 i = processingLength; 2088 } 2089 2090 // Goes through the queue and processes files if there aren't too many already. 2091 2092 }, { 2093 key: "processQueue", 2094 value: function processQueue() { 2095 var parallelUploads = this.options.parallelUploads; 2096 2097 var processingLength = this.getUploadingFiles().length; 2098 var i = processingLength; 2099 2100 // There are already at least as many files uploading than should be 1245 2101 if (processingLength >= parallelUploads) { 1246 2102 return; 1247 2103 } 1248 queuedFiles = this.getQueuedFiles(); 2104 2105 var queuedFiles = this.getQueuedFiles(); 2106 1249 2107 if (!(queuedFiles.length > 0)) { 1250 2108 return; 1251 2109 } 2110 1252 2111 if (this.options.uploadMultiple) { 2112 // The files should be uploaded in one request 1253 2113 return this.processFiles(queuedFiles.slice(0, parallelUploads - processingLength)); 1254 2114 } else { … … 1256 2116 if (!queuedFiles.length) { 1257 2117 return; 1258 } 2118 } // Nothing left to process 1259 2119 this.processFile(queuedFiles.shift()); 1260 2120 i++; 1261 2121 } 1262 2122 } 1263 }; 1264 1265 Dropzone.prototype.processFile = function(file) { 2123 } 2124 2125 // Wrapper for `processFiles` 2126 2127 }, { 2128 key: "processFile", 2129 value: function processFile(file) { 1266 2130 return this.processFiles([file]); 1267 }; 1268 1269 Dropzone.prototype.processFiles = function(files) { 1270 var file, j, len; 1271 for (j = 0, len = files.length; j < len; j++) { 1272 file = files[j]; 1273 file.processing = true; 2131 } 2132 2133 // Loads the file, then calls finishedLoading() 2134 2135 }, { 2136 key: "processFiles", 2137 value: function processFiles(files) { 2138 for (var _iterator18 = files, _isArray18 = true, _i19 = 0, _iterator18 = _isArray18 ? _iterator18 : _iterator18[Symbol.iterator]();;) { 2139 var _ref17; 2140 2141 if (_isArray18) { 2142 if (_i19 >= _iterator18.length) break; 2143 _ref17 = _iterator18[_i19++]; 2144 } else { 2145 _i19 = _iterator18.next(); 2146 if (_i19.done) break; 2147 _ref17 = _i19.value; 2148 } 2149 2150 var file = _ref17; 2151 2152 file.processing = true; // Backwards compatibility 1274 2153 file.status = Dropzone.UPLOADING; 2154 1275 2155 this.emit("processing", file); 1276 2156 } 2157 1277 2158 if (this.options.uploadMultiple) { 1278 2159 this.emit("processingmultiple", files); 1279 2160 } 2161 1280 2162 return this.uploadFiles(files); 1281 } ;1282 1283 Dropzone.prototype._getFilesWithXhr = function(xhr) {1284 var file, files;1285 return files = (function() {1286 var j, len, ref, results;1287 re f = this.files;1288 results = [];1289 for (j = 0, len = ref.length; j < len; j++) {1290 file = ref[j];1291 if (file.xhr === xhr) {1292 results.push(file); 1293 }1294 }1295 return results;1296 }).call(this);1297 }; 1298 1299 Dropzone.prototype.cancelUpload = function(file) {1300 var groupedFile, groupedFiles, j, k, len, len1, ref;2163 } 2164 }, { 2165 key: "_getFilesWithXhr", 2166 value: function _getFilesWithXhr(xhr) { 2167 var files = void 0; 2168 return files = this.files.filter(function (file) { 2169 return file.xhr === xhr; 2170 }).map(function (file) { 2171 return file; 2172 }); 2173 } 2174 2175 // Cancels the file upload and sets the status to CANCELED 2176 // **if** the file is actually being uploaded. 2177 // If it's still in the queue, the file is being removed from it and the status 2178 // set to CANCELED. 2179 2180 }, { 2181 key: "cancelUpload", 2182 value: function cancelUpload(file) { 1301 2183 if (file.status === Dropzone.UPLOADING) { 1302 groupedFiles = this._getFilesWithXhr(file.xhr); 1303 for (j = 0, len = groupedFiles.length; j < len; j++) { 1304 groupedFile = groupedFiles[j]; 2184 var groupedFiles = this._getFilesWithXhr(file.xhr); 2185 for (var _iterator19 = groupedFiles, _isArray19 = true, _i20 = 0, _iterator19 = _isArray19 ? _iterator19 : _iterator19[Symbol.iterator]();;) { 2186 var _ref18; 2187 2188 if (_isArray19) { 2189 if (_i20 >= _iterator19.length) break; 2190 _ref18 = _iterator19[_i20++]; 2191 } else { 2192 _i20 = _iterator19.next(); 2193 if (_i20.done) break; 2194 _ref18 = _i20.value; 2195 } 2196 2197 var groupedFile = _ref18; 2198 1305 2199 groupedFile.status = Dropzone.CANCELED; 1306 2200 } 1307 file.xhr.abort(); 1308 for (k = 0, len1 = groupedFiles.length; k < len1; k++) { 1309 groupedFile = groupedFiles[k]; 1310 this.emit("canceled", groupedFile); 2201 if (typeof file.xhr !== 'undefined') { 2202 file.xhr.abort(); 2203 } 2204 for (var _iterator20 = groupedFiles, _isArray20 = true, _i21 = 0, _iterator20 = _isArray20 ? _iterator20 : _iterator20[Symbol.iterator]();;) { 2205 var _ref19; 2206 2207 if (_isArray20) { 2208 if (_i21 >= _iterator20.length) break; 2209 _ref19 = _iterator20[_i21++]; 2210 } else { 2211 _i21 = _iterator20.next(); 2212 if (_i21.done) break; 2213 _ref19 = _i21.value; 2214 } 2215 2216 var _groupedFile = _ref19; 2217 2218 this.emit("canceled", _groupedFile); 1311 2219 } 1312 2220 if (this.options.uploadMultiple) { 1313 2221 this.emit("canceledmultiple", groupedFiles); 1314 2222 } 1315 } else if ( (ref = file.status) === Dropzone.ADDED || ref=== Dropzone.QUEUED) {2223 } else if (file.status === Dropzone.ADDED || file.status === Dropzone.QUEUED) { 1316 2224 file.status = Dropzone.CANCELED; 1317 2225 this.emit("canceled", file); … … 1320 2228 } 1321 2229 } 2230 1322 2231 if (this.options.autoProcessQueue) { 1323 2232 return this.processQueue(); 1324 2233 } 1325 }; 1326 1327 resolveOption = function() { 1328 var args, option; 1329 option = arguments[0], args = 2 <= arguments.length ? slice.call(arguments, 1) : []; 2234 } 2235 }, { 2236 key: "resolveOption", 2237 value: function resolveOption(option) { 1330 2238 if (typeof option === 'function') { 2239 for (var _len3 = arguments.length, args = Array(_len3 > 1 ? _len3 - 1 : 0), _key3 = 1; _key3 < _len3; _key3++) { 2240 args[_key3 - 1] = arguments[_key3]; 2241 } 2242 1331 2243 return option.apply(this, args); 1332 2244 } 1333 2245 return option; 1334 }; 1335 1336 Dropzone.prototype.uploadFile = function(file) { 2246 } 2247 }, { 2248 key: "uploadFile", 2249 value: function uploadFile(file) { 1337 2250 return this.uploadFiles([file]); 1338 }; 1339 1340 Dropzone.prototype.uploadFiles = function(files) { 1341 var doneCounter, doneFunction, file, formData, handleError, headerName, headerValue, headers, i, input, inputName, inputType, j, k, key, l, len, len1, len2, len3, m, method, o, option, progressObj, ref, ref1, ref2, ref3, ref4, ref5, response, results, updateProgress, url, value, xhr; 1342 xhr = new XMLHttpRequest(); 1343 for (j = 0, len = files.length; j < len; j++) { 1344 file = files[j]; 1345 file.xhr = xhr; 1346 } 1347 method = resolveOption(this.options.method, files); 1348 url = resolveOption(this.options.url, files); 1349 xhr.open(method, url, true); 1350 xhr.timeout = resolveOption(this.options.timeout, files); 1351 xhr.withCredentials = !!this.options.withCredentials; 1352 response = null; 1353 handleError = (function(_this) { 1354 return function() { 1355 var k, len1, results; 1356 results = []; 1357 for (k = 0, len1 = files.length; k < len1; k++) { 1358 file = files[k]; 1359 results.push(_this._errorProcessing(files, response || _this.options.dictResponseError.replace("{{statusCode}}", xhr.status), xhr)); 1360 } 1361 return results; 1362 }; 1363 })(this); 1364 updateProgress = (function(_this) { 1365 return function(e) { 1366 var allFilesFinished, k, l, len1, len2, len3, m, progress, results; 1367 if (e != null) { 1368 progress = 100 * e.loaded / e.total; 1369 for (k = 0, len1 = files.length; k < len1; k++) { 1370 file = files[k]; 1371 file.upload.progress = progress; 1372 file.upload.total = e.total; 1373 file.upload.bytesSent = e.loaded; 2251 } 2252 }, { 2253 key: "uploadFiles", 2254 value: function uploadFiles(files) { 2255 var _this15 = this; 2256 2257 this._transformFiles(files, function (transformedFiles) { 2258 if (files[0].upload.chunked) { 2259 // This file should be sent in chunks! 2260 2261 // If the chunking option is set, we **know** that there can only be **one** file, since 2262 // uploadMultiple is not allowed with this option. 2263 var file = files[0]; 2264 var transformedFile = transformedFiles[0]; 2265 var startedChunkCount = 0; 2266 2267 file.upload.chunks = []; 2268 2269 var handleNextChunk = function handleNextChunk() { 2270 var chunkIndex = 0; 2271 2272 // Find the next item in file.upload.chunks that is not defined yet. 2273 while (file.upload.chunks[chunkIndex] !== undefined) { 2274 chunkIndex++; 2275 } 2276 2277 // This means, that all chunks have already been started. 2278 if (chunkIndex >= file.upload.totalChunkCount) return; 2279 2280 startedChunkCount++; 2281 2282 var start = chunkIndex * _this15.options.chunkSize; 2283 var end = Math.min(start + _this15.options.chunkSize, file.size); 2284 2285 var dataBlock = { 2286 name: _this15._getParamName(0), 2287 data: transformedFile.webkitSlice ? transformedFile.webkitSlice(start, end) : transformedFile.slice(start, end), 2288 filename: file.upload.filename, 2289 chunkIndex: chunkIndex 2290 }; 2291 2292 file.upload.chunks[chunkIndex] = { 2293 file: file, 2294 index: chunkIndex, 2295 dataBlock: dataBlock, // In case we want to retry. 2296 status: Dropzone.UPLOADING, 2297 progress: 0, 2298 retries: 0 // The number of times this block has been retried. 2299 }; 2300 2301 _this15._uploadData(files, [dataBlock]); 2302 }; 2303 2304 file.upload.finishedChunkUpload = function (chunk) { 2305 var allFinished = true; 2306 chunk.status = Dropzone.SUCCESS; 2307 2308 // Clear the data from the chunk 2309 chunk.dataBlock = null; 2310 2311 for (var i = 0; i < file.upload.totalChunkCount; i++) { 2312 if (file.upload.chunks[i] === undefined) { 2313 return handleNextChunk(); 2314 } 2315 if (file.upload.chunks[i].status !== Dropzone.SUCCESS) { 2316 allFinished = false; 2317 } 2318 } 2319 2320 if (allFinished) { 2321 _this15.options.chunksUploaded(file, function () { 2322 _this15._finished(files, '', null); 2323 }); 2324 } 2325 }; 2326 2327 if (_this15.options.parallelChunkUploads) { 2328 for (var i = 0; i < file.upload.totalChunkCount; i++) { 2329 handleNextChunk(); 1374 2330 } 1375 2331 } else { 1376 allFilesFinished = true; 1377 progress = 100; 1378 for (l = 0, len2 = files.length; l < len2; l++) { 1379 file = files[l]; 1380 if (!(file.upload.progress === 100 && file.upload.bytesSent === file.upload.total)) { 1381 allFilesFinished = false; 1382 } 1383 file.upload.progress = progress; 1384 file.upload.bytesSent = file.upload.total; 1385 } 1386 if (allFilesFinished) { 1387 return; 1388 } 1389 } 1390 results = []; 1391 for (m = 0, len3 = files.length; m < len3; m++) { 1392 file = files[m]; 1393 results.push(_this.emit("uploadprogress", file, progress, file.upload.bytesSent)); 1394 } 1395 return results; 1396 }; 1397 })(this); 1398 xhr.onload = (function(_this) { 1399 return function(e) { 1400 var error1, ref; 1401 if (files[0].status === Dropzone.CANCELED) { 1402 return; 1403 } 1404 if (xhr.readyState !== 4) { 1405 return; 1406 } 1407 if (xhr.responseType !== 'arraybuffer' && xhr.responseType !== 'blob') { 1408 response = xhr.responseText; 1409 if (xhr.getResponseHeader("content-type") && ~xhr.getResponseHeader("content-type").indexOf("application/json")) { 1410 try { 1411 response = JSON.parse(response); 1412 } catch (error1) { 1413 e = error1; 1414 response = "Invalid JSON response from server."; 1415 } 1416 } 1417 } 1418 updateProgress(); 1419 if (!((200 <= (ref = xhr.status) && ref < 300))) { 1420 return handleError(); 1421 } else { 1422 return _this._finished(files, response, e); 1423 } 1424 }; 1425 })(this); 1426 xhr.onerror = (function(_this) { 1427 return function() { 1428 if (files[0].status === Dropzone.CANCELED) { 1429 return; 1430 } 1431 return handleError(); 1432 }; 1433 })(this); 1434 progressObj = (ref = xhr.upload) != null ? ref : xhr; 1435 progressObj.onprogress = updateProgress; 1436 headers = { 2332 handleNextChunk(); 2333 } 2334 } else { 2335 var dataBlocks = []; 2336 for (var _i22 = 0; _i22 < files.length; _i22++) { 2337 dataBlocks[_i22] = { 2338 name: _this15._getParamName(_i22), 2339 data: transformedFiles[_i22], 2340 filename: files[_i22].upload.filename 2341 }; 2342 } 2343 _this15._uploadData(files, dataBlocks); 2344 } 2345 }); 2346 } 2347 2348 /// Returns the right chunk for given file and xhr 2349 2350 }, { 2351 key: "_getChunk", 2352 value: function _getChunk(file, xhr) { 2353 for (var i = 0; i < file.upload.totalChunkCount; i++) { 2354 if (file.upload.chunks[i] !== undefined && file.upload.chunks[i].xhr === xhr) { 2355 return file.upload.chunks[i]; 2356 } 2357 } 2358 } 2359 2360 // This function actually uploads the file(s) to the server. 2361 // If dataBlocks contains the actual data to upload (meaning, that this could either be transformed 2362 // files, or individual chunks for chunked upload). 2363 2364 }, { 2365 key: "_uploadData", 2366 value: function _uploadData(files, dataBlocks) { 2367 var _this16 = this; 2368 2369 var xhr = new XMLHttpRequest(); 2370 2371 // Put the xhr object in the file objects to be able to reference it later. 2372 for (var _iterator21 = files, _isArray21 = true, _i23 = 0, _iterator21 = _isArray21 ? _iterator21 : _iterator21[Symbol.iterator]();;) { 2373 var _ref20; 2374 2375 if (_isArray21) { 2376 if (_i23 >= _iterator21.length) break; 2377 _ref20 = _iterator21[_i23++]; 2378 } else { 2379 _i23 = _iterator21.next(); 2380 if (_i23.done) break; 2381 _ref20 = _i23.value; 2382 } 2383 2384 var file = _ref20; 2385 2386 file.xhr = xhr; 2387 } 2388 if (files[0].upload.chunked) { 2389 // Put the xhr object in the right chunk object, so it can be associated later, and found with _getChunk 2390 files[0].upload.chunks[dataBlocks[0].chunkIndex].xhr = xhr; 2391 } 2392 2393 var method = this.resolveOption(this.options.method, files); 2394 var url = this.resolveOption(this.options.url, files); 2395 xhr.open(method, url, true); 2396 2397 // Setting the timeout after open because of IE11 issue: https://gitlab.com/meno/dropzone/issues/8 2398 xhr.timeout = this.resolveOption(this.options.timeout, files); 2399 2400 // Has to be after `.open()`. See https://github.com/enyo/dropzone/issues/179 2401 xhr.withCredentials = !!this.options.withCredentials; 2402 2403 xhr.onload = function (e) { 2404 _this16._finishedUploading(files, xhr, e); 2405 }; 2406 2407 xhr.onerror = function () { 2408 _this16._handleUploadError(files, xhr); 2409 }; 2410 2411 // Some browsers do not have the .upload property 2412 var progressObj = xhr.upload != null ? xhr.upload : xhr; 2413 progressObj.onprogress = function (e) { 2414 return _this16._updateFilesUploadProgress(files, xhr, e); 2415 }; 2416 2417 var headers = { 1437 2418 "Accept": "application/json", 1438 2419 "Cache-Control": "no-cache", 1439 2420 "X-Requested-With": "XMLHttpRequest" 1440 2421 }; 2422 1441 2423 if (this.options.headers) { 1442 extend(headers, this.options.headers); 1443 } 1444 for (headerName in headers) { 1445 headerValue = headers[headerName]; 2424 Dropzone.extend(headers, this.options.headers); 2425 } 2426 2427 for (var headerName in headers) { 2428 var headerValue = headers[headerName]; 1446 2429 if (headerValue) { 1447 2430 xhr.setRequestHeader(headerName, headerValue); 1448 2431 } 1449 2432 } 1450 formData = new FormData(); 2433 2434 var formData = new FormData(); 2435 2436 // Adding all @options parameters 1451 2437 if (this.options.params) { 1452 ref1 = this.options.params; 1453 for (key in ref1) { 1454 value = ref1[key]; 2438 var additionalParams = this.options.params; 2439 if (typeof additionalParams === 'function') { 2440 additionalParams = additionalParams.call(this, files, xhr, files[0].upload.chunked ? this._getChunk(files[0], xhr) : null); 2441 } 2442 2443 for (var key in additionalParams) { 2444 var value = additionalParams[key]; 1455 2445 formData.append(key, value); 1456 2446 } 1457 2447 } 1458 for (k = 0, len1 = files.length; k < len1; k++) { 1459 file = files[k]; 1460 this.emit("sending", file, xhr, formData); 2448 2449 // Let the user add additional data if necessary 2450 for (var _iterator22 = files, _isArray22 = true, _i24 = 0, _iterator22 = _isArray22 ? _iterator22 : _iterator22[Symbol.iterator]();;) { 2451 var _ref21; 2452 2453 if (_isArray22) { 2454 if (_i24 >= _iterator22.length) break; 2455 _ref21 = _iterator22[_i24++]; 2456 } else { 2457 _i24 = _iterator22.next(); 2458 if (_i24.done) break; 2459 _ref21 = _i24.value; 2460 } 2461 2462 var _file = _ref21; 2463 2464 this.emit("sending", _file, xhr, formData); 1461 2465 } 1462 2466 if (this.options.uploadMultiple) { 1463 2467 this.emit("sendingmultiple", files, xhr, formData); 1464 2468 } 2469 2470 this._addFormElementData(formData); 2471 2472 // Finally add the files 2473 // Has to be last because some servers (eg: S3) expect the file to be the last parameter 2474 for (var i = 0; i < dataBlocks.length; i++) { 2475 var dataBlock = dataBlocks[i]; 2476 formData.append(dataBlock.name, dataBlock.data, dataBlock.filename); 2477 } 2478 2479 this.submitRequest(xhr, formData, files); 2480 } 2481 2482 // Transforms all files with this.options.transformFile and invokes done with the transformed files when done. 2483 2484 }, { 2485 key: "_transformFiles", 2486 value: function _transformFiles(files, done) { 2487 var _this17 = this; 2488 2489 var transformedFiles = []; 2490 // Clumsy way of handling asynchronous calls, until I get to add a proper Future library. 2491 var doneCounter = 0; 2492 2493 var _loop = function _loop(i) { 2494 _this17.options.transformFile.call(_this17, files[i], function (transformedFile) { 2495 transformedFiles[i] = transformedFile; 2496 if (++doneCounter === files.length) { 2497 done(transformedFiles); 2498 } 2499 }); 2500 }; 2501 2502 for (var i = 0; i < files.length; i++) { 2503 _loop(i); 2504 } 2505 } 2506 2507 // Takes care of adding other input elements of the form to the AJAX request 2508 2509 }, { 2510 key: "_addFormElementData", 2511 value: function _addFormElementData(formData) { 2512 // Take care of other input elements 1465 2513 if (this.element.tagName === "FORM") { 1466 ref2 = this.element.querySelectorAll("input, textarea, select, button"); 1467 for (l = 0, len2 = ref2.length; l < len2; l++) { 1468 input = ref2[l]; 1469 inputName = input.getAttribute("name"); 1470 inputType = input.getAttribute("type"); 2514 for (var _iterator23 = this.element.querySelectorAll("input, textarea, select, button"), _isArray23 = true, _i25 = 0, _iterator23 = _isArray23 ? _iterator23 : _iterator23[Symbol.iterator]();;) { 2515 var _ref22; 2516 2517 if (_isArray23) { 2518 if (_i25 >= _iterator23.length) break; 2519 _ref22 = _iterator23[_i25++]; 2520 } else { 2521 _i25 = _iterator23.next(); 2522 if (_i25.done) break; 2523 _ref22 = _i25.value; 2524 } 2525 2526 var input = _ref22; 2527 2528 var inputName = input.getAttribute("name"); 2529 var inputType = input.getAttribute("type"); 2530 if (inputType) inputType = inputType.toLowerCase(); 2531 2532 // If the input doesn't have a name, we can't use it. 2533 if (typeof inputName === 'undefined' || inputName === null) continue; 2534 1471 2535 if (input.tagName === "SELECT" && input.hasAttribute("multiple")) { 1472 ref3 = input.options; 1473 for (m = 0, len3 = ref3.length; m < len3; m++) { 1474 option = ref3[m]; 2536 // Possibly multiple values 2537 for (var _iterator24 = input.options, _isArray24 = true, _i26 = 0, _iterator24 = _isArray24 ? _iterator24 : _iterator24[Symbol.iterator]();;) { 2538 var _ref23; 2539 2540 if (_isArray24) { 2541 if (_i26 >= _iterator24.length) break; 2542 _ref23 = _iterator24[_i26++]; 2543 } else { 2544 _i26 = _iterator24.next(); 2545 if (_i26.done) break; 2546 _ref23 = _i26.value; 2547 } 2548 2549 var option = _ref23; 2550 1475 2551 if (option.selected) { 1476 2552 formData.append(inputName, option.value); 1477 2553 } 1478 2554 } 1479 } else if (!inputType || ((ref4 = inputType.toLowerCase()) !== "checkbox" && ref4 !== "radio")|| input.checked) {2555 } else if (!inputType || inputType !== "checkbox" && inputType !== "radio" || input.checked) { 1480 2556 formData.append(inputName, input.value); 1481 2557 } 1482 2558 } 1483 2559 } 1484 doneCounter = 0; 1485 results = []; 1486 for (i = o = 0, ref5 = files.length - 1; 0 <= ref5 ? o <= ref5 : o >= ref5; i = 0 <= ref5 ? ++o : --o) { 1487 doneFunction = (function(_this) { 1488 return function(file, paramName, fileName) { 1489 return function(transformedFile) { 1490 formData.append(paramName, transformedFile, fileName); 1491 if (++doneCounter === files.length) { 1492 return _this.submitRequest(xhr, formData, files); 1493 } 1494 }; 1495 }; 1496 })(this); 1497 results.push(this.options.transformFile.call(this, files[i], doneFunction(files[i], this._getParamName(i), files[i].upload.filename))); 1498 } 1499 return results; 1500 }; 1501 1502 Dropzone.prototype.submitRequest = function(xhr, formData, files) { 1503 return xhr.send(formData); 1504 }; 1505 1506 Dropzone.prototype._finished = function(files, responseText, e) { 1507 var file, j, len; 1508 for (j = 0, len = files.length; j < len; j++) { 1509 file = files[j]; 2560 } 2561 2562 // Invoked when there is new progress information about given files. 2563 // If e is not provided, it is assumed that the upload is finished. 2564 2565 }, { 2566 key: "_updateFilesUploadProgress", 2567 value: function _updateFilesUploadProgress(files, xhr, e) { 2568 var progress = void 0; 2569 if (typeof e !== 'undefined') { 2570 progress = 100 * e.loaded / e.total; 2571 2572 if (files[0].upload.chunked) { 2573 var file = files[0]; 2574 // Since this is a chunked upload, we need to update the appropriate chunk progress. 2575 var chunk = this._getChunk(file, xhr); 2576 chunk.progress = progress; 2577 chunk.total = e.total; 2578 chunk.bytesSent = e.loaded; 2579 var fileProgress = 0, 2580 fileTotal = void 0, 2581 fileBytesSent = void 0; 2582 file.upload.progress = 0; 2583 file.upload.total = 0; 2584 file.upload.bytesSent = 0; 2585 for (var i = 0; i < file.upload.totalChunkCount; i++) { 2586 if (file.upload.chunks[i] !== undefined && file.upload.chunks[i].progress !== undefined) { 2587 file.upload.progress += file.upload.chunks[i].progress; 2588 file.upload.total += file.upload.chunks[i].total; 2589 file.upload.bytesSent += file.upload.chunks[i].bytesSent; 2590 } 2591 } 2592 file.upload.progress = file.upload.progress / file.upload.totalChunkCount; 2593 } else { 2594 for (var _iterator25 = files, _isArray25 = true, _i27 = 0, _iterator25 = _isArray25 ? _iterator25 : _iterator25[Symbol.iterator]();;) { 2595 var _ref24; 2596 2597 if (_isArray25) { 2598 if (_i27 >= _iterator25.length) break; 2599 _ref24 = _iterator25[_i27++]; 2600 } else { 2601 _i27 = _iterator25.next(); 2602 if (_i27.done) break; 2603 _ref24 = _i27.value; 2604 } 2605 2606 var _file2 = _ref24; 2607 2608 _file2.upload.progress = progress; 2609 _file2.upload.total = e.total; 2610 _file2.upload.bytesSent = e.loaded; 2611 } 2612 } 2613 for (var _iterator26 = files, _isArray26 = true, _i28 = 0, _iterator26 = _isArray26 ? _iterator26 : _iterator26[Symbol.iterator]();;) { 2614 var _ref25; 2615 2616 if (_isArray26) { 2617 if (_i28 >= _iterator26.length) break; 2618 _ref25 = _iterator26[_i28++]; 2619 } else { 2620 _i28 = _iterator26.next(); 2621 if (_i28.done) break; 2622 _ref25 = _i28.value; 2623 } 2624 2625 var _file3 = _ref25; 2626 2627 this.emit("uploadprogress", _file3, _file3.upload.progress, _file3.upload.bytesSent); 2628 } 2629 } else { 2630 // Called when the file finished uploading 2631 2632 var allFilesFinished = true; 2633 2634 progress = 100; 2635 2636 for (var _iterator27 = files, _isArray27 = true, _i29 = 0, _iterator27 = _isArray27 ? _iterator27 : _iterator27[Symbol.iterator]();;) { 2637 var _ref26; 2638 2639 if (_isArray27) { 2640 if (_i29 >= _iterator27.length) break; 2641 _ref26 = _iterator27[_i29++]; 2642 } else { 2643 _i29 = _iterator27.next(); 2644 if (_i29.done) break; 2645 _ref26 = _i29.value; 2646 } 2647 2648 var _file4 = _ref26; 2649 2650 if (_file4.upload.progress !== 100 || _file4.upload.bytesSent !== _file4.upload.total) { 2651 allFilesFinished = false; 2652 } 2653 _file4.upload.progress = progress; 2654 _file4.upload.bytesSent = _file4.upload.total; 2655 } 2656 2657 // Nothing to do, all files already at 100% 2658 if (allFilesFinished) { 2659 return; 2660 } 2661 2662 for (var _iterator28 = files, _isArray28 = true, _i30 = 0, _iterator28 = _isArray28 ? _iterator28 : _iterator28[Symbol.iterator]();;) { 2663 var _ref27; 2664 2665 if (_isArray28) { 2666 if (_i30 >= _iterator28.length) break; 2667 _ref27 = _iterator28[_i30++]; 2668 } else { 2669 _i30 = _iterator28.next(); 2670 if (_i30.done) break; 2671 _ref27 = _i30.value; 2672 } 2673 2674 var _file5 = _ref27; 2675 2676 this.emit("uploadprogress", _file5, progress, _file5.upload.bytesSent); 2677 } 2678 } 2679 } 2680 }, { 2681 key: "_finishedUploading", 2682 value: function _finishedUploading(files, xhr, e) { 2683 var response = void 0; 2684 2685 if (files[0].status === Dropzone.CANCELED) { 2686 return; 2687 } 2688 2689 if (xhr.readyState !== 4) { 2690 return; 2691 } 2692 2693 if (xhr.responseType !== 'arraybuffer' && xhr.responseType !== 'blob') { 2694 response = xhr.responseText; 2695 2696 if (xhr.getResponseHeader("content-type") && ~xhr.getResponseHeader("content-type").indexOf("application/json")) { 2697 try { 2698 response = JSON.parse(response); 2699 } catch (error) { 2700 e = error; 2701 response = "Invalid JSON response from server."; 2702 } 2703 } 2704 } 2705 2706 this._updateFilesUploadProgress(files); 2707 2708 if (!(200 <= xhr.status && xhr.status < 300)) { 2709 this._handleUploadError(files, xhr, response); 2710 } else { 2711 if (files[0].upload.chunked) { 2712 files[0].upload.finishedChunkUpload(this._getChunk(files[0], xhr)); 2713 } else { 2714 this._finished(files, response, e); 2715 } 2716 } 2717 } 2718 }, { 2719 key: "_handleUploadError", 2720 value: function _handleUploadError(files, xhr, response) { 2721 if (files[0].status === Dropzone.CANCELED) { 2722 return; 2723 } 2724 2725 if (files[0].upload.chunked && this.options.retryChunks) { 2726 var chunk = this._getChunk(files[0], xhr); 2727 if (chunk.retries++ < this.options.retryChunksLimit) { 2728 this._uploadData(files, [chunk.dataBlock]); 2729 return; 2730 } else { 2731 console.warn('Retried this chunk too often. Giving up.'); 2732 } 2733 } 2734 2735 for (var _iterator29 = files, _isArray29 = true, _i31 = 0, _iterator29 = _isArray29 ? _iterator29 : _iterator29[Symbol.iterator]();;) { 2736 var _ref28; 2737 2738 if (_isArray29) { 2739 if (_i31 >= _iterator29.length) break; 2740 _ref28 = _iterator29[_i31++]; 2741 } else { 2742 _i31 = _iterator29.next(); 2743 if (_i31.done) break; 2744 _ref28 = _i31.value; 2745 } 2746 2747 var file = _ref28; 2748 2749 this._errorProcessing(files, response || this.options.dictResponseError.replace("{{statusCode}}", xhr.status), xhr); 2750 } 2751 } 2752 }, { 2753 key: "submitRequest", 2754 value: function submitRequest(xhr, formData, files) { 2755 xhr.send(formData); 2756 } 2757 2758 // Called internally when processing is finished. 2759 // Individual callbacks have to be called in the appropriate sections. 2760 2761 }, { 2762 key: "_finished", 2763 value: function _finished(files, responseText, e) { 2764 for (var _iterator30 = files, _isArray30 = true, _i32 = 0, _iterator30 = _isArray30 ? _iterator30 : _iterator30[Symbol.iterator]();;) { 2765 var _ref29; 2766 2767 if (_isArray30) { 2768 if (_i32 >= _iterator30.length) break; 2769 _ref29 = _iterator30[_i32++]; 2770 } else { 2771 _i32 = _iterator30.next(); 2772 if (_i32.done) break; 2773 _ref29 = _i32.value; 2774 } 2775 2776 var file = _ref29; 2777 1510 2778 file.status = Dropzone.SUCCESS; 1511 2779 this.emit("success", file, responseText, e); … … 1516 2784 this.emit("completemultiple", files); 1517 2785 } 2786 1518 2787 if (this.options.autoProcessQueue) { 1519 2788 return this.processQueue(); 1520 2789 } 1521 }; 1522 1523 Dropzone.prototype._errorProcessing = function(files, message, xhr) { 1524 var file, j, len; 1525 for (j = 0, len = files.length; j < len; j++) { 1526 file = files[j]; 2790 } 2791 2792 // Called internally when processing is finished. 2793 // Individual callbacks have to be called in the appropriate sections. 2794 2795 }, { 2796 key: "_errorProcessing", 2797 value: function _errorProcessing(files, message, xhr) { 2798 for (var _iterator31 = files, _isArray31 = true, _i33 = 0, _iterator31 = _isArray31 ? _iterator31 : _iterator31[Symbol.iterator]();;) { 2799 var _ref30; 2800 2801 if (_isArray31) { 2802 if (_i33 >= _iterator31.length) break; 2803 _ref30 = _iterator31[_i33++]; 2804 } else { 2805 _i33 = _iterator31.next(); 2806 if (_i33.done) break; 2807 _ref30 = _i33.value; 2808 } 2809 2810 var file = _ref30; 2811 1527 2812 file.status = Dropzone.ERROR; 1528 2813 this.emit("error", file, message, xhr); … … 1533 2818 this.emit("completemultiple", files); 1534 2819 } 2820 1535 2821 if (this.options.autoProcessQueue) { 1536 2822 return this.processQueue(); 1537 2823 } 2824 } 2825 }], [{ 2826 key: "uuidv4", 2827 value: function uuidv4() { 2828 return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) { 2829 var r = Math.random() * 16 | 0, 2830 v = c === 'x' ? r : r & 0x3 | 0x8; 2831 return v.toString(16); 2832 }); 2833 } 2834 }]); 2835 2836 return Dropzone; 2837 }(Emitter); 2838 2839 Dropzone.initClass(); 2840 2841 Dropzone.version = "5.2.0"; 2842 2843 // This is a map of options for your different dropzones. Add configurations 2844 // to this object for your different dropzone elemens. 2845 // 2846 // Example: 2847 // 2848 // Dropzone.options.myDropzoneElementId = { maxFilesize: 1 }; 2849 // 2850 // To disable autoDiscover for a specific element, you can set `false` as an option: 2851 // 2852 // Dropzone.options.myDisabledElementId = false; 2853 // 2854 // And in html: 2855 // 2856 // <form action="/upload" id="my-dropzone-element-id" class="dropzone"></form> 2857 Dropzone.options = {}; 2858 2859 // Returns the options for an element or undefined if none available. 2860 Dropzone.optionsForElement = function (element) { 2861 // Get the `Dropzone.options.elementId` for this element if it exists 2862 if (element.getAttribute("id")) { 2863 return Dropzone.options[camelize(element.getAttribute("id"))]; 2864 } else { 2865 return undefined; 2866 } 2867 }; 2868 2869 // Holds a list of all dropzone instances 2870 Dropzone.instances = []; 2871 2872 // Returns the dropzone for given element if any 2873 Dropzone.forElement = function (element) { 2874 if (typeof element === "string") { 2875 element = document.querySelector(element); 2876 } 2877 if ((element != null ? element.dropzone : undefined) == null) { 2878 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."); 2879 } 2880 return element.dropzone; 2881 }; 2882 2883 // Set to false if you don't want Dropzone to automatically find and attach to .dropzone elements. 2884 Dropzone.autoDiscover = true; 2885 2886 // Looks for all .dropzone elements and creates a dropzone for them 2887 Dropzone.discover = function () { 2888 var dropzones = void 0; 2889 if (document.querySelectorAll) { 2890 dropzones = document.querySelectorAll(".dropzone"); 2891 } else { 2892 dropzones = []; 2893 // IE :( 2894 var checkElements = function checkElements(elements) { 2895 return function () { 2896 var result = []; 2897 for (var _iterator32 = elements, _isArray32 = true, _i34 = 0, _iterator32 = _isArray32 ? _iterator32 : _iterator32[Symbol.iterator]();;) { 2898 var _ref31; 2899 2900 if (_isArray32) { 2901 if (_i34 >= _iterator32.length) break; 2902 _ref31 = _iterator32[_i34++]; 2903 } else { 2904 _i34 = _iterator32.next(); 2905 if (_i34.done) break; 2906 _ref31 = _i34.value; 2907 } 2908 2909 var el = _ref31; 2910 2911 if (/(^| )dropzone($| )/.test(el.className)) { 2912 result.push(dropzones.push(el)); 2913 } else { 2914 result.push(undefined); 2915 } 2916 } 2917 return result; 2918 }(); 1538 2919 }; 1539 1540 return Dropzone; 1541 1542 })(Emitter); 1543 1544 Dropzone.version = "5.1.1"; 1545 1546 Dropzone.options = {}; 1547 1548 Dropzone.optionsForElement = function(element) { 1549 if (element.getAttribute("id")) { 1550 return Dropzone.options[camelize(element.getAttribute("id"))]; 2920 checkElements(document.getElementsByTagName("div")); 2921 checkElements(document.getElementsByTagName("form")); 2922 } 2923 2924 return function () { 2925 var result = []; 2926 for (var _iterator33 = dropzones, _isArray33 = true, _i35 = 0, _iterator33 = _isArray33 ? _iterator33 : _iterator33[Symbol.iterator]();;) { 2927 var _ref32; 2928 2929 if (_isArray33) { 2930 if (_i35 >= _iterator33.length) break; 2931 _ref32 = _iterator33[_i35++]; 2932 } else { 2933 _i35 = _iterator33.next(); 2934 if (_i35.done) break; 2935 _ref32 = _i35.value; 2936 } 2937 2938 var dropzone = _ref32; 2939 2940 // Create a dropzone unless auto discover has been disabled for specific element 2941 if (Dropzone.optionsForElement(dropzone) !== false) { 2942 result.push(new Dropzone(dropzone)); 2943 } else { 2944 result.push(undefined); 2945 } 2946 } 2947 return result; 2948 }(); 2949 }; 2950 2951 // Since the whole Drag'n'Drop API is pretty new, some browsers implement it, 2952 // but not correctly. 2953 // So I created a blacklist of userAgents. Yes, yes. Browser sniffing, I know. 2954 // But what to do when browsers *theoretically* support an API, but crash 2955 // when using it. 2956 // 2957 // This is a list of regular expressions tested against navigator.userAgent 2958 // 2959 // ** It should only be used on browser that *do* support the API, but 2960 // incorrectly ** 2961 // 2962 Dropzone.blacklistedBrowsers = [ 2963 // The mac os and windows phone version of opera 12 seems to have a problem with the File drag'n'drop API. 2964 /opera.*(Macintosh|Windows Phone).*version\/12/i]; 2965 2966 // Checks if the browser is supported 2967 Dropzone.isBrowserSupported = function () { 2968 var capableBrowser = true; 2969 2970 if (window.File && window.FileReader && window.FileList && window.Blob && window.FormData && document.querySelector) { 2971 if (!("classList" in document.createElement("a"))) { 2972 capableBrowser = false; 1551 2973 } else { 1552 return void 0; 1553 } 1554 }; 1555 1556 Dropzone.instances = []; 1557 1558 Dropzone.forElement = function(element) { 1559 if (typeof element === "string") { 1560 element = document.querySelector(element); 1561 } 1562 if ((element != null ? element.dropzone : void 0) == null) { 1563 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."); 1564 } 1565 return element.dropzone; 1566 }; 1567 1568 Dropzone.autoDiscover = true; 1569 1570 Dropzone.discover = function() { 1571 var checkElements, dropzone, dropzones, j, len, results; 1572 if (document.querySelectorAll) { 1573 dropzones = document.querySelectorAll(".dropzone"); 2974 // The browser supports the API, but may be blacklisted. 2975 for (var _iterator34 = Dropzone.blacklistedBrowsers, _isArray34 = true, _i36 = 0, _iterator34 = _isArray34 ? _iterator34 : _iterator34[Symbol.iterator]();;) { 2976 var _ref33; 2977 2978 if (_isArray34) { 2979 if (_i36 >= _iterator34.length) break; 2980 _ref33 = _iterator34[_i36++]; 2981 } else { 2982 _i36 = _iterator34.next(); 2983 if (_i36.done) break; 2984 _ref33 = _i36.value; 2985 } 2986 2987 var regex = _ref33; 2988 2989 if (regex.test(navigator.userAgent)) { 2990 capableBrowser = false; 2991 continue; 2992 } 2993 } 2994 } 2995 } else { 2996 capableBrowser = false; 2997 } 2998 2999 return capableBrowser; 3000 }; 3001 3002 Dropzone.dataURItoBlob = function (dataURI) { 3003 // convert base64 to raw binary data held in a string 3004 // doesn't handle URLEncoded DataURIs - see SO answer #6850276 for code that does this 3005 var byteString = atob(dataURI.split(',')[1]); 3006 3007 // separate out the mime component 3008 var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0]; 3009 3010 // write the bytes of the string to an ArrayBuffer 3011 var ab = new ArrayBuffer(byteString.length); 3012 var ia = new Uint8Array(ab); 3013 for (var i = 0, end = byteString.length, asc = 0 <= end; asc ? i <= end : i >= end; asc ? i++ : i--) { 3014 ia[i] = byteString.charCodeAt(i); 3015 } 3016 3017 // write the ArrayBuffer to a blob 3018 return new Blob([ab], { type: mimeString }); 3019 }; 3020 3021 // Returns an array without the rejected item 3022 var without = function without(list, rejectedItem) { 3023 return list.filter(function (item) { 3024 return item !== rejectedItem; 3025 }).map(function (item) { 3026 return item; 3027 }); 3028 }; 3029 3030 // abc-def_ghi -> abcDefGhi 3031 var camelize = function camelize(str) { 3032 return str.replace(/[\-_](\w)/g, function (match) { 3033 return match.charAt(1).toUpperCase(); 3034 }); 3035 }; 3036 3037 // Creates an element from string 3038 Dropzone.createElement = function (string) { 3039 var div = document.createElement("div"); 3040 div.innerHTML = string; 3041 return div.childNodes[0]; 3042 }; 3043 3044 // Tests if given element is inside (or simply is) the container 3045 Dropzone.elementInside = function (element, container) { 3046 if (element === container) { 3047 return true; 3048 } // Coffeescript doesn't support do/while loops 3049 while (element = element.parentNode) { 3050 if (element === container) { 3051 return true; 3052 } 3053 } 3054 return false; 3055 }; 3056 3057 Dropzone.getElement = function (el, name) { 3058 var element = void 0; 3059 if (typeof el === "string") { 3060 element = document.querySelector(el); 3061 } else if (el.nodeType != null) { 3062 element = el; 3063 } 3064 if (element == null) { 3065 throw new Error("Invalid `" + name + "` option provided. Please provide a CSS selector or a plain HTML element."); 3066 } 3067 return element; 3068 }; 3069 3070 Dropzone.getElements = function (els, name) { 3071 var el = void 0, 3072 elements = void 0; 3073 if (els instanceof Array) { 3074 elements = []; 3075 try { 3076 for (var _iterator35 = els, _isArray35 = true, _i37 = 0, _iterator35 = _isArray35 ? _iterator35 : _iterator35[Symbol.iterator]();;) { 3077 if (_isArray35) { 3078 if (_i37 >= _iterator35.length) break; 3079 el = _iterator35[_i37++]; 3080 } else { 3081 _i37 = _iterator35.next(); 3082 if (_i37.done) break; 3083 el = _i37.value; 3084 } 3085 3086 elements.push(this.getElement(el, name)); 3087 } 3088 } catch (e) { 3089 elements = null; 3090 } 3091 } else if (typeof els === "string") { 3092 elements = []; 3093 for (var _iterator36 = document.querySelectorAll(els), _isArray36 = true, _i38 = 0, _iterator36 = _isArray36 ? _iterator36 : _iterator36[Symbol.iterator]();;) { 3094 if (_isArray36) { 3095 if (_i38 >= _iterator36.length) break; 3096 el = _iterator36[_i38++]; 3097 } else { 3098 _i38 = _iterator36.next(); 3099 if (_i38.done) break; 3100 el = _i38.value; 3101 } 3102 3103 elements.push(el); 3104 } 3105 } else if (els.nodeType != null) { 3106 elements = [els]; 3107 } 3108 3109 if (elements == null || !elements.length) { 3110 throw new Error("Invalid `" + name + "` option provided. Please provide a CSS selector, a plain HTML element or a list of those."); 3111 } 3112 3113 return elements; 3114 }; 3115 3116 // Asks the user the question and calls accepted or rejected accordingly 3117 // 3118 // The default implementation just uses `window.confirm` and then calls the 3119 // appropriate callback. 3120 Dropzone.confirm = function (question, accepted, rejected) { 3121 if (window.confirm(question)) { 3122 return accepted(); 3123 } else if (rejected != null) { 3124 return rejected(); 3125 } 3126 }; 3127 3128 // Validates the mime type like this: 3129 // 3130 // https://developer.mozilla.org/en-US/docs/HTML/Element/input#attr-accept 3131 Dropzone.isValidFile = function (file, acceptedFiles) { 3132 if (!acceptedFiles) { 3133 return true; 3134 } // If there are no accepted mime types, it's OK 3135 acceptedFiles = acceptedFiles.split(","); 3136 3137 var mimeType = file.type; 3138 var baseMimeType = mimeType.replace(/\/.*$/, ""); 3139 3140 for (var _iterator37 = acceptedFiles, _isArray37 = true, _i39 = 0, _iterator37 = _isArray37 ? _iterator37 : _iterator37[Symbol.iterator]();;) { 3141 var _ref34; 3142 3143 if (_isArray37) { 3144 if (_i39 >= _iterator37.length) break; 3145 _ref34 = _iterator37[_i39++]; 1574 3146 } else { 1575 dropzones = []; 1576 checkElements = function(elements) { 1577 var el, j, len, results; 1578 results = []; 1579 for (j = 0, len = elements.length; j < len; j++) { 1580 el = elements[j]; 1581 if (/(^| )dropzone($| )/.test(el.className)) { 1582 results.push(dropzones.push(el)); 1583 } else { 1584 results.push(void 0); 1585 } 1586 } 1587 return results; 1588 }; 1589 checkElements(document.getElementsByTagName("div")); 1590 checkElements(document.getElementsByTagName("form")); 1591 } 1592 results = []; 1593 for (j = 0, len = dropzones.length; j < len; j++) { 1594 dropzone = dropzones[j]; 1595 if (Dropzone.optionsForElement(dropzone) !== false) { 1596 results.push(new Dropzone(dropzone)); 1597 } else { 1598 results.push(void 0); 1599 } 1600 } 1601 return results; 1602 }; 1603 1604 Dropzone.blacklistedBrowsers = [/opera.*Macintosh.*version\/12/i]; 1605 1606 Dropzone.isBrowserSupported = function() { 1607 var capableBrowser, j, len, ref, regex; 1608 capableBrowser = true; 1609 if (window.File && window.FileReader && window.FileList && window.Blob && window.FormData && document.querySelector) { 1610 if (!("classList" in document.createElement("a"))) { 1611 capableBrowser = false; 1612 } else { 1613 ref = Dropzone.blacklistedBrowsers; 1614 for (j = 0, len = ref.length; j < len; j++) { 1615 regex = ref[j]; 1616 if (regex.test(navigator.userAgent)) { 1617 capableBrowser = false; 1618 continue; 1619 } 1620 } 3147 _i39 = _iterator37.next(); 3148 if (_i39.done) break; 3149 _ref34 = _i39.value; 3150 } 3151 3152 var validType = _ref34; 3153 3154 validType = validType.trim(); 3155 if (validType.charAt(0) === ".") { 3156 if (file.name.toLowerCase().indexOf(validType.toLowerCase(), file.name.length - validType.length) !== -1) { 3157 return true; 3158 } 3159 } else if (/\/\*$/.test(validType)) { 3160 // This is something like a image/* mime type 3161 if (baseMimeType === validType.replace(/\/.*$/, "")) { 3162 return true; 1621 3163 } 1622 3164 } else { 1623 capableBrowser = false; 1624 } 1625 return capableBrowser; 1626 }; 1627 1628 Dropzone.dataURItoBlob = function(dataURI) { 1629 var ab, byteString, i, ia, j, mimeString, ref; 1630 byteString = atob(dataURI.split(',')[1]); 1631 mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0]; 1632 ab = new ArrayBuffer(byteString.length); 1633 ia = new Uint8Array(ab); 1634 for (i = j = 0, ref = byteString.length; 0 <= ref ? j <= ref : j >= ref; i = 0 <= ref ? ++j : --j) { 1635 ia[i] = byteString.charCodeAt(i); 1636 } 1637 return new Blob([ab], { 1638 type: mimeString 3165 if (mimeType === validType) { 3166 return true; 3167 } 3168 } 3169 } 3170 3171 return false; 3172 }; 3173 3174 // Augment jQuery 3175 if (typeof jQuery !== 'undefined' && jQuery !== null) { 3176 jQuery.fn.dropzone = function (options) { 3177 return this.each(function () { 3178 return new Dropzone(this, options); 1639 3179 }); 1640 3180 }; 1641 1642 without = function(list, rejectedItem) { 1643 var item, j, len, results; 1644 results = []; 1645 for (j = 0, len = list.length; j < len; j++) { 1646 item = list[j]; 1647 if (item !== rejectedItem) { 1648 results.push(item); 1649 } 1650 } 1651 return results; 1652 }; 1653 1654 camelize = function(str) { 1655 return str.replace(/[\-_](\w)/g, function(match) { 1656 return match.charAt(1).toUpperCase(); 1657 }); 1658 }; 1659 1660 Dropzone.createElement = function(string) { 1661 var div; 1662 div = document.createElement("div"); 1663 div.innerHTML = string; 1664 return div.childNodes[0]; 1665 }; 1666 1667 Dropzone.elementInside = function(element, container) { 1668 if (element === container) { 1669 return true; 1670 } 1671 while (element = element.parentNode) { 1672 if (element === container) { 1673 return true; 1674 } 1675 } 1676 return false; 1677 }; 1678 1679 Dropzone.getElement = function(el, name) { 1680 var element; 1681 if (typeof el === "string") { 1682 element = document.querySelector(el); 1683 } else if (el.nodeType != null) { 1684 element = el; 1685 } 1686 if (element == null) { 1687 throw new Error("Invalid `" + name + "` option provided. Please provide a CSS selector or a plain HTML element."); 1688 } 1689 return element; 1690 }; 1691 1692 Dropzone.getElements = function(els, name) { 1693 var e, el, elements, error1, j, k, len, len1, ref; 1694 if (els instanceof Array) { 1695 elements = []; 1696 try { 1697 for (j = 0, len = els.length; j < len; j++) { 1698 el = els[j]; 1699 elements.push(this.getElement(el, name)); 1700 } 1701 } catch (error1) { 1702 e = error1; 1703 elements = null; 1704 } 1705 } else if (typeof els === "string") { 1706 elements = []; 1707 ref = document.querySelectorAll(els); 1708 for (k = 0, len1 = ref.length; k < len1; k++) { 1709 el = ref[k]; 1710 elements.push(el); 1711 } 1712 } else if (els.nodeType != null) { 1713 elements = [els]; 1714 } 1715 if (!((elements != null) && elements.length)) { 1716 throw new Error("Invalid `" + name + "` option provided. Please provide a CSS selector, a plain HTML element or a list of those."); 1717 } 1718 return elements; 1719 }; 1720 1721 Dropzone.confirm = function(question, accepted, rejected) { 1722 if (window.confirm(question)) { 1723 return accepted(); 1724 } else if (rejected != null) { 1725 return rejected(); 1726 } 1727 }; 1728 1729 Dropzone.isValidFile = function(file, acceptedFiles) { 1730 var baseMimeType, j, len, mimeType, validType; 1731 if (!acceptedFiles) { 1732 return true; 1733 } 1734 acceptedFiles = acceptedFiles.split(","); 1735 mimeType = file.type; 1736 baseMimeType = mimeType.replace(/\/.*$/, ""); 1737 for (j = 0, len = acceptedFiles.length; j < len; j++) { 1738 validType = acceptedFiles[j]; 1739 validType = validType.trim(); 1740 if (validType.charAt(0) === ".") { 1741 if (file.name.toLowerCase().indexOf(validType.toLowerCase(), file.name.length - validType.length) !== -1) { 1742 return true; 1743 } 1744 } else if (/\/\*$/.test(validType)) { 1745 if (baseMimeType === validType.replace(/\/.*$/, "")) { 1746 return true; 1747 } 1748 } else { 1749 if (mimeType === validType) { 1750 return true; 1751 } 1752 } 1753 } 1754 return false; 1755 }; 1756 1757 if (typeof jQuery !== "undefined" && jQuery !== null) { 1758 jQuery.fn.dropzone = function(options) { 1759 return this.each(function() { 1760 return new Dropzone(this, options); 1761 }); 1762 }; 3181 } 3182 3183 if (typeof module !== 'undefined' && module !== null) { 3184 module.exports = Dropzone; 3185 } else { 3186 window.Dropzone = Dropzone; 3187 } 3188 3189 // Dropzone file status codes 3190 Dropzone.ADDED = "added"; 3191 3192 Dropzone.QUEUED = "queued"; 3193 // For backwards compatibility. Now, if a file is accepted, it's either queued 3194 // or uploading. 3195 Dropzone.ACCEPTED = Dropzone.QUEUED; 3196 3197 Dropzone.UPLOADING = "uploading"; 3198 Dropzone.PROCESSING = Dropzone.UPLOADING; // alias 3199 3200 Dropzone.CANCELED = "canceled"; 3201 Dropzone.ERROR = "error"; 3202 Dropzone.SUCCESS = "success"; 3203 3204 /* 3205 3206 Bugfix for iOS 6 and 7 3207 Source: http://stackoverflow.com/questions/11929099/html5-canvas-drawimage-ratio-bug-ios 3208 based on the work of https://github.com/stomita/ios-imagefile-megapixel 3209 3210 */ 3211 3212 // Detecting vertical squash in loaded image. 3213 // Fixes a bug which squash image vertically while drawing into canvas for some images. 3214 // This is a bug in iOS6 devices. This function from https://github.com/stomita/ios-imagefile-megapixel 3215 var detectVerticalSquash = function detectVerticalSquash(img) { 3216 var iw = img.naturalWidth; 3217 var ih = img.naturalHeight; 3218 var canvas = document.createElement("canvas"); 3219 canvas.width = 1; 3220 canvas.height = ih; 3221 var ctx = canvas.getContext("2d"); 3222 ctx.drawImage(img, 0, 0); 3223 3224 var _ctx$getImageData = ctx.getImageData(1, 0, 1, ih), 3225 data = _ctx$getImageData.data; 3226 3227 // search image edge pixel position in case it is squashed vertically. 3228 3229 3230 var sy = 0; 3231 var ey = ih; 3232 var py = ih; 3233 while (py > sy) { 3234 var alpha = data[(py - 1) * 4 + 3]; 3235 3236 if (alpha === 0) { 3237 ey = py; 3238 } else { 3239 sy = py; 3240 } 3241 3242 py = ey + sy >> 1; 1763 3243 } 1764 1765 if (typeof module !== "undefined" && module !== null) { 1766 module.exports = Dropzone; 3244 var ratio = py / ih; 3245 3246 if (ratio === 0) { 3247 return 1; 1767 3248 } else { 1768 window.Dropzone = Dropzone;3249 return ratio; 1769 3250 } 1770 1771 Dropzone.ADDED = "added"; 1772 1773 Dropzone.QUEUED = "queued"; 1774 1775 Dropzone.ACCEPTED = Dropzone.QUEUED; 1776 1777 Dropzone.UPLOADING = "uploading"; 1778 1779 Dropzone.PROCESSING = Dropzone.UPLOADING; 1780 1781 Dropzone.CANCELED = "canceled"; 1782 1783 Dropzone.ERROR = "error"; 1784 1785 Dropzone.SUCCESS = "success"; 1786 1787 1788 /* 1789 1790 Bugfix for iOS 6 and 7 1791 Source: http://stackoverflow.com/questions/11929099/html5-canvas-drawimage-ratio-bug-ios 1792 based on the work of https://github.com/stomita/ios-imagefile-megapixel 1793 */ 1794 1795 detectVerticalSquash = function(img) { 1796 var alpha, canvas, ctx, data, ey, ih, iw, py, ratio, sy; 1797 iw = img.naturalWidth; 1798 ih = img.naturalHeight; 1799 canvas = document.createElement("canvas"); 1800 canvas.width = 1; 1801 canvas.height = ih; 1802 ctx = canvas.getContext("2d"); 1803 ctx.drawImage(img, 0, 0); 1804 data = ctx.getImageData(1, 0, 1, ih).data; 1805 sy = 0; 1806 ey = ih; 1807 py = ih; 1808 while (py > sy) { 1809 alpha = data[(py - 1) * 4 + 3]; 1810 if (alpha === 0) { 1811 ey = py; 1812 } else { 1813 sy = py; 1814 } 1815 py = (ey + sy) >> 1; 1816 } 1817 ratio = py / ih; 1818 if (ratio === 0) { 1819 return 1; 1820 } else { 1821 return ratio; 1822 } 1823 }; 1824 1825 drawImageIOSFix = function(ctx, img, sx, sy, sw, sh, dx, dy, dw, dh) { 1826 var vertSquashRatio; 1827 vertSquashRatio = detectVerticalSquash(img); 1828 return ctx.drawImage(img, sx, sy, sw, sh, dx, dy, dw, dh / vertSquashRatio); 1829 }; 1830 1831 ExifRestore = (function() { 1832 function ExifRestore() {} 1833 1834 ExifRestore.KEY_STR = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='; 1835 1836 ExifRestore.encode64 = function(input) { 1837 var chr1, chr2, chr3, enc1, enc2, enc3, enc4, i, output; 1838 output = ''; 1839 chr1 = void 0; 1840 chr2 = void 0; 1841 chr3 = ''; 1842 enc1 = void 0; 1843 enc2 = void 0; 1844 enc3 = void 0; 1845 enc4 = ''; 1846 i = 0; 3251 }; 3252 3253 // A replacement for context.drawImage 3254 // (args are for source and destination). 3255 var drawImageIOSFix = function drawImageIOSFix(ctx, img, sx, sy, sw, sh, dx, dy, dw, dh) { 3256 var vertSquashRatio = detectVerticalSquash(img); 3257 return ctx.drawImage(img, sx, sy, sw, sh, dx, dy, dw, dh / vertSquashRatio); 3258 }; 3259 3260 // Based on MinifyJpeg 3261 // Source: http://www.perry.cz/files/ExifRestorer.js 3262 // http://elicon.blog57.fc2.com/blog-entry-206.html 3263 3264 var ExifRestore = function () { 3265 function ExifRestore() { 3266 _classCallCheck(this, ExifRestore); 3267 } 3268 3269 _createClass(ExifRestore, null, [{ 3270 key: "initClass", 3271 value: function initClass() { 3272 this.KEY_STR = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='; 3273 } 3274 }, { 3275 key: "encode64", 3276 value: function encode64(input) { 3277 var output = ''; 3278 var chr1 = undefined; 3279 var chr2 = undefined; 3280 var chr3 = ''; 3281 var enc1 = undefined; 3282 var enc2 = undefined; 3283 var enc3 = undefined; 3284 var enc4 = ''; 3285 var i = 0; 1847 3286 while (true) { 1848 3287 chr1 = input[i++]; … … 1866 3305 } 1867 3306 return output; 1868 } ;1869 1870 ExifRestore.restore = function(origFileBase64, resizedFileBase64) {1871 var image, rawImage, segments;3307 } 3308 }, { 3309 key: "restore", 3310 value: function restore(origFileBase64, resizedFileBase64) { 1872 3311 if (!origFileBase64.match('data:image/jpeg;base64,')) { 1873 3312 return resizedFileBase64; 1874 3313 } 1875 rawImage = this.decode64(origFileBase64.replace('data:image/jpeg;base64,', ''));1876 segments = this.slice2Segments(rawImage);1877 image = this.exifManipulation(resizedFileBase64, segments);1878 return 'data:image/jpeg;base64,'+ this.encode64(image);1879 } ;1880 1881 ExifRestore.exifManipulation = function(resizedFileBase64, segments) {1882 var aBuffer, exifArray, newImageArray;1883 exifArray = this.getExifArray(segments);1884 newImageArray = this.insertExif(resizedFileBase64, exifArray);1885 aBuffer = new Uint8Array(newImageArray);3314 var rawImage = this.decode64(origFileBase64.replace('data:image/jpeg;base64,', '')); 3315 var segments = this.slice2Segments(rawImage); 3316 var image = this.exifManipulation(resizedFileBase64, segments); 3317 return "data:image/jpeg;base64," + this.encode64(image); 3318 } 3319 }, { 3320 key: "exifManipulation", 3321 value: function exifManipulation(resizedFileBase64, segments) { 3322 var exifArray = this.getExifArray(segments); 3323 var newImageArray = this.insertExif(resizedFileBase64, exifArray); 3324 var aBuffer = new Uint8Array(newImageArray); 1886 3325 return aBuffer; 1887 } ;1888 1889 ExifRestore.getExifArray = function(segments) {1890 var seg, x;1891 seg = void 0;1892 x = 0;3326 } 3327 }, { 3328 key: "getExifArray", 3329 value: function getExifArray(segments) { 3330 var seg = undefined; 3331 var x = 0; 1893 3332 while (x < segments.length) { 1894 3333 seg = segments[x]; … … 1899 3338 } 1900 3339 return []; 1901 } ;1902 1903 ExifRestore.insertExif = function(resizedFileBase64, exifArray) {1904 var array, ato, buf, imageData, mae, separatePoint;1905 imageData = resizedFileBase64.replace('data:image/jpeg;base64,', '');1906 buf = this.decode64(imageData);1907 separatePoint = buf.indexOf(255, 3);1908 mae = buf.slice(0, separatePoint);1909 ato = buf.slice(separatePoint);1910 array = mae;3340 } 3341 }, { 3342 key: "insertExif", 3343 value: function insertExif(resizedFileBase64, exifArray) { 3344 var imageData = resizedFileBase64.replace('data:image/jpeg;base64,', ''); 3345 var buf = this.decode64(imageData); 3346 var separatePoint = buf.indexOf(255, 3); 3347 var mae = buf.slice(0, separatePoint); 3348 var ato = buf.slice(separatePoint); 3349 var array = mae; 1911 3350 array = array.concat(exifArray); 1912 3351 array = array.concat(ato); 1913 3352 return array; 1914 } ;1915 1916 ExifRestore.slice2Segments = function(rawImageArray) {1917 var endPoint, head, length, seg, segments;1918 head = 0;1919 segments = [];3353 } 3354 }, { 3355 key: "slice2Segments", 3356 value: function slice2Segments(rawImageArray) { 3357 var head = 0; 3358 var segments = []; 1920 3359 while (true) { 3360 var length; 1921 3361 if (rawImageArray[head] === 255 & rawImageArray[head + 1] === 218) { 1922 3362 break; … … 1926 3366 } else { 1927 3367 length = rawImageArray[head + 2] * 256 + rawImageArray[head + 3]; 1928 endPoint = head + length + 2;1929 seg = rawImageArray.slice(head, endPoint);3368 var endPoint = head + length + 2; 3369 var seg = rawImageArray.slice(head, endPoint); 1930 3370 segments.push(seg); 1931 3371 head = endPoint; … … 1936 3376 } 1937 3377 return segments; 1938 }; 1939 1940 ExifRestore.decode64 = function(input) { 1941 var base64test, buf, chr1, chr2, chr3, enc1, enc2, enc3, enc4, i, output; 1942 output = ''; 1943 chr1 = void 0; 1944 chr2 = void 0; 1945 chr3 = ''; 1946 enc1 = void 0; 1947 enc2 = void 0; 1948 enc3 = void 0; 1949 enc4 = ''; 1950 i = 0; 1951 buf = []; 1952 base64test = /[^A-Za-z0-9\+\/\=]/g; 3378 } 3379 }, { 3380 key: "decode64", 3381 value: function decode64(input) { 3382 var output = ''; 3383 var chr1 = undefined; 3384 var chr2 = undefined; 3385 var chr3 = ''; 3386 var enc1 = undefined; 3387 var enc2 = undefined; 3388 var enc3 = undefined; 3389 var enc4 = ''; 3390 var i = 0; 3391 var buf = []; 3392 // remove all characters that are not A-Z, a-z, 0-9, +, /, or = 3393 var base64test = /[^A-Za-z0-9\+\/\=]/g; 1953 3394 if (base64test.exec(input)) { 1954 console.warn ing('There were invalid base64 characters in the input text.\n' + 'Valid base64 characters are A-Z, a-z, 0-9, \'+\', \'/\',and \'=\'\n' + 'Expect errors in decoding.');3395 console.warn('There were invalid base64 characters in the input text.\nValid base64 characters are A-Z, a-z, 0-9, \'+\', \'/\',and \'=\'\nExpect errors in decoding.'); 1955 3396 } 1956 3397 input = input.replace(/[^A-Za-z0-9\+\/\=]/g, ''); … … 1977 3418 } 1978 3419 return buf; 1979 }; 1980 1981 return ExifRestore; 1982 1983 })(); 1984 1985 1986 /* 1987 * contentloaded.js 1988 * 1989 * Author: Diego Perini (diego.perini at gmail.com) 1990 * Summary: cross-browser wrapper for DOMContentLoaded 1991 * Updated: 20101020 1992 * License: MIT 1993 * Version: 1.2 1994 * 1995 * URL: 1996 * http://javascript.nwbox.com/ContentLoaded/ 1997 * http://javascript.nwbox.com/ContentLoaded/MIT-LICENSE 1998 */ 1999 2000 contentLoaded = function(win, fn) { 2001 var add, doc, done, init, poll, pre, rem, root, top; 2002 done = false; 2003 top = true; 2004 doc = win.document; 2005 root = doc.documentElement; 2006 add = (doc.addEventListener ? "addEventListener" : "attachEvent"); 2007 rem = (doc.addEventListener ? "removeEventListener" : "detachEvent"); 2008 pre = (doc.addEventListener ? "" : "on"); 2009 init = function(e) { 2010 if (e.type === "readystatechange" && doc.readyState !== "complete") { 2011 return; 2012 } 2013 (e.type === "load" ? win : doc)[rem](pre + e.type, init, false); 2014 if (!done && (done = true)) { 2015 return fn.call(win, e.type || e); 2016 } 2017 }; 2018 poll = function() { 2019 var e, error1; 3420 } 3421 }]); 3422 3423 return ExifRestore; 3424 }(); 3425 3426 ExifRestore.initClass(); 3427 3428 /* 3429 * contentloaded.js 3430 * 3431 * Author: Diego Perini (diego.perini at gmail.com) 3432 * Summary: cross-browser wrapper for DOMContentLoaded 3433 * Updated: 20101020 3434 * License: MIT 3435 * Version: 1.2 3436 * 3437 * URL: 3438 * http://javascript.nwbox.com/ContentLoaded/ 3439 * http://javascript.nwbox.com/ContentLoaded/MIT-LICENSE 3440 */ 3441 3442 // @win window reference 3443 // @fn function reference 3444 var contentLoaded = function contentLoaded(win, fn) { 3445 var done = false; 3446 var top = true; 3447 var doc = win.document; 3448 var root = doc.documentElement; 3449 var add = doc.addEventListener ? "addEventListener" : "attachEvent"; 3450 var rem = doc.addEventListener ? "removeEventListener" : "detachEvent"; 3451 var pre = doc.addEventListener ? "" : "on"; 3452 var init = function init(e) { 3453 if (e.type === "readystatechange" && doc.readyState !== "complete") { 3454 return; 3455 } 3456 (e.type === "load" ? win : doc)[rem](pre + e.type, init, false); 3457 if (!done && (done = true)) { 3458 return fn.call(win, e.type || e); 3459 } 3460 }; 3461 3462 var poll = function poll() { 3463 try { 3464 root.doScroll("left"); 3465 } catch (e) { 3466 setTimeout(poll, 50); 3467 return; 3468 } 3469 return init("poll"); 3470 }; 3471 3472 if (doc.readyState !== "complete") { 3473 if (doc.createEventObject && root.doScroll) { 2020 3474 try { 2021 root.doScroll("left"); 2022 } catch (error1) { 2023 e = error1; 2024 setTimeout(poll, 50); 2025 return; 2026 } 2027 return init("poll"); 2028 }; 2029 if (doc.readyState !== "complete") { 2030 if (doc.createEventObject && root.doScroll) { 2031 try { 2032 top = !win.frameElement; 2033 } catch (undefined) {} 2034 if (top) { 2035 poll(); 2036 } 2037 } 2038 doc[add](pre + "DOMContentLoaded", init, false); 2039 doc[add](pre + "readystatechange", init, false); 2040 return win[add](pre + "load", init, false); 2041 } 2042 }; 2043 2044 Dropzone._autoDiscoverFunction = function() { 2045 if (Dropzone.autoDiscover) { 2046 return Dropzone.discover(); 2047 } 2048 }; 2049 2050 contentLoaded(window, Dropzone._autoDiscoverFunction); 2051 2052 }).call(this); 3475 top = !win.frameElement; 3476 } catch (error) {} 3477 if (top) { 3478 poll(); 3479 } 3480 } 3481 doc[add](pre + "DOMContentLoaded", init, false); 3482 doc[add](pre + "readystatechange", init, false); 3483 return win[add](pre + "load", init, false); 3484 } 3485 }; 3486 3487 // As a single function to be able to write tests. 3488 Dropzone._autoDiscoverFunction = function () { 3489 if (Dropzone.autoDiscover) { 3490 return Dropzone.discover(); 3491 } 3492 }; 3493 contentLoaded(window, Dropzone._autoDiscoverFunction); 3494 3495 function __guard__(value, transform) { 3496 return typeof value !== 'undefined' && value !== null ? transform(value) : undefined; 3497 } 3498 function __guardMethod__(obj, methodName, transform) { 3499 if (typeof obj !== 'undefined' && obj !== null && typeof obj[methodName] === 'function') { 3500 return transform(obj, methodName); 3501 } else { 3502 return undefined; 3503 } 3504 }
Note: See TracChangeset
for help on using the changeset viewer.