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